talking-stick 0.1.1 → 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 +13 -17
- package/dist/cli/install-commands.js +53 -6
- package/dist/cli/output.js +1 -3
- package/dist/cli/registry.js +3 -3
- package/dist/mcp-server.js +1 -1
- package/docs/releases/0.1.2.md +40 -0
- package/package.json +1 -1
- package/skills/talking-stick/SKILL.md +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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.
|
|
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
|
|
|
@@ -18,7 +18,6 @@ npm i -g talking-stick
|
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
tt install --all
|
|
21
|
-
tt install-skill --all
|
|
22
21
|
```
|
|
23
22
|
|
|
24
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.
|
|
@@ -47,7 +46,7 @@ That's the whole workflow. They negotiate turns automatically, hand off structur
|
|
|
47
46
|
|
|
48
47
|
| Method | Command | Notes |
|
|
49
48
|
|---|---|---|
|
|
50
|
-
| **From npm** | `npm i -g talking-stick` | Published as `0.1.
|
|
49
|
+
| **From npm** | `npm i -g talking-stick` | Published as `0.1.2`. Requires Node ≥ 22. |
|
|
51
50
|
| **From GitHub** | `npm i -g github:mostlydev/talking-stick` | Tracks the `master` branch; builds on install via the `prepare` hook. |
|
|
52
51
|
| **From source** | `git clone … && npm install && npm link` | For contributors. |
|
|
53
52
|
|
|
@@ -55,21 +54,19 @@ All three produce a `tt` binary on your `PATH`. Everything else below works iden
|
|
|
55
54
|
|
|
56
55
|
### Verify without installing
|
|
57
56
|
|
|
58
|
-
Want to see exactly what `tt install
|
|
57
|
+
Want to see exactly what `tt install` would change before touching anything?
|
|
59
58
|
|
|
60
59
|
```bash
|
|
61
60
|
tt install --all --print
|
|
62
|
-
tt install-skill --all --print
|
|
63
61
|
```
|
|
64
62
|
|
|
65
63
|
### Install into a subset
|
|
66
64
|
|
|
67
65
|
```bash
|
|
68
66
|
tt install claude-code codex
|
|
69
|
-
tt install-skill gemini
|
|
70
67
|
```
|
|
71
68
|
|
|
72
|
-
During normal execution, install commands skip harnesses that are not present instead of failing or creating new harness config roots.
|
|
69
|
+
During normal execution, install commands skip harnesses that are not present instead of failing or creating new harness config roots.
|
|
73
70
|
|
|
74
71
|
### Update
|
|
75
72
|
|
|
@@ -85,7 +82,6 @@ Skills are symlinked automatically, so they don't need an update.
|
|
|
85
82
|
|
|
86
83
|
```bash
|
|
87
84
|
tt uninstall --all
|
|
88
|
-
tt uninstall-skill --all
|
|
89
85
|
```
|
|
90
86
|
|
|
91
87
|
## What it gives your agent
|
|
@@ -124,7 +120,9 @@ While you wait your turn you may still need to flag something to the current own
|
|
|
124
120
|
|
|
125
121
|
## How installation works per harness
|
|
126
122
|
|
|
127
|
-
`tt install`
|
|
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.
|
|
128
126
|
|
|
129
127
|
| Harness | Scope | Under the hood |
|
|
130
128
|
|---------------|--------------|-----------------------------------------------------------------------------|
|
|
@@ -135,9 +133,9 @@ While you wait your turn you may still need to flag something to the current own
|
|
|
135
133
|
|
|
136
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.
|
|
137
135
|
|
|
138
|
-
If you'd rather
|
|
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.
|
|
139
137
|
|
|
140
|
-
##
|
|
138
|
+
## Skill paths per harness
|
|
141
139
|
|
|
142
140
|
Talking Stick also ships with a portable `talking-stick` skill:
|
|
143
141
|
|
|
@@ -146,9 +144,9 @@ Talking Stick also ships with a portable `talking-stick` skill:
|
|
|
146
144
|
- Gemini: installed with `gemini skills install ... --scope user` or linked with `gemini skills link ... --scope user`
|
|
147
145
|
- OpenCode: copied or linked into `~/.opencode/skills/talking-stick`
|
|
148
146
|
|
|
149
|
-
By default, `tt install
|
|
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.
|
|
150
148
|
|
|
151
|
-
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
|
|
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.
|
|
152
150
|
|
|
153
151
|
## Human CLI
|
|
154
152
|
|
|
@@ -171,10 +169,8 @@ tt takeover [path] [--reason TEXT] # alias for take
|
|
|
171
169
|
tt notes add <body> [--turn N] [--path DIR] [--stdin] # leave an async note
|
|
172
170
|
tt notes list [--all] [--after ID] [--limit N] [--path DIR] # read notes
|
|
173
171
|
tt mcp # run the MCP stdio server
|
|
174
|
-
tt install <harness...> | --all [--print]
|
|
175
|
-
tt uninstall <harness...> | --all [--print] # remove MCP server
|
|
176
|
-
tt install-skill <harness...> | --all [--print] [--copy] [--link] # install global talking-stick skill
|
|
177
|
-
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
|
|
178
174
|
tt self-update [--print] [--manager npm|pnpm|yarn|bun] # update to the latest published tt
|
|
179
175
|
```
|
|
180
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 = {
|
|
11
|
-
|
|
12
|
+
const installOptions = {
|
|
13
|
+
link: resolveSkillInstallLinkMode(parsed),
|
|
14
|
+
skipMissing: true
|
|
15
|
+
};
|
|
12
16
|
if (dryRun) {
|
|
13
|
-
for (const action of
|
|
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(
|
|
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
|
|
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(
|
|
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);
|
package/dist/cli/output.js
CHANGED
|
@@ -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(", ")}
|
package/dist/cli/registry.js
CHANGED
|
@@ -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
|
{
|
package/dist/mcp-server.js
CHANGED
|
@@ -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.
|
|
30
|
+
version: "0.1.2"
|
|
31
31
|
});
|
|
32
32
|
server.registerTool("list_rooms", {
|
|
33
33
|
title: "List Rooms",
|
|
@@ -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
|
@@ -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
|
|
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
|
|
|
@@ -153,7 +153,7 @@ Example:
|
|
|
153
153
|
}
|
|
154
154
|
],
|
|
155
155
|
"open_questions": [
|
|
156
|
-
"Should install
|
|
156
|
+
"Should tt install default to copy or link for local development?"
|
|
157
157
|
]
|
|
158
158
|
}
|
|
159
159
|
```
|