@goodandready/dsh-moa 0.2.44 → 0.2.46

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/routes.js CHANGED
@@ -2,8 +2,9 @@
2
2
  * DeepSeek Harness Mixture of Agents (MoA) — HTTP Route Handlers
3
3
  */
4
4
 
5
+ import path from 'node:path'
5
6
  import { getMoaHistory, getMoaLeaderboard, getMoaRunById, exportMoaHistory } from './history.js'
6
- import { promoteCandidateWorkspace, readCandidateFiles, computeLineDiff, isSafeRelativePath } from './file-workspace.js'
7
+ import { promoteCandidateWorkspace, readCandidateFiles, computeLineDiff, isSafeRelativePath, isLoopbackUrl } from './file-workspace.js'
7
8
  import { isSafeWriteRequest } from './updater.js'
8
9
  import { runMoAPipeline } from './moa-runner.js'
9
10
  import { generateMoABenchmarkReport } from './moa-report.js'
@@ -36,10 +37,7 @@ ctx.effect(() => {
36
37
  kind: 'exact',
37
38
  path: '/dsh-moa/status',
38
39
  handler: (req, res) => {
39
- if (req.method !== 'GET') {
40
- writeJson(res, 405, { ok: false, error: 'GET required' })
41
- return
42
- }
40
+ if (req.method !== 'GET') return writeJson(res, 405, { ok: false, error: 'GET required' })
43
41
  try {
44
42
  const cfg = live()
45
43
  writeJson(res, 200, {
@@ -48,9 +46,7 @@ ctx.effect(() => {
48
46
  defaultPreset: cfg.default_preset || 'default',
49
47
  presetsCount: (cfg.presets || []).length,
50
48
  })
51
- } catch (err) {
52
- writeJson(res, 500, { ok: false, error: err?.message || String(err) })
53
- }
49
+ } catch (err) { writeJson(res, 500, { ok: false, error: err?.message || String(err) }) }
54
50
  },
55
51
  })
56
52
  }, 'dsh-moa: status route')
