@cotal-ai/manager 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.
Files changed (46) hide show
  1. package/LICENSE +202 -0
  2. package/dist/attach-client.d.ts +7 -0
  3. package/dist/attach-client.d.ts.map +1 -0
  4. package/dist/attach-client.js +48 -0
  5. package/dist/attach-client.js.map +1 -0
  6. package/dist/attach-endpoint.d.ts +38 -0
  7. package/dist/attach-endpoint.d.ts.map +1 -0
  8. package/dist/attach-endpoint.js +171 -0
  9. package/dist/attach-endpoint.js.map +1 -0
  10. package/dist/commands.d.ts +2 -0
  11. package/dist/commands.d.ts.map +1 -0
  12. package/dist/commands.js +157 -0
  13. package/dist/commands.js.map +1 -0
  14. package/dist/index.d.ts +4 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +3 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/manager.d.ts +43 -0
  19. package/dist/manager.d.ts.map +1 -0
  20. package/dist/manager.js +207 -0
  21. package/dist/manager.js.map +1 -0
  22. package/dist/runtime/cmux.d.ts +16 -0
  23. package/dist/runtime/cmux.d.ts.map +1 -0
  24. package/dist/runtime/cmux.js +50 -0
  25. package/dist/runtime/cmux.js.map +1 -0
  26. package/dist/runtime/index.d.ts +12 -0
  27. package/dist/runtime/index.d.ts.map +1 -0
  28. package/dist/runtime/index.js +34 -0
  29. package/dist/runtime/index.js.map +1 -0
  30. package/dist/runtime/pty.d.ts +13 -0
  31. package/dist/runtime/pty.d.ts.map +1 -0
  32. package/dist/runtime/pty.js +113 -0
  33. package/dist/runtime/pty.js.map +1 -0
  34. package/dist/runtime/tmux.d.ts +16 -0
  35. package/dist/runtime/tmux.d.ts.map +1 -0
  36. package/dist/runtime/tmux.js +77 -0
  37. package/dist/runtime/tmux.js.map +1 -0
  38. package/dist/runtime/types.d.ts +38 -0
  39. package/dist/runtime/types.d.ts.map +1 -0
  40. package/dist/runtime/types.js +2 -0
  41. package/dist/runtime/types.js.map +1 -0
  42. package/dist/ui.d.ts +10 -0
  43. package/dist/ui.d.ts.map +1 -0
  44. package/dist/ui.js +10 -0
  45. package/dist/ui.js.map +1 -0
  46. package/package.json +36 -0
