talking-stick 0.1.0 → 0.1.2

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 CHANGED
@@ -2,32 +2,51 @@
2
2
 
3
3
  An MCP coordination server that lets multiple AI coding agents share a single workspace without stepping on each other. One agent holds the stick at a time; handoffs carry structured context so the next agent doesn't have to re-derive it.
4
4
 
5
- **Version:** 0.1.0. Multi-process-safe (SQLite WAL), liveness-aware, no daemon. Supports Claude Code, Codex CLI, Gemini CLI, and OpenCode out of the box.
5
+ **Version:** 0.1.2. Multi-process-safe (SQLite WAL), liveness-aware, no daemon. Supports Claude Code, Codex CLI, Gemini CLI, and OpenCode out of the box.
6
6
 
7
7
  ## Quickstart
8
8
 
9
- Three commands from zero to coordinated agents. No repo clone required.
9
+ Three steps, then you're coordinating two agents in the same repo.
10
+
11
+ ### 1. Install the `tt` binary
10
12
 
11
13
  ```bash
12
- # 1. Install the `tt` binary from npm
13
14
  npm i -g talking-stick
15
+ ```
14
16
 
15
- # 2. Register Talking Stick as an MCP server + install the coordination skill
16
- # across every harness detected on your machine
17
- tt install --all
18
- tt install-skill --all
17
+ ### 2. Register the MCP server and skill in every harness
19
18
 
20
- # 3. Restart your agent harness (Claude Code, Codex, Gemini, OpenCode).
21
- # The `talking_stick` tools now appear in any workspace.
19
+ ```bash
20
+ tt install --all
22
21
  ```
23
22
 
24
- That's it. The next time two agents `cd` into the same repo, they see each other as members of one room, take turns automatically, and hand off structured context when they release the stick.
23
+ Restart any harness that was already running so it loads the new MCP server. The `talking_stick` tools and skill now appear in every workspace.
24
+
25
+ ### 3. Try it: two agents, one repo
26
+
27
+ Open two terminal panes side by side — tmux split, iTerm split, two windows, whatever you like. `cd` into the same repo in each, and launch a different harness in each pane:
28
+
29
+ | Pane A — Claude Code | Pane B — Codex |
30
+ |---|---|
31
+ | `cd ~/myrepo && claude [--dangerously-skip-permissions]` | `cd ~/myrepo && codex` |
32
+
33
+ Then prompt them.
34
+
35
+ **Pane A (Claude Code):**
36
+
37
+ > Draft a plan to add OAuth login. When it's solid, pass the stick to Codex for critique. After Codex hands it back with revisions, finalize, then pass to Codex to implement — you'll test and review. `/talking-stick`
38
+
39
+ **Pane B (Codex):**
40
+
41
+ > Join the room and wait for the stick. When Claude passes you a plan, critique it sharply and pass it back with revisions. Later, when Claude hands you the implementation turn, build it and pass back for review. `$talking-stick`
42
+
43
+ That's the whole workflow. They negotiate turns automatically, hand off structured context (status, next action, artifacts) at each transition, and never edit the repo at the same time.
25
44
 
26
45
  ### Install options
27
46
 
28
47
  | Method | Command | Notes |
29
48
  |---|---|---|
30
- | **From npm** | `npm i -g talking-stick` | Published as `0.1.0`. Requires Node ≥ 22. |
49
+ | **From npm** | `npm i -g talking-stick` | Published as `0.1.2`. Requires Node ≥ 22. |
31
50
  | **From GitHub** | `npm i -g github:mostlydev/talking-stick` | Tracks the `master` branch; builds on install via the `prepare` hook. |
32
51
  | **From source** | `git clone … && npm install && npm link` | For contributors. |
33
52
 
@@ -35,27 +54,34 @@ All three produce a `tt` binary on your `PATH`. Everything else below works iden
35
54
 
36
55
  ### Verify without installing
37
56
 
38
- Want to see exactly what `tt install`/`tt install-skill` would change before touching anything?
57
+ Want to see exactly what `tt install` would change before touching anything?
39
58
 
40
59
  ```bash
41
60
  tt install --all --print
42
- tt install-skill --all --print
43
61
  ```
44
62
 
45
63
  ### Install into a subset
46
64
 
47
65
  ```bash
48
66
  tt install claude-code codex
49
- tt install-skill gemini
50
67
  ```
51
68
 
