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 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,