@netnodeag/kraftwerk 0.62.0 → 0.63.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 (73) hide show
  1. package/dist/cli/routines.js +2 -3
  2. package/dist/client/index.d.ts +59 -0
  3. package/dist/client/index.js +63 -0
  4. package/dist/client/live.d.ts +34 -0
  5. package/dist/client/live.js +169 -0
  6. package/dist/client/routes.d.ts +125 -0
  7. package/dist/client/routes.js +126 -0
  8. package/dist/inspector/api/agents.d.ts +31 -0
  9. package/dist/inspector/api/agents.js +50 -0
  10. package/dist/inspector/api/attention.d.ts +10 -0
  11. package/dist/inspector/api/attention.js +23 -0
  12. package/dist/inspector/api/channels.d.ts +67 -0
  13. package/dist/inspector/api/channels.js +58 -0
  14. package/dist/inspector/api/chats.d.ts +55 -0
  15. package/dist/inspector/api/chats.js +154 -0
  16. package/dist/inspector/api/files.d.ts +15 -0
  17. package/dist/inspector/api/files.js +43 -0
  18. package/dist/inspector/api/git.d.ts +25 -0
  19. package/dist/inspector/api/git.js +56 -0
  20. package/dist/inspector/api/index.d.ts +334 -0
  21. package/dist/inspector/api/index.js +43 -0
  22. package/dist/inspector/api/knowledge.d.ts +13 -0
  23. package/dist/inspector/api/knowledge.js +56 -0
  24. package/dist/inspector/api/mime.d.ts +2 -0
  25. package/dist/inspector/api/mime.js +18 -0
  26. package/dist/inspector/api/projects.d.ts +11 -0
  27. package/dist/inspector/api/projects.js +32 -0
  28. package/dist/inspector/api/router.d.ts +75 -0
  29. package/dist/inspector/api/router.js +186 -0
  30. package/dist/inspector/api/runs.d.ts +33 -0
  31. package/dist/inspector/api/runs.js +105 -0
  32. package/dist/inspector/api/socket.d.ts +3 -0
  33. package/dist/inspector/api/socket.js +115 -0
  34. package/dist/inspector/api/vibeables.d.ts +4 -0
  35. package/dist/inspector/api/vibeables.js +31 -0
  36. package/dist/inspector/api/workspace.d.ts +55 -0
  37. package/dist/inspector/api/workspace.js +117 -0
  38. package/dist/inspector/chat/sessions.js +31 -19
  39. package/dist/inspector/context.d.ts +5 -7
  40. package/dist/inspector/context.js +6 -20
  41. package/dist/inspector/git.js +52 -43
  42. package/dist/inspector/live.d.ts +42 -0
  43. package/dist/inspector/live.js +91 -0
  44. package/dist/inspector/notifications.js +19 -13
  45. package/dist/inspector/routines.d.ts +1 -1
  46. package/dist/inspector/routines.js +8 -5
  47. package/dist/inspector/runner.js +5 -4
  48. package/dist/inspector/server.d.ts +2 -2
  49. package/dist/inspector/server.js +59 -1393
  50. package/dist/inspector/version.d.ts +9 -0
  51. package/dist/inspector/version.js +27 -0
  52. package/dist/inspector/vibeables.js +25 -23
  53. package/dist/inspector/workspace.d.ts +42 -0
  54. package/dist/inspector/workspace.js +63 -0
  55. package/dist/inspector/ws.d.ts +11 -0
  56. package/dist/inspector/ws.js +143 -0
  57. package/inspector/dist/assets/{dist-COwx246i.js → dist-9RESajfo.js} +1 -1
  58. package/inspector/dist/assets/{dist-OMwGczSn.js → dist-Bm5S1BoZ.js} +1 -1
  59. package/inspector/dist/assets/dist-C8BofvHx.js +1 -0
  60. package/inspector/dist/assets/{dist-jBYydzOe.js → dist-CIs4wnTu.js} +1 -1
  61. package/inspector/dist/assets/{dist-Crdu4xR8.js → dist-CjuETd-_.js} +1 -1
  62. package/inspector/dist/assets/{dist-ClyjyU-C.js → dist-CmVK6rgN.js} +1 -1
  63. package/inspector/dist/assets/{dist-CeGII4MF.js → dist-CryXvMV_.js} +1 -1
  64. package/inspector/dist/assets/{dist-DqU5Wgif.js → dist-D1hk0iC5.js} +1 -1
  65. package/inspector/dist/assets/{dist-BIHxko9t.js → dist-DvW9QE1d.js} +1 -1
  66. package/inspector/dist/assets/{dist-BMBdyFA5.js → dist-VD9jMxBv.js} +1 -1
  67. package/inspector/dist/assets/{dist-BnnTidDP.js → dist-VlAqWD8T.js} +1 -1
  68. package/inspector/dist/assets/{editor-Cmri6xKM.js → editor-DkWqwl89.js} +3 -3
  69. package/inspector/dist/assets/index-DRJS2pGj.js +229 -0
  70. package/inspector/dist/index.html +1 -1
  71. package/package.json +7 -2
  72. package/inspector/dist/assets/dist-wc-PzIzB.js +0 -1
  73. package/inspector/dist/assets/index-C1s81t9X.js +0 -229
