tryharness 0.1.0 → 0.3.0

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.
Files changed (3) hide show
  1. package/README.md +7 -4
  2. package/cli.mjs +22 -7
  3. package/package.json +11 -5
package/README.md CHANGED
@@ -7,13 +7,16 @@ npx tryharness
7
7
  ```
8
8
 
9
9
  Prints a short code — approve it in Harness (Settings, Connections, Connect a machine).
10
- Then it sets up everything it finds on this machine: memory access for your coding
11
- agents (Claude Code, Codex), automatic session sharing with a one-time history import,
12
- and the bridge that lets Harness send tasks to your agents (Claude Code, pi, opencode).
10
+ Then it sets up everything it finds on this machine: memory access, automatic sharing
11
+ for new sessions, accurate connection status, and task delegation for Claude Code,
12
+ Codex, pi, and opencode. Setup does not import old history, so it finishes quickly.
13
13
 
14
14
  Other commands: `npx tryharness bridge` (start the task bridge again),
15
- `npx tryharness backfill` (re-import recent Claude Code sessions),
15
+ `npx tryharness sync --agent all` (explicitly import existing sessions),
16
16
  `npx tryharness drain` (retry session reports that missed).
17
17
 
18
+ Use `npx tryharness --agent codex` (or another agent name) to connect only one
19
+ installed agent. Plain `npx tryharness` connects all detected agents.
20
+
18
21
  No tokens to copy: approval releases the credential directly to the waiting command.
19
22
  Everything your agents share stays between your machine and your browser.
package/cli.mjs CHANGED
@@ -1,20 +1,24 @@
1
1
  #!/usr/bin/env node
2
2
  // tryharness: thin bootstrap. The real logic lives on the Harness server and is fetched
3
3
  // fresh on every run, so this package never needs republishing to pick up improvements
4
- // (a cached copy in ~/.harness runs when offline). Commands:
4
+ // (a cached copy in ~/.harness runs when offline). Works on Node 18+ — when the runtime
5
+ // lacks a built-in WebSocket (added in Node 22), the bundled `ws` package fills it in,
6
+ // which is why scripts run IN-PROCESS here instead of being spawned. Commands:
5
7
  // npx tryharness pair this machine + set up every detected agent
8
+ // npx tryharness --agent codex set up only one detected agent
6
9
  // npx tryharness bridge start the task bridge (after pairing)
7
- // npx tryharness backfill re-import recent Claude Code sessions
10
+ // npx tryharness sync explicitly import existing agent sessions
8
11
  // npx tryharness drain retry any session reports that missed
9
12
  import fs from "node:fs";
10
13
  import path from "node:path";
11
14
  import os from "node:os";
12
- import { spawn } from "node:child_process";
15
+ import { pathToFileURL } from "node:url";
13
16
 
14
17
  const HARNESS_DIR = path.join(os.homedir(), ".harness");
15
18
  const COMMANDS = {
16
19
  connect: { file: "connect.mjs", args: [] },
17
20
  bridge: { file: "bridge.mjs", args: [] },
21
+ sync: { file: "report-session.mjs", args: ["--backfill"] },
18
22
  backfill: { file: "report-session.mjs", args: ["--backfill"] },
19
23
  drain: { file: "report-session.mjs", args: ["--drain"] },
20
24
  };
@@ -23,7 +27,7 @@ const argv = process.argv.slice(2);
23
27
  const sub = argv[0] && !argv[0].startsWith("-") ? argv.shift() : "connect";
24
28
  const command = COMMANDS[sub];
25
29
  if (!command) {
26
- console.error("unknown command: " + sub + " (try: connect | bridge | backfill | drain)");
30
+ console.error("unknown command: " + sub + " (try: connect | bridge | sync | drain)");
27
31
  process.exit(1);
28
32
  }
29
33
 
@@ -39,7 +43,9 @@ const origin = (originIndex !== -1 && argv[originIndex + 1] ? argv[originIndex +
39
43
  const dest = path.join(HARNESS_DIR, command.file);
40
44
  fs.mkdirSync(HARNESS_DIR, { recursive: true });
41
45
  try {
42
- const res = await fetch(origin + "/" + command.file);
46
+ // 15s cap: a fetch that dials the server mid-restart can otherwise hang forever
47
+ // with zero output. On timeout the cached copy runs, same as any other fetch failure.
48
+ const res = await fetch(origin + "/" + command.file, { signal: AbortSignal.timeout(15000) });
43
49
  if (!res.ok) throw new Error("HTTP " + res.status);
44
50
  fs.writeFileSync(dest, await res.text());
45
51
  } catch (error) {
@@ -50,5 +56,14 @@ try {
50
56
  console.error("could not refresh from " + origin + " - running the cached copy");
51
57
  }
52
58
 
53
- const child = spawn(process.execPath, [dest, ...command.args, ...argv], { stdio: "inherit" });
54
- child.on("close", (code) => process.exit(code ?? 0));
59
+ // Older LTS Node (18/20): provide WebSocket from the bundled `ws` package so the bridge
60
+ // works everywhere npx does.
61
+ if (typeof globalThis.WebSocket === "undefined") {
62
+ const { WebSocket } = await import("ws");
63
+ globalThis.WebSocket = WebSocket;
64
+ }
65
+
66
+ // Run the script in-process (so the polyfill above applies), with argv shaped exactly
67
+ // as a direct `node <script> <args>` run would see it.
68
+ process.argv = [process.argv[0], dest, ...command.args, ...argv];
69
+ await import(pathToFileURL(dest).href);
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "tryharness",
3
- "version": "0.1.0",
4
- "description": "Connect this machine to Harness: pair with a code, link your coding agents (Claude Code, Codex, opencode, pi), share session history, and accept delegated tasks.",
3
+ "version": "0.3.0",
4
+ "description": "Connect Claude Code, Codex, opencode, and pi to Harness memory, session history, status, and delegated tasks.",
5
5
  "bin": {
6
6
  "tryharness": "cli.mjs"
7
7
  },
8
8
  "type": "module",
9
9
  "engines": {
10
- "node": ">=20"
10
+ "node": ">=18"
11
11
  },
12
12
  "files": [
13
13
  "cli.mjs",
@@ -16,8 +16,14 @@
16
16
  "keywords": [
17
17
  "harness",
18
18
  "coding-agents",
19
- "claude-code"
19
+ "claude-code",
20
+ "codex",
21
+ "opencode",
22
+ "pi"
20
23
  ],
21
24
  "homepage": "https://tryharness.ai",
22
- "license": "MIT"
25
+ "license": "MIT",
26
+ "dependencies": {
27
+ "ws": "^8.18.0"
28
+ }
23
29
  }