@cleocode/core 2026.3.73 → 2026.3.74

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
@@ -631,6 +631,13 @@ var init_discovery = __esm({
631
631
  });
632
632
 
633
633
  // packages/core/src/logger.ts
634
+ var logger_exports = {};
635
+ __export(logger_exports, {
636
+ closeLogger: () => closeLogger,
637
+ getLogDir: () => getLogDir,
638
+ getLogger: () => getLogger,
639
+ initLogger: () => initLogger
640
+ });
634
641
  import { existsSync as existsSync2 } from "node:fs";
635
642
  import { dirname, join as join3 } from "node:path";
636
643
  import pino from "pino";
@@ -21512,6 +21519,54 @@ var init_codebase_map = __esm({
21512
21519
  }
21513
21520
  });
21514
21521
 
21522
+ // packages/core/src/tasks/dependency-check.ts
21523
+ function getUnresolvedDeps(taskId, tasks2) {
21524
+ const task = tasks2.find((t) => t.id === taskId);
21525
+ if (!task?.depends?.length) return [];
21526
+ const completedIds = new Set(
21527
+ tasks2.filter((t) => t.status === "done" || t.status === "cancelled").map((t) => t.id)
21528
+ );
21529
+ return task.depends.filter((depId) => !completedIds.has(depId));
21530
+ }
21531
+ function topologicalSort2(tasks2) {
21532
+ const inDegree = /* @__PURE__ */ new Map();
21533
+ const adjList = /* @__PURE__ */ new Map();
21534
+ for (const task of tasks2) {
21535
+ inDegree.set(task.id, 0);
21536
+ adjList.set(task.id, []);
21537
+ }
21538
+ for (const task of tasks2) {
21539
+ if (!task.depends?.length) continue;
21540
+ for (const depId of task.depends) {
21541
+ if (adjList.has(depId)) {
21542
+ adjList.get(depId).push(task.id);
21543
+ inDegree.set(task.id, (inDegree.get(task.id) ?? 0) + 1);
21544
+ }
21545
+ }
21546
+ }
21547
+ const queue = [];
21548
+ for (const [id, degree] of inDegree) {
21549
+ if (degree === 0) queue.push(id);
21550
+ }
21551
+ const sorted = [];
21552
+ while (queue.length > 0) {
21553
+ const id = queue.shift();
21554
+ sorted.push(id);
21555
+ for (const dependent of adjList.get(id) ?? []) {
21556
+ const newDegree = (inDegree.get(dependent) ?? 1) - 1;
21557
+ inDegree.set(dependent, newDegree);
21558
+ if (newDegree === 0) queue.push(dependent);
21559
+ }
21560
+ }
21561
+ if (sorted.length !== tasks2.length) return null;
21562
+ return sorted;
21563
+ }
21564
+ var init_dependency_check = __esm({
21565
+ "packages/core/src/tasks/dependency-check.ts"() {
21566
+ "use strict";
21567
+ }
21568
+ });
21569
+
21515
21570
  // packages/core/src/tasks/hierarchy.ts
21516
21571
  function getParentChain(taskId, tasks2) {
21517
21572
  const chain = [];
@@ -24958,7 +25013,150 @@ var init_registry3 = __esm({
24958
25013
  }
24959
25014
  });
24960
25015
 