@@ -2,32 +2,38 @@ import { promises as fs } from "node:fs";
2
2
  import path from "node:path";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { getOutputDir } from "./context.js";
5
+ import { perWorkspace } from "./workspace.js";
6
+ import { touch } from "./live.js";
5
7
  const MAX_ITEMS = 200;
6
8
  const BODY_MAX = 280;
7
- let cache = null;
8
- let writeChain = Promise.resolve();
9
+ /** The in-memory copy and the write queue, one per workspace. */
10
+ const store = perWorkspace(() => ({ cache: null, writeChain: Promise.resolve() }));
9
11
  const file = () => path.join(getOutputDir(), "notifications.json");
10
12
  async function load() {
11
- if (cache)
12
- return cache;
13
+ const st = store();
14
+ if (st.cache)
15
+ return st.cache;
13
16
  try {
14
17
  const parsed = JSON.parse(await fs.readFile(file(), "utf8"));
15
- cache = Array.isArray(parsed) ? parsed : [];
18
+ st.cache = Array.isArray(parsed) ? parsed : [];
16
19
  }
17
20
  catch {
18
- cache = [];
21
+ st.cache = [];
19
22
  }
20
- return cache;
23
+ return st.cache;
21
24
  }
22
25
  function persist(items) {
23
- cache = items;
24
- writeChain = writeChain
26
+ const st = store();
27
+ const [dir, target] = [getOutputDir(), file()];
28
+ st.cache = items;
29
+ touch();
30
+ st.writeChain = st.writeChain
25
31
  .then(async () => {
26
- await fs.mkdir(getOutputDir(), { recursive: true });
32
+ await fs.mkdir(dir, { recursive: true });
27
33
  // Write-then-rename: a reader (the UI, a test) never sees a half-written file.
28
- const tmp = `${file()}.${process.pid}.tmp`;
34
+ const tmp = `${target}.${process.pid}.tmp`;
29
35
  await fs.writeFile(tmp, JSON.stringify(items, null, 2));
30
- await fs.rename(tmp, file());
36
+ await fs.rename(tmp, target);
31
37
  })
32
38
  .catch(() => { });
33
39
  }
@@ -92,5 +98,5 @@ export async function clearNotifications() {
92
98
  }
93
99
  /** Tests / project switches: forget the in-memory copy so the next read hits disk. */
94
100
  export function resetNotificationsCache() {
95
- cache = null;
101
+ store().cache = null;
96
102
  }
@@ -74,6 +74,6 @@ export declare function routineStatuses(slug: string): Promise<RoutineStatus[]>;
74
74
  export declare function runRoutineNow(slug: string, id: string): Promise<{
75
75
  chatId: string;
76
76
  }>;
77
- /** Start the in-process scheduler; safe to call more than once. */
77
+ /** Start the current workspace's scheduler; safe to call more than once. Ticks run in that workspace. */
78
78
  export declare function startRoutineScheduler(): void;
79
79
  export {};
@@ -2,6 +2,7 @@ import { promises as fs } from "node:fs";
2
2
  import path from "node:path";
3
3
  import { parse, stringify } from "yaml";
4
4
  import { getOutputDir } from "./context.js";
5
+ import { perWorkspace } from "./workspace.js";
5
6
  import { getAgent, listAgents, safeAgentSlug, agentsRoot } from "./agents.js";
