@netnodeag/kraftwerk 0.32.1 → 0.33.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/dist/cli/doctor.js +2 -3
- package/dist/cli/kraftwerk.js +3 -0
- package/dist/cli/projects.d.ts +2 -0
- package/dist/cli/projects.js +126 -0
- package/dist/cli/ui.js +28 -11
- package/dist/config.d.ts +2 -0
- package/dist/config.js +2 -1
- package/dist/inspector/instances.d.ts +64 -1
- package/dist/inspector/instances.js +257 -15
- package/dist/inspector/self-command.d.ts +15 -0
- package/dist/inspector/self-command.js +18 -0
- package/dist/inspector/server.js +43 -7
- package/inspector/dist/assets/{editor-DhNlc5vd.js → editor-BlAeAqt0.js} +3 -3
- package/inspector/dist/assets/{index-CT73nPrH.js → index--9LQl_DL.js} +1 -1
- package/inspector/dist/assets/{index-xM_-dBjg.js → index--wwp-KD0.js} +1 -1
- package/inspector/dist/assets/{index-CWIXOY1D.js → index-9rElziKS.js} +1 -1
- package/inspector/dist/assets/{index-C22iDz8w.js → index-AR7uGZPa.js} +1 -1
- package/inspector/dist/assets/{index--vNjDAEm.js → index-B0qGMqfM.js} +1 -1
- package/inspector/dist/assets/index-B7W4QbA2.css +1 -0
- package/inspector/dist/assets/{index-DYnto4lP.js → index-BKnMNAOc.js} +1 -1
- package/inspector/dist/assets/{index-DmZE5psD.js → index-BvCAG0mQ.js} +1 -1
- package/inspector/dist/assets/{index-Hlokid_B.js → index-BvGhLr64.js} +1 -1
- package/inspector/dist/assets/{index-C9y82Xkr.js → index-BxPjb1aG.js} +1 -1
- package/inspector/dist/assets/{index-BWQugB-m.js → index-C3ugp_Wf.js} +1 -1
- package/inspector/dist/assets/{index-IK4Vsg-q.js → index-C5IBvIVa.js} +44 -44
- package/inspector/dist/assets/{index-Dx4HOh5k.js → index-CV4Aiss-.js} +1 -1
- package/inspector/dist/assets/{index-BanLa7PQ.js → index-CdkhUV5I.js} +1 -1
- package/inspector/dist/assets/{index-BvrVgIw_.js → index-D3O4auYk.js} +1 -1
- package/inspector/dist/assets/{index-BmdO9i46.js → index-DcXZX6dj.js} +1 -1
- package/inspector/dist/assets/{index-Dgi1UC16.js → index-Dnqjpy0h.js} +1 -1
- package/inspector/dist/assets/{index-CK6xHVuA.js → index-LBoNKP4N.js} +1 -1
- package/inspector/dist/assets/{index-2RQVAOu3.js → index-e-11MUIo.js} +1 -1
- package/inspector/dist/index.html +2 -2
- package/package.json +1 -1
- package/inspector/dist/assets/index-iGaBYIin.css +0 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
/**
|
|
3
|
+
* How to run "this same kraftwerk" as a new process: the node we run on
|
|
4
|
+
* plus the bin script we were started from. Identical for global installs,
|
|
5
|
+
* local node_modules, npx caches and a dev checkout (bin/kraftwerk.js
|
|
6
|
+
* picks src/ vs dist/ itself). Shared by the `kraftwerk ui` supervisor and
|
|
7
|
+
* the project-start feature so bin resolution lives in one place.
|
|
8
|
+
*
|
|
9
|
+
* If the bin file is gone (npx cache pruned, package removed) the
|
|
10
|
+
* fallback is `npx @netnodeag/kraftwerk`, i.e. the registry's latest —
|
|
11
|
+
* not the running version, but better than nothing.
|
|
12
|
+
*/
|
|
13
|
+
export function selfCommand(args) {
|
|
14
|
+
const bin = process.argv[1];
|
|
15
|
+
if (bin && existsSync(bin))
|
|
16
|
+
return { cmd: process.execPath, args: [bin, ...args] };
|
|
17
|
+
return { cmd: "npx", args: ["-y", "@netnodeag/kraftwerk", ...args] };
|
|
18
|
+
}
|
package/dist/inspector/server.js
CHANGED
|
@@ -10,7 +10,7 @@ import { cancelChat, createChat, deleteChat, disposeAllBackends, getChat, listCh
|
|
|
10
10
|
import { bundleDetail, conceptDetail, createBundle, knowledgeIndex, putConcept, verifyFromUi, } from "./knowledge.js";
|
|
11
11
|
import { deleteMember, getMember, listMembers, saveMember, setMemberArchived, teamRoot, } from "./team.js";
|
|
12
12
|
import { deleteAgentSkill, getSkill, listAgentSkills, listSkills, readSkill, saveAgentSkill, skillsRoot, } from "./skills.js";
|
|
13
|
-
import {
|
|
13
|
+
import { discoverWorkspaces, forgetProject, markProjectStopped, registerInstance, registerProject, startProject, tildify, unregisterInstance, } from "./instances.js";
|
|
14
14
|
import { getSettings, saveSettings } from "./settings.js";
|
|
15
15
|
import { deleteRoutine, routineStatuses, runRoutineNow, saveRoutine, startRoutineScheduler, } from "./routines.js";
|
|
16
16
|
/**
|
|
@@ -98,15 +98,17 @@ async function handleApi(req, res, url) {
|
|
|
98
98
|
const project = await resolveProject(getProjectRoot()).catch(() => null);
|
|
99
99
|
const projectName = project?.config.name ?? (project ? path.basename(project.root) : "");
|
|
100
100
|
const manual = project?.config.switcher ?? [];
|
|
101
|
-
const discovered = url.searchParams.get("probe") === "1" ? [] : await
|
|
101
|
+
const discovered = url.searchParams.get("probe") === "1" ? [] : await discoverWorkspaces();
|
|
102
102
|
// Manual switcher entries keep their configured name/icon; discovered
|
|
103
|
-
//
|
|
103
|
+
// workspaces that duplicate one (same url, running) only contribute
|
|
104
|
+
// the live flag. Stopped projects never collide — they carry a root,
|
|
105
|
+
// and a manual entry pointing at the same port is just a link.
|
|
104
106
|
const norm = (u) => u.replace(/\/+$/, "").replace("127.0.0.1", "localhost").toLowerCase();
|
|
105
107
|
const manualUrls = new Set(manual.map((e) => norm(e.url)));
|
|
106
|
-
const liveUrls = new Set(discovered.map((d) => norm(d.url)));
|
|
108
|
+
const liveUrls = new Set(discovered.filter((d) => d.live).map((d) => norm(d.url)));
|
|
107
109
|
const switcher = [
|
|
108
110
|
...manual.map((e) => (liveUrls.has(norm(e.url)) ? { ...e, live: true } : e)),
|
|
109
|
-
...discovered.filter((d) => !manualUrls.has(norm(d.url))),
|
|
111
|
+
...discovered.filter((d) => !(d.live && manualUrls.has(norm(d.url)))),
|
|
110
112
|
];
|
|
111
113
|
return json(res, {
|
|
112
114
|
version: await getPkgVersion(),
|
|
@@ -116,9 +118,37 @@ async function handleApi(req, res, url) {
|
|
|
116
118
|
restartable: supervised(),
|
|
117
119
|
projectName,
|
|
118
120
|
projectIcon: project?.config.icon ?? "",
|
|
121
|
+
projectRoot: project?.root ?? getProjectRoot(),
|
|
122
|
+
projectRootLabel: tildify(project?.root ?? getProjectRoot()),
|
|
119
123
|
switcher,
|
|
120
124
|
});
|
|
121
125
|
}
|
|
126
|
+
// POST /api/projects/start {root} — launch `kraftwerk ui` for a known
|
|
127
|
+
// project as a detached process (the switcher's Start button).
|
|
128
|
+
if (seg.length === 3 && seg[1] === "projects" && seg[2] === "start" && method === "POST") {
|
|
129
|
+
try {
|
|
130
|
+
const { root } = JSON.parse(await readBody(req));
|
|
131
|
+
if (!root)
|
|
132
|
+
return json(res, { error: "root required" }, 400);
|
|
133
|
+
const result = await startProject(root);
|
|
134
|
+
return json(res, result, result.ok ? 200 : 409);
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
return json(res, { error: err.message }, 400);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// POST /api/projects/forget {root} — drop a project from the registry
|
|
141
|
+
if (seg.length === 3 && seg[1] === "projects" && seg[2] === "forget" && method === "POST") {
|
|
142
|
+
try {
|
|
143
|
+
const { root } = JSON.parse(await readBody(req));
|
|
144
|
+
if (!root)
|
|
145
|
+
return json(res, { error: "root required" }, 400);
|
|
146
|
+
return json(res, { ok: await forgetProject(root) });
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
return json(res, { error: err.message }, 400);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
122
152
|
// GET /api/settings — kraftwerk.yml (parsed + resolved paths) for the settings page
|
|
123
153
|
if (seg.length === 2 && seg[1] === "settings" && method === "GET") {
|
|
124
154
|
return json(res, await getSettings());
|
|
@@ -618,12 +648,16 @@ export function startInspector(opts) {
|
|
|
618
648
|
process.once(sig, () => {
|
|
619
649
|
disposeAllBackends();
|
|
620
650
|
unregisterInstance();
|
|
651
|
+
markProjectStopped();
|
|
621
652
|
process.exit(sig === "SIGINT" ? 130 : 143);
|
|
622
653
|
});
|
|
623
654
|
}
|
|
624
|
-
process.once("exit", () => {
|
|
655
|
+
process.once("exit", (code) => {
|
|
625
656
|
disposeAllBackends();
|
|
626
657
|
unregisterInstance();
|
|
658
|
+
// A self-restart (new version) is not a stop — the project stays "running".
|
|
659
|
+
if (code !== RESTART_EXIT_CODE)
|
|
660
|
+
markProjectStopped();
|
|
627
661
|
});
|
|
628
662
|
const server = http.createServer(async (req, res) => {
|
|
629
663
|
try {
|
|
@@ -641,7 +675,9 @@ export function startInspector(opts) {
|
|
|
641
675
|
server.once("error", reject);
|
|
642
676
|
server.listen(opts.port, () => {
|
|
643
677
|
const addr = server.address();
|
|
644
|
-
|
|
678
|
+
const port = typeof addr === "object" && addr ? addr.port : opts.port;
|
|
679
|
+
void registerInstance(port, getProjectRoot());
|
|
680
|
+
void registerProject(getProjectRoot());
|
|
645
681
|
resolve(server);
|
|
646
682
|
});
|
|
647
683
|
});
|