@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.
- package/README.md +65 -0
- package/bin/tps.cjs +24 -0
- package/bin/tps.ts +435 -0
- package/package.json +29 -5
- package/dist/bin/tps.d.ts +0 -3
- package/dist/bin/tps.d.ts.map +0 -1
- package/dist/bin/tps.js +0 -414
- package/dist/bin/tps.js.map +0 -1
- package/dist/src/cli/hire.d.ts +0 -16
- package/dist/src/cli/hire.d.ts.map +0 -1
- package/dist/src/cli/hire.js +0 -176
- package/dist/src/cli/hire.js.map +0 -1
- package/dist/src/cli/office.d.ts +0 -7
- package/dist/src/cli/office.d.ts.map +0 -1
- package/dist/src/cli/office.js +0 -51
- package/dist/src/cli/office.js.map +0 -1
- package/dist/src/cli/review.d.ts +0 -9
- package/dist/src/cli/review.d.ts.map +0 -1
- package/dist/src/cli/review.js +0 -109
- package/dist/src/cli/review.js.map +0 -1
- package/dist/src/cli/roster.d.ts +0 -6
- package/dist/src/cli/roster.d.ts.map +0 -1
- package/dist/src/cli/roster.js +0 -60
- package/dist/src/cli/roster.js.map +0 -1
- package/dist/src/commands/backup.d.ts +0 -19
- package/dist/src/commands/backup.d.ts.map +0 -1
- package/dist/src/commands/backup.js +0 -595
- package/dist/src/commands/backup.js.map +0 -1
- package/dist/src/commands/bootstrap.d.ts +0 -7
- package/dist/src/commands/bootstrap.d.ts.map +0 -1
- package/dist/src/commands/bootstrap.js +0 -255
- package/dist/src/commands/bootstrap.js.map +0 -1
- package/dist/src/commands/branch.d.ts +0 -14
- package/dist/src/commands/branch.d.ts.map +0 -1
- package/dist/src/commands/branch.js +0 -395
- package/dist/src/commands/branch.js.map +0 -1
- package/dist/src/commands/context.d.ts +0 -9
- package/dist/src/commands/context.d.ts.map +0 -1
- package/dist/src/commands/context.js +0 -57
- package/dist/src/commands/context.js.map +0 -1
- package/dist/src/commands/git.d.ts +0 -8
- package/dist/src/commands/git.d.ts.map +0 -1
- package/dist/src/commands/git.js +0 -53
- package/dist/src/commands/git.js.map +0 -1
- package/dist/src/commands/identity.d.ts +0 -13
- package/dist/src/commands/identity.d.ts.map +0 -1
- package/dist/src/commands/identity.js +0 -231
- package/dist/src/commands/identity.js.map +0 -1
- package/dist/src/commands/mail.d.ts +0 -12
- package/dist/src/commands/mail.d.ts.map +0 -1
- package/dist/src/commands/mail.js +0 -251
- package/dist/src/commands/mail.js.map +0 -1
- package/dist/src/commands/office-manager.d.ts +0 -147
- package/dist/src/commands/office-manager.d.ts.map +0 -1
- package/dist/src/commands/office-manager.js +0 -171
- package/dist/src/commands/office-manager.js.map +0 -1
- package/dist/src/commands/office.d.ts +0 -12
- package/dist/src/commands/office.d.ts.map +0 -1
- package/dist/src/commands/office.js +0 -480
- package/dist/src/commands/office.js.map +0 -1
- package/dist/src/commands/roster.d.ts +0 -10
- package/dist/src/commands/roster.d.ts.map +0 -1
- package/dist/src/commands/roster.js +0 -143
- package/dist/src/commands/roster.js.map +0 -1
- package/dist/src/commands/secrets.d.ts +0 -9
- package/dist/src/commands/secrets.d.ts.map +0 -1
- package/dist/src/commands/secrets.js +0 -54
- package/dist/src/commands/secrets.js.map +0 -1
- package/dist/src/commands/status.d.ts +0 -33
- package/dist/src/commands/status.d.ts.map +0 -1
- package/dist/src/commands/status.js +0 -407
- package/dist/src/commands/status.js.map +0 -1
- package/dist/src/generators/brief.d.ts +0 -6
- package/dist/src/generators/brief.d.ts.map +0 -1
- package/dist/src/generators/brief.js +0 -33
- package/dist/src/generators/brief.js.map +0 -1
- package/dist/src/generators/claude-code.d.ts +0 -18
- package/dist/src/generators/claude-code.d.ts.map +0 -1
- package/dist/src/generators/claude-code.js +0 -85
- package/dist/src/generators/claude-code.js.map +0 -1
- package/dist/src/generators/codex.d.ts +0 -23
- package/dist/src/generators/codex.d.ts.map +0 -1
- package/dist/src/generators/codex.js +0 -83
- package/dist/src/generators/codex.js.map +0 -1
- package/dist/src/generators/ollama.d.ts +0 -18
- package/dist/src/generators/ollama.d.ts.map +0 -1
- package/dist/src/generators/ollama.js +0 -97
- package/dist/src/generators/ollama.js.map +0 -1
- package/dist/src/generators/openclaw.d.ts +0 -15
- package/dist/src/generators/openclaw.d.ts.map +0 -1
- package/dist/src/generators/openclaw.js +0 -107
- package/dist/src/generators/openclaw.js.map +0 -1
- package/dist/src/generators/registry.d.ts +0 -36
- package/dist/src/generators/registry.d.ts.map +0 -1
- package/dist/src/generators/registry.js +0 -99
- package/dist/src/generators/registry.js.map +0 -1
- package/dist/src/schema/manifest.d.ts +0 -287
- package/dist/src/schema/manifest.d.ts.map +0 -1
- package/dist/src/schema/manifest.js +0 -65
- package/dist/src/schema/manifest.js.map +0 -1
- package/dist/src/schema/report.d.ts +0 -166
- package/dist/src/schema/report.d.ts.map +0 -1
- package/dist/src/schema/report.js +0 -90
- package/dist/src/schema/report.js.map +0 -1
- package/dist/src/schema/sanitizer.d.ts +0 -30
- package/dist/src/schema/sanitizer.d.ts.map +0 -1
- package/dist/src/schema/sanitizer.js +0 -99
- package/dist/src/schema/sanitizer.js.map +0 -1
- package/dist/src/soundstage/mock-llm.d.ts +0 -3
- package/dist/src/soundstage/mock-llm.d.ts.map +0 -1
- package/dist/src/soundstage/mock-llm.js +0 -68
- package/dist/src/soundstage/mock-llm.js.map +0 -1
- package/dist/src/utils/agent-info.d.ts +0 -28
- package/dist/src/utils/agent-info.d.ts.map +0 -1
- package/dist/src/utils/agent-info.js +0 -102
- package/dist/src/utils/agent-info.js.map +0 -1
- package/dist/src/utils/archive.d.ts +0 -20
- package/dist/src/utils/archive.d.ts.map +0 -1
- package/dist/src/utils/archive.js +0 -108
- package/dist/src/utils/archive.js.map +0 -1
- package/dist/src/utils/config-inject.d.ts +0 -27
- package/dist/src/utils/config-inject.d.ts.map +0 -1
- package/dist/src/utils/config-inject.js +0 -83
- package/dist/src/utils/config-inject.js.map +0 -1
- package/dist/src/utils/config.d.ts +0 -30
- package/dist/src/utils/config.d.ts.map +0 -1
- package/dist/src/utils/config.js +0 -55
- package/dist/src/utils/config.js.map +0 -1
- package/dist/src/utils/connection-state.d.ts +0 -27
- package/dist/src/utils/connection-state.d.ts.map +0 -1
- package/dist/src/utils/connection-state.js +0 -81
- package/dist/src/utils/connection-state.js.map +0 -1
- package/dist/src/utils/context.d.ts +0 -14
- package/dist/src/utils/context.d.ts.map +0 -1
- package/dist/src/utils/context.js +0 -68
- package/dist/src/utils/context.js.map +0 -1
- package/dist/src/utils/github-webhook.d.ts +0 -3
- package/dist/src/utils/github-webhook.d.ts.map +0 -1
- package/dist/src/utils/github-webhook.js +0 -105
- package/dist/src/utils/github-webhook.js.map +0 -1
- package/dist/src/utils/identity.d.ts +0 -124
- package/dist/src/utils/identity.d.ts.map +0 -1
- package/dist/src/utils/identity.js +0 -434
- package/dist/src/utils/identity.js.map +0 -1
- package/dist/src/utils/internal-mail.d.ts +0 -18
- package/dist/src/utils/internal-mail.d.ts.map +0 -1
- package/dist/src/utils/internal-mail.js +0 -75
- package/dist/src/utils/internal-mail.js.map +0 -1
- package/dist/src/utils/loop-detector.d.ts +0 -27
- package/dist/src/utils/loop-detector.d.ts.map +0 -1
- package/dist/src/utils/loop-detector.js +0 -42
- package/dist/src/utils/loop-detector.js.map +0 -1
- package/dist/src/utils/mail-handler.d.ts +0 -19
- package/dist/src/utils/mail-handler.d.ts.map +0 -1
- package/dist/src/utils/mail-handler.js +0 -94
- package/dist/src/utils/mail-handler.js.map +0 -1
- package/dist/src/utils/mail.d.ts +0 -22
- package/dist/src/utils/mail.d.ts.map +0 -1
- package/dist/src/utils/mail.js +0 -111
- package/dist/src/utils/mail.js.map +0 -1
- package/dist/src/utils/manifest.d.ts +0 -36
- package/dist/src/utils/manifest.d.ts.map +0 -1
- package/dist/src/utils/manifest.js +0 -94
- package/dist/src/utils/manifest.js.map +0 -1
- package/dist/src/utils/noise-ik-transport.d.ts +0 -18
- package/dist/src/utils/noise-ik-transport.d.ts.map +0 -1
- package/dist/src/utils/noise-ik-transport.js +0 -357
- package/dist/src/utils/noise-ik-transport.js.map +0 -1
- package/dist/src/utils/nono.d.ts +0 -72
- package/dist/src/utils/nono.d.ts.map +0 -1
- package/dist/src/utils/nono.js +0 -166
- package/dist/src/utils/nono.js.map +0 -1
- package/dist/src/utils/outbox.d.ts +0 -10
- package/dist/src/utils/outbox.d.ts.map +0 -1
- package/dist/src/utils/outbox.js +0 -29
- package/dist/src/utils/outbox.js.map +0 -1
- package/dist/src/utils/output.d.ts +0 -17
- package/dist/src/utils/output.d.ts.map +0 -1
- package/dist/src/utils/output.js +0 -83
- package/dist/src/utils/output.js.map +0 -1
- package/dist/src/utils/plain-tcp-transport.d.ts +0 -10
- package/dist/src/utils/plain-tcp-transport.d.ts.map +0 -1
- package/dist/src/utils/plain-tcp-transport.js +0 -209
- package/dist/src/utils/plain-tcp-transport.js.map +0 -1
- package/dist/src/utils/provision.d.ts +0 -2
- package/dist/src/utils/provision.d.ts.map +0 -1
- package/dist/src/utils/provision.js +0 -193
- package/dist/src/utils/provision.js.map +0 -1
- package/dist/src/utils/relay.d.ts +0 -30
- package/dist/src/utils/relay.d.ts.map +0 -1
- package/dist/src/utils/relay.js +0 -539
- package/dist/src/utils/relay.js.map +0 -1
- package/dist/src/utils/sandbox.d.ts +0 -37
- package/dist/src/utils/sandbox.d.ts.map +0 -1
- package/dist/src/utils/sandbox.js +0 -126
- package/dist/src/utils/sandbox.js.map +0 -1
- package/dist/src/utils/transport.d.ts +0 -62
- package/dist/src/utils/transport.d.ts.map +0 -1
- package/dist/src/utils/transport.js +0 -75
- package/dist/src/utils/transport.js.map +0 -1
- package/dist/src/utils/vault.d.ts +0 -21
- package/dist/src/utils/vault.d.ts.map +0 -1
- package/dist/src/utils/vault.js +0 -67
- package/dist/src/utils/vault.js.map +0 -1
- package/dist/src/utils/wall.d.ts +0 -5
- package/dist/src/utils/wall.d.ts.map +0 -1
- package/dist/src/utils/wall.js +0 -51
- package/dist/src/utils/wall.js.map +0 -1
- package/dist/src/utils/wire-delivery.d.ts +0 -10
- package/dist/src/utils/wire-delivery.d.ts.map +0 -1
- package/dist/src/utils/wire-delivery.js +0 -57
- package/dist/src/utils/wire-delivery.js.map +0 -1
- package/dist/src/utils/wire-frame.d.ts +0 -10
- package/dist/src/utils/wire-frame.d.ts.map +0 -1
- package/dist/src/utils/wire-frame.js +0 -66
- package/dist/src/utils/wire-frame.js.map +0 -1
- package/dist/src/utils/wire-mail.d.ts +0 -54
- package/dist/src/utils/wire-mail.d.ts.map +0 -1
- package/dist/src/utils/wire-mail.js +0 -24
- package/dist/src/utils/wire-mail.js.map +0 -1
- package/dist/src/utils/workspace.d.ts +0 -14
- package/dist/src/utils/workspace.d.ts.map +0 -1
- package/dist/src/utils/workspace.js +0 -53
- package/dist/src/utils/workspace.js.map +0 -1
- package/dist/src/utils/ws-noise-transport.d.ts +0 -18
- package/dist/src/utils/ws-noise-transport.d.ts.map +0 -1
- package/dist/src/utils/ws-noise-transport.js +0 -356
- 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.
|
|
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": "./
|
|
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": [
|
|
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": [
|
|
61
|
+
"files": [
|
|
62
|
+
"bin",
|
|
63
|
+
"nono-profiles",
|
|
64
|
+
"personas",
|
|
65
|
+
"reports",
|
|
66
|
+
"README.md"
|
|
67
|
+
],
|
|
46
68
|
"author": "tpsdev-ai",
|
|
47
|
-
"publishConfig": {
|
|
69
|
+
"publishConfig": {
|
|
70
|
+
"access": "public"
|
|
71
|
+
}
|
|
48
72
|
}
|
package/dist/bin/tps.d.ts
DELETED
package/dist/bin/tps.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tps.d.ts","sourceRoot":"","sources":["../../bin/tps.ts"],"names":[],"mappings":""}
|