@adhdev/daemon-standalone 1.0.54-rc.4 → 1.0.54-rc.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-standalone",
3
- "version": "1.0.54-rc.4",
3
+ "version": "1.0.54-rc.6",
4
4
  "description": "ADHDev standalone daemon — embedded HTTP/WS server for local dashboard",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -37,7 +37,7 @@
37
37
  "license": "AGPL-3.0-or-later",
38
38
  "dependencies": {
39
39
  "@adhdev/ghostty-vt-node": "*",
40
- "@adhdev/session-host-core": "1.0.54-rc.4",
40
+ "@adhdev/session-host-core": "1.0.54-rc.6",
41
41
  "@xterm/addon-serialize": "^0.14.0",
42
42
  "@xterm/xterm": "^6.0.0",
43
43
  "chalk": "^5.3.0",
@@ -994,7 +994,7 @@ var MESH_ENQUEUE_TASK_TOOL = {
994
994
  preferWorktree: { type: "boolean", description: "CamelCase alias for prefer_worktree." },
995
995
  depends_on: { type: "array", items: { type: "string" }, description: "Task ids that must complete before this task becomes claimable. Cycles are rejected at enqueue." },
996
996
  dependsOn: { type: "array", items: { type: "string" }, description: "CamelCase alias for depends_on." },
997
- mission_id: { type: "string", description: "Mission this task belongs to (mesh_mission record id)." },
997
+ mission_id: { type: "string", description: "Mission this task belongs to (mesh_mission record id, full/exact). An unresolvable id is REJECTED at enqueue (mission_not_found), never silently attached \u2014 use mesh_mission_list to get a valid full id." },
998
998
  missionId: { type: "string", description: "CamelCase alias for mission_id." },
999
999
  priority: { type: "string", enum: ["low", "normal", "high"], description: "G6 (task-level scheduling priority). Within the claim tier a high task is pulled ahead of an older normal/low task (created_at is the tie-break); low is pulled last. Defaults to normal. This is the TASK priority (which task a node pulls first) \u2014 distinct from a node's schedulingPriority (which node work goes to). Use high to jump an urgent fix ahead of a backlog without cancelling the queue." },
1000
1000
  model: { type: "string", description: "Optional model override for the agent that runs this task, e.g. opus, sonnet, haiku. Best-effort: applied at launch for providers that support a model flag (claude-cli --model, ACP setConfigOption); ignored by providers that cannot honor it. Use a cheaper model for simple tasks to save tokens, a stronger one for hard work. Blank = the provider default." },
@@ -1037,7 +1037,7 @@ var MESH_ENQUEUE_BATCH_TOOL = {
1037
1037
  preferWorktree: { type: "boolean", description: "CamelCase alias for prefer_worktree." },
1038
1038
  depends_on: { type: "array", items: { type: "string" }, description: "Refs of sibling entries in THIS batch (forward references allowed) and/or EXISTING queue task ids that must complete before this task becomes claimable. Cycles and unknown values reject the whole batch." },
1039
1039
  dependsOn: { type: "array", items: { type: "string" }, description: "CamelCase alias for depends_on." },
1040
- mission_id: { type: "string", description: "Per-task mission override; defaults to the top-level mission_id." },
1040
+ mission_id: { type: "string", description: "Per-task mission override (full/exact id); defaults to the top-level mission_id. An unresolvable id rejects the WHOLE batch (atomic)." },
1041
1041
  missionId: { type: "string", description: "CamelCase alias for mission_id." },
1042
1042
  priority: { type: "string", enum: ["low", "normal", "high"], description: "G6 task-level scheduling priority (same semantics as mesh_enqueue_task)." },
1043
1043
  model: { type: "string", description: "Optional model override for the agent that runs this task (best-effort at launch)." },
@@ -1051,7 +1051,7 @@ var MESH_ENQUEUE_BATCH_TOOL = {
1051
1051
  required: ["message", "difficulty"]
1052
1052
  }
1053
1053
  },
1054
- mission_id: { type: "string", description: "Mission every task in this batch belongs to unless an entry overrides it. For multi-task work, create the mission first (mesh_mission_upsert) and pass it here." },
1054
+ mission_id: { type: "string", description: "Mission every task in this batch belongs to unless an entry overrides it (full/exact id). For multi-task work, create the mission first (mesh_mission_upsert) and pass it here. An unresolvable id rejects the WHOLE batch (atomic) before anything is inserted." },
1055
1055
  missionId: { type: "string", description: "CamelCase alias for mission_id." },
1056
1056
  block_duplicate: { type: "boolean", description: "G4: when any entry matches an in-flight task with the same message+target, refuse the WHOLE batch (it is atomic) with code duplicate_suspect. Default false = warn-only via duplicateSuspects in the response." },
1057
1057
  blockDuplicate: { type: "boolean", description: "CamelCase alias for block_duplicate." },
@@ -1124,7 +1124,7 @@ var MESH_SEND_TASK_TOOL = {
1124
1124
  taskMode: { type: "string", enum: ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"], description: "CamelCase alias for task_mode." },
1125
1125
  readonly: { type: "boolean", description: "Optional read-only axis (orthogonal to task_mode). When true the task runs without write isolation, is counted under the read-only cap, and rejects write/commit/push/deploy/destructive instructions like live_debug_readonly. Composable with any task_mode." },
1126
1126
  read_only: { type: "boolean", description: "Snake-case alias for readonly." },
1127
- mission_id: { type: "string", description: "Mission this task belongs to (mesh_mission record id). When set, the directly dispatched task is attributed to the mission task aggregates exactly like mesh_enqueue_task, including terminal completion. Omit for an unattributed direct dispatch." },
1127
+ mission_id: { type: "string", description: "Mission this task belongs to (mesh_mission record id, full/exact). When set, the directly dispatched task is attributed to the mission task aggregates exactly like mesh_enqueue_task, including terminal completion. Omit for an unattributed direct dispatch. An unresolvable id is REJECTED before dispatch (mission_not_found), never silently attached." },
1128
1128
  missionId: { type: "string", description: "CamelCase alias for mission_id." },
1129
1129
  difficulty: { type: "string", enum: ["easy", "medium", "difficult", "freeform"], description: "REQUIRED task execution difficulty. Classify each task by how hard the work actually is. On a direct dispatch the target node/session is already chosen, so difficulty is not used to ROUTE \u2014 it is recorded on the task so scheduling analytics, mission aggregates and (critically) failure-recovery relaunch all see the same axis a queued task carries. A recovery relaunch inherits this value from the ledger, so an unclassified direct dispatch would silently downgrade its own retry." }
1130
1130
  },
@@ -1293,7 +1293,7 @@ var MESH_MISSION_UPSERT_TOOL = {
1293
1293
  inputSchema: {
1294
1294
  type: "object",
1295
1295
  properties: {
1296
- mission_id: { type: "string", description: "Mission id to update. Omit to create a new mission. Ignored when mission_ids is provided." },
1296
+ mission_id: { type: "string", description: "Full mission id (exact match) to update. Omit to create a new mission \u2014 do not guess/truncate an id to force a create. An id that does not resolve to an existing mission is REJECTED (mission_not_found), never silently created under that id \u2014 use mesh_mission_list to get a valid full id. Ignored when mission_ids is provided." },
1297
1297
  mission_ids: {
1298
1298
  type: "array",
1299
1299
  items: { type: "string" },
@@ -1564,7 +1564,7 @@ var MESH_FORGET_NOTE_TOOL = {
1564
1564
  inputSchema: {
1565
1565
  type: "object",
1566
1566
  properties: {
1567
- note_id: { type: "string", description: "The ledger note id to retract (exact). Returned by mesh_record_note as noteId, or visible in mesh_task_history entries." },
1567
+ note_id: { type: "string", description: "The ledger note id to retract (full/exact \u2014 no prefix matching). Returned by mesh_record_note as noteId, or visible in mesh_task_history entries. An id that does not match a live note returns success:false, code:note_not_found (the tombstone is still recorded, but nothing was actually retracted) \u2014 do not guess/truncate an id." },
1568
1568
  text: { type: "string", description: "Retract every operating note whose trimmed text exactly matches this string. Use when you do not have the note id." },
1569
1569
  reason: { type: "string", description: "Optional short reason for the retraction, recorded on the tombstone for audit." }
1570
1570
  }
@@ -4605,6 +4605,14 @@ function normalizeEnqueueTaskArgs(ctx, args, callerLabel) {
4605
4605
  const requiredTags = (0, import_daemon_core5.normalizeMeshCapabilityTags)(Array.isArray(args.requiredTags) ? args.requiredTags : args.required_tags);
4606
4606
  const dependsOn = Array.isArray(args.dependsOn) ? args.dependsOn : Array.isArray(args.depends_on) ? args.depends_on : void 0;
4607
4607
  const missionId = readString(args.missionId) || readString(args.mission_id) || void 0;
4608
+ if (missionId && !(0, import_daemon_core5.getMeshMission)(ctx.mesh.id, missionId)) {
4609
+ return {
4610
+ ok: false,
4611
+ code: "mission_not_found",
4612
+ error: `mission '${missionId}' does not exist on this mesh \u2014 refusing to enqueue a task with an unresolvable mission_id. Omit mission_id, or use mesh_mission_list to get a valid full id.`,
4613
+ extra: { missionId }
4614
+ };
4615
+ }
4608
4616
  const priority = (0, import_daemon_core5.normalizeMeshTaskPriority)(readString(args.priority)) || void 0;
4609
4617
  const model = readString(args.model) || void 0;
4610
4618
  const thinkingLevel = readString(args.thinkingLevel) || void 0;
@@ -4864,6 +4872,14 @@ async function meshEnqueueBatch(ctx, args) {
4864
4872
  });
4865
4873
  }
4866
4874
  const batchMissionId = readString(args.missionId) || readString(args.mission_id) || void 0;
4875
+ if (batchMissionId && !(0, import_daemon_core5.getMeshMission)(ctx.mesh.id, batchMissionId)) {
4876
+ return JSON.stringify({
4877
+ success: false,
4878
+ code: "mission_not_found",
4879
+ error: `mission '${batchMissionId}' does not exist on this mesh \u2014 refusing to enqueue a batch with an unresolvable mission_id. Omit mission_id, or use mesh_mission_list to get a valid full id.`,
4880
+ missionId: batchMissionId
4881
+ });
4882
+ }
4867
4883
  const allowDuplicate = args.allowDuplicate === true || args.allow_duplicate === true;
4868
4884
  const blockDuplicate = args.blockDuplicate === true || args.block_duplicate === true;
4869
4885
  const specs = [];
@@ -5394,12 +5410,14 @@ async function meshForgetNote(ctx, args) {
5394
5410
  ...text ? { text } : {},
5395
5411
  ...typeof args.reason === "string" && args.reason.trim() ? { reason: args.reason.trim() } : {}
5396
5412
  });
5413
+ const idTargetMissed = Boolean(noteId) && matched === 0;
5397
5414
  return JSON.stringify({
5398
- success: true,
5415
+ success: !idTargetMissed,
5399
5416
  meshId: mesh.id,
5400
5417
  tombstoneId: tombstone.id,
5401
5418
  forgot: { noteId: noteId ?? null, text: text || null, matched },
5402
- note: matched > 0 ? `Retracted ${matched} operating note(s). Future coordinators on this mesh will no longer see them at launch. History is preserved (append-only tombstone).` : "No live operating note matched \u2014 recorded a tombstone anyway so any matching note appended later is also suppressed."
5419
+ ...idTargetMissed ? { code: "note_not_found" } : {},
5420
+ note: matched > 0 ? `Retracted ${matched} operating note(s). Future coordinators on this mesh will no longer see them at launch. History is preserved (append-only tombstone).` : idTargetMissed ? `No live operating note matched note_id '${noteId}' \u2014 likely a truncated/wrong id (this tool requires an exact match). A tombstone was still recorded so any matching note appended later is also suppressed, but nothing was actually retracted. Use mesh_task_history or mesh_record_note's returned noteId to get the full id.` : "No live operating note matched \u2014 recorded a tombstone anyway so any matching note appended later is also suppressed."
5403
5421
  }, null, 2);
5404
5422
  } catch (e) {
5405
5423
  return JSON.stringify({ success: false, error: e?.message || String(e) }, null, 2);
@@ -5538,7 +5556,7 @@ async function meshMissionUpsert(ctx, args) {
5538
5556
  });
5539
5557
  } catch (e) {
5540
5558
  const message = e?.message || String(e);
5541
- const code = message.includes("mission_title_required") ? "mission_title_required" : message.includes("invalid_mission_status") ? "invalid_mission_status" : void 0;
5559
+ const code = message.includes("mission_title_required") ? "mission_title_required" : message.includes("invalid_mission_status") ? "invalid_mission_status" : message.includes("mission_not_found") ? "mission_not_found" : void 0;
5542
5560
  return JSON.stringify({ success: false, ...code ? { code } : {}, error: message });
5543
5561
  }
5544
5562
  }
@@ -7460,6 +7478,14 @@ async function meshSendTask(ctx, args) {
7460
7478
  const requestedTaskMode = readString(args.task_mode) || readString(args.taskMode);
7461
7479
  const readonly = args.readonly === true || args.read_only === true;
7462
7480
  const missionId = readString(args.missionId) || readString(args.mission_id) || void 0;
7481
+ if (missionId && !(0, import_daemon_core5.getMeshMission)(ctx.mesh.id, missionId)) {
7482
+ return JSON.stringify({
7483
+ success: false,
7484
+ code: "mission_not_found",
7485
+ error: `mission '${missionId}' does not exist on this mesh \u2014 refusing to dispatch a task with an unresolvable mission_id. Omit mission_id, or use mesh_mission_list to get a valid full id.`,
7486
+ missionId
7487
+ });
7488
+ }
7463
7489
  const difficultyRaw = readString(args.difficulty);
7464
7490
  if (!difficultyRaw || !isMeshTaskDifficulty(difficultyRaw)) {
7465
7491
  return JSON.stringify({