naiad-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.
Files changed (50) hide show
  1. package/dist/api/client.d.ts +81 -0
  2. package/dist/api/client.js +130 -0
  3. package/dist/api/client.js.map +1 -0
  4. package/dist/callback/server.d.ts +11 -0
  5. package/dist/callback/server.js +53 -0
  6. package/dist/callback/server.js.map +1 -0
  7. package/dist/callback/server.test.d.ts +1 -0
  8. package/dist/callback/server.test.js +79 -0
  9. package/dist/callback/server.test.js.map +1 -0
  10. package/dist/commands/exec.d.ts +10 -0
  11. package/dist/commands/exec.js +94 -0
  12. package/dist/commands/exec.js.map +1 -0
  13. package/dist/commands/interactive.d.ts +6 -0
  14. package/dist/commands/interactive.js +137 -0
  15. package/dist/commands/interactive.js.map +1 -0
  16. package/dist/config/config.d.ts +5 -0
  17. package/dist/config/config.js +21 -0
  18. package/dist/config/config.js.map +1 -0
  19. package/dist/index.d.ts +2 -0
  20. package/dist/index.js +137 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/lifecycle/setup.d.ts +11 -0
  23. package/dist/lifecycle/setup.js +49 -0
  24. package/dist/lifecycle/setup.js.map +1 -0
  25. package/dist/lifecycle/teardown.d.ts +6 -0
  26. package/dist/lifecycle/teardown.js +34 -0
  27. package/dist/lifecycle/teardown.js.map +1 -0
  28. package/dist/lifecycle/types.d.ts +21 -0
  29. package/dist/lifecycle/types.js +2 -0
  30. package/dist/lifecycle/types.js.map +1 -0
  31. package/dist/lifecycle/workers.d.ts +2 -0
  32. package/dist/lifecycle/workers.js +22 -0
  33. package/dist/lifecycle/workers.js.map +1 -0
  34. package/dist/pi/launcher.d.ts +26 -0
  35. package/dist/pi/launcher.js +109 -0
  36. package/dist/pi/launcher.js.map +1 -0
  37. package/dist/sync/events.d.ts +14 -0
  38. package/dist/sync/events.js +44 -0
  39. package/dist/sync/events.js.map +1 -0
  40. package/dist/sync/heartbeat.d.ts +12 -0
  41. package/dist/sync/heartbeat.js +33 -0
  42. package/dist/sync/heartbeat.js.map +1 -0
  43. package/dist/sync/session-upload.d.ts +12 -0
  44. package/dist/sync/session-upload.js +69 -0
  45. package/dist/sync/session-upload.js.map +1 -0
  46. package/dist/utils/package-root.d.ts +1 -0
  47. package/dist/utils/package-root.js +13 -0
  48. package/dist/utils/package-root.js.map +1 -0
  49. package/extensions/naiad-extension.ts +330 -0
  50. package/package.json +31 -0