25016
+ // packages/core/src/task-work/index.ts
25017
+ var task_work_exports = {};
25018
+ __export(task_work_exports, {
25019
+ currentTask: () => currentTask,
25020
+ getTaskHistory: () => getTaskHistory,
25021
+ getWorkHistory: () => getWorkHistory,
25022
+ startTask: () => startTask,
25023
+ stopTask: () => stopTask
25024
+ });
25025
+ async function currentTask(cwd, accessor) {
25026
+ const acc = accessor ?? await getAccessor(cwd);
25027
+ const focus = await acc.getMetaValue("focus_state");
25028
+ return {
25029
+ currentTask: focus?.currentTask ?? null,
25030
+ currentPhase: focus?.currentPhase ?? null,
25031
+ sessionNote: focus?.sessionNote ?? null,
25032
+ nextAction: focus?.nextAction ?? null
25033
+ };
25034
+ }
25035
+ async function startTask(taskId, cwd, accessor) {
25036
+ if (!taskId) {
25037
+ throw new CleoError(2 /* INVALID_INPUT */, "Task ID is required");
25038
+ }
25039
+ const acc = accessor ?? await getAccessor(cwd);
25040
+ const task = await acc.loadSingleTask(taskId);
25041
+ if (!task) {
25042
+ throw new CleoError(4 /* NOT_FOUND */, `Task not found: ${taskId}`, {
25043
+ fix: `Use 'cleo find "${taskId}"' to search`
25044
+ });
25045
+ }
25046
+ const { tasks: allTasks } = await acc.queryTasks({});
25047
+ const unresolvedDeps = getUnresolvedDeps(taskId, allTasks);
25048
+ if (unresolvedDeps.length > 0) {
25049
+ throw new CleoError(
25050
+ 5 /* DEPENDENCY_ERROR */,
25051
+ `Task ${taskId} is blocked by unresolved dependencies: ${unresolvedDeps.join(", ")}`,
25052
+ {
25053
+ fix: `Complete blockers first: ${unresolvedDeps.map((d) => `cleo complete ${d}`).join(", ")}`
25054
+ }
25055
+ );
25056
+ }
25057
+ const focus = await acc.getMetaValue("focus_state") ?? {};
25058
+ const previousTask = focus.currentTask ?? null;
25059
+ focus.currentTask = taskId;
25060
+ focus.currentPhase = task.phase ?? null;
25061
+ const noteEntry = {
25062
+ note: `Started work on ${taskId}: ${task.title}`,
25063
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
25064
+ };
25065
+ if (!focus.sessionNotes) {
25066
+ focus.sessionNotes = [];
25067
+ }
25068
+ focus.sessionNotes.push(noteEntry);
25069
+ await acc.setMetaValue("focus_state", focus);
25070
+ await logOperation(
25071
+ "task_start",
25072
+ taskId,
25073
+ {
25074
+ previousTask,
25075
+ title: task.title
25076
+ },
25077
+ accessor
25078
+ );
25079
+ const { hooks: hooks2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
25080
+ hooks2.dispatch("PreToolUse", cwd ?? process.cwd(), {
25081
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
25082
+ taskId,
25083
+ taskTitle: task.title
25084
+ }).catch(() => {
25085
+ });
25086
+ return {
25087
+ taskId,
25088
+ taskTitle: task.title,
25089
+ previousTask
25090
+ };
25091
+ }
25092
+ async function stopTask(cwd, accessor) {
25093
+ const acc = accessor ?? await getAccessor(cwd);
25094
+ const focus = await acc.getMetaValue("focus_state");
25095
+ const previousTask = focus?.currentTask ?? null;
25096
+ if (!focus) {
25097
+ return { previousTask: null };
25098
+ }
25099
+ const taskId = focus.currentTask;
25100
+ const task = taskId ? await acc.loadSingleTask(taskId) : void 0;
25101
+ focus.currentTask = null;
25102
+ focus.nextAction = null;
25103
+ const now = (/* @__PURE__ */ new Date()).toISOString();
25104
+ if (taskId && task) {
25105
+ const { hooks: hooks2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
25106
+ hooks2.dispatch("PostToolUse", cwd ?? process.cwd(), {
25107
+ timestamp: now,
25108
+ taskId,
25109
+ taskTitle: task.title,
25110
+ status: "done"
25111
+ }).catch(() => {
25112
+ });
25113
+ }
25114
+ await acc.setMetaValue("focus_state", focus);
25115
+ await logOperation(
25116
+ "task_stop",
25117
+ previousTask ?? "none",
25118
+ {
25119
+ previousTask
25120
+ },
25121
+ accessor
25122
+ );
25123
+ return { previousTask };
25124
+ }
25125
+ async function getWorkHistory(cwd, accessor) {
25126
+ const acc = accessor ?? await getAccessor(cwd);
25127
+ const focus = await acc.getMetaValue("focus_state");
25128
+ const notes = focus?.sessionNotes ?? [];
25129
+ const history = [];
25130
+ for (const note of notes) {
25131
+ const match = note.note.match(/^(?:Focus set to|Started work on) (T\d+)/);
25132
+ if (match) {
25133
+ history.push({
25134
+ taskId: match[1],
25135
+ timestamp: note.timestamp
25136
+ });
25137
+ }
25138
+ }
25139
+ return history.reverse();
25140
+ }
25141
+ var getTaskHistory;
25142
+ var init_task_work = __esm({
25143
+ "packages/core/src/task-work/index.ts"() {
25144
+ "use strict";
25145
+ init_src();
25146
+ init_errors3();
25147
+ init_data_accessor();
25148
+ init_add();
25149
+ init_dependency_check();
25150
+ init_handlers();
25151
+ getTaskHistory = getWorkHistory;
25152
+ }
25153
+ });
25154
+
24961
25155
  // packages/core/src/tasks/complete.ts
25156
+ var complete_exports = {};
25157
+ __export(complete_exports, {
25158
+ completeTask: () => completeTask
25159
+ });
24962
25160
  function isVerificationGate(value) {
24963
25161
  return VERIFICATION_GATES.has(value);
24964
25162
  }
@@ -40866,50 +41064,8 @@ async function maybeExtractLearning(taskId, task, verification, confidenceScore,
40866
41064
  // packages/core/src/intelligence/impact.ts
40867
41065
  init_data_accessor();
40868
41066
 
40869
- // packages/core/src/tasks/dependency-check.ts
40870
- function getUnresolvedDeps(taskId, tasks2) {
40871
- const task = tasks2.find((t) => t.id === taskId);
40872
- if (!task?.depends?.length) return [];
40873
- const completedIds = new Set(
40874
- tasks2.filter((t) => t.status === "done" || t.status === "cancelled").map((t) => t.id)
40875
- );
40876
- return task.depends.filter((depId) => !completedIds.has(depId));
40877
- }
40878
- function topologicalSort2(tasks2) {
40879
- const inDegree = /* @__PURE__ */ new Map();
40880
- const adjList = /* @__PURE__ */ new Map();
40881
- for (const task of tasks2) {
40882
- inDegree.set(task.id, 0);
40883
- adjList.set(task.id, []);
40884
- }
40885
- for (const task of tasks2) {
40886
- if (!task.depends?.length) continue;
40887
- for (const depId of task.depends) {
40888
- if (adjList.has(depId)) {
40889
- adjList.get(depId).push(task.id);
40890
- inDegree.set(task.id, (inDegree.get(task.id) ?? 0) + 1);
40891
- }
40892
- }
40893
- }
40894
- const queue = [];
40895
- for (const [id, degree] of inDegree) {
40896
- if (degree === 0) queue.push(id);
40897
- }
40898
- const sorted = [];
40899
- while (queue.length > 0) {
40900
- const id = queue.shift();
40901
- sorted.push(id);
40902
- for (const dependent of adjList.get(id) ?? []) {
40903
- const newDegree = (inDegree.get(dependent) ?? 1) - 1;
40904
- inDegree.set(dependent, newDegree);
40905
- if (newDegree === 0) queue.push(dependent);
40906
- }
40907
- }
40908
- if (sorted.length !== tasks2.length) return null;
40909
- return sorted;
40910
- }
40911
-
40912
41067
  // packages/core/src/tasks/graph-ops.ts
41068
+ init_dependency_check();
40913
41069
  function getCriticalPath(tasks2) {
40914
41070
  const activeTasks = tasks2.filter((t) => t.status !== "done" && t.status !== "cancelled");
40915
41071
  if (activeTasks.length === 0) return [];
@@ -46786,6 +46942,7 @@ __export(nexus_exports, {
46786
46942
  nexusSyncAll: () => nexusSyncAll,
46787
46943
  nexusUnregister: () => nexusUnregister,
46788
46944
  orphanDetection: () => orphanDetection,
46945
+ parseDirective: () => parseDirective,
46789
46946
  parseQuery: () => parseQuery,
46790
46947
  permissionLevel: () => permissionLevel,
46791
46948
  previewTransfer: () => previewTransfer,
@@ -46796,10 +46953,13 @@ __export(nexus_exports, {
46796
46953
  resolveCrossDeps: () => resolveCrossDeps,
46797
46954
  resolveProjectPath: () => resolveProjectPath2,
46798
46955
  resolveTask: () => resolveTask,
46956
+ routeDirective: () => routeDirective,
46799
46957
  searchAcrossProjects: () => searchAcrossProjects,
46800
46958
  setPermission: () => setPermission,
46801
46959
  syncGitignore: () => syncGitignore,
46802
- validateSyntax: () => validateSyntax
46960
+ validateSyntax: () => validateSyntax,
46961
+ workspaceAgents: () => workspaceAgents,
46962
+ workspaceStatus: () => workspaceStatus
46803
46963
  });
46804
46964
 
46805
46965
  // packages/core/src/nexus/deps.ts
@@ -48025,6 +48185,275 @@ async function executeTransferInternal(params) {
48025
48185
  return result;
48026
48186
  }
48027
48187
 
48188
+ // packages/core/src/nexus/workspace.ts
48189
+ init_src();
48190
+ init_errors3();
48191
+ init_data_accessor();
48192
+ init_registry3();
48193
+ var RATE_LIMIT_WINDOW_MS = 6e4;
48194
+ var RATE_LIMIT_MAX_OPS = 100;
48195
+ var rateLimitCounters = /* @__PURE__ */ new Map();
48196
+ function checkRateLimit(agentId) {
48197
+ const now = Date.now();
48198
+ const entry = rateLimitCounters.get(agentId);
48199
+ if (!entry || now - entry.windowStart > RATE_LIMIT_WINDOW_MS) {
48200
+ rateLimitCounters.set(agentId, { count: 1, windowStart: now });
48201
+ return;
48202
+ }
48203
+ entry.count++;
48204
+ if (entry.count > RATE_LIMIT_MAX_OPS) {
48205
+ throw new CleoError(
48206
+ 1 /* GENERAL_ERROR */,
48207
+ `Agent '${agentId}' exceeded rate limit: ${RATE_LIMIT_MAX_OPS} routing ops per ${RATE_LIMIT_WINDOW_MS / 1e3}s`
48208
+ );
48209
+ }
48210
+ }
48211
+ var DEFAULT_ACL = { authorizedAgents: ["*"] };
48212
+ async function loadProjectACL(projectPath) {
48213
+ try {
48214
+ const { loadConfig: loadConfig3 } = await Promise.resolve().then(() => (init_config(), config_exports));
48215
+ const config2 = await loadConfig3(projectPath);
48216
+ const agents = config2?.authorizedAgents;
48217
+ if (Array.isArray(agents) && agents.length > 0) {
48218
+ return { authorizedAgents: agents };
48219
+ }
48220
+ } catch {
48221
+ }
48222
+ return DEFAULT_ACL;
48223
+ }
48224
+ function isAuthorized(acl, agentId) {
48225
+ if (acl.authorizedAgents.includes("*")) return true;
48226
+ return acl.authorizedAgents.includes(agentId);
48227
+ }
48228
+ var TASK_REF_PATTERN = /\bT(\d+)\b/g;
48229
+ function parseDirective(message) {
48230
+ const content = message.content;
48231
+ const verbMatch = content.match(/^\/(\w+)/);
48232
+ if (!verbMatch) return null;
48233
+ const verb = verbMatch[1];
48234
+ const taskRefs = [];
48235
+ const pattern = new RegExp(TASK_REF_PATTERN.source, "g");
48236
+ for (const m of content.matchAll(pattern)) {
48237
+ taskRefs.push(`T${m[1]}`);
48238
+ }
48239
+ const metaRefs = message.metadata?.taskRefs;
48240
+ if (Array.isArray(metaRefs)) {
48241
+ for (const ref of metaRefs) {
48242
+ if (typeof ref === "string" && !taskRefs.includes(ref)) {
48243
+ taskRefs.push(ref);
48244
+ }
48245
+ }
48246
+ }
48247
+ if (taskRefs.length === 0) return null;
48248
+ return {
48249
+ verb,
48250
+ taskRefs,
48251
+ agentId: message.from,
48252
+ messageId: message.id,
48253
+ timestamp: message.timestamp
48254
+ };
48255
+ }
48256
+ var VERB_TO_OPERATION = {
48257
+ claim: "tasks.start",
48258
+ done: "tasks.complete",
48259
+ complete: "tasks.complete",
48260
+ blocked: "tasks.update",
48261
+ // Update status to blocked
48262
+ start: "tasks.start",
48263
+ stop: "tasks.stop"
48264
+ };
48265
+ async function routeDirective(directive) {
48266
+ checkRateLimit(directive.agentId);
48267
+ const results = [];
48268
+ const operation = VERB_TO_OPERATION[directive.verb];
48269
+ if (!operation) {
48270
+ return results;
48271
+ }
48272
+ const projects = await nexusList();
48273
+ for (const taskRef of directive.taskRefs) {
48274
+ const result = await routeSingleTask(taskRef, directive, operation, projects);
48275
+ results.push(result);
48276
+ }
48277
+ return results;
48278
+ }
48279
+ async function routeSingleTask(taskId, directive, operation, projects) {
48280
+ let targetProject = null;
48281
+ let targetAccessor = null;
48282
+ for (const project of projects) {
48283
+ try {
48284
+ const acc = await getAccessor(project.path);
48285
+ const { tasks: tasks2 } = await acc.queryTasks({});
48286
+ const task = tasks2.find((t) => t.id === taskId);
48287
+ if (task) {
48288
+ targetProject = project;
48289
+ targetAccessor = acc;
48290
+ break;
48291
+ }
48292
+ } catch {
48293
+ }
48294
+ }
48295
+ if (!targetProject || !targetAccessor) {
48296
+ return {
48297
+ success: false,
48298
+ project: "unknown",
48299
+ projectPath: "",
48300
+ taskId,
48301
+ operation,
48302
+ error: `Task ${taskId} not found in any registered project`
48303
+ };
48304
+ }
48305
+ const acl = await loadProjectACL(targetProject.path);
48306
+ if (!isAuthorized(acl, directive.agentId)) {
48307
+ return {
48308
+ success: false,
48309
+ project: targetProject.name,
48310
+ projectPath: targetProject.path,
48311
+ taskId,
48312
+ operation,
48313
+ error: `Agent '${directive.agentId}' not authorized to mutate project '${targetProject.name}'`
48314
+ };
48315
+ }
48316
+ try {
48317
+ await executeOperation(operation, taskId, targetProject.path, targetAccessor, directive);
48318
+ await logRouteAudit(directive, targetProject.name, taskId, operation, true);
48319
+ return {
48320
+ success: true,
48321
+ project: targetProject.name,
48322
+ projectPath: targetProject.path,
48323
+ taskId,
48324
+ operation
48325
+ };
48326
+ } catch (err) {
48327
+ const errorMsg = err instanceof Error ? err.message : String(err);
48328
+ await logRouteAudit(directive, targetProject.name, taskId, operation, false, errorMsg);
48329
+ return {
48330
+ success: false,
48331
+ project: targetProject.name,
48332
+ projectPath: targetProject.path,
48333
+ taskId,
48334
+ operation,
48335
+ error: errorMsg
48336
+ };
48337
+ }
48338
+ }
48339
+ async function executeOperation(operation, taskId, projectPath, accessor, directive) {
48340
+ switch (operation) {
48341
+ case "tasks.start": {
48342
+ const { startTask: startTask2 } = await Promise.resolve().then(() => (init_task_work(), task_work_exports));
48343
+ await startTask2(taskId, projectPath, accessor);
48344
+ break;
48345
+ }
48346
+ case "tasks.complete": {
48347
+ const { completeTask: completeTask2 } = await Promise.resolve().then(() => (init_complete(), complete_exports));
48348
+ await completeTask2(
48349
+ { taskId, notes: `Completed via Conduit directive from ${directive.agentId}` },
48350
+ projectPath,
48351
+ accessor
48352
+ );
48353
+ break;
48354
+ }
48355
+ case "tasks.stop": {
48356
+ const { stopTask: stopTask2 } = await Promise.resolve().then(() => (init_task_work(), task_work_exports));
48357
+ await stopTask2(projectPath, accessor);
48358
+ break;
48359
+ }
48360
+ case "tasks.update": {
48361
+ const { updateTask: updateTask2 } = await Promise.resolve().then(() => (init_update2(), update_exports));
48362
+ await updateTask2(
48363
+ { taskId, notes: `Marked blocked via Conduit directive from ${directive.agentId}` },
48364
+ projectPath,
48365
+ accessor
48366
+ );
48367
+ break;
48368
+ }
48369
+ }
48370
+ }
48371
+ async function logRouteAudit(directive, projectName, taskId, operation, success2, error40) {
48372
+ try {
48373
+ const { getLogger: getLogger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
48374
+ const log9 = getLogger2("nexus.route");
48375
+ const level = success2 ? "info" : "warn";
48376
+ log9[level](
48377
+ {
48378
+ directive: directive.verb,
48379
+ agentId: directive.agentId,
48380
+ messageId: directive.messageId,
48381
+ project: projectName,
48382
+ taskId,
48383
+ operation,
48384
+ success: success2,
48385
+ error: error40
48386
+ },
48387
+ `Conduit directive routed: ${directive.verb} ${taskId} \u2192 ${projectName} (${success2 ? "OK" : "FAILED"})`
48388
+ );
48389
+ } catch {
48390
+ }
48391
+ }
48392
+ async function workspaceStatus() {
48393
+ const projects = await nexusList();
48394
+ const summaries = [];
48395
+ const totals = { pending: 0, active: 0, done: 0, total: 0 };
48396
+ for (const project of projects) {
48397
+ try {
48398
+ const acc = await getAccessor(project.path);
48399
+ const { tasks: tasks2 } = await acc.queryTasks({});
48400
+ const counts = {
48401
+ pending: tasks2.filter((t) => t.status === "pending").length,
48402
+ active: tasks2.filter((t) => t.status === "active").length,
48403
+ done: tasks2.filter((t) => t.status === "done").length,
48404
+ total: tasks2.length
48405
+ };
48406
+ summaries.push({
48407
+ name: project.name,
48408
+ path: project.path,
48409
+ counts,
48410
+ health: project.healthStatus,
48411
+ lastSync: project.lastSync
48412
+ });
48413
+ totals.pending += counts.pending;
48414
+ totals.active += counts.active;
48415
+ totals.done += counts.done;
48416
+ totals.total += counts.total;
48417
+ } catch {
48418
+ summaries.push({
48419
+ name: project.name,
48420
+ path: project.path,
48421
+ counts: { pending: 0, active: 0, done: 0, total: 0 },
48422
+ health: "unreachable",
48423
+ lastSync: project.lastSync
48424
+ });
48425
+ }
48426
+ }
48427
+ return {
48428
+ projectCount: projects.length,
48429
+ projects: summaries,
48430
+ totals,
48431
+ computedAt: (/* @__PURE__ */ new Date()).toISOString()
48432
+ };
48433
+ }
48434
+ async function workspaceAgents() {
48435
+ const projects = await nexusList();
48436
+ const agents = [];
48437
+ for (const project of projects) {
48438
+ try {
48439
+ const { listAgentInstances: listAgentInstances2 } = await Promise.resolve().then(() => (init_registry2(), registry_exports2));
48440
+ const instances = await listAgentInstances2(void 0, project.path);
48441
+ for (const inst of instances) {
48442
+ agents.push({
48443
+ agentId: inst.id,
48444
+ agentType: inst.agentType,
48445
+ status: inst.status,
48446
+ project: project.name,
48447
+ taskId: inst.taskId ?? null,
48448
+ lastHeartbeat: inst.lastHeartbeat
48449
+ });
48450
+ }
48451
+ } catch {
48452
+ }
48453
+ }
48454
+ return agents;
48455
+ }
48456
+
48028
48457
  // packages/core/src/observability/index.ts
48029
48458
  var observability_exports = {};
48030
48459
  __export(observability_exports, {
@@ -60827,137 +61256,8 @@ async function uncancelTask(projectRoot, params) {
60827
61256
  };
60828
61257
  }
60829
61258
 
60830
- // packages/core/src/task-work/index.ts
60831
- var task_work_exports = {};
60832
- __export(task_work_exports, {
60833
- currentTask: () => currentTask,
60834
- getTaskHistory: () => getTaskHistory,
60835
- getWorkHistory: () => getWorkHistory,
60836
- startTask: () => startTask,
60837
- stopTask: () => stopTask
60838
- });
60839
- init_src();
60840
- init_errors3();
60841
- init_data_accessor();
60842
- init_add();
60843
- init_handlers();
60844
- async function currentTask(cwd, accessor) {
60845
- const acc = accessor ?? await getAccessor(cwd);
60846
- const focus = await acc.getMetaValue("focus_state");
60847
- return {
60848
- currentTask: focus?.currentTask ?? null,
60849
- currentPhase: focus?.currentPhase ?? null,
60850
- sessionNote: focus?.sessionNote ?? null,
60851
- nextAction: focus?.nextAction ?? null
60852
- };
60853
- }
60854
- async function startTask(taskId, cwd, accessor) {
60855
- if (!taskId) {
60856
- throw new CleoError(2 /* INVALID_INPUT */, "Task ID is required");
60857
- }
60858
- const acc = accessor ?? await getAccessor(cwd);
60859
- const task = await acc.loadSingleTask(taskId);
60860
- if (!task) {
60861
- throw new CleoError(4 /* NOT_FOUND */, `Task not found: ${taskId}`, {
60862
- fix: `Use 'cleo find "${taskId}"' to search`
60863
- });
60864
- }
60865
- const { tasks: allTasks } = await acc.queryTasks({});
60866
- const unresolvedDeps = getUnresolvedDeps(taskId, allTasks);
60867
- if (unresolvedDeps.length > 0) {
60868
- throw new CleoError(
60869
- 5 /* DEPENDENCY_ERROR */,
60870
- `Task ${taskId} is blocked by unresolved dependencies: ${unresolvedDeps.join(", ")}`,
60871
- {
60872
- fix: `Complete blockers first: ${unresolvedDeps.map((d) => `cleo complete ${d}`).join(", ")}`
60873
- }
60874
- );
60875
- }
60876
- const focus = await acc.getMetaValue("focus_state") ?? {};
60877
- const previousTask = focus.currentTask ?? null;
60878
- focus.currentTask = taskId;
60879
- focus.currentPhase = task.phase ?? null;
60880
- const noteEntry = {
60881
- note: `Started work on ${taskId}: ${task.title}`,
60882
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
60883
- };
60884
- if (!focus.sessionNotes) {
60885
- focus.sessionNotes = [];
60886
- }
60887
- focus.sessionNotes.push(noteEntry);
60888
- await acc.setMetaValue("focus_state", focus);
60889
- await logOperation(
60890
- "task_start",
60891
- taskId,
60892
- {
60893
- previousTask,
60894
- title: task.title
60895
- },
60896
- accessor
60897
- );
60898
- const { hooks: hooks2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
60899
- hooks2.dispatch("PreToolUse", cwd ?? process.cwd(), {
60900
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
60901
- taskId,
60902
- taskTitle: task.title
60903
- }).catch(() => {
60904
- });
60905
- return {
60906
- taskId,
60907
- taskTitle: task.title,
60908
- previousTask
60909
- };
60910
- }
60911
- async function stopTask(cwd, accessor) {
60912
- const acc = accessor ?? await getAccessor(cwd);
60913
- const focus = await acc.getMetaValue("focus_state");
60914
- const previousTask = focus?.currentTask ?? null;
60915
- if (!focus) {
60916
- return { previousTask: null };
60917
- }
60918
- const taskId = focus.currentTask;
60919
- const task = taskId ? await acc.loadSingleTask(taskId) : void 0;
60920
- focus.currentTask = null;
60921
- focus.nextAction = null;
60922
- const now = (/* @__PURE__ */ new Date()).toISOString();
60923
- if (taskId && task) {
60924
- const { hooks: hooks2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
60925
- hooks2.dispatch("PostToolUse", cwd ?? process.cwd(), {
60926
- timestamp: now,
60927
- taskId,
60928
- taskTitle: task.title,
60929
- status: "done"
60930
- }).catch(() => {
60931
- });
60932
- }
60933
- await acc.setMetaValue("focus_state", focus);
60934
- await logOperation(
60935
- "task_stop",
60936
- previousTask ?? "none",
60937
- {
60938
- previousTask
60939
- },
60940
- accessor
60941
- );
60942
- return { previousTask };
60943
- }
60944
- async function getWorkHistory(cwd, accessor) {
60945
- const acc = accessor ?? await getAccessor(cwd);
60946
- const focus = await acc.getMetaValue("focus_state");
60947
- const notes = focus?.sessionNotes ?? [];
60948
- const history = [];
60949
- for (const note of notes) {
60950
- const match = note.note.match(/^(?:Focus set to|Started work on) (T\d+)/);
60951
- if (match) {
60952
- history.push({
60953
- taskId: match[1],
60954
- timestamp: note.timestamp
60955
- });
60956
- }
60957
- }
60958
- return history.reverse();
60959
- }
60960
- var getTaskHistory = getWorkHistory;
61259
+ // packages/core/src/index.ts
61260
+ init_task_work();
60961
61261
 
60962
61262
  // packages/core/src/tasks/index.ts
60963
61263
  var tasks_exports = {};
@@ -65656,6 +65956,7 @@ async function restoreSession(projectRoot, snapshot, options = {}, accessor) {
65656
65956
 
65657
65957
  // packages/core/src/cleo.ts
65658
65958
  init_data_accessor();
65959
+ init_task_work();
65659
65960
  init_add();
65660
65961
  init_complete();
65661
65962
  init_update2();
@@ -65880,7 +66181,14 @@ var Cleo = class _Cleo {
65880
66181
  discover: (p) => discoverRelated(p.query, p.method, p.limit),
65881
66182
  search: (p) => searchAcrossProjects(p.pattern, p.project, p.limit),
65882
66183
  setPermission: (p) => setPermission(p.name, p.level),
65883
- sharingStatus: () => getSharingStatus()
66184
+ sharingStatus: () => getSharingStatus(),
66185
+ route: (message) => {
66186
+ const directive = parseDirective(message);
66187
+ if (!directive) return Promise.resolve([]);
66188
+ return routeDirective(directive);
66189
+ },
66190
+ workspaceStatus: () => workspaceStatus(),
66191
+ workspaceAgents: () => workspaceAgents()
65884
66192
  };
65885
66193
  }
65886
66194
  // === Agents ===
@@ -65941,6 +66249,7 @@ init_registry();
65941
66249
  init_brain_retrieval();
65942
66250
  init_brain_search();
65943
66251
  init_sessions();
66252
+ init_task_work();
65944
66253
  init_add();
65945
66254
  init_complete();
65946
66255
  init_update2();