@renxqoo/renx-code 0.0.4 → 0.0.5

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.
Files changed (209) hide show
  1. package/bin/renx.cjs +16 -0
  2. package/package.json +2 -45
  3. package/src/agent/runtime/runtime.context-usage.test.ts +4 -5
  4. package/src/agent/runtime/runtime.error-handling.test.ts +4 -5
  5. package/src/agent/runtime/runtime.test.ts +7 -4
  6. package/src/agent/runtime/runtime.ts +3 -9
  7. package/src/agent/runtime/runtime.usage-forwarding.test.ts +4 -5
  8. package/src/agent/runtime/source-modules.test.ts +16 -35
  9. package/src/agent/runtime/source-modules.ts +17 -0
  10. package/vendor/agent-root/src/agent/ENTERPRISE_ACCEPTANCE_CHECKLIST.md +95 -0
  11. package/vendor/agent-root/src/agent/ENTERPRISE_REALTIME.html +1345 -0
  12. package/vendor/agent-root/src/agent/ENTERPRISE_REALTIME.md +1353 -0
  13. package/vendor/agent-root/src/agent/ERROR_CONTRACT.md +60 -0
  14. package/vendor/agent-root/src/agent/TEST_COVERAGE_ANALYSIS.md +278 -0
  15. package/vendor/agent-root/src/agent/__test__/error-contract.test.ts +72 -0
  16. package/vendor/agent-root/src/agent/__test__/types.test.ts +137 -0
  17. package/vendor/agent-root/src/agent/agent/__test__/abort-runtime.test.ts +83 -0
  18. package/vendor/agent-root/src/agent/agent/__test__/callback-safety.test.ts +34 -0
  19. package/vendor/agent-root/src/agent/agent/__test__/compaction.test.ts +323 -0
  20. package/vendor/agent-root/src/agent/agent/__test__/concurrency.test.ts +290 -0
  21. package/vendor/agent-root/src/agent/agent/__test__/error-normalizer.test.ts +377 -0
  22. package/vendor/agent-root/src/agent/agent/__test__/error.test.ts +212 -0
  23. package/vendor/agent-root/src/agent/agent/__test__/fault-injection.test.ts +295 -0
  24. package/vendor/agent-root/src/agent/agent/__test__/index.test.ts +3607 -0
  25. package/vendor/agent-root/src/agent/agent/__test__/logger.test.ts +35 -0
  26. package/vendor/agent-root/src/agent/agent/__test__/message-utils.test.ts +517 -0
  27. package/vendor/agent-root/src/agent/agent/__test__/telemetry.test.ts +97 -0
  28. package/vendor/agent-root/src/agent/agent/__test__/timeout-budget.test.ts +479 -0
  29. package/vendor/agent-root/src/agent/agent/__test__/tool-call-merge.test.ts +80 -0
  30. package/vendor/agent-root/src/agent/agent/__test__/tool-execution-ledger.test.ts +76 -0
  31. package/vendor/agent-root/src/agent/agent/__test__/write-buffer.test.ts +173 -0
  32. package/vendor/agent-root/src/agent/agent/__test__/write-file-session.test.ts +109 -0
  33. package/vendor/agent-root/src/agent/agent/abort-runtime.ts +71 -0
  34. package/vendor/agent-root/src/agent/agent/callback-safety.ts +33 -0
  35. package/vendor/agent-root/src/agent/agent/compaction.ts +291 -0
  36. package/vendor/agent-root/src/agent/agent/concurrency.ts +103 -0
  37. package/vendor/agent-root/src/agent/agent/error-normalizer.ts +190 -0
  38. package/vendor/agent-root/src/agent/agent/error.ts +198 -0
  39. package/vendor/agent-root/src/agent/agent/index.ts +1772 -0
  40. package/vendor/agent-root/src/agent/agent/logger.ts +65 -0
  41. package/vendor/agent-root/src/agent/agent/message-utils.ts +101 -0
  42. package/vendor/agent-root/src/agent/agent/stream-events.ts +61 -0
  43. package/vendor/agent-root/src/agent/agent/telemetry.ts +123 -0
  44. package/vendor/agent-root/src/agent/agent/timeout-budget.ts +227 -0
  45. package/vendor/agent-root/src/agent/agent/tool-call-merge.ts +111 -0
  46. package/vendor/agent-root/src/agent/agent/tool-execution-ledger.ts +164 -0
  47. package/vendor/agent-root/src/agent/agent/write-buffer.ts +188 -0
  48. package/vendor/agent-root/src/agent/agent/write-file-session.ts +238 -0
  49. package/vendor/agent-root/src/agent/app/__test__/agent-app-service.test.ts +1053 -0
  50. package/vendor/agent-root/src/agent/app/__test__/minimal-agent-application.test.ts +158 -0
  51. package/vendor/agent-root/src/agent/app/__test__/sqlite-agent-app-store.test.ts +437 -0
  52. package/vendor/agent-root/src/agent/app/agent-app-service.ts +748 -0
  53. package/vendor/agent-root/src/agent/app/contracts.ts +109 -0
  54. package/vendor/agent-root/src/agent/app/index.ts +5 -0
  55. package/vendor/agent-root/src/agent/app/minimal-agent-application.ts +151 -0
  56. package/vendor/agent-root/src/agent/app/ports.ts +72 -0
  57. package/vendor/agent-root/src/agent/app/sqlite-agent-app-store.ts +1182 -0
  58. package/vendor/agent-root/src/agent/app/sqlite-client.ts +177 -0
  59. package/vendor/agent-root/src/agent/docs/cli-app-layer/00-README.md +36 -0
  60. package/vendor/agent-root/src/agent/docs/cli-app-layer/01-scope-and-goals.md +33 -0
  61. package/vendor/agent-root/src/agent/docs/cli-app-layer/02-architecture-overview.md +40 -0
  62. package/vendor/agent-root/src/agent/docs/cli-app-layer/03-domain-model-and-contracts.md +91 -0
  63. package/vendor/agent-root/src/agent/docs/cli-app-layer/04-ports-and-interfaces.md +116 -0
  64. package/vendor/agent-root/src/agent/docs/cli-app-layer/05-run-orchestration-and-state-machine.md +52 -0
  65. package/vendor/agent-root/src/agent/docs/cli-app-layer/06-cli-commands-and-ux.md +53 -0
  66. package/vendor/agent-root/src/agent/docs/cli-app-layer/07-storage-design-local.md +52 -0
  67. package/vendor/agent-root/src/agent/docs/cli-app-layer/08-error-and-observability.md +40 -0
  68. package/vendor/agent-root/src/agent/docs/cli-app-layer/09-security-and-policy-boundary.md +19 -0
  69. package/vendor/agent-root/src/agent/docs/cli-app-layer/10-test-plan-and-acceptance.md +28 -0
  70. package/vendor/agent-root/src/agent/docs/cli-app-layer/11-implementation-phases.md +26 -0
  71. package/vendor/agent-root/src/agent/docs/cli-app-layer/12-open-questions-and-risks.md +30 -0
  72. package/vendor/agent-root/src/agent/docs/cli-app-layer/13-sqlite-schema-fields-and-rationale.md +567 -0
  73. package/vendor/agent-root/src/agent/docs/cli-app-layer/14-project-flow-mermaid.md +583 -0
  74. package/vendor/agent-root/src/agent/docs/cli-app-layer/15-openclaw-style-project-blueprint.md +972 -0
  75. package/vendor/agent-root/src/agent/error-contract.ts +154 -0
  76. package/vendor/agent-root/src/agent/prompts/system.ts +246 -0
  77. package/vendor/agent-root/src/agent/prompts/system1.ts +208 -0
  78. package/vendor/agent-root/src/agent/storage/__test__/file-history-store.test.ts +98 -0
  79. package/vendor/agent-root/src/agent/storage/file-history-store.ts +313 -0
  80. package/vendor/agent-root/src/agent/storage/file-storage-config.ts +94 -0
  81. package/vendor/agent-root/src/agent/storage/file-system.ts +31 -0
  82. package/vendor/agent-root/src/agent/storage/file-write-service.ts +21 -0
  83. package/vendor/agent-root/src/agent/tool/__test__/base-tool.test.ts +413 -0
  84. package/vendor/agent-root/src/agent/tool/__test__/bash-policy.test.ts +356 -0
  85. package/vendor/agent-root/src/agent/tool/__test__/bash.mocked-coverage.test.ts +375 -0
  86. package/vendor/agent-root/src/agent/tool/__test__/bash.test.ts +372 -0
  87. package/vendor/agent-root/src/agent/tool/__test__/error.test.ts +108 -0
  88. package/vendor/agent-root/src/agent/tool/__test__/file-edit-tool.test.ts +258 -0
  89. package/vendor/agent-root/src/agent/tool/__test__/file-history-tools.test.ts +121 -0
  90. package/vendor/agent-root/src/agent/tool/__test__/file-read-tool.test.ts +210 -0
  91. package/vendor/agent-root/src/agent/tool/__test__/glob.test.ts +139 -0
  92. package/vendor/agent-root/src/agent/tool/__test__/grep.mocked-coverage.test.ts +456 -0
  93. package/vendor/agent-root/src/agent/tool/__test__/grep.test.ts +192 -0
  94. package/vendor/agent-root/src/agent/tool/__test__/lsp.test.ts +300 -0
  95. package/vendor/agent-root/src/agent/tool/__test__/outside-workspace-confirmation.test.ts +214 -0
  96. package/vendor/agent-root/src/agent/tool/__test__/path-security.test.ts +336 -0
  97. package/vendor/agent-root/src/agent/tool/__test__/skill-loader.test.ts +494 -0
  98. package/vendor/agent-root/src/agent/tool/__test__/skill-parser.test.ts +543 -0
  99. package/vendor/agent-root/src/agent/tool/__test__/skill-tool.test.ts +172 -0
  100. package/vendor/agent-root/src/agent/tool/__test__/task-concurrency-and-version.test.ts +116 -0
  101. package/vendor/agent-root/src/agent/tool/__test__/task-create-get-list-update.test.ts +267 -0
  102. package/vendor/agent-root/src/agent/tool/__test__/task-create.test.ts +519 -0
  103. package/vendor/agent-root/src/agent/tool/__test__/task-errors.test.ts +225 -0
  104. package/vendor/agent-root/src/agent/tool/__test__/task-output-blocking.test.ts +223 -0
  105. package/vendor/agent-root/src/agent/tool/__test__/task-output.test.ts +184 -0
  106. package/vendor/agent-root/src/agent/tool/__test__/task-parent-abort.test.ts +287 -0
  107. package/vendor/agent-root/src/agent/tool/__test__/task-real-runner-adapter.test.ts +190 -0
  108. package/vendor/agent-root/src/agent/tool/__test__/task-run-lifecycle.test.ts +352 -0
  109. package/vendor/agent-root/src/agent/tool/__test__/task-store-runner-branches.test.ts +395 -0
  110. package/vendor/agent-root/src/agent/tool/__test__/task-store.test.ts +391 -0
  111. package/vendor/agent-root/src/agent/tool/__test__/task-subagent-config-integration.test.ts +176 -0
  112. package/vendor/agent-root/src/agent/tool/__test__/task-subagent-config.test.ts +68 -0
  113. package/vendor/agent-root/src/agent/tool/__test__/task-tools-core-edges.test.ts +630 -0
  114. package/vendor/agent-root/src/agent/tool/__test__/task-tools-runtime-edges.test.ts +732 -0
  115. package/vendor/agent-root/src/agent/tool/__test__/task-types.test.ts +494 -0
  116. package/vendor/agent-root/src/agent/tool/__test__/task-utils-branches.test.ts +175 -0
  117. package/vendor/agent-root/src/agent/tool/__test__/tool-manager.test.ts +505 -0
  118. package/vendor/agent-root/src/agent/tool/__test__/types.test.ts +55 -0
  119. package/vendor/agent-root/src/agent/tool/__test__/web-fetch.test.ts +244 -0
  120. package/vendor/agent-root/src/agent/tool/__test__/web-search.test.ts +290 -0
  121. package/vendor/agent-root/src/agent/tool/__test__/write-file.test.ts +368 -0
  122. package/vendor/agent-root/src/agent/tool/base-tool.ts +345 -0
  123. package/vendor/agent-root/src/agent/tool/bash-policy.ts +636 -0
  124. package/vendor/agent-root/src/agent/tool/bash.ts +688 -0
  125. package/vendor/agent-root/src/agent/tool/error.ts +131 -0
  126. package/vendor/agent-root/src/agent/tool/file-edit-tool.ts +264 -0
  127. package/vendor/agent-root/src/agent/tool/file-history-list.ts +103 -0
  128. package/vendor/agent-root/src/agent/tool/file-history-restore.ts +149 -0
  129. package/vendor/agent-root/src/agent/tool/file-read-tool.ts +211 -0
  130. package/vendor/agent-root/src/agent/tool/glob.ts +171 -0
  131. package/vendor/agent-root/src/agent/tool/grep.ts +496 -0
  132. package/vendor/agent-root/src/agent/tool/lsp.ts +481 -0
  133. package/vendor/agent-root/src/agent/tool/path-security.ts +117 -0
  134. package/vendor/agent-root/src/agent/tool/search/common.ts +153 -0
  135. package/vendor/agent-root/src/agent/tool/skill/index.ts +13 -0
  136. package/vendor/agent-root/src/agent/tool/skill/loader.ts +229 -0
  137. package/vendor/agent-root/src/agent/tool/skill/parser.ts +124 -0
  138. package/vendor/agent-root/src/agent/tool/skill/types.ts +27 -0
  139. package/vendor/agent-root/src/agent/tool/skill-tool.ts +143 -0
  140. package/vendor/agent-root/src/agent/tool/task-create.ts +186 -0
  141. package/vendor/agent-root/src/agent/tool/task-errors.ts +42 -0
  142. package/vendor/agent-root/src/agent/tool/task-get.ts +116 -0
  143. package/vendor/agent-root/src/agent/tool/task-graph.ts +78 -0
  144. package/vendor/agent-root/src/agent/tool/task-list.ts +141 -0
  145. package/vendor/agent-root/src/agent/tool/task-mock-runner-adapter.ts +232 -0
  146. package/vendor/agent-root/src/agent/tool/task-output.ts +223 -0
  147. package/vendor/agent-root/src/agent/tool/task-parent-abort.ts +115 -0
  148. package/vendor/agent-root/src/agent/tool/task-real-runner-adapter.ts +336 -0
  149. package/vendor/agent-root/src/agent/tool/task-runner-adapter.ts +55 -0
  150. package/vendor/agent-root/src/agent/tool/task-stop.ts +187 -0
  151. package/vendor/agent-root/src/agent/tool/task-store.ts +217 -0
  152. package/vendor/agent-root/src/agent/tool/task-subagent-config.ts +149 -0
  153. package/vendor/agent-root/src/agent/tool/task-types.ts +264 -0
  154. package/vendor/agent-root/src/agent/tool/task-update.ts +315 -0
  155. package/vendor/agent-root/src/agent/tool/task.ts +209 -0
  156. package/vendor/agent-root/src/agent/tool/tool-manager.ts +362 -0
  157. package/vendor/agent-root/src/agent/tool/tool-prompts.ts +242 -0
  158. package/vendor/agent-root/src/agent/tool/types.ts +116 -0
  159. package/vendor/agent-root/src/agent/tool/web-fetch.ts +227 -0
  160. package/vendor/agent-root/src/agent/tool/web-search.ts +208 -0
  161. package/vendor/agent-root/src/agent/tool/write-file.ts +497 -0
  162. package/vendor/agent-root/src/agent/types.ts +232 -0
  163. package/vendor/agent-root/src/agent/utils/__tests__/index.test.ts +18 -0
  164. package/vendor/agent-root/src/agent/utils/__tests__/message-utils.test.ts +610 -0
  165. package/vendor/agent-root/src/agent/utils/__tests__/message.test.ts +223 -0
  166. package/vendor/agent-root/src/agent/utils/__tests__/token.test.ts +42 -0
  167. package/vendor/agent-root/src/agent/utils/index.ts +16 -0
  168. package/vendor/agent-root/src/agent/utils/message.ts +171 -0
  169. package/vendor/agent-root/src/agent/utils/token.ts +28 -0
  170. package/vendor/agent-root/src/config/__tests__/load-config-to-env.test.ts +129 -0
  171. package/vendor/agent-root/src/config/__tests__/loader.test.ts +247 -0
  172. package/vendor/agent-root/src/config/__tests__/runtime.test.ts +88 -0
  173. package/vendor/agent-root/src/config/index.ts +54 -0
  174. package/vendor/agent-root/src/config/loader.ts +431 -0
  175. package/vendor/agent-root/src/config/paths.ts +30 -0
  176. package/vendor/agent-root/src/config/runtime.ts +163 -0
  177. package/vendor/agent-root/src/config/types.ts +70 -0
  178. package/vendor/agent-root/src/logger/index.ts +57 -0
  179. package/vendor/agent-root/src/logger/logger.ts +819 -0
  180. package/vendor/agent-root/src/logger/types.ts +150 -0
  181. package/vendor/agent-root/src/providers/__tests__/errors.test.ts +441 -0
  182. package/vendor/agent-root/src/providers/__tests__/index.test.ts +16 -0
  183. package/vendor/agent-root/src/providers/__tests__/openai-compatible.options.test.ts +318 -0
  184. package/vendor/agent-root/src/providers/__tests__/openai-compatible.test.ts +600 -0
  185. package/vendor/agent-root/src/providers/__tests__/registry.test.ts +449 -0
  186. package/vendor/agent-root/src/providers/__tests__/responses-adapter.test.ts +298 -0
  187. package/vendor/agent-root/src/providers/adapters/__tests__/anthropic.test.ts +354 -0
  188. package/vendor/agent-root/src/providers/adapters/__tests__/kimi.test.ts +58 -0
  189. package/vendor/agent-root/src/providers/adapters/__tests__/standard.test.ts +261 -0
  190. package/vendor/agent-root/src/providers/adapters/anthropic.ts +572 -0
  191. package/vendor/agent-root/src/providers/adapters/base.ts +131 -0
  192. package/vendor/agent-root/src/providers/adapters/kimi.ts +48 -0
  193. package/vendor/agent-root/src/providers/adapters/responses.ts +732 -0
  194. package/vendor/agent-root/src/providers/adapters/standard.ts +120 -0
  195. package/vendor/agent-root/src/providers/http/__tests__/client.timeout.test.ts +313 -0
  196. package/vendor/agent-root/src/providers/http/client.ts +289 -0
  197. package/vendor/agent-root/src/providers/http/stream-parser.ts +109 -0
  198. package/vendor/agent-root/src/providers/index.ts +76 -0
  199. package/vendor/agent-root/src/providers/kimi-headers.ts +177 -0
  200. package/vendor/agent-root/src/providers/openai-compatible.ts +387 -0
  201. package/vendor/agent-root/src/providers/registry/model-config.ts +230 -0
  202. package/vendor/agent-root/src/providers/registry/provider-factory.ts +123 -0
  203. package/vendor/agent-root/src/providers/registry.ts +135 -0
  204. package/vendor/agent-root/src/providers/types/api.ts +284 -0
  205. package/vendor/agent-root/src/providers/types/config.ts +58 -0
  206. package/vendor/agent-root/src/providers/types/errors.ts +323 -0
  207. package/vendor/agent-root/src/providers/types/index.ts +72 -0
  208. package/vendor/agent-root/src/providers/types/provider.ts +45 -0
  209. package/vendor/agent-root/src/providers/types/registry.ts +88 -0
