pi-kot 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 (222) hide show
  1. package/README.md +30 -0
  2. package/bin/pi-kot.mjs +125 -0
  3. package/dist/client/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  4. package/dist/client/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  5. package/dist/client/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  6. package/dist/client/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  7. package/dist/client/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  8. package/dist/client/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  9. package/dist/client/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  10. package/dist/client/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  11. package/dist/client/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  12. package/dist/client/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  13. package/dist/client/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  14. package/dist/client/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  15. package/dist/client/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  16. package/dist/client/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  17. package/dist/client/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  18. package/dist/client/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  19. package/dist/client/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  20. package/dist/client/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  21. package/dist/client/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  22. package/dist/client/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  23. package/dist/client/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  24. package/dist/client/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  25. package/dist/client/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  26. package/dist/client/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  27. package/dist/client/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  28. package/dist/client/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  29. package/dist/client/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  30. package/dist/client/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  31. package/dist/client/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  32. package/dist/client/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  33. package/dist/client/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  34. package/dist/client/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  35. package/dist/client/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  36. package/dist/client/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  37. package/dist/client/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  38. package/dist/client/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  39. package/dist/client/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  40. package/dist/client/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  41. package/dist/client/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  42. package/dist/client/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  43. package/dist/client/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  44. package/dist/client/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  45. package/dist/client/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  46. package/dist/client/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  47. package/dist/client/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  48. package/dist/client/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  49. package/dist/client/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  50. package/dist/client/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  51. package/dist/client/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  52. package/dist/client/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  53. package/dist/client/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  54. package/dist/client/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  55. package/dist/client/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  56. package/dist/client/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  57. package/dist/client/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  58. package/dist/client/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  59. package/dist/client/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  60. package/dist/client/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  61. package/dist/client/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  62. package/dist/client/assets/index-UJgsBs6a.js +361 -0
  63. package/dist/client/assets/index-UJgsBs6a.js.map +1 -0
  64. package/dist/client/assets/index-ZuTc_0YY.css +1 -0
  65. package/dist/client/index.html +14 -0
  66. package/dist/server/ask-user-question/envelope.d.ts +11 -0
  67. package/dist/server/ask-user-question/envelope.d.ts.map +1 -0
  68. package/dist/server/ask-user-question/envelope.js +41 -0
  69. package/dist/server/ask-user-question/envelope.js.map +1 -0
  70. package/dist/server/ask-user-question/prompt-strings.d.ts +4 -0
  71. package/dist/server/ask-user-question/prompt-strings.d.ts.map +1 -0
  72. package/dist/server/ask-user-question/prompt-strings.js +18 -0
  73. package/dist/server/ask-user-question/prompt-strings.js.map +1 -0
  74. package/dist/server/ask-user-question/registry.d.ts +39 -0
  75. package/dist/server/ask-user-question/registry.d.ts.map +1 -0
  76. package/dist/server/ask-user-question/registry.js +124 -0
  77. package/dist/server/ask-user-question/registry.js.map +1 -0
  78. package/dist/server/ask-user-question/tool.d.ts +4 -0
  79. package/dist/server/ask-user-question/tool.d.ts.map +1 -0
  80. package/dist/server/ask-user-question/tool.js +68 -0
  81. package/dist/server/ask-user-question/tool.js.map +1 -0
  82. package/dist/server/ask-user-question/types.d.ts +50 -0
  83. package/dist/server/ask-user-question/types.d.ts.map +1 -0
  84. package/dist/server/ask-user-question/types.js +7 -0
  85. package/dist/server/ask-user-question/types.js.map +1 -0
  86. package/dist/server/ask-user-question/validate.d.ts +3 -0
  87. package/dist/server/ask-user-question/validate.d.ts.map +1 -0
  88. package/dist/server/ask-user-question/validate.js +67 -0
  89. package/dist/server/ask-user-question/validate.js.map +1 -0
  90. package/dist/server/config-manager.d.ts +47 -0
  91. package/dist/server/config-manager.d.ts.map +1 -0
  92. package/dist/server/config-manager.js +182 -0
  93. package/dist/server/config-manager.js.map +1 -0
  94. package/dist/server/config.d.ts +20 -0
  95. package/dist/server/config.d.ts.map +1 -0
  96. package/dist/server/config.js +58 -0
  97. package/dist/server/config.js.map +1 -0
  98. package/dist/server/extension-manager.d.ts +70 -0
  99. package/dist/server/extension-manager.d.ts.map +1 -0
  100. package/dist/server/extension-manager.js +401 -0
  101. package/dist/server/extension-manager.js.map +1 -0
  102. package/dist/server/extension-ui-bridge.d.ts +35 -0
  103. package/dist/server/extension-ui-bridge.d.ts.map +1 -0
  104. package/dist/server/extension-ui-bridge.js +228 -0
  105. package/dist/server/extension-ui-bridge.js.map +1 -0
  106. package/dist/server/file-manager.d.ts +79 -0
  107. package/dist/server/file-manager.d.ts.map +1 -0
  108. package/dist/server/file-manager.js +526 -0
  109. package/dist/server/file-manager.js.map +1 -0
  110. package/dist/server/file-searcher.d.ts +29 -0
  111. package/dist/server/file-searcher.d.ts.map +1 -0
  112. package/dist/server/file-searcher.js +318 -0
  113. package/dist/server/file-searcher.js.map +1 -0
  114. package/dist/server/git-clone.d.ts +56 -0
  115. package/dist/server/git-clone.d.ts.map +1 -0
  116. package/dist/server/git-clone.js +173 -0
  117. package/dist/server/git-clone.js.map +1 -0
  118. package/dist/server/index.d.ts +22 -0
  119. package/dist/server/index.d.ts.map +1 -0
  120. package/dist/server/index.js +196 -0
  121. package/dist/server/index.js.map +1 -0
  122. package/dist/server/lifecycle-notifications.d.ts +28 -0
  123. package/dist/server/lifecycle-notifications.d.ts.map +1 -0
  124. package/dist/server/lifecycle-notifications.js +38 -0
  125. package/dist/server/lifecycle-notifications.js.map +1 -0
  126. package/dist/server/orchestration/config.d.ts +5 -0
  127. package/dist/server/orchestration/config.d.ts.map +1 -0
  128. package/dist/server/orchestration/config.js +35 -0
  129. package/dist/server/orchestration/config.js.map +1 -0
  130. package/dist/server/orchestration/event-bridge.d.ts +32 -0
  131. package/dist/server/orchestration/event-bridge.d.ts.map +1 -0
  132. package/dist/server/orchestration/event-bridge.js +110 -0
  133. package/dist/server/orchestration/event-bridge.js.map +1 -0
  134. package/dist/server/orchestration/inbox.d.ts +9 -0
  135. package/dist/server/orchestration/inbox.d.ts.map +1 -0
  136. package/dist/server/orchestration/inbox.js +186 -0
  137. package/dist/server/orchestration/inbox.js.map +1 -0
  138. package/dist/server/orchestration/init.d.ts +2 -0
  139. package/dist/server/orchestration/init.d.ts.map +1 -0
  140. package/dist/server/orchestration/init.js +22 -0
  141. package/dist/server/orchestration/init.js.map +1 -0
  142. package/dist/server/orchestration/store.d.ts +33 -0
  143. package/dist/server/orchestration/store.d.ts.map +1 -0
  144. package/dist/server/orchestration/store.js +331 -0
  145. package/dist/server/orchestration/store.js.map +1 -0
  146. package/dist/server/orchestration/tools.d.ts +15 -0
  147. package/dist/server/orchestration/tools.d.ts.map +1 -0
  148. package/dist/server/orchestration/tools.js +621 -0
  149. package/dist/server/orchestration/tools.js.map +1 -0
  150. package/dist/server/orchestration/types.d.ts +68 -0
  151. package/dist/server/orchestration/types.d.ts.map +1 -0
  152. package/dist/server/orchestration/types.js +43 -0
  153. package/dist/server/orchestration/types.js.map +1 -0
  154. package/dist/server/orchestration/worker-lifecycle.d.ts +15 -0
  155. package/dist/server/orchestration/worker-lifecycle.d.ts.map +1 -0
  156. package/dist/server/orchestration/worker-lifecycle.js +45 -0
  157. package/dist/server/orchestration/worker-lifecycle.js.map +1 -0
  158. package/dist/server/project-manager.d.ts +25 -0
  159. package/dist/server/project-manager.d.ts.map +1 -0
  160. package/dist/server/project-manager.js +157 -0
  161. package/dist/server/project-manager.js.map +1 -0
  162. package/dist/server/routes/_schemas.d.ts +16 -0
  163. package/dist/server/routes/_schemas.d.ts.map +1 -0
  164. package/dist/server/routes/_schemas.js +12 -0
  165. package/dist/server/routes/_schemas.js.map +1 -0
  166. package/dist/server/routes/ask-user-question.d.ts +3 -0
  167. package/dist/server/routes/ask-user-question.d.ts.map +1 -0
  168. package/dist/server/routes/ask-user-question.js +105 -0
  169. package/dist/server/routes/ask-user-question.js.map +1 -0
  170. package/dist/server/routes/auth.d.ts +7 -0
  171. package/dist/server/routes/auth.d.ts.map +1 -0
  172. package/dist/server/routes/auth.js +126 -0
  173. package/dist/server/routes/auth.js.map +1 -0
  174. package/dist/server/routes/config.d.ts +3 -0
  175. package/dist/server/routes/config.d.ts.map +1 -0
  176. package/dist/server/routes/config.js +203 -0
  177. package/dist/server/routes/config.js.map +1 -0
  178. package/dist/server/routes/control.d.ts +3 -0
  179. package/dist/server/routes/control.d.ts.map +1 -0
  180. package/dist/server/routes/control.js +180 -0
  181. package/dist/server/routes/control.js.map +1 -0
  182. package/dist/server/routes/extension-commands.d.ts +22 -0
  183. package/dist/server/routes/extension-commands.d.ts.map +1 -0
  184. package/dist/server/routes/extension-commands.js +178 -0
  185. package/dist/server/routes/extension-commands.js.map +1 -0
  186. package/dist/server/routes/extensions.d.ts +8 -0
  187. package/dist/server/routes/extensions.d.ts.map +1 -0
  188. package/dist/server/routes/extensions.js +169 -0
  189. package/dist/server/routes/extensions.js.map +1 -0
  190. package/dist/server/routes/files.d.ts +3 -0
  191. package/dist/server/routes/files.d.ts.map +1 -0
  192. package/dist/server/routes/files.js +549 -0
  193. package/dist/server/routes/files.js.map +1 -0
  194. package/dist/server/routes/orchestration.d.ts +3 -0
  195. package/dist/server/routes/orchestration.d.ts.map +1 -0
  196. package/dist/server/routes/orchestration.js +251 -0
  197. package/dist/server/routes/orchestration.js.map +1 -0
  198. package/dist/server/routes/projects.d.ts +3 -0
  199. package/dist/server/routes/projects.d.ts.map +1 -0
  200. package/dist/server/routes/projects.js +412 -0
  201. package/dist/server/routes/projects.js.map +1 -0
  202. package/dist/server/routes/prompt.d.ts +3 -0
  203. package/dist/server/routes/prompt.d.ts.map +1 -0
  204. package/dist/server/routes/prompt.js +192 -0
  205. package/dist/server/routes/prompt.js.map +1 -0
  206. package/dist/server/routes/sessions.d.ts +3 -0
  207. package/dist/server/routes/sessions.d.ts.map +1 -0
  208. package/dist/server/routes/sessions.js +581 -0
  209. package/dist/server/routes/sessions.js.map +1 -0
  210. package/dist/server/routes/stream.d.ts +3 -0
  211. package/dist/server/routes/stream.d.ts.map +1 -0
  212. package/dist/server/routes/stream.js +109 -0
  213. package/dist/server/routes/stream.js.map +1 -0
  214. package/dist/server/session-registry.d.ts +151 -0
  215. package/dist/server/session-registry.d.ts.map +1 -0
  216. package/dist/server/session-registry.js +655 -0
  217. package/dist/server/session-registry.js.map +1 -0
  218. package/dist/server/sse-bridge.d.ts +31 -0
  219. package/dist/server/sse-bridge.d.ts.map +1 -0
  220. package/dist/server/sse-bridge.js +126 -0
  221. package/dist/server/sse-bridge.js.map +1 -0
  222. package/package.json +69 -0
