@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
@@ -1,434 +0,0 @@
1
- /**
2
- * TPS Identity Primitives — Ed25519 signing + X25519 encryption.
3
- *
4
- * Every entity (host or branch) has TWO keypairs derived from one 32-byte seed:
5
- * - Ed25519 for signing/verification (identity proof)
6
- * - X25519 for encryption/key exchange (secret delivery, Noise handshake)
7
- *
8
- * The private key IS the identity. Lose it → revoke and re-provision.
9
- * Branch generates its own keys — the host NEVER sees a branch's private key.
10
- */
11
- import * as ed from "@noble/ed25519";
12
- import { x25519 } from "@noble/curves/ed25519.js";
13
- import { randomBytes, createHash } from "node:crypto";
14
- import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync, statSync, readdirSync, unlinkSync, } from "node:fs";
15
- import { join } from "node:path";
16
- import { homedir, hostname } from "node:os";
17
- import { encryptVault, decryptVault, saveVault, loadVaultFile } from "./vault.js";
18
- function vaultPath() {
19
- return join(getIdentityDir(), "vault.json");
20
- }
21
- function getVaultPassphrase() {
22
- const key = process.env.TPS_VAULT_KEY;
23
- if (!key) {
24
- console.error("❌ TPS_VAULT_KEY environment variable is required to unlock the identity vault.");
25
- process.exit(1);
26
- }
27
- return key;
28
- }
29
- export async function saveToVault(data) {
30
- const passphrase = getVaultPassphrase();
31
- const vaultData = await encryptVault(data, passphrase);
32
- saveVault(vaultPath(), vaultData);
33
- }
34
- export async function loadFromVault() {
35
- const path = vaultPath();
36
- const vaultFile = loadVaultFile(path);
37
- if (!vaultFile)
38
- return null;
39
- const passphrase = getVaultPassphrase();
40
- try {
41
- return await decryptVault(vaultFile, passphrase);
42
- }
43
- catch (err) {
44
- throw new Error("Failed to decrypt vault. Check passphrase.");
45
- }
46
- }
47
- async function migrateToVault() {
48
- const dir = getIdentityDir();
49
- const seedPath = join(dir, "host.seed");
50
- const metaPath = join(dir, "host.meta.json");
51
- if (existsSync(seedPath)) {
52
- const seed = new Uint8Array(readFileSync(seedPath));
53
- const meta = existsSync(metaPath) ? JSON.parse(readFileSync(metaPath, "utf-8")) : {};
54
- const vault = {
55
- identity: {
56
- seed: Buffer.from(seed).toString("base64"),
57
- createdAt: meta.createdAt || new Date().toISOString(),
58
- expiresAt: meta.expiresAt,
59
- },
60
- secrets: {},
61
- };
62
- await saveToVault(vault);
63
- const filesToDelete = [
64
- "host.seed", "host.key", "host.pub",
65
- "host.x25519.key", "host.x25519.pub", "host.meta.json"
66
- ];
67
- for (const f of filesToDelete) {
68
- const p = join(dir, f);
69
- if (existsSync(p))
70
- unlinkSync(p);
71
- }
72
- }
73
- }
74
- // noble/ed25519 v3 needs hashes.sha512 set for sync operations.
75
- import { hashes } from "@noble/ed25519";
76
- hashes.sha512 = (message) => {
77
- return new Uint8Array(createHash("sha512").update(message).digest());
78
- };
79
- /**
80
- * Compute the fingerprint (SHA-256 hex) of a public key.
81
- */
82
- export function fingerprint(publicKey) {
83
- return createHash("sha256").update(publicKey).digest("hex");
84
- }
85
- /**
86
- * Derive X25519 private key from Ed25519 seed.
87
- * Uses SHA-512 of the seed (same as Ed25519 key expansion) and clamps
88
- * the first 32 bytes for Curve25519 scalar multiplication.
89
- * This is the same approach as libsodium's crypto_sign_ed25519_sk_to_curve25519.
90
- */
91
- export function edSeedToX25519Private(seed) {
92
- const h = createHash("sha512").update(seed).digest();
93
- const scalar = new Uint8Array(h.slice(0, 32));
94
- // Clamp for Curve25519
95
- scalar[0] &= 248;
96
- scalar[31] &= 127;
97
- scalar[31] |= 64;
98
- return scalar;
99
- }
100
- /**
101
- * Generate a new identity keypair (Ed25519 signing + X25519 encryption).
102
- * Both are derived from a single 32-byte seed.
103
- */
104
- export function generateKeyPair(options) {
105
- const seed = new Uint8Array(randomBytes(32));
106
- // Ed25519 signing keypair
107
- const edPublic = ed.getPublicKey(seed);
108
- // X25519 encryption keypair (derived from same seed)
109
- const xPrivate = edSeedToX25519Private(seed);
110
- const xPublic = x25519.getPublicKey(xPrivate);
111
- const now = new Date();
112
- const fp = fingerprint(edPublic);
113
- return {
114
- signing: { publicKey: edPublic, privateKey: seed },
115
- encryption: { publicKey: xPublic, privateKey: xPrivate },
116
- seed,
117
- fingerprint: fp,
118
- createdAt: now.toISOString(),
119
- expiresAt: options?.expiresIn
120
- ? new Date(now.getTime() + options.expiresIn).toISOString()
121
- : undefined,
122
- // Backward compat
123
- publicKey: edPublic,
124
- privateKey: seed,
125
- };
126
- }
127
- /**
128
- * Sign a message with a private key.
129
- * Returns the 64-byte Ed25519 signature.
130
- */
131
- export function sign(message, privateKey) {
132
- return ed.sign(message, privateKey);
133
- }
134
- /**
135
- * Verify a signature against a message and public key.
136
- */
137
- export function verify(message, signature, publicKey) {
138
- try {
139
- return ed.verify(signature, message, publicKey);
140
- }
141
- catch {
142
- return false;
143
- }
144
- }
145
- // --- Filesystem storage ---
146
- function getIdentityDir() {
147
- return (process.env.TPS_IDENTITY_DIR ||
148
- join(process.env.HOME || homedir(), ".tps", "identity"));
149
- }
150
- function getRegistryDir() {
151
- return (process.env.TPS_REGISTRY_DIR ||
152
- join(process.env.HOME || homedir(), ".tps", "registry"));
153
- }
154
- /**
155
- * Save a keypair to a directory.
156
- * Private keys get 0600 permissions. Both Ed25519 and X25519 keys stored.
157
- */
158
- export function saveKeyPair(keyPair, dir, prefix = "host") {
159
- mkdirSync(dir, { recursive: true });
160
- // Store the master seed (32 bytes — derives both keypairs)
161
- const seedPath = join(dir, `${prefix}.seed`);
162
- writeFileSync(seedPath, Buffer.from(keyPair.seed));
163
- chmodSync(seedPath, 0o600);
164
- // Ed25519 signing keys
165
- const keyPath = join(dir, `${prefix}.key`);
166
- const pubPath = join(dir, `${prefix}.pub`);
167
- writeFileSync(keyPath, Buffer.from(keyPair.signing.privateKey));
168
- chmodSync(keyPath, 0o600);
169
- writeFileSync(pubPath, Buffer.from(keyPair.signing.publicKey));
170
- // X25519 encryption keys
171
- const xKeyPath = join(dir, `${prefix}.x25519.key`);
172
- const xPubPath = join(dir, `${prefix}.x25519.pub`);
173
- writeFileSync(xKeyPath, Buffer.from(keyPair.encryption.privateKey));
174
- chmodSync(xKeyPath, 0o600);
175
- writeFileSync(xPubPath, Buffer.from(keyPair.encryption.publicKey));
176
- // Write metadata
177
- const meta = {
178
- fingerprint: keyPair.fingerprint,
179
- createdAt: keyPair.createdAt,
180
- expiresAt: keyPair.expiresAt,
181
- };
182
- writeFileSync(join(dir, `${prefix}.meta.json`), JSON.stringify(meta, null, 2), "utf-8");
183
- }
184
- /**
185
- * Load a keypair from a directory.
186
- * Supports both new format (with seed + x25519) and legacy (ed25519 only).
187
- */
188
- export function loadKeyPair(dir, prefix = "host") {
189
- const keyPath = join(dir, `${prefix}.key`);
190
- const pubPath = join(dir, `${prefix}.pub`);
191
- const metaPath = join(dir, `${prefix}.meta.json`);
192
- const seedPath = join(dir, `${prefix}.seed`);
193
- if (!existsSync(keyPath) || !existsSync(pubPath)) {
194
- throw new Error(`No keypair found at ${dir}/${prefix}.*`);
195
- }
196
- const edPrivate = new Uint8Array(readFileSync(keyPath));
197
- const edPublic = new Uint8Array(readFileSync(pubPath));
198
- let meta = {
199
- fingerprint: fingerprint(edPublic),
200
- createdAt: new Date().toISOString(),
201
- };
202
- if (existsSync(metaPath)) {
203
- meta = JSON.parse(readFileSync(metaPath, "utf-8"));
204
- }
205
- // Load or derive X25519 keys
206
- const seed = existsSync(seedPath)
207
- ? new Uint8Array(readFileSync(seedPath))
208
- : edPrivate; // legacy: seed IS the ed25519 private key (32 bytes)
209
- const xPrivate = edSeedToX25519Private(seed);
210
- const xPubPath = join(dir, `${prefix}.x25519.pub`);
211
- const xPublic = existsSync(xPubPath)
212
- ? new Uint8Array(readFileSync(xPubPath))
213
- : x25519.getPublicKey(xPrivate);
214
- return {
215
- signing: { publicKey: edPublic, privateKey: edPrivate },
216
- encryption: { publicKey: xPublic, privateKey: xPrivate },
217
- seed,
218
- fingerprint: meta.fingerprint,
219
- createdAt: meta.createdAt,
220
- expiresAt: meta.expiresAt,
221
- publicKey: edPublic,
222
- privateKey: edPrivate,
223
- };
224
- }
225
- /**
226
- * Check if a private key file has safe permissions (0600).
227
- * Returns true if permissions are restrictive enough.
228
- */
229
- export function checkKeyPermissions(keyPath) {
230
- try {
231
- const st = statSync(keyPath);
232
- const mode = st.mode & 0o777;
233
- // Allow 0600 or 0400 (read-only)
234
- return mode === 0o600 || mode === 0o400;
235
- }
236
- catch {
237
- return false;
238
- }
239
- }
240
- // --- Host identity convenience ---
241
- /**
242
- * Initialize host identity (generate keypair if not exists).
243
- * Returns the keypair (existing or newly generated).
244
- */
245
- export async function initHostIdentity(options) {
246
- const dir = getIdentityDir();
247
- if (existsSync(join(dir, "host.seed")) && !options?.force) {
248
- await migrateToVault();
249
- }
250
- const existing = await loadFromVault();
251
- if (existing && !options?.force) {
252
- const seed = new Uint8Array(Buffer.from(existing.identity.seed, "base64"));
253
- return deriveFromSeed(seed, {
254
- createdAt: existing.identity.createdAt,
255
- expiresAt: existing.identity.expiresAt,
256
- });
257
- }
258
- const kp = generateKeyPair({ expiresIn: options?.expiresIn });
259
- const vault = {
260
- identity: {
261
- seed: Buffer.from(kp.seed).toString("base64"),
262
- createdAt: kp.createdAt,
263
- expiresAt: kp.expiresAt,
264
- },
265
- secrets: {},
266
- };
267
- await saveToVault(vault);
268
- return kp;
269
- }
270
- function deriveFromSeed(seed, meta) {
271
- const edPublic = ed.getPublicKey(seed);
272
- const xPrivate = edSeedToX25519Private(seed);
273
- const xPublic = x25519.getPublicKey(xPrivate);
274
- return {
275
- signing: { publicKey: edPublic, privateKey: seed },
276
- encryption: { publicKey: xPublic, privateKey: xPrivate },
277
- seed,
278
- fingerprint: fingerprint(edPublic),
279
- createdAt: meta.createdAt,
280
- expiresAt: meta.expiresAt,
281
- publicKey: edPublic,
282
- privateKey: seed,
283
- };
284
- }
285
- /**
286
- * Load the host identity. Throws if not initialized.
287
- */
288
- export async function loadHostIdentity() {
289
- const vault = await loadFromVault();
290
- if (!vault) {
291
- if (existsSync(join(getIdentityDir(), "host.seed"))) {
292
- await migrateToVault();
293
- return loadHostIdentity();
294
- }
295
- throw new Error("No host identity found. Run `tps office init` first.");
296
- }
297
- return deriveFromSeed(new Uint8Array(Buffer.from(vault.identity.seed, "base64")), vault.identity);
298
- }
299
- export async function loadHostIdentityId() {
300
- const safeHostname = () => hostname().split(".")[0];
301
- try {
302
- const vault = await loadFromVault();
303
- if (vault) {
304
- return safeHostname();
305
- }
306
- }
307
- catch {
308
- return safeHostname();
309
- }
310
- return safeHostname();
311
- }
312
- /**
313
- * Register a branch's public keys in the host registry.
314
- * Branch generates its own keys — only PUBLIC keys are registered here.
315
- * The host NEVER sees a branch's private key.
316
- */
317
- export function registerBranch(branchId, publicKey, meta, encryptionKey) {
318
- if (!/^[a-zA-Z0-9_-]+$/.test(branchId)) {
319
- throw new Error(`Invalid branch ID: "${branchId}". Use only letters, numbers, hyphens, underscores.`);
320
- }
321
- const dir = getRegistryDir();
322
- mkdirSync(dir, { recursive: true });
323
- const fp = fingerprint(publicKey);
324
- const fullMeta = {
325
- fingerprint: fp,
326
- createdAt: meta?.createdAt || new Date().toISOString(),
327
- expiresAt: meta?.expiresAt,
328
- trust: meta?.trust || "standard",
329
- };
330
- // Ed25519 signing public key
331
- writeFileSync(join(dir, `${branchId}.pub`), Buffer.from(publicKey));
332
- // X25519 encryption public key (if provided)
333
- if (encryptionKey) {
334
- writeFileSync(join(dir, `${branchId}.x25519.pub`), Buffer.from(encryptionKey));
335
- }
336
- writeFileSync(join(dir, `${branchId}.meta.json`), JSON.stringify(fullMeta, null, 2), "utf-8");
337
- return { branchId, publicKey, encryptionKey, meta: fullMeta };
338
- }
339
- /**
340
- * Look up a branch's registered key.
341
- */
342
- export function lookupBranch(branchId) {
343
- if (!/^[a-zA-Z0-9_-]+$/.test(branchId))
344
- return null;
345
- const dir = getRegistryDir();
346
- const pubPath = join(dir, `${branchId}.pub`);
347
- if (!existsSync(pubPath))
348
- return null;
349
- // Check if revoked
350
- const revokedPath = join(dir, "revoked", `${branchId}.meta.json`);
351
- if (existsSync(revokedPath))
352
- return null;
353
- const publicKey = new Uint8Array(readFileSync(pubPath));
354
- const metaPath = join(dir, `${branchId}.meta.json`);
355
- let meta = {
356
- fingerprint: fingerprint(publicKey),
357
- createdAt: new Date().toISOString(),
358
- };
359
- if (existsSync(metaPath)) {
360
- meta = JSON.parse(readFileSync(metaPath, "utf-8"));
361
- }
362
- // Load X25519 encryption public key if available
363
- const xPubPath = join(dir, `${branchId}.x25519.pub`);
364
- const encryptionKey = existsSync(xPubPath)
365
- ? new Uint8Array(readFileSync(xPubPath))
366
- : undefined;
367
- return { branchId, publicKey, encryptionKey, meta };
368
- }
369
- /**
370
- * Revoke a branch's key. Moves metadata to revoked/ directory.
371
- */
372
- export function revokeBranch(branchId, reason) {
373
- const dir = getRegistryDir();
374
- const pubPath = join(dir, `${branchId}.pub`);
375
- const metaPath = join(dir, `${branchId}.meta.json`);
376
- if (!existsSync(pubPath)) {
377
- throw new Error(`No registered key for branch: ${branchId}`);
378
- }
379
- const revokedDir = join(dir, "revoked");
380
- mkdirSync(revokedDir, { recursive: true });
381
- // Read existing meta, add revocation info
382
- let meta = {
383
- fingerprint: "",
384
- createdAt: new Date().toISOString(),
385
- };
386
- if (existsSync(metaPath)) {
387
- meta = JSON.parse(readFileSync(metaPath, "utf-8"));
388
- }
389
- meta.revokedAt = new Date().toISOString();
390
- meta.revokeReason = reason;
391
- // Move to revoked
392
- writeFileSync(join(revokedDir, `${branchId}.meta.json`), JSON.stringify(meta, null, 2), "utf-8");
393
- // Remove from active registry
394
- try {
395
- unlinkSync(pubPath);
396
- if (existsSync(metaPath))
397
- unlinkSync(metaPath);
398
- }
399
- catch {
400
- // Best effort cleanup
401
- }
402
- }
403
- /**
404
- * Check if a branch key is revoked.
405
- */
406
- export function isRevoked(branchId) {
407
- const dir = getRegistryDir();
408
- return existsSync(join(dir, "revoked", `${branchId}.meta.json`));
409
- }
410
- /**
411
- * Check if a branch key is expired.
412
- */
413
- export function isExpired(meta) {
414
- if (!meta.expiresAt)
415
- return false;
416
- return new Date(meta.expiresAt) < new Date();
417
- }
418
- /**
419
- * List all registered (non-revoked) branches.
420
- */
421
- export function listBranches() {
422
- const dir = getRegistryDir();
423
- if (!existsSync(dir))
424
- return [];
425
- const files = readdirSync(dir);
426
- return files
427
- .filter((f) => f.endsWith(".pub") && !f.includes(".x25519."))
428
- .map((f) => {
429
- const branchId = f.replace(/\.pub$/, "");
430
- return lookupBranch(branchId);
431
- })
432
- .filter((r) => r !== null);
433
- }
434
- //# sourceMappingURL=identity.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../src/utils/identity.ts"],"names":[],"mappings":"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"}
@@ -1,18 +0,0 @@
1
- export interface InternalMessage {
2
- id: string;
3
- from: string;
4
- to: string;
5
- body: string;
6
- timestamp: string;
7
- read: boolean;
8
- }
9
- export declare function internalMailRoot(officeDir: string): string;
10
- export declare function getInternalInbox(officeDir: string, agent: string): {
11
- root: string;
12
- tmp: string;
13
- fresh: string;
14
- cur: string;
15
- };
16
- export declare function sendInternalMessage(officeDir: string, from: string, to: string, body: string): InternalMessage;
17
- export declare function checkInternalMessages(officeDir: string, agent: string): InternalMessage[];
18
- //# sourceMappingURL=internal-mail.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"internal-mail.d.ts","sourceRoot":"","sources":["../../../src/utils/internal-mail.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;CACf;AAUD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAK1D;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAY5H;AAID,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CAoB9G;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,eAAe,EAAE,CAmBzF"}
@@ -1,75 +0,0 @@
1
- import { mkdirSync, readFileSync, readdirSync, renameSync, writeFileSync } from "node:fs";
2
- import { join, resolve, sep } from "node:path";
3
- import { homedir } from "node:os";
4
- import { randomUUID } from "node:crypto";
5
- import { sanitizeIdentifier } from "../schema/sanitizer.js";
6
- function assertOfficeDir(officeDir) {
7
- const resolved = resolve(officeDir);
8
- const root = resolve(join(process.env.HOME || homedir(), ".tps", "branch-office"));
9
- if (!resolved.startsWith(root + sep) && resolved !== root) {
10
- throw new Error(`Office directory out of bounds: ${officeDir}`);
11
- }
12
- }
13
- export function internalMailRoot(officeDir) {
14
- assertOfficeDir(officeDir);
15
- const dir = join(officeDir, "mail", "internal");
16
- mkdirSync(dir, { recursive: true });
17
- return dir;
18
- }
19
- export function getInternalInbox(officeDir, agent) {
20
- assertOfficeDir(officeDir);
21
- const safe = sanitizeIdentifier(agent);
22
- if (!agent || safe !== agent)
23
- throw new Error(`Invalid agent id: ${agent}`);
24
- const root = join(internalMailRoot(officeDir), agent);
25
- const tmp = join(root, "tmp");
26
- const fresh = join(root, "new");
27
- const cur = join(root, "cur");
28
- mkdirSync(tmp, { recursive: true });
29
- mkdirSync(fresh, { recursive: true });
30
- mkdirSync(cur, { recursive: true });
31
- return { root, tmp, fresh, cur };
32
- }
33
- const MAX_BODY_BYTES = 64 * 1024;
34
- export function sendInternalMessage(officeDir, from, to, body) {
35
- assertOfficeDir(officeDir);
36
- const safeFrom = sanitizeIdentifier(from);
37
- const safeTo = sanitizeIdentifier(to);
38
- if (!from || safeFrom !== from)
39
- throw new Error(`Invalid agent id: ${from}`);
40
- if (!to || safeTo !== to)
41
- throw new Error(`Invalid agent id: ${to}`);
42
- if (body.includes("\u0000"))
43
- throw new Error("Message body contains invalid null byte.");
44
- if (Buffer.byteLength(body, "utf8") > MAX_BODY_BYTES)
45
- throw new Error("Message body exceeds maximum size (64KB).");
46
- const inbox = getInternalInbox(officeDir, to);
47
- const timestamp = new Date().toISOString();
48
- const id = randomUUID();
49
- const message = { id, from, to, body, timestamp, read: false };
50
- const safeTs = timestamp.replace(/[:.]/g, "-");
51
- const filename = `${safeTs}-${id}.json`;
52
- writeFileSync(join(inbox.tmp, filename), JSON.stringify(message, null, 2), "utf-8");
53
- renameSync(join(inbox.tmp, filename), join(inbox.fresh, filename));
54
- return message;
55
- }
56
- export function checkInternalMessages(officeDir, agent) {
57
- assertOfficeDir(officeDir);
58
- const safe = sanitizeIdentifier(agent);
59
- if (!agent || safe !== agent)
60
- throw new Error(`Invalid agent id: ${agent}`);
61
- const inbox = getInternalInbox(officeDir, agent);
62
- const files = readdirSync(inbox.fresh).filter((f) => f.endsWith(".json"));
63
- const messages = [];
64
- for (const f of files) {
65
- const fromPath = join(inbox.fresh, f);
66
- const toPath = join(inbox.cur, f);
67
- renameSync(fromPath, toPath);
68
- const raw = readFileSync(toPath, "utf-8");
69
- const msg = JSON.parse(raw);
70
- msg.read = true;
71
- messages.push(msg);
72
- }
73
- return messages.sort((a, b) => (a.timestamp < b.timestamp ? 1 : -1));
74
- }
75
- //# sourceMappingURL=internal-mail.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"internal-mail.js","sourceRoot":"","sources":["../../../src/utils/internal-mail.ts"],"names":[],"mappings":"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"}
@@ -1,27 +0,0 @@
1
- export interface LoopDetectorOptions {
2
- /** Max duplicate messages before triggering. Default: 3 */
3
- threshold?: number;
4
- /** Time window in ms. Default: 300_000 (5 min) */
5
- windowMs?: number;
6
- }
7
- export declare class LoopDetector {
8
- private history;
9
- private readonly threshold;
10
- private readonly windowMs;
11
- constructor(opts?: LoopDetectorOptions);
12
- /** Hash a message body (SHA-256, first 16 hex chars) */
13
- private hash;
14
- /** Prune entries outside the time window */
15
- private prune;
16
- /**
17
- * Check if a message body is a duplicate.
18
- * Returns true if this message should be PAUSED (loop detected).
19
- * Always records the hash regardless of result.
20
- */
21
- check(body: string): boolean;
22
- /** Reset all history (e.g., after manual intervention) */
23
- reset(): void;
24
- /** Get current duplicate count for a body */
25
- duplicateCount(body: string): number;
26
- }
27
- //# sourceMappingURL=loop-detector.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"loop-detector.d.ts","sourceRoot":"","sources":["../../../src/utils/loop-detector.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAOD,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,IAAI,GAAE,mBAAwB;IAK1C,wDAAwD;IACxD,OAAO,CAAC,IAAI;IAIZ,4CAA4C;IAC5C,OAAO,CAAC,KAAK;IAKb;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAQ5B,0DAA0D;IAC1D,KAAK,IAAI,IAAI;IAIb,6CAA6C;IAC7C,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAKrC"}
@@ -1,42 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- export class LoopDetector {
3
- history = [];
4
- threshold;
5
- windowMs;
6
- constructor(opts = {}) {
7
- this.threshold = opts.threshold ?? 3;
8
- this.windowMs = opts.windowMs ?? 300_000;
9
- }
10
- /** Hash a message body (SHA-256, first 16 hex chars) */
11
- hash(body) {
12
- return createHash("sha256").update(body).digest("hex").slice(0, 16);
13
- }
14
- /** Prune entries outside the time window */
15
- prune() {
16
- const cutoff = Date.now() - this.windowMs;
17
- this.history = this.history.filter((e) => e.timestamp > cutoff);
18
- }
19
- /**
20
- * Check if a message body is a duplicate.
21
- * Returns true if this message should be PAUSED (loop detected).
22
- * Always records the hash regardless of result.
23
- */
24
- check(body) {
25
- this.prune();
26
- const h = this.hash(body);
27
- this.history.push({ hash: h, timestamp: Date.now() });
28
- const count = this.history.filter((e) => e.hash === h).length;
29
- return count >= this.threshold;
30
- }
31
- /** Reset all history (e.g., after manual intervention) */
32
- reset() {
33
- this.history = [];
34
- }
35
- /** Get current duplicate count for a body */
36
- duplicateCount(body) {
37
- this.prune();
38
- const h = this.hash(body);
39
- return this.history.filter((e) => e.hash === h).length;
40
- }
41
- }
42
- //# sourceMappingURL=loop-detector.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"loop-detector.js","sourceRoot":"","sources":["../../../src/utils/loop-detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAczC,MAAM,OAAO,YAAY;IACf,OAAO,GAAgB,EAAE,CAAC;IACjB,SAAS,CAAS;IAClB,QAAQ,CAAS;IAElC,YAAY,OAA4B,EAAE;QACxC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC;IAC3C,CAAC;IAED,wDAAwD;IAChD,IAAI,CAAC,IAAY;QACvB,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,4CAA4C;IACpC,KAAK;QACX,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC1C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC;IAClE,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAY;QAChB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QAC9D,OAAO,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC;IACjC,CAAC;IAED,0DAA0D;IAC1D,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;IACpB,CAAC;IAED,6CAA6C;IAC7C,cAAc,CAAC,IAAY;QACzB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IACzD,CAAC;CACF"}
@@ -1,19 +0,0 @@
1
- import type { AgentManifest } from "./manifest.js";
2
- export interface HandlerAction {
3
- type: "reply" | "forward" | "drop" | "inbox";
4
- body?: string;
5
- to?: string;
6
- }
7
- export interface MailMessage {
8
- id: string;
9
- from: string;
10
- to: string;
11
- body: string;
12
- timestamp: string;
13
- }
14
- /**
15
- * Runs the mail handler pipeline for an incoming message.
16
- * Iterates through manifests in priority order (assumed sorted from discoverManifests).
17
- */
18
- export declare function runHandlerPipeline(msg: MailMessage, manifests: AgentManifest[], registeredAgents: string[]): Promise<HandlerAction>;
19
- //# sourceMappingURL=mail-handler.d.ts.map