dsh-tiddlywiki 0.6.0 → 0.7.2
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/lib/index.js +176 -2
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/host/config.ts +7 -0
- package/src/host/routes.ts +145 -0
- package/src/index.ts +14 -3
package/lib/index.js
CHANGED
|
@@ -852,6 +852,151 @@ function registerRoutes(ctx, deps) {
|
|
|
852
852
|
ui: deps.uiDefaults()
|
|
853
853
|
});
|
|
854
854
|
};
|
|
855
|
+
/**
|
|
856
|
+
* GET /dsh-tiddlywiki/agent/sessions — visible ordinary sessions for the TW
|
|
857
|
+
* one-click picker (excludes subagent sessions, activity-descending).
|
|
858
|
+
*/
|
|
859
|
+
const handleAgentSessions = async (_req, res) => {
|
|
860
|
+
try {
|
|
861
|
+
const sc = deps.getSessionController();
|
|
862
|
+
if (sc === void 0) {
|
|
863
|
+
json$1(res, {
|
|
864
|
+
ok: false,
|
|
865
|
+
error: "session service unavailable"
|
|
866
|
+
}, 503);
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
json$1(res, {
|
|
870
|
+
ok: true,
|
|
871
|
+
items: ((await sc.list({}, AbortSignal.timeout(1e4))).items ?? []).filter((s) => s.parentSessionId === void 0).map((s) => ({
|
|
872
|
+
sessionId: s.sessionId,
|
|
873
|
+
cwd: s.cwd ?? null,
|
|
874
|
+
running: !!s.running,
|
|
875
|
+
blank: !!s.blank,
|
|
876
|
+
updatedAt: s.updatedAt ?? 0
|
|
877
|
+
})).sort((a, b) => b.updatedAt - a.updatedAt)
|
|
878
|
+
});
|
|
879
|
+
} catch (err) {
|
|
880
|
+
json$1(res, {
|
|
881
|
+
ok: false,
|
|
882
|
+
error: err instanceof Error ? err.message : String(err)
|
|
883
|
+
}, 500);
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
/**
|
|
887
|
+
* POST /dsh-tiddlywiki/agent/send — deliver a note to one agent session as a
|
|
888
|
+
* queued user message (sessionController.prompt, the same API the GUI chat
|
|
889
|
+
* input uses). Guards: feature switch, optional shared token, body shape.
|
|
890
|
+
*/
|
|
891
|
+
const handleAgentSend = async (req, res) => {
|
|
892
|
+
try {
|
|
893
|
+
if (!deps.sendToAgentEnabled()) {
|
|
894
|
+
json$1(res, {
|
|
895
|
+
ok: false,
|
|
896
|
+
error: "send-to-agent is disabled"
|
|
897
|
+
}, 403);
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
900
|
+
const token = deps.sendToAgentToken().trim();
|
|
901
|
+
if (token.length > 0) {
|
|
902
|
+
const got = req.headers["x-send-to-agent-token"];
|
|
903
|
+
if ((typeof got === "string" ? got : Array.isArray(got) ? got[0] ?? "" : "") !== token) {
|
|
904
|
+
json$1(res, {
|
|
905
|
+
ok: false,
|
|
906
|
+
error: "unauthorized"
|
|
907
|
+
}, 401);
|
|
908
|
+
return;
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
const body = JSON.parse(await readBody$1(req));
|
|
912
|
+
const sessionId = typeof body.sessionId === "string" && body.sessionId.trim().length > 0 ? body.sessionId.trim() : "";
|
|
913
|
+
const text = typeof body.text === "string" && body.text.trim().length > 0 ? body.text.trim() : "";
|
|
914
|
+
if (sessionId.length === 0 || text.length === 0) {
|
|
915
|
+
json$1(res, {
|
|
916
|
+
ok: false,
|
|
917
|
+
error: "sessionId and text are required"
|
|
918
|
+
}, 400);
|
|
919
|
+
return;
|
|
920
|
+
}
|
|
921
|
+
const sc = deps.getSessionController();
|
|
922
|
+
if (sc === void 0) {
|
|
923
|
+
json$1(res, {
|
|
924
|
+
ok: false,
|
|
925
|
+
error: "session service unavailable"
|
|
926
|
+
}, 503);
|
|
927
|
+
return;
|
|
928
|
+
}
|
|
929
|
+
const requestId = `tw-send-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
|
930
|
+
await sc.prompt({
|
|
931
|
+
requestId,
|
|
932
|
+
sessionId,
|
|
933
|
+
mode: "queue",
|
|
934
|
+
content: [{
|
|
935
|
+
type: "text",
|
|
936
|
+
text
|
|
937
|
+
}]
|
|
938
|
+
}, AbortSignal.timeout(2e4));
|
|
939
|
+
json$1(res, {
|
|
940
|
+
ok: true,
|
|
941
|
+
requestId,
|
|
942
|
+
sessionId
|
|
943
|
+
});
|
|
944
|
+
} catch (err) {
|
|
945
|
+
json$1(res, {
|
|
946
|
+
ok: false,
|
|
947
|
+
error: err instanceof Error ? err.message : String(err)
|
|
948
|
+
}, 500);
|
|
949
|
+
}
|
|
950
|
+
};
|
|
951
|
+
/**
|
|
952
|
+
* POST /dsh-tiddlywiki/agent/create — create (or adopt) one ordinary session,
|
|
953
|
+
* optionally inside a workspace path. The picker uses it for "new workspace /
|
|
954
|
+
* new session"; the created session's cwd becomes its workspace. The directory
|
|
955
|
+
* is materialised so a brand-new workspace actually exists on disk.
|
|
956
|
+
*/
|
|
957
|
+
const handleAgentCreate = async (req, res) => {
|
|
958
|
+
try {
|
|
959
|
+
if (!deps.sendToAgentEnabled()) {
|
|
960
|
+
json$1(res, {
|
|
961
|
+
ok: false,
|
|
962
|
+
error: "send-to-agent is disabled"
|
|
963
|
+
}, 403);
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
966
|
+
const token = deps.sendToAgentToken().trim();
|
|
967
|
+
if (token.length > 0) {
|
|
968
|
+
const got = req.headers["x-send-to-agent-token"];
|
|
969
|
+
if ((typeof got === "string" ? got : Array.isArray(got) ? got[0] ?? "" : "") !== token) {
|
|
970
|
+
json$1(res, {
|
|
971
|
+
ok: false,
|
|
972
|
+
error: "unauthorized"
|
|
973
|
+
}, 401);
|
|
974
|
+
return;
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
const body = JSON.parse(await readBody$1(req));
|
|
978
|
+
const cwd = typeof body.cwd === "string" ? body.cwd.trim() : "";
|
|
979
|
+
const sc = deps.getSessionController();
|
|
980
|
+
if (sc === void 0) {
|
|
981
|
+
json$1(res, {
|
|
982
|
+
ok: false,
|
|
983
|
+
error: "session service unavailable"
|
|
984
|
+
}, 503);
|
|
985
|
+
return;
|
|
986
|
+
}
|
|
987
|
+
if (cwd.length > 0) await mkdir(cwd, { recursive: true });
|
|
988
|
+
json$1(res, {
|
|
989
|
+
ok: true,
|
|
990
|
+
sessionId: (await sc.create({ cwd: cwd.length > 0 ? cwd : void 0 })).sessionId,
|
|
991
|
+
cwd: cwd || null
|
|
992
|
+
});
|
|
993
|
+
} catch (err) {
|
|
994
|
+
json$1(res, {
|
|
995
|
+
ok: false,
|
|
996
|
+
error: err instanceof Error ? err.message : String(err)
|
|
997
|
+
}, 500);
|
|
998
|
+
}
|
|
999
|
+
};
|
|
855
1000
|
const handleNote = async (req, res) => {
|
|
856
1001
|
try {
|
|
857
1002
|
const body = JSON.parse(await readBody$1(req));
|
|
@@ -1311,6 +1456,27 @@ function registerRoutes(ctx, deps) {
|
|
|
1311
1456
|
handleRestart(req, res);
|
|
1312
1457
|
}
|
|
1313
1458
|
}),
|
|
1459
|
+
ctx.webServer.register({
|
|
1460
|
+
kind: "exact",
|
|
1461
|
+
path: `${ROUTE_PREFIX}/agent/sessions`,
|
|
1462
|
+
handler: (req, res) => {
|
|
1463
|
+
handleAgentSessions(req, res);
|
|
1464
|
+
}
|
|
1465
|
+
}),
|
|
1466
|
+
ctx.webServer.register({
|
|
1467
|
+
kind: "exact",
|
|
1468
|
+
path: `${ROUTE_PREFIX}/agent/send`,
|
|
1469
|
+
handler: (req, res) => {
|
|
1470
|
+
handleAgentSend(req, res);
|
|
1471
|
+
}
|
|
1472
|
+
}),
|
|
1473
|
+
ctx.webServer.register({
|
|
1474
|
+
kind: "exact",
|
|
1475
|
+
path: `${ROUTE_PREFIX}/agent/create`,
|
|
1476
|
+
handler: (req, res) => {
|
|
1477
|
+
handleAgentCreate(req, res);
|
|
1478
|
+
}
|
|
1479
|
+
}),
|
|
1314
1480
|
ctx.webServer.register({
|
|
1315
1481
|
kind: "prefix",
|
|
1316
1482
|
path: `${ROUTE_PREFIX}/api`,
|
|
@@ -2924,7 +3090,8 @@ const DEFAULTS = {
|
|
|
2924
3090
|
ui: {
|
|
2925
3091
|
showQuickNote: true,
|
|
2926
3092
|
showPanelStatus: true,
|
|
2927
|
-
showSyncButton: true
|
|
3093
|
+
showSyncButton: true,
|
|
3094
|
+
sendToAgent: { enabled: true }
|
|
2928
3095
|
},
|
|
2929
3096
|
auth: {
|
|
2930
3097
|
username: "",
|
|
@@ -3164,6 +3331,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
3164
3331
|
})();
|
|
3165
3332
|
ctx.inject(["webServer"], (webCtx) => {
|
|
3166
3333
|
const ws = webCtx.webServer;
|
|
3334
|
+
const getSessionController = () => ctx.get("sessionController");
|
|
3167
3335
|
const disposeRoutes = registerRoutes({ webServer: ws }, {
|
|
3168
3336
|
server,
|
|
3169
3337
|
getClient: client,
|
|
@@ -3171,7 +3339,13 @@ function apply(ctx, rawConfig = {}) {
|
|
|
3171
3339
|
autoCommit: () => committer?.touch(),
|
|
3172
3340
|
noteDefaults: () => ({ tag: effectiveNoteTag() }),
|
|
3173
3341
|
uiDefaults: () => effectiveUi(),
|
|
3174
|
-
getWikiPath: () => wikiPath
|
|
3342
|
+
getWikiPath: () => wikiPath,
|
|
3343
|
+
getSessionController,
|
|
3344
|
+
sendToAgentEnabled: () => eff().ui?.sendToAgent?.enabled !== false,
|
|
3345
|
+
sendToAgentToken: () => {
|
|
3346
|
+
const token = eff().ui?.sendToAgent?.token;
|
|
3347
|
+
return typeof token === "string" ? token : "";
|
|
3348
|
+
}
|
|
3175
3349
|
});
|
|
3176
3350
|
const disposeAdmin = registerAdminRoutes({ webServer: ws }, {
|
|
3177
3351
|
server,
|