maestro-agent-sdk 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +197 -10
  2. package/dist/agents/contracts.d.ts +10 -0
  3. package/dist/agents/contracts.d.ts.map +1 -1
  4. package/dist/index.d.ts +9 -6
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +8 -5
  7. package/dist/index.js.map +1 -1
  8. package/dist/memory/reminder.d.ts +9 -9
  9. package/dist/memory/reminder.d.ts.map +1 -1
  10. package/dist/memory/reminder.js +21 -15
  11. package/dist/memory/reminder.js.map +1 -1
  12. package/dist/platform/version.d.ts +13 -0
  13. package/dist/platform/version.d.ts.map +1 -0
  14. package/dist/platform/version.js +13 -0
  15. package/dist/platform/version.js.map +1 -0
  16. package/dist/provider.d.ts +62 -0
  17. package/dist/provider.d.ts.map +1 -1
  18. package/dist/provider.js +161 -22
  19. package/dist/provider.js.map +1 -1
  20. package/dist/registry.d.ts.map +1 -1
  21. package/dist/registry.js +16 -1
  22. package/dist/registry.js.map +1 -1
  23. package/dist/session-store.d.ts +95 -4
  24. package/dist/session-store.d.ts.map +1 -1
  25. package/dist/session-store.js +144 -13
  26. package/dist/session-store.js.map +1 -1
  27. package/dist/skills/curator.d.ts +8 -6
  28. package/dist/skills/curator.d.ts.map +1 -1
  29. package/dist/skills/curator.js +13 -7
  30. package/dist/skills/curator.js.map +1 -1
  31. package/dist/skills/loader.d.ts +45 -20
  32. package/dist/skills/loader.d.ts.map +1 -1
  33. package/dist/skills/loader.js +56 -11
  34. package/dist/skills/loader.js.map +1 -1
  35. package/dist/state/tasks.d.ts +107 -0
  36. package/dist/state/tasks.d.ts.map +1 -0
  37. package/dist/state/tasks.js +398 -0
  38. package/dist/state/tasks.js.map +1 -0
  39. package/dist/sub-agent/runner.d.ts +1 -1
  40. package/dist/sub-agent/runner.js +3 -3
  41. package/dist/tools/builtin/glob.d.ts +17 -0
  42. package/dist/tools/builtin/glob.d.ts.map +1 -0
  43. package/dist/tools/builtin/glob.js +235 -0
  44. package/dist/tools/builtin/glob.js.map +1 -0
  45. package/dist/tools/builtin/grep.d.ts +3 -0
  46. package/dist/tools/builtin/grep.d.ts.map +1 -0
  47. package/dist/tools/builtin/grep.js +272 -0
  48. package/dist/tools/builtin/grep.js.map +1 -0
  49. package/dist/tools/builtin/skill_write.d.ts +53 -0
  50. package/dist/tools/builtin/skill_write.d.ts.map +1 -0
  51. package/dist/tools/builtin/skill_write.js +264 -0
  52. package/dist/tools/builtin/skill_write.js.map +1 -0
  53. package/dist/tools/builtin/tasks.d.ts +34 -0
  54. package/dist/tools/builtin/tasks.d.ts.map +1 -0
  55. package/dist/tools/builtin/tasks.js +258 -0
  56. package/dist/tools/builtin/tasks.js.map +1 -0
  57. package/dist/types.d.ts +95 -0
  58. package/dist/types.d.ts.map +1 -1
  59. package/package.json +1 -1
  60. package/dist/state/todos.d.ts +0 -95
  61. package/dist/state/todos.d.ts.map +0 -1
  62. package/dist/state/todos.js +0 -198
  63. package/dist/state/todos.js.map +0 -1
  64. package/dist/tools/builtin/todo_write.d.ts +0 -29
  65. package/dist/tools/builtin/todo_write.d.ts.map +0 -1
  66. package/dist/tools/builtin/todo_write.js +0 -96
  67. package/dist/tools/builtin/todo_write.js.map +0 -1