@@ -0,0 +1,77 @@
1
+ import { execFileSync } from "node:child_process";
2
+ export function tmuxAvailable() {
3
+ try {
4
+ execFileSync("tmux", ["-V"], { stdio: "ignore" });
5
+ return true;
6
+ }
7
+ catch {
8
+ return false;
9
+ }
10
+ }
11
+ function shellQuote(s) {
12
+ return `'${s.replace(/'/g, "'\\''")}'`;
13
+ }
14
+ function hasSession(session) {
15
+ try {
16
+ execFileSync("tmux", ["has-session", "-t", session], { stdio: "ignore" });
17
+ return true;
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ }
23
+ function windowAlive(session, name) {
24
+ try {
25
+ const out = execFileSync("tmux", ["list-windows", "-t", session, "-F", "#W"], {
26
+ encoding: "utf8",
27
+ });
28
+ return out.split("\n").includes(name);
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ /**
35
+ * Opt-in runtime for users already living in a multiplexer: each agent gets a
36
+ * tmux window in a shared per-space session. You watch / drive it natively
37
+ * (`tmux attach -t <session>:<name>`), so `attach()` here points you there
38
+ * rather than streaming — the PTY runtime is the streamable default.
39
+ */
40
+ export class TmuxRuntime {
41
+ session;
42
+ kind = "tmux";
43
+ constructor(session) {
44
+ this.session = session;
45
+ }
46
+ spawn(name, spec, cwd) {
47
+ if (!hasSession(this.session)) {
48
+ execFileSync("tmux", ["new-session", "-d", "-s", this.session, "-c", cwd], {
49
+ stdio: "ignore",
50
+ });
51
+ }
52
+ const envPrefix = Object.entries(spec.env ?? {}).map(([k, v]) => `${k}=${shellQuote(v)}`);
53
+ const cmd = [...envPrefix, spec.command, ...spec.args.map(shellQuote)].join(" ");
54
+ execFileSync("tmux", ["new-window", "-t", this.session, "-n", name, "-c", cwd, cmd], { stdio: "ignore" });
55
+ const target = `${this.session}:${name}`;
56
+ return {
57
+ name,
58
+ kind: "tmux",
59
+ status: () => (windowAlive(this.session, name) ? "running" : "exited"),
60
+ stop: () => {
61
+ try {
62
+ execFileSync("tmux", ["kill-window", "-t", target], { stdio: "ignore" });
63
+ }
64
+ catch {
65
+ /* already gone */
66
+ }
67
+ },
68
+ interrupt: () => {
69
+ execFileSync("tmux", ["send-keys", "-t", target, "C-c"], { stdio: "ignore" });
70
+ },
71
+ attach: () => {
72
+ throw new Error(`tmux runtime: attach natively with \`tmux attach -t ${target}\``);
73
+ },
74
+ };
75
+ }
76
+ }
77
+ //# sourceMappingURL=tmux.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tmux.js","sourceRoot":"","sources":["../../src/runtime/tmux.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { LaunchSpec } from "@cotal-ai/core";
2
+ export type RuntimeKind = "pty" | "tmux" | "cmux";
3
+ /** A live attach onto a running agent's terminal — the stream `cotal attach`
4
+ * (and, later, the browser console) consumes. PTY frames flow here directly,
5
+ * never over the mesh. */
6
+ export interface AttachSession {
7
+ readonly cols: number;
8
+ readonly rows: number;
9
+ /** Scrollback so a late attach sees output that already scrolled past. */
10
+ backlog(): Buffer;
11
+ /** Subscribe to live output; returns an unsubscribe fn. */
12
+ onData(fn: (chunk: Buffer) => void): () => void;
13
+ /** Fires when the underlying process exits; returns an unsubscribe fn. */
14
+ onExit(fn: () => void): () => void;
15
+ /** Forward keystrokes to the process. */
16
+ write(data: string): void;
17
+ /** Resize the pseudo-terminal. */
18
+ resize(cols: number, rows: number): void;
19
+ }
20
+ /** An OS handle on one spawned agent — the manager owns this to *control* the
21
+ * process (the mesh observes its presence separately). */
22
+ export interface AgentHandle {
23
+ readonly name: string;
24
+ readonly kind: RuntimeKind;
25
+ status(): "running" | "exited";
26
+ stop(): void;
27
+ interrupt(): void;
28
+ /** Open a live attach. Throws on backends that can't stream (e.g. tmux, which
29
+ * you attach to natively). */
30
+ attach(): AttachSession;
31
+ }
32
+ /** A pluggable agent backend — `pty` (default) owns a real pseudo-terminal;
33
+ * `tmux` (opt-in) drives a multiplexer pane. Selectable, no silent fallback. */
34
+ export interface Runtime {
35
+ readonly kind: RuntimeKind;
36
+ spawn(name: string, spec: LaunchSpec, cwd: string): AgentHandle;
37
+ }
38
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAElD;;2BAE2B;AAC3B,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,OAAO,IAAI,MAAM,CAAC;IAClB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAChD,0EAA0E;IAC1E,MAAM,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IACnC,yCAAyC;IACzC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,kCAAkC;IAClC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C;AAED;2DAC2D;AAC3D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,MAAM,IAAI,SAAS,GAAG,QAAQ,CAAC;IAC/B,IAAI,IAAI,IAAI,CAAC;IACb,SAAS,IAAI,IAAI,CAAC;IAClB;mCAC+B;IAC/B,MAAM,IAAI,aAAa,CAAC;CACzB;AAED;iFACiF;AACjF,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;CACjE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":""}
package/dist/ui.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /** Minimal ANSI helpers — local to the manager so it never imports the CLI. */
2
+ export declare const c: {
3
+ dim: (s: string) => string;
4
+ bold: (s: string) => string;
5
+ green: (s: string) => string;
6
+ cyan: (s: string) => string;
7
+ yellow: (s: string) => string;
8
+ red: (s: string) => string;
9
+ };
10
+ //# sourceMappingURL=ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,eAAO,MAAM,CAAC;aACH,MAAM;cACL,MAAM;eACL,MAAM;cACP,MAAM;gBACJ,MAAM;aACT,MAAM;CAChB,CAAC"}
package/dist/ui.js ADDED
@@ -0,0 +1,10 @@
1
+ /** Minimal ANSI helpers — local to the manager so it never imports the CLI. */
2
+ export const c = {
3
+ dim: (s) => `\x1b[2m${s}\x1b[0m`,
4
+ bold: (s) => `\x1b[1m${s}\x1b[0m`,
5
+ green: (s) => `\x1b[32m${s}\x1b[0m`,
6
+ cyan: (s) => `\x1b[36m${s}\x1b[0m`,
7
+ yellow: (s) => `\x1b[33m${s}\x1b[0m`,
8
+ red: (s) => `\x1b[31m${s}\x1b[0m`,
9
+ };
10
+ //# sourceMappingURL=ui.js.map
package/dist/ui.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,CAAC,MAAM,CAAC,GAAG;IACf,GAAG,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,UAAU,CAAC,SAAS;IACxC,IAAI,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,UAAU,CAAC,SAAS;IACzC,KAAK,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS;IAC3C,IAAI,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS;IAC1C,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS;IAC5C,GAAG,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS;CAC1C,CAAC"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@cotal-ai/manager",
3
+ "version": "0.1.0",
4
+ "license": "Apache-2.0",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "dependencies": {
15
+ "@lydell/node-pty": "1.2.0-beta.12",
16
+ "@xterm/addon-attach": "^0.11.0",
17
+ "@xterm/addon-fit": "^0.10.0",
18
+ "@xterm/xterm": "^5.5.0",
19
+ "ws": "^8.21.0",
20
+ "@cotal-ai/cmux": "0.1.0",
21
+ "@cotal-ai/core": "0.1.0"
22
+ },
23
+ "devDependencies": {
24
+ "@types/ws": "^8.18.1"
25
+ },
26
+ "files": [
27
+ "dist"
28
+ ],
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "scripts": {
33
+ "typecheck": "tsc -p tsconfig.json --noEmit",
34
+ "build": "tsc -p tsconfig.json"
35
+ }
36
+ }