@wopr-network/defcon 1.2.0 → 1.2.1

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.
@@ -249,20 +249,20 @@ export function createHttpServer(deps) {
249
249
  return mcpResultToApi(result);
250
250
  });
251
251
  // --- Admin: Drain/Undrain Worker ---
252
- router.add("POST", "/api/admin/workers/:workerId/drain", async (req) => {
252
+ router.add("POST", "/api/admin/workers/:worker_id/drain", async (req) => {
253
253
  const authErr = requireAdminToken(deps, req);
254
254
  if (authErr)
255
255
  return authErr;
256
256
  const callerToken = extractBearerToken(req.authorization);
257
- const result = await callToolHandler(deps.mcpDeps, "admin.worker.drain", { worker_id: req.params.workerId }, { adminToken: deps.adminToken, callerToken });
257
+ const result = await callToolHandler(deps.mcpDeps, "admin.worker.drain", { worker_id: req.params.worker_id }, { adminToken: deps.adminToken, callerToken });
258
258
  return mcpResultToApi(result);
259
259
  });
260
- router.add("POST", "/api/admin/workers/:workerId/undrain", async (req) => {
260
+ router.add("POST", "/api/admin/workers/:worker_id/undrain", async (req) => {
261
261
  const authErr = requireAdminToken(deps, req);
262
262
  if (authErr)
263
263
  return authErr;
264
264
  const callerToken = extractBearerToken(req.authorization);
265
- const result = await callToolHandler(deps.mcpDeps, "admin.worker.undrain", { worker_id: req.params.workerId }, { adminToken: deps.adminToken, callerToken });
265
+ const result = await callToolHandler(deps.mcpDeps, "admin.worker.undrain", { worker_id: req.params.worker_id }, { adminToken: deps.adminToken, callerToken });
266
266
  return mcpResultToApi(result);
267
267
  });
268
268
  // --- Admin: Rerun Gate ---
@@ -771,6 +771,7 @@ async function handleAdminFlowPause(deps, args) {
771
771
  const flow = await deps.flows.getByName(v.data.flow_name);
772
772
  if (!flow)
773
773
  return errorResult(`Flow not found: ${v.data.flow_name}`);
774
+ await deps.flows.snapshot(flow.id);
774
775
  await deps.flows.update(flow.id, { paused: true });
775
776
  emitDefinitionChanged(deps.eventRepo, flow.id, "admin.flow.pause", { name: v.data.flow_name });
776
777
  return jsonResult({ paused: true, flow: v.data.flow_name });
@@ -782,6 +783,7 @@ async function handleAdminFlowResume(deps, args) {
782
783
  const flow = await deps.flows.getByName(v.data.flow_name);
783
784
  if (!flow)
784
785
  return errorResult(`Flow not found: ${v.data.flow_name}`);
786
+ await deps.flows.snapshot(flow.id);
785
787
  await deps.flows.update(flow.id, { paused: false });
786
788
  emitDefinitionChanged(deps.eventRepo, flow.id, "admin.flow.resume", { name: v.data.flow_name });
787
789
  return jsonResult({ paused: false, flow: v.data.flow_name });
@@ -793,6 +795,12 @@ async function handleAdminEntityCancel(deps, args) {
793
795
  const entity = await deps.entities.get(v.data.entity_id);
794
796
  if (!entity)
795
797
  return errorResult(`Entity not found: ${v.data.entity_id}`);
798
+ const flow = await deps.flows.get(entity.flowId);
799
+ if (!flow)
800
+ return errorResult(`Flow not found for entity: ${v.data.entity_id}`);
801
+ const cancelledState = flow.states.find((s) => s.name === "cancelled");
802
+ if (!cancelledState)
803
+ return errorResult(`State 'cancelled' not found in flow '${flow.name}'`);
796
804
  const invocations = await deps.invocations.findByEntity(v.data.entity_id);
797
805
  for (const inv of invocations) {
798
806
  if (inv.completedAt === null && inv.failedAt === null) {
@@ -800,6 +808,14 @@ async function handleAdminEntityCancel(deps, args) {
800
808
  }
801
809
  }
802
810
  await deps.entities.cancelEntity(v.data.entity_id);
811
+ await deps.transitions.record({
812
+ entityId: v.data.entity_id,
813
+ fromState: entity.state,
814
+ toState: "cancelled",
815
+ trigger: "admin.cancel",
816
+ invocationId: null,
817
+ timestamp: new Date(),
818
+ });
803
819
  return jsonResult({ cancelled: true, entity_id: v.data.entity_id });
804
820
  }
805
821
  async function handleAdminEntityReset(deps, args) {
@@ -822,6 +838,14 @@ async function handleAdminEntityReset(deps, args) {
822
838
  }
823
839
  }
824
840
  const updated = await deps.entities.resetEntity(v.data.entity_id, v.data.target_state);
841
+ await deps.transitions.record({
842
+ entityId: v.data.entity_id,
843
+ fromState: entity.state,
844
+ toState: updated.state,
845
+ trigger: "admin.reset",
846
+ invocationId: null,
847
+ timestamp: new Date(),
848
+ });
825
849
  return jsonResult({ reset: true, entity_id: v.data.entity_id, state: updated.state });
826
850
  }
827
851
  async function handleAdminWorkerDrain(deps, args) {
@@ -97,7 +97,7 @@ export class DrizzleGateRepository {
97
97
  return rows.map(toGateResult);
98
98
  }
99
99
  async clearResult(entityId, gateId) {
100
- this.db
100
+ await this.db
101
101
  .delete(gateResults)
102
102
  .where(and(eq(gateResults.entityId, entityId), eq(gateResults.gateId, gateId)))
103
103
  .run();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wopr-network/defcon",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "type": "module",
5
5
  "packageManager": "pnpm@9.15.4",
6
6
  "engines": {