@netnodeag/kraftwerk 0.65.0 → 0.66.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.
- package/README.md +93 -23
- package/dist/acp.js +3 -1
- package/dist/cli/daemon.d.ts +14 -0
- package/dist/cli/daemon.js +60 -0
- package/dist/cli/doctor.js +9 -1
- package/dist/cli/init.js +1 -0
- package/dist/cli/kraftwerk.js +4 -0
- package/dist/cli/ui.d.ts +8 -0
- package/dist/cli/ui.js +35 -8
- package/dist/cli/workspaces.js +5 -3
- package/dist/client/index.d.ts +8 -0
- package/dist/client/index.js +2 -1
- package/dist/client/live.d.ts +1 -2
- package/dist/client/live.js +2 -1
- package/dist/client/routes.d.ts +3 -0
- package/dist/client/routes.js +3 -0
- package/dist/config.d.ts +16 -0
- package/dist/config.js +23 -1
- package/dist/core/chat/pi.js +2 -1
- package/dist/core/chat/sessions.d.ts +1 -1
- package/dist/core/chat/sessions.js +1 -1
- package/dist/core/chat/state.d.ts +2 -0
- package/dist/core/chat/state.js +5 -0
- package/dist/core/daemon.d.ts +27 -0
- package/dist/core/daemon.js +61 -0
- package/dist/core/env.d.ts +16 -0
- package/dist/core/env.js +45 -0
- package/dist/core/git.d.ts +2 -0
- package/dist/core/git.js +20 -4
- package/dist/core/instances.d.ts +32 -12
- package/dist/core/instances.js +136 -64
- package/dist/core/routines.d.ts +6 -0
- package/dist/core/routines.js +11 -0
- package/dist/core/runner.js +7 -3
- package/dist/core/vibeables.d.ts +2 -0
- package/dist/core/vibeables.js +17 -5
- package/dist/core/workspace.d.ts +13 -0
- package/dist/core/workspace.js +25 -0
- package/dist/server/api/hub.d.ts +25 -0
- package/dist/server/api/hub.js +32 -0
- package/dist/server/api/index.d.ts +24 -1
- package/dist/server/api/index.js +2 -0
- package/dist/server/api/socket.d.ts +9 -1
- package/dist/server/api/socket.js +27 -7
- package/dist/server/api/workspace.d.ts +1 -0
- package/dist/server/api/workspace.js +2 -1
- package/dist/server/cloud.d.ts +5 -1
- package/dist/server/cloud.js +86 -54
- package/dist/server/hub-context.d.ts +7 -0
- package/dist/server/hub-context.js +18 -0
- package/dist/server/live.d.ts +2 -0
- package/dist/server/live.js +9 -0
- package/dist/server/preview.js +2 -1
- package/dist/server/server.d.ts +52 -1
- package/dist/server/server.js +249 -52
- package/dist/server/target.d.ts +20 -0
- package/dist/server/target.js +18 -0
- package/package.json +1 -1
- package/schema/kraftwerk.schema.json +5 -0
- package/web/dist/assets/{dist-CAWmDGJC.js → dist-1bNkaWWA.js} +1 -1
- package/web/dist/assets/dist-BU1SOB5S.js +1 -0
- package/web/dist/assets/{dist-BCfXUgtf.js → dist-Bk3f-J5U.js} +1 -1
- package/web/dist/assets/{dist-DnMgiPT1.js → dist-Bx99Puvv.js} +1 -1
- package/web/dist/assets/{dist-v6-49xpW.js → dist-C0M2aITo.js} +1 -1
- package/web/dist/assets/{dist-C-CclD1E.js → dist-C0z19Zge.js} +1 -1
- package/web/dist/assets/{dist-nA7q2-h7.js → dist-COEgBKG6.js} +1 -1
- package/web/dist/assets/{dist-Bnxg6V5L.js → dist-CYRrdlae.js} +1 -1
- package/web/dist/assets/{dist-hevbMnoj.js → dist-CbEFnSCD.js} +1 -1
- package/web/dist/assets/{dist-DS1R2xKJ.js → dist-DCYVKU-H.js} +1 -1
- package/web/dist/assets/{dist-10uPVFvu.js → dist-XyTHWtoN.js} +1 -1
- package/web/dist/assets/{editor-C8yy8YS9.js → editor-DPcGvSPy.js} +3 -3
- package/web/dist/assets/index-DKLJdwYE.js +229 -0
- package/web/dist/index.html +1 -1
- package/web/dist/assets/dist-yoh47aAL.js +0 -1
- package/web/dist/assets/index-DWS1u71Y.js +0 -229
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Attachment, ChatAgentId, ChatMeta, ChatScope, ElicitationAnswer, StoredChatEvent } from "./types.js";
|
|
2
2
|
import { type Channel } from "../channels.js";
|
|
3
3
|
export { agentFilesContext, agentJournalContext, agentVibeablesContext, vibeableContext } from "./context.js";
|
|
4
|
-
export { disposeAllBackends } from "./state.js";
|
|
4
|
+
export { disposeAllBackends, disposeWorkspaceBackends } from "./state.js";
|
|
5
5
|
/**
|
|
6
6
|
* The folder the agent is actually spawned in. A vibeable that was removed
|
|
7
7
|
* leaves meta.cwd pointing nowhere; spawning there fails, so fall back to
|
|
@@ -12,7 +12,7 @@ import { expandSkillInvocation, scopeContext } from "./context.js";
|
|
|
12
12
|
import { ensureBackend } from "./seats.js";
|
|
13
13
|
import { MAIN, chatLabel, chatStates, dropBackend, dropSeat, emit, forgetFailedResume, isBusy, isUnattended, lastEventText, loadState, mainSeat, newSeat, ownerLabel, routineRef } from "./state.js";
|
|
14
14
|
export { agentFilesContext, agentJournalContext, agentVibeablesContext, vibeableContext } from "./context.js";
|
|
15
|
-
export { disposeAllBackends } from "./state.js";
|
|
15
|
+
export { disposeAllBackends, disposeWorkspaceBackends } from "./state.js";
|
|
16
16
|
/**
|
|
17
17
|
* Chats: what the API does with them — create, post, steer, answer, fork,
|
|
18
18
|
* rename, delete, subscribe. The pieces live beside it: the live state and
|
|
@@ -77,5 +77,7 @@ export declare function forgetFailedResume(state: ChatState, seat: Seat): void;
|
|
|
77
77
|
export declare function dropBackend(state: ChatState): void;
|
|
78
78
|
/** Server shutdown: no agent subprocess may outlive the inspector. */
|
|
79
79
|
export declare function disposeAllBackends(): void;
|
|
80
|
+
/** The current workspace's agent processes end (the workspace closes); transcripts stay on disk. */
|
|
81
|
+
export declare function disposeWorkspaceBackends(): void;
|
|
80
82
|
export declare function loadState(id: string): Promise<ChatState | null>;
|
|
81
83
|
export declare function emit(state: ChatState, ev: ChatEvent, from?: Author): StoredChatEvent;
|
package/dist/core/chat/state.js
CHANGED
|
@@ -134,6 +134,11 @@ export function disposeAllBackends() {
|
|
|
134
134
|
for (const [ws, states] of chatStates.entries())
|
|
135
135
|
ws.run(() => states.forEach((state) => dropBackend(state)));
|
|
136
136
|
}
|
|
137
|
+
/** The current workspace's agent processes end (the workspace closes); transcripts stay on disk. */
|
|
138
|
+
export function disposeWorkspaceBackends() {
|
|
139
|
+
for (const state of chatStates().values())
|
|
140
|
+
dropBackend(state);
|
|
141
|
+
}
|
|
137
142
|
export async function loadState(id) {
|
|
138
143
|
const existing = chatStates().get(id);
|
|
139
144
|
if (existing)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The machine's kraftwerk daemon: one process (`kraftwerk daemon`) serving
|
|
3
|
+
* every open workspace, each by its slug (`<slug>.localhost:<port>`,
|
|
4
|
+
* `/w/<slug>/`). It writes ~/.kraftwerk/daemon.json while it runs, so the CLI
|
|
5
|
+
* (`kraftwerk ui`) and other kraftwerks (the switcher's start/stop) hand
|
|
6
|
+
* workspaces to it instead of starting a server of their own. The file
|
|
7
|
+
* outlives the daemon on purpose: it lists what was open, and the next start
|
|
8
|
+
* (a reboot, a self-update) opens it again. Whether a daemon runs is told by
|
|
9
|
+
* asking it (findDaemon), never by the file alone.
|
|
10
|
+
*/
|
|
11
|
+
export declare const DAEMON_PORT = 1980;
|
|
12
|
+
export declare function writeDaemonFile(port: number, open: string[]): Promise<void>;
|
|
13
|
+
/** What the last daemon served, to open again; [] without a file. */
|
|
14
|
+
export declare function lastOpenRoots(): Promise<string[]>;
|
|
15
|
+
/** The running daemon (its file, and a hub that answers on its port), or null. */
|
|
16
|
+
export declare function findDaemon(): Promise<{
|
|
17
|
+
pid: number;
|
|
18
|
+
port: number;
|
|
19
|
+
} | null>;
|
|
20
|
+
/** Ask the daemon to open or close a workspace (this machine's request: local trust). */
|
|
21
|
+
export declare function daemonCall<T>(port: number, verb: "open" | "close", root: string): Promise<{
|
|
22
|
+
ok: boolean;
|
|
23
|
+
status: number;
|
|
24
|
+
data: T & {
|
|
25
|
+
error?: string;
|
|
26
|
+
};
|
|
27
|
+
}>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
/**
|
|
5
|
+
* The machine's kraftwerk daemon: one process (`kraftwerk daemon`) serving
|
|
6
|
+
* every open workspace, each by its slug (`<slug>.localhost:<port>`,
|
|
7
|
+
* `/w/<slug>/`). It writes ~/.kraftwerk/daemon.json while it runs, so the CLI
|
|
8
|
+
* (`kraftwerk ui`) and other kraftwerks (the switcher's start/stop) hand
|
|
9
|
+
* workspaces to it instead of starting a server of their own. The file
|
|
10
|
+
* outlives the daemon on purpose: it lists what was open, and the next start
|
|
11
|
+
* (a reboot, a self-update) opens it again. Whether a daemon runs is told by
|
|
12
|
+
* asking it (findDaemon), never by the file alone.
|
|
13
|
+
*/
|
|
14
|
+
export const DAEMON_PORT = 1980;
|
|
15
|
+
const daemonFile = () => path.join(os.homedir(), ".kraftwerk", "daemon.json");
|
|
16
|
+
const startedAt = new Date().toISOString();
|
|
17
|
+
export async function writeDaemonFile(port, open) {
|
|
18
|
+
await fs.mkdir(path.dirname(daemonFile()), { recursive: true });
|
|
19
|
+
const tmp = `${daemonFile()}.${process.pid}.tmp`;
|
|
20
|
+
await fs.writeFile(tmp, JSON.stringify({ pid: process.pid, port, startedAt, open }));
|
|
21
|
+
await fs.rename(tmp, daemonFile());
|
|
22
|
+
}
|
|
23
|
+
/** What the last daemon served, to open again; [] without a file. */
|
|
24
|
+
export async function lastOpenRoots() {
|
|
25
|
+
try {
|
|
26
|
+
const rec = JSON.parse(await fs.readFile(daemonFile(), "utf8"));
|
|
27
|
+
return Array.isArray(rec.open) ? rec.open.filter((r) => typeof r === "string") : [];
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** The running daemon (its file, and a hub that answers on its port), or null. */
|
|
34
|
+
export async function findDaemon() {
|
|
35
|
+
let rec;
|
|
36
|
+
try {
|
|
37
|
+
rec = JSON.parse(await fs.readFile(daemonFile(), "utf8"));
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
// Every kraftwerk server answers /api/hub; only the daemon says it is one (a standalone `kraftwerk ui` may sit on that port now).
|
|
44
|
+
const r = await fetch(`http://127.0.0.1:${rec.port}/api/hub`, { signal: AbortSignal.timeout(800) });
|
|
45
|
+
const body = r.ok ? (await r.json()) : null;
|
|
46
|
+
return body?.daemon === true ? { pid: rec.pid, port: rec.port } : null;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** Ask the daemon to open or close a workspace (this machine's request: local trust). */
|
|
53
|
+
export async function daemonCall(port, verb, root) {
|
|
54
|
+
const r = await fetch(`http://127.0.0.1:${port}/api/hub/${verb}`, {
|
|
55
|
+
method: "POST",
|
|
56
|
+
headers: { "content-type": "application/json" },
|
|
57
|
+
body: JSON.stringify({ root }),
|
|
58
|
+
signal: AbortSignal.timeout(30_000),
|
|
59
|
+
});
|
|
60
|
+
return { ok: r.ok, status: r.status, data: (await r.json().catch(() => ({}))) };
|
|
61
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The environment a workspace's processes run with: this process's, plus
|
|
3
|
+
* the workspace's own `.env` (dotenv.ts for the precedence — a value set in
|
|
4
|
+
* the shell wins, unless an earlier kraftwerk process injected it from a
|
|
5
|
+
* `.env`). Everything a workspace spawns — agents, workflow runs, app dev
|
|
6
|
+
* servers, git — takes its environment from here, never from process.env
|
|
7
|
+
* directly: one process may serve several workspaces, and one team's
|
|
8
|
+
* `.env` must not reach another's agents.
|
|
9
|
+
*
|
|
10
|
+
* With one workspace per process the CLI has already applied that
|
|
11
|
+
* workspace's `.env` to process.env, so the result is the same as before.
|
|
12
|
+
*/
|
|
13
|
+
/** Read `<root>/.env` (parsed, not applied); {} without one. Read when a workspace is served — a changed file applies on restart, as before. */
|
|
14
|
+
export declare function readWorkspaceDotenv(root: string): Record<string, string>;
|
|
15
|
+
/** The current workspace's environment (outside any workspace: process.env). */
|
|
16
|
+
export declare function workspaceEnv(): NodeJS.ProcessEnv;
|
package/dist/core/env.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { DOTENV_FILE, DOTENV_MARKER, parseDotenv } from "../dotenv.js";
|
|
4
|
+
import { currentWorkspace } from "./workspace.js";
|
|
5
|
+
/**
|
|
6
|
+
* The environment a workspace's processes run with: this process's, plus
|
|
7
|
+
* the workspace's own `.env` (dotenv.ts for the precedence — a value set in
|
|
8
|
+
* the shell wins, unless an earlier kraftwerk process injected it from a
|
|
9
|
+
* `.env`). Everything a workspace spawns — agents, workflow runs, app dev
|
|
10
|
+
* servers, git — takes its environment from here, never from process.env
|
|
11
|
+
* directly: one process may serve several workspaces, and one team's
|
|
12
|
+
* `.env` must not reach another's agents.
|
|
13
|
+
*
|
|
14
|
+
* With one workspace per process the CLI has already applied that
|
|
15
|
+
* workspace's `.env` to process.env, so the result is the same as before.
|
|
16
|
+
*/
|
|
17
|
+
/** Read `<root>/.env` (parsed, not applied); {} without one. Read when a workspace is served — a changed file applies on restart, as before. */
|
|
18
|
+
export function readWorkspaceDotenv(root) {
|
|
19
|
+
try {
|
|
20
|
+
return parseDotenv(readFileSync(path.join(root, DOTENV_FILE), "utf8"));
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** The current workspace's environment (outside any workspace: process.env). */
|
|
27
|
+
export function workspaceEnv() {
|
|
28
|
+
let dotenv;
|
|
29
|
+
try {
|
|
30
|
+
dotenv = currentWorkspace().env;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return { ...process.env };
|
|
34
|
+
}
|
|
35
|
+
const env = { ...process.env };
|
|
36
|
+
const injected = new Set((process.env[DOTENV_MARKER] ?? "").split(",").filter(Boolean));
|
|
37
|
+
// What another workspace's .env put into this process is not this workspace's.
|
|
38
|
+
for (const key of injected)
|
|
39
|
+
if (!(key in dotenv))
|
|
40
|
+
delete env[key];
|
|
41
|
+
for (const [key, value] of Object.entries(dotenv))
|
|
42
|
+
if (!process.env[key] || injected.has(key))
|
|
43
|
+
env[key] = value;
|
|
44
|
+
return env;
|
|
45
|
+
}
|
package/dist/core/git.d.ts
CHANGED
|
@@ -146,3 +146,5 @@ export declare function gitPush(): Promise<{
|
|
|
146
146
|
* out) before the next one starts, or a short interval piles up processes.
|
|
147
147
|
*/
|
|
148
148
|
export declare function startGitSync(): void;
|
|
149
|
+
/** Stop the current workspace's background sync (the workspace closes). A tick in flight finishes, then stops. */
|
|
150
|
+
export declare function stopGitSync(): void;
|
package/dist/core/git.js
CHANGED
|
@@ -4,7 +4,8 @@ import path from "node:path";
|
|
|
4
4
|
import { projectsRootFor, reposRootFor, resolveWorkspace, vibeablesRootFor, isSafeGitName } from "../config.js";
|
|
5
5
|
import { ENV_FILE } from "../runner/docker.js";
|
|
6
6
|
import { getOutputDir, workspaceRoot } from "./context.js";
|
|
7
|
-
import { perWorkspace } from "./workspace.js";
|
|
7
|
+
import { perWorkspace, workspaceOpen } from "./workspace.js";
|
|
8
|
+
import { workspaceEnv } from "./env.js";
|
|
8
9
|
/**
|
|
9
10
|
* Workspace git sync. Several people run kraftwerk against one git repo, so
|
|
10
11
|
* knowledge, agents, skills, channels and workflows travel between them like
|
|
@@ -65,7 +66,7 @@ const MAX_BLOCKED = 200;
|
|
|
65
66
|
* terminal read that never returns, and the inspector hangs with it.
|
|
66
67
|
*/
|
|
67
68
|
const gitEnv = (extra) => ({
|
|
68
|
-
...
|
|
69
|
+
...workspaceEnv(),
|
|
69
70
|
GIT_TERMINAL_PROMPT: "0",
|
|
70
71
|
GIT_ASKPASS: "",
|
|
71
72
|
SSH_ASKPASS: "",
|
|
@@ -341,6 +342,8 @@ const gitState = perWorkspace(() => ({
|
|
|
341
342
|
timer: null,
|
|
342
343
|
ticking: false,
|
|
343
344
|
lastRun: 0,
|
|
345
|
+
/** Set when the workspace closes: a tick in flight does not schedule the next one. */
|
|
346
|
+
stopped: false,
|
|
344
347
|
}));
|
|
345
348
|
/** Invalidate the status cache after anything that changes the repo. */
|
|
346
349
|
const touched = () => {
|
|
@@ -643,10 +646,19 @@ const RECHECK_MS = 60_000;
|
|
|
643
646
|
* out) before the next one starts, or a short interval piles up processes.
|
|
644
647
|
*/
|
|
645
648
|
export function startGitSync() {
|
|
649
|
+
gitState().stopped = false;
|
|
646
650
|
if (gitState().timer || gitState().ticking)
|
|
647
651
|
return;
|
|
648
652
|
schedule(0);
|
|
649
653
|
}
|
|
654
|
+
/** Stop the current workspace's background sync (the workspace closes). A tick in flight finishes, then stops. */
|
|
655
|
+
export function stopGitSync() {
|
|
656
|
+
const s = gitState();
|
|
657
|
+
s.stopped = true;
|
|
658
|
+
if (s.timer)
|
|
659
|
+
clearTimeout(s.timer);
|
|
660
|
+
s.timer = null;
|
|
661
|
+
}
|
|
650
662
|
function schedule(ms) {
|
|
651
663
|
const timer = setTimeout(() => void tick(), ms);
|
|
652
664
|
timer.unref?.();
|
|
@@ -671,8 +683,12 @@ async function tick() {
|
|
|
671
683
|
// A failed tick is retried at the next one; the status carries lastError.
|
|
672
684
|
}
|
|
673
685
|
finally {
|
|
674
|
-
|
|
675
|
-
|
|
686
|
+
// The workspace may have closed while git ran: then its state is gone and nothing is scheduled.
|
|
687
|
+
if (workspaceOpen()) {
|
|
688
|
+
gitState().ticking = false;
|
|
689
|
+
if (!gitState().stopped)
|
|
690
|
+
schedule(next);
|
|
691
|
+
}
|
|
676
692
|
}
|
|
677
693
|
}
|
|
678
694
|
async function sync(repo) {
|
package/dist/core/instances.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export declare const legacyWorkspacesDir: () => string;
|
|
|
6
6
|
/** Durable per-project record. The root is the key; everything else derives from it. */
|
|
7
7
|
export interface WorkspaceRecord {
|
|
8
8
|
root: string;
|
|
9
|
+
/** The workspace's address on this machine (kraftwerk.yml `slug`, else its folder name), as of its last start. */
|
|
10
|
+
slug?: string;
|
|
9
11
|
firstSeen: string;
|
|
10
12
|
lastStarted: string;
|
|
11
13
|
/** Set on clean shutdown; older than lastStarted means the last run died. */
|
|
@@ -29,10 +31,14 @@ export interface DiscoveredInstance {
|
|
|
29
31
|
named?: boolean;
|
|
30
32
|
live: true;
|
|
31
33
|
root?: string;
|
|
32
|
-
/** Server process id (what to signal to stop it). */
|
|
34
|
+
/** Server process id (what to signal to stop it — unless `hub`). */
|
|
33
35
|
pid: number;
|
|
34
36
|
/** The kraftwerk version the instance runs. */
|
|
35
37
|
version?: string;
|
|
38
|
+
/** Its slug, when a daemon serves it. */
|
|
39
|
+
slug?: string;
|
|
40
|
+
/** Served by a daemon next to other workspaces: stopped by closing it there. */
|
|
41
|
+
hub?: boolean;
|
|
36
42
|
}
|
|
37
43
|
/**
|
|
38
44
|
* One workspace as the switcher shows it: a known project (running or
|
|
@@ -60,12 +66,20 @@ export interface WorkspaceEntry {
|
|
|
60
66
|
export declare const workspaceRecordName: (root: string) => string;
|
|
61
67
|
/** ~/… for display. */
|
|
62
68
|
export declare const tildify: (p: string) => string;
|
|
63
|
-
/**
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Write a served workspace's registry file (call once the server listens).
|
|
71
|
+
* A daemon's workspaces carry their slug and address and get a file each;
|
|
72
|
+
* a standalone server keeps the one `<pid>.json` it always had.
|
|
73
|
+
*/
|
|
74
|
+
export declare function registerInstance(port: number, root: string, opts?: {
|
|
75
|
+
url?: string;
|
|
76
|
+
slug?: string;
|
|
77
|
+
hub?: boolean;
|
|
78
|
+
}): Promise<void>;
|
|
79
|
+
/** Where the current workspace answers, as the switcher links it (null before listen). */
|
|
66
80
|
export declare const currentInstanceUrl: () => string | null;
|
|
67
|
-
/** Remove
|
|
68
|
-
export declare function unregisterInstance(): void;
|
|
81
|
+
/** Remove a served workspace's registry file — every one this process wrote when no root is given. Sync so exit handlers can call it. */
|
|
82
|
+
export declare function unregisterInstance(root?: string): void;
|
|
69
83
|
/**
|
|
70
84
|
* All other running instances, verified live. Cached briefly — /api/meta is
|
|
71
85
|
* polled. `fresh` probes now; `readOnly` leaves the records of instances that
|
|
@@ -80,10 +94,14 @@ export declare function registerWorkspace(root: string): Promise<void>;
|
|
|
80
94
|
export declare const syncWorkspaceAgents: (root: string, agents: AgentSummary[]) => Promise<void>;
|
|
81
95
|
export declare const syncWorkspaceChannels: (root: string, channels: ChannelSummary[]) => Promise<void>;
|
|
82
96
|
export declare const syncWorkspaceProjects: (root: string, projects: ProjectHit[]) => Promise<void>;
|
|
83
|
-
/** Stamp lastStopped on clean
|
|
84
|
-
export declare function markWorkspaceStopped(): void;
|
|
97
|
+
/** Stamp lastStopped on a clean stop — every workspace this process serves when no root is given. Sync so exit handlers can call it. */
|
|
98
|
+
export declare function markWorkspaceStopped(root?: string): void;
|
|
85
99
|
/** All known workspaces, most recently started first. */
|
|
86
100
|
export declare function listWorkspaceRecords(): Promise<WorkspaceRecord[]>;
|
|
101
|
+
/** A record's slug: as registered, or (records from before 0.66) its folder name made into one. */
|
|
102
|
+
export declare const recordSlug: (r: WorkspaceRecord) => string;
|
|
103
|
+
/** Other registered workspaces with this slug — two workspaces cannot share an address. */
|
|
104
|
+
export declare function slugClashes(slug: string, root: string): Promise<WorkspaceRecord[]>;
|
|
87
105
|
/** Drop a workspace record (the root itself is untouched) — from the legacy directory too, see migrateRegistry. */
|
|
88
106
|
export declare function forgetWorkspace(root: string): Promise<boolean>;
|
|
89
107
|
/**
|
|
@@ -137,10 +155,12 @@ export interface StartResult {
|
|
|
137
155
|
*/
|
|
138
156
|
export declare function startWorkspace(root: string): Promise<StartResult>;
|
|
139
157
|
/**
|
|
140
|
-
* Stop a running workspace
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
158
|
+
* Stop a running workspace. A daemon's workspace is closed there — the
|
|
159
|
+
* daemon and every other workspace in it keep running. A standalone one
|
|
160
|
+
* gets SIGTERM to its server process, which unregisters, stamps
|
|
161
|
+
* lastStopped and exits; the `kraftwerk ui` supervisor follows. Matched by
|
|
162
|
+
* root, or by url for instances from older versions that registered no
|
|
163
|
+
* root. Waits up to ~5s for it to go quiet.
|
|
144
164
|
*/
|
|
145
165
|
export declare function stopWorkspace(target: {
|
|
146
166
|
root?: string;
|