@@ -61,10 +57,7 @@ ctx.effect(() => {
61
57
  kind: 'exact',
62
58
  path: '/dsh-moa/models',
63
59
  handler: async (req, res) => {
64
- if (req.method !== 'GET') {
65
- writeJson(res, 405, { ok: false, error: 'GET required' })
66
- return
67
- }
60
+ if (req.method !== 'GET') return writeJson(res, 405, { ok: false, error: 'GET required' })
68
61
  if (_modelsCache.models.length > 0 && Date.now() - _modelsCache.timestamp < MODELS_CACHE_TTL) {
69
62
  writeJson(res, 200, { ok: true, models: _modelsCache.models, cached: true })
70
63
  return
@@ -123,19 +116,11 @@ ctx.effect(() => {
123
116
  // Query settings for configured providers
124
117
  try {
125
118
  let s = null
126
- try {
127
- s = ctx.get ? ctx.get('settings') : null
128
- } catch {
129
- s = null
130
- }
131
- const getSetting = (k) => {
132
- try { return s?.get?.(k) } catch { return undefined }
133
- }
119
+ try { s = ctx.get ? ctx.get('settings') : null } catch { s = null }
120
+ const getSetting = (k) => { try { return s?.get?.(k) } catch { return undefined } }
134
121
 
135
122
  const def = getSetting('agent-default-model')
136
- if (def?.provider && def?.model) {
137
- add(def.provider, def.model)
138
- }
123
+ if (def?.provider && def?.model) add(def.provider, def.model)
139
124
 
140
125
  const piAi = getSetting('llm-pi-ai')
141
126
  for (const [pName, pData] of Object.entries(piAi?.providers || {})) {
@@ -208,25 +193,21 @@ ctx.effect(() => {
208
193
  }
209
194
 
210
195
  // Persist via saveConfig (in-memory and DSH profile settings)
196
+ let persistResult
211
197
  if (typeof saveConfig === 'function') {
212
- try {
213
- await saveConfig(validated)
214
- } catch (perr) {
215
- writeJson(res, 500, { ok: false, error: 'Settings persistence failed: ' + (perr?.message || String(perr)) })
216
- return
217
- }
198
+ try { persistResult = await saveConfig(validated) }
199
+ catch (perr) { return writeJson(res, 500, { ok: false, error: 'Settings persistence failed: ' + (perr?.message || String(perr)) }) }
218
200
  }
219
201
 
220
202
  const unwrapped = typeof plainConfig === 'function' ? plainConfig(validated) : validated
221
203
  writeJson(res, 200, {
222
204
  ok: true,
205
+ persisted: persistResult?.persisted ?? false,
223
206
  enabled: unwrapped.enabled !== false,
224
207
  defaultPreset: unwrapped.default_preset,
225
208
  presets: unwrapped.presets,
226
209
  })
227
- } catch (err) {
228
- writeJson(res, 400, { ok: false, error: err?.message || String(err) })
229
- }
210
+ } catch (err) { writeJson(res, 400, { ok: false, error: err?.message || String(err) }) }
230
211
  return
231
212
  }
232
213
 
@@ -241,21 +222,14 @@ ctx.effect(() => {
241
222
  kind: 'exact',
242
223
  path: '/dsh-moa/history',
243
224
  handler: async (req, res) => {
244
- if (req.method !== 'GET') {
245
- writeJson(res, 405, { ok: false, error: 'GET required' })
246
- return
247
- }
225
+ if (req.method !== 'GET') return writeJson(res, 405, { ok: false, error: 'GET required' })
248
226
  try {
249
227
  const u = new URL(req.url, 'http://localhost')
250
- const rawLimit = parseInt(u.searchParams.get('limit') || '20', 10)
251
- const rawOffset = parseInt(u.searchParams.get('offset') || '0', 10)
252
- const limit = Math.max(1, Math.min(100, Number.isFinite(rawLimit) ? rawLimit : 20))
253
- const offset = Math.max(0, Number.isFinite(rawOffset) ? rawOffset : 0)
228
+ const limit = Math.max(1, Math.min(100, parseInt(u.searchParams.get('limit') || '20', 10) || 20))
229
+ const offset = Math.max(0, parseInt(u.searchParams.get('offset') || '0', 10) || 0)
254
230
  const data = getMoaHistory(limit, offset)
255
231
  writeJson(res, 200, { ok: true, ...data })
256
- } catch (err) {
257
- writeJson(res, 500, { ok: false, error: err?.message || String(err) })
258
- }
232
+ } catch (err) { writeJson(res, 500, { ok: false, error: err?.message || String(err) }) }
259
233
  },
260
234
  })
261
235
  }, 'dsh-moa: history route')
@@ -266,10 +240,7 @@ ctx.effect(() => {
266
240
  kind: 'exact',
267
241
  path: '/dsh-moa/leaderboard',
268
242
  handler: async (req, res) => {
269
- if (req.method !== 'GET') {
270
- writeJson(res, 405, { ok: false, error: 'GET required' })
271
- return
272
- }
243
+ if (req.method !== 'GET') return writeJson(res, 405, { ok: false, error: 'GET required' })
273
244
  try {
274
245
  const url = new URL(req.url || '', 'http://127.0.0.1')
275
246
  const preset = url.searchParams.get('preset') || null
@@ -287,9 +258,7 @@ ctx.effect(() => {
287
258
 
288
259
  const data = getMoaLeaderboard(undefined, { preset })
289
260
  writeJson(res, 200, { ok: true, ...data })
290
- } catch (err) {
291
- writeJson(res, 500, { ok: false, error: err?.message || String(err) })
292
- }
261
+ } catch (err) { writeJson(res, 500, { ok: false, error: err?.message || String(err) }) }
293
262
  },
294
263
  })
295
264
  }, 'dsh-moa: leaderboard route')
@@ -300,10 +269,7 @@ ctx.effect(() => {
300
269
  kind: 'exact',
301
270
  path: '/dsh-moa/promote',
302
271
  handler: async (req, res) => {
303
- if (req.method !== 'POST') {
304
- writeJson(res, 405, { ok: false, error: 'POST required' })
305
- return
306
- }
272
+ if (req.method !== 'POST') return writeJson(res, 405, { ok: false, error: 'POST required' })
307
273
  if (!isSafeWriteRequest(req)) {
308
274
  writeJson(res, 403, { ok: false, error: 'Forbidden: cross-site request rejected' })
309
275
  return
@@ -316,19 +282,35 @@ ctx.effect(() => {
316
282
  writeJson(res, 400, { ok: false, error: 'Valid candidateIndex required (>= 1)' })
317
283
  return
318
284
  }
319
- const cwd = body?.cwd || process.cwd()
320
285
  const runId = body?.runId
321
- const promotedFiles = await promoteCandidateWorkspace(cwd, candidateIndex, {
322
- runId,
286
+ let recordedRun = null
287
+ if (runId) {
288
+ recordedRun = getMoaRunById(runId)
289
+ if (!recordedRun) {
290
+ writeJson(res, 404, { ok: false, error: `Run '${runId}' not found` })
291
+ return
292
+ }
293
+ } else {
294
+ recordedRun = getMoaHistory(1, 0)?.runs?.[0] || null
295
+ if (!recordedRun) {
296
+ writeJson(res, 400, { ok: false, error: 'No recorded MoA run found' })
297
+ return
298
+ }
299
+ }
300
+ if (body?.cwd && path.resolve(body.cwd) !== path.resolve(recordedRun.cwd)) {
301
+ writeJson(res, 403, { ok: false, error: 'Forbidden: cwd does not match recorded run cwd' })
302
+ return
303
+ }
304
+ const effectiveCwd = recordedRun.cwd
305
+ const promotedFiles = await promoteCandidateWorkspace(effectiveCwd, candidateIndex, {
306
+ runId: runId ? recordedRun.id : undefined,
323
307
  keepMoa: true,
324
308
  port: ctx.webServer?.port,
325
309
  timeMachineEngine: timeMachineEngine || ctx.reflect?.get?.('timeMachineEngine', false),
326
310
  force: Boolean(body?.force),
327
311
  })
328
312
  writeJson(res, 200, { ok: true, candidateIndex, promotedFiles, checkpoint: promotedFiles?.checkpoint || null })
329
- } catch (err) {
330
- writeJson(res, 500, { ok: false, error: err?.message || String(err) })
331
- }
313
+ } catch (err) { writeJson(res, 500, { ok: false, error: err?.message || String(err) }) }
332
314
  },
333
315
  })
334
316
  }, 'dsh-moa: promote candidate route')
@@ -339,17 +321,31 @@ ctx.effect(() => {
339
321
  kind: 'exact',
340
322
  path: '/dsh-moa/diff',
341
323
  handler: async (req, res) => {
342
- if (req.method !== 'GET') {
343
- writeJson(res, 405, { ok: false, error: 'GET required' })
344
- return
345
- }
324
+ if (req.method !== 'GET') return writeJson(res, 405, { ok: false, error: 'GET required' })
346
325
  try {
347
326
  const u = new URL(req.url, 'http://localhost')
348
327
  const rawRunId = u.searchParams.get('runId')
349
- const latestRun = (!rawRunId || rawRunId === 'latest' || rawRunId === 'active') ? getMoaHistory(1, 0).runs[0] : null
350
- const runId = (rawRunId && rawRunId !== 'latest' && rawRunId !== 'active') ? rawRunId : latestRun?.id
351
- const run = runId ? getMoaRunById(runId) : null
352
- const cwd = run?.cwd || latestRun?.cwd || u.searchParams.get('cwd') || process.cwd()
328
+ const queryCwd = u.searchParams.get('cwd')
329
+ let run = null
330
+ if (rawRunId && rawRunId !== 'latest' && rawRunId !== 'active') {
331
+ run = getMoaRunById(rawRunId)
332
+ if (!run) {
333
+ writeJson(res, 404, { ok: false, error: `Run '${rawRunId}' not found` })
334
+ return
335
+ }
336
+ } else {
337
+ run = getMoaHistory(1, 0)?.runs?.[0] || null
338
+ if (!run) {
339
+ writeJson(res, 404, { ok: false, error: 'No recorded MoA run found' })
340
+ return
341
+ }
342
+ }
343
+ if (queryCwd && path.resolve(queryCwd) !== path.resolve(run.cwd)) {
344
+ writeJson(res, 403, { ok: false, error: 'Forbidden: cwd does not match recorded run cwd' })
345
+ return
346
+ }
347
+ const runId = run.id
348
+ const cwd = run.cwd
353
349
  const sanitizeTarget = (val, def) => {
354
350
  const clean = String(val || '').trim().replace(/[^a-zA-Z0-9_-]/g, '')
355
351
  return clean || def
@@ -386,47 +382,31 @@ ctx.effect(() => {
386
382
  toSize: toItem?.size || 0,
387
383
  diff,
388
384
  })
389
- } catch (err) {
390
- writeJson(res, 500, { ok: false, error: err?.message || String(err) })
391
- }
385
+ } catch (err) { writeJson(res, 500, { ok: false, error: err?.message || String(err) }) }
392
386
  },
393
387
  })
394
388
  }, 'dsh-moa: candidate diff route')