@@ -0,0 +1,21 @@
1
+ import { readFileSync, existsSync } from "fs";
2
+ import { join } from "path";
3
+ import { homedir } from "os";
4
+ export function loadConfig() {
5
+ const apiUrl = process.env.NAIAD_API_URL || loadFromFile("api_url") || "http://localhost:3000";
6
+ const apiKey = process.env.NAIAD_API_KEY || loadFromFile("api_key") || "";
7
+ return { apiUrl, apiKey };
8
+ }
9
+ function loadFromFile(key) {
10
+ const configPath = join(homedir(), ".naiad", "config.json");
11
+ if (!existsSync(configPath))
12
+ return undefined;
13
+ try {
14
+ const config = JSON.parse(readFileSync(configPath, "utf-8"));
15
+ return config[key];
16
+ }
17
+ catch {
18
+ return undefined;
19
+ }
20
+ }
21
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAO7B,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,YAAY,CAAC,SAAS,CAAC,IAAI,uBAAuB,CAAC;IAC/F,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAE1E,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,YAAY,CAAC,GAAW;IAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IAC5D,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from "fs";
3
+ import { parseArgs } from "node:util";
4
+ import { loadConfig } from "./config/config.js";
5
+ import { execCommand } from "./commands/exec.js";
6
+ import { interactiveCommand } from "./commands/interactive.js";
7
+ const args = process.argv.slice(2);
8
+ if (args.includes("--help") || args.includes("-h")) {
9
+ console.log(`naiad - Naiad 2.0 CLI
10
+
11
+ Usage:
12
+ naiad [options] Interactive mode (default)
13
+ naiad exec [options] "<prompt>" Headless mode
14
+
15
+ Interactive options:
16
+ --model <model_id> Model to use (default: first active model from server)
17
+ --session <session_id> Resume specific session
18
+ -c, --continue Continue most recent session
19
+ --help, -h Show this help
20
+
21
+ Exec options:
22
+ --model <model_id> Model to use (default: first active model from server)
23
+ --source <source> Thread source (default: cli)
24
+ --trigger <trigger> Thread trigger (default: cli)
25
+ --context <json> Thread context JSON
26
+ --reply-target <json> Reply target JSON
27
+ --prompt-file <path> Read prompt from file
28
+ --output <path> Write result JSON to file
29
+
30
+ Environment:
31
+ NAIAD_API_URL Platform API URL (default: http://localhost:3000)
32
+ NAIAD_API_KEY API key for authentication`);
33
+ process.exit(0);
34
+ }
35
+ const config = loadConfig();
36
+ if (!config.apiKey) {
37
+ console.error("Error: NAIAD_API_KEY is required. Set it via environment variable or ~/.naiad/config.json");
38
+ process.exit(1);
39
+ }
40
+ const command = args[0];
41
+ if (command === "exec") {
42
+ const execArgv = args.slice(1);
43
+ let values;
44
+ let positionals;
45
+ try {
46
+ const parsed = parseArgs({
47
+ args: execArgv,
48
+ options: {
49
+ model: { type: "string" },
50
+ source: { type: "string" },
51
+ trigger: { type: "string" },
52
+ context: { type: "string" },
53
+ "reply-target": { type: "string" },
54
+ "prompt-file": { type: "string" },
55
+ output: { type: "string" },
56
+ },
57
+ allowPositionals: true,
58
+ strict: true,
59
+ });
60
+ values = parsed.values;
61
+ positionals = parsed.positionals;
62
+ }
63
+ catch (err) {
64
+ console.error(`Error: ${err.message}`);
65
+ process.exit(1);
66
+ }
67
+ // Resolve prompt from --prompt-file or positional args
68
+ let prompt;
69
+ if (values["prompt-file"]) {
70
+ try {
71
+ prompt = readFileSync(values["prompt-file"], "utf-8").trim();
72
+ }
73
+ catch (err) {
74
+ console.error(`Error: cannot read prompt file: ${err.message}`);
75
+ process.exit(1);
76
+ }
77
+ }
78
+ else if (positionals.length > 0) {
79
+ prompt = positionals.join(" ");
80
+ }
81
+ else {
82
+ console.error("Error: prompt required (positional arg or --prompt-file)");
83
+ process.exit(1);
84
+ }
85
+ // Validate JSON flags
86
+ if (values.context) {
87
+ try {
88
+ JSON.parse(values.context);
89
+ }
90
+ catch {
91
+ console.error("Error: --context must be valid JSON");
92
+ process.exit(1);
93
+ }
94
+ }
95
+ if (values["reply-target"]) {
96
+ try {
97
+ JSON.parse(values["reply-target"]);
98
+ }
99
+ catch {
100
+ console.error("Error: --reply-target must be valid JSON");
101
+ process.exit(1);
102
+ }
103
+ }
104
+ execCommand(config, prompt, {
105
+ model: values.model,
106
+ source: values.source,
107
+ trigger: values.trigger,
108
+ context: values.context,
109
+ replyTarget: values["reply-target"],
110
+ output: values.output,
111
+ }).catch((err) => {
112
+ console.error("Error:", err.message || err);
113
+ process.exit(1);
114
+ });
115
+ }
116
+ else {
117
+ // Interactive mode (default) — unchanged arg parsing
118
+ let model;
119
+ let sessionId;
120
+ let continueRecent = false;
121
+ for (let i = 0; i < args.length; i++) {
122
+ if (args[i] === "--model" && args[i + 1]) {
123
+ model = args[++i];
124
+ }
125
+ else if (args[i] === "--session" && args[i + 1]) {
126
+ sessionId = args[++i];
127
+ }
128
+ else if (args[i] === "-c" || args[i] === "--continue") {
129
+ continueRecent = true;
130
+ }
131
+ }
132
+ interactiveCommand(config, { modelFlag: model, sessionId, continueRecent }).catch((err) => {
133
+ console.error("Error:", err.message || err);
134
+ process.exit(1);
135
+ });
136
+ }
137
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { NaiadConfig } from "../config/config.js";
2
+ import type { LifecycleContext } from "./types.js";
3
+ export declare function setupLifecycle(params: {
4
+ config: NaiadConfig;
5
+ modelFlag?: string;
6
+ threadPrompt: string;
7
+ source?: string;
8
+ trigger?: string;
9
+ context?: string;
10
+ replyTarget?: string;
11
+ }): Promise<LifecycleContext>;
@@ -0,0 +1,49 @@
1
+ import { mkdtempSync } from "fs";
2
+ import { join } from "path";
3
+ import { tmpdir } from "os";
4
+ import { randomUUID } from "crypto";
5
+ import { APIClient } from "../api/client.js";
6
+ import { findPackageRoot } from "../utils/package-root.js";
7
+ export async function setupLifecycle(params) {
8
+ const { config, modelFlag, threadPrompt } = params;
9
+ const client = new APIClient(config);
10
+ // Validate API key by listing models
11
+ console.error("[naiad] Validating API key...");
12
+ const { models } = await client.listModels();
13
+ if (models.length === 0) {
14
+ throw new Error("No models available");
15
+ }
16
+ const model = modelFlag || models[0].id;
17
+ console.error(`[naiad] Using model: ${model}`);
18
+ // Create thread with metadata
19
+ const thread = await client.createThread(threadPrompt, {
20
+ source: params.source || "cli",
21
+ trigger: params.trigger || "cli",
22
+ context: params.context ? JSON.parse(params.context) : {},
23
+ replyTarget: params.replyTarget ? JSON.parse(params.replyTarget) : undefined,
24
+ });
25
+ console.error(`[naiad] Created thread: ${thread.id}`);
26
+ // Create session
27
+ const agentId = randomUUID();
28
+ const runtime = params.source === "github" ? "github_actions" : "local_cli";
29
+ const session = await client.createSession(thread.id, agentId, runtime);
30
+ console.error(`[naiad] Created session: ${session.id}`);
31
+ // Transition to RUNNING
32
+ await client.updateThread(thread.id, { status: "RUNNING" });
33
+ // Set up session dir
34
+ const sessionDir = mkdtempSync(join(tmpdir(), "naiad-session-"));
35
+ // Resolve extension path relative to package root
36
+ const pkgRoot = findPackageRoot();
37
+ const extensionPath = join(pkgRoot, "extensions", "naiad-extension.ts");
38
+ return {
39
+ config,
40
+ client,
41
+ model,
42
+ agentId,
43
+ threadId: thread.id,
44
+ sessionId: session.id,
45
+ sessionDir,
46
+ extensionPath,
47
+ };
48
+ }
49
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/lifecycle/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGpC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE3D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAQpC;IACC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IACnD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;IAErC,qCAAqC;IACrC,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC/C,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;IAC7C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxC,OAAO,CAAC,KAAK,CAAC,wBAAwB,KAAK,EAAE,CAAC,CAAC;IAE/C,8BAA8B;IAC9B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,YAAY,EAAE;QACrD,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,KAAK;QAC9B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,KAAK;QAChC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;QACzD,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS;KAC7E,CAAC,CAAC;IACH,OAAO,CAAC,KAAK,CAAC,2BAA2B,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;IAEtD,iBAAiB;IACjB,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC;IAC5E,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACxE,OAAO,CAAC,KAAK,CAAC,4BAA4B,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IAExD,wBAAwB;IACxB,MAAM,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IAE5D,qBAAqB;IACrB,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAEjE,kDAAkD;IAClD,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;IAClC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,oBAAoB,CAAC,CAAC;IAExE,OAAO;QACL,MAAM;QACN,MAAM;QACN,KAAK;QACL,OAAO;QACP,QAAQ,EAAE,MAAM,CAAC,EAAE;QACnB,SAAS,EAAE,OAAO,CAAC,EAAE;QACrB,UAAU;QACV,aAAa;KACd,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { LifecycleContext } from "./types.js";
2
+ export declare function teardownLifecycle(params: {
3
+ ctx: LifecycleContext;
4
+ exitCode: number;
5
+ errorMessage?: string;
6
+ }): Promise<"COMPLETED" | "FAILED">;
@@ -0,0 +1,34 @@
1
+ export async function teardownLifecycle(params) {
2
+ const { ctx, exitCode, errorMessage } = params;
3
+ const finalStatus = exitCode === 0 ? "COMPLETED" : "FAILED";
4
+ try {
5
+ await ctx.client.updateSession(ctx.sessionId, finalStatus);
6
+ }
7
+ catch (err) {
8
+ console.error("[naiad] Failed to update session:", err);
9
+ }
10
+ try {
11
+ if (finalStatus === "FAILED") {
12
+ await ctx.client.updateThread(ctx.threadId, {
13
+ status: "FAILED",
14
+ error: errorMessage || `pi exited with code ${exitCode}`,
15
+ });
16
+ }
17
+ else {
18
+ await ctx.client.updateThread(ctx.threadId, { status: "COMPLETED" });
19
+ }
20
+ }
21
+ catch (err) {
22
+ // Treat 409 as non-fatal (thread may already be in target state)
23
+ const msg = err instanceof Error ? err.message : String(err);
24
+ if (msg.includes("409")) {
25
+ console.error("[naiad] Thread status already set (409), continuing");
26
+ }
27
+ else {
28
+ console.error("[naiad] Failed to update thread:", err);
29
+ }
30
+ }
31
+ console.error(`[naiad] Thread ${ctx.threadId}: ${finalStatus}`);
32
+ return finalStatus;
33
+ }
34
+ //# sourceMappingURL=teardown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teardown.js","sourceRoot":"","sources":["../../src/lifecycle/teardown.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAIvC;IACC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAC/C,MAAM,WAAW,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC;IAE5D,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC7D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,CAAC;QACH,IAAI,WAAW,KAAK,QAAQ,EAAE,CAAC;YAC7B,MAAM,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE;gBAC1C,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,YAAY,IAAI,uBAAuB,QAAQ,EAAE;aACzD,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,iEAAiE;QACjE,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACvE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,GAAG,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,kBAAkB,GAAG,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC,CAAC;IAChE,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { NaiadConfig } from "../config/config.js";
2
+ import type { APIClient } from "../api/client.js";
3
+ import type { EventSpool } from "../sync/events.js";
4
+ import type { SessionUploader } from "../sync/session-upload.js";
5
+ import type { HeartbeatReporter } from "../sync/heartbeat.js";
6
+ export interface LifecycleContext {
7
+ config: NaiadConfig;
8
+ client: APIClient;
9
+ model: string;
10
+ agentId: string;
11
+ threadId: string;
12
+ sessionId: string;
13
+ sessionDir: string;
14
+ extensionPath: string;
15
+ }
16
+ export interface Workers {
17
+ eventSpool: EventSpool;
18
+ uploader: SessionUploader;
19
+ heartbeat: HeartbeatReporter;
20
+ stop(): Promise<void>;
21
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lifecycle/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ import type { LifecycleContext, Workers } from "./types.js";
2
+ export declare function startWorkers(ctx: LifecycleContext): Workers;
@@ -0,0 +1,22 @@
1
+ import { EventSpool } from "../sync/events.js";
2
+ import { SessionUploader } from "../sync/session-upload.js";
3
+ import { HeartbeatReporter } from "../sync/heartbeat.js";
4
+ export function startWorkers(ctx) {
5
+ const eventSpool = new EventSpool(ctx.client, ctx.threadId, ctx.sessionId);
6
+ eventSpool.start();
7
+ const uploader = new SessionUploader(ctx.client, ctx.sessionId, ctx.sessionDir);
8
+ uploader.start();
9
+ const heartbeat = new HeartbeatReporter(ctx.client, ctx.agentId, ctx.threadId, ctx.sessionId);
10
+ heartbeat.start();
11
+ return {
12
+ eventSpool,
13
+ uploader,
14
+ heartbeat,
15
+ async stop() {
16
+ heartbeat.stop();
17
+ await eventSpool.stop();
18
+ await uploader.stop();
19
+ },
20
+ };
21
+ }
22
+ //# sourceMappingURL=workers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workers.js","sourceRoot":"","sources":["../../src/lifecycle/workers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,MAAM,UAAU,YAAY,CAAC,GAAqB;IAChD,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;IAC3E,UAAU,CAAC,KAAK,EAAE,CAAC;IAEnB,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IAChF,QAAQ,CAAC,KAAK,EAAE,CAAC;IAEjB,MAAM,SAAS,GAAG,IAAI,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;IAC9F,SAAS,CAAC,KAAK,EAAE,CAAC;IAElB,OAAO;QACL,UAAU;QACV,QAAQ;QACR,SAAS;QACT,KAAK,CAAC,IAAI;YACR,SAAS,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;YACxB,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACxB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { type ChildProcess } from "child_process";
2
+ export interface PiOptions {
3
+ model: string;
4
+ sessionDir: string;
5
+ extensionPath: string;
6
+ env: Record<string, string>;
7
+ }
8
+ export interface PiProcess {
9
+ process: ChildProcess;
10
+ sendPrompt: (prompt: string) => void;
11
+ shutdown: () => Promise<void>;
12
+ onEvent: (handler: (event: PiRpcEvent) => void) => void;
13
+ }
14
+ export interface PiRpcEvent {
15
+ type: string;
16
+ [key: string]: unknown;
17
+ }
18
+ export declare function launchPi(options: PiOptions): PiProcess;
19
+ export interface PiInteractiveProcess {
20
+ process: ChildProcess;
21
+ shutdown: () => Promise<void>;
22
+ }
23
+ export interface PiInteractiveOptions extends PiOptions {
24
+ resumeSessionFile?: string;
25
+ }
26
+ export declare function launchPiInteractive(options: PiInteractiveOptions): PiInteractiveProcess;
@@ -0,0 +1,109 @@
1
+ import { spawn } from "child_process";
2
+ import { join } from "path";
3
+ import { existsSync } from "fs";
4
+ import { findPackageRoot } from "../utils/package-root.js";
5
+ export function launchPi(options) {
6
+ const piPath = resolvePiBin();
7
+ const piProcess = spawn(piPath, [
8
+ "--mode", "rpc",
9
+ "--provider", "naiad-proxy",
10
+ "--model", options.model,
11
+ "--session-dir", options.sessionDir,
12
+ "-e", options.extensionPath,
13
+ ], {
14
+ env: { ...process.env, ...options.env },
15
+ stdio: ["pipe", "pipe", "pipe"],
16
+ });
17
+ let eventHandler = null;
18
+ let lineBuffer = "";
19
+ piProcess.stdout.on("data", (data) => {
20
+ lineBuffer += data.toString();
21
+ const lines = lineBuffer.split("\n");
22
+ lineBuffer = lines.pop() ?? "";
23
+ for (const line of lines) {
24
+ if (!line.trim())
25
+ continue;
26
+ try {
27
+ const event = JSON.parse(line);
28
+ eventHandler?.(event);
29
+ }
30
+ catch {
31
+ // Not JSON, forward as raw output
32
+ process.stdout.write(line + "\n");
33
+ }
34
+ }
35
+ });
36
+ piProcess.stderr.on("data", (data) => {
37
+ process.stderr.write(data);
38
+ });
39
+ return {
40
+ process: piProcess,
41
+ sendPrompt(prompt) {
42
+ const msg = JSON.stringify({ type: "prompt", message: prompt });
43
+ piProcess.stdin.write(msg + "\n");
44
+ },
45
+ async shutdown() {
46
+ // Close stdin (EOF) + SIGTERM per spike results
47
+ piProcess.stdin.end();
48
+ await new Promise((resolve) => {
49
+ const timeout = setTimeout(() => {
50
+ piProcess.kill("SIGKILL");
51
+ resolve();
52
+ }, 5000);
53
+ piProcess.on("exit", () => {
54
+ clearTimeout(timeout);
55
+ resolve();
56
+ });
57
+ setTimeout(() => piProcess.kill("SIGTERM"), 100);
58
+ });
59
+ },
60
+ onEvent(handler) {
61
+ eventHandler = handler;
62
+ },
63
+ };
64
+ }
65
+ export function launchPiInteractive(options) {
66
+ const piPath = resolvePiBin();
67
+ const args = [
68
+ "--provider", "naiad-proxy",
69
+ "--model", options.model,
70
+ "--session-dir", options.sessionDir,
71
+ "-e", options.extensionPath,
72
+ ];
73
+ if (options.resumeSessionFile) {
74
+ args.push("--session", options.resumeSessionFile);
75
+ }
76
+ const piProcess = spawn(piPath, args, {
77
+ env: { ...process.env, ...options.env },
78
+ stdio: "inherit",
79
+ });
80
+ return {
81
+ process: piProcess,
82
+ async shutdown() {
83
+ await new Promise((resolve) => {
84
+ const timeout = setTimeout(() => {
85
+ piProcess.kill("SIGKILL");
86
+ resolve();
87
+ }, 5000);
88
+ piProcess.on("exit", () => {
89
+ clearTimeout(timeout);
90
+ resolve();
91
+ });
92
+ piProcess.kill("SIGTERM");
93
+ });
94
+ },
95
+ };
96
+ }
97
+ function resolvePiBin() {
98
+ try {
99
+ const pkgRoot = findPackageRoot();
100
+ const piCli = join(pkgRoot, "node_modules", ".bin", "pi");
101
+ if (existsSync(piCli))
102
+ return piCli;
103
+ }
104
+ catch {
105
+ // fall through
106
+ }
107
+ return "pi"; // Fall back to PATH
108
+ }
109
+ //# sourceMappingURL=launcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launcher.js","sourceRoot":"","sources":["../../src/pi/launcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { APIClient } from "../api/client.js";
2
+ export declare class EventSpool {
3
+ private buffer;
4
+ private nextSeq;
5
+ private flushTimer;
6
+ private threadId;
7
+ private sessionId;
8
+ private client;
9
+ constructor(client: APIClient, threadId: string, sessionId: string);
10
+ start(): void;
11
+ pushEvent(eventType: string, data: unknown): void;
12
+ flush(): Promise<void>;
13
+ stop(): Promise<void>;
14
+ }
@@ -0,0 +1,44 @@
1
+ export class EventSpool {
2
+ buffer = [];
3
+ nextSeq = 1;
4
+ flushTimer = null;
5
+ threadId;
6
+ sessionId;
7
+ client;
8
+ constructor(client, threadId, sessionId) {
9
+ this.client = client;
10
+ this.threadId = threadId;
11
+ this.sessionId = sessionId;
12
+ }
13
+ start() {
14
+ this.flushTimer = setInterval(() => this.flush(), 200);
15
+ }
16
+ pushEvent(eventType, data) {
17
+ this.buffer.push({
18
+ client_seq: this.nextSeq++,
19
+ event_type: eventType,
20
+ data,
21
+ });
22
+ }
23
+ async flush() {
24
+ if (this.buffer.length === 0)
25
+ return;
26
+ const batch = this.buffer.splice(0);
27
+ try {
28
+ await this.client.postEvents(this.threadId, this.sessionId, batch);
29
+ }
30
+ catch (err) {
31
+ // Re-add events to buffer on failure
32
+ this.buffer.unshift(...batch);
33
+ console.error("[event-spool] Failed to send events:", err);
34
+ }
35
+ }
36
+ async stop() {
37
+ if (this.flushTimer) {
38
+ clearInterval(this.flushTimer);
39
+ this.flushTimer = null;
40
+ }
41
+ await this.flush();
42
+ }
43
+ }
44
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/sync/events.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,UAAU;IACb,MAAM,GAAqE,EAAE,CAAC;IAC9E,OAAO,GAAG,CAAC,CAAC;IACZ,UAAU,GAA0C,IAAI,CAAC;IACzD,QAAQ,CAAS;IACjB,SAAS,CAAS;IAClB,MAAM,CAAY;IAE1B,YAAY,MAAiB,EAAE,QAAgB,EAAE,SAAiB;QAChE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,GAAG,CAAC,CAAC;IACzD,CAAC;IAED,SAAS,CAAC,SAAiB,EAAE,IAAa;QACxC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE;YAC1B,UAAU,EAAE,SAAS;YACrB,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAErC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACrE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,qCAAqC;YACrC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;YAC9B,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,GAAG,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QACD,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import type { APIClient } from "../api/client.js";
2
+ export declare class HeartbeatReporter {
3
+ private client;
4
+ private agentId;
5
+ private threadId;
6
+ private sessionId;
7
+ private timer;
8
+ constructor(client: APIClient, agentId: string, threadId: string, sessionId: string);
9
+ start(): void;
10
+ stop(): void;
11
+ private send;
12
+ }
@@ -0,0 +1,33 @@
1
+ export class HeartbeatReporter {
2
+ client;
3
+ agentId;
4
+ threadId;
5
+ sessionId;
6
+ timer = null;
7
+ constructor(client, agentId, threadId, sessionId) {
8
+ this.client = client;
9
+ this.agentId = agentId;
10
+ this.threadId = threadId;
11
+ this.sessionId = sessionId;
12
+ }
13
+ start() {
14
+ this.timer = setInterval(() => this.send(), 30_000);
15
+ // Send initial heartbeat immediately
16
+ this.send();
17
+ }
18
+ stop() {
19
+ if (this.timer) {
20
+ clearInterval(this.timer);
21
+ this.timer = null;
22
+ }
23
+ }
24
+ async send() {
25
+ try {
26
+ await this.client.postHeartbeat(this.agentId, this.threadId, this.sessionId, "working");
27
+ }
28
+ catch (err) {
29
+ console.error("[heartbeat] Failed to send:", err);
30
+ }
31
+ }
32
+ }
33
+ //# sourceMappingURL=heartbeat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../src/sync/heartbeat.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,iBAAiB;IACpB,MAAM,CAAY;IAClB,OAAO,CAAS;IAChB,QAAQ,CAAS;IACjB,SAAS,CAAS;IAClB,KAAK,GAA0C,IAAI,CAAC;IAE5D,YAAY,MAAiB,EAAE,OAAe,EAAE,QAAgB,EAAE,SAAiB;QACjF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;QACpD,qCAAqC;QACrC,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC1F,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import type { APIClient } from "../api/client.js";
2
+ export declare class SessionUploader {
3
+ private client;
4
+ private sessionId;
5
+ private sessionDir;
6
+ private pollTimer;
7
+ constructor(client: APIClient, sessionId: string, sessionDir: string);
8
+ start(): void;
9
+ stop(): Promise<void>;
10
+ private checkAndUpload;
11
+ private uploadFile;
12
+ }