@@ -0,0 +1,630 @@
1
+ import * as os from 'node:os';
2
+ import * as path from 'node:path';
3
+ import * as fsPromises from 'node:fs/promises';
4
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
+ import { TaskCreateTool } from '../task-create';
6
+ import { TaskGetTool } from '../task-get';
7
+ import { TaskListTool } from '../task-list';
8
+ import { TaskStore } from '../task-store';
9
+ import { TaskUpdateTool } from '../task-update';
10
+ import type { TaskEntity } from '../task-types';
11
+
12
+ function parseOutput<T>(output: string | undefined): T {
13
+ return JSON.parse(output || '{}') as T;
14
+ }
15
+
16
+ function makeTask(overrides: Partial<TaskEntity> = {}): TaskEntity {
17
+ const now = 1000;
18
+ return {
19
+ id: overrides.id || 'task_x',
20
+ subject: overrides.subject || 'Subject',
21
+ description: overrides.description || 'Long enough description field.',
22
+ activeForm: overrides.activeForm || 'Active subject',
23
+ status: overrides.status || 'pending',
24
+ priority: overrides.priority || 'normal',
25
+ owner: overrides.owner === undefined ? null : overrides.owner,
26
+ blockedBy: overrides.blockedBy || [],
27
+ blocks: overrides.blocks || [],
28
+ progress: overrides.progress || 0,
29
+ checkpoints: overrides.checkpoints || [],
30
+ retryConfig: overrides.retryConfig || {
31
+ maxRetries: 3,
32
+ retryDelayMs: 100,
33
+ backoffMultiplier: 2,
34
+ retryOn: ['timeout'],
35
+ },
36
+ retryCount: overrides.retryCount || 0,
37
+ lastError: overrides.lastError,
38
+ lastErrorAt: overrides.lastErrorAt,
39
+ timeoutMs: overrides.timeoutMs,
40
+ tags: overrides.tags || [],
41
+ metadata: overrides.metadata || {},
42
+ history: overrides.history || [],
43
+ agentId: overrides.agentId,
44
+ createdAt: overrides.createdAt || now,
45
+ updatedAt: overrides.updatedAt || now,
46
+ startedAt: overrides.startedAt,
47
+ completedAt: overrides.completedAt,
48
+ cancelledAt: overrides.cancelledAt,
49
+ version: overrides.version || 1,
50
+ };
51
+ }
52
+
53
+ describe('task_create/task_get/task_list/task_update edge branches', () => {
54
+ let baseDir: string;
55
+ let store: TaskStore;
56
+ let taskCreate: TaskCreateTool;
57
+ let taskGet: TaskGetTool;
58
+ let taskList: TaskListTool;
59
+ let taskUpdate: TaskUpdateTool;
60
+
61
+ beforeEach(async () => {
62
+ baseDir = await fsPromises.mkdtemp(path.join(os.tmpdir(), 'renx-task-core-edge-'));
63
+ store = new TaskStore({ baseDir });
64
+ taskCreate = new TaskCreateTool({ store, defaultNamespace: 'def-ns' });
65
+ taskGet = new TaskGetTool({ store, defaultNamespace: 'def-ns' });
66
+ taskList = new TaskListTool({ store, defaultNamespace: 'def-ns' });
67
+ taskUpdate = new TaskUpdateTool({ store, defaultNamespace: 'def-ns' });
68
+ });
69
+
70
+ afterEach(async () => {
71
+ await fsPromises.rm(baseDir, { recursive: true, force: true });
72
+ });
73
+
74
+ it('covers task_create checkpoint/retry branches and concurrency metadata', async () => {
75
+ const defaultCreateTool = new TaskCreateTool();
76
+ expect(
77
+ defaultCreateTool.getConcurrencyLockKey({
78
+ subject: 's',
79
+ description: '0123456789a',
80
+ } as never)
81
+ ).toBe('taskns:default');
82
+
83
+ expect(taskCreate.getConcurrencyMode()).toBe('exclusive');
84
+ expect(
85
+ taskCreate.getConcurrencyLockKey({
86
+ subject: 's',
87
+ description: '0123456789a',
88
+ } as never)
89
+ ).toBe('taskns:def-ns');
90
+ expect(
91
+ taskCreate.getConcurrencyLockKey({
92
+ namespace: 'abc',
93
+ subject: 's',
94
+ description: '0123456789a',
95
+ } as never)
96
+ ).toBe('taskns:abc');
97
+
98
+ const created = await taskCreate.execute({
99
+ subject: 'Create with checkpoints',
100
+ description: 'Create with explicit checkpoints and retry config here.',
101
+ active_form: 'Actively creating checkpoints',
102
+ checkpoints: [
103
+ { id: 'c1', name: 'first', completed: true },
104
+ { id: 'c2', name: 'second', completed: false },
105
+ ],
106
+ retry_config: {
107
+ maxRetries: 9,
108
+ retryDelayMs: 200,
109
+ backoffMultiplier: 3,
110
+ retryOn: ['x', 'y'],
111
+ },
112
+ });
113
+ expect(created.success).toBe(true);
114
+ const payload = parseOutput<{
115
+ namespace: string;
116
+ task: {
117
+ checkpoints: Array<{ id: string; completed: boolean }>;
118
+ retryConfig: { maxRetries: number };
119
+ };
120
+ }>(created.output);
121
+ expect(payload.namespace).toBe('def-ns');
122
+ expect((payload as { task: { activeForm?: string } }).task.activeForm).toBe(
123
+ 'Actively creating checkpoints'
124
+ );
125
+ expect(payload.task.checkpoints).toEqual([
126
+ { id: 'c1', name: 'first', completed: true },
127
+ { id: 'c2', name: 'second', completed: false },
128
+ ]);
129
+ expect(payload.task.retryConfig.maxRetries).toBe(9);
130
+ });
131
+
132
+ it('covers task_create catch fallback when store throws non-prefixed error', async () => {
133
+ const fakeStore = {
134
+ normalizeNamespace: () => 'n1',
135
+ updateState: async () => {
136
+ throw 'raw failure';
137
+ },
138
+ } as unknown as TaskStore;
139
+ const tool = new TaskCreateTool({ store: fakeStore });
140
+ const result = await tool.execute({
141
+ namespace: 'n1',
142
+ subject: 'abc',
143
+ description: '0123456789abcd',
144
+ });
145
+ expect(result.success).toBe(false);
146
+ expect(result.output).toContain('TASK_OPERATION_FAILED');
147
+ });
148
+
149
+ it('covers task_get not-found, checkpoint progress, missing blocker/blocked branches', async () => {
150
+ const defaultGetTool = new TaskGetTool();
151
+ expect(defaultGetTool.getConcurrencyLockKey({ task_id: 'x' } as never)).toBe(
152
+ 'taskns:default:task:x'
153
+ );
154
+
155
+ expect(taskGet.getConcurrencyMode()).toBe('parallel-safe');
156
+ expect(taskGet.getConcurrencyLockKey({ task_id: 't1' } as never)).toBe('taskns:def-ns:task:t1');
157
+ expect(taskGet.getConcurrencyLockKey({ namespace: 'ns', task_id: 't2' } as never)).toBe(
158
+ 'taskns:ns:task:t2'
159
+ );
160
+
161
+ const missing = await taskGet.execute({
162
+ task_id: 'missing',
163
+ });
164
+ expect(missing.success).toBe(false);
165
+ expect(missing.output).toContain('TASK_NOT_FOUND');
166
+
167
+ const created = await taskCreate.execute({
168
+ namespace: 'g1',
169
+ subject: 'Task get detail',
170
+ description: 'Task get detail with checkpoints and links.',
171
+ checkpoints: [
172
+ { id: 'a', name: 'A', completed: true },
173
+ { id: 'b', name: 'B', completed: false },
174
+ ],
175
+ });
176
+ const taskId = parseOutput<{ task: { id: string } }>(created.output).task.id;
177
+
178
+ await store.updateState('g1', (state) => {
179
+ const task = state.tasks[taskId];
180
+ task.blockedBy = ['missing-upstream'];
181
+ task.blocks = ['missing-downstream'];
182
+ return null;
183
+ });
184
+
185
+ const detail = await taskGet.execute({
186
+ namespace: 'g1',
187
+ task_id: taskId,
188
+ include_history: true,
189
+ });
190
+ expect(detail.success).toBe(true);
191
+ const payload = parseOutput<{
192
+ task: {
193
+ blockers: Array<{ status: string }>;
194
+ blocked_tasks: Array<{ status: string }>;
195
+ checkpoint_progress: number;
196
+ history?: unknown[];
197
+ };
198
+ }>(detail.output);
199
+ expect(payload.task.blockers[0].status).toBe('missing');
200
+ expect(payload.task.blocked_tasks[0].status).toBe('missing');
201
+ expect(payload.task.checkpoint_progress).toBe(50);
202
+ expect(Array.isArray(payload.task.history)).toBe(true);
203
+ });
204
+
205
+ it('covers task_list filters, ranking branches and tie-breaking', async () => {
206
+ const defaultListTool = new TaskListTool();
207
+ expect(defaultListTool.getConcurrencyLockKey({} as never)).toBe('taskns:default:list');
208
+
209
+ expect(taskList.getConcurrencyMode()).toBe('parallel-safe');
210
+ expect(taskList.getConcurrencyLockKey({} as never)).toBe('taskns:def-ns:list');
211
+ expect(taskList.getConcurrencyLockKey({ namespace: 'l1' } as never)).toBe('taskns:l1:list');
212
+
213
+ await store.updateState('l1', (state) => {
214
+ const now = 10;
215
+ state.tasks = {
216
+ critical_claim: makeTask({
217
+ id: 'critical_claim',
218
+ subject: 'critical',
219
+ status: 'pending',
220
+ priority: 'critical',
221
+ createdAt: now + 1,
222
+ updatedAt: now + 1,
223
+ tags: [{ name: 'backend' }],
224
+ }),
225
+ in_progress: makeTask({
226
+ id: 'in_progress',
227
+ subject: 'in progress',
228
+ status: 'in_progress',
229
+ owner: 'worker',
230
+ createdAt: now + 2,
231
+ updatedAt: now + 2,
232
+ tags: [{ name: 'backend' }],
233
+ }),
234
+ high_old: makeTask({
235
+ id: 'high_old',
236
+ subject: 'high old',
237
+ status: 'pending',
238
+ priority: 'high',
239
+ createdAt: now + 3,
240
+ updatedAt: now + 3,
241
+ owner: null,
242
+ }),
243
+ high_new: makeTask({
244
+ id: 'high_new',
245
+ subject: 'high new',
246
+ status: 'pending',
247
+ priority: 'high',
248
+ createdAt: now + 9,
249
+ updatedAt: now + 9,
250
+ owner: null,
251
+ }),
252
+ normal_claim: makeTask({
253
+ id: 'normal_claim',
254
+ subject: 'normal',
255
+ status: 'pending',
256
+ priority: 'normal',
257
+ createdAt: now + 4,
258
+ updatedAt: now + 4,
259
+ }),
260
+ low_b: makeTask({
261
+ id: 'low_b',
262
+ subject: 'low b',
263
+ status: 'pending',
264
+ priority: 'low',
265
+ createdAt: now + 5,
266
+ updatedAt: now + 5,
267
+ }),
268
+ low_a: makeTask({
269
+ id: 'low_a',
270
+ subject: 'low a',
271
+ status: 'pending',
272
+ priority: 'low',
273
+ createdAt: now + 5,
274
+ updatedAt: now + 5,
275
+ }),
276
+ blocked_missing: makeTask({
277
+ id: 'blocked_missing',
278
+ subject: 'blocked',
279
+ status: 'pending',
280
+ priority: 'normal',
281
+ blockedBy: ['missing_blocker'],
282
+ createdAt: now + 6,
283
+ updatedAt: now + 6,
284
+ }),
285
+ blocked_by_completed: makeTask({
286
+ id: 'blocked_by_completed',
287
+ subject: 'blocked by completed',
288
+ status: 'pending',
289
+ priority: 'normal',
290
+ blockedBy: ['completed_task'],
291
+ createdAt: now + 6,
292
+ updatedAt: now + 6,
293
+ }),
294
+ completed_task: makeTask({
295
+ id: 'completed_task',
296
+ subject: 'completed',
297
+ status: 'completed',
298
+ createdAt: now + 7,
299
+ updatedAt: now + 7,
300
+ }),
301
+ cancelled_task: makeTask({
302
+ id: 'cancelled_task',
303
+ subject: 'cancelled',
304
+ status: 'cancelled',
305
+ createdAt: now + 8,
306
+ updatedAt: now + 8,
307
+ }),
308
+ failed_task: makeTask({
309
+ id: 'failed_task',
310
+ subject: 'failed',
311
+ status: 'failed',
312
+ createdAt: now + 11,
313
+ updatedAt: now + 11,
314
+ }),
315
+ pending_owned: makeTask({
316
+ id: 'pending_owned',
317
+ subject: 'pending owned',
318
+ status: 'pending',
319
+ owner: 'someone',
320
+ createdAt: now + 12,
321
+ updatedAt: now + 12,
322
+ }),
323
+ };
324
+ return null;
325
+ });
326
+
327
+ const all = await taskList.execute({
328
+ namespace: 'l1',
329
+ include_history: true,
330
+ });
331
+ expect(all.success).toBe(true);
332
+ const allPayload = parseOutput<{ tasks: Array<{ id: string; history?: unknown }> }>(all.output);
333
+ expect(allPayload.tasks[0].id).toBe('critical_claim');
334
+ const ids = allPayload.tasks.map((item) => item.id);
335
+ expect(ids.indexOf('high_old')).toBeLessThan(ids.indexOf('high_new'));
336
+ expect(ids.indexOf('low_a')).toBeLessThan(ids.indexOf('low_b'));
337
+ expect(allPayload.tasks.every((item) => item.history !== undefined)).toBe(true);
338
+
339
+ const byStatus = await taskList.execute({
340
+ namespace: 'l1',
341
+ statuses: ['pending'],
342
+ });
343
+ expect(byStatus.success).toBe(true);
344
+ const byStatusPayload = parseOutput<{ tasks: Array<{ status: string }> }>(byStatus.output);
345
+ expect(byStatusPayload.tasks.every((task) => task.status === 'pending')).toBe(true);
346
+
347
+ const byOwner = await taskList.execute({
348
+ namespace: 'l1',
349
+ owner: 'worker',
350
+ });
351
+ const byOwnerPayload = parseOutput<{ total: number; tasks: Array<{ owner: string | null }> }>(
352
+ byOwner.output
353
+ );
354
+ expect(byOwnerPayload.total).toBe(1);
355
+ expect(byOwnerPayload.tasks[0].owner).toBe('worker');
356
+
357
+ const byTag = await taskList.execute({
358
+ namespace: 'l1',
359
+ tag: 'backend',
360
+ });
361
+ const byTagPayload = parseOutput<{ total: number }>(byTag.output);
362
+ expect(byTagPayload.total).toBe(2);
363
+
364
+ const defaultNamespaceList = await defaultListTool.execute({});
365
+ expect(defaultNamespaceList.success).toBe(true);
366
+ });
367
+
368
+ it('covers task_update edge branches across validation/dependency/status/history', async () => {
369
+ const defaultUpdateTool = new TaskUpdateTool();
370
+ expect(defaultUpdateTool.getConcurrencyLockKey({ task_id: 'x' } as never)).toBe(
371
+ 'taskns:default'
372
+ );
373
+
374
+ expect(taskUpdate.getConcurrencyMode()).toBe('exclusive');
375
+ expect(taskUpdate.getConcurrencyLockKey({ task_id: 'x' } as never)).toBe('taskns:def-ns');
376
+ expect(taskUpdate.getConcurrencyLockKey({ namespace: 'u1', task_id: 'x' } as never)).toBe(
377
+ 'taskns:u1'
378
+ );
379
+
380
+ const empty = await taskUpdate.execute({
381
+ namespace: 'u1',
382
+ task_id: 'none',
383
+ });
384
+ expect(empty.success).toBe(false);
385
+ expect(empty.output).toContain('TASK_UPDATE_EMPTY');
386
+
387
+ const notFound = await taskUpdate.execute({
388
+ namespace: 'u1',
389
+ task_id: 'none',
390
+ subject: 'new subject',
391
+ });
392
+ expect(notFound.success).toBe(false);
393
+ expect(notFound.output).toContain('TASK_NOT_FOUND');
394
+
395
+ const created = await taskCreate.execute({
396
+ namespace: 'u1',
397
+ subject: 'updatable task',
398
+ description: 'Updatable task with enough details in description.',
399
+ });
400
+ const taskId = parseOutput<{ task: { id: string } }>(created.output).task.id;
401
+
402
+ await store.updateState('u1', (state) => {
403
+ state.tasks[taskId].status = 'completed';
404
+ return null;
405
+ });
406
+
407
+ const terminal = await taskUpdate.execute({
408
+ namespace: 'u1',
409
+ task_id: taskId,
410
+ subject: 'should fail',
411
+ });
412
+ expect(terminal.success).toBe(false);
413
+ expect(terminal.output).toContain('TASK_TERMINAL_IMMUTABLE');
414
+
415
+ const created2 = await taskCreate.execute({
416
+ namespace: 'u1',
417
+ subject: 'second updatable task',
418
+ description: 'Second task with details for update branches.',
419
+ });
420
+ const task2 = parseOutput<{ task: { id: string } }>(created2.output).task.id;
421
+
422
+ const invalidTransition = await taskUpdate.execute({
423
+ namespace: 'u1',
424
+ task_id: task2,
425
+ status: 'completed',
426
+ });
427
+ expect(invalidTransition.success).toBe(false);
428
+ expect(invalidTransition.output).toContain('TASK_INVALID_STATUS_TRANSITION');
429
+
430
+ const missingBlocker = await taskUpdate.execute({
431
+ namespace: 'u1',
432
+ task_id: task2,
433
+ add_blocked_by: ['missing-task'],
434
+ });
435
+ expect(missingBlocker.success).toBe(false);
436
+ expect(missingBlocker.output).toContain('TASK_NOT_FOUND');
437
+
438
+ const selfDependency = await taskUpdate.execute({
439
+ namespace: 'u1',
440
+ task_id: task2,
441
+ add_blocked_by: [task2],
442
+ });
443
+ expect(selfDependency.success).toBe(false);
444
+ expect(selfDependency.output).toContain('TASK_CYCLE_DEPENDENCY');
445
+
446
+ const removeMissing = await taskUpdate.execute({
447
+ namespace: 'u1',
448
+ task_id: task2,
449
+ remove_blocked_by: ['not-exists'],
450
+ reason: 'cleanup',
451
+ updated_by: 'tester',
452
+ });
453
+ expect(removeMissing.success).toBe(true);
454
+ const removePayload = parseOutput<{ task: { history: Array<{ action: string }> } }>(
455
+ removeMissing.output
456
+ );
457
+ expect(removePayload.task.history.some((entry) => entry.action === 'dependency_removed')).toBe(
458
+ true
459
+ );
460
+
461
+ const merged = await taskUpdate.execute({
462
+ namespace: 'u1',
463
+ task_id: task2,
464
+ subject: 'second updatable task renamed',
465
+ metadata: { k1: 'v1' },
466
+ reason: 'minor edit',
467
+ updated_by: 'tester',
468
+ });
469
+ expect(merged.success).toBe(true);
470
+ const mergedPayload = parseOutput<{
471
+ task: { metadata: Record<string, unknown>; history: Array<{ action: string }> };
472
+ }>(merged.output);
473
+ expect(mergedPayload.task.metadata.k1).toBe('v1');
474
+ expect(mergedPayload.task.history.some((entry) => entry.action === 'updated')).toBe(true);
475
+
476
+ const fieldUpdates = await taskUpdate.execute({
477
+ namespace: 'u1',
478
+ task_id: task2,
479
+ description: 'Updated description with enough detail for branch coverage.',
480
+ active_form: 'Actively updating task fields',
481
+ priority: 'high',
482
+ progress: 55,
483
+ });
484
+ expect(fieldUpdates.success).toBe(true);
485
+ const fieldUpdatePayload = parseOutput<{
486
+ task: { description: string; activeForm: string; priority: string; progress: number };
487
+ }>(fieldUpdates.output);
488
+ expect(fieldUpdatePayload.task.description).toContain('Updated description');
489
+ expect(fieldUpdatePayload.task.activeForm).toBe('Actively updating task fields');
490
+ expect(fieldUpdatePayload.task.priority).toBe('high');
491
+ expect(fieldUpdatePayload.task.progress).toBe(55);
492
+
493
+ const goRunning = await taskUpdate.execute({
494
+ namespace: 'u1',
495
+ task_id: task2,
496
+ status: 'in_progress',
497
+ owner: 'agent-x',
498
+ });
499
+ expect(goRunning.success).toBe(true);
500
+
501
+ const backPending = await taskUpdate.execute({
502
+ namespace: 'u1',
503
+ task_id: task2,
504
+ status: 'pending',
505
+ });
506
+ expect(backPending.success).toBe(true);
507
+ const backPendingPayload = parseOutput<{ task: { owner: string | null } }>(backPending.output);
508
+ expect(backPendingPayload.task.owner).toBeNull();
509
+
510
+ const goRunningAgain = await taskUpdate.execute({
511
+ namespace: 'u1',
512
+ task_id: task2,
513
+ status: 'in_progress',
514
+ owner: 'agent-y',
515
+ });
516
+ expect(goRunningAgain.success).toBe(true);
517
+
518
+ const failed = await taskUpdate.execute({
519
+ namespace: 'u1',
520
+ task_id: task2,
521
+ status: 'failed',
522
+ reason: 'boom',
523
+ });
524
+ expect(failed.success).toBe(true);
525
+ const failedPayload = parseOutput<{ task: { lastError?: string; owner: string | null } }>(
526
+ failed.output
527
+ );
528
+ expect(failedPayload.task.lastError).toContain('boom');
529
+ expect(failedPayload.task.owner).toBeNull();
530
+
531
+ const created4 = await taskCreate.execute({
532
+ namespace: 'u1',
533
+ subject: 'failed uses previous lastError',
534
+ description: 'Task to test lastError fallback using existing error value.',
535
+ });
536
+ const task4 = parseOutput<{ task: { id: string } }>(created4.output).task.id;
537
+ await taskUpdate.execute({
538
+ namespace: 'u1',
539
+ task_id: task4,
540
+ status: 'in_progress',
541
+ owner: 'agent-prev',
542
+ });
543
+ await store.updateState('u1', (state) => {
544
+ state.tasks[task4].lastError = 'existing error';
545
+ return null;
546
+ });
547
+ const failedUsePrevious = await taskUpdate.execute({
548
+ namespace: 'u1',
549
+ task_id: task4,
550
+ status: 'failed',
551
+ });
552
+ expect(failedUsePrevious.success).toBe(true);
553
+ const failedUsePreviousPayload = parseOutput<{ task: { lastError?: string } }>(
554
+ failedUsePrevious.output
555
+ );
556
+ expect(failedUsePreviousPayload.task.lastError).toBe('existing error');
557
+
558
+ const created5 = await taskCreate.execute({
559
+ namespace: 'u1',
560
+ subject: 'failed uses default lastError',
561
+ description: 'Task to test default lastError fallback when none is provided.',
562
+ });
563
+ const task5 = parseOutput<{ task: { id: string } }>(created5.output).task.id;
564
+ await taskUpdate.execute({
565
+ namespace: 'u1',
566
+ task_id: task5,
567
+ status: 'in_progress',
568
+ owner: 'agent-default',
569
+ });
570
+ const failedDefault = await taskUpdate.execute({
571
+ namespace: 'u1',
572
+ task_id: task5,
573
+ status: 'failed',
574
+ });
575
+ expect(failedDefault.success).toBe(true);
576
+ const failedDefaultPayload = parseOutput<{ task: { lastError?: string } }>(
577
+ failedDefault.output
578
+ );
579
+ expect(failedDefaultPayload.task.lastError).toContain('task marked as failed');
580
+
581
+ const created3 = await taskCreate.execute({
582
+ namespace: 'u1',
583
+ subject: 'cancel path task',
584
+ description: 'Task for cancelled status branch in update tool.',
585
+ });
586
+ const task3 = parseOutput<{ task: { id: string } }>(created3.output).task.id;
587
+ const cancelled = await taskUpdate.execute({
588
+ namespace: 'u1',
589
+ task_id: task3,
590
+ status: 'cancelled',
591
+ reason: 'stop',
592
+ });
593
+ expect(cancelled.success).toBe(true);
594
+ const cancelledPayload = parseOutput<{
595
+ task: { status: string; history: Array<{ action: string }> };
596
+ }>(cancelled.output);
597
+ expect(cancelledPayload.task.status).toBe('cancelled');
598
+ expect(cancelledPayload.task.history.some((entry) => entry.action === 'cancelled')).toBe(true);
599
+ });
600
+
601
+ it('covers task_update catch fallback for non-prefixed thrown values', async () => {
602
+ const fakeStore = {
603
+ normalizeNamespace: () => 'n1',
604
+ updateState: async () => {
605
+ throw 'unstructured failure';
606
+ },
607
+ } as unknown as TaskStore;
608
+ const tool = new TaskUpdateTool({ store: fakeStore });
609
+ const result = await tool.execute({
610
+ namespace: 'n1',
611
+ task_id: 'x',
612
+ subject: 'abc',
613
+ });
614
+ expect(result.success).toBe(false);
615
+ expect(result.output).toContain('TASK_OPERATION_FAILED');
616
+ });
617
+
618
+ it('covers namespace fallback execution path in task_update', async () => {
619
+ const created = await taskCreate.execute({
620
+ subject: 'default namespace update',
621
+ description: 'Task created in default namespace for update execution fallback.',
622
+ });
623
+ const taskId = parseOutput<{ task: { id: string } }>(created.output).task.id;
624
+ const updated = await taskUpdate.execute({
625
+ task_id: taskId,
626
+ subject: 'default namespace updated',
627
+ });
628
+ expect(updated.success).toBe(true);
629
+ });
630
+ });