@tpsdev-ai/cli 0.2.0 → 0.3.1

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 (228) hide show
  1. package/README.md +65 -0
  2. package/bin/tps.cjs +24 -0
  3. package/bin/tps.ts +435 -0
  4. package/package.json +29 -5
  5. package/dist/bin/tps.d.ts +0 -3
  6. package/dist/bin/tps.d.ts.map +0 -1
  7. package/dist/bin/tps.js +0 -414
  8. package/dist/bin/tps.js.map +0 -1
  9. package/dist/src/cli/hire.d.ts +0 -16
  10. package/dist/src/cli/hire.d.ts.map +0 -1
  11. package/dist/src/cli/hire.js +0 -176
  12. package/dist/src/cli/hire.js.map +0 -1
  13. package/dist/src/cli/office.d.ts +0 -7
  14. package/dist/src/cli/office.d.ts.map +0 -1
  15. package/dist/src/cli/office.js +0 -51
  16. package/dist/src/cli/office.js.map +0 -1
  17. package/dist/src/cli/review.d.ts +0 -9
  18. package/dist/src/cli/review.d.ts.map +0 -1
  19. package/dist/src/cli/review.js +0 -109
  20. package/dist/src/cli/review.js.map +0 -1
  21. package/dist/src/cli/roster.d.ts +0 -6
  22. package/dist/src/cli/roster.d.ts.map +0 -1
  23. package/dist/src/cli/roster.js +0 -60
  24. package/dist/src/cli/roster.js.map +0 -1
  25. package/dist/src/commands/backup.d.ts +0 -19
  26. package/dist/src/commands/backup.d.ts.map +0 -1
  27. package/dist/src/commands/backup.js +0 -595
  28. package/dist/src/commands/backup.js.map +0 -1
  29. package/dist/src/commands/bootstrap.d.ts +0 -7
  30. package/dist/src/commands/bootstrap.d.ts.map +0 -1
  31. package/dist/src/commands/bootstrap.js +0 -255
  32. package/dist/src/commands/bootstrap.js.map +0 -1
  33. package/dist/src/commands/branch.d.ts +0 -14
  34. package/dist/src/commands/branch.d.ts.map +0 -1
  35. package/dist/src/commands/branch.js +0 -395
  36. package/dist/src/commands/branch.js.map +0 -1
  37. package/dist/src/commands/context.d.ts +0 -9
  38. package/dist/src/commands/context.d.ts.map +0 -1
  39. package/dist/src/commands/context.js +0 -57
  40. package/dist/src/commands/context.js.map +0 -1
  41. package/dist/src/commands/git.d.ts +0 -8
  42. package/dist/src/commands/git.d.ts.map +0 -1
  43. package/dist/src/commands/git.js +0 -53
  44. package/dist/src/commands/git.js.map +0 -1
  45. package/dist/src/commands/identity.d.ts +0 -13
  46. package/dist/src/commands/identity.d.ts.map +0 -1
  47. package/dist/src/commands/identity.js +0 -231
  48. package/dist/src/commands/identity.js.map +0 -1
  49. package/dist/src/commands/mail.d.ts +0 -12
  50. package/dist/src/commands/mail.d.ts.map +0 -1
  51. package/dist/src/commands/mail.js +0 -251
  52. package/dist/src/commands/mail.js.map +0 -1
  53. package/dist/src/commands/office-manager.d.ts +0 -147
  54. package/dist/src/commands/office-manager.d.ts.map +0 -1
  55. package/dist/src/commands/office-manager.js +0 -171
  56. package/dist/src/commands/office-manager.js.map +0 -1
  57. package/dist/src/commands/office.d.ts +0 -12
  58. package/dist/src/commands/office.d.ts.map +0 -1
  59. package/dist/src/commands/office.js +0 -480
  60. package/dist/src/commands/office.js.map +0 -1
  61. package/dist/src/commands/roster.d.ts +0 -10
  62. package/dist/src/commands/roster.d.ts.map +0 -1
  63. package/dist/src/commands/roster.js +0 -143
  64. package/dist/src/commands/roster.js.map +0 -1
  65. package/dist/src/commands/secrets.d.ts +0 -9
  66. package/dist/src/commands/secrets.d.ts.map +0 -1
  67. package/dist/src/commands/secrets.js +0 -54
  68. package/dist/src/commands/secrets.js.map +0 -1
  69. package/dist/src/commands/status.d.ts +0 -33
  70. package/dist/src/commands/status.d.ts.map +0 -1
  71. package/dist/src/commands/status.js +0 -407
  72. package/dist/src/commands/status.js.map +0 -1
  73. package/dist/src/generators/brief.d.ts +0 -6
  74. package/dist/src/generators/brief.d.ts.map +0 -1
  75. package/dist/src/generators/brief.js +0 -33
  76. package/dist/src/generators/brief.js.map +0 -1
  77. package/dist/src/generators/claude-code.d.ts +0 -18
  78. package/dist/src/generators/claude-code.d.ts.map +0 -1
  79. package/dist/src/generators/claude-code.js +0 -85
  80. package/dist/src/generators/claude-code.js.map +0 -1
  81. package/dist/src/generators/codex.d.ts +0 -23
  82. package/dist/src/generators/codex.d.ts.map +0 -1
  83. package/dist/src/generators/codex.js +0 -83
  84. package/dist/src/generators/codex.js.map +0 -1
  85. package/dist/src/generators/ollama.d.ts +0 -18
  86. package/dist/src/generators/ollama.d.ts.map +0 -1
  87. package/dist/src/generators/ollama.js +0 -97
  88. package/dist/src/generators/ollama.js.map +0 -1
  89. package/dist/src/generators/openclaw.d.ts +0 -15
  90. package/dist/src/generators/openclaw.d.ts.map +0 -1
  91. package/dist/src/generators/openclaw.js +0 -107
  92. package/dist/src/generators/openclaw.js.map +0 -1
  93. package/dist/src/generators/registry.d.ts +0 -36
  94. package/dist/src/generators/registry.d.ts.map +0 -1
  95. package/dist/src/generators/registry.js +0 -99
  96. package/dist/src/generators/registry.js.map +0 -1
  97. package/dist/src/schema/manifest.d.ts +0 -287
  98. package/dist/src/schema/manifest.d.ts.map +0 -1
  99. package/dist/src/schema/manifest.js +0 -65
  100. package/dist/src/schema/manifest.js.map +0 -1
  101. package/dist/src/schema/report.d.ts +0 -166
  102. package/dist/src/schema/report.d.ts.map +0 -1
  103. package/dist/src/schema/report.js +0 -90
  104. package/dist/src/schema/report.js.map +0 -1
  105. package/dist/src/schema/sanitizer.d.ts +0 -30
  106. package/dist/src/schema/sanitizer.d.ts.map +0 -1
  107. package/dist/src/schema/sanitizer.js +0 -99
  108. package/dist/src/schema/sanitizer.js.map +0 -1
  109. package/dist/src/soundstage/mock-llm.d.ts +0 -3
  110. package/dist/src/soundstage/mock-llm.d.ts.map +0 -1
  111. package/dist/src/soundstage/mock-llm.js +0 -68
  112. package/dist/src/soundstage/mock-llm.js.map +0 -1
  113. package/dist/src/utils/agent-info.d.ts +0 -28
  114. package/dist/src/utils/agent-info.d.ts.map +0 -1
  115. package/dist/src/utils/agent-info.js +0 -102
  116. package/dist/src/utils/agent-info.js.map +0 -1
  117. package/dist/src/utils/archive.d.ts +0 -20
  118. package/dist/src/utils/archive.d.ts.map +0 -1
  119. package/dist/src/utils/archive.js +0 -108
  120. package/dist/src/utils/archive.js.map +0 -1
  121. package/dist/src/utils/config-inject.d.ts +0 -27
  122. package/dist/src/utils/config-inject.d.ts.map +0 -1
  123. package/dist/src/utils/config-inject.js +0 -83
  124. package/dist/src/utils/config-inject.js.map +0 -1
  125. package/dist/src/utils/config.d.ts +0 -30
  126. package/dist/src/utils/config.d.ts.map +0 -1
  127. package/dist/src/utils/config.js +0 -55
  128. package/dist/src/utils/config.js.map +0 -1
  129. package/dist/src/utils/connection-state.d.ts +0 -27
  130. package/dist/src/utils/connection-state.d.ts.map +0 -1
  131. package/dist/src/utils/connection-state.js +0 -81
  132. package/dist/src/utils/connection-state.js.map +0 -1
  133. package/dist/src/utils/context.d.ts +0 -14
  134. package/dist/src/utils/context.d.ts.map +0 -1
  135. package/dist/src/utils/context.js +0 -68
  136. package/dist/src/utils/context.js.map +0 -1
  137. package/dist/src/utils/github-webhook.d.ts +0 -3
  138. package/dist/src/utils/github-webhook.d.ts.map +0 -1
  139. package/dist/src/utils/github-webhook.js +0 -105
  140. package/dist/src/utils/github-webhook.js.map +0 -1
  141. package/dist/src/utils/identity.d.ts +0 -124
  142. package/dist/src/utils/identity.d.ts.map +0 -1
  143. package/dist/src/utils/identity.js +0 -434
  144. package/dist/src/utils/identity.js.map +0 -1
  145. package/dist/src/utils/internal-mail.d.ts +0 -18
  146. package/dist/src/utils/internal-mail.d.ts.map +0 -1
  147. package/dist/src/utils/internal-mail.js +0 -75
  148. package/dist/src/utils/internal-mail.js.map +0 -1
  149. package/dist/src/utils/loop-detector.d.ts +0 -27
  150. package/dist/src/utils/loop-detector.d.ts.map +0 -1
  151. package/dist/src/utils/loop-detector.js +0 -42
  152. package/dist/src/utils/loop-detector.js.map +0 -1
  153. package/dist/src/utils/mail-handler.d.ts +0 -19
  154. package/dist/src/utils/mail-handler.d.ts.map +0 -1
  155. package/dist/src/utils/mail-handler.js +0 -94
  156. package/dist/src/utils/mail-handler.js.map +0 -1
  157. package/dist/src/utils/mail.d.ts +0 -22
  158. package/dist/src/utils/mail.d.ts.map +0 -1
  159. package/dist/src/utils/mail.js +0 -111
  160. package/dist/src/utils/mail.js.map +0 -1
  161. package/dist/src/utils/manifest.d.ts +0 -36
  162. package/dist/src/utils/manifest.d.ts.map +0 -1
  163. package/dist/src/utils/manifest.js +0 -94
  164. package/dist/src/utils/manifest.js.map +0 -1
  165. package/dist/src/utils/noise-ik-transport.d.ts +0 -18
  166. package/dist/src/utils/noise-ik-transport.d.ts.map +0 -1
  167. package/dist/src/utils/noise-ik-transport.js +0 -357
  168. package/dist/src/utils/noise-ik-transport.js.map +0 -1
  169. package/dist/src/utils/nono.d.ts +0 -72
  170. package/dist/src/utils/nono.d.ts.map +0 -1
  171. package/dist/src/utils/nono.js +0 -166
  172. package/dist/src/utils/nono.js.map +0 -1
  173. package/dist/src/utils/outbox.d.ts +0 -10
  174. package/dist/src/utils/outbox.d.ts.map +0 -1
  175. package/dist/src/utils/outbox.js +0 -29
  176. package/dist/src/utils/outbox.js.map +0 -1
  177. package/dist/src/utils/output.d.ts +0 -17
  178. package/dist/src/utils/output.d.ts.map +0 -1
  179. package/dist/src/utils/output.js +0 -83
  180. package/dist/src/utils/output.js.map +0 -1
  181. package/dist/src/utils/plain-tcp-transport.d.ts +0 -10
  182. package/dist/src/utils/plain-tcp-transport.d.ts.map +0 -1
  183. package/dist/src/utils/plain-tcp-transport.js +0 -209
  184. package/dist/src/utils/plain-tcp-transport.js.map +0 -1
  185. package/dist/src/utils/provision.d.ts +0 -2
  186. package/dist/src/utils/provision.d.ts.map +0 -1
  187. package/dist/src/utils/provision.js +0 -193
  188. package/dist/src/utils/provision.js.map +0 -1
  189. package/dist/src/utils/relay.d.ts +0 -30
  190. package/dist/src/utils/relay.d.ts.map +0 -1
  191. package/dist/src/utils/relay.js +0 -539
  192. package/dist/src/utils/relay.js.map +0 -1
  193. package/dist/src/utils/sandbox.d.ts +0 -37
  194. package/dist/src/utils/sandbox.d.ts.map +0 -1
  195. package/dist/src/utils/sandbox.js +0 -126
  196. package/dist/src/utils/sandbox.js.map +0 -1
  197. package/dist/src/utils/transport.d.ts +0 -62
  198. package/dist/src/utils/transport.d.ts.map +0 -1
  199. package/dist/src/utils/transport.js +0 -75
  200. package/dist/src/utils/transport.js.map +0 -1
  201. package/dist/src/utils/vault.d.ts +0 -21
  202. package/dist/src/utils/vault.d.ts.map +0 -1
  203. package/dist/src/utils/vault.js +0 -67
  204. package/dist/src/utils/vault.js.map +0 -1
  205. package/dist/src/utils/wall.d.ts +0 -5
  206. package/dist/src/utils/wall.d.ts.map +0 -1
  207. package/dist/src/utils/wall.js +0 -51
  208. package/dist/src/utils/wall.js.map +0 -1
  209. package/dist/src/utils/wire-delivery.d.ts +0 -10
  210. package/dist/src/utils/wire-delivery.d.ts.map +0 -1
  211. package/dist/src/utils/wire-delivery.js +0 -57
  212. package/dist/src/utils/wire-delivery.js.map +0 -1
  213. package/dist/src/utils/wire-frame.d.ts +0 -10
  214. package/dist/src/utils/wire-frame.d.ts.map +0 -1
  215. package/dist/src/utils/wire-frame.js +0 -66
  216. package/dist/src/utils/wire-frame.js.map +0 -1
  217. package/dist/src/utils/wire-mail.d.ts +0 -54
  218. package/dist/src/utils/wire-mail.d.ts.map +0 -1
  219. package/dist/src/utils/wire-mail.js +0 -24
  220. package/dist/src/utils/wire-mail.js.map +0 -1
  221. package/dist/src/utils/workspace.d.ts +0 -14
  222. package/dist/src/utils/workspace.d.ts.map +0 -1
  223. package/dist/src/utils/workspace.js +0 -53
  224. package/dist/src/utils/workspace.js.map +0 -1
  225. package/dist/src/utils/ws-noise-transport.d.ts +0 -18
  226. package/dist/src/utils/ws-noise-transport.d.ts.map +0 -1
  227. package/dist/src/utils/ws-noise-transport.js +0 -356
  228. package/dist/src/utils/ws-noise-transport.js.map +0 -1
