dominds 1.9.1 → 1.9.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/dist/llm/kernel-driver/subdialog.d.ts +2 -0
- package/dist/llm/kernel-driver/subdialog.js +9 -4
- package/dist/llm/kernel-driver/tellask-special.js +1 -0
- package/dist/persistence.js +31 -16
- package/dist/priming.js +32 -12
- package/dist/server/api-routes.js +212 -89
- package/dist/server/auth.d.ts +1 -0
- package/dist/server/auth.js +21 -0
- package/dist/server/server-core.js +15 -0
- package/package.json +1 -1
- package/webapp/dist/assets/{_basePickBy-BCSeQ8Mb.js → _basePickBy-9Z1lbVTN.js} +3 -3
- package/webapp/dist/assets/{_basePickBy-BCSeQ8Mb.js.map → _basePickBy-9Z1lbVTN.js.map} +1 -1
- package/webapp/dist/assets/{_baseUniq-B5WIJgde.js → _baseUniq-C3pRnD57.js} +2 -2
- package/webapp/dist/assets/{_baseUniq-B5WIJgde.js.map → _baseUniq-C3pRnD57.js.map} +1 -1
- package/webapp/dist/assets/{arc-CWDgoT74.js → arc-BvNng3O_.js} +2 -2
- package/webapp/dist/assets/{arc-CWDgoT74.js.map → arc-BvNng3O_.js.map} +1 -1
- package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-DFdZI4Uu.js → architectureDiagram-2XIMDMQ5-BF8vwQ4e.js} +7 -7
- package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-DFdZI4Uu.js.map → architectureDiagram-2XIMDMQ5-BF8vwQ4e.js.map} +1 -1
- package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-DRcKQf9Q.js → blockDiagram-WCTKOSBZ-C7kfjZhf.js} +7 -7
- package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-DRcKQf9Q.js.map → blockDiagram-WCTKOSBZ-C7kfjZhf.js.map} +1 -1
- package/webapp/dist/assets/{c4Diagram-IC4MRINW-B0AMlCwV.js → c4Diagram-IC4MRINW-CaJ6bX75.js} +3 -3
- package/webapp/dist/assets/{c4Diagram-IC4MRINW-B0AMlCwV.js.map → c4Diagram-IC4MRINW-CaJ6bX75.js.map} +1 -1
- package/webapp/dist/assets/{channel-B0ljx2su.js → channel-DDuIUO0R.js} +2 -2
- package/webapp/dist/assets/{channel-B0ljx2su.js.map → channel-DDuIUO0R.js.map} +1 -1
- package/webapp/dist/assets/{chunk-4BX2VUAB-DbKTqY07.js → chunk-4BX2VUAB-BQPkQh6v.js} +2 -2
- package/webapp/dist/assets/{chunk-4BX2VUAB-DbKTqY07.js.map → chunk-4BX2VUAB-BQPkQh6v.js.map} +1 -1
- package/webapp/dist/assets/{chunk-55IACEB6-DwJgszOl.js → chunk-55IACEB6-C2eZTkZ1.js} +2 -2
- package/webapp/dist/assets/{chunk-55IACEB6-DwJgszOl.js.map → chunk-55IACEB6-C2eZTkZ1.js.map} +1 -1
- package/webapp/dist/assets/{chunk-FMBD7UC4-BzUcOjMH.js → chunk-FMBD7UC4-aXp5zApD.js} +2 -2
- package/webapp/dist/assets/{chunk-FMBD7UC4-BzUcOjMH.js.map → chunk-FMBD7UC4-aXp5zApD.js.map} +1 -1
- package/webapp/dist/assets/{chunk-JSJVCQXG-B-adw7iw.js → chunk-JSJVCQXG-DXyaccrz.js} +2 -2
- package/webapp/dist/assets/{chunk-JSJVCQXG-B-adw7iw.js.map → chunk-JSJVCQXG-DXyaccrz.js.map} +1 -1
- package/webapp/dist/assets/{chunk-KX2RTZJC-a1S8VCMi.js → chunk-KX2RTZJC-C-u000c0.js} +2 -2
- package/webapp/dist/assets/{chunk-KX2RTZJC-a1S8VCMi.js.map → chunk-KX2RTZJC-C-u000c0.js.map} +1 -1
- package/webapp/dist/assets/{chunk-NQ4KR5QH-BkpgGRb2.js → chunk-NQ4KR5QH-BoYRoo4A.js} +4 -4
- package/webapp/dist/assets/{chunk-NQ4KR5QH-BkpgGRb2.js.map → chunk-NQ4KR5QH-BoYRoo4A.js.map} +1 -1
- package/webapp/dist/assets/{chunk-QZHKN3VN-BzG0M8E7.js → chunk-QZHKN3VN-BAc_2ceG.js} +2 -2
- package/webapp/dist/assets/{chunk-QZHKN3VN-BzG0M8E7.js.map → chunk-QZHKN3VN-BAc_2ceG.js.map} +1 -1
- package/webapp/dist/assets/{chunk-WL4C6EOR-Jdr3sqWq.js → chunk-WL4C6EOR-D6ws69Jx.js} +6 -6
- package/webapp/dist/assets/{chunk-WL4C6EOR-Jdr3sqWq.js.map → chunk-WL4C6EOR-D6ws69Jx.js.map} +1 -1
- package/webapp/dist/assets/{classDiagram-VBA2DB6C-Bgs-IGF1.js → classDiagram-VBA2DB6C-BIRrKhqs.js} +7 -7
- package/webapp/dist/assets/{classDiagram-VBA2DB6C-Bgs-IGF1.js.map → classDiagram-VBA2DB6C-BIRrKhqs.js.map} +1 -1
- package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-Bgs-IGF1.js → classDiagram-v2-RAHNMMFH-BIRrKhqs.js} +7 -7
- package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-Bgs-IGF1.js.map → classDiagram-v2-RAHNMMFH-BIRrKhqs.js.map} +1 -1
- package/webapp/dist/assets/{clone-8W6qtrsz.js → clone-DweFyVW6.js} +2 -2
- package/webapp/dist/assets/{clone-8W6qtrsz.js.map → clone-DweFyVW6.js.map} +1 -1
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-gwXVRMa3.js → cose-bilkent-S5V4N54A-vgovmGKM.js} +2 -2
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-gwXVRMa3.js.map → cose-bilkent-S5V4N54A-vgovmGKM.js.map} +1 -1
- package/webapp/dist/assets/{dagre-KLK3FWXG-CgLK6cUW.js → dagre-KLK3FWXG-B-Ax3qBf.js} +7 -7
- package/webapp/dist/assets/{dagre-KLK3FWXG-CgLK6cUW.js.map → dagre-KLK3FWXG-B-Ax3qBf.js.map} +1 -1
- package/webapp/dist/assets/{diagram-E7M64L7V-BUDea9FM.js → diagram-E7M64L7V-B1sUlvtn.js} +8 -8
- package/webapp/dist/assets/{diagram-E7M64L7V-BUDea9FM.js.map → diagram-E7M64L7V-B1sUlvtn.js.map} +1 -1
- package/webapp/dist/assets/{diagram-IFDJBPK2-CiVS6fbK.js → diagram-IFDJBPK2-3IlyK_xp.js} +7 -7
- package/webapp/dist/assets/{diagram-IFDJBPK2-CiVS6fbK.js.map → diagram-IFDJBPK2-3IlyK_xp.js.map} +1 -1
- package/webapp/dist/assets/{diagram-P4PSJMXO-DpYGO4Wi.js → diagram-P4PSJMXO-C3x0JkgF.js} +7 -7
- package/webapp/dist/assets/{diagram-P4PSJMXO-DpYGO4Wi.js.map → diagram-P4PSJMXO-C3x0JkgF.js.map} +1 -1
- package/webapp/dist/assets/{erDiagram-INFDFZHY-Cz1TI05E.js → erDiagram-INFDFZHY-mEp6kC6i.js} +5 -5
- package/webapp/dist/assets/{erDiagram-INFDFZHY-Cz1TI05E.js.map → erDiagram-INFDFZHY-mEp6kC6i.js.map} +1 -1
- package/webapp/dist/assets/{flowDiagram-PKNHOUZH-CxjVowsG.js → flowDiagram-PKNHOUZH-AsG_wdLN.js} +7 -7
- package/webapp/dist/assets/{flowDiagram-PKNHOUZH-CxjVowsG.js.map → flowDiagram-PKNHOUZH-AsG_wdLN.js.map} +1 -1
- package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-C3t2AHs5.js → ganttDiagram-A5KZAMGK-zv3UhEAO.js} +3 -3
- package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-C3t2AHs5.js.map → ganttDiagram-A5KZAMGK-zv3UhEAO.js.map} +1 -1
- package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-D3Fz3qNA.js → gitGraphDiagram-K3NZZRJ6-C1yyISy7.js} +8 -8
- package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-D3Fz3qNA.js.map → gitGraphDiagram-K3NZZRJ6-C1yyISy7.js.map} +1 -1
- package/webapp/dist/assets/{graph-DEeBvsT_.js → graph-CkQycYq_.js} +3 -3
- package/webapp/dist/assets/{graph-DEeBvsT_.js.map → graph-CkQycYq_.js.map} +1 -1
- package/webapp/dist/assets/{index-D-SgXZTb.js → index-CCGi5dDE.js} +969 -260
- package/webapp/dist/assets/{index-D-SgXZTb.js.map → index-CCGi5dDE.js.map} +1 -1
- package/webapp/dist/assets/{infoDiagram-LFFYTUFH-CcsQeBG4.js → infoDiagram-LFFYTUFH-Dw1wAgpl.js} +6 -6
- package/webapp/dist/assets/{infoDiagram-LFFYTUFH-CcsQeBG4.js.map → infoDiagram-LFFYTUFH-Dw1wAgpl.js.map} +1 -1
- package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-CAV8iv45.js → ishikawaDiagram-PHBUUO56-DY9fHLYz.js} +2 -2
- package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-CAV8iv45.js.map → ishikawaDiagram-PHBUUO56-DY9fHLYz.js.map} +1 -1
- package/webapp/dist/assets/{journeyDiagram-4ABVD52K-C_mKL3Wf.js → journeyDiagram-4ABVD52K-CSGjRykr.js} +5 -5
- package/webapp/dist/assets/{journeyDiagram-4ABVD52K-C_mKL3Wf.js.map → journeyDiagram-4ABVD52K-CSGjRykr.js.map} +1 -1
- package/webapp/dist/assets/{kanban-definition-K7BYSVSG-Ptg6jh3y.js → kanban-definition-K7BYSVSG-DDCQetMc.js} +3 -3
- package/webapp/dist/assets/{kanban-definition-K7BYSVSG-Ptg6jh3y.js.map → kanban-definition-K7BYSVSG-DDCQetMc.js.map} +1 -1
- package/webapp/dist/assets/{layout-vY-lESK1.js → layout-DpuTr6cl.js} +5 -5
- package/webapp/dist/assets/{layout-vY-lESK1.js.map → layout-DpuTr6cl.js.map} +1 -1
- package/webapp/dist/assets/{linear-Cw12N-49.js → linear-BQv5LuhW.js} +2 -2
- package/webapp/dist/assets/{linear-Cw12N-49.js.map → linear-BQv5LuhW.js.map} +1 -1
- package/webapp/dist/assets/{mindmap-definition-YRQLILUH--gGSoZfe.js → mindmap-definition-YRQLILUH-C5ajM9Hr.js} +4 -4
- package/webapp/dist/assets/{mindmap-definition-YRQLILUH--gGSoZfe.js.map → mindmap-definition-YRQLILUH-C5ajM9Hr.js.map} +1 -1
- package/webapp/dist/assets/{pieDiagram-SKSYHLDU-DBQkeFNk.js → pieDiagram-SKSYHLDU-Daqms3DT.js} +8 -8
- package/webapp/dist/assets/{pieDiagram-SKSYHLDU-DBQkeFNk.js.map → pieDiagram-SKSYHLDU-Daqms3DT.js.map} +1 -1
- package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-BRqQEQ5R.js → quadrantDiagram-337W2JSQ-BMNWp18J.js} +3 -3
- package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-BRqQEQ5R.js.map → quadrantDiagram-337W2JSQ-BMNWp18J.js.map} +1 -1
- package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-Bg-ZQVHw.js → requirementDiagram-Z7DCOOCP-C1Mc4MX-.js} +4 -4
- package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-Bg-ZQVHw.js.map → requirementDiagram-Z7DCOOCP-C1Mc4MX-.js.map} +1 -1
- package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-ADkSZ215.js → sankeyDiagram-WA2Y5GQK-DTHGhOsp.js} +2 -2
- package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-ADkSZ215.js.map → sankeyDiagram-WA2Y5GQK-DTHGhOsp.js.map} +1 -1
- package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-D4N6ze3Y.js → sequenceDiagram-2WXFIKYE-C6cA5ncc.js} +4 -4
- package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-D4N6ze3Y.js.map → sequenceDiagram-2WXFIKYE-C6cA5ncc.js.map} +1 -1
- package/webapp/dist/assets/{stateDiagram-RAJIS63D-vNdpo2RN.js → stateDiagram-RAJIS63D-DRDqVPKY.js} +9 -9
- package/webapp/dist/assets/{stateDiagram-RAJIS63D-vNdpo2RN.js.map → stateDiagram-RAJIS63D-DRDqVPKY.js.map} +1 -1
- package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-DklmFziq.js → stateDiagram-v2-FVOUBMTO-B-pby7Ke.js} +5 -5
- package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-DklmFziq.js.map → stateDiagram-v2-FVOUBMTO-B-pby7Ke.js.map} +1 -1
- package/webapp/dist/assets/{timeline-definition-YZTLITO2-BrGjv8Mt.js → timeline-definition-YZTLITO2-C-m1bG_Z.js} +3 -3
- package/webapp/dist/assets/{timeline-definition-YZTLITO2-BrGjv8Mt.js.map → timeline-definition-YZTLITO2-C-m1bG_Z.js.map} +1 -1
- package/webapp/dist/assets/{treemap-KZPCXAKY-CuF9Fl6a.js → treemap-KZPCXAKY-BWvLuAyU.js} +5 -5
- package/webapp/dist/assets/{treemap-KZPCXAKY-CuF9Fl6a.js.map → treemap-KZPCXAKY-BWvLuAyU.js.map} +1 -1
- package/webapp/dist/assets/{vennDiagram-LZ73GAT5-BsWMgmkQ.js → vennDiagram-LZ73GAT5-C8gZYuUq.js} +2 -2
- package/webapp/dist/assets/{vennDiagram-LZ73GAT5-BsWMgmkQ.js.map → vennDiagram-LZ73GAT5-C8gZYuUq.js.map} +1 -1
- package/webapp/dist/assets/{xychartDiagram-JWTSCODW-MwmjJKc5.js → xychartDiagram-JWTSCODW-Bb3azvDM.js} +3 -3
- package/webapp/dist/assets/{xychartDiagram-JWTSCODW-MwmjJKc5.js.map → xychartDiagram-JWTSCODW-Bb3azvDM.js.map} +1 -1
- package/webapp/dist/index.html +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type CallerCourseNumber } from '@longrun-ai/kernel/types/storage';
|
|
1
2
|
import { Dialog, DialogID, SubDialog } from '../../dialog';
|
|
2
3
|
import type { KernelDriverDriveCallOptions, KernelDriverSubdialogReplyTarget } from './types';
|
|
3
4
|
export type SubdialogReplyTarget = KernelDriverSubdialogReplyTarget;
|
|
@@ -13,6 +14,7 @@ export declare function supplyResponseToSupdialog(args: {
|
|
|
13
14
|
course: number;
|
|
14
15
|
genseq: number;
|
|
15
16
|
};
|
|
17
|
+
callerCourseOverride?: CallerCourseNumber;
|
|
16
18
|
scheduleDrive: ScheduleDriveFn;
|
|
17
19
|
subdialog?: SubDialog;
|
|
18
20
|
}): Promise<void>;
|
|
@@ -148,7 +148,7 @@ async function resolveLatestAssignmentAnchorRef(args) {
|
|
|
148
148
|
return undefined;
|
|
149
149
|
}
|
|
150
150
|
async function supplyResponseToSupdialog(args) {
|
|
151
|
-
const { parentDialog, subdialogId, responseText, callType, callId, status = 'completed', calleeResponseRef, scheduleDrive, subdialog: maybeSubdialog, } = args;
|
|
151
|
+
const { parentDialog, subdialogId, responseText, callType, callId, status = 'completed', calleeResponseRef, callerCourseOverride, scheduleDrive, subdialog: maybeSubdialog, } = args;
|
|
152
152
|
try {
|
|
153
153
|
const result = await (0, subdialog_txn_1.withSubdialogTxnLock)(parentDialog.id, async () => {
|
|
154
154
|
const pendingSubdialogs = await persistence_1.DialogPersistence.loadPendingSubdialogs(parentDialog.id, parentDialog.status);
|
|
@@ -231,6 +231,9 @@ async function supplyResponseToSupdialog(args) {
|
|
|
231
231
|
sessionSlug,
|
|
232
232
|
callId: pendingRecord?.callId,
|
|
233
233
|
callingCourse: pendingRecord?.callingCourse,
|
|
234
|
+
callerCourse: pendingRecord?.callingCourse !== undefined
|
|
235
|
+
? (0, storage_1.toCallerCourseNumber)(pendingRecord.callingCourse)
|
|
236
|
+
: callerCourseOverride,
|
|
234
237
|
shouldRevive,
|
|
235
238
|
};
|
|
236
239
|
});
|
|
@@ -271,6 +274,10 @@ async function supplyResponseToSupdialog(args) {
|
|
|
271
274
|
})
|
|
272
275
|
: undefined;
|
|
273
276
|
if (resolvedCallId !== '' && calleeResponseRef) {
|
|
277
|
+
if (result.callerCourse === undefined) {
|
|
278
|
+
throw new Error(`tellask response anchor invariant violation: missing callerCourse ` +
|
|
279
|
+
`(parentId=${parentDialog.id.selfId}, subdialogId=${subdialogId.selfId}, callId=${resolvedCallId})`);
|
|
280
|
+
}
|
|
274
281
|
const assignmentRef = await resolveLatestAssignmentAnchorRef({
|
|
275
282
|
calleeDialogId: subdialogId,
|
|
276
283
|
callId: resolvedCallId,
|
|
@@ -308,9 +315,7 @@ async function supplyResponseToSupdialog(args) {
|
|
|
308
315
|
? (0, storage_1.toAssignmentGenerationSeqNumber)(assignmentRef.genseq)
|
|
309
316
|
: undefined,
|
|
310
317
|
callerDialogId: parentDialog.id.selfId,
|
|
311
|
-
callerCourse: result.
|
|
312
|
-
? (0, storage_1.toCallerCourseNumber)(result.callingCourse)
|
|
313
|
-
: undefined,
|
|
318
|
+
callerCourse: result.callerCourse,
|
|
314
319
|
};
|
|
315
320
|
await persistence_1.DialogPersistence.appendEvent(subdialogId, calleeResponseRef.course, anchorRecord, parentDialog.status);
|
|
316
321
|
}
|
|
@@ -800,6 +800,7 @@ async function executeTellaskCall(dlg, mentionList, body, callId, callbacks, opt
|
|
|
800
800
|
course: sub.currentCourse,
|
|
801
801
|
genseq: finalized.responseGenseq,
|
|
802
802
|
},
|
|
803
|
+
callerCourseOverride: callingCourse !== undefined ? (0, storage_1.toCallerCourseNumber)(callingCourse) : undefined,
|
|
803
804
|
scheduleDrive: callbacks.scheduleDrive,
|
|
804
805
|
});
|
|
805
806
|
sub.setFbrConclusionToolsEnabled(false);
|
package/dist/persistence.js
CHANGED
|
@@ -2260,22 +2260,37 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
2260
2260
|
break;
|
|
2261
2261
|
}
|
|
2262
2262
|
case 'tellask_call_anchor_record': {
|
|
2263
|
-
const anchorEvent =
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2263
|
+
const anchorEvent = event.anchorRole === 'assignment'
|
|
2264
|
+
? {
|
|
2265
|
+
type: 'tellask_call_anchor_evt',
|
|
2266
|
+
course,
|
|
2267
|
+
genseq: event.genseq,
|
|
2268
|
+
anchorRole: 'assignment',
|
|
2269
|
+
callId: event.callId,
|
|
2270
|
+
assignmentCourse: event.assignmentCourse,
|
|
2271
|
+
assignmentGenseq: event.assignmentGenseq,
|
|
2272
|
+
dialog: {
|
|
2273
|
+
selfId: dialog.id.selfId,
|
|
2274
|
+
rootId: dialog.id.rootId,
|
|
2275
|
+
},
|
|
2276
|
+
timestamp: event.ts,
|
|
2277
|
+
}
|
|
2278
|
+
: {
|
|
2279
|
+
type: 'tellask_call_anchor_evt',
|
|
2280
|
+
course,
|
|
2281
|
+
genseq: event.genseq,
|
|
2282
|
+
anchorRole: 'response',
|
|
2283
|
+
callId: event.callId,
|
|
2284
|
+
assignmentCourse: event.assignmentCourse,
|
|
2285
|
+
assignmentGenseq: event.assignmentGenseq,
|
|
2286
|
+
callerDialogId: event.callerDialogId,
|
|
2287
|
+
callerCourse: event.callerCourse,
|
|
2288
|
+
dialog: {
|
|
2289
|
+
selfId: dialog.id.selfId,
|
|
2290
|
+
rootId: dialog.id.rootId,
|
|
2291
|
+
},
|
|
2292
|
+
timestamp: event.ts,
|
|
2293
|
+
};
|
|
2279
2294
|
if (ws.readyState === 1) {
|
|
2280
2295
|
ws.send(JSON.stringify(anchorEvent));
|
|
2281
2296
|
}
|
package/dist/priming.js
CHANGED
|
@@ -746,27 +746,47 @@ function normalizePrimingRecordFromJson(raw) {
|
|
|
746
746
|
if (callerDialogId !== undefined && typeof callerDialogId !== 'string') {
|
|
747
747
|
throw new Error(`${context}.callerDialogId must be a string when provided`);
|
|
748
748
|
}
|
|
749
|
-
const
|
|
749
|
+
const baseRecord = {
|
|
750
750
|
ts: '',
|
|
751
751
|
type,
|
|
752
752
|
...(0, storage_1.toRootGenerationAnchor)({
|
|
753
753
|
rootCourse: expectIntegerField(raw, 'rootCourse', context),
|
|
754
754
|
rootGenseq: expectIntegerField(raw, 'rootGenseq', context),
|
|
755
755
|
}),
|
|
756
|
-
anchorRole,
|
|
757
756
|
callId: expectStringField(raw, 'callId', context),
|
|
758
757
|
genseq: expectIntegerField(raw, 'genseq', context),
|
|
758
|
+
...(assignmentCourse !== undefined
|
|
759
|
+
? { assignmentCourse: (0, storage_1.toAssignmentCourseNumber)(assignmentCourse) }
|
|
760
|
+
: {}),
|
|
761
|
+
...(assignmentGenseq !== undefined
|
|
762
|
+
? { assignmentGenseq: (0, storage_1.toAssignmentGenerationSeqNumber)(assignmentGenseq) }
|
|
763
|
+
: {}),
|
|
759
764
|
};
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
765
|
+
let record;
|
|
766
|
+
switch (anchorRole) {
|
|
767
|
+
case 'assignment':
|
|
768
|
+
if (callerDialogId !== undefined || callerCourse !== undefined) {
|
|
769
|
+
throw new Error(`${context} assignment anchor must not provide callerDialogId/callerCourse`);
|
|
770
|
+
}
|
|
771
|
+
record = {
|
|
772
|
+
...baseRecord,
|
|
773
|
+
anchorRole: 'assignment',
|
|
774
|
+
};
|
|
775
|
+
break;
|
|
776
|
+
case 'response':
|
|
777
|
+
if (typeof callerDialogId !== 'string' || callerDialogId.trim() === '') {
|
|
778
|
+
throw new Error(`${context}.callerDialogId must be a non-empty string for response`);
|
|
779
|
+
}
|
|
780
|
+
if (callerCourse === undefined) {
|
|
781
|
+
throw new Error(`${context}.callerCourse is required for response`);
|
|
782
|
+
}
|
|
783
|
+
record = {
|
|
784
|
+
...baseRecord,
|
|
785
|
+
anchorRole: 'response',
|
|
786
|
+
callerDialogId,
|
|
787
|
+
callerCourse: (0, storage_1.toCallerCourseNumber)(callerCourse),
|
|
788
|
+
};
|
|
789
|
+
break;
|
|
770
790
|
}
|
|
771
791
|
if (sourceTag)
|
|
772
792
|
record.sourceTag = sourceTag;
|
|
@@ -320,6 +320,22 @@ async function handleSaveCurrentCoursePriming(req, res) {
|
|
|
320
320
|
}
|
|
321
321
|
}
|
|
322
322
|
async function handleWorkspaceFilePreviewPage(req, res, pathname) {
|
|
323
|
+
const pseudoPathRel = parseWorkspacePseudoPreviewPathname(pathname);
|
|
324
|
+
if (pseudoPathRel !== null) {
|
|
325
|
+
if (req.method !== 'GET') {
|
|
326
|
+
res.writeHead(405, { 'Content-Type': 'text/plain; charset=utf-8', Allow: 'GET' });
|
|
327
|
+
res.end('Method Not Allowed');
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
const urlObj = new URL(req.url ?? '', 'http://127.0.0.1');
|
|
331
|
+
const location = `${buildWorkspacePreviewRoutePath(pseudoPathRel)}${urlObj.search}`;
|
|
332
|
+
res.writeHead(307, {
|
|
333
|
+
Location: location,
|
|
334
|
+
'Cache-Control': 'no-store',
|
|
335
|
+
});
|
|
336
|
+
res.end();
|
|
337
|
+
return true;
|
|
338
|
+
}
|
|
323
339
|
if (!(pathname === '/f' || pathname === '/f/' || pathname.startsWith('/f/'))) {
|
|
324
340
|
return false;
|
|
325
341
|
}
|
|
@@ -359,6 +375,8 @@ async function handleWorkspaceFilePreviewPage(req, res, pathname) {
|
|
|
359
375
|
}
|
|
360
376
|
}
|
|
361
377
|
}
|
|
378
|
+
const initialPreviewPayload = await buildWorkspacePreviewPagePayload(pathRel);
|
|
379
|
+
const initialPreviewPayloadJson = serializeJsonForInlineScript(initialPreviewPayload);
|
|
362
380
|
const html = `<!doctype html>
|
|
363
381
|
<html lang="en">
|
|
364
382
|
<head>
|
|
@@ -539,7 +557,7 @@ async function handleWorkspaceFilePreviewPage(req, res, pathname) {
|
|
|
539
557
|
<div id="preview-meta" class="meta"></div>
|
|
540
558
|
</div>
|
|
541
559
|
<div class="body">
|
|
542
|
-
<div id="status" class="status">Loading
|
|
560
|
+
<div id="status" class="status">Loading preview...</div>
|
|
543
561
|
<div id="code-wrap" class="code-wrap" style="display:none;">
|
|
544
562
|
<div id="code-view" class="code-view"></div>
|
|
545
563
|
</div>
|
|
@@ -874,15 +892,10 @@ async function handleWorkspaceFilePreviewPage(req, res, pathname) {
|
|
|
874
892
|
return;
|
|
875
893
|
}
|
|
876
894
|
|
|
895
|
+
var initialPayload = ${initialPreviewPayloadJson};
|
|
877
896
|
var search = new URLSearchParams(window.location.search);
|
|
878
897
|
var line = parsePositiveInt(search.get('line'));
|
|
879
898
|
var column = parsePositiveInt(search.get('column'));
|
|
880
|
-
var authFromUrl = search.get('auth');
|
|
881
|
-
var authFromStorage = null;
|
|
882
|
-
try { authFromStorage = window.localStorage.getItem('dominds.authKey'); } catch {}
|
|
883
|
-
var token =
|
|
884
|
-
(typeof authFromUrl === 'string' && authFromUrl.trim() !== '' ? authFromUrl.trim() : null) ||
|
|
885
|
-
(typeof authFromStorage === 'string' && authFromStorage.trim() !== '' ? authFromStorage.trim() : null);
|
|
886
899
|
|
|
887
900
|
pathEl.textContent = previewPath.length > 0 ? previewPath : '.';
|
|
888
901
|
if (line !== null) {
|
|
@@ -891,64 +904,44 @@ async function handleWorkspaceFilePreviewPage(req, res, pathname) {
|
|
|
891
904
|
metaEl.textContent = '';
|
|
892
905
|
}
|
|
893
906
|
|
|
894
|
-
var headers = { Accept: 'application/json' };
|
|
895
|
-
if (token !== null) {
|
|
896
|
-
headers['Authorization'] = 'Bearer ' + token;
|
|
897
|
-
}
|
|
898
|
-
|
|
899
907
|
resetViews();
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
});
|
|
909
|
-
})
|
|
910
|
-
.then(function (result) {
|
|
911
|
-
if (!result.ok || !result.payload || result.payload.success !== true || typeof result.payload.kind !== 'string') {
|
|
912
|
-
var msg = result.payload && typeof result.payload.error === 'string' && result.payload.error !== ''
|
|
913
|
-
? result.payload.error
|
|
914
|
-
: ('Request failed: HTTP ' + String(result.status));
|
|
915
|
-
setError(msg);
|
|
916
|
-
return;
|
|
917
|
-
}
|
|
908
|
+
if (!initialPayload || initialPayload.success !== true || typeof initialPayload.kind !== 'string') {
|
|
909
|
+
var errorMessage =
|
|
910
|
+
initialPayload && typeof initialPayload.error === 'string' && initialPayload.error !== ''
|
|
911
|
+
? initialPayload.error
|
|
912
|
+
: 'Failed to load preview';
|
|
913
|
+
setError(errorMessage);
|
|
914
|
+
return;
|
|
915
|
+
}
|
|
918
916
|
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
917
|
+
showReady();
|
|
918
|
+
pathEl.textContent =
|
|
919
|
+
typeof initialPayload.path === 'string' && initialPayload.path.length > 0
|
|
920
|
+
? initialPayload.path
|
|
921
|
+
: '.';
|
|
924
922
|
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
923
|
+
if (initialPayload.kind === 'file' && typeof initialPayload.raw === 'string') {
|
|
924
|
+
var lang = detectLang(typeof initialPayload.path === 'string' ? initialPayload.path : previewPath);
|
|
925
|
+
var sizeText = formatBytes(initialPayload.size);
|
|
926
|
+
var metaItems = [];
|
|
927
|
+
if (line !== null) metaItems.push('Line ' + String(line) + (column !== null ? ':' + String(column) : ''));
|
|
928
|
+
metaItems.push(lang);
|
|
929
|
+
if (sizeText) metaItems.push(sizeText);
|
|
930
|
+
metaEl.textContent = metaItems.join(' | ');
|
|
931
|
+
renderFile(initialPayload.raw, lang, line, column);
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
936
934
|
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
935
|
+
if (initialPayload.kind === 'directory' && Array.isArray(initialPayload.entries)) {
|
|
936
|
+
metaEl.textContent = 'directory | ' + String(initialPayload.entries.length) + ' entries';
|
|
937
|
+
renderDirectory(
|
|
938
|
+
typeof initialPayload.path === 'string' ? initialPayload.path : previewPath,
|
|
939
|
+
initialPayload.entries,
|
|
940
|
+
);
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
945
943
|
|
|
946
|
-
|
|
947
|
-
})
|
|
948
|
-
.catch(function (err) {
|
|
949
|
-
var msg = err && typeof err.message === 'string' ? err.message : 'Failed to load workspace entry';
|
|
950
|
-
setError(msg);
|
|
951
|
-
});
|
|
944
|
+
setError('Invalid preview payload');
|
|
952
945
|
})();
|
|
953
946
|
</script>
|
|
954
947
|
</body>
|
|
@@ -1192,9 +1185,8 @@ async function handleApiRoute(req, res, pathname, context) {
|
|
|
1192
1185
|
if (pathname === '/api/docs/read' && req.method === 'GET') {
|
|
1193
1186
|
return await handleReadDocsMarkdown(req, res);
|
|
1194
1187
|
}
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
return await handleReadWorkspaceEntry(req, res);
|
|
1188
|
+
if (pathname === '/api/markdown-links/resolve' && req.method === 'POST') {
|
|
1189
|
+
return await handleResolveMarkdownLinks(req, res);
|
|
1198
1190
|
}
|
|
1199
1191
|
if (pathname === '/api/snippets/builtin' && req.method === 'GET') {
|
|
1200
1192
|
const payload = await (0, snippets_routes_1.handleGetBuiltinSnippets)();
|
|
@@ -1437,6 +1429,7 @@ async function handleReadDocsMarkdown(req, res) {
|
|
|
1437
1429
|
return true;
|
|
1438
1430
|
}
|
|
1439
1431
|
const WORKSPACE_FILE_PREVIEW_MAX_BYTES = 2 * 1024 * 1024;
|
|
1432
|
+
const RTWS_PSEUDO_ROUTE_SEGMENTS = ['workspace', 'rtws'];
|
|
1440
1433
|
function ensurePathSuffixSeparator(input) {
|
|
1441
1434
|
if (input.endsWith(path.sep))
|
|
1442
1435
|
return input;
|
|
@@ -1473,6 +1466,25 @@ function normalizeRtwsRelativePath(input, options) {
|
|
|
1473
1466
|
}
|
|
1474
1467
|
return normalized;
|
|
1475
1468
|
}
|
|
1469
|
+
function normalizeWorkspacePseudoRelativePath(input) {
|
|
1470
|
+
const trimmed = input.trim();
|
|
1471
|
+
for (const prefix of RTWS_PSEUDO_ROUTE_SEGMENTS) {
|
|
1472
|
+
let tail = null;
|
|
1473
|
+
if (trimmed === prefix || trimmed === `/${prefix}`) {
|
|
1474
|
+
tail = '';
|
|
1475
|
+
}
|
|
1476
|
+
else if (trimmed.startsWith(`/${prefix}/`)) {
|
|
1477
|
+
tail = trimmed.slice(prefix.length + 2);
|
|
1478
|
+
}
|
|
1479
|
+
else if (trimmed.startsWith(`${prefix}/`)) {
|
|
1480
|
+
tail = trimmed.slice(prefix.length + 1);
|
|
1481
|
+
}
|
|
1482
|
+
if (tail !== null) {
|
|
1483
|
+
return normalizeRtwsRelativePath(tail, { allowRoot: true });
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
return null;
|
|
1487
|
+
}
|
|
1476
1488
|
function parseWorkspacePreviewPathname(pathname) {
|
|
1477
1489
|
if (pathname === '/f' || pathname === '/f/')
|
|
1478
1490
|
return '';
|
|
@@ -1502,6 +1514,47 @@ function parseWorkspacePreviewPathname(pathname) {
|
|
|
1502
1514
|
}
|
|
1503
1515
|
return normalizeRtwsRelativePath(decodedParts.join('/'), { allowRoot: true });
|
|
1504
1516
|
}
|
|
1517
|
+
function parseWorkspacePseudoPreviewPathname(pathname) {
|
|
1518
|
+
for (const prefixSegment of RTWS_PSEUDO_ROUTE_SEGMENTS) {
|
|
1519
|
+
const prefix = `/${prefixSegment}`;
|
|
1520
|
+
if (pathname === prefix || pathname === `${prefix}/`)
|
|
1521
|
+
return '';
|
|
1522
|
+
if (!pathname.startsWith(`${prefix}/`))
|
|
1523
|
+
continue;
|
|
1524
|
+
const tail = pathname.slice(prefix.length + 1);
|
|
1525
|
+
if (tail.length < 1)
|
|
1526
|
+
return '';
|
|
1527
|
+
const rawParts = tail.split('/');
|
|
1528
|
+
const decodedParts = [];
|
|
1529
|
+
for (const rawPart of rawParts) {
|
|
1530
|
+
if (rawPart.length < 1)
|
|
1531
|
+
continue;
|
|
1532
|
+
let decoded;
|
|
1533
|
+
try {
|
|
1534
|
+
decoded = decodeURIComponent(rawPart);
|
|
1535
|
+
}
|
|
1536
|
+
catch {
|
|
1537
|
+
return null;
|
|
1538
|
+
}
|
|
1539
|
+
if (decoded.length < 1)
|
|
1540
|
+
continue;
|
|
1541
|
+
if (decoded.includes('/') || decoded.includes('\\') || decoded.includes('\0')) {
|
|
1542
|
+
return null;
|
|
1543
|
+
}
|
|
1544
|
+
decodedParts.push(decoded);
|
|
1545
|
+
}
|
|
1546
|
+
return normalizeWorkspacePseudoRelativePath(decodedParts.join('/'));
|
|
1547
|
+
}
|
|
1548
|
+
return null;
|
|
1549
|
+
}
|
|
1550
|
+
function buildWorkspacePreviewRoutePath(pathRel) {
|
|
1551
|
+
if (pathRel.length < 1)
|
|
1552
|
+
return '/f';
|
|
1553
|
+
return `/f/${pathRel
|
|
1554
|
+
.split('/')
|
|
1555
|
+
.map((segment) => encodeURIComponent(segment))
|
|
1556
|
+
.join('/')}`;
|
|
1557
|
+
}
|
|
1505
1558
|
async function getWorkspaceRootRealAbs() {
|
|
1506
1559
|
const workspaceRootAbs = path.resolve(process.cwd());
|
|
1507
1560
|
try {
|
|
@@ -1620,13 +1673,13 @@ async function readFileHead(fileAbsPath, maxBytes) {
|
|
|
1620
1673
|
await file.close();
|
|
1621
1674
|
}
|
|
1622
1675
|
}
|
|
1623
|
-
async function
|
|
1624
|
-
const urlObj = new URL(req.url ?? '', 'http://127.0.0.1');
|
|
1625
|
-
const pathRaw = urlObj.searchParams.get('path');
|
|
1626
|
-
const pathRel = typeof pathRaw === 'string' ? normalizeRtwsRelativePath(pathRaw, { allowRoot: true }) : '';
|
|
1676
|
+
async function buildWorkspacePreviewPagePayload(pathRel) {
|
|
1627
1677
|
if (pathRel === null) {
|
|
1628
|
-
|
|
1629
|
-
|
|
1678
|
+
return {
|
|
1679
|
+
success: false,
|
|
1680
|
+
error: 'Invalid preview path. Expected /f/<rtws-relative-path> and no ..',
|
|
1681
|
+
status: 400,
|
|
1682
|
+
};
|
|
1630
1683
|
}
|
|
1631
1684
|
try {
|
|
1632
1685
|
const resolved = await resolveWorkspacePreviewPath(pathRel);
|
|
@@ -1637,59 +1690,129 @@ async function handleReadWorkspaceEntry(req, res) {
|
|
|
1637
1690
|
dirAbsPath: resolved.resolvedAbsPath,
|
|
1638
1691
|
workspaceRootRealAbs: resolved.workspaceRootRealAbs,
|
|
1639
1692
|
});
|
|
1640
|
-
|
|
1693
|
+
return {
|
|
1641
1694
|
success: true,
|
|
1642
1695
|
kind: 'directory',
|
|
1643
1696
|
path: pathRel,
|
|
1644
1697
|
entries,
|
|
1645
|
-
}
|
|
1646
|
-
return true;
|
|
1698
|
+
};
|
|
1647
1699
|
}
|
|
1648
1700
|
if (!stat.isFile()) {
|
|
1649
|
-
|
|
1701
|
+
return {
|
|
1650
1702
|
success: false,
|
|
1651
1703
|
error: 'Path must resolve to a file or directory',
|
|
1652
1704
|
path: pathRel,
|
|
1653
|
-
|
|
1654
|
-
|
|
1705
|
+
status: 400,
|
|
1706
|
+
};
|
|
1655
1707
|
}
|
|
1656
1708
|
if (stat.size > WORKSPACE_FILE_PREVIEW_MAX_BYTES) {
|
|
1657
|
-
|
|
1709
|
+
return {
|
|
1658
1710
|
success: false,
|
|
1659
1711
|
error: `File too large for preview (max ${WORKSPACE_FILE_PREVIEW_MAX_BYTES} bytes)`,
|
|
1660
1712
|
path: pathRel,
|
|
1661
|
-
|
|
1662
|
-
}
|
|
1663
|
-
return true;
|
|
1713
|
+
status: 413,
|
|
1714
|
+
};
|
|
1664
1715
|
}
|
|
1665
1716
|
const raw = await promises_1.default.readFile(resolved.candidateAbsPath, 'utf-8');
|
|
1666
|
-
|
|
1717
|
+
return {
|
|
1667
1718
|
success: true,
|
|
1668
1719
|
kind: 'file',
|
|
1669
1720
|
path: pathRel,
|
|
1670
1721
|
raw,
|
|
1671
1722
|
size: stat.size,
|
|
1672
|
-
}
|
|
1673
|
-
return true;
|
|
1723
|
+
};
|
|
1674
1724
|
}
|
|
1675
1725
|
catch (error) {
|
|
1676
1726
|
const code = getErrorCode(error);
|
|
1677
1727
|
if (code === 'ENOENT') {
|
|
1678
|
-
|
|
1679
|
-
|
|
1728
|
+
return {
|
|
1729
|
+
success: false,
|
|
1730
|
+
error: 'Path not found',
|
|
1731
|
+
path: pathRel,
|
|
1732
|
+
status: 404,
|
|
1733
|
+
};
|
|
1680
1734
|
}
|
|
1681
1735
|
if (code === 'OUTSIDE_RTWS') {
|
|
1682
|
-
|
|
1736
|
+
return {
|
|
1683
1737
|
success: false,
|
|
1684
1738
|
error: 'Path resolves outside rtws',
|
|
1685
1739
|
path: pathRel,
|
|
1686
|
-
|
|
1687
|
-
|
|
1740
|
+
status: 403,
|
|
1741
|
+
};
|
|
1688
1742
|
}
|
|
1689
|
-
log.error('Failed to
|
|
1690
|
-
|
|
1743
|
+
log.error('Failed to build workspace preview payload', error, { path: pathRel });
|
|
1744
|
+
return {
|
|
1745
|
+
success: false,
|
|
1746
|
+
error: 'Failed to load preview',
|
|
1747
|
+
path: pathRel,
|
|
1748
|
+
status: 500,
|
|
1749
|
+
};
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
function serializeJsonForInlineScript(value) {
|
|
1753
|
+
return JSON.stringify(value)
|
|
1754
|
+
.replace(/</g, '\\u003c')
|
|
1755
|
+
.replace(/>/g, '\\u003e')
|
|
1756
|
+
.replace(/&/g, '\\u0026')
|
|
1757
|
+
.replace(/\u2028/g, '\\u2028')
|
|
1758
|
+
.replace(/\u2029/g, '\\u2029');
|
|
1759
|
+
}
|
|
1760
|
+
async function resolveWorkspaceEntryExists(pathRel) {
|
|
1761
|
+
const resolved = await resolveWorkspacePreviewPath(pathRel);
|
|
1762
|
+
const stat = await promises_1.default.stat(resolved.candidateAbsPath);
|
|
1763
|
+
return stat.isFile() || stat.isDirectory();
|
|
1764
|
+
}
|
|
1765
|
+
async function handleResolveMarkdownLinks(req, res) {
|
|
1766
|
+
let parsed;
|
|
1767
|
+
try {
|
|
1768
|
+
const body = await readRequestBody(req);
|
|
1769
|
+
parsed = body.length > 0 ? JSON.parse(body) : {};
|
|
1770
|
+
}
|
|
1771
|
+
catch {
|
|
1772
|
+
respondJson(res, 400, { success: false, error: 'Invalid JSON body' });
|
|
1773
|
+
return true;
|
|
1774
|
+
}
|
|
1775
|
+
if (!isRecord(parsed)) {
|
|
1776
|
+
respondJson(res, 400, { success: false, error: 'Invalid JSON body' });
|
|
1691
1777
|
return true;
|
|
1692
1778
|
}
|
|
1779
|
+
const pathsRaw = parsed['paths'];
|
|
1780
|
+
if (!Array.isArray(pathsRaw)) {
|
|
1781
|
+
respondJson(res, 400, { success: false, error: '`paths` must be an array' });
|
|
1782
|
+
return true;
|
|
1783
|
+
}
|
|
1784
|
+
const normalizedPaths = [];
|
|
1785
|
+
for (const entry of pathsRaw) {
|
|
1786
|
+
if (typeof entry !== 'string') {
|
|
1787
|
+
respondJson(res, 400, { success: false, error: '`paths` entries must be strings' });
|
|
1788
|
+
return true;
|
|
1789
|
+
}
|
|
1790
|
+
const normalized = normalizeRtwsRelativePath(entry, { allowRoot: true });
|
|
1791
|
+
if (normalized === null) {
|
|
1792
|
+
respondJson(res, 400, { success: false, error: `Invalid workspace path: ${entry}` });
|
|
1793
|
+
return true;
|
|
1794
|
+
}
|
|
1795
|
+
normalizedPaths.push(normalized);
|
|
1796
|
+
}
|
|
1797
|
+
const uniquePaths = Array.from(new Set(normalizedPaths));
|
|
1798
|
+
const results = await Promise.all(uniquePaths.map(async (pathRel) => {
|
|
1799
|
+
try {
|
|
1800
|
+
const exists = await resolveWorkspaceEntryExists(pathRel);
|
|
1801
|
+
return { path: pathRel, exists };
|
|
1802
|
+
}
|
|
1803
|
+
catch (error) {
|
|
1804
|
+
const code = getErrorCode(error);
|
|
1805
|
+
if (code === 'ENOENT' || code === 'OUTSIDE_RTWS') {
|
|
1806
|
+
return { path: pathRel, exists: false };
|
|
1807
|
+
}
|
|
1808
|
+
throw error;
|
|
1809
|
+
}
|
|
1810
|
+
}));
|
|
1811
|
+
respondJson(res, 200, {
|
|
1812
|
+
success: true,
|
|
1813
|
+
results,
|
|
1814
|
+
});
|
|
1815
|
+
return true;
|
|
1693
1816
|
}
|
|
1694
1817
|
async function handleGetToolsRegistry(req, res) {
|
|
1695
1818
|
try {
|
package/dist/server/auth.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export declare function isAuthEnabled(auth: AuthConfig): auth is Extract<AuthCon
|
|
|
35
35
|
kind: 'enabled';
|
|
36
36
|
}>;
|
|
37
37
|
export declare function getHttpAuthCheck(req: IncomingMessage, auth: AuthConfig): AuthCheckResult;
|
|
38
|
+
export declare function getHttpAuthCheckAllowUrlParam(req: IncomingMessage, auth: AuthConfig, requestUrl: URL): AuthCheckResult;
|
|
38
39
|
export declare function getWebSocketAuthCheck(req: IncomingMessage, auth: AuthConfig): AuthCheckResult;
|
|
39
40
|
export declare function formatAutoAuthUrl(params: {
|
|
40
41
|
host: string;
|
package/dist/server/auth.js
CHANGED
|
@@ -51,6 +51,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
51
51
|
exports.computeAuthConfig = computeAuthConfig;
|
|
52
52
|
exports.isAuthEnabled = isAuthEnabled;
|
|
53
53
|
exports.getHttpAuthCheck = getHttpAuthCheck;
|
|
54
|
+
exports.getHttpAuthCheckAllowUrlParam = getHttpAuthCheckAllowUrlParam;
|
|
54
55
|
exports.getWebSocketAuthCheck = getWebSocketAuthCheck;
|
|
55
56
|
exports.formatAutoAuthUrl = formatAutoAuthUrl;
|
|
56
57
|
const crypto = __importStar(require("crypto"));
|
|
@@ -86,6 +87,26 @@ function getHttpAuthCheck(req, auth) {
|
|
|
86
87
|
? { kind: 'ok' }
|
|
87
88
|
: { kind: 'unauthorized', reason: 'invalid' };
|
|
88
89
|
}
|
|
90
|
+
function getHttpAuthCheckAllowUrlParam(req, auth, requestUrl) {
|
|
91
|
+
if (auth.kind === 'disabled')
|
|
92
|
+
return { kind: 'ok' };
|
|
93
|
+
const header = getSingleHeaderValue(req.headers.authorization);
|
|
94
|
+
if (header) {
|
|
95
|
+
const parsed = parseBearerAuthHeader(header);
|
|
96
|
+
if (!parsed)
|
|
97
|
+
return { kind: 'unauthorized', reason: 'invalid' };
|
|
98
|
+
return constantTimeEqual(parsed.token, auth.key)
|
|
99
|
+
? { kind: 'ok' }
|
|
100
|
+
: { kind: 'unauthorized', reason: 'invalid' };
|
|
101
|
+
}
|
|
102
|
+
const queryToken = requestUrl.searchParams.get('auth');
|
|
103
|
+
if (typeof queryToken !== 'string' || queryToken === '') {
|
|
104
|
+
return { kind: 'unauthorized', reason: 'missing' };
|
|
105
|
+
}
|
|
106
|
+
return constantTimeEqual(queryToken, auth.key)
|
|
107
|
+
? { kind: 'ok' }
|
|
108
|
+
: { kind: 'unauthorized', reason: 'invalid' };
|
|
109
|
+
}
|
|
89
110
|
function getWebSocketAuthCheck(req, auth) {
|
|
90
111
|
if (auth.kind === 'disabled')
|
|
91
112
|
return { kind: 'ok' };
|
|
@@ -105,6 +105,21 @@ class HttpServerCore {
|
|
|
105
105
|
return;
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
|
+
if (pathname === '/f' ||
|
|
109
|
+
pathname === '/f/' ||
|
|
110
|
+
pathname.startsWith('/f/') ||
|
|
111
|
+
pathname === '/workspace' ||
|
|
112
|
+
pathname === '/workspace/' ||
|
|
113
|
+
pathname.startsWith('/workspace/') ||
|
|
114
|
+
pathname === '/rtws' ||
|
|
115
|
+
pathname === '/rtws/' ||
|
|
116
|
+
pathname.startsWith('/rtws/')) {
|
|
117
|
+
const authCheck = (0, auth_1.getHttpAuthCheckAllowUrlParam)(req, this.config.auth ?? { kind: 'disabled' }, requestUrl);
|
|
118
|
+
if (authCheck.kind !== 'ok') {
|
|
119
|
+
this.sendUnauthorized(res);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
108
123
|
// Backend-direct workspace file preview page.
|
|
109
124
|
if (await (0, api_routes_1.handleWorkspaceFilePreviewPage)(req, res, pathname)) {
|
|
110
125
|
return;
|