@questionbase/deskfree 0.3.0-alpha.39 → 0.3.0-alpha.40

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/index.d.ts CHANGED
@@ -468,6 +468,7 @@ interface TaskWithContext extends Task {
468
468
  }
469
469
  interface CompleteTaskInput {
470
470
  taskId: string;
471
+ humanApproved: boolean;
471
472
  learnings?: {
472
473
  reasoning: string;
473
474
  globalWoW?: string;
@@ -600,6 +601,14 @@ declare class DeskFreeClient {
600
601
  getTask(input: {
601
602
  taskId: string;
602
603
  }): Promise<TaskSummary>;
604
+ /** Update task step progress. */
605
+ updateSteps(input: {
606
+ taskId: string;
607
+ steps: Array<{
608
+ label: string;
609
+ status: 'pending' | 'in_progress' | 'done';
610
+ }>;
611
+ }): Promise<void>;
603
612
  /** Update the content of an existing file. */
604
613
  updateFile(input: {
605
614
  fileId: string;
package/dist/index.js CHANGED
@@ -4025,6 +4025,11 @@ var DeskFreeClient = class {
4025
4025
  this.requireNonEmpty(input.taskId, "taskId");
4026
4026
  return this.request("GET", "tasks.get", input);
4027
4027
  }
4028
+ /** Update task step progress. */
4029
+ async updateSteps(input) {
4030
+ this.requireNonEmpty(input.taskId, "taskId");
4031
+ return this.request("POST", "tasks.updateSteps", input);
4032
+ }
4028
4033
  /** Update the content of an existing file. */
4029
4034
  async updateFile(input) {
4030
4035
  this.requireNonEmpty(input.fileId, "fileId");
@@ -8209,9 +8214,21 @@ var ORCHESTRATOR_TOOLS = {
8209
8214
  }),
8210
8215
  instructions: Type.Optional(
8211
8216
  Type.String({
8212
- description: "3-8 bullet points max in simple markdown (bold, lists, inline code \u2014 no # headers). What to do, what done looks like, key constraints. Under 500 words. Skip context the worker can infer from the title."
8217
+ description: "Optional background context or constraints. Keep brief \u2014 steps carry the main structure."
8213
8218
  })
8214
8219
  ),
8220
+ steps: Type.Optional(
8221
+ Type.Array(
8222
+ Type.String({
8223
+ description: "Short action phrase (max 300 chars)"
8224
+ }),
8225
+ {
8226
+ description: "3-8 step labels as short action phrases. These become the visual progress tracker for the worker.",
8227
+ minItems: 1,
8228
+ maxItems: 20
8229
+ }
8230
+ )
8231
+ ),
8215
8232
  file: Type.Optional(
8216
8233
  Type.Union(
8217
8234
  [
@@ -8292,6 +8309,9 @@ var SHARED_TOOLS = {
8292
8309
  description: "Mark a task as done. Only call when truly finished and human confirmed. Pass learnings to update knowledge atomically with completion. Pass followUps to propose next tasks.",
8293
8310
  parameters: Type.Object({
8294
8311
  taskId: Type.String({ description: "Task UUID" }),
8312
+ humanApproved: Type.Boolean({
8313
+ description: "Must be true. Confirms the human reviewed and approved completion. Backend validates a human message exists after your last ask."
8314
+ }),
8295
8315
  learnings: Type.Optional(
8296
8316
  Type.Object(
8297
8317
  {
@@ -8397,9 +8417,21 @@ var SHARED_TOOLS = {
8397
8417
  }),
8398
8418
  instructions: Type.Optional(
8399
8419
  Type.String({
8400
- description: "3-8 bullet points max in simple markdown (bold, lists, inline code \u2014 no # headers). What to do, what done looks like, key constraints. Under 500 words. Skip context the worker can infer from the title."
8420
+ description: "Optional background context or constraints. Keep brief \u2014 steps carry the main structure."
8401
8421
  })
8402
8422
  ),
8423
+ steps: Type.Optional(
8424
+ Type.Array(
8425
+ Type.String({
8426
+ description: "Short action phrase (max 300 chars)"
8427
+ }),
8428
+ {
8429
+ description: "3-8 step labels as short action phrases. These become the visual progress tracker for the worker.",
8430
+ minItems: 1,
8431
+ maxItems: 20
8432
+ }
8433
+ )
8434
+ ),
8403
8435
  file: Type.Optional(
8404
8436
  Type.Union(
8405
8437
  [
@@ -8473,6 +8505,31 @@ var WORKER_TOOLS = {
8473
8505
  })
8474
8506
  },
8475
8507
  UPDATE_FILE: SHARED_TOOLS.UPDATE_FILE,
8508
+ UPDATE_STEPS: {
8509
+ name: "deskfree_update_steps",
8510
+ description: "Update step progress for your current task. Send the full step list each time (full replacement). Call this as you work through steps to show progress.",
8511
+ parameters: Type.Object({
8512
+ taskId: Type.String({ description: "Task UUID" }),
8513
+ steps: Type.Array(
8514
+ Type.Object({
8515
+ label: Type.String({ description: "Step label (max 300 chars)" }),
8516
+ status: Type.Union(
8517
+ [
8518
+ Type.Literal("pending"),
8519
+ Type.Literal("in_progress"),
8520
+ Type.Literal("done")
8521
+ ],
8522
+ { description: "Current status of this step" }
8523
+ )
8524
+ }),
8525
+ {
8526
+ description: "Full step list with current statuses (1-20 items)",
8527
+ minItems: 1,
8528
+ maxItems: 20
8529
+ }
8530
+ )
8531
+ })
8532
+ },
8476
8533
  COMPLETE_TASK: SHARED_TOOLS.COMPLETE_TASK,
8477
8534
  SEND_MESSAGE: SHARED_TOOLS.SEND_MESSAGE,
8478
8535
  PROPOSE: SHARED_TOOLS.PROPOSE,
@@ -8938,22 +8995,25 @@ You are the orchestrator. Your job: turn human intent into approved tasks, then
8938
8995
 
8939
8996
  You do NOT claim tasks, complete tasks, or do work directly \u2014 you have no access to deskfree_start_task or deskfree_complete_task. Spawn a sub-agent for each approved task and pass it the taskId.
8940
8997
  - When a human writes in a task thread, decide: does it need bot action? If yes \u2192 reopen and spawn sub-agent. If it's just confirmation or deferred \u2014 leave it for now.
8941
- - Write task instructions as 3-8 bullet points max (bold, lists, inline code \u2014 no # headers). What to do, what done looks like, key constraints. Under 500 words \u2014 brief a contractor, not write a spec.
8998
+ - Propose tasks with 3-8 steps (short action phrases). Steps are the visual progress tracker for the worker. Add brief instructions only for context or constraints the steps don't capture.
8942
8999
  - Estimate token cost per task \u2014 consider files to read, reasoning, output.
8943
9000
  - One initiative per proposal \u2014 make multiple calls for multiple initiatives.
8944
9001
  - Initiative titles should reflect aspirations and outcomes, not activities. "AI Thought Leadership on LinkedIn" over "LinkedIn Content."
8945
9002
  - Initiative descriptions should be 2-3 sentences that make the human think "wow, this will enable my dreams." Reflect their ambition back to them. No headers, no phases, no formal structure. Aspirational, not operational.`;
8946
9003
  var DESKFREE_WORKER_DIRECTIVE = `## DeskFree Worker
8947
9004
  You are a worker sub-agent. Call \`deskfree_start_task\` with your taskId to claim and load context.
8948
- Tools: deskfree_start_task, deskfree_update_file, deskfree_complete_task, deskfree_send_message, deskfree_propose.
8949
- - Claim your task first with deskfree_start_task \u2014 this loads instructions, messages, and file context.
8950
- - Save work to linked files with deskfree_update_file. Build up incrementally \u2014 start with structure/outline, then flesh out. Send an "ask" for review before going deep. The human should see the shape before the details.
8951
- - Use deskfree_send_message with type "notify" for progress updates \u2014 what you're doing, what you found. Keep it brief.
8952
- - Use deskfree_send_message with type "ask" when you need human input OR when your work is done for review. This surfaces to the main thread. Terminate after sending an ask.
8953
- - When completing: pass "learnings" only if you have genuine new knowledge. WoW updates should be surgical \u2014 add or modify only the relevant section, do not restate existing content. Reasoning should be 1-2 sentences. Pass "followUps" as brief handoffs (title + 2-3 bullets each).
8954
- - Only complete when the human has confirmed or no review is needed.
8955
- - Write like a senior colleague giving a status update \u2014 not a report. 1-3 sentences for messages.
8956
- - On 409 or 404 errors: STOP. Do not retry the same taskId. Call deskfree_state to find available tasks.`;
9005
+ Tools: deskfree_start_task, deskfree_update_steps, deskfree_update_file, deskfree_complete_task, deskfree_send_message, deskfree_propose.
9006
+
9007
+ **After claiming a task, your first message should be how you plan to approach it.** Work one step at a time and share progress naturally \u2014 like updating a coworker.
9008
+
9009
+ - Claim your task first with deskfree_start_task \u2014 this loads steps, messages, and file context.
9010
+ - Use deskfree_update_steps to update step progress as you work. Send the full step list each time with updated statuses.
9011
+ - Save work to linked files with deskfree_update_file. Build up incrementally \u2014 start with structure/outline, then flesh out.
9012
+ - Use deskfree_send_message with type "notify" for progress updates. Keep it brief \u2014 1-3 sentences.
9013
+ - Use deskfree_send_message with type "ask" when you need human input OR when work is ready for review. Terminate after sending an ask.
9014
+ - Only complete (deskfree_complete_task with humanApproved: true) after the human has confirmed in the thread. Never self-complete without human response.
9015
+ - When completing: pass "learnings" only for genuine new knowledge. Pass "followUps" as brief handoffs.
9016
+ - On 409 or 404 errors: STOP. Do not retry. Call deskfree_state to find available tasks.`;
8957
9017
  function getDeskFreeContext(sessionKey) {
8958
9018
  const isWorker = sessionKey && (sessionKey.includes(":sub:") || sessionKey.includes(":spawn:") || sessionKey.includes(":run:"));
8959
9019
  const directive = isWorker ? DESKFREE_WORKER_DIRECTIVE : DESKFREE_AGENT_DIRECTIVE;
@@ -9091,6 +9151,9 @@ function trimTaskContext(result) {
9091
9151
  if (raw["substeps"]) {
9092
9152
  trimmed.substeps = raw["substeps"];
9093
9153
  }
9154
+ if (raw["steps"]) {
9155
+ trimmed.steps = raw["steps"];
9156
+ }
9094
9157
  if (raw["parentContext"]) {
9095
9158
  trimmed.parentContext = raw["parentContext"];
9096
9159
  }
@@ -9309,6 +9372,36 @@ function parseInitiative(raw) {
9309
9372
  }
9310
9373
  return void 0;
9311
9374
  }
9375
+ function makeUpdateStepsHandler(client) {
9376
+ return async (_id, params) => {
9377
+ try {
9378
+ const taskId = validateStringParam(params, "taskId", true);
9379
+ const rawSteps = params["steps"];
9380
+ if (!Array.isArray(rawSteps) || rawSteps.length === 0) {
9381
+ throw new Error("steps must be a non-empty array");
9382
+ }
9383
+ const steps = rawSteps.map((s) => {
9384
+ if (typeof s !== "object" || s === null) throw new Error("Invalid step");
9385
+ const obj = s;
9386
+ const label = typeof obj["label"] === "string" ? obj["label"].trim() : "";
9387
+ const status = typeof obj["status"] === "string" ? obj["status"] : "pending";
9388
+ if (!label) throw new Error("Step label is required");
9389
+ if (!["pending", "in_progress", "done"].includes(status)) {
9390
+ throw new Error(`Invalid step status: ${status}`);
9391
+ }
9392
+ return { label, status };
9393
+ });
9394
+ await client.updateSteps({ taskId, steps });
9395
+ const doneCount = steps.filter((s) => s.status === "done").length;
9396
+ return formatConfirmation(
9397
+ `Updated steps for task ${taskId} (${doneCount}/${steps.length} done)`,
9398
+ ["Step progress saved \u2014 continue working"]
9399
+ );
9400
+ } catch (err) {
9401
+ return errorResult(err);
9402
+ }
9403
+ };
9404
+ }
9312
9405
  function makeUpdateFileHandler(client) {
9313
9406
  return async (_id, params) => {
9314
9407
  try {
@@ -9356,8 +9449,10 @@ function makeCompleteTaskHandler(client) {
9356
9449
  }).filter((item) => item.title.length > 0);
9357
9450
  if (parsed.length > 0) followUps = parsed;
9358
9451
  }
9452
+ const humanApproved = params["humanApproved"] === true;
9359
9453
  const result = await client.completeTask({
9360
9454
  taskId,
9455
+ humanApproved,
9361
9456
  learnings,
9362
9457
  followUps
9363
9458
  });
@@ -9567,6 +9662,7 @@ ${s.criticalSection}`
9567
9662
  return errorResult(err);
9568
9663
  }
9569
9664
  }),
9665
+ createTool(WORKER_TOOLS.UPDATE_STEPS, makeUpdateStepsHandler(client)),
9570
9666
  createTool(WORKER_TOOLS.UPDATE_FILE, makeUpdateFileHandler(client)),
9571
9667
  createTool(WORKER_TOOLS.COMPLETE_TASK, makeCompleteTaskHandler(client)),
9572
9668
  createTool(WORKER_TOOLS.SEND_MESSAGE, makeSendMessageHandler(client)),