6
7
  import { chatAwaitingApproval, createChat, postMessage } from "./chat/sessions.js";
7
8
  import { pushNotification } from "./notifications.js";
@@ -251,7 +252,8 @@ export async function runRoutineNow(slug, id) {
251
252
  }
252
253
  }
253
254
  /* ---------- scheduler ---------- */
254
- let timer = null;
255
+ /** The scheduler's timer, one per workspace. */
256
+ const scheduler = perWorkspace(() => ({ timer: null }));
255
257
  async function tick() {
256
258
  const now = new Date();
257
259
  const p = (n) => String(n).padStart(2, "0");
@@ -295,10 +297,11 @@ async function tick() {
295
297
  if (dirty)
296
298
  await writeState(state);
297
299
  }
298
- /** Start the in-process scheduler; safe to call more than once. */
300
+ /** Start the current workspace's scheduler; safe to call more than once. Ticks run in that workspace. */
299
301
  export function startRoutineScheduler() {
300
- if (timer)
302
+ const s = scheduler();
303
+ if (s.timer)
301
304
  return;
302
- timer = setInterval(() => void tick().catch(() => { }), 20_000);
303
- timer.unref?.();
305
+ s.timer = setInterval(() => void tick().catch(() => { }), 20_000);
306
+ s.timer.unref?.();
304
307
  }
@@ -2,6 +2,7 @@ import { spawn, spawnSync } from "node:child_process";
2
2
  import { mkdirSync, openSync, closeSync, writeFileSync } from "node:fs";
3
3
  import path from "node:path";
4
4
  import { getProjectRoot } from "./context.js";
5
+ import { perWorkspace } from "./workspace.js";
5
6
  import { RUN_ID_RE, getRun, safeRunDir } from "./runs.js";
6
7
  import { pushNotification } from "./notifications.js";
7
8
  import { newRunId } from "../workflow.js";
@@ -29,7 +30,7 @@ export function dockerStatus() {
29
30
  return { available: true, image: image.status === 0 };
30
31
  }
31
32
  /** Launchers this inspector started and that have not exited yet, by run id. */
32
- const live = new Map();
33
+ const launchers = perWorkspace(() => new Map());
33
34
  export function triggerRun(opts) {
34
35
  if (opts.sandbox) {
35
36
  const docker = dockerStatus();
@@ -57,7 +58,7 @@ export function triggerRun(opts) {
57
58
  });
58
59
  child.unref();
59
60
  closeSync(log);
60
- live.set(runId, child);
61
+ launchers().set(runId, child);
61
62
  // Detached, but as long as the inspector lives it still hears the exit:
62
63
  // that is when the run's outcome goes to the bell (read from the trace,
63
64
  // the exit code alone does not say whether a gate blocked). The exit
@@ -65,7 +66,7 @@ export function triggerRun(opts) {
65
66
  // framework wrote a trace (missing env var, npx failure) shows as failed
66
67
  // instead of running until the stale timeout.
67
68
  child.on("exit", (code, signal) => {
68
- live.delete(runId);
69
+ launchers().delete(runId);
69
70
  try {
70
71
  writeFileSync(path.join(runDir, "trigger.json"), JSON.stringify({ exitCode: code ?? 1, signal, finishedAt: new Date().toISOString() }, null, 2) + "\n");
71
72
  }
@@ -93,7 +94,7 @@ export function stopRun(runId) {
93
94
  return false;
94
95
  // A local run this inspector launched: the launcher is detached into its
95
96
  // own process group, so the negative pid ends npx and the framework under it.
96
- const child = live.get(runId);
97
+ const child = launchers().get(runId);
97
98
  if (child?.pid && child.exitCode == null) {
98
99
  try {
99
100
  process.kill(-child.pid, "SIGTERM");
@@ -1,6 +1,6 @@
1
1
  import http from "node:http";
2
- /** Exit code the `kraftwerk ui` supervisor treats as "relaunch me". */
3
- export declare const RESTART_EXIT_CODE = 75;
2
+ import { RESTART_EXIT_CODE } from "./version.js";
3
+ export { RESTART_EXIT_CODE };
4
4
  export interface InspectorOptions {
5
5
  outputDir: string;
6
6
  staticDir: string;