coordigent 0.1.0 → 0.1.3

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Coordigent, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,26 +1,54 @@
1
1
  # Coordigent npm launcher
2
2
 
3
- Runs Coordigent's `coord` CLI from npm:
3
+ Coordigent's `coord` CLI and `coord-mcp` MCP server, from npm:
4
4
 
5
5
  ```sh
6
- npx coordigent connect # once, or:
7
- npm i -g coordigent && coordigent connect
6
+ npm i -g coordigent
7
+ coord connect
8
8
  ```
9
9
 
10
- (Not on npm yet: `package.json` stays `"private": true` until the trusted publisher is set up;
11
- see [Publishing](#publishing).)
10
+ `npm i -g coordigent` puts three commands on `PATH`: `coord` runs `coord`, `coord-mcp` runs
11
+ `coord-mcp`, and `coordigent` runs `coord` (or `coord-mcp` with `mcp` first, below). So every
12
+ `coord …` command in the docs works as written. Without installing: `npx coordigent connect`.
13
+
14
+ As an MCP server (stdio), for any MCP client, and the npm entry of the
15
+ [MCP Registry listing](../../docs/operations.md#mcp-registry):
16
+
17
+ ```json
18
+ { "mcpServers": { "coordigent": { "command": "npx", "args": ["-y", "coordigent", "mcp"] } } }
19
+ ```
20
+
21
+ `coord-mcp [args]`, and `coordigent mcp [args]`, run `coord-mcp [args]` after the same first-run
22
+ download and checks. Everything the launcher prints goes to stderr, so stdout stays the MCP
23
+ channel. `coord-mcp` reads the login from `~/.tower/config.json` (`npx coordigent login`) and the
24
+ repo from the folder it starts in, or `COORDIGENT_REPO`.
12
25
 
13
26
  The package holds one Node file and no binaries. On first run it downloads `coord` and
14
27
  `coord-mcp` for this machine from the server's `/install/<artifact>`, checks each against the
15
28
  SHA-256 published in `/install/version`, and puts them where the installers do. After that, and on
16
- every later run, it runs `coord` with the same arguments and exits with its exit code. Because the
29
+ every later run, it runs `coord` (or `coord-mcp`) with the same arguments and exits with its exit
30
+ code. Because the
17
31
  binaries live where `install.sh` puts them, `coord update` and every MCP config keep working
18
32
  unchanged.
19
33
 
20
34
  - **Platforms:** macOS arm64 and x64 (an x64 Node under Rosetta gets the arm64 build), glibc Linux
21
35
  x64 and arm64, Windows x64. Anything else, and Alpine/musl, exits 1 before downloading.
22
36
  - **Where:** `~/.tower/bin`, or `%LOCALAPPDATA%\Coordigent\bin` on Windows (as `install.ps1`).
23
- `TOWER_BIN_DIR` overrides both. The directory is not added to `PATH`; `coordigent <command>` is.
37
+ `TOWER_BIN_DIR` overrides both. The launcher never edits `PATH`: npm's global bin folder, already
38
+ on it, holds the `coord`, `coord-mcp` and `coordigent` commands, which run the binaries there.
39
+ - **Which bin runs what:** each bin is its own file: `bin/coord.js` always runs `coord`,
40
+ `bin/coord-mcp.js` always runs `coord-mcp`, and `bin/coordigent.js` (the launcher itself) reads
41
+ `mcp` from its first argument. Not one file checking the name it was run as: on Windows npm's
42
+ `.cmd` shim runs `node <bin file>`, so the file is all that says which command was typed.
43
+ - **Next to `install.sh`:** a `coord` from the installer (`~/.tower/bin`) and one from npm can
44
+ both be on `PATH`. Whichever comes first starts, and both run the same `~/.tower/bin/coord`, so
45
+ it does not matter which. An npm global prefix of `~/.tower` would link npm's `coord` into the
46
+ folder the binaries go in; the launcher refuses that with a message rather than run itself.
47
+ - **Updating and removing:** `coord update` updates the binaries, as for any install;
48
+ `npm update -g coordigent` updates only this launcher. To remove everything, `coord uninstall`
49
+ first (binaries, hooks, `~/.tower`), then `npm rm -g coordigent`. Removing only the package
50
+ leaves the binaries in place, and running npm's `coord` after `coord uninstall` downloads them
51
+ again.
24
52
  - **Which server:** `COORDIGENT_SERVER_URL`, then `TOWER_SERVER_URL`, then the `serverUrl` saved in
25
53
  `~/.tower/config.json`, then `https://coordigent.com`: the order `coord` itself uses. A machine
26
54
  with no config yet gets one naming that server, with no token, as `install.sh` writes.
@@ -36,8 +64,11 @@ unchanged.
36
64
 
37
65
  Tests: `bun test packaging/npm` from the repo root (a local fake server stands in for
38
66
  `/install`). CI runs `npm pack --dry-run` on it (`.github/workflows/ci.yml`, job `npm-package`)
39
- and fails if the tarball holds anything but `bin/coordigent.js`, `README.md` and `package.json`,
40
- or gains an install-time script. Both that check and the release checks are
67
+ and fails if the tarball holds anything but `bin/coordigent.js`, `bin/coord.js`, `bin/coord-mcp.js`,
68
+ `LICENSE` (MIT), `README.md` and `package.json`, if `bin` does not map `coord`, `coord-mcp` and
69
+ `coordigent` to those three files, if any of them is not executable, or if it gains an
70
+ install-time script. The tests also pack the package and `npm i -g` the tarball into a scratch
71
+ prefix, then run each linked command. Both that check and the release checks are
41
72
  `scripts/release-checks.js`, which is not shipped.
42
73
 
43
74
  ## Publishing
@@ -45,11 +76,13 @@ or gains an install-time script. Both that check and the release checks are
45
76
  `.github/workflows/publish-npm.yml` publishes on a tag `npm-v<version>` (the `v*` tags publish the
46
77
  container image and never touch npm), or by hand from Actions with an existing tag. It uses npm
47
78
  trusted publishing: no `NPM_TOKEN`; npm trades the job's GitHub OIDC token for a one-time
48
- credential, and `npm publish --provenance --access public` attaches a provenance statement. Before
79
+ credential, and `npm publish --access public` publishes it (no provenance: npm only attests public source repos, and this repo is private). Before
49
80
  publishing, `scripts/release-checks.js release <tag>` refuses, with the reason, when:
50
81
 
51
82
  - the tag is not exactly `npm-v` plus `package.json`'s `version`;
52
83
  - the name is not `coordigent`;
84
+ - `mcpName` is not `com.coordigent/coordigent`, which the MCP Registry reads from the published
85
+ version to accept the listing's npm entry;
53
86
  - `package.json` still has `"private": true`. It stays until the steps below are done, so
54
87
  until then every run of the workflow fails at that check and publishes nothing.
55
88
 
@@ -73,4 +106,6 @@ publishing, `scripts/release-checks.js release <tag>` refuses, with the reason,
73
106
  `git tag npm-v<version> <commit> && git push origin npm-v<version>`. The workflow publishes;
74
107
  the version page on npmjs.com then shows its provenance, linked to that run.
75
108
 
76
- Each later release: bump `version` in a PR, merge, push `npm-v<version>`.
109
+ Each later release: bump `version` in a PR, merge, push `npm-v<version>`. Bump `version` and
110
+ `packages[0].version` in the root `server.json` in the same PR (a test holds them equal), and
111
+ after npm has published, publish the listing (docs/operations.md, "MCP Registry").
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ // `coord-mcp <args>` after `npm i -g coordigent`: the launcher, always running coord-mcp, the
3
+ // stdio MCP server (bin/coordigent.js). Nothing but coord-mcp writes to stdout.
4
+ "use strict";
5
+
6
+ require("./coordigent.js").main(process.argv.slice(2), process.env, "coord-mcp");
package/bin/coord.js ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ // `coord <args>` after `npm i -g coordigent`: the launcher, always running coord
3
+ // (bin/coordigent.js). Everything is passed through, `mcp` included.
4
+ "use strict";
5
+
6
+ require("./coordigent.js").main(process.argv.slice(2), process.env, "coord");
package/bin/coordigent.js CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
- // The npm launcher: `npx coordigent <args>` or `npm i -g` and `coordigent <args>`.
2
+ // The npm launcher: `npx coordigent <args>`, or after `npm i -g coordigent`, `coord <args>`,
3
+ // `coord-mcp <args>` and `coordigent <args>`.
3
4
  //
4
5
  // It ships no binaries. On first run it downloads coord and coord-mcp for this
5
6
  // machine from the server's /install/<artifact>, checks each against the SHA-256
@@ -8,18 +9,29 @@
8
9
  // and on every later run, it runs `coord <args>`. Because the binaries live where
9
10
  // the installers put them, `coord update` and every MCP config keep working.
10
11
  //
12
+ // `coordigent mcp [args]` runs coord-mcp instead: the stdio MCP server, for an MCP
13
+ // client configured with `npx -y coordigent mcp` (the MCP Registry's npm entry,
14
+ // server.json). Its stdout is the MCP channel, so the launcher writes only to stderr.
15
+ //
16
+ // The package's `coord` and `coord-mcp` bins are bin/coord.js and bin/coord-mcp.js, which
17
+ // call main() here with the binary fixed. Separate files, not a check of the name this was
18
+ // invoked as: on Windows npm's .cmd shim runs `node <bin file>`, so the file is all that
19
+ // says which command was typed.
20
+ //
11
21
  // Plain Node with no dependencies and no install scripts: the download happens at
12
22
  // run time, so `npm i --ignore-scripts` installs a working launcher.
13
23
  "use strict";
14
24
 
15
25
  const { spawn, execFileSync } = require("node:child_process");
16
26
  const { createHash } = require("node:crypto");
17
- const { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } = require("node:fs");
18
27
  const { homedir } = require("node:os");
19
- const { join } = require("node:path");
28
+ const { chmodSync, existsSync, mkdirSync, readFileSync, realpathSync, renameSync, writeFileSync } = require("node:fs");
29
+ const { join, dirname } = require("node:path");
20
30
 
21
31
  const HOSTED_SERVER_URL = "https://coordigent.com";
22
32
  const BINARIES = ["coord", "coord-mcp"];
33
+ /** The first argument that runs coord-mcp rather than coord. coord has no `mcp` command. */
34
+ const MCP_MODE = "mcp";
23
35
 
24
36
  /** A failure the person can act on: printed as one message, exit 1, no stack. */
25
37
  class LauncherError extends Error {}
@@ -133,7 +145,7 @@ function downloadFailure(response, url, platform) {
133
145
  return new LauncherError(`could not download ${url}\nWindows build not available yet.`);
134
146
  }
135
147
  return new LauncherError(
136
- `could not download ${url} (HTTP ${response.status})\nThe server may not be publishing binaries. See docs/operations.md.`
148
+ `could not download ${url} (HTTP ${response.status})\nThe server may not be publishing binaries. See https://coordigent.com/docs/get-started/install.`
137
149
  );
138
150
  }
139
151
 
@@ -187,13 +199,36 @@ function rememberServer(env, server) {
187
199
  writeFileSync(config, `{\n "serverUrl": "${server}"\n}\n`, { mode: 0o600, flag: "wx" });
188
200
  }
189
201
 
190
- function run(coord, args) {
191
- const child = spawn(coord, args, { stdio: "inherit" });
202
+ /**
203
+ * Which binary to run, and what to pass it. The `coord` and `coord-mcp` bins fix the binary and
204
+ * pass every argument through. `coordigent` reads it from the arguments: `mcp …` is coord-mcp,
205
+ * anything else coord.
206
+ */
207
+ function resolveCommand(args, fixed) {
208
+ if (BINARIES.includes(fixed)) return { name: fixed, args };
209
+ return args[0] === MCP_MODE ? { name: "coord-mcp", args: args.slice(1) } : { name: "coord", args };
210
+ }
211
+
212
+ /**
213
+ * True when `target` is one of this package's own bins rather than a binary: what npm leaves in
214
+ * ~/.tower/bin when its global prefix is ~/.tower. Running it would start this launcher again,
215
+ * forever.
216
+ */
217
+ function isLauncherItself(target) {
218
+ try {
219
+ return dirname(realpathSync(target)) === realpathSync(__dirname);
220
+ } catch {
221
+ return false;
222
+ }
223
+ }
224
+
225
+ function run(binary, args) {
226
+ const child = spawn(binary, args, { stdio: "inherit" });
192
227
  // Ctrl-C reaches coord from the terminal already; stay alive until it exits.
193
228
  process.on("SIGINT", () => {});
194
229
  for (const signal of ["SIGTERM", "SIGHUP"]) process.on(signal, () => child.kill(signal));
195
230
  child.on("error", (error) => {
196
- process.stderr.write(`coordigent: could not run ${coord}: ${error.message}\n`);
231
+ process.stderr.write(`coordigent: could not run ${binary}: ${error.message}\n`);
197
232
  process.exit(1);
198
233
  });
199
234
  child.on("exit", (code, signal) => {
@@ -205,14 +240,22 @@ function run(coord, args) {
205
240
  });
206
241
  }
207
242
 
208
- async function main(args = process.argv.slice(2), env = process.env) {
243
+ /** `fixed` is "coord" or "coord-mcp" from those bins; absent for `coordigent`. */
244
+ async function main(args = process.argv.slice(2), env = process.env, fixed = undefined) {
209
245
  const log = (line) => process.stderr.write(`${line}\n`);
210
246
  try {
211
247
  const binDir = resolveBinDir(env);
212
248
  // The platform is resolved before anything is fetched or written, like install.sh.
213
249
  const platform = resolvePlatform();
214
250
  const suffix = exeSuffix(platform);
215
- const coord = join(binDir, `coord${suffix}`);
251
+ const command = resolveCommand(args, fixed);
252
+ const binary = join(binDir, `${command.name}${suffix}`);
253
+ if (isLauncherItself(binary)) {
254
+ throw new LauncherError(
255
+ `${binary} is this npm launcher, not the ${command.name} binary: npm's global prefix is the folder\n` +
256
+ "the binaries go in. Install with another npm prefix, or set TOWER_BIN_DIR to another folder."
257
+ );
258
+ }
216
259
  if (!BINARIES.every((name) => existsSync(join(binDir, `${name}${suffix}`)))) {
217
260
  const server = resolveServer(env);
218
261
  await install({ server, binDir, platform, fetchImpl: fetch, log });
@@ -222,7 +265,7 @@ async function main(args = process.argv.slice(2), env = process.env) {
222
265
  // Optional, as in install.sh: coord login records the server too.
223
266
  }
224
267
  }
225
- run(coord, args);
268
+ run(binary, command.args);
226
269
  } catch (error) {
227
270
  if (!(error instanceof LauncherError)) throw error;
228
271
  log(`coordigent: ${error.message}`);
@@ -230,6 +273,6 @@ async function main(args = process.argv.slice(2), env = process.env) {
230
273
  }
231
274
  }
232
275
 
233
- module.exports = { resolvePlatform, resolveServer, resolveBinDir };
276
+ module.exports = { main, resolvePlatform, resolveServer, resolveBinDir, resolveCommand };
234
277
 
235
278
  if (require.main === module) main();
package/package.json CHANGED
@@ -1,17 +1,34 @@
1
1
  {
2
2
  "name": "coordigent",
3
- "version": "0.1.0",
4
- "description": "Runs Coordigent's coord CLI: downloads the coord and coord-mcp binaries for this machine on first run, checks their SHA-256, and runs coord.",
3
+ "version": "0.1.3",
4
+ "description": "Coordigent's coord and coord-mcp commands: downloads the binaries for this machine on first run, checks their SHA-256, and runs them. `npx coordigent` and `npx coordigent mcp` work too.",
5
5
  "homepage": "https://coordigent.com",
6
+ "license": "MIT",
7
+ "mcpName": "com.coordigent/coordigent",
8
+ "keywords": [
9
+ "mcp",
10
+ "mcp-server",
11
+ "coding-agents",
12
+ "multi-agent",
13
+ "claude-code",
14
+ "codex",
15
+ "cursor",
16
+ "coordination",
17
+ "developer-tools"
18
+ ],
6
19
  "repository": {
7
20
  "type": "git",
8
21
  "url": "git+https://github.com/startupproj/coordigent.git",
9
22
  "directory": "packaging/npm"
10
23
  },
11
24
  "bin": {
25
+ "coord": "bin/coord.js",
26
+ "coord-mcp": "bin/coord-mcp.js",
12
27
  "coordigent": "bin/coordigent.js"
13
28
  },
14
29
  "files": [
30
+ "bin/coord.js",
31
+ "bin/coord-mcp.js",
15
32
  "bin/coordigent.js"
16
33
  ],
17
34
  "engines": {