@netnodeag/kraftwerk 0.37.1 → 0.38.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/config.d.ts +3 -0
- package/dist/config.js +7 -1
- package/dist/inspector/instances.d.ts +8 -0
- package/dist/inspector/instances.js +23 -3
- package/dist/inspector/server.js +2 -0
- package/dist/inspector/settings.d.ts +2 -0
- package/dist/inspector/settings.js +8 -0
- package/inspector/dist/assets/{editor-vM6JSj5h.js → editor-BnDJd3j4.js} +3 -3
- package/inspector/dist/assets/{index-MWv5H1oP.js → index-1K-YGe-R.js} +1 -1
- package/inspector/dist/assets/{index-C1UXlW32.js → index-5n-x53jb.js} +1 -1
- package/inspector/dist/assets/{index-BAAjszPI.js → index-B6zeZ-I9.js} +1 -1
- package/inspector/dist/assets/{index-CtMGH62C.js → index-BCwvYdEE.js} +1 -1
- package/inspector/dist/assets/{index-DfZT0IoM.js → index-BDHHRQvJ.js} +1 -1
- package/inspector/dist/assets/{index-D_11IZBV.js → index-BFmXikOX.js} +1 -1
- package/inspector/dist/assets/{index-Bb08wK-l.js → index-C2kxy-K_.js} +1 -1
- package/inspector/dist/assets/{index-DykDNrYm.js → index-CTECF5uX.js} +1 -1
- package/inspector/dist/assets/index-CtnGrZvu.js +217 -0
- package/inspector/dist/assets/{index-BrCwDkJZ.js → index-DBHgQG4M.js} +1 -1
- package/inspector/dist/assets/{index-CQ2XKqmD.js → index-DfqhDHp9.js} +1 -1
- package/inspector/dist/assets/index-DjMx3a5H.css +1 -0
- package/inspector/dist/assets/{index-yGZsomcy.js → index-DmY7gYaR.js} +1 -1
- package/inspector/dist/assets/{index-CaKmxcD6.js → index-Dq3QrDLb.js} +1 -1
- package/inspector/dist/assets/{index-oIQqfbwm.js → index-Fd3s8yys.js} +1 -1
- package/inspector/dist/assets/{index-Bs1U0rWW.js → index-Rmy9pam8.js} +1 -1
- package/inspector/dist/assets/{index-CUGfxoYt.js → index-VxlzgVIX.js} +1 -1
- package/inspector/dist/assets/{index-CReepirH.js → index-o4xPJnqZ.js} +1 -1
- package/inspector/dist/assets/{index-BKcOp35r.js → index-sSEE6ykA.js} +1 -1
- package/inspector/dist/index.html +2 -2
- package/package.json +1 -1
- package/inspector/dist/assets/index-Ba8VU6Wz.js +0 -217
- package/inspector/dist/assets/index-D4_mLTSH.css +0 -1
package/dist/config.d.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* name: my-project # display name (inspector header, "environment")
|
|
13
13
|
* icon: "⚡" # emoji shown as inspector favicon
|
|
14
|
+
* color: "#c2410c" # accent for this workspace in the switcher (default: derived from the root)
|
|
14
15
|
* port: 1981 # port `kraftwerk ui` listens on
|
|
15
16
|
* workflows: src/workflows # workflows root, relative to the file
|
|
16
17
|
* output: output # run-artifact directory, relative to the file
|
|
@@ -88,6 +89,8 @@ export interface ProjectConfig {
|
|
|
88
89
|
name?: string;
|
|
89
90
|
/** Emoji used as the inspector favicon (browser-tab icon). */
|
|
90
91
|
icon?: string;
|
|
92
|
+
/** Accent colour (#rgb / #rrggbb) for this workspace in the switcher. Default: derived from the root path. */
|
|
93
|
+
color?: string;
|
|
91
94
|
/** Port `kraftwerk ui` listens on. Default: 1981 (CLI --port wins). */
|
|
92
95
|
port?: number;
|
|
93
96
|
/** Workflows root relative to the project root. */
|
package/dist/config.js
CHANGED
|
@@ -15,6 +15,7 @@ import { parse } from "yaml";
|
|
|
15
15
|
*
|
|
16
16
|
* name: my-project # display name (inspector header, "environment")
|
|
17
17
|
* icon: "⚡" # emoji shown as inspector favicon
|
|
18
|
+
* color: "#c2410c" # accent for this workspace in the switcher (default: derived from the root)
|
|
18
19
|
* port: 1981 # port `kraftwerk ui` listens on
|
|
19
20
|
* workflows: src/workflows # workflows root, relative to the file
|
|
20
21
|
* output: output # run-artifact directory, relative to the file
|
|
@@ -126,7 +127,7 @@ export async function resolveProject(cwd) {
|
|
|
126
127
|
const root = gitFallback ?? start;
|
|
127
128
|
return { root, config: {}, outputDir: path.join(root, "output") };
|
|
128
129
|
}
|
|
129
|
-
const KNOWN_KEYS = ["name", "icon", "port", "workflows", "output", "knowledge", "agents", "skills", "switcher", "git", "repos"];
|
|
130
|
+
const KNOWN_KEYS = ["name", "icon", "color", "port", "workflows", "output", "knowledge", "agents", "skills", "switcher", "git", "repos"];
|
|
130
131
|
async function loadConfig(configPath) {
|
|
131
132
|
let raw;
|
|
132
133
|
try {
|
|
@@ -151,6 +152,11 @@ async function loadConfig(configPath) {
|
|
|
151
152
|
throw new Error(`${path.basename(configPath)}: port must be an integer`);
|
|
152
153
|
}
|
|
153
154
|
}
|
|
155
|
+
else if (key === "color") {
|
|
156
|
+
if (typeof config[key] !== "string" || !/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(config[key])) {
|
|
157
|
+
throw new Error(`${path.basename(configPath)}: color must be a hex colour like "#c2410c"`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
154
160
|
else if (key === "switcher") {
|
|
155
161
|
validateSwitcher(configPath, config[key]);
|
|
156
162
|
}
|
|
@@ -15,6 +15,10 @@ export interface DiscoveredInstance {
|
|
|
15
15
|
name: string;
|
|
16
16
|
url: string;
|
|
17
17
|
icon?: string;
|
|
18
|
+
/** kraftwerk.yml `color`, if set. */
|
|
19
|
+
color?: string;
|
|
20
|
+
/** True when the name comes from kraftwerk.yml (false = folder name). */
|
|
21
|
+
named?: boolean;
|
|
18
22
|
live: true;
|
|
19
23
|
root?: string;
|
|
20
24
|
/** Server process id (what to signal to stop it). */
|
|
@@ -29,6 +33,10 @@ export interface WorkspaceEntry {
|
|
|
29
33
|
/** Where the inspector answers (live) or would answer once started. */
|
|
30
34
|
url: string;
|
|
31
35
|
icon?: string;
|
|
36
|
+
/** kraftwerk.yml `color`, if set; the UI derives one from the root otherwise. */
|
|
37
|
+
color?: string;
|
|
38
|
+
/** True when the name comes from kraftwerk.yml, false when it is just the folder name. */
|
|
39
|
+
named?: boolean;
|
|
32
40
|
live: boolean;
|
|
33
41
|
root?: string;
|
|
34
42
|
/** Root with ~ for the home dir — what the UI prints. */
|
|
@@ -86,6 +86,8 @@ async function probeAt(host, port) {
|
|
|
86
86
|
name: meta.projectName || `localhost:${port}`,
|
|
87
87
|
url: `http://localhost:${port}`,
|
|
88
88
|
icon: meta.projectIcon || undefined,
|
|
89
|
+
color: meta.projectColor || undefined,
|
|
90
|
+
named: typeof meta.projectNamed === "boolean" ? meta.projectNamed : undefined,
|
|
89
91
|
live: true,
|
|
90
92
|
};
|
|
91
93
|
}
|
|
@@ -232,7 +234,7 @@ export async function forgetProject(root) {
|
|
|
232
234
|
* so without this check a stale record would wear its parent's identity.
|
|
233
235
|
*/
|
|
234
236
|
async function describeRoot(root) {
|
|
235
|
-
const fallback = { name: path.basename(root), port: 1981, exists: false };
|
|
237
|
+
const fallback = { name: path.basename(root), named: false, port: 1981, exists: false };
|
|
236
238
|
if (!(await isDir(root)))
|
|
237
239
|
return fallback;
|
|
238
240
|
try {
|
|
@@ -241,7 +243,9 @@ async function describeRoot(root) {
|
|
|
241
243
|
return fallback;
|
|
242
244
|
return {
|
|
243
245
|
name: project.config.name ?? path.basename(project.root),
|
|
246
|
+
named: !!project.config.name,
|
|
244
247
|
icon: project.config.icon || undefined,
|
|
248
|
+
color: project.config.color || undefined,
|
|
245
249
|
port: project.config.port ?? 1981,
|
|
246
250
|
exists: true,
|
|
247
251
|
};
|
|
@@ -278,15 +282,29 @@ export async function discoverWorkspaces() {
|
|
|
278
282
|
}
|
|
279
283
|
if (running) {
|
|
280
284
|
consumed.add(running);
|
|
281
|
-
|
|
285
|
+
// An instance from before 0.38 answers without color/named — read them from its root.
|
|
286
|
+
if (running.named === undefined)
|
|
287
|
+
d = await describeRoot(p.root);
|
|
288
|
+
return {
|
|
289
|
+
...base,
|
|
290
|
+
name: running.name,
|
|
291
|
+
url: running.url,
|
|
292
|
+
icon: running.icon,
|
|
293
|
+
color: running.color ?? d?.color,
|
|
294
|
+
named: running.named ?? d?.named,
|
|
295
|
+
live: true,
|
|
296
|
+
exists: true,
|
|
297
|
+
};
|
|
282
298
|
}
|
|
283
|
-
return { ...base, name: d.name, url: `http://localhost:${d.port}`, icon: d.icon, live: false, exists: d.exists };
|
|
299
|
+
return { ...base, name: d.name, url: `http://localhost:${d.port}`, icon: d.icon, color: d.color, named: d.named, live: false, exists: d.exists };
|
|
284
300
|
}))).concat(await Promise.all(live
|
|
285
301
|
.filter((i) => !consumed.has(i))
|
|
286
302
|
.map(async (i) => ({
|
|
287
303
|
name: i.name,
|
|
288
304
|
url: i.url,
|
|
289
305
|
icon: i.icon,
|
|
306
|
+
color: i.color,
|
|
307
|
+
named: i.named,
|
|
290
308
|
live: true,
|
|
291
309
|
root: i.root,
|
|
292
310
|
rootLabel: i.root ? tildify(i.root) : undefined,
|
|
@@ -335,6 +353,8 @@ export async function listWorkspacesDetailed() {
|
|
|
335
353
|
all.unshift({
|
|
336
354
|
name: d.name,
|
|
337
355
|
icon: d.icon,
|
|
356
|
+
color: d.color,
|
|
357
|
+
named: d.named,
|
|
338
358
|
url: `http://localhost:${selfPort}`,
|
|
339
359
|
live: true,
|
|
340
360
|
root: selfRoot,
|
package/dist/inspector/server.js
CHANGED
|
@@ -213,6 +213,8 @@ async function handleApi(req, res, url) {
|
|
|
213
213
|
restartable: supervised(),
|
|
214
214
|
projectName,
|
|
215
215
|
projectIcon: project?.config.icon ?? "",
|
|
216
|
+
projectColor: project?.config.color ?? "",
|
|
217
|
+
projectNamed: !!project?.config.name,
|
|
216
218
|
projectRoot: project?.root ?? getProjectRoot(),
|
|
217
219
|
projectRootLabel: tildify(project?.root ?? getProjectRoot()),
|
|
218
220
|
git: (project?.config.git && project.config.git.enabled !== false) === true,
|
|
@@ -20,6 +20,8 @@ export interface SaveSettingsInput {
|
|
|
20
20
|
/** Omitted = untouched; empty string = remove the key. */
|
|
21
21
|
name?: string;
|
|
22
22
|
icon?: string;
|
|
23
|
+
/** Omitted = untouched; empty string = remove the key. Hex colour otherwise. */
|
|
24
|
+
color?: string;
|
|
23
25
|
/** Omitted = untouched; empty list = remove the key. */
|
|
24
26
|
switcher?: SwitcherEntry[];
|
|
25
27
|
/** Omitted = untouched. See cleanGit for how the block is written. */
|
|
@@ -94,6 +94,13 @@ export async function saveSettings(input) {
|
|
|
94
94
|
throw new Error("name must be a string");
|
|
95
95
|
if (input.icon !== undefined && typeof input.icon !== "string")
|
|
96
96
|
throw new Error("icon must be a string");
|
|
97
|
+
if (input.color !== undefined) {
|
|
98
|
+
if (typeof input.color !== "string")
|
|
99
|
+
throw new Error("color must be a string");
|
|
100
|
+
if (input.color.trim() && !/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(input.color.trim())) {
|
|
101
|
+
throw new Error('color must be a hex colour like "#c2410c"');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
97
104
|
const switcher = input.switcher === undefined ? undefined : cleanSwitcher(input.switcher);
|
|
98
105
|
const project = await resolveProject(getProjectRoot());
|
|
99
106
|
const configPath = project.configPath ?? path.join(project.root, "kraftwerk.yml");
|
|
@@ -111,6 +118,7 @@ export async function saveSettings(input) {
|
|
|
111
118
|
};
|
|
112
119
|
setOrDelete("name", input.name?.trim());
|
|
113
120
|
setOrDelete("icon", input.icon?.trim());
|
|
121
|
+
setOrDelete("color", input.color?.trim());
|
|
114
122
|
setOrDelete("switcher", switcher);
|
|
115
123
|
if (input.git !== undefined) {
|
|
116
124
|
const git = cleanGit(input.git);
|