@action-llama/action-llama 0.17.7 → 0.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/agent-docs/AGENTS.md +5 -5
  2. package/dist/agents/bash-prefix.d.ts +9 -0
  3. package/dist/agents/bash-prefix.d.ts.map +1 -0
  4. package/dist/agents/bash-prefix.js +15 -0
  5. package/dist/agents/bash-prefix.js.map +1 -0
  6. package/dist/agents/chat-entry.d.ts +9 -0
  7. package/dist/agents/chat-entry.d.ts.map +1 -0
  8. package/dist/agents/chat-entry.js +165 -0
  9. package/dist/agents/chat-entry.js.map +1 -0
  10. package/dist/agents/container-entry.d.ts.map +1 -1
  11. package/dist/agents/container-entry.js +11 -148
  12. package/dist/agents/container-entry.js.map +1 -1
  13. package/dist/agents/container-runner.d.ts +1 -1
  14. package/dist/agents/container-runner.d.ts.map +1 -1
  15. package/dist/agents/container-runner.js.map +1 -1
  16. package/dist/agents/credential-setup.d.ts +21 -0
  17. package/dist/agents/credential-setup.d.ts.map +1 -0
  18. package/dist/agents/credential-setup.js +160 -0
  19. package/dist/agents/credential-setup.js.map +1 -0
  20. package/dist/agents/prompt.d.ts +2 -1
  21. package/dist/agents/prompt.d.ts.map +1 -1
  22. package/dist/agents/prompt.js +8 -2
  23. package/dist/agents/prompt.js.map +1 -1
  24. package/dist/agents/runner.d.ts +1 -1
  25. package/dist/agents/runner.d.ts.map +1 -1
  26. package/dist/agents/runner.js.map +1 -1
  27. package/dist/agents/session-factory.d.ts.map +1 -1
  28. package/dist/agents/session-factory.js +2 -1
  29. package/dist/agents/session-factory.js.map +1 -1
  30. package/dist/build-info.json +1 -1
  31. package/dist/chat/container-launcher.d.ts +33 -0
  32. package/dist/chat/container-launcher.d.ts.map +1 -0
  33. package/dist/chat/container-launcher.js +82 -0
  34. package/dist/chat/container-launcher.js.map +1 -0
  35. package/dist/chat/event-mapper.d.ts +27 -0
  36. package/dist/chat/event-mapper.d.ts.map +1 -0
  37. package/dist/chat/event-mapper.js +56 -0
  38. package/dist/chat/event-mapper.js.map +1 -0
  39. package/dist/chat/ink-adapter.d.ts +9 -0
  40. package/dist/chat/ink-adapter.d.ts.map +1 -0
  41. package/dist/chat/ink-adapter.js +120 -0
  42. package/dist/chat/ink-adapter.js.map +1 -0
  43. package/dist/chat/local-transport.d.ts +28 -0
  44. package/dist/chat/local-transport.d.ts.map +1 -0
  45. package/dist/chat/local-transport.js +68 -0
  46. package/dist/chat/local-transport.js.map +1 -0
  47. package/dist/chat/remote-transport.d.ts +30 -0
  48. package/dist/chat/remote-transport.d.ts.map +1 -0
  49. package/dist/chat/remote-transport.js +110 -0
  50. package/dist/chat/remote-transport.js.map +1 -0
  51. package/dist/chat/routes.d.ts +10 -0
  52. package/dist/chat/routes.d.ts.map +1 -0
  53. package/dist/chat/routes.js +58 -0
  54. package/dist/chat/routes.js.map +1 -0
  55. package/dist/chat/session-manager.d.ts +20 -0
  56. package/dist/chat/session-manager.d.ts.map +1 -0
  57. package/dist/chat/session-manager.js +64 -0
  58. package/dist/chat/session-manager.js.map +1 -0
  59. package/dist/chat/transport.d.ts +15 -0
  60. package/dist/chat/transport.d.ts.map +1 -0
  61. package/dist/chat/transport.js +5 -0
  62. package/dist/chat/transport.js.map +1 -0
  63. package/dist/chat/types.d.ts +50 -0
  64. package/dist/chat/types.d.ts.map +1 -0
  65. package/dist/chat/types.js +7 -0
  66. package/dist/chat/types.js.map +1 -0
  67. package/dist/chat/validation.d.ts +30 -0
  68. package/dist/chat/validation.d.ts.map +1 -0
  69. package/dist/chat/validation.js +79 -0
  70. package/dist/chat/validation.js.map +1 -0
  71. package/dist/chat/ws-handler.d.ts +31 -0
  72. package/dist/chat/ws-handler.d.ts.map +1 -0
  73. package/dist/chat/ws-handler.js +247 -0
  74. package/dist/chat/ws-handler.js.map +1 -0
  75. package/dist/cli/commands/add.d.ts +14 -0
  76. package/dist/cli/commands/add.d.ts.map +1 -0
  77. package/dist/cli/commands/add.js +188 -0
  78. package/dist/cli/commands/add.js.map +1 -0
  79. package/dist/cli/commands/agent.d.ts.map +1 -1
  80. package/dist/cli/commands/agent.js +93 -41
  81. package/dist/cli/commands/agent.js.map +1 -1
  82. package/dist/cli/commands/chat.d.ts.map +1 -1
  83. package/dist/cli/commands/chat.js +38 -2
  84. package/dist/cli/commands/chat.js.map +1 -1
  85. package/dist/cli/commands/doctor.d.ts.map +1 -1
  86. package/dist/cli/commands/doctor.js +26 -13
  87. package/dist/cli/commands/doctor.js.map +1 -1
  88. package/dist/cli/commands/run.d.ts +1 -1
  89. package/dist/cli/commands/run.d.ts.map +1 -1
  90. package/dist/cli/commands/run.js +2 -1
  91. package/dist/cli/commands/run.js.map +1 -1
  92. package/dist/cli/commands/update.d.ts +14 -0
  93. package/dist/cli/commands/update.d.ts.map +1 -0
  94. package/dist/cli/commands/update.js +191 -0
  95. package/dist/cli/commands/update.js.map +1 -0
  96. package/dist/cli/commands/webhook.js +9 -10
  97. package/dist/cli/commands/webhook.js.map +1 -1
  98. package/dist/cli/main.js +32 -2
  99. package/dist/cli/main.js.map +1 -1
  100. package/dist/control/routes/control.d.ts +1 -1
  101. package/dist/control/routes/control.d.ts.map +1 -1
  102. package/dist/control/routes/control.js +12 -2
  103. package/dist/control/routes/control.js.map +1 -1
  104. package/dist/control/routes/dashboard.d.ts.map +1 -1
  105. package/dist/control/routes/dashboard.js +11 -1
  106. package/dist/control/routes/dashboard.js.map +1 -1
  107. package/dist/execution/execution.d.ts +5 -2
  108. package/dist/execution/execution.d.ts.map +1 -1
  109. package/dist/execution/execution.js +22 -7
  110. package/dist/execution/execution.js.map +1 -1
  111. package/dist/execution/runner-pool.d.ts +1 -1
  112. package/dist/execution/runner-pool.d.ts.map +1 -1
  113. package/dist/execution/runner-setup.d.ts.map +1 -1
  114. package/dist/execution/runner-setup.js +15 -2
  115. package/dist/execution/runner-setup.js.map +1 -1
  116. package/dist/frontend/assets/index-Cb_hkpne.js +13 -0
  117. package/dist/frontend/assets/index-ClYf0bqf.css +2 -0
  118. package/dist/frontend/index.html +2 -2
  119. package/dist/gateway/index.d.ts +11 -0
  120. package/dist/gateway/index.d.ts.map +1 -1
  121. package/dist/gateway/index.js +32 -1
  122. package/dist/gateway/index.js.map +1 -1
  123. package/dist/remote/push.js +1 -4
  124. package/dist/remote/push.js.map +1 -1
  125. package/dist/scheduler/gateway-setup.d.ts +3 -0
  126. package/dist/scheduler/gateway-setup.d.ts.map +1 -1
  127. package/dist/scheduler/gateway-setup.js +47 -7
  128. package/dist/scheduler/gateway-setup.js.map +1 -1
  129. package/dist/scheduler/index.d.ts.map +1 -1
  130. package/dist/scheduler/index.js +4 -1
  131. package/dist/scheduler/index.js.map +1 -1
  132. package/dist/setup/scaffold.d.ts.map +1 -1
  133. package/dist/setup/scaffold.js +21 -21
  134. package/dist/setup/scaffold.js.map +1 -1
  135. package/dist/shared/config.d.ts +29 -5
  136. package/dist/shared/config.d.ts.map +1 -1
  137. package/dist/shared/config.js +50 -37
  138. package/dist/shared/config.js.map +1 -1
  139. package/dist/shared/environment.d.ts +0 -7
  140. package/dist/shared/environment.d.ts.map +1 -1
  141. package/dist/shared/environment.js +0 -29
  142. package/dist/shared/environment.js.map +1 -1
  143. package/dist/shared/validation.d.ts +9 -2
  144. package/dist/shared/validation.d.ts.map +1 -1
  145. package/dist/shared/validation.js +39 -20
  146. package/dist/shared/validation.js.map +1 -1
  147. package/dist/tui/App.js +2 -2
  148. package/dist/tui/App.js.map +1 -1
  149. package/dist/tui/status-tracker.d.ts +8 -0
  150. package/dist/tui/status-tracker.d.ts.map +1 -1
  151. package/dist/tui/status-tracker.js +27 -0
  152. package/dist/tui/status-tracker.js.map +1 -1
  153. package/dist/webhooks/providers/index.js +4 -4
  154. package/dist/webhooks/providers/index.js.map +1 -1
  155. package/package.json +3 -1
  156. package/dist/frontend/assets/index-heXAA4Ev.js +0 -13
  157. package/dist/frontend/assets/index-tjVM5-7N.css +0 -2
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Chat protocol types for bidirectional real-time agent communication.
3
+ *
4
+ * Used by both browser WebSocket connections and container-side chat entries.
5
+ */
6
+ export interface UserMessage {
7
+ type: "user_message";
8
+ text: string;
9
+ }
10
+ export interface CancelMessage {
11
+ type: "cancel";
12
+ }
13
+ export interface ShutdownMessage {
14
+ type: "shutdown";
15
+ }
16
+ export type ChatInbound = UserMessage | CancelMessage | ShutdownMessage;
17
+ export interface AssistantMessage {
18
+ type: "assistant_message";
19
+ text: string;
20
+ done: boolean;
21
+ }
22
+ export interface ToolStart {
23
+ type: "tool_start";
24
+ toolCallId: string;
25
+ tool: string;
26
+ input: string;
27
+ }
28
+ export interface ToolResult {
29
+ type: "tool_result";
30
+ toolCallId: string;
31
+ tool: string;
32
+ output: string;
33
+ error?: boolean;
34
+ }
35
+ export interface ChatError {
36
+ type: "error";
37
+ message: string;
38
+ }
39
+ export interface Heartbeat {
40
+ type: "heartbeat";
41
+ }
42
+ export type ChatOutbound = AssistantMessage | ToolStart | ToolResult | ChatError | Heartbeat;
43
+ export interface ChatSession {
44
+ sessionId: string;
45
+ agentName: string;
46
+ containerName?: string;
47
+ createdAt: Date;
48
+ lastActivityAt: Date;
49
+ }
50
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/chat/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,aAAa,GAAG,eAAe,CAAC;AAIxE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,YAAY,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,MAAM,MAAM,YAAY,GACpB,gBAAgB,GAChB,SAAS,GACT,UAAU,GACV,SAAS,GACT,SAAS,CAAC;AAId,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,IAAI,CAAC;IAChB,cAAc,EAAE,IAAI,CAAC;CACtB"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Chat protocol types for bidirectional real-time agent communication.
3
+ *
4
+ * Used by both browser WebSocket connections and container-side chat entries.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/chat/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Message validation and rate limiting for the chat protocol.
3
+ */
4
+ export interface ValidationResult {
5
+ valid: boolean;
6
+ error?: string;
7
+ }
8
+ /**
9
+ * Validate an inbound chat message.
10
+ */
11
+ export declare function validateInbound(raw: string): ValidationResult;
12
+ /**
13
+ * Validate an outbound chat message.
14
+ */
15
+ export declare function validateOutbound(raw: string): ValidationResult;
16
+ /**
17
+ * Token bucket rate limiter for chat messages.
18
+ */
19
+ export declare class RateLimiter {
20
+ private tokens;
21
+ private lastRefill;
22
+ private readonly maxTokens;
23
+ private readonly refillRate;
24
+ constructor(maxTokens?: number, refillRatePerSecond?: number);
25
+ /**
26
+ * Try to consume a token. Returns true if allowed, false if rate-limited.
27
+ */
28
+ consume(): boolean;
29
+ }
30
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/chat/validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAuB7D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAiB9D;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,SAAS,SAAK,EAAE,mBAAmB,SAAK;IAOpD;;OAEG;IACH,OAAO,IAAI,OAAO;CAYnB"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Message validation and rate limiting for the chat protocol.
3
+ */
4
+ const MAX_MESSAGE_SIZE = 64 * 1024; // 64KB
5
+ const INBOUND_TYPES = new Set(["user_message", "cancel", "shutdown"]);
6
+ const OUTBOUND_TYPES = new Set(["assistant_message", "tool_start", "tool_result", "error", "heartbeat"]);
7
+ /**
8
+ * Validate an inbound chat message.
9
+ */
10
+ export function validateInbound(raw) {
11
+ if (raw.length > MAX_MESSAGE_SIZE) {
12
+ return { valid: false, error: `Message exceeds ${MAX_MESSAGE_SIZE} byte limit` };
13
+ }
14
+ let msg;
15
+ try {
16
+ msg = JSON.parse(raw);
17
+ }
18
+ catch {
19
+ return { valid: false, error: "Invalid JSON" };
20
+ }
21
+ if (!msg || typeof msg !== "object" || !INBOUND_TYPES.has(msg.type)) {
22
+ return { valid: false, error: `Invalid message type: ${msg?.type}` };
23
+ }
24
+ if (msg.type === "user_message") {
25
+ if (typeof msg.text !== "string" || msg.text.length === 0) {
26
+ return { valid: false, error: "user_message requires non-empty text" };
27
+ }
28
+ }
29
+ return { valid: true };
30
+ }
31
+ /**
32
+ * Validate an outbound chat message.
33
+ */
34
+ export function validateOutbound(raw) {
35
+ if (raw.length > MAX_MESSAGE_SIZE) {
36
+ return { valid: false, error: `Message exceeds ${MAX_MESSAGE_SIZE} byte limit` };
37
+ }
38
+ let msg;
39
+ try {
40
+ msg = JSON.parse(raw);
41
+ }
42
+ catch {
43
+ return { valid: false, error: "Invalid JSON" };
44
+ }
45
+ if (!msg || typeof msg !== "object" || !OUTBOUND_TYPES.has(msg.type)) {
46
+ return { valid: false, error: `Invalid message type: ${msg?.type}` };
47
+ }
48
+ return { valid: true };
49
+ }
50
+ /**
51
+ * Token bucket rate limiter for chat messages.
52
+ */
53
+ export class RateLimiter {
54
+ tokens;
55
+ lastRefill;
56
+ maxTokens;
57
+ refillRate;
58
+ constructor(maxTokens = 10, refillRatePerSecond = 10) {
59
+ this.maxTokens = maxTokens;
60
+ this.tokens = maxTokens;
61
+ this.refillRate = refillRatePerSecond;
62
+ this.lastRefill = Date.now();
63
+ }
64
+ /**
65
+ * Try to consume a token. Returns true if allowed, false if rate-limited.
66
+ */
67
+ consume() {
68
+ const now = Date.now();
69
+ const elapsed = (now - this.lastRefill) / 1000;
70
+ this.tokens = Math.min(this.maxTokens, this.tokens + elapsed * this.refillRate);
71
+ this.lastRefill = now;
72
+ if (this.tokens >= 1) {
73
+ this.tokens -= 1;
74
+ return true;
75
+ }
76
+ return false;
77
+ }
78
+ }
79
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/chat/validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * WebSocket handler for chat — bridges browser ↔ container per session.
3
+ *
4
+ * Two WS paths:
5
+ * /chat/ws/:sessionId — browser connects here (auth via header/cookie)
6
+ * /chat/container/:sessionId — container connects here (auth via first-message token)
7
+ */
8
+ import type { Server } from "http";
9
+ import { WebSocket } from "ws";
10
+ import type { ChatSessionManager } from "./session-manager.js";
11
+ import { RateLimiter } from "./validation.js";
12
+ import type { SessionStore } from "../control/session-store.js";
13
+ import type { Logger } from "../shared/logger.js";
14
+ interface BrowserConnection {
15
+ ws: WebSocket;
16
+ rateLimiter: RateLimiter;
17
+ }
18
+ interface ContainerConnection {
19
+ ws: WebSocket;
20
+ authenticated: boolean;
21
+ }
22
+ export interface ChatWebSocketState {
23
+ browserConnections: Map<string, BrowserConnection>;
24
+ containerConnections: Map<string, ContainerConnection>;
25
+ cleanupInterval: ReturnType<typeof setInterval>;
26
+ /** Callback to stop a chat container by session. */
27
+ stopContainer?: (sessionId: string) => Promise<void>;
28
+ }
29
+ export declare function attachChatWebSocket(server: Server, sessionManager: ChatSessionManager, apiKey: string, sessionStore?: SessionStore, logger?: Logger): ChatWebSocketState;
30
+ export {};
31
+ //# sourceMappingURL=ws-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-handler.d.ts","sourceRoot":"","sources":["../../src/chat/ws-handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,EAAmB,SAAS,EAAgB,MAAM,IAAI,CAAC;AAE9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAqC,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACjF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD,UAAU,iBAAiB;IACzB,EAAE,EAAE,SAAS,CAAC;IACd,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,UAAU,mBAAmB;IAC3B,EAAE,EAAE,SAAS,CAAC;IACd,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACnD,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IACvD,eAAe,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IAChD,oDAAoD;IACpD,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,kBAAkB,EAClC,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,YAAY,EAC3B,MAAM,CAAC,EAAE,MAAM,GACd,kBAAkB,CA2OpB"}
@@ -0,0 +1,247 @@
1
+ /**
2
+ * WebSocket handler for chat — bridges browser ↔ container per session.
3
+ *
4
+ * Two WS paths:
5
+ * /chat/ws/:sessionId — browser connects here (auth via header/cookie)
6
+ * /chat/container/:sessionId — container connects here (auth via first-message token)
7
+ */
8
+ import { WebSocketServer, WebSocket } from "ws";
9
+ import { safeCompare } from "../control/auth.js";
10
+ import { validateInbound, validateOutbound, RateLimiter } from "./validation.js";
11
+ export function attachChatWebSocket(server, sessionManager, apiKey, sessionStore, logger) {
12
+ const browserConnections = new Map();
13
+ const containerConnections = new Map();
14
+ // Browser-facing WS server
15
+ const browserWss = new WebSocketServer({ noServer: true });
16
+ // Container-facing WS server
17
+ const containerWss = new WebSocketServer({ noServer: true });
18
+ // Disconnection grace periods: track when browser disconnected
19
+ const browserDisconnectTimers = new Map();
20
+ server.on("upgrade", async (req, socket, head) => {
21
+ const url = new URL(req.url || "/", `http://${req.headers.host || "localhost"}`);
22
+ const pathname = url.pathname;
23
+ // Browser path: /chat/ws/:sessionId
24
+ const browserMatch = pathname.match(/^\/chat\/ws\/([^/]+)$/);
25
+ if (browserMatch) {
26
+ const sessionId = browserMatch[1];
27
+ const session = sessionManager.getSession(sessionId);
28
+ if (!session) {
29
+ socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
30
+ socket.destroy();
31
+ return;
32
+ }
33
+ // Authenticate via Authorization header or cookie
34
+ const authenticated = await authenticateBrowser(req, apiKey, sessionStore);
35
+ if (!authenticated) {
36
+ socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
37
+ socket.destroy();
38
+ return;
39
+ }
40
+ browserWss.handleUpgrade(req, socket, head, (ws) => {
41
+ handleBrowserConnection(ws, sessionId);
42
+ });
43
+ return;
44
+ }
45
+ // Container path: /chat/container/:sessionId
46
+ const containerMatch = pathname.match(/^\/chat\/container\/([^/]+)$/);
47
+ if (containerMatch) {
48
+ const sessionId = containerMatch[1];
49
+ const session = sessionManager.getSession(sessionId);
50
+ if (!session) {
51
+ socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
52
+ socket.destroy();
53
+ return;
54
+ }
55
+ containerWss.handleUpgrade(req, socket, head, (ws) => {
56
+ handleContainerConnection(ws, sessionId);
57
+ });
58
+ return;
59
+ }
60
+ // Not a chat path — let other upgrade handlers deal with it
61
+ });
62
+ function handleBrowserConnection(ws, sessionId) {
63
+ logger?.debug({ sessionId }, "browser WebSocket connected");
64
+ // Clear any grace-period timer from a prior disconnect
65
+ const timer = browserDisconnectTimers.get(sessionId);
66
+ if (timer) {
67
+ clearTimeout(timer);
68
+ browserDisconnectTimers.delete(sessionId);
69
+ }
70
+ const conn = { ws, rateLimiter: new RateLimiter() };
71
+ browserConnections.set(sessionId, conn);
72
+ ws.on("message", (data) => {
73
+ const raw = data.toString();
74
+ sessionManager.touchSession(sessionId);
75
+ if (!conn.rateLimiter.consume()) {
76
+ ws.send(JSON.stringify({ type: "error", message: "Rate limited" }));
77
+ return;
78
+ }
79
+ const validation = validateInbound(raw);
80
+ if (!validation.valid) {
81
+ ws.send(JSON.stringify({ type: "error", message: validation.error }));
82
+ return;
83
+ }
84
+ // Forward to container
85
+ const containerConn = containerConnections.get(sessionId);
86
+ if (containerConn?.authenticated && containerConn.ws.readyState === WebSocket.OPEN) {
87
+ containerConn.ws.send(raw);
88
+ }
89
+ else {
90
+ ws.send(JSON.stringify({ type: "error", message: "Agent container not connected" }));
91
+ }
92
+ });
93
+ ws.on("close", () => {
94
+ logger?.debug({ sessionId }, "browser WebSocket disconnected");
95
+ browserConnections.delete(sessionId);
96
+ // Grace period: wait 60s before shutting down the container
97
+ const gracePeriod = setTimeout(() => {
98
+ browserDisconnectTimers.delete(sessionId);
99
+ logger?.info({ sessionId }, "browser grace period expired, shutting down container");
100
+ shutdownSession(sessionId);
101
+ }, 60_000);
102
+ browserDisconnectTimers.set(sessionId, gracePeriod);
103
+ });
104
+ ws.on("error", (err) => {
105
+ logger?.warn({ sessionId, err: err.message }, "browser WebSocket error");
106
+ });
107
+ }
108
+ function handleContainerConnection(ws, sessionId) {
109
+ logger?.debug({ sessionId }, "container WebSocket connected");
110
+ const conn = { ws, authenticated: false };
111
+ containerConnections.set(sessionId, conn);
112
+ // Container must authenticate with session token in first message within 5s
113
+ const authTimeout = setTimeout(() => {
114
+ if (!conn.authenticated) {
115
+ logger?.warn({ sessionId }, "container auth timeout");
116
+ ws.close(4001, "Auth timeout");
117
+ containerConnections.delete(sessionId);
118
+ }
119
+ }, 5000);
120
+ ws.on("message", (data) => {
121
+ const raw = data.toString();
122
+ // First message must be auth token
123
+ if (!conn.authenticated) {
124
+ try {
125
+ const msg = JSON.parse(raw);
126
+ if (msg.type === "auth" && typeof msg.token === "string") {
127
+ const session = sessionManager.getSession(sessionId);
128
+ if (session && safeCompare(msg.token, sessionId)) {
129
+ conn.authenticated = true;
130
+ clearTimeout(authTimeout);
131
+ ws.send(JSON.stringify({ type: "auth_ok" }));
132
+ logger?.info({ sessionId }, "container authenticated");
133
+ return;
134
+ }
135
+ }
136
+ }
137
+ catch { /* invalid JSON */ }
138
+ ws.close(4003, "Auth failed");
139
+ containerConnections.delete(sessionId);
140
+ clearTimeout(authTimeout);
141
+ return;
142
+ }
143
+ sessionManager.touchSession(sessionId);
144
+ // Validate outbound message from container
145
+ const validation = validateOutbound(raw);
146
+ if (!validation.valid) {
147
+ logger?.warn({ sessionId, error: validation.error }, "invalid outbound from container");
148
+ return;
149
+ }
150
+ // Forward to browser
151
+ const browserConn = browserConnections.get(sessionId);
152
+ if (browserConn && browserConn.ws.readyState === WebSocket.OPEN) {
153
+ browserConn.ws.send(raw);
154
+ }
155
+ });
156
+ ws.on("close", () => {
157
+ logger?.debug({ sessionId }, "container WebSocket disconnected");
158
+ containerConnections.delete(sessionId);
159
+ // Notify browser
160
+ const browserConn = browserConnections.get(sessionId);
161
+ if (browserConn && browserConn.ws.readyState === WebSocket.OPEN) {
162
+ browserConn.ws.send(JSON.stringify({ type: "error", message: "Agent container disconnected" }));
163
+ }
164
+ sessionManager.removeSession(sessionId);
165
+ });
166
+ ws.on("error", (err) => {
167
+ logger?.warn({ sessionId, err: err.message }, "container WebSocket error");
168
+ });
169
+ }
170
+ async function shutdownSession(sessionId) {
171
+ // Send shutdown to container
172
+ const containerConn = containerConnections.get(sessionId);
173
+ if (containerConn?.authenticated && containerConn.ws.readyState === WebSocket.OPEN) {
174
+ containerConn.ws.send(JSON.stringify({ type: "shutdown" }));
175
+ containerConn.ws.close();
176
+ }
177
+ containerConnections.delete(sessionId);
178
+ // Close browser connection
179
+ const browserConn = browserConnections.get(sessionId);
180
+ if (browserConn && browserConn.ws.readyState === WebSocket.OPEN) {
181
+ browserConn.ws.close();
182
+ }
183
+ browserConnections.delete(sessionId);
184
+ // Stop container via callback
185
+ if (state.stopContainer) {
186
+ try {
187
+ await state.stopContainer(sessionId);
188
+ }
189
+ catch (err) {
190
+ logger?.warn({ sessionId, err: err.message }, "failed to stop chat container");
191
+ }
192
+ }
193
+ sessionManager.removeSession(sessionId);
194
+ }
195
+ // Idle session cleanup interval (Phase 8)
196
+ const IDLE_TIMEOUT_MS = 15 * 60 * 1000; // 15 minutes
197
+ const cleanupInterval = setInterval(() => {
198
+ const idle = sessionManager.getIdleSessions(IDLE_TIMEOUT_MS);
199
+ for (const session of idle) {
200
+ logger?.info({ sessionId: session.sessionId, agentName: session.agentName }, "cleaning up idle chat session");
201
+ shutdownSession(session.sessionId);
202
+ }
203
+ }, 60_000);
204
+ cleanupInterval.unref();
205
+ const state = {
206
+ browserConnections,
207
+ containerConnections,
208
+ cleanupInterval,
209
+ };
210
+ return state;
211
+ }
212
+ // --- Auth helpers ---
213
+ async function authenticateBrowser(req, apiKey, sessionStore) {
214
+ // Check Authorization header
215
+ const authHeader = req.headers.authorization;
216
+ if (authHeader?.startsWith("Bearer ")) {
217
+ const token = authHeader.slice(7);
218
+ if (safeCompare(token, apiKey))
219
+ return true;
220
+ }
221
+ // Check al_session cookie
222
+ const cookieHeader = req.headers.cookie || "";
223
+ const sessionToken = parseCookie(cookieHeader)["al_session"];
224
+ if (sessionToken) {
225
+ if (sessionStore) {
226
+ const session = await sessionStore.getSession(sessionToken);
227
+ if (session)
228
+ return true;
229
+ }
230
+ else {
231
+ if (safeCompare(sessionToken, apiKey))
232
+ return true;
233
+ }
234
+ }
235
+ return false;
236
+ }
237
+ function parseCookie(header) {
238
+ const result = {};
239
+ for (const part of header.split(";")) {
240
+ const eq = part.indexOf("=");
241
+ if (eq === -1)
242
+ continue;
243
+ result[part.slice(0, eq).trim()] = part.slice(eq + 1).trim();
244
+ }
245
+ return result;
246
+ }
247
+ //# sourceMappingURL=ws-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-handler.js","sourceRoot":"","sources":["../../src/chat/ws-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * al add — install a skill from a git repository.
3
+ *
4
+ * 1. Fetch repo (shallow clone to temp dir)
5
+ * 2. Discover SKILL.md files (root or skills/star/)
6
+ * 3. If multiple and no --skill, prompt user to pick
7
+ * 4. Copy SKILL.md + config.toml into agents dir
8
+ * 5. Run al config for interactive gap-filling
9
+ */
10
+ export declare function execute(repo: string, opts: {
11
+ skill?: string;
12
+ project: string;
13
+ }): Promise<void>;
14
+ //# sourceMappingURL=add.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/add.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAmFH,wBAAsB,OAAO,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACxC,OAAO,CAAC,IAAI,CAAC,CAiHf"}