52
- During normal execution, install commands skip harnesses that are not present instead of failing or creating new harness config roots. For example, `tt install-skill codex` only creates `~/.codex/skills/` if `~/.codex/` already exists.
69
+ During normal execution, install commands skip harnesses that are not present instead of failing or creating new harness config roots.
70
+
71
+ ### Update
72
+
73
+ Uses the right npm/pnpm/yarn by default:
74
+
75
+ ```bash
76
+ tt self-update
77
+ ```
78
+
79
+ Skills are symlinked automatically, so they don't need an update.
53
80
 
54
81
  ### Remove
55
82
 
56
83
  ```bash
57
84
  tt uninstall --all
58
- tt uninstall-skill --all
59
85
  ```
60
86
 
61
87
  ## What it gives your agent
@@ -94,7 +120,9 @@ While you wait your turn you may still need to flag something to the current own
94
120
 
95
121
  ## How installation works per harness
96
122
 
97
- `tt install` prefers each harness's own `mcp add` subcommand when available (so the server ends up in the right user-global config with the right schema), and falls back to direct JSON editing when it isn't.
123
+ `tt install` installs both pieces a harness needs: the MCP server registration and the bundled `talking-stick` skill.
124
+
125
+ For MCP registration, it prefers each harness's own `mcp add` subcommand when available (so the server ends up in the right user-global config with the right schema), and falls back to direct JSON editing when it isn't.
98
126
 
99
127
  | Harness | Scope | Under the hood |
100
128
  |---------------|--------------|-----------------------------------------------------------------------------|
@@ -105,9 +133,9 @@ While you wait your turn you may still need to flag something to the current own
105
133
 
106
134
  All four install into **user-global scope**, not project-local. A coordination server is only useful if every workspace your agent enters can see the same rooms — project-scoped MCP would defeat the point.
107
135
 
108
- If you'd rather register it by hand, run `tt install --print <harness>` to see the exact command or JSON edit, then apply it yourself.
136
+ If you'd rather apply setup by hand, run `tt install --print <harness>` to see the exact MCP and skill actions, then apply them yourself.
109
137
 
110
- ## How skill installation works per harness
138
+ ## Skill paths per harness
111
139
 
112
140
  Talking Stick also ships with a portable `talking-stick` skill:
113
141
 
@@ -116,9 +144,9 @@ Talking Stick also ships with a portable `talking-stick` skill:
116
144
  - Gemini: installed with `gemini skills install ... --scope user` or linked with `gemini skills link ... --scope user`
117
145
  - OpenCode: copied or linked into `~/.opencode/skills/talking-stick`
118
146
 
119
- By default, `tt install-skill` links the bundled skill into each harness so local updates are picked up immediately. Pass `--copy` if you want a standalone snapshot instead.
147
+ By default, `tt install` links the bundled skill into each harness so local updates are picked up immediately. Pass `--copy` if you want a standalone snapshot instead.
120
148
 
121
- Human CLI invocations also perform a silent best-effort sync for already-installed file-based skills in Claude Code, Codex, and OpenCode. If the installed skill is a copy, it is refreshed from the bundled skill; if it is a stale symlink, it is relinked. Missing harness config directories and missing skill installs are skipped. Gemini skills are managed by Gemini's own registry, so use `tt install-skill gemini` after updating when needed.
149
+ Human CLI invocations also perform a silent best-effort sync for already-installed file-based skills in Claude Code, Codex, and OpenCode. If the installed skill is a copy, it is refreshed from the bundled skill; if it is a stale symlink, it is relinked. Missing harness config directories and missing skill installs are skipped. Gemini skills are managed by Gemini's own registry, so use `tt install gemini` after updating when needed.
122
150
 
123
151
  ## Human CLI
124
152
 
@@ -141,10 +169,8 @@ tt takeover [path] [--reason TEXT] # alias for take
141
169
  tt notes add <body> [--turn N] [--path DIR] [--stdin] # leave an async note
142
170
  tt notes list [--all] [--after ID] [--limit N] [--path DIR] # read notes
143
171
  tt mcp # run the MCP stdio server
144
- tt install <harness...> | --all [--print] # register MCP server
145
- tt uninstall <harness...> | --all [--print] # remove MCP server
146
- tt install-skill <harness...> | --all [--print] [--copy] [--link] # install global talking-stick skill
147
- tt uninstall-skill <harness...> | --all [--print] # remove global talking-stick skill
172
+ tt install <harness...> | --all [--print] [--copy] [--link] # install MCP server and skill
173
+ tt uninstall <harness...> | --all [--print] # remove MCP server and skill
148
174
  tt self-update [--print] [--manager npm|pnpm|yarn|bun] # update to the latest published tt