395
389
 
396
-
397
390
  // Route: /dsh-moa/history/export
398
391
  ctx.effect(() => {
399
392
  return ctx.webServer.register({
400
393
  kind: 'exact',
401
394
  path: '/dsh-moa/history/export',
402
395
  handler: async (req, res) => {
403
- if (req.method !== 'GET') {
404
- writeJson(res, 405, { ok: false, error: 'GET required' })
405
- return
406
- }
396
+ if (req.method !== 'GET') return writeJson(res, 405, { ok: false, error: 'GET required' })
407
397
  try {
408
398
  const url = new URL(req.url || '', 'http://127.0.0.1')
409
399
  const preset = url.searchParams.get('preset') || null
410
400
  const format = url.searchParams.get('format') || 'json'
411
401
  const data = exportMoaHistory(undefined, { format, preset })
412
402
 
413
- if (format === 'csv') {
414
- res.writeHead(200, {
415
- 'Content-Type': 'text/csv; charset=utf-8',
416
- 'Content-Disposition': 'attachment; filename="moa-history.csv"',
417
- })
418
- res.end(data)
419
- return
420
- }
421
-
403
+ const isCsv = format === 'csv'
422
404
  res.writeHead(200, {
423
- 'Content-Type': 'application/json; charset=utf-8',
424
- 'Content-Disposition': 'attachment; filename="moa-history.json"',
405
+ 'Content-Type': isCsv ? 'text/csv; charset=utf-8' : 'application/json; charset=utf-8',
406
+ 'Content-Disposition': `attachment; filename="moa-history.${isCsv ? 'csv' : 'json'}"`,
425
407
  })
426
408
  res.end(data)
427
- } catch (err) {
428
- writeJson(res, 500, { ok: false, error: err?.message || String(err) })
429
- }
409
+ } catch (err) { writeJson(res, 500, { ok: false, error: err?.message || String(err) }) }
430
410
  },
431
411
  })
432
412
  }, 'dsh-moa: history export route')
