@netnodeag/kraftwerk 0.38.1 → 0.39.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/init.js +1 -0
- package/dist/cli/kraftwerk.js +2 -0
- package/dist/cli/vibeables.d.ts +2 -0
- package/dist/cli/vibeables.js +89 -0
- package/dist/config.d.ts +20 -0
- package/dist/config.js +29 -10
- package/dist/inspector/chat/sessions.d.ts +11 -0
- package/dist/inspector/chat/sessions.js +86 -10
- package/dist/inspector/chat/types.d.ts +2 -0
- package/dist/inspector/git.js +5 -3
- package/dist/inspector/mtime.d.ts +3 -0
- package/dist/inspector/mtime.js +31 -0
- package/dist/inspector/repos.d.ts +2 -0
- package/dist/inspector/repos.js +5 -1
- package/dist/inspector/server.js +90 -1
- package/dist/inspector/settings.d.ts +3 -1
- package/dist/inspector/settings.js +19 -8
- package/dist/inspector/vibeables.d.ts +152 -0
- package/dist/inspector/vibeables.js +509 -0
- package/inspector/dist/assets/apl-gfMMiTNf.js +1 -0
- package/inspector/dist/assets/asciiarmor-C_eisQCp.js +1 -0
- package/inspector/dist/assets/asn1-DCl_8MCW.js +1 -0
- package/inspector/dist/assets/asterisk-BEn0Cwpx.js +1 -0
- package/inspector/dist/assets/brainfuck-D5EjA2JK.js +1 -0
- package/inspector/dist/assets/clike-D_6L3tnO.js +1 -0
- package/inspector/dist/assets/clojure-BflJGmDX.js +1 -0
- package/inspector/dist/assets/cmake-84nbDH0I.js +1 -0
- package/inspector/dist/assets/cobol-DHLQUbN7.js +1 -0
- package/inspector/dist/assets/coffeescript-De_zI4J0.js +1 -0
- package/inspector/dist/assets/commonlisp-DgAKBe0r.js +1 -0
- package/inspector/dist/assets/crystal-Bsdphhtm.js +1 -0
- package/inspector/dist/assets/css-CnaYoQib.js +1 -0
- package/inspector/dist/assets/cypher-p9eYesGn.js +1 -0
- package/inspector/dist/assets/d-DWkQyNnU.js +1 -0
- package/inspector/dist/assets/diff-ChtP43wD.js +1 -0
- package/inspector/dist/assets/dist-3Nzkrylv.js +1 -0
- package/inspector/dist/assets/dist-5wk4daHl.js +1 -0
- package/inspector/dist/assets/dist-BCM6ehYa.js +1 -0
- package/inspector/dist/assets/dist-BECiZEqH.js +1 -0
- package/inspector/dist/assets/dist-BbhR2mEU.js +1 -0
- package/inspector/dist/assets/dist-CF7An11X.js +1 -0
- package/inspector/dist/assets/dist-CI-2-8Tz.js +23 -0
- package/inspector/dist/assets/dist-CPlSMtdY.js +1 -0
- package/inspector/dist/assets/dist-CXS6W3P9.js +9 -0
- package/inspector/dist/assets/dist-Ceimhh7q.js +1 -0
- package/inspector/dist/assets/dist-D3tgdU3w.js +1 -0
- package/inspector/dist/assets/dist-D8nmL5S9.js +1 -0
- package/inspector/dist/assets/dist-DNBDudvB.js +1 -0
- package/inspector/dist/assets/dist-DTW4FhJ_.js +1 -0
- package/inspector/dist/assets/dist-DXIk6Ebu.js +1 -0
- package/inspector/dist/assets/dist-DaG9QYNU.js +1 -0
- package/inspector/dist/assets/dist-Dd-u7fXY.js +1 -0
- package/inspector/dist/assets/dist-DwyxsFyN.js +1 -0
- package/inspector/dist/assets/dist-H3rerbMg.js +13 -0
- package/inspector/dist/assets/dist-ZMc9InB9.js +1 -0
- package/inspector/dist/assets/dist-nc_mc1w0.js +1 -0
- package/inspector/dist/assets/dist-rE2oRtJp.js +11 -0
- package/inspector/dist/assets/dist-yFKhRrHN.js +2 -0
- package/inspector/dist/assets/dockerfile-DJkHQgkl.js +1 -0
- package/inspector/dist/assets/dtd-DTF72YNO.js +1 -0
- package/inspector/dist/assets/dylan-BCDoL_-p.js +1 -0
- package/inspector/dist/assets/ebnf-D4c0_ac3.js +1 -0
- package/inspector/dist/assets/ecl-BVIeWmwY.js +1 -0
- package/inspector/dist/assets/editor-6yCJBeDg.js +120 -0
- package/inspector/dist/assets/editor-B1Jq9YIq.css +1 -0
- package/inspector/dist/assets/eiffel-BEjRio4Q.js +1 -0
- package/inspector/dist/assets/elm-Cshzl8qu.js +1 -0
- package/inspector/dist/assets/erlang-BV0c4Hdn.js +1 -0
- package/inspector/dist/assets/factor-LKH5gN8L.js +1 -0
- package/inspector/dist/assets/fcl-ClOhbFR7.js +1 -0
- package/inspector/dist/assets/forth-D6RzAl64.js +1 -0
- package/inspector/dist/assets/fortran-Bt6PBEDR.js +1 -0
- package/inspector/dist/assets/gas-BHEdbvp9.js +1 -0
- package/inspector/dist/assets/gherkin-oBAE_ms0.js +1 -0
- package/inspector/dist/assets/groovy-CUpZ7dEl.js +1 -0
- package/inspector/dist/assets/haskell-BRsoo5mP.js +1 -0
- package/inspector/dist/assets/haxe-DjVOVvNP.js +1 -0
- package/inspector/dist/assets/http-CLVgA2GD.js +1 -0
- package/inspector/dist/assets/idl-BUZw3wgd.js +1 -0
- package/inspector/dist/assets/index-Dom87GNV.css +1 -0
- package/inspector/dist/assets/index-DurTvcNI.js +218 -0
- package/inspector/dist/assets/javascript-Bu8mWwtz.js +1 -0
- package/inspector/dist/assets/julia-CQfgDRfP.js +1 -0
- package/inspector/dist/assets/livescript-BXxG0Yva.js +1 -0
- package/inspector/dist/assets/lua-DPCEkfD_.js +1 -0
- package/inspector/dist/assets/material-symbols-rounded-DzDTtRam.woff2 +0 -0
- package/inspector/dist/assets/mathematica-u8YMmbU0.js +1 -0
- package/inspector/dist/assets/mbox-BEMVcqjs.js +1 -0
- package/inspector/dist/assets/{mirc-CjQqDB4T.js → mirc-C9zpzAZU.js} +1 -1
- package/inspector/dist/assets/mllike-B45xgp2S.js +1 -0
- package/inspector/dist/assets/modelica-CqHI_q-D.js +1 -0
- package/inspector/dist/assets/mscgen-qgSLujhx.js +1 -0
- package/inspector/dist/assets/mumps-BSzj6Xyz.js +1 -0
- package/inspector/dist/assets/{nginx-DdIZxoE0.js → nginx-8H7HVH4w.js} +1 -1
- package/inspector/dist/assets/nsis-viPvXFiq.js +1 -0
- package/inspector/dist/assets/ntriples-B9h1VB_g.js +1 -0
- package/inspector/dist/assets/octave-D2Q8cUp1.js +1 -0
- package/inspector/dist/assets/oz-BwTct_5T.js +1 -0
- package/inspector/dist/assets/pascal-Dp_KdFgX.js +1 -0
- package/inspector/dist/assets/perl-BkSkiI9m.js +1 -0
- package/inspector/dist/assets/pig-AF4Hwhju.js +1 -0
- package/inspector/dist/assets/powershell-BcIto6Sf.js +1 -0
- package/inspector/dist/assets/properties-C357ku5U.js +1 -0
- package/inspector/dist/assets/protobuf-D1ij_kNL.js +1 -0
- package/inspector/dist/assets/pug-3K-JMW4g.js +1 -0
- package/inspector/dist/assets/puppet-BZyAS7I4.js +1 -0
- package/inspector/dist/assets/python-B_1Jd8HM.js +1 -0
- package/inspector/dist/assets/q-B9NhS7L_.js +1 -0
- package/inspector/dist/assets/r-CxDmU1I4.js +1 -0
- package/inspector/dist/assets/rpm-gpDK5sbt.js +1 -0
- package/inspector/dist/assets/ruby-ChfNwlCY.js +1 -0
- package/inspector/dist/assets/{sas-B4kiWyti.js → sas-C2OyD2Y6.js} +1 -1
- package/inspector/dist/assets/scheme-D9qYN0V5.js +1 -0
- package/inspector/dist/assets/shell-DwuoZtxw.js +1 -0
- package/inspector/dist/assets/sieve-tLWDfEkZ.js +1 -0
- package/inspector/dist/assets/simple-mode-DXiLM1-G.js +1 -0
- package/inspector/dist/assets/smalltalk-BLp5-jwC.js +1 -0
- package/inspector/dist/assets/solr-B78wSQJQ.js +1 -0
- package/inspector/dist/assets/sparql-Dz-mlCAC.js +1 -0
- package/inspector/dist/assets/spreadsheet-CTIncYxj.js +1 -0
- package/inspector/dist/assets/sql-DuQMFDvy.js +1 -0
- package/inspector/dist/assets/stex-DNzd62Q_.js +1 -0
- package/inspector/dist/assets/stylus-BOVgKnng.js +1 -0
- package/inspector/dist/assets/swift-DKB6_1j6.js +1 -0
- package/inspector/dist/assets/tcl-BGfruO1u.js +1 -0
- package/inspector/dist/assets/textile-C4jVoHG1.js +1 -0
- package/inspector/dist/assets/tiddlywiki-VlUiK86J.js +1 -0
- package/inspector/dist/assets/tiki-AK6FwT8q.js +1 -0
- package/inspector/dist/assets/toml-BPTmHmyx.js +1 -0
- package/inspector/dist/assets/troff-C2dAgh7P.js +1 -0
- package/inspector/dist/assets/ttcn-PPSTk1ow.js +1 -0
- package/inspector/dist/assets/ttcn-cfg-2b4Gb5sE.js +1 -0
- package/inspector/dist/assets/turtle-Cx3rYX2g.js +1 -0
- package/inspector/dist/assets/vb-BthdM_4N.js +1 -0
- package/inspector/dist/assets/vbscript-D9f6rSsU.js +1 -0
- package/inspector/dist/assets/velocity-CqftRsjg.js +1 -0
- package/inspector/dist/assets/verilog-CjI9Y6RI.js +1 -0
- package/inspector/dist/assets/vhdl-kS471soi.js +1 -0
- package/inspector/dist/assets/webidl-D5jiJvOU.js +1 -0
- package/inspector/dist/assets/xquery-BKJx4mf9.js +1 -0
- package/inspector/dist/assets/yacas-CXXgtw0p.js +1 -0
- package/inspector/dist/assets/z80-Co3PbHdE.js +1 -0
- package/inspector/dist/index.html +2 -2
- package/package.json +6 -6
- package/inspector/dist/assets/apl-B4CMkyY2.js +0 -1
- package/inspector/dist/assets/asciiarmor-Df11BRmG.js +0 -1
- package/inspector/dist/assets/asn1-EdZsLKOL.js +0 -1
- package/inspector/dist/assets/asterisk-B-8jnY81.js +0 -1
- package/inspector/dist/assets/brainfuck-C4LP7Hcl.js +0 -1
- package/inspector/dist/assets/clike-B9uivgTg.js +0 -1
- package/inspector/dist/assets/clojure-BMjYHr_A.js +0 -1
- package/inspector/dist/assets/cmake-BQqOBYOt.js +0 -1
- package/inspector/dist/assets/cobol-CWcv1MsR.js +0 -1
- package/inspector/dist/assets/coffeescript-S37ZYGWr.js +0 -1
- package/inspector/dist/assets/commonlisp-DBKNyK5s.js +0 -1
- package/inspector/dist/assets/crystal-SjHAIU92.js +0 -1
- package/inspector/dist/assets/css-BnMrqG3P.js +0 -1
- package/inspector/dist/assets/cypher-C_CwsFkJ.js +0 -1
- package/inspector/dist/assets/d-pRatUO7H.js +0 -1
- package/inspector/dist/assets/diff-DbItnlRl.js +0 -1
- package/inspector/dist/assets/dockerfile-BKs6k2Af.js +0 -1
- package/inspector/dist/assets/dtd-DF_7sFjM.js +0 -1
- package/inspector/dist/assets/dylan-DwRh75JA.js +0 -1
- package/inspector/dist/assets/ebnf-CDyGwa7X.js +0 -1
- package/inspector/dist/assets/ecl-Cabwm37j.js +0 -1
- package/inspector/dist/assets/editor-9rr2cQaW.css +0 -1
- package/inspector/dist/assets/editor-CONb__vl.js +0 -144
- package/inspector/dist/assets/eiffel-CnydiIhH.js +0 -1
- package/inspector/dist/assets/elm-vLlmbW-K.js +0 -1
- package/inspector/dist/assets/erlang-BNw1qcRV.js +0 -1
- package/inspector/dist/assets/factor-kuTfRLto.js +0 -1
- package/inspector/dist/assets/fcl-Kvtd6kyn.js +0 -1
- package/inspector/dist/assets/forth-Ffai-XNe.js +0 -1
- package/inspector/dist/assets/fortran-DYz_wnZ1.js +0 -1
- package/inspector/dist/assets/gas-Bneqetm1.js +0 -1
- package/inspector/dist/assets/gherkin-heZmZLOM.js +0 -1
- package/inspector/dist/assets/groovy-D9Dt4D0W.js +0 -1
- package/inspector/dist/assets/haskell-Cw1EW3IL.js +0 -1
- package/inspector/dist/assets/haxe-H-WmDvRZ.js +0 -1
- package/inspector/dist/assets/http-DBlCnlav.js +0 -1
- package/inspector/dist/assets/idl-BEugSyMb.js +0 -1
- package/inspector/dist/assets/index-6VtYKf_K.js +0 -1
- package/inspector/dist/assets/index-B_BJEGG5.js +0 -1
- package/inspector/dist/assets/index-BkznuDSS.js +0 -1
- package/inspector/dist/assets/index-BrGHSw5I.js +0 -1
- package/inspector/dist/assets/index-BuiRW-03.js +0 -1
- package/inspector/dist/assets/index-C1tY1uK0.js +0 -1
- package/inspector/dist/assets/index-CDY-uFno.js +0 -7
- package/inspector/dist/assets/index-CcGsEtey.js +0 -1
- package/inspector/dist/assets/index-CntcQxRr.js +0 -1
- package/inspector/dist/assets/index-CpDzWqX0.js +0 -3
- package/inspector/dist/assets/index-Cw6eNCH7.js +0 -1
- package/inspector/dist/assets/index-D1_Glu0y.css +0 -1
- package/inspector/dist/assets/index-DMWUqEQi.js +0 -217
- package/inspector/dist/assets/index-DfK1f9gz.js +0 -1
- package/inspector/dist/assets/index-IosqBxL0.js +0 -1
- package/inspector/dist/assets/index-iRFYcgNN.js +0 -1
- package/inspector/dist/assets/index-p5w5E19N.js +0 -1
- package/inspector/dist/assets/index-rAZqRLhj.js +0 -2
- package/inspector/dist/assets/index-yGDq5Egm.js +0 -1
- package/inspector/dist/assets/javascript-iXu5QeM3.js +0 -1
- package/inspector/dist/assets/julia-DuME0IfC.js +0 -1
- package/inspector/dist/assets/livescript-BwQOo05w.js +0 -1
- package/inspector/dist/assets/lua-VAEuO923.js +0 -1
- package/inspector/dist/assets/material-symbols-rounded-DxXFL64Y.woff2 +0 -0
- package/inspector/dist/assets/mathematica-DTrFuWx2.js +0 -1
- package/inspector/dist/assets/mbox-CNhZ1qSd.js +0 -1
- package/inspector/dist/assets/mllike-CXdrOF99.js +0 -1
- package/inspector/dist/assets/modelica-Dc1JOy9r.js +0 -1
- package/inspector/dist/assets/mscgen-BA5vi2Kp.js +0 -1
- package/inspector/dist/assets/mumps-BT43cFF4.js +0 -1
- package/inspector/dist/assets/nsis-LY0VT_u5.js +0 -1
- package/inspector/dist/assets/ntriples-BfvgReVJ.js +0 -1
- package/inspector/dist/assets/octave-Ck1zUtKM.js +0 -1
- package/inspector/dist/assets/oz-BzwKVEFT.js +0 -1
- package/inspector/dist/assets/pascal--L3eBynH.js +0 -1
- package/inspector/dist/assets/perl-CdXCOZ3F.js +0 -1
- package/inspector/dist/assets/pig-CevX1Tat.js +0 -1
- package/inspector/dist/assets/powershell-CFHJl5sT.js +0 -1
- package/inspector/dist/assets/properties-C78fOPTZ.js +0 -1
- package/inspector/dist/assets/protobuf-ChK-085T.js +0 -1
- package/inspector/dist/assets/pug-DeIclll2.js +0 -1
- package/inspector/dist/assets/puppet-DMA9R1ak.js +0 -1
- package/inspector/dist/assets/python-BuPzkPfP.js +0 -1
- package/inspector/dist/assets/q-pXgVlZs6.js +0 -1
- package/inspector/dist/assets/r-B6wPVr8A.js +0 -1
- package/inspector/dist/assets/rpm-CTu-6PCP.js +0 -1
- package/inspector/dist/assets/ruby-BK5aLJev.js +0 -1
- package/inspector/dist/assets/scheme-C41bIUwD.js +0 -1
- package/inspector/dist/assets/shell-CjFT_Tl9.js +0 -1
- package/inspector/dist/assets/sieve-C3Gn_uJK.js +0 -1
- package/inspector/dist/assets/simple-mode-GW_nhZxv.js +0 -1
- package/inspector/dist/assets/smalltalk-CnHTOXQT.js +0 -1
- package/inspector/dist/assets/solr-DehyRSwq.js +0 -1
- package/inspector/dist/assets/sparql-DkYu6x3z.js +0 -1
- package/inspector/dist/assets/spreadsheet-BCZA_wO0.js +0 -1
- package/inspector/dist/assets/sql-D0XecflT.js +0 -1
- package/inspector/dist/assets/stex-C3f8Ysf7.js +0 -1
- package/inspector/dist/assets/stylus-B533Al4x.js +0 -1
- package/inspector/dist/assets/swift-BzpIVaGY.js +0 -1
- package/inspector/dist/assets/tcl-DVfN8rqt.js +0 -1
- package/inspector/dist/assets/textile-CnDTJFAw.js +0 -1
- package/inspector/dist/assets/tiddlywiki-DO-Gjzrf.js +0 -1
- package/inspector/dist/assets/tiki-DGYXhP31.js +0 -1
- package/inspector/dist/assets/toml-Bm5Em-hy.js +0 -1
- package/inspector/dist/assets/troff-wAsdV37c.js +0 -1
- package/inspector/dist/assets/ttcn-CfJYG6tj.js +0 -1
- package/inspector/dist/assets/ttcn-cfg-B9xdYoR4.js +0 -1
- package/inspector/dist/assets/turtle-B1tBg_DP.js +0 -1
- package/inspector/dist/assets/vb-CmGdzxic.js +0 -1
- package/inspector/dist/assets/vbscript-BuJXcnF6.js +0 -1
- package/inspector/dist/assets/velocity-D8B20fx6.js +0 -1
- package/inspector/dist/assets/verilog-C6RDOZhf.js +0 -1
- package/inspector/dist/assets/vhdl-lSbBsy5d.js +0 -1
- package/inspector/dist/assets/webidl-ZXfAyPTL.js +0 -1
- package/inspector/dist/assets/xquery-DzFWVndE.js +0 -1
- package/inspector/dist/assets/yacas-BJ4BC0dw.js +0 -1
- package/inspector/dist/assets/z80-Hz9HOZM7.js +0 -1
package/dist/inspector/server.js
CHANGED
|
@@ -6,7 +6,7 @@ import { resolveProject } from "../config.js";
|
|
|
6
6
|
import { listRuns, getRun, readRunFile } from "./runs.js";
|
|
7
7
|
import { listWorkflows, getWorkflow } from "./workflows.js";
|
|
8
8
|
import { dockerStatus, triggerRun, stopRun } from "./runner.js";
|
|
9
|
-
import { cancelChat, createChat, deleteChat, disposeAllBackends, getChat, listChats, postMessage, resolvePermission, subscribeChat, } from "./chat/sessions.js";
|
|
9
|
+
import { cancelChat, createChat, deleteChat, disposeAllBackends, getChat, listChats, postMessage, resolvePermission, setChatVibeable, subscribeChat, } from "./chat/sessions.js";
|
|
10
10
|
import { bundleDetail, conceptDetail, createBundle, knowledgeIndex, putConcept, verifyFromUi, } from "./knowledge.js";
|
|
11
11
|
import { deleteAgent, getAgent, listAgents, saveAgent, setAgentArchived, agentsRoot, } from "./agents.js";
|
|
12
12
|
import { deleteAgentSkill, getSkill, listAgentSkills, listSkills, readSkill, saveAgentSkill, skillsRoot, } from "./skills.js";
|
|
@@ -14,6 +14,7 @@ import { discoverWorkspaces, forgetProject, listWorkspacesDetailed, markProjectS
|
|
|
14
14
|
import { gitCommit, gitDiff, gitFetch, gitPull, gitPush, gitStatus, startGitSync, } from "./git.js";
|
|
15
15
|
import { getSettings, saveSettings } from "./settings.js";
|
|
16
16
|
import { addRepo, listRepos, openRepos, removeRepo, updateRepo } from "./repos.js";
|
|
17
|
+
import { createVibeable, deleteVibeable, disposeAllDevs, listVibeables, openVibeables, resolveVibeable, serveVibeable, startDev, stopDev, subscribeVibeable, vibeableStatus, } from "./vibeables.js";
|
|
17
18
|
import { searchAgents } from "./search.js";
|
|
18
19
|
import { deleteRoutine, routineStatuses, runRoutineNow, saveRoutine, startRoutineScheduler, } from "./routines.js";
|
|
19
20
|
/**
|
|
@@ -219,6 +220,7 @@ async function handleApi(req, res, url) {
|
|
|
219
220
|
projectRootLabel: tildify(project?.root ?? getProjectRoot()),
|
|
220
221
|
git: (project?.config.git && project.config.git.enabled !== false) === true,
|
|
221
222
|
repos: (project?.config.repos && project.config.repos.enabled !== false) === true,
|
|
223
|
+
vibeables: (project?.config.vibeables && project.config.vibeables.enabled !== false) === true,
|
|
222
224
|
switcher,
|
|
223
225
|
});
|
|
224
226
|
}
|
|
@@ -273,6 +275,75 @@ async function handleApi(req, res, url) {
|
|
|
273
275
|
return json(res, { error: err.message }, 400);
|
|
274
276
|
}
|
|
275
277
|
}
|
|
278
|
+
// GET /api/vibeables — every app folder under the vibeables root | POST {name} — create one with the starter
|
|
279
|
+
if (seg.length === 2 && seg[1] === "vibeables") {
|
|
280
|
+
if (method === "GET")
|
|
281
|
+
return json(res, await listVibeables());
|
|
282
|
+
if (method === "POST") {
|
|
283
|
+
if ((await openVibeables()).off)
|
|
284
|
+
return json(res, { error: "vibeables are off" }, 409);
|
|
285
|
+
try {
|
|
286
|
+
const body = JSON.parse(await readBody(req));
|
|
287
|
+
return json(res, await createVibeable(typeof body.name === "string" ? body.name : ""), 201);
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
return json(res, { error: err.message }, 400);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
const vibeableError = (err) => {
|
|
295
|
+
const msg = err.message;
|
|
296
|
+
return [/^no vibeable/.test(msg) ? 404 : /are off/.test(msg) ? 409 : 400, { error: msg }];
|
|
297
|
+
};
|
|
298
|
+
// GET /api/vibeables/<slug> — how the app previews: mode, static url, dev server state | DELETE — remove the folder
|
|
299
|
+
if (seg.length === 3 && seg[1] === "vibeables") {
|
|
300
|
+
try {
|
|
301
|
+
if (method === "GET")
|
|
302
|
+
return json(res, await vibeableStatus(seg[2]));
|
|
303
|
+
if (method === "DELETE") {
|
|
304
|
+
await deleteVibeable(seg[2]);
|
|
305
|
+
return json(res, { ok: true });
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
catch (err) {
|
|
309
|
+
const [status, body] = vibeableError(err);
|
|
310
|
+
return json(res, body, status);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// GET /api/vibeables/<slug>/events — SSE: file changes (debounced) and dev-server state
|
|
314
|
+
if (seg.length === 4 && seg[1] === "vibeables" && seg[3] === "events" && method === "GET") {
|
|
315
|
+
let dir;
|
|
316
|
+
try {
|
|
317
|
+
dir = (await resolveVibeable(seg[2])).dir;
|
|
318
|
+
}
|
|
319
|
+
catch (err) {
|
|
320
|
+
const [status, body] = vibeableError(err);
|
|
321
|
+
return json(res, body, status);
|
|
322
|
+
}
|
|
323
|
+
res.writeHead(200, { "content-type": "text/event-stream", "cache-control": "no-store", connection: "keep-alive" });
|
|
324
|
+
res.write(":ok\n\n");
|
|
325
|
+
const unsubscribe = subscribeVibeable(seg[2], dir, (ev) => res.write(`data: ${JSON.stringify(ev)}\n\n`));
|
|
326
|
+
const heartbeat = setInterval(() => res.write(":hb\n\n"), 25_000);
|
|
327
|
+
req.on("close", () => {
|
|
328
|
+
clearInterval(heartbeat);
|
|
329
|
+
unsubscribe();
|
|
330
|
+
});
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
// POST /api/vibeables/<slug>/dev/{start,stop} — the app's dev command
|
|
334
|
+
if (seg.length === 5 && seg[1] === "vibeables" && seg[3] === "dev" && method === "POST") {
|
|
335
|
+
try {
|
|
336
|
+
if (seg[4] === "start")
|
|
337
|
+
return json(res, await startDev(seg[2]));
|
|
338
|
+
if (seg[4] === "stop")
|
|
339
|
+
return json(res, await stopDev(seg[2]));
|
|
340
|
+
return json(res, { error: "not found" }, 404);
|
|
341
|
+
}
|
|
342
|
+
catch (err) {
|
|
343
|
+
const [status, body] = vibeableError(err);
|
|
344
|
+
return json(res, body, status);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
276
347
|
// POST /api/repos/<slug>/update — fetch, fast-forward when clean
|
|
277
348
|
if (seg.length === 4 && seg[1] === "repos" && seg[3] === "update" && method === "POST") {
|
|
278
349
|
try {
|
|
@@ -380,6 +451,7 @@ async function handleApi(req, res, url) {
|
|
|
380
451
|
json(res, { ok: true });
|
|
381
452
|
setTimeout(() => {
|
|
382
453
|
disposeAllBackends();
|
|
454
|
+
disposeAllDevs();
|
|
383
455
|
process.exit(RESTART_EXIT_CODE);
|
|
384
456
|
}, 150);
|
|
385
457
|
return;
|
|
@@ -770,6 +842,18 @@ async function handleApi(req, res, url) {
|
|
|
770
842
|
});
|
|
771
843
|
return;
|
|
772
844
|
}
|
|
845
|
+
// POST /api/chats/:id/vibeable {slug | null} — open an app in the chat's preview pane (cwd follows), or close it
|
|
846
|
+
if (seg.length === 4 && seg[1] === "chats" && seg[3] === "vibeable" && method === "POST") {
|
|
847
|
+
try {
|
|
848
|
+
const body = JSON.parse((await readBody(req)) || "{}");
|
|
849
|
+
const slug = body.slug == null || body.slug === "" ? null : String(body.slug);
|
|
850
|
+
const result = await setChatVibeable(seg[2], slug);
|
|
851
|
+
return result.error ? json(res, { error: result.error }, result.status ?? 400) : json(res, result.meta);
|
|
852
|
+
}
|
|
853
|
+
catch (err) {
|
|
854
|
+
return json(res, { error: err.message }, 400);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
773
857
|
// POST /api/chats/:id/{message,permission,cancel}
|
|
774
858
|
if (seg.length === 4 && seg[1] === "chats" && method === "POST") {
|
|
775
859
|
let body = {};
|
|
@@ -840,6 +924,7 @@ export function startInspector(opts) {
|
|
|
840
924
|
for (const sig of ["SIGINT", "SIGTERM"]) {
|
|
841
925
|
process.once(sig, () => {
|
|
842
926
|
disposeAllBackends();
|
|
927
|
+
disposeAllDevs();
|
|
843
928
|
unregisterInstance();
|
|
844
929
|
markProjectStopped();
|
|
845
930
|
process.exit(sig === "SIGINT" ? 130 : 143);
|
|
@@ -847,6 +932,7 @@ export function startInspector(opts) {
|
|
|
847
932
|
}
|
|
848
933
|
process.once("exit", (code) => {
|
|
849
934
|
disposeAllBackends();
|
|
935
|
+
disposeAllDevs();
|
|
850
936
|
unregisterInstance();
|
|
851
937
|
// A self-restart (new version) is not a stop — the project stays "running".
|
|
852
938
|
if (code !== RESTART_EXIT_CODE)
|
|
@@ -859,6 +945,9 @@ export function startInspector(opts) {
|
|
|
859
945
|
return json(res, { error: "unexpected Host header" }, 421);
|
|
860
946
|
if (url.pathname.startsWith("/api/"))
|
|
861
947
|
await handleApi(req, res, url);
|
|
948
|
+
// /vibeables/<slug>/… is an app's own files, served for the preview pane.
|
|
949
|
+
else if (url.pathname === "/vibeables" || url.pathname.startsWith("/vibeables/"))
|
|
950
|
+
await serveVibeable(req, res, url);
|
|
862
951
|
else
|
|
863
952
|
await serveStatic(res, opts.staticDir, url.pathname);
|
|
864
953
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ProjectConfig, type SwitcherEntry } from "../config.js";
|
|
2
2
|
/**
|
|
3
3
|
* Workspace settings: read kraftwerk.yml for the UI and write the
|
|
4
|
-
* UI-editable subset (name, icon, switcher, git, repos) back. Edits go through the
|
|
4
|
+
* UI-editable subset (name, icon, switcher, git, repos, vibeables) back. Edits go through the
|
|
5
5
|
* yaml Document API so comments and every other key survive untouched;
|
|
6
6
|
* a missing kraftwerk.yml is created at the project root on first save.
|
|
7
7
|
*/
|
|
@@ -28,6 +28,8 @@ export interface SaveSettingsInput {
|
|
|
28
28
|
git?: GitSettingsInput;
|
|
29
29
|
/** Omitted = untouched. Same rules as git: off with defaults = no block. */
|
|
30
30
|
repos?: ReposSettingsInput;
|
|
31
|
+
/** Omitted = untouched. Same shape and rules as repos. */
|
|
32
|
+
vibeables?: ReposSettingsInput;
|
|
31
33
|
}
|
|
32
34
|
export interface ReposSettingsInput {
|
|
33
35
|
enabled: boolean;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { promises as fs } from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { parseDocument } from "yaml";
|
|
4
|
-
import { ignoreEntryFor, REPOS_DEFAULT_ROOT, resolveProject } from "../config.js";
|
|
4
|
+
import { ignoreEntryFor, REPOS_DEFAULT_ROOT, resolveProject, VIBEABLES_DEFAULT_ROOT } from "../config.js";
|
|
5
|
+
import { ensureVibeablesRoot } from "./vibeables.js";
|
|
5
6
|
import { getProjectRoot } from "./context.js";
|
|
6
7
|
import { ensureReposRoot } from "./repos.js";
|
|
7
8
|
const GIT_DEFAULTS = { remote: "origin", interval: 300, autosync: "pull" };
|
|
@@ -70,18 +71,19 @@ function cleanGit(value) {
|
|
|
70
71
|
return null;
|
|
71
72
|
return { enabled: false, ...out };
|
|
72
73
|
}
|
|
73
|
-
/** The repos block to write; null when the feature is off and nothing else is set. */
|
|
74
|
-
function
|
|
74
|
+
/** The repos or vibeables block to write; null when the feature is off and nothing else is set. */
|
|
75
|
+
function cleanRootBlock(block, value, projectRoot) {
|
|
75
76
|
if (typeof value !== "object" || value === null)
|
|
76
|
-
throw new Error(
|
|
77
|
+
throw new Error(`${block} must be an object`);
|
|
77
78
|
if (typeof value.enabled !== "boolean")
|
|
78
|
-
throw new Error(
|
|
79
|
+
throw new Error(`${block}.enabled must be true or false`);
|
|
79
80
|
const out = {};
|
|
80
81
|
const root = typeof value.root === "string" ? value.root.trim().replace(/\/+$/, "") : "";
|
|
81
82
|
if (root && !ignoreEntryFor(projectRoot, root)) {
|
|
82
|
-
throw new Error(
|
|
83
|
+
throw new Error(`${block}.root must be a directory inside the project (not ".", ".." or an absolute path outside it)`);
|
|
83
84
|
}
|
|
84
|
-
|
|
85
|
+
const dflt = block === "repos" ? REPOS_DEFAULT_ROOT : VIBEABLES_DEFAULT_ROOT;
|
|
86
|
+
if (root && root !== dflt)
|
|
85
87
|
out.root = root;
|
|
86
88
|
if (value.enabled)
|
|
87
89
|
return out;
|
|
@@ -128,16 +130,25 @@ export async function saveSettings(input) {
|
|
|
128
130
|
doc.set("git", git);
|
|
129
131
|
}
|
|
130
132
|
if (input.repos !== undefined) {
|
|
131
|
-
const repos =
|
|
133
|
+
const repos = cleanRootBlock("repos", input.repos, project.root);
|
|
132
134
|
if (repos === null)
|
|
133
135
|
doc.delete("repos");
|
|
134
136
|
else
|
|
135
137
|
doc.set("repos", repos);
|
|
136
138
|
}
|
|
139
|
+
if (input.vibeables !== undefined) {
|
|
140
|
+
const vibeables = cleanRootBlock("vibeables", input.vibeables, project.root);
|
|
141
|
+
if (vibeables === null)
|
|
142
|
+
doc.delete("vibeables");
|
|
143
|
+
else
|
|
144
|
+
doc.set("vibeables", vibeables);
|
|
145
|
+
}
|
|
137
146
|
await fs.writeFile(configPath, doc.toString());
|
|
138
147
|
// Turning repositories on prepares the folder so the first clone and the
|
|
139
148
|
// workspace git both find it in the right state.
|
|
140
149
|
if (input.repos?.enabled)
|
|
141
150
|
await ensureReposRoot().catch(() => { });
|
|
151
|
+
if (input.vibeables?.enabled)
|
|
152
|
+
await ensureVibeablesRoot().catch(() => { });
|
|
142
153
|
return getSettings();
|
|
143
154
|
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import { type Project } from "../config.js";
|
|
3
|
+
/**
|
|
4
|
+
* Vibeables: small applications built live in a chat. The agent edits the
|
|
5
|
+
* folder, the user watches the result in a preview pane next to the thread
|
|
6
|
+
* — lovable-style, but for whatever ad-hoc software the user needs: a
|
|
7
|
+
* dashboard, a slideshow, a tracker with its own backend.
|
|
8
|
+
*
|
|
9
|
+
* A vibeable is one folder under the vibeables root (`vibeables.root` in
|
|
10
|
+
* kraftwerk.yml, default kraftwerk-data/vibeables/). Like agents and knowledge it is part
|
|
11
|
+
* of the workspace: versioned by the workspace git, no repository of its
|
|
12
|
+
* own. The folder is the registry — whatever directory is under the root
|
|
13
|
+
* is a vibeable, whoever created it.
|
|
14
|
+
*
|
|
15
|
+
* Two ways to run one, chosen by the folder itself:
|
|
16
|
+
*
|
|
17
|
+
* - static (default): the inspector serves the folder at /vibeables/<slug>/
|
|
18
|
+
* — index.html in, no build step. A file watcher tells the pane to reload.
|
|
19
|
+
* - dev: `vibeable.yml` names a `dev` command (npm run dev, node server.js).
|
|
20
|
+
* The inspector spawns it with PORT set and the pane embeds that server;
|
|
21
|
+
* anything with a build tool, a backend or a database lives here.
|
|
22
|
+
*
|
|
23
|
+
* Static files go out under a CSP sandbox: the code is what the agent
|
|
24
|
+
* wrote, and it must not act on the inspector API as the user. Nothing here
|
|
25
|
+
* has a shell in the middle except the dev command, which is the user's own
|
|
26
|
+
* choice in their own workspace.
|
|
27
|
+
*/
|
|
28
|
+
export interface VibeableConfig {
|
|
29
|
+
/** Command that starts a dev server; gets PORT in its environment. */
|
|
30
|
+
dev?: string;
|
|
31
|
+
/** Port the dev command listens on. Default: a free port, passed as PORT. */
|
|
32
|
+
port?: number;
|
|
33
|
+
/** Folder served in static mode, relative to the vibeable. Default: the vibeable itself. */
|
|
34
|
+
dir?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface VibeableInfo {
|
|
37
|
+
/** Folder name under the root; the id everywhere. */
|
|
38
|
+
slug: string;
|
|
39
|
+
/** Absolute path of the folder. */
|
|
40
|
+
path: string;
|
|
41
|
+
/** index.html exists in the served folder, so the static preview renders something. */
|
|
42
|
+
hasIndex: boolean;
|
|
43
|
+
/** Dev command from vibeable.yml, when declared. */
|
|
44
|
+
dev?: string;
|
|
45
|
+
/** Set when vibeable.yml exists but is unusable. */
|
|
46
|
+
configError?: string;
|
|
47
|
+
/** Newest change inside the folder (node_modules and dot entries excluded). */
|
|
48
|
+
updatedAt?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface VibeablesView {
|
|
51
|
+
enabled: boolean;
|
|
52
|
+
root?: string;
|
|
53
|
+
vibeables: VibeableInfo[];
|
|
54
|
+
/** Set when the feature is off or the root cannot be read. */
|
|
55
|
+
error?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface VibeableDev {
|
|
58
|
+
command: string;
|
|
59
|
+
port: number;
|
|
60
|
+
/** The process is alive. */
|
|
61
|
+
running: boolean;
|
|
62
|
+
/** The server answered HTTP on its port. */
|
|
63
|
+
ready: boolean;
|
|
64
|
+
pid?: number;
|
|
65
|
+
startedAt: string;
|
|
66
|
+
/** Set once the process ended. */
|
|
67
|
+
exitCode?: number | null;
|
|
68
|
+
/** Last lines of stdout + stderr. */
|
|
69
|
+
log: string[];
|
|
70
|
+
}
|
|
71
|
+
export interface VibeableStatus {
|
|
72
|
+
slug: string;
|
|
73
|
+
/** Absolute folder path. */
|
|
74
|
+
path: string;
|
|
75
|
+
/** Absolute folder served in static mode. */
|
|
76
|
+
dir: string;
|
|
77
|
+
/** What the pane shows right now: the dev server once it runs, the static folder otherwise. */
|
|
78
|
+
mode: "static" | "dev";
|
|
79
|
+
/** Static preview url, relative to the inspector. */
|
|
80
|
+
url: string;
|
|
81
|
+
config: VibeableConfig;
|
|
82
|
+
/** Set when vibeable.yml exists but is unusable; static mode still works. */
|
|
83
|
+
configError?: string;
|
|
84
|
+
dev?: VibeableDev;
|
|
85
|
+
}
|
|
86
|
+
export type VibeableEvent = {
|
|
87
|
+
type: "change";
|
|
88
|
+
files: string[];
|
|
89
|
+
} | {
|
|
90
|
+
type: "dev";
|
|
91
|
+
dev: VibeableDev;
|
|
92
|
+
} | {
|
|
93
|
+
type: "error";
|
|
94
|
+
message: string;
|
|
95
|
+
};
|
|
96
|
+
export declare const VIBEABLE_CONFIG_FILE = "vibeable.yml";
|
|
97
|
+
export declare function safeVibeableSlug(slug: string): string;
|
|
98
|
+
/** The files a fresh vibeable starts with: a page that renders, and the config template. */
|
|
99
|
+
export declare function vibeableStarter(name: string): Record<string, string>;
|
|
100
|
+
/** Resolve the project and its vibeables block. `off` when the feature is not on. */
|
|
101
|
+
export declare function openVibeables(): Promise<{
|
|
102
|
+
project?: Project;
|
|
103
|
+
root?: string;
|
|
104
|
+
off?: boolean;
|
|
105
|
+
error?: string;
|
|
106
|
+
}>;
|
|
107
|
+
/** Make sure the root exists; runs when the feature is switched on. */
|
|
108
|
+
export declare function ensureVibeablesRoot(): Promise<void>;
|
|
109
|
+
interface Resolved {
|
|
110
|
+
slug: string;
|
|
111
|
+
dir: string;
|
|
112
|
+
servedDir: string;
|
|
113
|
+
config: VibeableConfig;
|
|
114
|
+
configError?: string;
|
|
115
|
+
}
|
|
116
|
+
/** The folder behind a slug, or throw `no vibeable "<slug>"`. */
|
|
117
|
+
export declare function resolveVibeable(slug: string): Promise<Resolved>;
|
|
118
|
+
/** Every folder under the root, alphabetically. Dot folders and odd names are skipped. */
|
|
119
|
+
export declare function listVibeables(): Promise<VibeablesView>;
|
|
120
|
+
/**
|
|
121
|
+
* Create <root>/<name> with the starter files. The folder is claimed with a
|
|
122
|
+
* plain mkdir first: it fails when anything is there already, so two
|
|
123
|
+
* creates of the same name cannot both win.
|
|
124
|
+
*/
|
|
125
|
+
export declare function createVibeable(name: string): Promise<VibeableInfo>;
|
|
126
|
+
/** Delete a vibeable folder. Its history stays in the workspace git. */
|
|
127
|
+
export declare function deleteVibeable(slug: string): Promise<void>;
|
|
128
|
+
export declare function vibeableStatus(slug: string): Promise<VibeableStatus>;
|
|
129
|
+
/**
|
|
130
|
+
* GET /vibeables/<slug>/<file>. Dot segments (.env, .git) are never served;
|
|
131
|
+
* a directory answers with its index.html, and a directory url without the
|
|
132
|
+
* trailing slash redirects so the page's relative links resolve.
|
|
133
|
+
*/
|
|
134
|
+
export declare function serveVibeable(req: http.IncomingMessage, res: http.ServerResponse, url: URL): Promise<void>;
|
|
135
|
+
/**
|
|
136
|
+
* Stream a vibeable's events: file changes (debounced, node_modules and
|
|
137
|
+
* the like excluded) and dev-server state. The watcher exists while
|
|
138
|
+
* someone listens. `fs.watch` recursive covers macOS and Linux on Node 20+;
|
|
139
|
+
* where it cannot watch, the pane still has its manual reload.
|
|
140
|
+
*/
|
|
141
|
+
export declare function subscribeVibeable(slug: string, dir: string, fn: (ev: VibeableEvent) => void): () => void;
|
|
142
|
+
/**
|
|
143
|
+
* Start the vibeable's dev command. Idempotent while it runs. The child
|
|
144
|
+
* leads its own process group so stopping it also stops what it spawned
|
|
145
|
+
* (npm → vite → esbuild).
|
|
146
|
+
*/
|
|
147
|
+
export declare function startDev(slug: string): Promise<VibeableStatus>;
|
|
148
|
+
/** SIGTERM the dev process group, SIGKILL what is still there after 3 s. */
|
|
149
|
+
export declare function stopDev(slug: string): Promise<VibeableStatus>;
|
|
150
|
+
/** Server shutdown: no dev server may outlive the inspector. */
|
|
151
|
+
export declare function disposeAllDevs(): void;
|
|
152
|
+
export {};
|