@@ -0,0 +1,264 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import { dirname, isAbsolute, join, normalize, relative } from "node:path";
3
+ import { invalidateSkillsCache } from "../../skills/loader.js";
4
+ import { logger } from "../../platform/logger.js";
5
+ /** kebab-case validator: lowercase letters, digits, dashes. Must start with
6
+ * a letter; no leading/trailing/consecutive dashes. */
7
+ const NAME_RE = /^[a-z](?:[a-z0-9]|-(?=[a-z0-9]))*$/;
8
+ /** Soft sanity check — the loader will surface the skill regardless, but
9
+ * warning the agent here helps it land a clawgram-conformant file on the
10
+ * first try. */
11
+ function lintContent(content) {
12
+ const warnings = [];
13
+ if (!/^#\s+\S/m.test(content)) {
14
+ warnings.push("Missing a top-level `# Title` heading.");
15
+ }
16
+ if (!/^[ \t]*>[ \t]*(?:\*\*)?\s*description\s*(?:\*\*)?[ \t]*:/im.test(content)) {
17
+ warnings.push("Missing a `> **Description**: ...` blockquote — trigger keywords " +
18
+ "won't surface in the system-prompt index until you add one.");
19
+ }
20
+ return { warnings };
21
+ }
22
+ export function createSkillWriteTool(opts) {
23
+ const { skillsDir } = opts;
24
+ return {
25
+ // Writes mutate disk + invalidate cache — not safe for parallel
26
+ // dispatch with another skill_write (two writes racing the cache
27
+ // invalidation could leave a stale entry). Reads are fine to overlap
28
+ // because the cache TTL absorbs the staleness.
29
+ parallelSafe: false,
30
+ schema: {
31
+ name: "skill_write",
32
+ description: "Author or update a skill manifest (and optional adjacent assets) " +
33
+ "inside the session's skills directory. Writes " +
34
+ "`<skillsDir>/<name>/skill.md` with the provided markdown content, " +
35
+ "plus any files listed in `files` under the same skill folder " +
36
+ "(e.g. `scripts/foo.py`, `templates/x.tex`, `references/api.md`). " +
37
+ "Folder layout is mandatory — progressive-disclosure assets sit " +
38
+ "next to the manifest. The catalog reloads on the NEXT turn " +
39
+ "(not the current one) — finish your current task, then the new " +
40
+ "skill is available via skill_view.\n\n" +
41
+ "Content conventions (clawgram-style):\n" +
42
+ " - First line: `# Title` (the display title; can be Korean or English).\n" +
43
+ " - Near the top: `> **Description**: <comma-separated trigger keywords>`. " +
44
+ "This drives skill activation — be specific, list the words a user would " +
45
+ "actually type.\n" +
46
+ " - Sections to include: 트리거 / 프로세스 / Gotchas. Gotchas is the " +
47
+ "most valuable section — accumulate failure cases + fixes over time.\n" +
48
+ " - Don't restate the obvious; focus on knowledge that changes behavior.\n\n" +
49
+ "Returns success with the manifest path + per-asset paths, or an " +
50
+ "error JSON when validation fails or any target already exists " +
51
+ "(pass `overwrite: true` to replace).",
52
+ input_schema: {
53
+ type: "object",
54
+ properties: {
55
+ name: {
56
+ type: "string",
57
+ description: "Skill identifier in kebab-case (lowercase, dashes between words, " +
58
+ "no leading/trailing dashes). Becomes the folder name; the loader " +
59
+ "uses it as the canonical name when no frontmatter `name:` is set.",
60
+ },
61
+ content: {
62
+ type: "string",
63
+ description: "Full markdown body of the skill. Must include `# Title` and " +
64
+ "`> **Description**: ...` near the top (a warning surfaces if either " +
65
+ "is missing). No YAML frontmatter required.",
66
+ },
67
+ files: {
68
+ type: "object",
69
+ description: "Optional map of `<relative-path>: <file-content>` for adjacent " +
70
+ "assets inside the skill folder. Paths are relative to " +
71
+ "`<skillsDir>/<name>/`, use forward slashes, must not contain `..` " +
72
+ "or absolute prefixes, and cannot equal `skill.md` (reserved for " +
73
+ "the manifest). Parent directories are created automatically. " +
74
+ "Example: `{\"scripts/run.sh\": \"#!/bin/bash\\n...\", " +
75
+ "\"templates/x.tex\": \"...\", \"references/api.md\": \"...\"}`",
76
+ additionalProperties: { type: "string" },
77
+ },
78
+ overwrite: {
79
+ type: "boolean",
80
+ description: "Replace existing files at the manifest path OR any `files` " +
81
+ "target. Default false; when false, any preexisting target aborts " +
82
+ "the whole call BEFORE writing anything.",
83
+ },
84
+ },
85
+ required: ["name", "content"],
86
+ },
87
+ },
88
+ async execute(input) {
89
+ const name = typeof input.name === "string" ? input.name.trim() : "";
90
+ const content = typeof input.content === "string" ? input.content : "";
91
+ const overwrite = input.overwrite === true;
92
+ const filesInput = input.files && typeof input.files === "object" && !Array.isArray(input.files)
93
+ ? input.files
94
+ : null;
95
+ if (!name) {
96
+ return JSON.stringify({ error: "skill_write: missing 'name' argument" });
97
+ }
98
+ if (!NAME_RE.test(name)) {
99
+ return JSON.stringify({
100
+ error: `skill_write: invalid name '${name}' — must be kebab-case ` +
101
+ "(lowercase letters/digits, single dashes between segments, " +
102
+ "start with a letter).",
103
+ });
104
+ }
105
+ if (!content.trim()) {
106
+ return JSON.stringify({
107
+ error: "skill_write: 'content' is empty — provide the skill markdown body",
108
+ });
109
+ }
110
+ // Final path: <skillsDir>/<name>/skill.md. The skillsDir was resolved
111
+ // from (cwd, skillKey) at session start, so the agent's write
112
+ // automatically lands in its own profile.
113
+ const skillDir = join(skillsDir, name);
114
+ const skillFile = join(skillDir, "skill.md");
115
+ // ---- Phase 1: validate the entire write set BEFORE touching disk ----
116
+ // Up-front validation lets us reject a malformed batch as a unit
117
+ // (e.g. one bad relative path among ten files) instead of writing
118
+ // half the assets and then bailing.
119
+ const fileWrites = [];
120
+ if (filesInput) {
121
+ for (const [rel, raw] of Object.entries(filesInput)) {
122
+ if (typeof rel !== "string" || rel.trim() === "") {
123
+ return JSON.stringify({
124
+ error: `skill_write: 'files' has an empty key (entry value: ${typeof raw})`,
125
+ });
126
+ }
127
+ if (typeof raw !== "string") {
128
+ return JSON.stringify({
129
+ error: `skill_write: 'files[${rel}]' must be a string, got ${typeof raw}`,
130
+ });
131
+ }
132
+ const safetyErr = validateRelativePath(rel);
133
+ if (safetyErr) {
134
+ return JSON.stringify({
135
+ error: `skill_write: ${safetyErr} (entry '${rel}')`,
136
+ });
137
+ }
138
+ if (rel === "skill.md") {
139
+ return JSON.stringify({
140
+ error: "skill_write: 'files' may not include 'skill.md' — pass the " +
141
+ "manifest body via the top-level `content` argument instead",
142
+ });
143
+ }
144
+ fileWrites.push({ rel, abs: join(skillDir, rel), body: raw });
145
+ }
146
+ }
147
+ // Pre-check existing-target conflicts when overwrite=false. We do
148
+ // this AFTER validating shapes so a malformed entry surfaces first.
149
+ if (!overwrite) {
150
+ if (existsSync(skillFile)) {
151
+ return JSON.stringify({
152
+ error: `skill_write: '${skillFile}' already exists — pass overwrite: true to replace`,
153
+ path: skillFile,
154
+ });
155
+ }
156
+ for (const f of fileWrites) {
157
+ if (existsSync(f.abs)) {
158
+ return JSON.stringify({
159
+ error: `skill_write: '${f.abs}' already exists — pass overwrite: true to replace`,
160
+ path: f.abs,
161
+ rel: f.rel,
162
+ });
163
+ }
164
+ }
165
+ }
166
+ // ---- Phase 2: write manifest + adjacent files ----
167
+ let bytesTotal = 0;
168
+ const writtenFiles = [];
169
+ try {
170
+ mkdirSync(skillDir, { recursive: true });
171
+ // Manifest first — ensure trailing newline.
172
+ const manifestBody = content.endsWith("\n") ? content : `${content}\n`;
173
+ writeFileSync(skillFile, manifestBody, "utf-8");
174
+ const manifestBytes = Buffer.byteLength(manifestBody, "utf-8");
175
+ bytesTotal += manifestBytes;
176
+ for (const f of fileWrites) {
177
+ mkdirSync(dirname(f.abs), { recursive: true });
178
+ writeFileSync(f.abs, f.body, "utf-8");
179
+ const b = Buffer.byteLength(f.body, "utf-8");
180
+ bytesTotal += b;
181
+ writtenFiles.push({ rel: f.rel, path: f.abs, bytes: b });
182
+ }
183
+ }
184
+ catch (e) {
185
+ // Partial failure: the manifest may or may not be written, and
186
+ // some files may have landed. Report what succeeded so the agent
187
+ // can decide whether to re-try with overwrite or clean up by hand.
188
+ return JSON.stringify({
189
+ error: `skill_write: failed mid-write: ${e instanceof Error ? e.message : String(e)}`,
190
+ manifestPath: skillFile,
191
+ manifestWritten: existsSync(skillFile),
192
+ filesWritten: writtenFiles,
193
+ });
194
+ }
195
+ // Bust the loader cache so the next provider call (next turn) sees
196
+ // this skill in the catalog without waiting for the TTL.
197
+ invalidateSkillsCache();
198
+ const { warnings } = lintContent(content);
199
+ const result = {
200
+ ok: true,
201
+ path: skillFile,
202
+ skillDir,
203
+ name,
204
+ action: overwrite ? "overwritten" : "created",
205
+ bytes: bytesTotal,
206
+ note: "Catalog reloads on the NEXT turn — the new skill is not visible " +
207
+ "in the current turn's <available_skills> list. Call skill_view " +
208
+ "after the next user turn to verify activation.",
209
+ };
210
+ if (writtenFiles.length > 0)
211
+ result.files = writtenFiles;
212
+ if (warnings.length > 0)
213
+ result.warnings = warnings;
214
+ logger.info({
215
+ name,
216
+ path: skillFile,
217
+ action: result.action,
218
+ bytes: bytesTotal,
219
+ fileCount: writtenFiles.length,
220
+ warningCount: warnings.length,
221
+ }, "skill_write: skill manifest + assets persisted");
222
+ return JSON.stringify(result);
223
+ },
224
+ };
225
+ }
226
+ /**
227
+ * Validate a relative path supplied via `files`. Returns an error string on
228
+ * failure, or `null` when the path is safe to use as `join(skillDir, rel)`.
229
+ *
230
+ * Rejected:
231
+ * - absolute paths (any drive prefix or leading `/`)
232
+ * - paths that normalize outside the skill folder (`..` escapes)
233
+ * - paths that resolve to "." (i.e. the skill folder itself)
234
+ * - paths with backslashes (force forward-slash to keep cross-platform
235
+ * behavior predictable; Windows hosts will translate on `join`)
236
+ *
237
+ * Note: we don't validate against a per-file regex — the model can write
238
+ * any filename the host filesystem accepts, including dotfiles. Only the
239
+ * traversal vector is the safety boundary.
240
+ */
241
+ function validateRelativePath(rel) {
242
+ if (rel.includes("\\")) {
243
+ return `path '${rel}' must use forward slashes, not backslashes`;
244
+ }
245
+ if (isAbsolute(rel)) {
246
+ return `path '${rel}' must be relative to the skill folder, not absolute`;
247
+ }
248
+ const normalized = normalize(rel);
249
+ if (normalized === "." || normalized === "") {
250
+ return `path '${rel}' resolves to the skill folder itself`;
251
+ }
252
+ // The reliable cross-platform escape check: a `..` segment anywhere.
253
+ const segments = normalized.split(/[/\\]/);
254
+ if (segments.includes("..")) {
255
+ return `path '${rel}' escapes the skill folder via '..'`;
256
+ }
257
+ // Defensive: ensure relative() from "." still keeps us inside.
258
+ const back = relative(".", normalized);
259
+ if (back.startsWith("..")) {
260
+ return `path '${rel}' escapes the skill folder via '..'`;
261
+ }
262
+ return null;
263
+ }
264
+ //# sourceMappingURL=skill_write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill_write.js","sourceRoot":"","sources":["../../../src/tools/builtin/skill_write.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { TaskStore } from "../../state/tasks.js";
2
+ import type { ToolHandler } from "../../tools/registry.js";
3
+ /**
4
+ * `TaskCreate` / `TaskUpdate` / `TaskList` / `TaskGet` builtins — the
5
+ * granular replacement for the v0.1.x `todo_write` snapshot-replace tool.
6
+ *
7
+ * Each tool covers a single CRUD verb so the model can mutate one task per
8
+ * call without round-tripping the whole list. The store enforces a single
9
+ * `in_progress` task at a time (TaskUpdate flips any prior in_progress to
10
+ * pending and surfaces the demoted id), and dependency edges
11
+ * (`blockedBy` / `blocks`) are kept bidirectionally consistent.
12
+ *
13
+ * The read side stays cheap: every per-turn `<system-reminder>` already
14
+ * renders the current list. `TaskList` exists for explicit refresh after
15
+ * a long stretch of tool work (sub-agent delegation, batch updates), and
16
+ * `TaskGet` returns the full entry — including description, owner, and
17
+ * metadata — which the reminder summary intentionally omits.
18
+ *
19
+ * Side-effecting tools (`TaskCreate`, `TaskUpdate`) are `parallelSafe: false`
20
+ * because two concurrent writes would race on the in-progress sweep and
21
+ * dependency-edge maintenance. Reads (`TaskList`, `TaskGet`) are safe to
22
+ * parallelise — they snapshot the in-memory map.
23
+ */
24
+ export interface TaskToolsOptions {
25
+ /** Required. The per-session store. Built by maestroProvider via
26
+ * `getTaskStore(sessionId)` so the same instance is shared across
27
+ * every tool call in this turn. */
28
+ store: TaskStore;
29
+ }
30
+ export declare function createTaskCreateTool(opts: TaskToolsOptions): ToolHandler;
31
+ export declare function createTaskUpdateTool(opts: TaskToolsOptions): ToolHandler;
32
+ export declare function createTaskListTool(opts: TaskToolsOptions): ToolHandler;
33
+ export declare function createTaskGetTool(opts: TaskToolsOptions): ToolHandler;
34
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../../src/tools/builtin/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,SAAS,EAEV,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,WAAW,gBAAgB;IAC/B;;wCAEoC;IACpC,KAAK,EAAE,SAAS,CAAC;CAClB;AA+BD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,CAgExE;AAQD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,CAsGxE;AAMD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,CAiCtE;AAMD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,CAiCrE"}
@@ -0,0 +1,258 @@
1
+ function summarize(t) {
2
+ const out = {
3
+ id: t.id,
4
+ subject: t.subject,
5
+ status: t.status,
6
+ blockedBy: t.blockedBy,
7
+ blocks: t.blocks,
8
+ };
9
+ if (t.activeForm)
10
+ out.activeForm = t.activeForm;
11
+ if (t.owner)
12
+ out.owner = t.owner;
13
+ return out;
14
+ }
15
+ // ---------------------------------------------------------------------------
16
+ // TaskCreate
17
+ // ---------------------------------------------------------------------------
18
+ export function createTaskCreateTool(opts) {
19
+ const { store } = opts;
20
+ return {
21
+ parallelSafe: false,
22
+ schema: {
23
+ name: "TaskCreate",
24
+ description: "Create a single new task. Returns the freshly assigned id (numeric " +
25
+ "string like '1', '2', ...). The task starts in 'pending' status — " +
26
+ "transition it with TaskUpdate. Set up dependencies via TaskUpdate's " +
27
+ "`addBlockedBy` / `addBlocks` fields after the dependent tasks exist.",
28
+ input_schema: {
29
+ type: "object",
30
+ properties: {
31
+ subject: {
32
+ type: "string",
33
+ description: "Imperative title — what needs to be done. e.g. 'Read spec'.",
34
+ },
35
+ description: {
36
+ type: "string",
37
+ description: "Optional longer detail or acceptance criteria. Use this for context " +
38
+ "the subject line is too short to carry.",
39
+ },
40
+ activeForm: {
41
+ type: "string",
42
+ description: "Optional present-continuous form for spinner/status display " +
43
+ "('Reading spec' vs the imperative 'Read spec'). Hosts that " +
44
+ "render a live task list show this while status is in_progress.",
45
+ },
46
+ owner: {
47
+ type: "string",
48
+ description: "Optional owner / agent name. Useful when delegating to sub-agents " +
49
+ "via the Agent tool so a glance at TaskList shows who's responsible.",
50
+ },
51
+ metadata: {
52
+ type: "object",
53
+ description: "Arbitrary host-controlled bag, round-tripped verbatim. The SDK " +
54
+ "neither reads nor interprets the shape.",
55
+ additionalProperties: true,
56
+ },
57
+ },
58
+ required: ["subject"],
59
+ },
60
+ },
61
+ async execute(input) {
62
+ const subject = typeof input.subject === "string" ? input.subject.trim() : "";
63
+ if (!subject) {
64
+ return JSON.stringify({ error: "TaskCreate: 'subject' must be a non-empty string" });
65
+ }
66
+ const create = { subject };
67
+ if (typeof input.description === "string")
68
+ create.description = input.description;
69
+ if (typeof input.activeForm === "string")
70
+ create.activeForm = input.activeForm;
71
+ if (typeof input.owner === "string")
72
+ create.owner = input.owner;
73
+ if (input.metadata && typeof input.metadata === "object" && !Array.isArray(input.metadata)) {
74
+ create.metadata = input.metadata;
75
+ }
76
+ const entry = store.create(create);
77
+ return JSON.stringify({ ok: true, id: entry.id, subject: entry.subject });
78
+ },
79
+ };
80
+ }
81
+ // ---------------------------------------------------------------------------
82
+ // TaskUpdate
83
+ // ---------------------------------------------------------------------------
84
+ const VALID_STATUSES = new Set(["pending", "in_progress", "completed", "deleted"]);
85
+ export function createTaskUpdateTool(opts) {
86
+ const { store } = opts;
87
+ return {
88
+ parallelSafe: false,
89
+ schema: {
90
+ name: "TaskUpdate",
91
+ description: "Update a single existing task by id. Any subset of fields can change " +
92
+ "in one call (status, subject, description, activeForm, owner, " +
93
+ "metadata, dependency edges). Status transitions:\n" +
94
+ " - → 'in_progress': the store demotes any other in_progress task to " +
95
+ "'pending' (1-in-progress invariant) and reports the demoted id back.\n" +
96
+ " - → 'deleted': permanent. The task disappears from TaskList output " +
97
+ "but stays on disk for TaskGet forensics.\n" +
98
+ "Dependency edges are bidirectional — addBlockedBy: ['3'] on task 5 " +
99
+ "also adds '5' to task 3's blocks list. Self-loops and unknown ids " +
100
+ "are silently ignored.",
101
+ input_schema: {
102
+ type: "object",
103
+ properties: {
104
+ taskId: {
105
+ type: "string",
106
+ description: "Id of the task to mutate (as returned by TaskCreate).",
107
+ },
108
+ status: {
109
+ type: "string",
110
+ enum: ["pending", "in_progress", "completed", "deleted"],
111
+ description: "New status. Setting in_progress triggers the 1-in-progress sweep; " +
112
+ "setting deleted is permanent.",
113
+ },
114
+ subject: { type: "string", description: "New imperative title." },
115
+ description: { type: "string", description: "New long-form detail." },
116
+ activeForm: { type: "string", description: "New spinner / status display form." },
117
+ owner: { type: "string", description: "New owner / agent name." },
118
+ metadata: {
119
+ type: "object",
120
+ description: "New metadata bag (overwrites previous).",
121
+ additionalProperties: true,
122
+ },
123
+ addBlockedBy: {
124
+ type: "array",
125
+ items: { type: "string" },
126
+ description: "Task ids that must complete before this one can start. Edges " +
127
+ "are added bidirectionally on the blockers' `blocks` lists.",
128
+ },
129
+ addBlocks: {
130
+ type: "array",
131
+ items: { type: "string" },
132
+ description: "Task ids that this task blocks. Edges are added bidirectionally " +
133
+ "on the blocked tasks' `blockedBy` lists.",
134
+ },
135
+ },
136
+ required: ["taskId"],
137
+ },
138
+ },
139
+ async execute(input) {
140
+ const taskId = typeof input.taskId === "string" ? input.taskId.trim() : "";
141
+ if (!taskId) {
142
+ return JSON.stringify({ error: "TaskUpdate: 'taskId' must be a non-empty string" });
143
+ }
144
+ if (!store.get(taskId)) {
145
+ return JSON.stringify({ error: `TaskUpdate: no task with id '${taskId}'` });
146
+ }
147
+ const update = {};
148
+ if (typeof input.status === "string") {
149
+ if (!VALID_STATUSES.has(input.status)) {
150
+ return JSON.stringify({
151
+ error: `TaskUpdate: invalid status '${input.status}' — must be one of ` +
152
+ "pending, in_progress, completed, deleted",
153
+ });
154
+ }
155
+ update.status = input.status;
156
+ }
157
+ if (typeof input.subject === "string" && input.subject.trim()) {
158
+ update.subject = input.subject;
159
+ }
160
+ if (typeof input.description === "string")
161
+ update.description = input.description;
162
+ if (typeof input.activeForm === "string")
163
+ update.activeForm = input.activeForm;
164
+ if (typeof input.owner === "string")
165
+ update.owner = input.owner;
166
+ if (input.metadata && typeof input.metadata === "object" && !Array.isArray(input.metadata)) {
167
+ update.metadata = input.metadata;
168
+ }
169
+ if (Array.isArray(input.addBlockedBy)) {
170
+ update.addBlockedBy = input.addBlockedBy.filter((x) => typeof x === "string");
171
+ }
172
+ if (Array.isArray(input.addBlocks)) {
173
+ update.addBlocks = input.addBlocks.filter((x) => typeof x === "string");
174
+ }
175
+ const result = store.update(taskId, update);
176
+ const payload = {
177
+ ok: true,
178
+ task: summarize(result.task),
179
+ };
180
+ if (result.demotedId)
181
+ payload.demotedId = result.demotedId;
182
+ return JSON.stringify(payload);
183
+ },
184
+ };
185
+ }
186
+ // ---------------------------------------------------------------------------
187
+ // TaskList
188
+ // ---------------------------------------------------------------------------
189
+ export function createTaskListTool(opts) {
190
+ const { store } = opts;
191
+ return {
192
+ parallelSafe: true,
193
+ schema: {
194
+ name: "TaskList",
195
+ description: "Return all non-deleted tasks (compact form: id, subject, status, " +
196
+ "activeForm, owner, blockedBy, blocks). The per-turn system reminder " +
197
+ "already carries a summary — use TaskList when you need the full " +
198
+ "state programmatically (e.g. after a stretch of TaskUpdate calls " +
199
+ "or sub-agent delegation). Pass `includeDeleted: true` to also see " +
200
+ "tasks the model marked deleted earlier.",
201
+ input_schema: {
202
+ type: "object",
203
+ properties: {
204
+ includeDeleted: {
205
+ type: "boolean",
206
+ description: "When true, include tasks with status='deleted'. Default false.",
207
+ },
208
+ },
209
+ },
210
+ },
211
+ async execute(input) {
212
+ const includeDeleted = input.includeDeleted === true;
213
+ const list = includeDeleted ? store.listAll() : store.list();
214
+ return JSON.stringify({
215
+ ok: true,
216
+ count: list.length,
217
+ tasks: list.map(summarize),
218
+ });
219
+ },
220
+ };
221
+ }
222
+ // ---------------------------------------------------------------------------
223
+ // TaskGet
224
+ // ---------------------------------------------------------------------------
225
+ export function createTaskGetTool(opts) {
226
+ const { store } = opts;
227
+ return {
228
+ parallelSafe: true,
229
+ schema: {
230
+ name: "TaskGet",
231
+ description: "Fetch the full entry for a single task (every field including " +
232
+ "description, metadata, createdAt/updatedAt timestamps). Use this " +
233
+ "when the compact TaskList summary doesn't carry enough detail.",
234
+ input_schema: {
235
+ type: "object",
236
+ properties: {
237
+ taskId: {
238
+ type: "string",
239
+ description: "Id of the task to fetch.",
240
+ },
241
+ },
242
+ required: ["taskId"],
243
+ },
244
+ },
245
+ async execute(input) {
246
+ const taskId = typeof input.taskId === "string" ? input.taskId.trim() : "";
247
+ if (!taskId) {
248
+ return JSON.stringify({ error: "TaskGet: 'taskId' must be a non-empty string" });
249
+ }
250
+ const task = store.get(taskId);
251
+ if (!task) {
252
+ return JSON.stringify({ error: `TaskGet: no task with id '${taskId}'` });
253
+ }
254
+ return JSON.stringify({ ok: true, task });
255
+ },
256
+ };
257
+ }
258
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/tools/builtin/tasks.ts"],"names":[],"mappings":"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"}