@tpsdev-ai/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +79 -0
- package/dist/bin/tps.d.ts +3 -0
- package/dist/bin/tps.d.ts.map +1 -0
- package/dist/bin/tps.js +267 -0
- package/dist/bin/tps.js.map +1 -0
- package/dist/src/cli/hire.d.ts +16 -0
- package/dist/src/cli/hire.d.ts.map +1 -0
- package/dist/src/cli/hire.js +176 -0
- package/dist/src/cli/hire.js.map +1 -0
- package/dist/src/cli/office.d.ts +7 -0
- package/dist/src/cli/office.d.ts.map +1 -0
- package/dist/src/cli/office.js +51 -0
- package/dist/src/cli/office.js.map +1 -0
- package/dist/src/cli/review.d.ts +9 -0
- package/dist/src/cli/review.d.ts.map +1 -0
- package/dist/src/cli/review.js +109 -0
- package/dist/src/cli/review.js.map +1 -0
- package/dist/src/cli/roster.d.ts +6 -0
- package/dist/src/cli/roster.d.ts.map +1 -0
- package/dist/src/cli/roster.js +60 -0
- package/dist/src/cli/roster.js.map +1 -0
- package/dist/src/commands/branch.d.ts +14 -0
- package/dist/src/commands/branch.d.ts.map +1 -0
- package/dist/src/commands/branch.js +395 -0
- package/dist/src/commands/branch.js.map +1 -0
- package/dist/src/commands/context.d.ts +9 -0
- package/dist/src/commands/context.d.ts.map +1 -0
- package/dist/src/commands/context.js +57 -0
- package/dist/src/commands/context.js.map +1 -0
- package/dist/src/commands/identity.d.ts +13 -0
- package/dist/src/commands/identity.d.ts.map +1 -0
- package/dist/src/commands/identity.js +231 -0
- package/dist/src/commands/identity.js.map +1 -0
- package/dist/src/commands/mail.d.ts +12 -0
- package/dist/src/commands/mail.d.ts.map +1 -0
- package/dist/src/commands/mail.js +225 -0
- package/dist/src/commands/mail.js.map +1 -0
- package/dist/src/commands/office.d.ts +19 -0
- package/dist/src/commands/office.d.ts.map +1 -0
- package/dist/src/commands/office.js +598 -0
- package/dist/src/commands/office.js.map +1 -0
- package/dist/src/commands/roster.d.ts +10 -0
- package/dist/src/commands/roster.d.ts.map +1 -0
- package/dist/src/commands/roster.js +143 -0
- package/dist/src/commands/roster.js.map +1 -0
- package/dist/src/generators/claude-code.d.ts +17 -0
- package/dist/src/generators/claude-code.d.ts.map +1 -0
- package/dist/src/generators/claude-code.js +80 -0
- package/dist/src/generators/claude-code.js.map +1 -0
- package/dist/src/generators/codex.d.ts +22 -0
- package/dist/src/generators/codex.d.ts.map +1 -0
- package/dist/src/generators/codex.js +78 -0
- package/dist/src/generators/codex.js.map +1 -0
- package/dist/src/generators/ollama.d.ts +18 -0
- package/dist/src/generators/ollama.d.ts.map +1 -0
- package/dist/src/generators/ollama.js +97 -0
- package/dist/src/generators/ollama.js.map +1 -0
- package/dist/src/generators/openclaw.d.ts +15 -0
- package/dist/src/generators/openclaw.d.ts.map +1 -0
- package/dist/src/generators/openclaw.js +103 -0
- package/dist/src/generators/openclaw.js.map +1 -0
- package/dist/src/generators/registry.d.ts +36 -0
- package/dist/src/generators/registry.d.ts.map +1 -0
- package/dist/src/generators/registry.js +99 -0
- package/dist/src/generators/registry.js.map +1 -0
- package/dist/src/schema/manifest.d.ts +140 -0
- package/dist/src/schema/manifest.d.ts.map +1 -0
- package/dist/src/schema/manifest.js +62 -0
- package/dist/src/schema/manifest.js.map +1 -0
- package/dist/src/schema/report.d.ts +166 -0
- package/dist/src/schema/report.d.ts.map +1 -0
- package/dist/src/schema/report.js +90 -0
- package/dist/src/schema/report.js.map +1 -0
- package/dist/src/schema/sanitizer.d.ts +30 -0
- package/dist/src/schema/sanitizer.d.ts.map +1 -0
- package/dist/src/schema/sanitizer.js +97 -0
- package/dist/src/schema/sanitizer.js.map +1 -0
- package/dist/src/soundstage/mock-llm.d.ts +3 -0
- package/dist/src/soundstage/mock-llm.d.ts.map +1 -0
- package/dist/src/soundstage/mock-llm.js +68 -0
- package/dist/src/soundstage/mock-llm.js.map +1 -0
- package/dist/src/utils/agent-info.d.ts +28 -0
- package/dist/src/utils/agent-info.d.ts.map +1 -0
- package/dist/src/utils/agent-info.js +102 -0
- package/dist/src/utils/agent-info.js.map +1 -0
- package/dist/src/utils/archive.d.ts +27 -0
- package/dist/src/utils/archive.d.ts.map +1 -0
- package/dist/src/utils/archive.js +80 -0
- package/dist/src/utils/archive.js.map +1 -0
- package/dist/src/utils/config-inject.d.ts +27 -0
- package/dist/src/utils/config-inject.d.ts.map +1 -0
- package/dist/src/utils/config-inject.js +83 -0
- package/dist/src/utils/config-inject.js.map +1 -0
- package/dist/src/utils/config.d.ts +30 -0
- package/dist/src/utils/config.d.ts.map +1 -0
- package/dist/src/utils/config.js +55 -0
- package/dist/src/utils/config.js.map +1 -0
- package/dist/src/utils/connection-state.d.ts +27 -0
- package/dist/src/utils/connection-state.d.ts.map +1 -0
- package/dist/src/utils/connection-state.js +81 -0
- package/dist/src/utils/connection-state.js.map +1 -0
- package/dist/src/utils/context.d.ts +14 -0
- package/dist/src/utils/context.d.ts.map +1 -0
- package/dist/src/utils/context.js +68 -0
- package/dist/src/utils/context.js.map +1 -0
- package/dist/src/utils/github-webhook.d.ts +3 -0
- package/dist/src/utils/github-webhook.d.ts.map +1 -0
- package/dist/src/utils/github-webhook.js +105 -0
- package/dist/src/utils/github-webhook.js.map +1 -0
- package/dist/src/utils/identity.d.ts +114 -0
- package/dist/src/utils/identity.d.ts.map +1 -0
- package/dist/src/utils/identity.js +341 -0
- package/dist/src/utils/identity.js.map +1 -0
- package/dist/src/utils/internal-mail.d.ts +18 -0
- package/dist/src/utils/internal-mail.d.ts.map +1 -0
- package/dist/src/utils/internal-mail.js +75 -0
- package/dist/src/utils/internal-mail.js.map +1 -0
- package/dist/src/utils/loop-detector.d.ts +27 -0
- package/dist/src/utils/loop-detector.d.ts.map +1 -0
- package/dist/src/utils/loop-detector.js +42 -0
- package/dist/src/utils/loop-detector.js.map +1 -0
- package/dist/src/utils/mail-handler.d.ts +19 -0
- package/dist/src/utils/mail-handler.d.ts.map +1 -0
- package/dist/src/utils/mail-handler.js +94 -0
- package/dist/src/utils/mail-handler.js.map +1 -0
- package/dist/src/utils/mail.d.ts +22 -0
- package/dist/src/utils/mail.d.ts.map +1 -0
- package/dist/src/utils/mail.js +111 -0
- package/dist/src/utils/mail.js.map +1 -0
- package/dist/src/utils/manifest.d.ts +36 -0
- package/dist/src/utils/manifest.d.ts.map +1 -0
- package/dist/src/utils/manifest.js +91 -0
- package/dist/src/utils/manifest.js.map +1 -0
- package/dist/src/utils/noise-ik-transport.d.ts +18 -0
- package/dist/src/utils/noise-ik-transport.d.ts.map +1 -0
- package/dist/src/utils/noise-ik-transport.js +357 -0
- package/dist/src/utils/noise-ik-transport.js.map +1 -0
- package/dist/src/utils/nono.d.ts +72 -0
- package/dist/src/utils/nono.d.ts.map +1 -0
- package/dist/src/utils/nono.js +166 -0
- package/dist/src/utils/nono.js.map +1 -0
- package/dist/src/utils/outbox.d.ts +10 -0
- package/dist/src/utils/outbox.d.ts.map +1 -0
- package/dist/src/utils/outbox.js +29 -0
- package/dist/src/utils/outbox.js.map +1 -0
- package/dist/src/utils/output.d.ts +17 -0
- package/dist/src/utils/output.d.ts.map +1 -0
- package/dist/src/utils/output.js +83 -0
- package/dist/src/utils/output.js.map +1 -0
- package/dist/src/utils/plain-tcp-transport.d.ts +10 -0
- package/dist/src/utils/plain-tcp-transport.d.ts.map +1 -0
- package/dist/src/utils/plain-tcp-transport.js +209 -0
- package/dist/src/utils/plain-tcp-transport.js.map +1 -0
- package/dist/src/utils/provision.d.ts +2 -0
- package/dist/src/utils/provision.d.ts.map +1 -0
- package/dist/src/utils/provision.js +186 -0
- package/dist/src/utils/provision.js.map +1 -0
- package/dist/src/utils/relay.d.ts +30 -0
- package/dist/src/utils/relay.d.ts.map +1 -0
- package/dist/src/utils/relay.js +539 -0
- package/dist/src/utils/relay.js.map +1 -0
- package/dist/src/utils/sandbox.d.ts +37 -0
- package/dist/src/utils/sandbox.d.ts.map +1 -0
- package/dist/src/utils/sandbox.js +126 -0
- package/dist/src/utils/sandbox.js.map +1 -0
- package/dist/src/utils/transport.d.ts +62 -0
- package/dist/src/utils/transport.d.ts.map +1 -0
- package/dist/src/utils/transport.js +75 -0
- package/dist/src/utils/transport.js.map +1 -0
- package/dist/src/utils/wall.d.ts +5 -0
- package/dist/src/utils/wall.d.ts.map +1 -0
- package/dist/src/utils/wall.js +51 -0
- package/dist/src/utils/wall.js.map +1 -0
- package/dist/src/utils/wire-delivery.d.ts +10 -0
- package/dist/src/utils/wire-delivery.d.ts.map +1 -0
- package/dist/src/utils/wire-delivery.js +57 -0
- package/dist/src/utils/wire-delivery.js.map +1 -0
- package/dist/src/utils/wire-frame.d.ts +10 -0
- package/dist/src/utils/wire-frame.d.ts.map +1 -0
- package/dist/src/utils/wire-frame.js +66 -0
- package/dist/src/utils/wire-frame.js.map +1 -0
- package/dist/src/utils/wire-mail.d.ts +54 -0
- package/dist/src/utils/wire-mail.d.ts.map +1 -0
- package/dist/src/utils/wire-mail.js +24 -0
- package/dist/src/utils/wire-mail.js.map +1 -0
- package/dist/src/utils/ws-noise-transport.d.ts +18 -0
- package/dist/src/utils/ws-noise-transport.d.ts.map +1 -0
- package/dist/src/utils/ws-noise-transport.js +356 -0
- package/dist/src/utils/ws-noise-transport.js.map +1 -0
- package/nono-profiles/tps-hire.toml +17 -0
- package/nono-profiles/tps-review-deep.toml +18 -0
- package/nono-profiles/tps-review-local.toml +21 -0
- package/nono-profiles/tps-roster.toml +16 -0
- package/package.json +68 -0
- package/personas/designer.tps +58 -0
- package/personas/developer.tps +59 -0
- package/personas/ea.tps +59 -0
- package/personas/ops.tps +60 -0
- package/personas/security.tps +59 -0
- package/personas/strategy.tps +60 -0
- package/personas/support.tps +57 -0
- package/reports/anvil.tps +68 -0
- package/reports/flint.tps +71 -0
- package/reports/kern.tps +65 -0
- package/reports/pulse.tps +64 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, readdirSync, renameSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
function outboxDir(kind) {
|
|
6
|
+
return join(process.env.HOME || homedir(), ".tps", "outbox", kind);
|
|
7
|
+
}
|
|
8
|
+
export function queueOutboxMessage(to, body, from) {
|
|
9
|
+
const dir = outboxDir("new");
|
|
10
|
+
mkdirSync(dir, { recursive: true });
|
|
11
|
+
const id = randomUUID();
|
|
12
|
+
const timestamp = new Date().toISOString();
|
|
13
|
+
const filename = `${timestamp.replace(/[:.]/g, "-")}-${id}.json`;
|
|
14
|
+
writeFileSync(join(dir, filename), JSON.stringify({ id, to, from, body, timestamp }, null, 2), "utf-8");
|
|
15
|
+
}
|
|
16
|
+
export function drainOutbox() {
|
|
17
|
+
const newDir = outboxDir("new");
|
|
18
|
+
const sentDir = outboxDir("sent");
|
|
19
|
+
mkdirSync(newDir, { recursive: true });
|
|
20
|
+
mkdirSync(sentDir, { recursive: true });
|
|
21
|
+
const files = readdirSync(newDir).filter((f) => f.endsWith(".json"));
|
|
22
|
+
return files.map((f) => {
|
|
23
|
+
const src = join(newDir, f);
|
|
24
|
+
const msg = JSON.parse(readFileSync(src, "utf-8"));
|
|
25
|
+
renameSync(src, join(sentDir, f));
|
|
26
|
+
return msg;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=outbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbox.js","sourceRoot":"","sources":["../../../src/utils/outbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC1F,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAUlC,SAAS,SAAS,CAAC,IAAoB;IACrC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,EAAU,EAAE,IAAY,EAAE,IAAY;IACvE,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC7B,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;IACxB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,QAAQ,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC;IACjE,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AAC1G,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAClC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAExC,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IACrE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAkB,CAAC;QACpE,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAClC,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const quips: {
|
|
2
|
+
success: string[];
|
|
3
|
+
error: string[];
|
|
4
|
+
empty: string[];
|
|
5
|
+
};
|
|
6
|
+
export declare function randomQuip(category: keyof typeof quips): string;
|
|
7
|
+
export declare function formatBytes(bytes: number): string;
|
|
8
|
+
/**
|
|
9
|
+
* Resolve a report path argument to an actual file path.
|
|
10
|
+
*
|
|
11
|
+
* Lookup order:
|
|
12
|
+
* 1. If it contains `/` or ends in `.tps` → treat as file path
|
|
13
|
+
* 2. Otherwise → look for matching persona in built-in personas directory
|
|
14
|
+
* 3. If not found → error with Office Space flavor
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveReportPath(input: string): string;
|
|
17
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../src/utils/output.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,KAAK;;;;CAiBjB,CAAC;AAEF,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,OAAO,KAAK,GAAG,MAAM,CAG/D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjD;AAqBD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CA0BvD"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join, dirname } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
5
|
+
const __dirname = dirname(__filename);
|
|
6
|
+
export const quips = {
|
|
7
|
+
success: [
|
|
8
|
+
"Yeah, if you could go ahead and add that config, that'd be great.",
|
|
9
|
+
"Welcome to Initech. I mean, your org.",
|
|
10
|
+
"That's... that's a terrific TPS report. Really terrific.",
|
|
11
|
+
"Looks like somebody's got a case of the promotions.",
|
|
12
|
+
],
|
|
13
|
+
error: [
|
|
14
|
+
"PC Load Letter? What does that even mean?",
|
|
15
|
+
"I'm gonna need you to go ahead and fix that.",
|
|
16
|
+
"Somebody's got a case of the Mondays.",
|
|
17
|
+
],
|
|
18
|
+
empty: [
|
|
19
|
+
"Looks like someone has a case of the Mondays.",
|
|
20
|
+
"I... I believe you have my stapler.",
|
|
21
|
+
"What exactly would you say... you do here?",
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
export function randomQuip(category) {
|
|
25
|
+
const arr = quips[category];
|
|
26
|
+
return arr[Math.floor(Math.random() * arr.length)];
|
|
27
|
+
}
|
|
28
|
+
export function formatBytes(bytes) {
|
|
29
|
+
if (bytes < 1024)
|
|
30
|
+
return `${bytes}b`;
|
|
31
|
+
return `${(bytes / 1024).toFixed(1)}kb`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Available built-in persona names.
|
|
35
|
+
*/
|
|
36
|
+
const BUILTIN_PERSONAS = ["developer", "designer", "support", "ea", "ops", "strategy", "security"];
|
|
37
|
+
/**
|
|
38
|
+
* Find the personas directory — works from both dist and source layouts.
|
|
39
|
+
*/
|
|
40
|
+
function findPersonasDir() {
|
|
41
|
+
const candidates = [
|
|
42
|
+
join(__dirname, "..", "..", "personas"), // dist/src/utils -> personas
|
|
43
|
+
join(__dirname, "..", "..", "..", "personas"), // deeper nesting
|
|
44
|
+
];
|
|
45
|
+
for (const c of candidates) {
|
|
46
|
+
if (existsSync(c))
|
|
47
|
+
return c;
|
|
48
|
+
}
|
|
49
|
+
throw new Error("Can't find personas directory.");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Resolve a report path argument to an actual file path.
|
|
53
|
+
*
|
|
54
|
+
* Lookup order:
|
|
55
|
+
* 1. If it contains `/` or ends in `.tps` → treat as file path
|
|
56
|
+
* 2. Otherwise → look for matching persona in built-in personas directory
|
|
57
|
+
* 3. If not found → error with Office Space flavor
|
|
58
|
+
*/
|
|
59
|
+
export function resolveReportPath(input) {
|
|
60
|
+
// Direct file path
|
|
61
|
+
if (input.includes("/") || input.endsWith(".tps")) {
|
|
62
|
+
if (!existsSync(input)) {
|
|
63
|
+
throw new Error(`PC Load Letter? Couldn't read file: ${input}\nCheck the path and try again.`);
|
|
64
|
+
}
|
|
65
|
+
return input;
|
|
66
|
+
}
|
|
67
|
+
// Built-in persona lookup
|
|
68
|
+
const personaName = input.toLowerCase();
|
|
69
|
+
try {
|
|
70
|
+
const personasDir = findPersonasDir();
|
|
71
|
+
const personaPath = join(personasDir, `${personaName}.tps`);
|
|
72
|
+
if (existsSync(personaPath)) {
|
|
73
|
+
return personaPath;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// personas dir not found, fall through
|
|
78
|
+
}
|
|
79
|
+
throw new Error(`I'm gonna need you to be more specific about that TPS report.\n\n` +
|
|
80
|
+
`"${input}" is not a file path or a known persona.\n` +
|
|
81
|
+
`Built-in personas: ${BUILTIN_PERSONAS.join(", ")}`);
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/utils/output.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { BranchTarget, TransportChannel, TransportServer, WireTransport } from "./transport.js";
|
|
2
|
+
import { type TpsKeyPair } from "./identity.js";
|
|
3
|
+
export declare class PlainTcpTransport implements WireTransport {
|
|
4
|
+
private readonly branchKeyPair;
|
|
5
|
+
private readonly hostKeyPair?;
|
|
6
|
+
constructor(branchKeyPair: TpsKeyPair, hostKeyPair?: TpsKeyPair | undefined);
|
|
7
|
+
listen(port: number): Promise<TransportServer>;
|
|
8
|
+
connect(target: BranchTarget): Promise<TransportChannel>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=plain-tcp-transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plain-tcp-transport.d.ts","sourceRoot":"","sources":["../../../src/utils/plain-tcp-transport.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,eAAe,EAEf,aAAa,EACd,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAA+C,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAsJ7F,qBAAa,iBAAkB,YAAW,aAAa;IAEnD,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;gBADZ,aAAa,EAAE,UAAU,EACzB,WAAW,CAAC,EAAE,UAAU,YAAA;IAGrC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IA2C9C,OAAO,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;CA6B/D"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WARNING: No encryption. Plain TCP with pubkey identity check.
|
|
3
|
+
* Messages are transmitted in cleartext. Do NOT use over untrusted networks.
|
|
4
|
+
* Real Noise_IK encryption will replace this before remote branch support ships.
|
|
5
|
+
*/
|
|
6
|
+
import net from "node:net";
|
|
7
|
+
import { EventEmitter } from "node:events";
|
|
8
|
+
import { HEADER_BYTES, MAX_PAYLOAD_BYTES, extractWireFrames, encodeWireMessage } from "./wire-frame.js";
|
|
9
|
+
import { fingerprint, loadHostIdentity, lookupBranch } from "./identity.js";
|
|
10
|
+
function readJsonLine(socket) {
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
let buf = "";
|
|
13
|
+
const MAX_HANDSHAKE_BYTES = 65536;
|
|
14
|
+
const cleanup = () => {
|
|
15
|
+
socket.off("data", onData);
|
|
16
|
+
socket.off("error", onErr);
|
|
17
|
+
socket.off("close", onClose);
|
|
18
|
+
socket.off("end", onClose);
|
|
19
|
+
};
|
|
20
|
+
const onErr = (err) => {
|
|
21
|
+
cleanup();
|
|
22
|
+
reject(err);
|
|
23
|
+
};
|
|
24
|
+
const onClose = () => {
|
|
25
|
+
cleanup();
|
|
26
|
+
reject(new Error("Socket closed before complete frame"));
|
|
27
|
+
};
|
|
28
|
+
const onData = (chunk) => {
|
|
29
|
+
buf += chunk.toString("utf-8");
|
|
30
|
+
if (buf.length > MAX_HANDSHAKE_BYTES) {
|
|
31
|
+
cleanup();
|
|
32
|
+
socket.destroy();
|
|
33
|
+
reject(new Error("Handshake message too large"));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const idx = buf.indexOf("\n");
|
|
37
|
+
if (idx >= 0) {
|
|
38
|
+
cleanup();
|
|
39
|
+
try {
|
|
40
|
+
resolve(JSON.parse(buf.slice(0, idx)));
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
reject(e);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
socket.on("data", onData);
|
|
48
|
+
socket.once("error", onErr);
|
|
49
|
+
socket.once("close", onClose);
|
|
50
|
+
socket.once("end", onClose);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function writeJsonLine(socket, obj) {
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
socket.write(`${JSON.stringify(obj)}\n`, (err) => {
|
|
56
|
+
if (err)
|
|
57
|
+
reject(err);
|
|
58
|
+
else
|
|
59
|
+
resolve();
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
class PlainTcpChannel {
|
|
64
|
+
socket;
|
|
65
|
+
peerFp;
|
|
66
|
+
alive = true;
|
|
67
|
+
emitter = new EventEmitter();
|
|
68
|
+
rxBuffer = Buffer.alloc(0);
|
|
69
|
+
constructor(socket, peerFp) {
|
|
70
|
+
this.socket = socket;
|
|
71
|
+
this.peerFp = peerFp;
|
|
72
|
+
this.socket.on("close", () => {
|
|
73
|
+
this.alive = false;
|
|
74
|
+
});
|
|
75
|
+
this.socket.on("data", (chunk) => {
|
|
76
|
+
try {
|
|
77
|
+
this.rxBuffer = Buffer.from(Buffer.concat([this.rxBuffer, chunk]));
|
|
78
|
+
if (this.rxBuffer.length > MAX_PAYLOAD_BYTES + HEADER_BYTES) {
|
|
79
|
+
this.socket.destroy();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const { messages, rest } = extractWireFrames(this.rxBuffer);
|
|
83
|
+
this.rxBuffer = rest;
|
|
84
|
+
for (const msg of messages) {
|
|
85
|
+
this.emitter.emit("message", msg);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
this.socket.destroy();
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
async send(msg) {
|
|
94
|
+
const frame = encodeWireMessage(msg);
|
|
95
|
+
await new Promise((resolve, reject) => {
|
|
96
|
+
this.socket.write(frame, (err) => (err ? reject(err) : resolve()));
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
onMessage(handler) {
|
|
100
|
+
this.emitter.on("message", handler);
|
|
101
|
+
}
|
|
102
|
+
offMessage(handler) {
|
|
103
|
+
this.emitter.off("message", handler);
|
|
104
|
+
}
|
|
105
|
+
async close() {
|
|
106
|
+
this.socket.end();
|
|
107
|
+
this.alive = false;
|
|
108
|
+
}
|
|
109
|
+
isAlive() {
|
|
110
|
+
return this.alive && !this.socket.destroyed;
|
|
111
|
+
}
|
|
112
|
+
peerFingerprint() {
|
|
113
|
+
return this.peerFp;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
class PlainTcpServer {
|
|
117
|
+
server;
|
|
118
|
+
onConn = null;
|
|
119
|
+
constructor(server) {
|
|
120
|
+
this.server = server;
|
|
121
|
+
}
|
|
122
|
+
port() {
|
|
123
|
+
const addr = this.server.address();
|
|
124
|
+
if (!addr || typeof addr === "string")
|
|
125
|
+
return 0;
|
|
126
|
+
return addr.port;
|
|
127
|
+
}
|
|
128
|
+
onConnection(handler) {
|
|
129
|
+
this.onConn = handler;
|
|
130
|
+
}
|
|
131
|
+
dispatch(channel) {
|
|
132
|
+
this.onConn?.(channel);
|
|
133
|
+
}
|
|
134
|
+
async close() {
|
|
135
|
+
await new Promise((resolve, reject) => {
|
|
136
|
+
this.server.close((err) => (err ? reject(err) : resolve()));
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
export class PlainTcpTransport {
|
|
141
|
+
branchKeyPair;
|
|
142
|
+
hostKeyPair;
|
|
143
|
+
constructor(branchKeyPair, hostKeyPair) {
|
|
144
|
+
this.branchKeyPair = branchKeyPair;
|
|
145
|
+
this.hostKeyPair = hostKeyPair;
|
|
146
|
+
}
|
|
147
|
+
async listen(port) {
|
|
148
|
+
const host = this.hostKeyPair ?? loadHostIdentity();
|
|
149
|
+
const server = net.createServer();
|
|
150
|
+
const wrapper = new PlainTcpServer(server);
|
|
151
|
+
server.on("connection", async (socket) => {
|
|
152
|
+
try {
|
|
153
|
+
const init = (await readJsonLine(socket));
|
|
154
|
+
if (init?.kind !== "noise_ik_init") {
|
|
155
|
+
socket.destroy();
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
// WARNING: connection is NOT authenticated until Noise_IK handshake completes.
|
|
159
|
+
// Do not trust branchId until post-handshake.
|
|
160
|
+
const known = lookupBranch(init.branchId);
|
|
161
|
+
const expectedPub = known?.publicKey ? Buffer.from(known.publicKey).toString("hex") : null;
|
|
162
|
+
if (!expectedPub || expectedPub !== init.branchPub) {
|
|
163
|
+
socket.destroy();
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const branchFp = fingerprint(Buffer.from(init.branchPub, "hex"));
|
|
167
|
+
await writeJsonLine(socket, {
|
|
168
|
+
kind: "noise_ik_resp",
|
|
169
|
+
hostPub: Buffer.from(host.signing.publicKey).toString("hex"),
|
|
170
|
+
peerFingerprint: branchFp,
|
|
171
|
+
});
|
|
172
|
+
wrapper.dispatch(new PlainTcpChannel(socket, branchFp));
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
socket.destroy();
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
await new Promise((resolve, reject) => {
|
|
179
|
+
server.listen(port, "127.0.0.1", () => resolve());
|
|
180
|
+
server.once("error", reject);
|
|
181
|
+
});
|
|
182
|
+
return wrapper;
|
|
183
|
+
}
|
|
184
|
+
async connect(target) {
|
|
185
|
+
const socket = net.createConnection({ host: target.host, port: target.port });
|
|
186
|
+
await new Promise((resolve, reject) => {
|
|
187
|
+
socket.once("connect", () => resolve());
|
|
188
|
+
socket.once("error", reject);
|
|
189
|
+
});
|
|
190
|
+
await writeJsonLine(socket, {
|
|
191
|
+
kind: "noise_ik_init",
|
|
192
|
+
branchId: target.branchId,
|
|
193
|
+
branchPub: Buffer.from(this.branchKeyPair.signing.publicKey).toString("hex"),
|
|
194
|
+
});
|
|
195
|
+
const resp = (await readJsonLine(socket));
|
|
196
|
+
if (resp?.kind !== "noise_ik_resp") {
|
|
197
|
+
socket.destroy();
|
|
198
|
+
throw new Error("Invalid handshake response message");
|
|
199
|
+
}
|
|
200
|
+
const expectedHostPub = Buffer.from(target.hostPublicKey).toString("hex");
|
|
201
|
+
if (resp.hostPub !== expectedHostPub) {
|
|
202
|
+
socket.destroy();
|
|
203
|
+
throw new Error("Host key mismatch");
|
|
204
|
+
}
|
|
205
|
+
const hostFp = fingerprint(Buffer.from(resp.hostPub, "hex"));
|
|
206
|
+
return new PlainTcpChannel(socket, hostFp);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=plain-tcp-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plain-tcp-transport.js","sourceRoot":"","sources":["../../../src/utils/plain-tcp-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provision.d.ts","sourceRoot":"","sources":["../../../src/utils/provision.ts"],"names":[],"mappings":"AA4DA,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CA6J9E"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { dirname, join, resolve } from "node:path";
|
|
2
|
+
import { copyFileSync, lstatSync, mkdirSync, realpathSync, statSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { parseOfficeManifest } from "../schema/manifest.js";
|
|
4
|
+
import { resolveReportPath } from "./output.js";
|
|
5
|
+
import { parseTPSReport } from "../schema/report.js";
|
|
6
|
+
import { generateWorkspace } from "../generators/openclaw.js";
|
|
7
|
+
import { sanitizeIdentifier } from "../schema/sanitizer.js";
|
|
8
|
+
import { getInternalInbox } from "./internal-mail.js";
|
|
9
|
+
import { initWall } from "./wall.js";
|
|
10
|
+
function isWithin(base, candidate) {
|
|
11
|
+
const b = resolve(base);
|
|
12
|
+
const c = resolve(candidate);
|
|
13
|
+
return c === b || c.startsWith(`${b}/`);
|
|
14
|
+
}
|
|
15
|
+
function validateAndResolveHostMount(hostPath) {
|
|
16
|
+
const expanded = hostPath.startsWith("~/")
|
|
17
|
+
? join(process.env.HOME || "", hostPath.slice(2))
|
|
18
|
+
: hostPath;
|
|
19
|
+
const absolute = resolve(expanded);
|
|
20
|
+
const home = resolve(process.env.HOME || "");
|
|
21
|
+
const homeReal = realpathSync(home);
|
|
22
|
+
if (!isWithin(home, absolute) && !isWithin(homeReal, absolute)) {
|
|
23
|
+
throw new Error(`Mount host path must stay within HOME: ${hostPath}`);
|
|
24
|
+
}
|
|
25
|
+
const lst = lstatSync(absolute);
|
|
26
|
+
if (lst.isSymbolicLink()) {
|
|
27
|
+
throw new Error(`Mount host path cannot be a symlink: ${hostPath}`);
|
|
28
|
+
}
|
|
29
|
+
const real = realpathSync(absolute);
|
|
30
|
+
if (!isWithin(homeReal, real)) {
|
|
31
|
+
throw new Error(`Mount host path resolves outside HOME: ${hostPath}`);
|
|
32
|
+
}
|
|
33
|
+
const st = statSync(real);
|
|
34
|
+
if (!st.isFile()) {
|
|
35
|
+
throw new Error(`Mount host path must be a regular file: ${hostPath}`);
|
|
36
|
+
}
|
|
37
|
+
return real;
|
|
38
|
+
}
|
|
39
|
+
function validateAndResolveTargetMount(sharedWorkspace, targetPath) {
|
|
40
|
+
if (targetPath.startsWith("/") || targetPath.includes("..")) {
|
|
41
|
+
throw new Error(`Mount target must be a relative workspace path: ${targetPath}`);
|
|
42
|
+
}
|
|
43
|
+
const wsReal = realpathSync(sharedWorkspace);
|
|
44
|
+
const absolute = resolve(wsReal, targetPath);
|
|
45
|
+
if (!isWithin(wsReal, absolute)) {
|
|
46
|
+
throw new Error(`Mount target escapes workspace: ${targetPath}`);
|
|
47
|
+
}
|
|
48
|
+
return absolute;
|
|
49
|
+
}
|
|
50
|
+
export function provisionTeam(manifestPath, branchRoot) {
|
|
51
|
+
const manifest = parseOfficeManifest(manifestPath);
|
|
52
|
+
if (manifest.purpose === "adversarial") {
|
|
53
|
+
throw new Error("Adversarial offices require per-agent isolation (not yet implemented). Use 'development', 'research', or 'ops' purpose instead.");
|
|
54
|
+
}
|
|
55
|
+
const teamId = sanitizeIdentifier(manifest.name);
|
|
56
|
+
const teamDir = join(branchRoot, teamId);
|
|
57
|
+
const dotOpenClaw = join(teamDir, ".openclaw");
|
|
58
|
+
const agentsRoot = join(dotOpenClaw, "agents");
|
|
59
|
+
const sharedWorkspace = join(teamDir, "workspace");
|
|
60
|
+
mkdirSync(dotOpenClaw, { recursive: true });
|
|
61
|
+
mkdirSync(agentsRoot, { recursive: true });
|
|
62
|
+
mkdirSync(sharedWorkspace, { recursive: true });
|
|
63
|
+
const agentConfigs = [];
|
|
64
|
+
const agents = [manifest.manager, ...manifest.agents];
|
|
65
|
+
const agentIds = new Set();
|
|
66
|
+
for (const agentSpec of agents) {
|
|
67
|
+
const reportPath = resolveReportPath(agentSpec.persona);
|
|
68
|
+
const report = parseTPSReport(reportPath);
|
|
69
|
+
if (agentSpec.role) {
|
|
70
|
+
report.name = agentSpec.role;
|
|
71
|
+
}
|
|
72
|
+
// Determine agent ID ahead of time to build paths
|
|
73
|
+
const tempGen = generateWorkspace(report, { name: agentSpec.name });
|
|
74
|
+
const agentId = String(tempGen.config.id);
|
|
75
|
+
if (agentIds.has(agentId)) {
|
|
76
|
+
throw new Error(`Duplicate agent ID in manifest: ${agentId}`);
|
|
77
|
+
}
|
|
78
|
+
agentIds.add(agentId);
|
|
79
|
+
const agentDir = join(agentsRoot, agentId, "agent");
|
|
80
|
+
const isManager = agentSpec === manifest.manager;
|
|
81
|
+
// Generate with correct paths
|
|
82
|
+
const generated = generateWorkspace(report, {
|
|
83
|
+
name: agentSpec.name,
|
|
84
|
+
workspace: sharedWorkspace,
|
|
85
|
+
branch: true,
|
|
86
|
+
agentDir: agentDir,
|
|
87
|
+
isManager: isManager,
|
|
88
|
+
});
|
|
89
|
+
// Write agent definition files to agentDir
|
|
90
|
+
mkdirSync(agentDir, { recursive: true });
|
|
91
|
+
for (const [name, content] of Object.entries(generated.files)) {
|
|
92
|
+
// Skip package files for agent dirs
|
|
93
|
+
if (name === "package.json" || name === "package-lock.json") {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
writeFileSync(join(agentDir, name), content, "utf-8");
|
|
97
|
+
}
|
|
98
|
+
agentConfigs.push(generated.config);
|
|
99
|
+
}
|
|
100
|
+
// Write shared openclaw.json
|
|
101
|
+
const sandboxConfig = {
|
|
102
|
+
agents: {
|
|
103
|
+
defaults: {
|
|
104
|
+
model: {
|
|
105
|
+
primary: "anthropic/claude-sonnet-4-6",
|
|
106
|
+
fallbacks: ["ollama/qwen2.5:7b"],
|
|
107
|
+
},
|
|
108
|
+
heartbeat: {
|
|
109
|
+
every: "30m",
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
list: agentConfigs,
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
writeFileSync(join(dotOpenClaw, "openclaw.json"), JSON.stringify(sandboxConfig, null, 2), "utf-8");
|
|
116
|
+
// Write shared package.json and lockfile
|
|
117
|
+
// We can use the templates from the last agent generation, but with team ID
|
|
118
|
+
// Or just construct a minimal one.
|
|
119
|
+
const packageJson = {
|
|
120
|
+
name: `workspace-${teamId}`,
|
|
121
|
+
version: "0.0.0",
|
|
122
|
+
private: true,
|
|
123
|
+
description: "Generated by TPS. Do not modify manually.",
|
|
124
|
+
scripts: {},
|
|
125
|
+
dependencies: {},
|
|
126
|
+
devDependencies: {}
|
|
127
|
+
};
|
|
128
|
+
writeFileSync(join(sharedWorkspace, "package.json"), JSON.stringify(packageJson, null, 2), "utf-8");
|
|
129
|
+
// Minimal lockfile v3
|
|
130
|
+
const lockfile = {
|
|
131
|
+
name: `workspace-${teamId}`,
|
|
132
|
+
version: "0.0.0",
|
|
133
|
+
lockfileVersion: 3,
|
|
134
|
+
requires: true,
|
|
135
|
+
packages: {
|
|
136
|
+
"": {
|
|
137
|
+
name: `workspace-${teamId}`,
|
|
138
|
+
version: "0.0.0",
|
|
139
|
+
license: "UNLICENSED",
|
|
140
|
+
dependencies: {},
|
|
141
|
+
devDependencies: {}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
writeFileSync(join(sharedWorkspace, "package-lock.json"), JSON.stringify(lockfile, null, 2), "utf-8");
|
|
146
|
+
// Setup internal mail inboxes for all agents
|
|
147
|
+
for (const agentId of agentIds) {
|
|
148
|
+
getInternalInbox(sharedWorkspace, agentId);
|
|
149
|
+
}
|
|
150
|
+
// Initialize broadcast wall if enabled
|
|
151
|
+
if (manifest.wall) {
|
|
152
|
+
initWall(sharedWorkspace, manifest.name);
|
|
153
|
+
}
|
|
154
|
+
// Optional context injection (briefs + mounts)
|
|
155
|
+
if (manifest.context?.briefs && manifest.context.briefs.length > 0) {
|
|
156
|
+
const content = [
|
|
157
|
+
"# CONTEXT",
|
|
158
|
+
"",
|
|
159
|
+
...manifest.context.briefs.map((b, i) => `- ${i + 1}. ${b}`),
|
|
160
|
+
"",
|
|
161
|
+
].join("\n");
|
|
162
|
+
writeFileSync(join(sharedWorkspace, "CONTEXT.md"), content, "utf-8");
|
|
163
|
+
}
|
|
164
|
+
if (manifest.context?.mounts && manifest.context.mounts.length > 0) {
|
|
165
|
+
for (const mount of manifest.context.mounts) {
|
|
166
|
+
if (mount.readonly !== true) {
|
|
167
|
+
throw new Error(`Mount readonly must be true: ${mount.target}`);
|
|
168
|
+
}
|
|
169
|
+
const source = validateAndResolveHostMount(mount.host);
|
|
170
|
+
const target = validateAndResolveTargetMount(sharedWorkspace, mount.target);
|
|
171
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
172
|
+
copyFileSync(source, target);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Write team membership sidecar for relay lookups
|
|
176
|
+
// Relay reads this instead of re-parsing office.yaml on every delivery
|
|
177
|
+
const teamMembership = {
|
|
178
|
+
teamId,
|
|
179
|
+
members: Array.from(agentIds),
|
|
180
|
+
workspaceMail: join(sharedWorkspace, "mail"),
|
|
181
|
+
createdAt: new Date().toISOString(),
|
|
182
|
+
};
|
|
183
|
+
writeFileSync(join(teamDir, "team.json"), JSON.stringify(teamMembership, null, 2), "utf-8");
|
|
184
|
+
return teamDir;
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=provision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provision.js","sourceRoot":"","sources":["../../../src/utils/provision.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { TransportRegistry, type TpsMessage } from "./transport.js";
|
|
2
|
+
export interface RelayMessage {
|
|
3
|
+
id?: string;
|
|
4
|
+
from?: string;
|
|
5
|
+
to: string;
|
|
6
|
+
body: string;
|
|
7
|
+
timestamp?: string;
|
|
8
|
+
read?: boolean;
|
|
9
|
+
origin?: string;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function processOutboxOnce(agentId: string): Promise<{
|
|
13
|
+
processed: number;
|
|
14
|
+
failed: number;
|
|
15
|
+
}>;
|
|
16
|
+
export declare function connectRemoteBranches(registry: TransportRegistry, onMail?: (branchId: string, msg: TpsMessage) => void): Promise<{
|
|
17
|
+
connected: string[];
|
|
18
|
+
cleanup: () => Promise<void>;
|
|
19
|
+
}>;
|
|
20
|
+
export declare function handleIncomingMail(branchId: string, msg: TpsMessage): void;
|
|
21
|
+
export declare function startRelay(agentId: string): () => void;
|
|
22
|
+
export declare function deliverToRemoteBranch(branchId: string, message: RelayMessage): Promise<void>;
|
|
23
|
+
export declare function syncRemoteBranch(branchId: string): Promise<{
|
|
24
|
+
received: number;
|
|
25
|
+
}>;
|
|
26
|
+
export declare function connectAndKeepAlive(branchId: string, opts?: {
|
|
27
|
+
onMessage?: (msg: TpsMessage) => void;
|
|
28
|
+
}): Promise<() => Promise<void>>;
|
|
29
|
+
export declare function deliverToSandbox(agentId: string, message: RelayMessage): void;
|
|
30
|
+
//# sourceMappingURL=relay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../../../src/utils/relay.ts"],"names":[],"mappings":"AAOA,OAAO,EAAyC,iBAAiB,EAAyB,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAQlI,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAyED,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA8FvG;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,KAAK,IAAI,GACnD,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAuFhE;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAsB1E;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,IAAI,CA6BtD;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC,CAoFf;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAiDtF;AAMD,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAA;CAAO,GACnD,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CA4F9B;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,CAkB7E"}
|