@@ -0,0 +1,196 @@
1
+ import Fastify from "fastify";
2
+ import cors from "@fastify/cors";
3
+ import swagger from "@fastify/swagger";
4
+ import swaggerUi from "@fastify/swagger-ui";
5
+ import fastifyStatic from "@fastify/static";
6
+ import { existsSync } from "node:fs";
7
+ import { config } from "./config.js";
8
+ import { authEnabled, extractBearer, verifyHmac } from "./routes/auth.js";
9
+ import { healthRoutes, authRoutes } from "./routes/auth.js";
10
+ import { askUserQuestionRoutes } from "./routes/ask-user-question.js";
11
+ import { sessionRoutes } from "./routes/sessions.js";
12
+ import { promptRoutes } from "./routes/prompt.js";
13
+ import { streamRoutes } from "./routes/stream.js";
14
+ import { configRoutes } from "./routes/config.js";
15
+ import { controlRoutes } from "./routes/control.js";
16
+ import { projectRoutes } from "./routes/projects.js";
17
+ import { fileRoutes } from "./routes/files.js";
18
+ import { disposeAllSessions, getSession } from "./session-registry.js";
19
+ import { subscribe as subscribeAskUserQuestion } from "./ask-user-question/registry.js";
20
+ import { initOrchestrationAskUserQuestionBridge } from "./orchestration/init.js";
21
+ import { orchestrationRoutes } from "./routes/orchestration.js";
22
+ import { extensionRoutes } from "./routes/extensions.js";
23
+ import { extensionCommandRoutes } from "./routes/extension-commands.js";
24
+ /**
25
+ * Build the Fastify server with all routes registered.
26
+ * Architecture adapted from pi-forge:
27
+ * - Fastify HTTP server with CORS
28
+ * - Auth gate via onRequest hook (public routes opt out)
29
+ * - All routes under /api/v1/
30
+ * - Clean teardown on close
31
+ */
32
+ export async function buildServer() {
33
+ const fastify = Fastify({
34
+ logger: {
35
+ level: config.logLevel,
36
+ serializers: {
37
+ req(req) {
38
+ return {
39
+ method: req.method,
40
+ url: req.url,
41
+ hostname: req.hostname,
42
+ remoteAddress: req.ip,
43
+ };
44
+ },
45
+ },
46
+ },
47
+ disableRequestLogging: config.isTest,
48
+ trustProxy: config.trustProxy,
49
+ });
50
+ // CORS — default to true (reflect request origin) for dev convenience
51
+ await fastify.register(cors, {
52
+ origin: config.corsOrigin,
53
+ credentials: false,
54
+ });
55
+ // OpenAPI / Swagger
56
+ await fastify.register(swagger, {
57
+ openapi: {
58
+ info: { title: "pi-kot API", version: "0.1.0" },
59
+ components: {
60
+ securitySchemes: {
61
+ bearerAuth: { type: "http", scheme: "bearer" },
62
+ },
63
+ },
64
+ security: [{ bearerAuth: [] }],
65
+ },
66
+ });
67
+ await fastify.register(swaggerUi, {
68
+ routePrefix: "/api/docs",
69
+ uiConfig: { docExpansion: "list", persistAuthorization: true },
70
+ });
71
+ // Auth gate — applies to all /api/v1/* routes not marked public
72
+ fastify.addHook("onRequest", async (req, reply) => {
73
+ const path = req.url.split("?")[0] ?? req.url;
74
+ // /api/docs is open when auth is disabled (dev default)
75
+ if (path === "/api/docs" || path.startsWith("/api/docs/")) {
76
+ return;
77
+ }
78
+ if (!path.startsWith("/api/v1/"))
79
+ return;
80
+ const routeConfig = req.routeOptions?.config;
81
+ if (routeConfig?.public === true)
82
+ return;
83
+ if (!authEnabled())
84
+ return;
85
+ const presented = extractBearer(req.headers.authorization);
86
+ if (presented === undefined) {
87
+ return reply.code(401).send({ error: "missing_token" });
88
+ }
89
+ const payload = verifyHmac(presented);
90
+ if (payload !== undefined)
91
+ return;
92
+ // Fallback: check API key
93
+ if (config.apiKey !== undefined && presented === config.apiKey)
94
+ return;
95
+ return reply.code(401).send({ error: "invalid_token" });
96
+ });
97
+ // Register all API routes under /api/v1
98
+ await fastify.register(async (api) => {
99
+ await api.register(healthRoutes);
100
+ await api.register(authRoutes);
101
+ await api.register(sessionRoutes);
102
+ await api.register(askUserQuestionRoutes);
103
+ await api.register(promptRoutes);
104
+ await api.register(streamRoutes);
105
+ await api.register(configRoutes);
106
+ await api.register(controlRoutes);
107
+ await api.register(fileRoutes);
108
+ await api.register(projectRoutes);
109
+ await api.register(extensionRoutes);
110
+ await api.register(extensionCommandRoutes);
111
+ await api.register(orchestrationRoutes);
112
+ }, { prefix: "/api/v1" });
113
+ // Wire ask_user_question registry events into SSE fanout
114
+ subscribeAskUserQuestion((event) => {
115
+ const live = getSession(event.sessionId);
116
+ if (live === undefined)
117
+ return;
118
+ for (const client of live.clients) {
119
+ try {
120
+ client.send(event);
121
+ }
122
+ catch {
123
+ live.clients.delete(client);
124
+ }
125
+ }
126
+ });
127
+ // Wire orchestration ask-user-question bridge
128
+ initOrchestrationAskUserQuestionBridge();
129
+ // ---- static client (production) ----
130
+ // After `npm run build`, Fastify serves the Vite build directly.
131
+ // In dev mode, Vite owns :5173 and proxies to us.
132
+ if (config.serveClient && existsSync(config.clientDistPath)) {
133
+ await fastify.register(fastifyStatic, {
134
+ root: config.clientDistPath,
135
+ wildcard: false,
136
+ });
137
+ // SPA fallback: non-/api/* GETs → index.html
138
+ fastify.setNotFoundHandler((req, reply) => {
139
+ if (req.url.startsWith("/api/")) {
140
+ return reply.status(404).send({ error: "not_found" });
141
+ }
142
+ return reply.sendFile("index.html");
143
+ });
144
+ }
145
+ // Clean teardown on close
146
+ fastify.addHook("onClose", async () => {
147
+ await disposeAllSessions();
148
+ });
149
+ return fastify;
150
+ }
151
+ export async function start() {
152
+ const fastify = await buildServer();
153
+ // Auto-create default project if none exist
154
+ try {
155
+ const { mkdir } = await import("node:fs/promises");
156
+ await mkdir(config.workspacePath, { recursive: true });
157
+ const { listProjects, createProject } = await import("./project-manager.js");
158
+ const projects = await listProjects();
159
+ if (projects.length === 0) {
160
+ const project = await createProject("Default", config.workspacePath);
161
+ fastify.log.info("auto-created default project");
162
+ // Migrate old sessions from "default" literal dir to project UUID
163
+ const { rename, stat } = await import("node:fs/promises");
164
+ const { join } = await import("node:path");
165
+ const oldDir = join(config.sessionDir, "default");
166
+ const newDir = join(config.sessionDir, project.id);
167
+ try {
168
+ await stat(oldDir);
169
+ if (oldDir !== newDir) {
170
+ await rename(oldDir, newDir).catch(() => { });
171
+ fastify.log.info("migrated sessions from default/ to project UUID");
172
+ }
173
+ }
174
+ catch {
175
+ // oldDir doesn't exist, nothing to migrate
176
+ }
177
+ }
178
+ }
179
+ catch (err) {
180
+ fastify.log.warn({ err }, "failed to auto-create default project");
181
+ }
182
+ try {
183
+ await fastify.listen({ port: config.port, host: config.host });
184
+ fastify.log.info(`pi-kot server listening on :${config.port}`);
185
+ }
186
+ catch (err) {
187
+ fastify.log.error(err);
188
+ process.exit(1);
189
+ }
190
+ }
191
+ // Start when run directly
192
+ const isMainModule = process.argv[1] !== undefined;
193
+ if (isMainModule) {
194
+ void start();
195
+ }
196
+ //# 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,28 @@
1
+ import type { AgentSession } from "@earendil-works/pi-coding-agent";
2
+ export interface CustomLifecycleMessage {
3
+ customType: string;
4
+ content: string;
5
+ display: boolean;
6
+ details?: unknown;
7
+ }
8
+ interface LifecycleSession {
9
+ isStreaming: boolean;
10
+ messages: readonly unknown[];
11
+ sendCustomMessage: AgentSession["sendCustomMessage"];
12
+ }
13
+ /**
14
+ * Send a custom lifecycle/status card with explicit active-run behavior.
15
+ *
16
+ * While streaming, lifecycle cards use `steer`. When idle, `triggerTurn`
17
+ * controls whether the card starts a new model turn.
18
+ */
19
+ export declare function sendCustomLifecycleMessage(session: LifecycleSession, message: CustomLifecycleMessage, options: {
20
+ triggerTurn: boolean;
21
+ dedupe?: {
22
+ detailKey: string;
23
+ detailValue: string;
24
+ };
25
+ onError?: (err: unknown) => void;
26
+ }): void;
27
+ export {};
28
+ //# sourceMappingURL=lifecycle-notifications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle-notifications.d.ts","sourceRoot":"","sources":["../src/lifecycle-notifications.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAEpE,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,gBAAgB;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IAC7B,iBAAiB,EAAE,YAAY,CAAC,mBAAmB,CAAC,CAAC;CACtD;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE;IACP,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CAClC,GACA,IAAI,CA6BN"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Send a custom lifecycle/status card with explicit active-run behavior.
3
+ *
4
+ * While streaming, lifecycle cards use `steer`. When idle, `triggerTurn`
5
+ * controls whether the card starts a new model turn.
6
+ */
7
+ export function sendCustomLifecycleMessage(session, message, options) {
8
+ if (options.dedupe !== undefined &&
9
+ hasExistingNotification(session.messages, message.customType, options.dedupe)) {
10
+ return;
11
+ }
12
+ const send = (sendOptions) => {
13
+ void session.sendCustomMessage(message, sendOptions).catch((err) => {
14
+ options.onError?.(err);
15
+ });
16
+ };
17
+ if (session.isStreaming) {
18
+ send({ deliverAs: "steer", triggerTurn: options.triggerTurn });
19
+ return;
20
+ }
21
+ if (options.dedupe !== undefined &&
22
+ hasExistingNotification(session.messages, message.customType, options.dedupe)) {
23
+ return;
24
+ }
25
+ send({ triggerTurn: options.triggerTurn });
26
+ }
27
+ function hasExistingNotification(messages, customType, dedupe) {
28
+ return messages.some((message) => {
29
+ const m = message;
30
+ if (m.role !== "custom" || m.customType !== customType)
31
+ return false;
32
+ if (typeof m.details !== "object" || m.details === null)
33
+ return false;
34
+ const details = m.details;
35
+ return details[dedupe.detailKey] === dedupe.detailValue;
36
+ });
37
+ }
38
+ //# sourceMappingURL=lifecycle-notifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle-notifications.js","sourceRoot":"","sources":["../src/lifecycle-notifications.ts"],"names":[],"mappings":"AAeA;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAAyB,EACzB,OAA+B,EAC/B,OAIC;IAED,IACE,OAAO,CAAC,MAAM,KAAK,SAAS;QAC5B,uBAAuB,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,EAC7E,CAAC;QACD,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,WAGb,EAAQ,EAAE;QACT,KAAK,OAAO,CAAC,iBAAiB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;YAC1E,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IAED,IACE,OAAO,CAAC,MAAM,KAAK,SAAS;QAC5B,uBAAuB,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,EAC7E,CAAC;QACD,OAAO;IACT,CAAC;IACD,IAAI,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,uBAAuB,CAC9B,QAA4B,EAC5B,UAAkB,EAClB,MAAkD;IAElD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;QAC/B,MAAM,CAAC,GAAG,OAAsE,CAAC;QACjF,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,UAAU,KAAK,UAAU;YAAE,OAAO,KAAK,CAAC;QACrE,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QACtE,MAAM,OAAO,GAAG,CAAC,CAAC,OAAkC,CAAC;QACrD,OAAO,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,MAAM,CAAC,WAAW,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function isOrchestrationEnabled(): boolean;
2
+ export declare function maxWorkersPerSupervisor(): number;
3
+ export declare function isOrchestrationAvailable(): boolean;
4
+ export declare function availableReason(): string;
5
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/orchestration/config.ts"],"names":[],"mappings":"AASA,wBAAgB,sBAAsB,IAAI,OAAO,CAGhD;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAED,wBAAgB,wBAAwB,IAAI,OAAO,CAElD;AAGD,wBAAgB,eAAe,IAAI,MAAM,CAUxC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Runtime config for the orchestration feature.
3
+ *
4
+ * Enabled by default with an instance-level disable switch + tunable
5
+ * limits. MINIMAL_UI is a HARD gate (checked separately in routes +
6
+ * tool registration).
7
+ */
8
+ import { config } from "../config.js";
9
+ export function isOrchestrationEnabled() {
10
+ if (config.minimalUi)
11
+ return false;
12
+ return config.orchestrationEnabled;
13
+ }
14
+ export function maxWorkersPerSupervisor() {
15
+ return Math.max(1, Math.min(config.orchestrationMaxWorkersPerSupervisor, 100));
16
+ }
17
+ export function isOrchestrationAvailable() {
18
+ return config.orchestrationEnabled && !config.minimalUi;
19
+ }
20
+ let _disabledReason;
21
+ export function availableReason() {
22
+ if (_disabledReason !== undefined)
23
+ return _disabledReason;
24
+ if (config.minimalUi) {
25
+ _disabledReason = "Orchestration is disabled under MINIMAL_UI mode.";
26
+ }
27
+ else if (!config.orchestrationEnabled) {
28
+ _disabledReason = "Orchestration is disabled by operator config.";
29
+ }
30
+ else {
31
+ _disabledReason = "available";
32
+ }
33
+ return _disabledReason;
34
+ }
35
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/orchestration/config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,MAAM,UAAU,sBAAsB;IACpC,IAAI,MAAM,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,MAAM,CAAC,oBAAoB,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,OAAO,MAAM,CAAC,oBAAoB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;AAC1D,CAAC;AAED,IAAI,eAAmC,CAAC;AACxC,MAAM,UAAU,eAAe;IAC7B,IAAI,eAAe,KAAK,SAAS;QAAE,OAAO,eAAe,CAAC;IAC1D,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,eAAe,GAAG,kDAAkD,CAAC;IACvE,CAAC;SAAM,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC;QACxC,eAAe,GAAG,+CAA+C,CAAC;IACpE,CAAC;SAAM,CAAC;QACN,eAAe,GAAG,WAAW,CAAC;IAChC,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Bridges forge-side worker events into supervisor notifications/history.
3
+ *
4
+ * Four event sources feed worker lifecycle updates:
5
+ * AgentSession events (per-session subscribe in session-registry):
6
+ * - `agent_start` → record open turn state only
7
+ * - `agent_end` → `worker.ended` (with final error info)
8
+ * ask-user-question registry:
9
+ * - `ask_user_question` → `worker.ask_user` + awaiting_question state
10
+ * processManager:
11
+ * - `process_alert` → intentionally NOT bridged (too noisy)
12
+ * session-registry lifecycle (sessions DELETE route):
13
+ * - hot delete → `worker.deleted`
14
+ */
15
+ import type { AgentSession, AgentSessionEvent } from "@earendil-works/pi-coding-agent";
16
+ export declare function bridgeWorkerAgentEvent(meta: {
17
+ sessionId: string;
18
+ session: AgentSession;
19
+ }, event: AgentSessionEvent): Promise<void>;
20
+ export declare function bridgeWorkerAskUserQuestion(sessionId: string, questions: readonly {
21
+ header?: string;
22
+ question?: string;
23
+ }[], requestId: string): Promise<void>;
24
+ export declare function bridgeWorkerExecutionStopped(sessionId: string, meta: {
25
+ wasLive: boolean;
26
+ reason: "deleted" | "killed" | "disposed" | "aborted";
27
+ }): Promise<void>;
28
+ export declare function bridgeWorkerDeleted(sessionId: string, meta: {
29
+ wasLive: boolean;
30
+ reason?: "deleted" | "killed" | "disposed" | "aborted";
31
+ }): Promise<void>;
32
+ //# sourceMappingURL=event-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-bridge.d.ts","sourceRoot":"","sources":["../../src/orchestration/event-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAoCvF,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,EAClD,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,IAAI,CAAC,CAmCf;AAED,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,EAC5D,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,wBAAsB,4BAA4B,CAChD,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAA;CAAE,GAChF,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAA;CAAE,GACjF,OAAO,CAAC,IAAI,CAAC,CAYf"}
@@ -0,0 +1,110 @@
1
+ import { bridgeWorkerEvent } from "./inbox.js";
2
+ import { getWorkerRecord, updateWorkerLifecycle } from "./store.js";
3
+ function findLastAssistant(messages) {
4
+ for (let i = messages.length - 1; i >= 0; i--) {
5
+ const m = messages[i];
6
+ if (m?.role !== "assistant")
7
+ continue;
8
+ const a = m;
9
+ const text = extractAssistantText(a.content);
10
+ const out = {};
11
+ if (a.stopReason !== undefined)
12
+ out.stopReason = a.stopReason;
13
+ if (a.errorMessage !== undefined)
14
+ out.errorMessage = a.errorMessage;
15
+ if (text !== undefined)
16
+ out.text = text;
17
+ return out;
18
+ }
19
+ return undefined;
20
+ }
21
+ function extractAssistantText(content) {
22
+ if (!Array.isArray(content))
23
+ return undefined;
24
+ const parts = [];
25
+ for (const c of content) {
26
+ const o = c;
27
+ if (o.type === "text" && typeof o.text === "string")
28
+ parts.push(o.text);
29
+ }
30
+ if (parts.length === 0)
31
+ return undefined;
32
+ return parts.join("\n");
33
+ }
34
+ export async function bridgeWorkerAgentEvent(meta, event) {
35
+ const e = event;
36
+ const now = new Date().toISOString();
37
+ if (e.type === "agent_start") {
38
+ await updateWorkerLifecycle(meta.sessionId, {
39
+ state: "running",
40
+ turnOpen: true,
41
+ lastStateAt: now,
42
+ lastAgentStartAt: now,
43
+ stopReason: null,
44
+ errorMessage: null,
45
+ });
46
+ return;
47
+ }
48
+ if (e.type !== "agent_end")
49
+ return;
50
+ const messages = meta.session.messages;
51
+ const lastAssistant = findLastAssistant(messages);
52
+ const errorMessage = meta.session.errorMessage ??
53
+ lastAssistant?.errorMessage;
54
+ const hasError = typeof errorMessage === "string" && errorMessage.length > 0;
55
+ await updateWorkerLifecycle(meta.sessionId, {
56
+ state: hasError ? "errored" : "ended",
57
+ turnOpen: false,
58
+ lastStateAt: now,
59
+ lastAgentEndAt: now,
60
+ stopReason: lastAssistant?.stopReason ?? null,
61
+ errorMessage: errorMessage ?? null,
62
+ });
63
+ await bridgeWorkerEvent(meta.sessionId, "worker.ended", {
64
+ stopReason: lastAssistant?.stopReason ?? null,
65
+ errorMessage: errorMessage ?? null,
66
+ assistantText: lastAssistant?.text ?? null,
67
+ });
68
+ }
69
+ export async function bridgeWorkerAskUserQuestion(sessionId, questions, requestId) {
70
+ await updateWorkerLifecycle(sessionId, {
71
+ state: "awaiting_question",
72
+ lastStateAt: new Date().toISOString(),
73
+ });
74
+ await bridgeWorkerEvent(sessionId, "worker.ask_user", {
75
+ requestId,
76
+ questionCount: questions.length,
77
+ firstQuestionHeader: questions[0]?.header ?? null,
78
+ firstQuestionText: questions[0]?.question ?? null,
79
+ });
80
+ }
81
+ export async function bridgeWorkerExecutionStopped(sessionId, meta) {
82
+ const rec = await getWorkerRecord(sessionId);
83
+ if (rec?.turnOpen !== true)
84
+ return;
85
+ await updateWorkerLifecycle(sessionId, {
86
+ state: "stopped",
87
+ turnOpen: false,
88
+ lastStateAt: new Date().toISOString(),
89
+ stopReason: meta.reason,
90
+ });
91
+ await bridgeWorkerEvent(sessionId, "worker.execution_stopped_without_agent_end", {
92
+ reason: meta.reason,
93
+ wasLive: meta.wasLive,
94
+ lastAgentStartAt: rec.lastAgentStartAt ?? null,
95
+ });
96
+ }
97
+ export async function bridgeWorkerDeleted(sessionId, meta) {
98
+ const reason = meta.reason ?? "deleted";
99
+ await bridgeWorkerExecutionStopped(sessionId, { wasLive: meta.wasLive, reason });
100
+ await updateWorkerLifecycle(sessionId, {
101
+ state: "deleted",
102
+ turnOpen: false,
103
+ lastStateAt: new Date().toISOString(),
104
+ stopReason: reason,
105
+ });
106
+ await bridgeWorkerEvent(sessionId, "worker.deleted", {
107
+ wasLive: meta.wasLive,
108
+ });
109
+ }
110
+ //# sourceMappingURL=event-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-bridge.js","sourceRoot":"","sources":["../../src/orchestration/event-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { InboxEventType, InboxItem } from "./types.js";
2
+ export declare const ORCHESTRATION_WAKE_PREFIX = "[orchestration]";
3
+ export declare const ORCHESTRATION_NOTIFY_TYPE = "orchestration-notify";
4
+ export declare function shouldTriggerWorkerTurn(type: InboxEventType): boolean;
5
+ export declare function bridgeWorkerEvent(workerId: string, type: InboxEventType, data: Record<string, unknown>): Promise<InboxItem | undefined>;
6
+ export declare function notifySupervisorIdle(supervisorId: string): Promise<void>;
7
+ export declare function notifySupervisorDisposed(supervisorId: string): void;
8
+ export declare function drainInbox(supervisorId: string): Promise<InboxItem[]>;
9
+ //# sourceMappingURL=inbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../src/orchestration/inbox.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAgB5D,eAAO,MAAM,yBAAyB,oBAAoB,CAAC;AAC3D,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAEhE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAErE;AAyID,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAmBhC;AAED,wBAAsB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9E;AAED,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAEnE;AAED,wBAAsB,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAE3E"}