@@ -437,10 +417,7 @@ ctx.effect(() => {
437
417
  kind: 'prefix',
438
418
  path: '/dsh-moa/runs/',
439
419
  handler: (req, res) => {
440
- if (req.method !== 'GET') {
441
- writeJson(res, 405, { ok: false, error: 'GET required' })
442
- return
443
- }
420
+ if (req.method !== 'GET') return writeJson(res, 405, { ok: false, error: 'GET required' })
444
421
  const urlPath = req.url.split('?')[0]
445
422
  const parts = urlPath.split('/').filter(Boolean)
446
423
  const runId = parts[2] || ''
@@ -485,10 +462,7 @@ ctx.effect(() => {
485
462
  kind: 'exact',
486
463
  path: '/dsh-moa/route-preset',
487
464
  handler: async (req, res) => {
488
- if (req.method !== 'POST') {
489
- writeJson(res, 405, { ok: false, error: 'POST required' })
490
- return
491
- }
465
+ if (req.method !== 'POST') return writeJson(res, 405, { ok: false, error: 'POST required' })
492
466
  if (!isSafeWriteRequest(req)) {
493
467
  writeJson(res, 403, { ok: false, error: 'Forbidden: cross-site request rejected' })
494
468
  return
@@ -514,9 +488,7 @@ ctx.effect(() => {
514
488
  enabled: cfg.enabled !== false,
515
489
  })
516
490
  writeJson(res, 200, { ok: true, ...result })
517
- } catch (err) {
518
- writeJson(res, 500, { ok: false, error: err?.message || String(err) })
519
- }
491
+ } catch (err) { writeJson(res, 500, { ok: false, error: err?.message || String(err) }) }
520
492
  },
521
493
  })
522
494
  }, 'dsh-moa: route preset endpoint')
