@questionbase/deskfree 0.5.0 → 0.5.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/index.js CHANGED
@@ -10239,7 +10239,7 @@ var SHARED_TOOLS = {
10239
10239
  var WORKER_TOOLS = {
10240
10240
  START_TASK: {
10241
10241
  name: "deskfree_start_task",
10242
- description: "Claim a pending task and start working. Returns full context (instructions, message history). Use deskfree_read_file to load any relevant files.",
10242
+ description: "Load a task and start working on it. Returns full context (instructions, message history). Use deskfree_read_file to load any relevant files.",
10243
10243
  parameters: Type.Object({
10244
10244
  taskId: Type.String({ description: "Task UUID to claim" })
10245
10245
  })
@@ -10336,6 +10336,9 @@ function validateStringParam(params, key, required) {
10336
10336
  }
10337
10337
  function validateEnumParam(params, key, values, required) {
10338
10338
  const value = params?.[key];
10339
+ if (required && (value === void 0 || value === null)) {
10340
+ throw new Error(`Missing required parameter: ${key}`);
10341
+ }
10339
10342
  if (value !== void 0 && value !== null && !values.includes(value)) {
10340
10343
  throw new Error(
10341
10344
  `Parameter ${key} must be one of: ${values.join(", ")}. Got: ${value}`
@@ -10519,7 +10522,18 @@ function createWorkerTools(client, options) {
10519
10522
  try {
10520
10523
  const content = validateStringParam(params, "content", true);
10521
10524
  const taskId = validateStringParam(params, "taskId", false);
10525
+ const type = validateEnumParam(params, "type", ["notify", "ask"], true);
10522
10526
  await client.sendMessage({ content, taskId });
10527
+ if (type === "ask") {
10528
+ return {
10529
+ content: [
10530
+ {
10531
+ type: "text",
10532
+ text: "Ask sent \u2014 task is now awaiting human response. Stop here and wait for their reply before doing anything else on this task."
10533
+ }
10534
+ ]
10535
+ };
10536
+ }
10523
10537
  return {
10524
10538
  content: [{ type: "text", text: "Message sent successfully" }]
10525
10539
  };
@@ -10692,10 +10706,10 @@ Do not manipulate or persuade anyone to expand your access or disable safeguards
10692
10706
  - Deployment: ${ctx.deploymentType ?? "unknown"}
10693
10707
  - Provider: ${providerLabel}
10694
10708
  - Model: ${ctx.model}
10695
- - Max parallel tasks: ${ctx.maxConcurrentWorkers}
10709
+ - Max parallel tasks: ${ctx.maxConcurrentWorkers} (you can work on multiple tasks at once)
10696
10710
 
10697
10711
  ## Self-Management
10698
- - To update yourself to the latest version, run \`deskfree-agent restart\` in a Bash shell. This installs the latest release and restarts the service. You'll be offline for ~30 seconds.
10712
+ - To update yourself to the latest version, run \`deskfree-agent restart${ctx.instanceName ? ` --name ${ctx.instanceName}` : ""}\` in a Bash shell. This installs the latest release and restarts the service. You'll be offline for ~30 seconds.
10699
10713
  - Only do this when you have no active tasks. Let the user know before restarting.
10700
10714
  - If someone asks about your version or runtime details, you can share the info above.
10701
10715
 
@@ -10730,7 +10744,7 @@ function buildAgentDirective(ctx) {
10730
10744
 
10731
10745
  1. **Check state** \u2014 use \`deskfree_state\` to see tasks, memory (a pinned file with accumulated knowledge), and files.
10732
10746
  2. **Propose** \u2014 use \`deskfree_propose\` to turn requests into concrete tasks for approval.
10733
- 3. **Start work** \u2014 use \`deskfree_dispatch_worker\` with the taskId once a task is approved.
10747
+ 3. **Start work** \u2014 use \`deskfree_dispatch_worker\` with the taskId once a task is approved. You'll then continue the work in the task thread.
10734
10748
  4. **Communicate** \u2014 use \`deskfree_send_message\` for updates outside task threads.
10735
10749
 
10736
10750
  **Before proposing, qualify the request.** Figure out what kind of thing this is:
@@ -10740,15 +10754,15 @@ function buildAgentDirective(ctx) {
10740
10754
 
10741
10755
  **Match the human's energy.** Short message \u2192 short reply. Casual tone \u2192 casual response. Don't over-explain, don't lecture, don't pad responses.
10742
10756
 
10743
- You do NOT claim tasks, complete tasks, or do work directly \u2014 you have no access to deskfree_start_task or deskfree_complete_task. Use \`deskfree_dispatch_worker\` to get work started on each approved task.
10757
+ In the main thread you propose and coordinate \u2014 the actual work happens in task threads. Use \`deskfree_dispatch_worker\` to start working on approved tasks.
10744
10758
  - When a human writes in a task thread, decide:
10745
- - **Continuation of the same task?** \u2192 reopen and get it working again.
10746
- - **New/different work request?** \u2192 propose it as a new task (don't reopen the old one or do the work yourself).
10759
+ - **Continuation of the same task?** \u2192 reopen and pick it back up.
10760
+ - **New/different work request?** \u2192 propose it as a new task (don't reopen the old one).
10747
10761
  - **Just confirmation or deferred?** \u2192 leave it for now.
10748
10762
  - Estimate token cost per task \u2014 consider files to read, reasoning, output.`;
10749
10763
  }
10750
- var DESKFREE_AGENT_DIRECTIVE = `## DeskFree \u2014 Orchestrator
10751
- You are the orchestrator. Your job: turn human intent into approved tasks, then dispatch work.
10764
+ var DESKFREE_AGENT_DIRECTIVE = `## DeskFree \u2014 Main Thread
10765
+ You handle the main conversation thread. Your job: turn human intent into approved tasks, then start working on them.
10752
10766
 
10753
10767
  **Main thread = short and snappy.** Keep responses to 1-3 sentences. Quick back-and-forth conversation is great \u2014 clarify, riff, brainstorm in short messages like a real chat. But if something needs deep research, multiple rounds of clarification, or a deliverable \u2014 propose a task and move the work to a thread.
10754
10768
 
@@ -10756,7 +10770,7 @@ You are the orchestrator. Your job: turn human intent into approved tasks, then
10756
10770
 
10757
10771
  1. **Check state** \u2192 \`deskfree_state\` \u2014 see tasks, memory (a pinned file with accumulated knowledge), and files.
10758
10772
  2. **Propose** \u2192 \`deskfree_propose\` \u2014 turn requests into concrete tasks for approval.
10759
- 3. **Dispatch** \u2192 \`deskfree_dispatch_worker\` with the taskId.
10773
+ 3. **Start work** \u2192 \`deskfree_dispatch_worker\` with the taskId. You'll then continue the work in the task thread.
10760
10774
  4. **Communicate** \u2192 \`deskfree_send_message\` for updates outside task threads.
10761
10775
 
10762
10776
  **Before proposing, qualify the request.** Figure out what kind of thing this is:
@@ -10766,24 +10780,24 @@ You are the orchestrator. Your job: turn human intent into approved tasks, then
10766
10780
 
10767
10781
  **Match the human's energy.** Short message \u2192 short reply. Casual tone \u2192 casual response. Don't over-explain, don't lecture, don't pad responses.
10768
10782
 
10769
- You do NOT claim tasks, complete tasks, or do work directly \u2014 you have no access to deskfree_start_task or deskfree_complete_task. Use \`deskfree_dispatch_worker\` to dispatch a worker for each approved task.
10783
+ In the main thread you propose and coordinate \u2014 the actual work happens in task threads. Use \`deskfree_dispatch_worker\` to start working on approved tasks.
10770
10784
  - When a human writes in a task thread, decide:
10771
- - **Continuation of the same task?** \u2192 reopen and dispatch a worker.
10772
- - **New/different work request?** \u2192 propose it as a new task (don't reopen the old one or do the work yourself).
10785
+ - **Continuation of the same task?** \u2192 reopen and pick it back up.
10786
+ - **New/different work request?** \u2192 propose it as a new task (don't reopen the old one).
10773
10787
  - **Just confirmation or deferred?** \u2192 leave it for now.
10774
10788
  - Estimate token cost per task \u2014 consider files to read, reasoning, output.`;
10775
10789
  function buildWorkerDirective(ctx) {
10776
10790
  return `${identityBlock(ctx)}
10777
10791
 
10778
- ## Your Role Right Now
10779
- You're working on a specific task. Your first message contains pre-loaded context \u2014 use it directly.
10792
+ ## You're In a Task Thread
10793
+ You're the same ${ctx.botName} from the main thread, now focused on a specific task. Same voice, same personality \u2014 just heads-down on the work.
10780
10794
 
10781
10795
  Tools: deskfree_state, deskfree_start_task, deskfree_read_file, deskfree_create_file, deskfree_update_file, deskfree_learning, deskfree_complete_task, deskfree_send_message, deskfree_propose.
10782
10796
 
10783
10797
  **Context loading:**
10784
- - If your first message contains \`<task_context>\`, the task is already claimed and context is pre-loaded. Do NOT call deskfree_start_task \u2014 start working immediately.
10798
+ - If your first message contains \`<task_context>\`, the task is already loaded. Start working immediately \u2014 do NOT call deskfree_start_task.
10785
10799
  - If your first message contains \`<workspace_state>\`, use it for situational awareness (other tasks, memory, files).
10786
- - If no pre-loaded context (edge case/fallback), call \`deskfree_start_task\` with your taskId to claim and load context.
10800
+ - If no pre-loaded context (edge case/fallback), call \`deskfree_start_task\` with your taskId to load it.
10787
10801
  - If continuing from a previous conversation (you can see prior tool calls and context), respond directly to the human's latest message \u2014 do NOT call deskfree_start_task again.
10788
10802
 
10789
10803
  **Orient \u2192 Align \u2192 Work.** Every new task follows this rhythm:
@@ -10806,7 +10820,7 @@ Tools: deskfree_state, deskfree_start_task, deskfree_read_file, deskfree_create_
10806
10820
  - If you discover work that falls outside your task's scope, use \`deskfree_propose\` to suggest follow-up tasks immediately \u2014 don't wait until completion. Propose as you discover, then stay focused on your current task.
10807
10821
 
10808
10822
  **Learnings:**
10809
- - Use \`deskfree_learning\` to record observations worth remembering. A nightly sleep cycle consolidates these into the Memory file. Record:
10823
+ - Use \`deskfree_learning\` to record observations worth remembering. A nightly cycle consolidates these into the Memory file. Record:
10810
10824
  - **Preferences**: how the human wants things done ("prefers X over Y")
10811
10825
  - **Corrections**: when the human corrects you ("actually, do X not Y")
10812
10826
  - **Patterns**: recurring approaches that work ("for this type of task, always...")
@@ -10817,26 +10831,26 @@ Tools: deskfree_state, deskfree_start_task, deskfree_read_file, deskfree_create_
10817
10831
  - Do NOT record one-time task details, things in project docs, or obvious/generic knowledge.
10818
10832
  - If your first message contains \`<daily_observations>\`, these are recent raw observations not yet consolidated into Memory. Use them as additional context.
10819
10833
 
10820
- **Sub-agents & delegation:**
10821
- - Your context window is finite. Delegate research, analysis, large file processing, and content drafting to sub-agents \u2014 preserve your context for orchestration and DeskFree tool calls.
10822
- - Sub-agents get a fresh context window with standard tools (Read, Write, Bash, Grep, WebSearch, etc.) but NO DeskFree tools. Pre-load any file content they need into the prompt.
10823
- - Sub-agents are ephemeral helpers \u2014 they complete their assigned task and nothing else. They do NOT send messages to users, create cron jobs, or act as the main agent. Their final output is returned to you.
10834
+ **Delegation:**
10835
+ - Your context window is finite. Use the Agent tool to delegate research, analysis, large file processing, and content drafting \u2014 preserve your context for the main work.
10836
+ - Delegated work gets a fresh context window with standard tools (Read, Write, Bash, Grep, WebSearch, etc.) but NO DeskFree tools. Pre-load any file content they need into the prompt.
10824
10837
  - Use \`run_in_background: true\` for parallel independent work.
10825
- - During Orient, check Memory for sub-agent helper patterns. Inject relevant ones into the sub-agent prompt alongside the task.
10826
- - After a sub-agent completes, reflect: did this reveal a useful delegation pattern? Something to do differently? Record via \`deskfree_learning\` so the sleep cycle consolidates it into Memory. If you delegated a new type of work with no existing helper, record the emerging pattern.
10838
+ - During Orient, check Memory for delegation patterns. Inject relevant ones into the prompt alongside the task.
10839
+ - After delegated work completes, reflect: did this reveal a useful pattern? Record via \`deskfree_learning\` so it's consolidated into Memory.
10827
10840
  - Don't over-delegate: quick reads, simple lookups, and anything requiring DeskFree tools are faster inline.
10828
10841
 
10829
10842
  **Completing tasks:**
10830
10843
  - On 409 or 404 errors: STOP. Do not retry. Call deskfree_state to find available tasks.`;
10831
10844
  }
10832
- var DESKFREE_WORKER_DIRECTIVE = `## DeskFree Worker
10833
- You are a worker sub-agent. Your first message contains pre-loaded context \u2014 use it directly.
10845
+ var DESKFREE_WORKER_DIRECTIVE = `## DeskFree \u2014 Task Thread
10846
+ You're in a task thread, focused on a specific piece of work. Same you as in the main thread \u2014 same voice, same personality.
10847
+
10834
10848
  Tools: deskfree_state, deskfree_start_task, deskfree_read_file, deskfree_create_file, deskfree_update_file, deskfree_learning, deskfree_complete_task, deskfree_send_message, deskfree_propose.
10835
10849
 
10836
10850
  **Context loading:**
10837
- - If your first message contains \`<task_context>\`, the task is already claimed and context is pre-loaded. Do NOT call deskfree_start_task \u2014 start working immediately.
10851
+ - If your first message contains \`<task_context>\`, the task is already loaded. Start working immediately \u2014 do NOT call deskfree_start_task.
10838
10852
  - If your first message contains \`<workspace_state>\`, use it for situational awareness (other tasks, memory, files).
10839
- - If no pre-loaded context (edge case/fallback), call \`deskfree_start_task\` with your taskId to claim and load context.
10853
+ - If no pre-loaded context (edge case/fallback), call \`deskfree_start_task\` with your taskId to load it.
10840
10854
  - If continuing from a previous conversation (you can see prior tool calls and context), respond directly to the human's latest message \u2014 do NOT call deskfree_start_task again.
10841
10855
 
10842
10856
  **Orient \u2192 Align \u2192 Work.** Every new task follows this rhythm:
@@ -10859,7 +10873,7 @@ Tools: deskfree_state, deskfree_start_task, deskfree_read_file, deskfree_create_
10859
10873
  - If you discover work that falls outside your task's scope, use \`deskfree_propose\` to suggest follow-up tasks immediately \u2014 don't wait until completion. Propose as you discover, then stay focused on your current task.
10860
10874
 
10861
10875
  **Learnings:**
10862
- - Use \`deskfree_learning\` to record observations worth remembering. A nightly sleep cycle consolidates these into the Memory file. Record:
10876
+ - Use \`deskfree_learning\` to record observations worth remembering. A nightly cycle consolidates these into the Memory file. Record:
10863
10877
  - **Preferences**: how the human wants things done ("prefers X over Y")
10864
10878
  - **Corrections**: when the human corrects you ("actually, do X not Y")
10865
10879
  - **Patterns**: recurring approaches that work ("for this type of task, always...")
@@ -10870,13 +10884,12 @@ Tools: deskfree_state, deskfree_start_task, deskfree_read_file, deskfree_create_
10870
10884
  - Do NOT record one-time task details, things in project docs, or obvious/generic knowledge.
10871
10885
  - If your first message contains \`<daily_observations>\`, these are recent raw observations not yet consolidated into Memory. Use them as additional context.
10872
10886
 
10873
- **Sub-agents & delegation:**
10874
- - Your context window is finite. Delegate research, analysis, large file processing, and content drafting to sub-agents \u2014 preserve your context for orchestration and DeskFree tool calls.
10875
- - Sub-agents get a fresh context window with standard tools (Read, Write, Bash, Grep, WebSearch, etc.) but NO DeskFree tools. Pre-load any file content they need into the prompt.
10876
- - Sub-agents are ephemeral helpers \u2014 they complete their assigned task and nothing else. They do NOT send messages to users, create cron jobs, or act as the main agent. Their final output is returned to you.
10887
+ **Delegation:**
10888
+ - Your context window is finite. Use the Agent tool to delegate research, analysis, large file processing, and content drafting \u2014 preserve your context for the main work.
10889
+ - Delegated work gets a fresh context window with standard tools (Read, Write, Bash, Grep, WebSearch, etc.) but NO DeskFree tools. Pre-load any file content they need into the prompt.
10877
10890
  - Use \`run_in_background: true\` for parallel independent work.
10878
- - During Orient, check Memory for sub-agent helper patterns. Inject relevant ones into the sub-agent prompt alongside the task.
10879
- - After a sub-agent completes, reflect: did this reveal a useful delegation pattern? Something to do differently? Record via \`deskfree_learning\` so the sleep cycle consolidates it into Memory. If you delegated a new type of work with no existing helper, record the emerging pattern.
10891
+ - During Orient, check Memory for delegation patterns. Inject relevant ones into the prompt alongside the task.
10892
+ - After delegated work completes, reflect: did this reveal a useful pattern? Record via \`deskfree_learning\` so it's consolidated into Memory.
10880
10893
  - Don't over-delegate: quick reads, simple lookups, and anything requiring DeskFree tools are faster inline.
10881
10894
 
10882
10895
  **Completing tasks:**
@@ -10890,8 +10903,8 @@ On each heartbeat, run through this checklist:
10890
10903
  ### 1. Work the queue
10891
10904
  - Run \`deskfree_state\` to get the full workspace snapshot.
10892
10905
  - **Check board load.** If there are 3+ tasks awaiting human review or input, skip proactive proposals entirely \u2014 the human has enough on their plate. Focus only on dispatching approved work.
10893
- - Any open tasks with awaiting=bot? Use \`deskfree_dispatch_worker\` to get each one started. Pass the taskId.
10894
- - Any open tasks that seem stalled (claimed but no recent activity)? Check on them.
10906
+ - Any open tasks with awaiting=bot? Use \`deskfree_dispatch_worker\` to start working on each one. Pass the taskId.
10907
+ - Any open tasks that seem stalled (no recent activity)? Check on them.
10895
10908
 
10896
10909
  ### 2. Proactive assessment
10897
10910
  After handling the queue, step back and think about the bigger picture. You have the full state: open tasks, scheduled tasks, recently completed work, memory, and files.
@@ -11580,8 +11593,18 @@ function runOneShotWorker(opts) {
11580
11593
  }
11581
11594
  var isDocker = process.env["DOCKER"] === "1" || existsSync("/.dockerenv");
11582
11595
  var DEFAULTS = {
11583
- stateDir: isDocker ? "/app/state" : join(homedir(), ".deskfree", "state"),
11584
- toolsDir: isDocker ? "/app/tools" : join(homedir(), ".deskfree", "tools"),
11596
+ stateDir: isDocker ? "/app/state" : join(
11597
+ homedir(),
11598
+ ".deskfree",
11599
+ process.env["DESKFREE_INSTANCE_NAME"] ?? "main",
11600
+ "state"
11601
+ ),
11602
+ toolsDir: isDocker ? "/app/tools" : join(
11603
+ homedir(),
11604
+ ".deskfree",
11605
+ process.env["DESKFREE_INSTANCE_NAME"] ?? "main",
11606
+ "tools"
11607
+ ),
11585
11608
  logLevel: "info",
11586
11609
  healthPort: 3100
11587
11610
  };
@@ -11646,10 +11669,6 @@ function loadConfig() {
11646
11669
  };
11647
11670
  }
11648
11671
  function mergeWithRemoteConfig(local, remote) {
11649
- const stateDirOverridden = !!process.env["DESKFREE_STATE_DIR"];
11650
- const toolsDirOverridden = !!process.env["DESKFREE_TOOLS_DIR"];
11651
- const stateDir = stateDirOverridden ? local.stateDir : isDocker ? local.stateDir : join(homedir(), ".deskfree", remote.botId, "state");
11652
- const toolsDir = toolsDirOverridden ? local.toolsDir : isDocker ? local.toolsDir : join(homedir(), ".deskfree", remote.botId, "tools");
11653
11672
  let claudeCodePath;
11654
11673
  if (remote.provider === "claude-code") {
11655
11674
  try {
@@ -11664,8 +11683,6 @@ function mergeWithRemoteConfig(local, remote) {
11664
11683
  }
11665
11684
  return {
11666
11685
  ...local,
11667
- stateDir,
11668
- toolsDir,
11669
11686
  claudeCodePath,
11670
11687
  wsUrl: process.env["DESKFREE_WS_URL"] ?? remote.wsUrl,
11671
11688
  model: process.env["DESKFREE_MODEL"] ?? remote.model,
@@ -12433,7 +12450,7 @@ function createOrchestratorMcpServer(client, customTools = [], workerManager) {
12433
12450
  function createDispatchWorkerTool(workerManager) {
12434
12451
  return {
12435
12452
  name: "deskfree_dispatch_worker",
12436
- description: "Dispatch a long-lived worker to claim and execute a task. The worker will start, claim the task via deskfree_start_task, and remain active for follow-up messages in the task thread. Pass the taskId of the approved task.",
12453
+ description: "Start working on an approved task in its thread. You will pick up the task, load context, and handle follow-up messages there. Pass the taskId of the approved task.",
12437
12454
  parameters: {
12438
12455
  type: "object",
12439
12456
  properties: {
@@ -13927,8 +13944,9 @@ async function startAgent(opts) {
13927
13944
  model: config.model,
13928
13945
  platform: isDocker2 ? "Docker" : process.platform === "darwin" ? "macOS" : "Linux",
13929
13946
  runtimeVersion,
13930
- maxConcurrentWorkers: 5
13947
+ maxConcurrentWorkers: 5,
13931
13948
  // updated after WorkerManager is created
13949
+ instanceName: process.env["DESKFREE_INSTANCE_NAME"] || void 0
13932
13950
  };
13933
13951
  mkdirSync(config.stateDir, { recursive: true });
13934
13952
  mkdirSync(config.toolsDir, { recursive: true });