149
175
  ```
150
176
 
@@ -5,17 +5,21 @@ import { detectInstallSource, isPackageManager, planSelfUpdate, resolveCurrentBi
5
5
  import { getStringOption, hasOption, normalizeBooleanFlag } from "./parser.js";
6
6
  export async function runInstallCommand(parsed) {
7
7
  normalizeBooleanFlag(parsed, "print");
8
+ normalizeBooleanFlag(parsed, "copy");
9
+ normalizeBooleanFlag(parsed, "link");
8
10
  const harnesses = selectHarnesses(parsed);
9
11
  const dryRun = hasOption(parsed, "print");
10
- const installOptions = { skipMissing: true };
11
- const actions = harnesses.map((harness) => planInstall(harness, installOptions));
12
+ const installOptions = {
13
+ link: resolveSkillInstallLinkMode(parsed),
14
+ skipMissing: true
15
+ };
12
16
  if (dryRun) {
13
- for (const action of actions) {
17
+ for (const action of planCombinedInstallActions(harnesses, installOptions)) {
14
18
  printActionPlan(action);
15
19
  }
16
20
  return;
17
21
  }
18
- const results = await Promise.all(actions.map((action) => runAction(action, installOptions)));
22
+ const results = (await Promise.all(harnesses.map((harness) => runCombinedInstall(harness, installOptions)))).flat();
19
23
  reportInstallResults(results, "install");
20
24
  }
21
25
  export async function runUninstallCommand(parsed) {
@@ -23,14 +27,14 @@ export async function runUninstallCommand(parsed) {
23
27
  const harnesses = selectHarnesses(parsed);
24
28
  const dryRun = hasOption(parsed, "print");
25
29
  const installOptions = { skipMissing: true };
26
- const actions = harnesses.map((harness) => planUninstall(harness, installOptions));
30
+ const actions = planCombinedUninstallActions(harnesses, installOptions);
27
31
  if (dryRun) {
28
32
  for (const action of actions) {
29
33
  printActionPlan(action);
30
34
  }
31
35
  return;
32
36
  }
33
- const results = await Promise.all(actions.map((action) => runAction(action, installOptions)));
37
+ const results = (await Promise.all(harnesses.map((harness) => runCombinedUninstall(harness, installOptions)))).flat();
34
38
  reportInstallResults(results, "uninstall");
35
39
  }
36
40
  export async function runInstallSkillCommand(parsed) {
@@ -107,6 +111,49 @@ function resolveSkillInstallLinkMode(parsed) {
107
111
  }
108
112
  return true;
109
113
  }
114
+ function planCombinedInstallActions(harnesses, installOptions) {
115
+ return harnesses.flatMap((harness) => {
116
+ const mcpAction = planInstall(harness, installOptions);
117
+ if (mcpAction.kind === "skip") {
118
+ return [mcpAction];
119
+ }
120
+ return [
121
+ mcpAction,
122
+ planSkillInstall(harness, {
123
+ ...installOptions,
124
+ // In dry-run mode, show the skill action that will follow MCP setup
125
+ // even when the MCP installer is what creates the harness config root.
126
+ skipMissing: false
127
+ })
128
+ ];
129
+ });
130
+ }
131
+ function planCombinedUninstallActions(harnesses, installOptions) {
132
+ return harnesses.flatMap((harness) => [
133
+ planUninstall(harness, installOptions),
134
+ planSkillUninstall(harness, {
135
+ ...installOptions,
136
+ skipMissing: false
137
+ })
138
+ ]);
139
+ }
140
+ async function runCombinedInstall(harness, installOptions) {
141
+ const mcpAction = planInstall(harness, installOptions);
142
+ const mcpResult = await runAction(mcpAction, installOptions);
143
+ if (!mcpResult.ok || mcpResult.skipped) {
144
+ return [mcpResult];
145
+ }
146
+ const skillAction = planSkillInstall(harness, installOptions);
147
+ const skillResult = await runAction(skillAction, installOptions);
148
+ return [mcpResult, skillResult];
149
+ }
150
+ async function runCombinedUninstall(harness, installOptions) {
151
+ const mcpAction = planUninstall(harness, installOptions);
152
+ const mcpResult = await runAction(mcpAction, installOptions);
153
+ const skillAction = planSkillUninstall(harness, installOptions);
154
+ const skillResult = await runAction(skillAction, installOptions);
155
+ return [mcpResult, skillResult];
156
+ }
110
157
  function selectHarnesses(parsed) {
111
158
  if (hasOption(parsed, "all")) {
112
159
  const detected = SUPPORTED_HARNESSES.filter((harness) => detectHarness(harness).detected);
@@ -134,10 +134,8 @@ Commands:
134
134
  tt notes add <body> [--turn N] [--path DIR] [--stdin]
135
135
  tt notes list [--all] [--after NOTE_ID] [--limit N] [--path DIR]
136
136
  tt mcp
137
- tt install <harness...> | --all [--print]
137
+ tt install <harness...> | --all [--print] [--copy] [--link]
138
138
  tt uninstall <harness...> | --all [--print]
139
- tt install-skill <harness...> | --all [--print] [--copy] [--link]
140
- tt uninstall-skill <harness...> | --all [--print]
141
139
  tt self-update [--print] [--manager npm|pnpm|yarn|bun]
142
140
 
143
141
  Harnesses: ${SUPPORTED_HARNESSES.join(", ")}
@@ -28,8 +28,8 @@ export const COMMAND_REGISTRY = [
28
28
  needsRuntime: false,
29
29
  startupMaintenance: false,
30
30
  internal: false,
31
- usage: "tt install <harness...> | --all [--print]",
32
- description: "Install Talking Stick into harness MCP configs.",
31
+ usage: "tt install <harness...> | --all [--print] [--copy] [--link]",
32
+ description: "Install Talking Stick into harness MCP configs and skills.",
33
33
  handler: ({ parsed }) => runInstallCommand(parsed)
34
34
  },
35
35
  {
@@ -38,7 +38,7 @@ export const COMMAND_REGISTRY = [
38
38
  startupMaintenance: false,
39
39
  internal: false,
40
40
  usage: "tt uninstall <harness...> | --all [--print]",
41
- description: "Remove Talking Stick from harness MCP configs.",
41
+ description: "Remove Talking Stick from harness MCP configs and skills.",
42
42
  handler: ({ parsed }) => runUninstallCommand(parsed)
43
43
  },
44
44
  {
@@ -27,7 +27,7 @@ export function createMcpServer(service = new TalkingStickService()) {
27
27
  const resolveConnectionIdentity = createConnectionIdentityResolver();
28
28
  const server = new McpServer({
29
29
  name: "talking-stick",
30
- version: "0.1.0"
30
+ version: "0.1.2"
31
31
  });
32
32
  server.registerTool("list_rooms", {
33
33
  title: "List Rooms",
@@ -0,0 +1,30 @@
1
+ # Talking Stick 0.1.1
2
+
3
+ Date: 2026-04-27
4
+
5
+ Patch release focused on onboarding clarity and tighter multi-agent wait
6
+ cadence.
7
+
8
+ ## Changed
9
+
10
+ ### Clearer quickstart
11
+
12
+ The README quickstart now presents the setup as three steps: install `tt`,
13
+ register the MCP server and skill across harnesses, then try a concrete
14
+ two-agent Claude Code / Codex workflow in one repo.
15
+
16
+ ### Wait cycles before scheduled wakeups
17
+
18
+ The bundled skill now tells agents to prefer direct `wait_for_turn` wait cycles
19
+ and background long-polls over scheduled wakeups. Scheduled wakeups are framed
20
+ as fallback behavior, and active multi-agent wakeups are capped at 60-120
21
+ seconds unless the operator explicitly pauses the room or the task is blocked
22
+ outside the room.
23
+
24
+ ## Verification
25
+
26
+ - `npm run typecheck`
27
+ - `npm test` — 208 tests across 14 files
28
+ - `npm run build`
29
+ - `git diff --check`
30
+ - `npm pack --dry-run --ignore-scripts`
@@ -0,0 +1,40 @@
1
+ # Talking Stick 0.1.2
2
+
3
+ Date: 2026-04-27
4
+
5
+ Patch release focused on simplifying first-time setup and keeping the README in
6
+ sync with the CLI.
7
+
8
+ ## Changed
9
+
10
+ ### Combined harness setup
11
+
12
+ `tt install` now installs both pieces each harness needs: the MCP server
13
+ registration and the bundled Talking Stick skill. The command accepts the skill
14
+ mode flags directly, so `tt install --all --copy` produces standalone skill
15
+ copies while the default still links the bundled skill.
16
+
17
+ `tt uninstall` now removes both the MCP registration and the installed skill for
18
+ each selected harness.
19
+
20
+ The older `tt install-skill` and `tt uninstall-skill` commands remain available
21
+ for targeted maintenance, but they are no longer part of the normal README/help
22
+ setup path.
23
+
24
+ ### README setup path
25
+
26
+ The quickstart, dry-run instructions, subset install example, removal example,
27
+ installation details, skill path section, and CLI reference now document a
28
+ single-command setup flow:
29
+
30
+ ```bash
31
+ tt install --all
32
+ ```
33
+
34
+ ## Verification
35
+
36
+ - `npm run typecheck`
37
+ - `npm test` — 212 tests across 14 files
38
+ - `npm run build`
39
+ - `git diff --check`
40
+ - `npm pack --dry-run --ignore-scripts`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "talking-stick",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "MCP coordination server for path-scoped agent handoffs.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -30,7 +30,7 @@ Prefer the Talking Stick MCP tools when they are available. If they are not avai
30
30
 
31
31
  If coordination is required and neither the MCP tools nor the `tt` CLI are available, say so briefly and ask the user whether they want to install or enable Talking Stick first. Do not pretend coordination is active.
32
32
 
33
- Human CLI runs silently keep already-installed Claude Code, Codex, and OpenCode skill copies/symlinks aligned with the bundled Talking Stick skill. This is best effort and only updates existing installs; Gemini skills are registry-managed and should be refreshed with `tt install-skill gemini` when needed.
33
+ Human CLI runs silently keep already-installed Claude Code, Codex, and OpenCode skill copies/symlinks aligned with the bundled Talking Stick skill. This is best effort and only updates existing installs; Gemini skills are registry-managed and should be refreshed with `tt install gemini` when needed.
34
34
 
35
35
  ### 2. Join the workspace room once
36
36
 
@@ -70,15 +70,15 @@ Possible outcomes:
70
70
 
71
71
  **Prefer to run the wait in the background.** If your harness supports running a command or subtask in the background, launch the wait (`wait_for_turn` or `tt wait`) as a background process so your foreground stays free for other work — reading, planning, answering the operator — until your turn arrives. Blocking the whole harness on the wait defeats the point.
72
72
 
73
- **Even better: use a wakeup if your harness supports one.** Some harnesses (for example Claude Code with `ScheduleWakeup`, cron-backed agents, or runtime-resumed sleeps) can sleep without keeping conversation context loaded. Prefer that over repeated long-polls: a long-poll re-evaluates your full conversation each cycle, while a wakeup pays one re-entry per actual room event.
73
+ **Prefer wait cycles over scheduled wakeups.** A direct `wait_for_turn` long-poll keeps your cadence aligned with other agents and usually notices a released stick within the same cycle. Use scheduling only when your harness cannot keep a wait running in the background, or when it must return control between checks.
74
74
 
75
75
  Wakeup pattern:
76
76
 
77
77
  1. Probe `wait_for_turn` with `max_wait_ms: 0`.
78
- 2. If it returns `not_yet`, schedule a wakeup and return control to the harness. Use 60-240 s in active multi-agent sessions, or 1200-1800 s at idle/operator-blocked pause points. Avoid roughly 300 s; most prompt caches expire around 5 minutes, so stay under that window or choose a much longer interval.
78
+ 2. If it returns `not_yet`, schedule a wakeup and return control to the harness. Keep active multi-agent wakeups tight: use 60-120 s, and never more than 120 s unless the operator explicitly pauses the room or the task is blocked outside the room.
79
79
  3. On wakeup, repeat from step 1.
80
80
 
81
- This converts repeated re-prompts into roughly one re-entry per actual event. If your harness has neither background work nor wakeups, fall back to synchronous long-polls with the longest client-safe `max_wait_ms` from §3.
81
+ Scheduled wakeups are a fallback, not a reason to check in more slowly than agents using `wait_for_turn` directly. If your harness has neither background work nor wakeups, fall back to synchronous long-polls with the longest client-safe `max_wait_ms` from §3.
82
82
 
83
83
  Whether the wait runs in the foreground or the background, call it **once** with the client-safe `max_wait_ms` budget from above and let the server long-poll. When it returns without `your_turn`, call it again. Do not busy-loop with short waits — that generates log noise and burns cache without buying anything.
84
84
 
@@ -153,7 +153,7 @@ Example:
153
153
  }
154
154
  ],
155
155
  "open_questions": [
156
- "Should install-skill default to copy or link for local development?"
156
+ "Should tt install default to copy or link for local development?"
157
157
  ]
158
158
  }
159
159
  ```