@grackle-ai/core 0.75.4

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 (130) hide show
  1. package/README.md +30 -0
  2. package/dist/adapter-config.d.ts +6 -0
  3. package/dist/adapter-config.d.ts.map +1 -0
  4. package/dist/adapter-config.js +19 -0
  5. package/dist/adapter-config.js.map +1 -0
  6. package/dist/adapter-manager.d.ts +22 -0
  7. package/dist/adapter-manager.d.ts.map +1 -0
  8. package/dist/adapter-manager.js +81 -0
  9. package/dist/adapter-manager.js.map +1 -0
  10. package/dist/auto-reconnect.d.ts +23 -0
  11. package/dist/auto-reconnect.d.ts.map +1 -0
  12. package/dist/auto-reconnect.js +164 -0
  13. package/dist/auto-reconnect.js.map +1 -0
  14. package/dist/compute-task-status.d.ts +28 -0
  15. package/dist/compute-task-status.d.ts.map +1 -0
  16. package/dist/compute-task-status.js +70 -0
  17. package/dist/compute-task-status.js.map +1 -0
  18. package/dist/credential-bundle.d.ts +12 -0
  19. package/dist/credential-bundle.d.ts.map +1 -0
  20. package/dist/credential-bundle.js +183 -0
  21. package/dist/credential-bundle.js.map +1 -0
  22. package/dist/event-bus.d.ts +37 -0
  23. package/dist/event-bus.d.ts.map +1 -0
  24. package/dist/event-bus.js +65 -0
  25. package/dist/event-bus.js.map +1 -0
  26. package/dist/event-processor.d.ts +36 -0
  27. package/dist/event-processor.d.ts.map +1 -0
  28. package/dist/event-processor.js +312 -0
  29. package/dist/event-processor.js.map +1 -0
  30. package/dist/grpc-service.d.ts +22 -0
  31. package/dist/grpc-service.d.ts.map +1 -0
  32. package/dist/grpc-service.js +1724 -0
  33. package/dist/grpc-service.js.map +1 -0
  34. package/dist/index.d.ts +16 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +25 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/knowledge-init.d.ts +27 -0
  39. package/dist/knowledge-init.d.ts.map +1 -0
  40. package/dist/knowledge-init.js +212 -0
  41. package/dist/knowledge-init.js.map +1 -0
  42. package/dist/lifecycle.d.ts +36 -0
  43. package/dist/lifecycle.d.ts.map +1 -0
  44. package/dist/lifecycle.js +112 -0
  45. package/dist/lifecycle.js.map +1 -0
  46. package/dist/log-writer.d.ts +32 -0
  47. package/dist/log-writer.d.ts.map +1 -0
  48. package/dist/log-writer.js +104 -0
  49. package/dist/log-writer.js.map +1 -0
  50. package/dist/logger.d.ts +4 -0
  51. package/dist/logger.d.ts.map +1 -0
  52. package/dist/logger.js +10 -0
  53. package/dist/logger.js.map +1 -0
  54. package/dist/pipe-delivery.d.ts +41 -0
  55. package/dist/pipe-delivery.d.ts.map +1 -0
  56. package/dist/pipe-delivery.js +186 -0
  57. package/dist/pipe-delivery.js.map +1 -0
  58. package/dist/processor-registry.d.ts +25 -0
  59. package/dist/processor-registry.d.ts.map +1 -0
  60. package/dist/processor-registry.js +58 -0
  61. package/dist/processor-registry.js.map +1 -0
  62. package/dist/reanimate-agent.d.ts +12 -0
  63. package/dist/reanimate-agent.d.ts.map +1 -0
  64. package/dist/reanimate-agent.js +76 -0
  65. package/dist/reanimate-agent.js.map +1 -0
  66. package/dist/session-recovery.d.ts +16 -0
  67. package/dist/session-recovery.d.ts.map +1 -0
  68. package/dist/session-recovery.js +129 -0
  69. package/dist/session-recovery.js.map +1 -0
  70. package/dist/signals/sigchld.d.ts +7 -0
  71. package/dist/signals/sigchld.d.ts.map +1 -0
  72. package/dist/signals/sigchld.js +167 -0
  73. package/dist/signals/sigchld.js.map +1 -0
  74. package/dist/signals/signal-delivery.d.ts +14 -0
  75. package/dist/signals/signal-delivery.d.ts.map +1 -0
  76. package/dist/signals/signal-delivery.js +166 -0
  77. package/dist/signals/signal-delivery.js.map +1 -0
  78. package/dist/stream-hub.d.ts +14 -0
  79. package/dist/stream-hub.d.ts.map +1 -0
  80. package/dist/stream-hub.js +95 -0
  81. package/dist/stream-hub.js.map +1 -0
  82. package/dist/stream-registry.d.ts +84 -0
  83. package/dist/stream-registry.d.ts.map +1 -0
  84. package/dist/stream-registry.js +363 -0
  85. package/dist/stream-registry.js.map +1 -0
  86. package/dist/test-utils/integration-setup.d.ts +11 -0
  87. package/dist/test-utils/integration-setup.d.ts.map +1 -0
  88. package/dist/test-utils/integration-setup.js +32 -0
  89. package/dist/test-utils/integration-setup.js.map +1 -0
  90. package/dist/test-utils/mock-database.d.ts +130 -0
  91. package/dist/test-utils/mock-database.d.ts.map +1 -0
  92. package/dist/test-utils/mock-database.js +147 -0
  93. package/dist/test-utils/mock-database.js.map +1 -0
  94. package/dist/token-push.d.ts +22 -0
  95. package/dist/token-push.d.ts.map +1 -0
  96. package/dist/token-push.js +78 -0
  97. package/dist/token-push.js.map +1 -0
  98. package/dist/transcript.d.ts +5 -0
  99. package/dist/transcript.d.ts.map +1 -0
  100. package/dist/transcript.js +71 -0
  101. package/dist/transcript.js.map +1 -0
  102. package/dist/utils/exec.d.ts +17 -0
  103. package/dist/utils/exec.d.ts.map +1 -0
  104. package/dist/utils/exec.js +21 -0
  105. package/dist/utils/exec.js.map +1 -0
  106. package/dist/utils/format-gh-error.d.ts +6 -0
  107. package/dist/utils/format-gh-error.d.ts.map +1 -0
  108. package/dist/utils/format-gh-error.js +30 -0
  109. package/dist/utils/format-gh-error.js.map +1 -0
  110. package/dist/utils/network.d.ts +7 -0
  111. package/dist/utils/network.d.ts.map +1 -0
  112. package/dist/utils/network.js +21 -0
  113. package/dist/utils/network.js.map +1 -0
  114. package/dist/utils/ports.d.ts +3 -0
  115. package/dist/utils/ports.d.ts.map +1 -0
  116. package/dist/utils/ports.js +19 -0
  117. package/dist/utils/ports.js.map +1 -0
  118. package/dist/utils/sleep.d.ts +3 -0
  119. package/dist/utils/sleep.d.ts.map +1 -0
  120. package/dist/utils/sleep.js +5 -0
  121. package/dist/utils/sleep.js.map +1 -0
  122. package/dist/ws-bridge.d.ts +30 -0
  123. package/dist/ws-bridge.d.ts.map +1 -0
  124. package/dist/ws-bridge.js +372 -0
  125. package/dist/ws-bridge.js.map +1 -0
  126. package/dist/ws-broadcast.d.ts +19 -0
  127. package/dist/ws-broadcast.d.ts.map +1 -0
  128. package/dist/ws-broadcast.js +60 -0
  129. package/dist/ws-broadcast.js.map +1 -0
  130. package/package.json +57 -0
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Shared mock factory for `@grackle-ai/database` used by server test files.
3
+ *
4
+ * Usage in test files:
5
+ * ```typescript
6
+ * import { createDatabaseMock } from "./test-utils/mock-database.js";
7
+ * vi.mock("@grackle-ai/database", () => createDatabaseMock());
8
+ * ```
9
+ *
10
+ * All store namespaces are provided with vi.fn() stubs that return safe defaults
11
+ * (empty arrays, undefined, etc.). Individual tests can override specific functions
12
+ * via `vi.mocked(store.someMethod).mockReturnValue(...)`.
13
+ */
14
+ import { vi } from "vitest";
15
+ /** Create a complete mock of the `@grackle-ai/database` barrel export. */
16
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
17
+ export function createDatabaseMock() {
18
+ return {
19
+ db: {},
20
+ sqlite: undefined,
21
+ openDatabase: vi.fn(),
22
+ initDatabase: vi.fn(),
23
+ seedDatabase: vi.fn(),
24
+ schema: {},
25
+ sessionStore: {
26
+ createSession: vi.fn(),
27
+ getSession: vi.fn(() => undefined),
28
+ listSessions: vi.fn(() => []),
29
+ listByEnv: vi.fn(() => []),
30
+ listSessionsForTask: vi.fn(() => []),
31
+ listSessionsByTaskIds: vi.fn(() => []),
32
+ getLatestSessionForTask: vi.fn(() => undefined),
33
+ getActiveForEnv: vi.fn(() => undefined),
34
+ getActiveSessionsForTask: vi.fn(() => []),
35
+ getSuspendedForEnv: vi.fn(() => []),
36
+ getChildSessions: vi.fn(() => []),
37
+ updateSession: vi.fn(),
38
+ updateSessionStatus: vi.fn(),
39
+ updateSessionUsage: vi.fn(),
40
+ updateRuntimeSessionId: vi.fn(),
41
+ incrementTurns: vi.fn(),
42
+ suspendSession: vi.fn(),
43
+ reanimateSession: vi.fn(),
44
+ setSessionTask: vi.fn(),
45
+ deleteByEnvironment: vi.fn(),
46
+ aggregateUsage: vi.fn(() => ({ inputTokens: 0, outputTokens: 0, costUsd: 0, sessionCount: 0 })),
47
+ },
48
+ taskStore: {
49
+ createTask: vi.fn(),
50
+ insertTask: vi.fn(),
51
+ getTask: vi.fn(() => undefined),
52
+ listTasks: vi.fn(() => []),
53
+ updateTask: vi.fn(),
54
+ updateTaskStatus: vi.fn(),
55
+ markTaskComplete: vi.fn(),
56
+ deleteTask: vi.fn(),
57
+ setTaskWorkspace: vi.fn(),
58
+ setTaskDependsOn: vi.fn(),
59
+ getUnblockedTasks: vi.fn(() => []),
60
+ checkAndUnblock: vi.fn(() => []),
61
+ areDependenciesMet: vi.fn(() => true),
62
+ buildChildIdsMap: vi.fn(() => new Map()),
63
+ getChildren: vi.fn(() => []),
64
+ getDescendants: vi.fn(() => []),
65
+ getAncestors: vi.fn(() => []),
66
+ getChildStatusCounts: vi.fn(() => ({})),
67
+ },
68
+ workspaceStore: {
69
+ createWorkspace: vi.fn(),
70
+ getWorkspace: vi.fn(() => undefined),
71
+ listWorkspaces: vi.fn(() => []),
72
+ updateWorkspace: vi.fn(),
73
+ archiveWorkspace: vi.fn(),
74
+ countWorkspacesByEnvironment: vi.fn(() => 0),
75
+ },
76
+ personaStore: {
77
+ createPersona: vi.fn(),
78
+ getPersona: vi.fn(() => undefined),
79
+ getPersonaByName: vi.fn(() => undefined),
80
+ listPersonas: vi.fn(() => []),
81
+ updatePersona: vi.fn(),
82
+ deletePersona: vi.fn(),
83
+ },
84
+ findingStore: {
85
+ postFinding: vi.fn(),
86
+ queryFindings: vi.fn(() => []),
87
+ },
88
+ settingsStore: {
89
+ getSetting: vi.fn(() => undefined),
90
+ setSetting: vi.fn(),
91
+ isAllowedSettingKey: vi.fn(() => true),
92
+ WRITABLE_SETTING_KEYS: new Set(["default_persona_id", "onboarding_completed"]),
93
+ },
94
+ envRegistry: {
95
+ listEnvironments: vi.fn(() => []),
96
+ getEnvironment: vi.fn(() => undefined),
97
+ addEnvironment: vi.fn(),
98
+ removeEnvironment: vi.fn(),
99
+ updateEnvironmentStatus: vi.fn(),
100
+ markBootstrapped: vi.fn(),
101
+ setEnvInfo: vi.fn(),
102
+ updateAdapterConfig: vi.fn(),
103
+ updateEnvironment: vi.fn(),
104
+ resetAllStatuses: vi.fn(),
105
+ },
106
+ tokenStore: {
107
+ setToken: vi.fn(),
108
+ deleteToken: vi.fn(),
109
+ listTokens: vi.fn(() => []),
110
+ getBundle: vi.fn(() => ({ tokens: [] })),
111
+ },
112
+ credentialProviders: {
113
+ getCredentialProviders: vi.fn(() => ({ claude: "off", github: "off", copilot: "off", codex: "off", goose: "off" })),
114
+ setCredentialProviders: vi.fn(),
115
+ parseCredentialProviderConfig: vi.fn(),
116
+ isValidCredentialProviderConfig: vi.fn(() => true),
117
+ VALID_PROVIDERS: ["claude", "github", "copilot", "codex", "goose"],
118
+ VALID_CLAUDE_VALUES: new Set(["off", "subscription", "api_key"]),
119
+ VALID_TOGGLE_VALUES: new Set(["off", "on"]),
120
+ },
121
+ // Direct barrel exports
122
+ isAllowedSettingKey: vi.fn(() => true),
123
+ WRITABLE_SETTING_KEYS: new Set(["default_persona_id", "onboarding_completed"]),
124
+ VALID_PROVIDERS: ["claude", "github", "copilot", "codex", "goose"],
125
+ VALID_CLAUDE_VALUES: new Set(["off", "subscription", "api_key"]),
126
+ VALID_TOGGLE_VALUES: new Set(["off", "on"]),
127
+ persistEvent: vi.fn(),
128
+ // Utilities
129
+ grackleHome: "/tmp/test-grackle",
130
+ safeParseJsonArray: (value) => {
131
+ if (!value) {
132
+ return [];
133
+ }
134
+ try {
135
+ const p = JSON.parse(value);
136
+ return Array.isArray(p) ? p.filter((i) => typeof i === "string") : [];
137
+ }
138
+ catch {
139
+ return [];
140
+ }
141
+ },
142
+ slugify: (text) => text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40),
143
+ encrypt: vi.fn((x) => x),
144
+ decrypt: vi.fn((x) => x),
145
+ };
146
+ }
147
+ //# sourceMappingURL=mock-database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-database.js","sourceRoot":"","sources":["../../src/test-utils/mock-database.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /** Options for {@link pushToEnv}. */
2
+ export interface PushToEnvOptions {
3
+ /** When true, filter out file-type tokens (only push env vars). */
4
+ excludeFileTokens?: boolean;
5
+ }
6
+ /** Push the current token bundle to a single connected environment. */
7
+ export declare function pushToEnv(environmentId: string, options?: PushToEnvOptions): Promise<void>;
8
+ /** Push the current token bundle to all connected environments in parallel. */
9
+ export declare function pushToAll(): Promise<void>;
10
+ /**
11
+ * Push enabled provider credentials to a single connected environment.
12
+ * When `runtime` is specified, only providers relevant to that runtime are included.
13
+ * Reads fresh values from `process.env` / disk based on the credential provider config.
14
+ */
15
+ export declare function pushProviderCredentialsToEnv(environmentId: string, runtime?: string, options?: PushToEnvOptions): Promise<void>;
16
+ /**
17
+ * Best-effort push of stored tokens and provider credentials before a task spawn.
18
+ * When `runtime` is specified, only providers relevant to that runtime are pushed.
19
+ * Both pushes run concurrently; failures are logged as warnings and do not block.
20
+ */
21
+ export declare function refreshTokensForTask(environmentId: string, runtime?: string, options?: PushToEnvOptions): Promise<void>;
22
+ //# sourceMappingURL=token-push.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-push.d.ts","sourceRoot":"","sources":["../src/token-push.ts"],"names":[],"mappings":"AAcA,qCAAqC;AACrC,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,uEAAuE;AACvE,wBAAsB,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhG;AAED,+EAA+E;AAC/E,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAc/C;AAED;;;;GAIG;AACH,wBAAsB,4BAA4B,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBrI;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAY7H"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Token push orchestration — distributes stored tokens and credential
3
+ * provider bundles to connected PowerLine environments.
4
+ *
5
+ * This is service-level logic that depends on adapter-manager (network) and
6
+ * env-registry (lookup). The pure persistence layer lives in
7
+ * `@grackle-ai/database` (tokenStore), and credential bundle building lives in
8
+ * {@link ./credential-bundle.ts}.
9
+ */
10
+ import * as adapterManager from "./adapter-manager.js";
11
+ import { envRegistry, tokenStore } from "@grackle-ai/database";
12
+ import { buildProviderTokenBundle } from "./credential-bundle.js";
13
+ import { logger } from "./logger.js";
14
+ /** Push the current token bundle to a single connected environment. */
15
+ export async function pushToEnv(environmentId, options) {
16
+ const conn = adapterManager.getConnection(environmentId);
17
+ if (!conn) {
18
+ return;
19
+ }
20
+ const bundle = tokenStore.getBundle();
21
+ if (options?.excludeFileTokens) {
22
+ bundle.tokens = bundle.tokens.filter((t) => t.type !== "file");
23
+ }
24
+ if (bundle.tokens.length === 0) {
25
+ return;
26
+ }
27
+ await conn.client.pushTokens(bundle);
28
+ }
29
+ /** Push the current token bundle to all connected environments in parallel. */
30
+ export async function pushToAll() {
31
+ const connections = adapterManager.listConnections();
32
+ const promises = [];
33
+ for (const [environmentId] of connections) {
34
+ const env = envRegistry.getEnvironment(environmentId);
35
+ const opts = env?.adapterType === "local" ? { excludeFileTokens: true } : undefined;
36
+ promises.push(pushToEnv(environmentId, opts).catch((err) => {
37
+ logger.error({ environmentId, err }, "Failed to push tokens");
38
+ }));
39
+ }
40
+ await Promise.all(promises);
41
+ }
42
+ /**
43
+ * Push enabled provider credentials to a single connected environment.
44
+ * When `runtime` is specified, only providers relevant to that runtime are included.
45
+ * Reads fresh values from `process.env` / disk based on the credential provider config.
46
+ */
47
+ export async function pushProviderCredentialsToEnv(environmentId, runtime, options) {
48
+ const conn = adapterManager.getConnection(environmentId);
49
+ if (!conn) {
50
+ return;
51
+ }
52
+ const bundle = buildProviderTokenBundle(runtime);
53
+ if (options?.excludeFileTokens) {
54
+ bundle.tokens = bundle.tokens.filter((t) => t.type !== "file");
55
+ }
56
+ if (bundle.tokens.length === 0) {
57
+ return;
58
+ }
59
+ await conn.client.pushTokens(bundle);
60
+ }
61
+ /**
62
+ * Best-effort push of stored tokens and provider credentials before a task spawn.
63
+ * When `runtime` is specified, only providers relevant to that runtime are pushed.
64
+ * Both pushes run concurrently; failures are logged as warnings and do not block.
65
+ */
66
+ export async function refreshTokensForTask(environmentId, runtime, options) {
67
+ const results = await Promise.allSettled([
68
+ pushToEnv(environmentId, options),
69
+ pushProviderCredentialsToEnv(environmentId, runtime, options),
70
+ ]);
71
+ if (results[0].status === "rejected") {
72
+ logger.warn({ environmentId, err: results[0].reason }, "Failed to push tokens before task start");
73
+ }
74
+ if (results[1].status === "rejected") {
75
+ logger.warn({ environmentId, err: results[1].reason }, "Failed to push provider credentials before task start");
76
+ }
77
+ }
78
+ //# sourceMappingURL=token-push.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-push.js","sourceRoot":"","sources":["../src/token-push.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** Generate a Markdown transcript from a session's JSONL log. */
2
+ export declare function generateTranscript(logPath: string): string;
3
+ /** Generate and write a Markdown transcript file alongside the session log. */
4
+ export declare function writeTranscript(logPath: string): void;
5
+ //# sourceMappingURL=transcript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../src/transcript.ts"],"names":[],"mappings":"AAkDA,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAgB1D;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKrD"}
@@ -0,0 +1,71 @@
1
+ import { readLog } from "./log-writer.js";
2
+ import { writeFileSync, mkdirSync } from "node:fs";
3
+ import { join, dirname } from "node:path";
4
+ function renderEntry(entry) {
5
+ switch (entry.type) {
6
+ case "system": {
7
+ // System context events contain the full system prompt — render as a
8
+ // collapsible details block instead of an inline italic line.
9
+ if (entry.raw) {
10
+ try {
11
+ const raw = JSON.parse(entry.raw);
12
+ if (raw.systemContext === true) {
13
+ return `<details>\n<summary>System Prompt</summary>\n\n\`\`\`\n${entry.content}\n\`\`\`\n</details>\n`;
14
+ }
15
+ }
16
+ catch { /* not JSON, render as normal */ }
17
+ }
18
+ return `> _${entry.content}_\n`;
19
+ }
20
+ case "text":
21
+ return `${entry.content}\n`;
22
+ case "tool_use": {
23
+ try {
24
+ const parsed = JSON.parse(entry.content);
25
+ return `\`\`\`\n${parsed.tool}: ${JSON.stringify(parsed.args, null, 2)}\n\`\`\`\n`;
26
+ }
27
+ catch {
28
+ return `\`\`\`\n${entry.content}\n\`\`\`\n`;
29
+ }
30
+ }
31
+ case "tool_result":
32
+ return `<details>\n<summary>Tool output</summary>\n\n\`\`\`\n${entry.content}\n\`\`\`\n</details>\n`;
33
+ case "error":
34
+ return `**Error:** ${entry.content}\n`;
35
+ case "status":
36
+ return `---\n*Status: ${entry.content}*\n`;
37
+ case "signal": {
38
+ if (!entry.content) {
39
+ return `> **[SIGNAL]**\n`;
40
+ }
41
+ const lines = entry.content.split("\n");
42
+ const renderedLines = lines.map((line, index) => index === 0 ? `> **[SIGNAL]** ${line}` : `> ${line}`);
43
+ return renderedLines.join("\n") + "\n";
44
+ }
45
+ default:
46
+ return `${entry.content}\n`;
47
+ }
48
+ }
49
+ /** Generate a Markdown transcript from a session's JSONL log. */
50
+ export function generateTranscript(logPath) {
51
+ const entries = readLog(logPath);
52
+ if (entries.length === 0)
53
+ return "*(empty session)*\n";
54
+ const lines = [];
55
+ lines.push(`# Session Transcript\n`);
56
+ lines.push(`*Started: ${entries[0].timestamp}*\n`);
57
+ for (const entry of entries) {
58
+ lines.push(renderEntry(entry));
59
+ }
60
+ const last = entries[entries.length - 1];
61
+ lines.push(`\n*Ended: ${last.timestamp}*\n`);
62
+ return lines.join("\n");
63
+ }
64
+ /** Generate and write a Markdown transcript file alongside the session log. */
65
+ export function writeTranscript(logPath) {
66
+ const md = generateTranscript(logPath);
67
+ const transcriptPath = join(logPath, "transcript.md");
68
+ mkdirSync(dirname(transcriptPath), { recursive: true });
69
+ writeFileSync(transcriptPath, md, "utf8");
70
+ }
71
+ //# sourceMappingURL=transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.js","sourceRoot":"","sources":["../src/transcript.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /** Trimmed stdout/stderr from a child process execution. */
2
+ export interface ExecResult {
3
+ stdout: string;
4
+ stderr: string;
5
+ }
6
+ /**
7
+ * Execute a command as a child process and return its trimmed output.
8
+ * @param cmd - Executable name or path.
9
+ * @param args - Arguments to pass to the executable.
10
+ * @param opts - Optional timeout, cwd, and env overrides.
11
+ */
12
+ export declare function exec(cmd: string, args: string[], opts?: {
13
+ timeout?: number;
14
+ cwd?: string;
15
+ env?: NodeJS.ProcessEnv;
16
+ }): Promise<ExecResult>;
17
+ //# sourceMappingURL=exec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAQA,4DAA4D;AAC5D,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAsB,IAAI,CACxB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,GACjE,OAAO,CAAC,UAAU,CAAC,CAQrB"}
@@ -0,0 +1,21 @@
1
+ import { execFile as _execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ const execFileAsync = promisify(_execFile);
4
+ const DEFAULT_EXEC_TIMEOUT_MS = 60_000;
5
+ const EXEC_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
6
+ /**
7
+ * Execute a command as a child process and return its trimmed output.
8
+ * @param cmd - Executable name or path.
9
+ * @param args - Arguments to pass to the executable.
10
+ * @param opts - Optional timeout, cwd, and env overrides.
11
+ */
12
+ export async function exec(cmd, args, opts) {
13
+ const { stdout, stderr } = await execFileAsync(cmd, args, {
14
+ timeout: opts?.timeout ?? DEFAULT_EXEC_TIMEOUT_MS,
15
+ cwd: opts?.cwd,
16
+ env: opts?.env ?? process.env,
17
+ maxBuffer: EXEC_MAX_BUFFER_BYTES,
18
+ });
19
+ return { stdout: stdout.trim(), stderr: stderr.trim() };
20
+ }
21
+ //# sourceMappingURL=exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAmC,SAAS,CAAC,SAAS,CAAC,CAAC;AAE3E,MAAM,uBAAuB,GAAW,MAAM,CAAC;AAC/C,MAAM,qBAAqB,GAAW,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAQvD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,GAAW,EACX,IAAc,EACd,IAAkE;IAElE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE;QACxD,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,uBAAuB;QACjD,GAAG,EAAE,IAAI,EAAE,GAAG;QACd,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG;QAC7B,SAAS,EAAE,qBAAqB;KACjC,CAAC,CAAC;IACH,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Translate a raw `gh` CLI error into a user-friendly message.
3
+ * The raw error is still logged server-side for diagnostics.
4
+ */
5
+ export declare function formatGhError(err: unknown, operation: string): string;
6
+ //# sourceMappingURL=format-gh-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-gh-error.d.ts","sourceRoot":"","sources":["../../src/utils/format-gh-error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CA4BrE"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Translate a raw `gh` CLI error into a user-friendly message.
3
+ * The raw error is still logged server-side for diagnostics.
4
+ */
5
+ export function formatGhError(err, operation) {
6
+ const message = err instanceof Error ? err.message : String(err);
7
+ const rawStderr = err instanceof Error && "stderr" in err
8
+ ? err.stderr
9
+ : undefined;
10
+ const stderr = typeof rawStderr === "string" && rawStderr.length > 0
11
+ ? rawStderr
12
+ : Buffer.isBuffer(rawStderr) && rawStderr.length > 0
13
+ ? rawStderr.toString()
14
+ : "";
15
+ const code = err instanceof Error && "code" in err
16
+ ? String(err.code)
17
+ : "";
18
+ if (code === "ENOENT" || message.includes("ENOENT")) {
19
+ return "Could not find the `gh` CLI. Ensure GitHub CLI is installed and available on your system PATH, then restart the Grackle server.";
20
+ }
21
+ if (code === "EACCES" || message.includes("EACCES")) {
22
+ return "`gh` CLI found but not executable. Check file permissions.";
23
+ }
24
+ const combined = `${stderr} ${message}`.toLowerCase();
25
+ if (combined.includes("auth") || combined.includes("login")) {
26
+ return "GitHub CLI is not authenticated. Run `gh auth login` and restart.";
27
+ }
28
+ return `Failed to ${operation}: ${stderr || message}`;
29
+ }
30
+ //# sourceMappingURL=format-gh-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-gh-error.js","sourceRoot":"","sources":["../../src/utils/format-gh-error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,GAAY,EAAE,SAAiB;IAC3D,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,MAAM,SAAS,GACb,GAAG,YAAY,KAAK,IAAI,QAAQ,IAAI,GAAG;QACrC,CAAC,CAAE,GAAmC,CAAC,MAAM;QAC7C,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,MAAM,GACV,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;QACnD,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;YAClD,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE;YACtB,CAAC,CAAC,EAAE,CAAC;IACX,MAAM,IAAI,GACR,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG;QACnC,CAAC,CAAC,MAAM,CAAE,GAAiC,CAAC,IAAI,CAAC;QACjD,CAAC,CAAC,EAAE,CAAC;IAET,IAAI,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpD,OAAO,iIAAiI,CAAC;IAC3I,CAAC;IACD,IAAI,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpD,OAAO,4DAA4D,CAAC;IACtE,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,WAAW,EAAE,CAAC;IACtD,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5D,OAAO,mEAAmE,CAAC;IAC7E,CAAC;IACD,OAAO,aAAa,SAAS,KAAK,MAAM,IAAI,OAAO,EAAE,CAAC;AACxD,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Detect the first non-internal IPv4 address on the machine (LAN IP).
3
+ *
4
+ * Returns `undefined` when no suitable interface is found.
5
+ */
6
+ export declare function detectLanIp(): string | undefined;
7
+ //# sourceMappingURL=network.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../src/utils/network.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,MAAM,GAAG,SAAS,CAahD"}
@@ -0,0 +1,21 @@
1
+ import { networkInterfaces } from "node:os";
2
+ /**
3
+ * Detect the first non-internal IPv4 address on the machine (LAN IP).
4
+ *
5
+ * Returns `undefined` when no suitable interface is found.
6
+ */
7
+ export function detectLanIp() {
8
+ const interfaces = networkInterfaces();
9
+ for (const entries of Object.values(interfaces)) {
10
+ if (!entries) {
11
+ continue;
12
+ }
13
+ for (const entry of entries) {
14
+ if (entry.family === "IPv4" && !entry.internal) {
15
+ return entry.address;
16
+ }
17
+ }
18
+ }
19
+ return undefined;
20
+ }
21
+ //# sourceMappingURL=network.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.js","sourceRoot":"","sources":["../../src/utils/network.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5C;;;;GAIG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;IACvC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;QAChD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,SAAS;QACX,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC/C,OAAO,KAAK,CAAC,OAAO,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Find and return an available TCP port by briefly binding to port 0. */
2
+ export declare function findFreePort(): Promise<number>;
3
+ //# sourceMappingURL=ports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../../src/utils/ports.ts"],"names":[],"mappings":"AAEA,0EAA0E;AAC1E,wBAAgB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAc9C"}
@@ -0,0 +1,19 @@
1
+ import { createServer } from "node:net";
2
+ /** Find and return an available TCP port by briefly binding to port 0. */
3
+ export function findFreePort() {
4
+ return new Promise((resolve, reject) => {
5
+ const server = createServer();
6
+ server.listen(0, () => {
7
+ const addr = server.address();
8
+ if (addr && typeof addr === "object") {
9
+ const port = addr.port;
10
+ server.close(() => resolve(port));
11
+ }
12
+ else {
13
+ server.close(() => reject(new Error("Failed to get port")));
14
+ }
15
+ });
16
+ server.on("error", reject);
17
+ });
18
+ }
19
+ //# sourceMappingURL=ports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.js","sourceRoot":"","sources":["../../src/utils/ports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,0EAA0E;AAC1E,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE;YACpB,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;YAC9B,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;gBACvB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Return a promise that resolves after the specified number of milliseconds. */
2
+ export declare function sleep(ms: number): Promise<void>;
3
+ //# sourceMappingURL=sleep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sleep.d.ts","sourceRoot":"","sources":["../../src/utils/sleep.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C"}
@@ -0,0 +1,5 @@
1
+ /** Return a promise that resolves after the specified number of milliseconds. */
2
+ export function sleep(ms) {
3
+ return new Promise((resolve) => setTimeout(resolve, ms));
4
+ }
5
+ //# sourceMappingURL=sleep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sleep.js","sourceRoot":"","sources":["../../src/utils/sleep.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,MAAM,UAAU,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { WebSocketServer, WebSocket } from "ws";
2
+ import type { Server as HttpServer } from "node:http";
3
+ import { taskStore } from "@grackle-ai/database";
4
+ /**
5
+ * Check whether a WebSocket Origin header is allowed.
6
+ *
7
+ * Rules:
8
+ * - Missing origin (non-browser clients, extensions) → always allowed
9
+ * - Origin port must match the web server port
10
+ * - In local mode (`allowNetwork === false`), hostname must be loopback
11
+ * - In network mode (`allowNetwork === true`), any hostname on the right port is allowed
12
+ */
13
+ export declare function isAllowedOrigin(origin: string | undefined, webPort: number, allowNetwork: boolean): boolean;
14
+ /** Options for creating the WebSocket bridge. */
15
+ interface WsBridgeOptions {
16
+ verifyApiKey: (token: string) => boolean;
17
+ validateCookie?: (cookieHeader: string) => boolean;
18
+ webPort?: number;
19
+ allowNetwork?: boolean;
20
+ }
21
+ /** Create a WebSocket server on top of an HTTP server for real-time event streaming. */
22
+ export declare function createWsBridge(httpServer: HttpServer, options: WsBridgeOptions): WebSocketServer;
23
+ /** Start a new agent session for a task. Returns an error message string on failure, undefined on success. */
24
+ export declare function startTaskSession(ws: WebSocket | undefined, task: taskStore.TaskRow, options?: {
25
+ personaId?: string;
26
+ environmentId?: string;
27
+ notes?: string;
28
+ }): Promise<string | undefined>;
29
+ export {};
30
+ //# sourceMappingURL=ws-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-bridge.d.ts","sourceRoot":"","sources":["../src/ws-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AAItD,OAAO,EAA6C,SAAS,EAAe,MAAM,sBAAsB,CAAC;AAqCzG;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,OAAO,GACpB,OAAO,CAyBT;AAQD,iDAAiD;AACjD,UAAU,eAAe;IACvB,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACzC,cAAc,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wFAAwF;AACxF,wBAAgB,cAAc,CAC5B,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,eAAe,GACvB,eAAe,CAiDjB;AA6HD,8GAA8G;AAC9G,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,SAAS,GAAG,SAAS,EACzB,IAAI,EAAE,SAAS,CAAC,OAAO,EACvB,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACvE,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA6I7B"}