@@ -530,10 +502,7 @@ ctx.effect(() => {
530
502
  kind: 'exact',
531
503
  path: '/dsh-moa/run',
532
504
  handler: async (req, res) => {
533
- if (req.method !== 'POST') {
534
- writeJson(res, 405, { ok: false, error: 'POST required' })
535
- return
536
- }
505
+ if (req.method !== 'POST') return writeJson(res, 405, { ok: false, error: 'POST required' })
537
506
  if (!isSafeWriteRequest(req)) {
538
507
  writeJson(res, 403, { ok: false, error: 'Forbidden: cross-site request rejected' })
539
508
  return
@@ -559,6 +528,10 @@ ctx.effect(() => {
559
528
  writeJson(res, 400, { ok: false, error: 'MoA is disabled in settings' })
560
529
  return
561
530
  }
531
+ if (payload.timeMachineUrl && !isLoopbackUrl(payload.timeMachineUrl)) {
532
+ writeJson(res, 400, { ok: false, error: 'Invalid timeMachineUrl: loopback host required' })
533
+ return
534
+ }
562
535
  const presetName = payload.preset || cfg.default_preset || 'default'
563
536
  const preset = (cfg.presets || []).find((p) => p.name === presetName) || cfg.presets?.[0]
564
537
 
@@ -568,23 +541,20 @@ ctx.effect(() => {
568
541
  webServerPort: webServerPort || ctx.webServer?.port,
569
542
  timeMachineEngine: timeMachineEngine || ctx.reflect?.get?.('timeMachineEngine', false),
570
543
  timeMachineUrl: payload.timeMachineUrl, force: payload.force,
571
- checkpoint: payload.checkpoint, checkpointFn: payload.checkpointFn,
544
+ checkpoint: payload.checkpoint,
572
545
  runId: payload.runId,
573
546
  })
574
547
 
575
548
  if (result?.skippedFiles > 0) {
576
549
  ctx.logger?.warn?.(`[dsh-moa] Workspace scan skipped ${result.skippedFiles} file(s): ${result.skippedList.join(', ')}`)
577
550
  }
578
-
579
551
  if (result?.error) {
580
552
  writeJson(res, 500, { ok: false, error: result.error?.message || String(result.error) })
581
553
  return
582
554
  }
583
555
 
584
556
  writeJson(res, 200, { ok: true, ...result })
585
- } catch (err) {
586
- writeJson(res, 500, { ok: false, error: err?.message || String(err) })
587
- }
557
+ } catch (err) { writeJson(res, 500, { ok: false, error: err?.message || String(err) }) }
588
558
  },
589
559
  })
590
560
  }, 'dsh-moa: run pipeline route')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-moa",
3
- "version": "0.2.44",
3
+ "version": "0.2.46",
4
4
  "description": "Mixture of Agents (MoA) plugin for DeepSeek Harness with /moa slash command",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",