package/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # @tpsdev-ai/cli
2
+
3
+ > TPS (Team Provisioning System) — an Agent OS CLI for managing isolated AI agents.
4
+
5
+ Hire agents, provision secure branch offices, manage identity and encrypted comms, track operational health — all from the command line.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install -g @tpsdev-ai/cli
11
+ ```
12
+
13
+ ## Commands
14
+
15
+ | Command | Description |
16
+ |---------|-------------|
17
+ | `tps hire <report>` | Onboard a new agent from a TPS report |
18
+ | `tps roster` | List all agents and their status |
19
+ | `tps bootstrap <agent>` | Run first-boot health checks and workspace scaffolding |
20
+ | `tps office setup` | Configure sandbox environment from workspace manifest |
21
+ | `tps backup <agent>` | Create encrypted, checksummed workspace backup |
22
+ | `tps restore <agent> <archive>` | Restore agent workspace with transactional rollback |
23
+ | `tps status` | Operational dashboard — health, uptime, cost tracking |
24
+ | `tps heartbeat <agent>` | Agent self-reports health (workspace, gateway, provider) |
25
+ | `tps identity init` | Generate Ed25519 host keypair |
26
+ | `tps branch init` | Initialize a remote branch office |
27
+ | `tps office join` | Join a branch to the head office via Noise_IK handshake |
28
+ | `tps office connect` | Establish persistent encrypted relay channel |
29
+ | `tps mail send` | Send async mail to a branch agent |
30
+ | `tps mail check` | Check for incoming mail |
31
+ | `tps secrets set/get` | Encrypted vault for API keys and credentials |
32
+
33
+ ## Architecture
34
+
35
+ TPS treats AI agents like employees in an organization:
36
+
37
+ - **Branch Offices** — isolated sandboxes (Docker, VMs, or `nono` process isolation)
38
+ - **The Mailroom** — async, persistent, cross-boundary messaging via Maildir
39
+ - **Wire Security** — Noise_IK protocol over WebSocket for E2E encrypted transport
40
+ - **Identity** — Ed25519 keypairs with signed join tokens
41
+
42
+ Agents communicate through three channels:
43
+ 1. **Mail** for messages (tasks, status, coordination)
44
+ 2. **Git** for artifacts (code, reports, generated files)
45
+ 3. **APIs** for external data
46
+
47
+ ## Security
48
+
49
+ - All inter-office traffic is E2E encrypted (Noise_IK + MessagePack)
50
+ - Sandbox profiles enforce filesystem, network, and exec boundaries
51
+ - Encrypted secrets vault (Argon2id key derivation)
52
+ - Audit trail with append-only logging and search
53
+ - Path traversal protection on all user-supplied identifiers
54
+
55
+ See [SECURITY.md](https://github.com/tpsdev-ai/cli/blob/main/SECURITY.md) for responsible disclosure.
56
+
57
+ ## Links
58
+
59
+ - [GitHub](https://github.com/tpsdev-ai/cli)
60
+ - [Runtime Library](https://www.npmjs.com/package/@tpsdev-ai/agent)
61
+ - [Contributing](https://github.com/tpsdev-ai/cli/blob/main/CONTRIBUTING.md)
62
+
63
+ ## License
64
+
65
+ Apache-2.0
package/bin/tps.cjs ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { execFileSync } = require('child_process');
4
+
5
+ const platform = process.platform;
6
+ const arch = process.arch;
7
+ const pkg = `@tpsdev-ai/cli-${platform}-${arch}`;
8
+
9
+ function runBinary() {
10
+ try {
11
+ const path = require('path');
12
+ const pkgJson = require.resolve(`${pkg}/package.json`);
13
+ const binPath = path.join(path.dirname(pkgJson), 'tps');
14
+ execFileSync(binPath, process.argv.slice(2), { stdio: 'inherit' });
15
+ return;
16
+ } catch (err) {
17
+ console.error(`TPS: no binary package available for ${platform}-${arch}.`);
18
+ console.error(`Run npm install -g ${pkg} to install the platform binary package.`);
19
+ console.error('Or run from source inside the repository via `bun run tps` in packages/cli.');
20
+ process.exitCode = 1;
21
+ }
22
+ }
23
+
24
+ runBinary();
package/bin/tps.ts ADDED
@@ -0,0 +1,435 @@
1
+ #!/usr/bin/env node
2
+ import meow from "meow";
3
+
4
+ const cli = meow(
5
+ `
6
+ Usage
7
+ $ tps <command> [options]
8
+
9
+ Commands
10
+ hire <report> Onboard a new agent from a .tps report or persona
11
+ roster <action> Agent directory (list/show/find)
12
+ review <name> Performance review for a specific agent
13
+ office <action> Branch office sandbox lifecycle (start/stop/list/status/kill)
14
+ bootstrap <agent-id> Bring a hired agent to operational state
15
+ backup <agent-id> [--schedule daily|off] [--keep n] [--sanitize] Backup agent workspace
16
+ restore <agent-id> <archive> [--clone] [--overwrite] [--from <archive>] Restore agent workspace from a backup
17
+ status [agent-id] [--auto-prune] [--prune] [--json] [--cost] [--shared]
18
+ heartbeat <agent-id> [--nonono] Send a heartbeat/ping for an agent
19
+ context <action> Workstream context memory (read/update/list)
20
+ mail <action> Mailroom operations (send/check/list/search)
21
+ identity <action> Key management (init/show/register/list/revoke/verify)
22
+ secrets <action> Secret management (set/list/remove)
23
+ git <action> Git utilities (worktree)
24
+ branch <action> Branch office node (init/start/stop/status/log)
25
+
26
+ Options
27
+ --help Show this help text
28
+ --version Show version number
29
+ --config <path> Path to openclaw.json (default: auto-discover)
30
+
31
+ Examples
32
+ $ tps hire developer --name Fred
33
+ $ tps hire ./reports/strategy-lead.tps --dry-run
34
+ $ tps hire developer --name Scout --runtime claude-code
35
+ $ tps hire ops --name Monitor --runtime ollama --base-model llama3.1:8b
36
+ $ tps hire developer --name Coder --runtime codex
37
+ $ tps roster list
38
+ $ tps roster show flint --json
39
+ $ tps roster find --channel discord
40
+ $ tps roster list --config ~/custom/openclaw.json
41
+ $ tps mail send kern "hi"
42
+ $ tps mail check kern
43
+ $ tps mail log --limit 10
44
+ $ tps mail log flint --since 2026-02-20
45
+ $ tps office start branch-a
46
+ $ tps office status branch-a
47
+ $ tps bootstrap flint
48
+ $ tps backup flint --schedule daily
49
+ $ tps restore flint ~/.tps/backups/flint/old.tps-backup.tar.gz
50
+ $ tps status
51
+ $ tps status flint --cost
52
+ $ tps heartbeat flint
53
+ $ tps review flint
54
+
55
+ Built-in personas: developer, designer, support, ea, ops, strategy, security
56
+
57
+ If you could just go ahead and use the correct command, that'd be great.
58
+ `,
59
+ {
60
+ importMeta: import.meta,
61
+ flags: {
62
+ reason: { type: "string" },
63
+ expiresIn: { type: "string" },
64
+ trust: { type: "string" },
65
+ pubkey: { type: "string" },
66
+ encPubkey: { type: "string" },
67
+ name: { type: "string" },
68
+ workspace: { type: "string" },
69
+ dryRun: { type: "boolean", default: false },
70
+ json: { type: "boolean", default: false },
71
+ config: { type: "string" },
72
+ deep: { type: "boolean", default: false },
73
+ summary: { type: "string" },
74
+ channel: { type: "string" },
75
+ branch: { type: "boolean", default: false },
76
+ manifest: { type: "string" },
77
+ soundstage: { type: "boolean", default: false },
78
+ nonono: { type: "boolean", default: false },
79
+ inject: { type: "boolean", default: true },
80
+ runtime: { type: "string", default: "openclaw" },
81
+ baseModel: { type: "string" },
82
+ since: { type: "string" },
83
+ limit: { type: "number" },
84
+ from: { type: "string" },
85
+ clone: { type: "boolean", default: false },
86
+ overwrite: { type: "boolean", default: false },
87
+ schedule: { type: "string" },
88
+ keep: { type: "number" },
89
+ sanitize: { type: "boolean", default: true },
90
+ listen: { type: "number" },
91
+ host: { type: "string" },
92
+ force: { type: "boolean", default: false },
93
+ follow: { type: "boolean", default: false },
94
+ lines: { type: "number" },
95
+ transport: { type: "string" },
96
+ autoPrune: { type: "boolean", default: false },
97
+ prune: { type: "boolean", default: false },
98
+ staleMinutes: { type: "number" },
99
+ offlineHours: { type: "number" },
100
+ shared: { type: "boolean", default: false },
101
+ cost: { type: "boolean", default: false },
102
+ statusOverride: { type: "string" },
103
+ },
104
+ }
105
+ );
106
+
107
+ const [command, ...rest] = cli.input;
108
+
109
+ // nono availability check (skip for --no-nono or office/mail relay commands)
110
+ async function checkNono() {
111
+ if (cli.flags.nonono) return;
112
+ if (command === "office" && rest[0] === "relay") return; // relay runs in background
113
+ const { findNono } = await import("../src/utils/nono.js");
114
+ if (!findNono()) {
115
+ console.warn(
116
+ "⚠️ nono not found. Host agents will run without process isolation.\n" +
117
+ " Install nono for syscall filtering + filesystem boundaries.\n" +
118
+ " Use --nonono to run anyway (not recommended).\n"
119
+ );
120
+ }
121
+ }
122
+
123
+ async function main() {
124
+ await checkNono();
125
+ switch (command) {
126
+ case "hire": {
127
+ const reportPath = rest[0];
128
+ if (!reportPath) {
129
+ console.error(
130
+ "I'm gonna need you to specify a TPS report file or persona.\n\n tps hire <report.tps | persona> [--name Name]\n\nBuilt-in personas: developer, designer, support, ea, ops, strategy"
131
+ );
132
+ process.exit(1);
133
+ }
134
+ const { runHire } = await import("../src/cli/hire.js");
135
+ runHire({
136
+ reportPath,
137
+ name: cli.flags.name,
138
+ workspace: cli.flags.workspace,
139
+ dryRun: cli.flags.dryRun,
140
+ jsonOutput: cli.flags.json,
141
+ configPath: cli.flags.config,
142
+ branch: cli.flags.branch,
143
+ inject: cli.flags.inject,
144
+ runtime: cli.flags.runtime as any,
145
+ baseModel: cli.flags.baseModel,
146
+ });
147
+ break;
148
+ }
149
+ case "roster": {
150
+ // Backward-compatible path (keeps nono re-exec behavior used by existing tests):
151
+ // `tps roster` with no subcommand routes to the legacy CLI implementation.
152
+ if (!rest[0]) {
153
+ const { runRoster } = await import("../src/cli/roster.js");
154
+ runRoster({ configPath: cli.flags.config });
155
+ break;
156
+ }
157
+
158
+ const action = rest[0] as "list" | "show" | "find";
159
+ if (!["list", "show", "find"].includes(action)) {
160
+ console.error(
161
+ "Usage:\n tps roster\n tps roster list\n tps roster show <agent> [--json]\n tps roster find --channel <channel> [--json]"
162
+ );
163
+ process.exit(1);
164
+ }
165
+ const { runRoster } = await import("../src/commands/roster.js");
166
+ runRoster({
167
+ action,
168
+ agent: rest[1],
169
+ channel: cli.flags.channel || undefined,
170
+ json: cli.flags.json,
171
+ configPath: cli.flags.config,
172
+ });
173
+ break;
174
+ }
175
+ case "review": {
176
+ const agentName = rest[0];
177
+ if (!agentName) {
178
+ console.error(
179
+ "Review who? I'm gonna need a name.\n\n tps review <agent-name>"
180
+ );
181
+ process.exit(1);
182
+ }
183
+ const { runReview } = await import("../src/cli/review.js");
184
+ runReview({ agentName, configPath: cli.flags.config, deep: cli.flags.deep });
185
+ break;
186
+ }
187
+ case "bootstrap": {
188
+ const agentId = rest[0];
189
+ if (!agentId) {
190
+ console.error("Usage: tps bootstrap <agent-id>");
191
+ process.exit(1);
192
+ }
193
+
194
+ const { runBootstrap } = await import("../src/commands/bootstrap.js");
195
+ await runBootstrap({
196
+ agentId,
197
+ configPath: cli.flags.config,
198
+ channel: cli.flags.channel,
199
+ });
200
+ break;
201
+ }
202
+
203
+ case "office": {
204
+ const action = rest[0] as "start" | "stop" | "list" | "status" | "relay" | "exec" | "join" | "revoke" | "sync" | "connect" | "kill" | "setup" | undefined;
205
+ const validActions = ["start", "stop", "list", "status", "relay", "exec", "join", "revoke", "sync", "connect", "kill", "setup"];
206
+ // Backward compatibility: `tps office <agent>` maps to `start <agent>`.
207
+ const isLegacy = action && !validActions.includes(action);
208
+ if ((!action && !isLegacy) || (!isLegacy && !validActions.includes(action!))) {
209
+ console.error(
210
+ "Usage:\n tps office start <agent>\n tps office stop <agent>\n tps office list\n tps office status [agent]\n tps office exec <agent> -- <command...>\n tps office join <name> <join-token>\n tps office revoke <name>\n tps office sync <name>\n tps office connect <name>\n tps office setup <agent> [--dry-run]\n tps office kill"
211
+ );
212
+ process.exit(1);
213
+ }
214
+
215
+ const { runOffice } = await import("../src/commands/office.js");
216
+ if (isLegacy) {
217
+ await runOffice({ action: "start", agent: rest[0] });
218
+ } else if (action === "exec") {
219
+ // Everything after "--" is the command
220
+ const dashIdx = process.argv.indexOf("--");
221
+ const execCmd = dashIdx >= 0 ? process.argv.slice(dashIdx + 1) : rest.slice(2);
222
+ await runOffice({ action: "exec", agent: rest[1], command: execCmd });
223
+ } else if (action === "join") {
224
+ const joinToken = rest[2];
225
+ if (!rest[1] || !joinToken) {
226
+ console.error("Usage: tps office join <name> <join-token-url>");
227
+ process.exit(1);
228
+ }
229
+ await runOffice({ action: "join", agent: rest[1], joinToken });
230
+ } else if (action === "revoke") {
231
+ if (!rest[1]) {
232
+ console.error("Usage: tps office revoke <name>");
233
+ process.exit(1);
234
+ }
235
+ await runOffice({ action: "revoke", agent: rest[1] });
236
+ } else if (action === "setup") {
237
+ const dryRun = process.argv.includes("--dry-run") || process.argv.includes("--dry");
238
+ await runOffice({ action: "setup", agent: rest[1], dryRun });
239
+ } else {
240
+ const soundstageIdx = process.argv.indexOf("--soundstage");
241
+ const isSoundstage = soundstageIdx >= 0 || cli.flags.soundstage;
242
+ if (soundstageIdx >= 0) process.argv.splice(soundstageIdx, 1);
243
+
244
+ await runOffice({ action: action!, agent: rest[1], manifest: cli.flags.manifest, soundstage: isSoundstage });
245
+ }
246
+ break;
247
+ }
248
+ case "context": {
249
+ const action = rest[0] as "read" | "update" | "list" | undefined;
250
+ const workstream = rest[1];
251
+ if (!action || !["read", "update", "list"].includes(action)) {
252
+ console.error(
253
+ "Usage:\n tps context read <workstream>\n tps context update <workstream> --summary \"...\"\n tps context list"
254
+ );
255
+ process.exit(1);
256
+ }
257
+ const { runContext } = await import("../src/commands/context.js");
258
+ runContext({
259
+ action,
260
+ workstream,
261
+ summary: cli.flags.summary,
262
+ json: cli.flags.json,
263
+ });
264
+ break;
265
+ }
266
+ case "mail": {
267
+ const action = rest[0] as "send" | "check" | "list" | "log" | "read" | "watch" | "search" | undefined;
268
+ if (cli.flags.help || !action || !["send", "check", "list", "log", "read", "watch", "search"].includes(action)) {
269
+ console.log(
270
+ "Usage:\n tps mail send <agent> <message> Send mail to a local or remote agent\n tps mail check [agent] Read new messages (marks as read)\n tps mail watch [agent] Watch inbox for new messages\n tps mail list [agent] List all messages (read + unread)\n tps mail read <agent> <id> Show a specific message by ID (prefix ok)\n tps mail search <query> Search mail history using full-text search\n tps mail log [agent] Show audit log [--since YYYY-MM-DD] [--limit N]"
271
+ );
272
+ process.exit(cli.flags.help ? 0 : 1);
273
+ }
274
+ const { runMail } = await import("../src/commands/mail.js");
275
+ await runMail({
276
+ action,
277
+ agent: rest[1],
278
+ message: action === "send" ? rest.slice(2).join(" ") : undefined,
279
+ messageId: action === "read" ? rest[2] : undefined,
280
+ json: cli.flags.json,
281
+ since: cli.flags.since,
282
+ limit: cli.flags.limit ? Number(cli.flags.limit) : undefined,
283
+ });
284
+ break;
285
+ }
286
+ case "identity": {
287
+ const action = rest[0] as "init" | "show" | "register" | "list" | "revoke" | "verify" | undefined;
288
+ if (!action || !["init", "show", "register", "list", "revoke", "verify"].includes(action)) {
289
+ console.error(
290
+ "Usage:\n tps identity init [--expires-in 90d]\n tps identity show\n tps identity register <branch> [--expires-in 90d] [--trust standard]\n tps identity list\n tps identity revoke <branch> --reason \"...\"\n tps identity verify <branch>"
291
+ );
292
+ process.exit(1);
293
+ }
294
+ const { runIdentity } = await import("../src/commands/identity.js");
295
+ await runIdentity({
296
+ action,
297
+ branch: rest[1],
298
+ reason: cli.flags.reason,
299
+ json: cli.flags.json,
300
+ expiresIn: cli.flags.expiresIn,
301
+ trust: cli.flags.trust as any,
302
+ pubkey: cli.flags.pubkey,
303
+ encPubkey: cli.flags.encPubkey,
304
+ });
305
+ break;
306
+ }
307
+ case "secrets": {
308
+ const action = rest[0] as "set" | "list" | "remove" | undefined;
309
+ if (!action || !["set", "list", "remove"].includes(action)) {
310
+ console.error("Usage:\n tps secrets set <KEY>=<VALUE>\n tps secrets list\n tps secrets remove <KEY>");
311
+ process.exit(1);
312
+ }
313
+ const { runSecrets } = await import("../src/commands/secrets.js");
314
+ let key: string | undefined;
315
+ let value: string | undefined;
316
+ if (action === "set") {
317
+ const parts = rest[1]?.split("=");
318
+ key = parts?.[0];
319
+ value = parts?.slice(1).join("=");
320
+ } else {
321
+ key = rest[1];
322
+ }
323
+ await runSecrets({ action, key, value, json: cli.flags.json });
324
+ break;
325
+ }
326
+ case "backup": {
327
+ const agentId = rest[0];
328
+ if (!agentId) {
329
+ console.error("Usage: tps backup <agent-id> [--schedule daily|off] [--keep n]");
330
+ process.exit(1);
331
+ }
332
+ const { runBackup } = await import("../src/commands/backup.js");
333
+ await runBackup({
334
+ agentId,
335
+ keep: typeof cli.flags.keep === "number" ? Number(cli.flags.keep) : undefined,
336
+ schedule: cli.flags.schedule,
337
+ sanitize: cli.flags.sanitize,
338
+ configPath: cli.flags.config,
339
+ });
340
+ break;
341
+ }
342
+ case "restore": {
343
+ const agentId = rest[0];
344
+ const archivePath = cli.flags.from || rest[1];
345
+ if (!agentId || !archivePath) {
346
+ console.error("Usage: tps restore <agent-id> <archive> [--from <archive>] [--clone] [--overwrite] [--force]");
347
+ process.exit(1);
348
+ }
349
+ const { runRestore } = await import("../src/commands/backup.js");
350
+ await runRestore({
351
+ agentId,
352
+ archivePath,
353
+ force: !!cli.flags.force,
354
+ overwrite: !!cli.flags.overwrite,
355
+ clone: !!cli.flags.clone,
356
+ configPath: cli.flags.config,
357
+ });
358
+ break;
359
+ }
360
+ case "heartbeat": {
361
+ const agentId = rest[0];
362
+ if (!agentId) {
363
+ console.error("Usage: tps heartbeat <agent-id>");
364
+ process.exit(1);
365
+ }
366
+ const { runHeartbeat } = await import("../src/commands/status.js");
367
+ await runHeartbeat({
368
+ agentId,
369
+ status: (cli.flags.statusOverride as any) || undefined,
370
+ nonono: !!cli.flags.nonono,
371
+ profile: "tps-status",
372
+ });
373
+ break;
374
+ }
375
+ case "status": {
376
+ const agentId = rest[0];
377
+ const { runStatus } = await import("../src/commands/status.js");
378
+ await runStatus({
379
+ agentId,
380
+ autoPrune: !!cli.flags.autoPrune,
381
+ prune: !!cli.flags.prune,
382
+ json: !!cli.flags.json,
383
+ staleMinutes: cli.flags.staleMinutes ? Number(cli.flags.staleMinutes) : undefined,
384
+ offlineHours: cli.flags.offlineHours ? Number(cli.flags.offlineHours) : undefined,
385
+ cost: !!cli.flags.cost,
386
+ shared: !!cli.flags.shared,
387
+ });
388
+ break;
389
+ }
390
+ case "branch": {
391
+ const action = rest[0] as "init" | "start" | "stop" | "status" | "log" | undefined;
392
+ const valid = ["init", "start", "stop", "status", "log"];
393
+ if (!action || !valid.includes(action)) {
394
+ console.error("Usage:\n tps branch init [--listen <port>] [--host <hostname>] [--transport ws|tcp]\n tps branch start\n tps branch stop\n tps branch status\n tps branch log [--lines N] [--follow]");
395
+ process.exit(1);
396
+ }
397
+ const { runBranch } = await import("../src/commands/branch.js");
398
+ await runBranch({
399
+ action,
400
+ port: typeof cli.flags.listen === "number" ? Number(cli.flags.listen) : undefined,
401
+ host: cli.flags.host,
402
+ transport: cli.flags.transport === "tcp" ? "tcp" : cli.flags.transport === "ws" ? "ws" : undefined,
403
+ force: cli.flags.force,
404
+ lines: typeof cli.flags.lines === "number" ? Number(cli.flags.lines) : undefined,
405
+ follow: !!cli.flags.follow,
406
+ });
407
+ break;
408
+ }
409
+ case "git": {
410
+ const action = rest[0];
411
+ if (action === "worktree") {
412
+ const agent = rest[1];
413
+ const repoPath = rest[2];
414
+ const branchName = rest[3];
415
+ if (!agent || !repoPath) {
416
+ console.error("Usage: tps git worktree <agent> <repo-path> [branch-name]");
417
+ process.exit(1);
418
+ }
419
+ const { runGit } = await import("../src/commands/git.js");
420
+ await runGit({ action, agent, repoPath, branchName });
421
+ } else {
422
+ console.error("Unknown git action. Supported: worktree");
423
+ process.exit(1);
424
+ }
425
+ break;
426
+ }
427
+ default:
428
+ cli.showHelp();
429
+ }
430
+ }
431
+
432
+ main().catch((err) => {
433
+ console.error(err?.message || err);
434
+ process.exit(1);
435
+ });
package/package.json CHANGED
@@ -1,13 +1,24 @@
1
1
  {
2
2
  "name": "@tpsdev-ai/cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "TPS Report CLI — because every agent needs the proper paperwork.",
5
5
  "type": "module",
6
6
  "bin": {
7
- "tps": "./dist/bin/tps.js"
7
+ "tps": "./bin/tps.cjs"
8
+ },
9
+ "optionalDependencies": {
10
+ "@tpsdev-ai/cli-darwin-arm64": "0.3.1",
11
+ "@tpsdev-ai/cli-darwin-x64": "0.3.1",
12
+ "@tpsdev-ai/cli-linux-arm64": "0.3.1",
13
+ "@tpsdev-ai/cli-linux-x64": "0.3.1"
8
14
  },
9
15
  "scripts": {
10
16
  "build": "tsc",
17
+ "build:binary": "bun run build:binary:darwin-arm64 && bun run build:binary:darwin-x64 && bun run build:binary:linux-arm64 && bun run build:binary:linux-x64",
18
+ "build:binary:darwin-arm64": "bun build --compile bin/tps.ts --target=bun-darwin-arm64 --outfile=dist/tps-darwin-arm64",
19
+ "build:binary:darwin-x64": "bun build --compile bin/tps.ts --target=bun-darwin-x64 --outfile=dist/tps-darwin-x64",
20
+ "build:binary:linux-arm64": "bun build --compile bin/tps.ts --target=bun-linux-arm64 --outfile=dist/tps-linux-arm64",
21
+ "build:binary:linux-x64": "bun build --compile bin/tps.ts --target=bun-linux-x64 --outfile=dist/tps-linux-x64",
11
22
  "dev": "tsc --watch",
12
23
  "start": "node dist/bin/tps.js",
13
24
  "tps": "node dist/bin/tps.js",
@@ -16,7 +27,12 @@
16
27
  "pretest": "tsc",
17
28
  "test": "bun test"
18
29
  },
19
- "keywords": ["cli", "agents", "openclaw", "tps"],
30
+ "keywords": [
31
+ "cli",
32
+ "agents",
33
+ "openclaw",
34
+ "tps"
35
+ ],
20
36
  "license": "Apache-2.0",
21
37
  "dependencies": {
22
38
  "@noble/curves": "^2.0.1",
@@ -42,7 +58,15 @@
42
58
  "fast-check": "^4.5.3",
43
59
  "typescript": "^5.7.0"
44
60
  },
45
- "files": ["dist", "nono-profiles", "personas", "reports"],
61
+ "files": [
62
+ "bin",
63
+ "nono-profiles",
64
+ "personas",
65
+ "reports",
66
+ "README.md"
67
+ ],
46
68
  "author": "tpsdev-ai",
47
- "publishConfig": { "access": "public" }
69
+ "publishConfig": {
70
+ "access": "public"
71
+ }
48
72
  }
package/dist/bin/tps.d.ts DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=tps.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tps.d.ts","sourceRoot":"","sources":["../../bin/tps.ts"],"names":[],"mappings":""}