maestro-agent-sdk 0.1.4 → 0.1.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.
- package/README.md +197 -10
- package/dist/agents/contracts.d.ts +10 -0
- package/dist/agents/contracts.d.ts.map +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -5
- package/dist/index.js.map +1 -1
- package/dist/memory/reminder.d.ts +9 -9
- package/dist/memory/reminder.d.ts.map +1 -1
- package/dist/memory/reminder.js +21 -15
- package/dist/memory/reminder.js.map +1 -1
- package/dist/platform/version.d.ts +13 -0
- package/dist/platform/version.d.ts.map +1 -0
- package/dist/platform/version.js +13 -0
- package/dist/platform/version.js.map +1 -0
- package/dist/provider.d.ts +62 -0
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +136 -22
- package/dist/provider.js.map +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +16 -1
- package/dist/registry.js.map +1 -1
- package/dist/session-store.d.ts +95 -4
- package/dist/session-store.d.ts.map +1 -1
- package/dist/session-store.js +144 -13
- package/dist/session-store.js.map +1 -1
- package/dist/skills/curator.d.ts +8 -6
- package/dist/skills/curator.d.ts.map +1 -1
- package/dist/skills/curator.js +13 -7
- package/dist/skills/curator.js.map +1 -1
- package/dist/skills/loader.d.ts +45 -20
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js +56 -11
- package/dist/skills/loader.js.map +1 -1
- package/dist/state/tasks.d.ts +107 -0
- package/dist/state/tasks.d.ts.map +1 -0
- package/dist/state/tasks.js +398 -0
- package/dist/state/tasks.js.map +1 -0
- package/dist/sub-agent/runner.d.ts +1 -1
- package/dist/sub-agent/runner.js +3 -3
- package/dist/tools/builtin/glob.d.ts +17 -0
- package/dist/tools/builtin/glob.d.ts.map +1 -0
- package/dist/tools/builtin/glob.js +235 -0
- package/dist/tools/builtin/glob.js.map +1 -0
- package/dist/tools/builtin/grep.d.ts +3 -0
- package/dist/tools/builtin/grep.d.ts.map +1 -0
- package/dist/tools/builtin/grep.js +272 -0
- package/dist/tools/builtin/grep.js.map +1 -0
- package/dist/tools/builtin/skill_write.d.ts +53 -0
- package/dist/tools/builtin/skill_write.d.ts.map +1 -0
- package/dist/tools/builtin/skill_write.js +264 -0
- package/dist/tools/builtin/skill_write.js.map +1 -0
- package/dist/tools/builtin/tasks.d.ts +34 -0
- package/dist/tools/builtin/tasks.d.ts.map +1 -0
- package/dist/tools/builtin/tasks.js +258 -0
- package/dist/tools/builtin/tasks.js.map +1 -0
- package/dist/types.d.ts +64 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/state/todos.d.ts +0 -95
- package/dist/state/todos.d.ts.map +0 -1
- package/dist/state/todos.js +0 -198
- package/dist/state/todos.js.map +0 -1
- package/dist/tools/builtin/todo_write.d.ts +0 -29
- package/dist/tools/builtin/todo_write.d.ts.map +0 -1
- package/dist/tools/builtin/todo_write.js +0 -96
- package/dist/tools/builtin/todo_write.js.map +0 -1
package/dist/types.d.ts
CHANGED
|
@@ -84,6 +84,24 @@ export interface AgentQueryOptions {
|
|
|
84
84
|
agent: AgentKind;
|
|
85
85
|
prompt: string;
|
|
86
86
|
sessionId?: string | null;
|
|
87
|
+
/**
|
|
88
|
+
* Working-directory hint for this session.
|
|
89
|
+
*
|
|
90
|
+
* The SDK uses this for two narrow purposes:
|
|
91
|
+
* 1. `mkdir -p` so the path exists when subsequent host code stats it
|
|
92
|
+
* (e.g. resume flows that read files from the session's expected root).
|
|
93
|
+
* 2. Stamp it into the rollout `_meta` header (since v0.1.5) so a future
|
|
94
|
+
* indexer / forensic sweep can attribute the on-disk JSONL to a project.
|
|
95
|
+
*
|
|
96
|
+
* Note: the SDK loop itself does **not** chdir, and the built-in tools
|
|
97
|
+
* (Read/Write/Edit) require absolute paths regardless of this value. The
|
|
98
|
+
* Bash tool's `cwd` is per-call input from the model, NOT auto-injected
|
|
99
|
+
* from this field. Future minor versions may evolve tools to respect this
|
|
100
|
+
* hint, but today it is treated as metadata.
|
|
101
|
+
*
|
|
102
|
+
* Pass the canonical project / workspace path the host wants associated
|
|
103
|
+
* with this session.
|
|
104
|
+
*/
|
|
87
105
|
cwd: string;
|
|
88
106
|
systemPrompt: string;
|
|
89
107
|
userId?: string;
|
|
@@ -106,5 +124,51 @@ export interface AgentQueryOptions {
|
|
|
106
124
|
mcpExtra?: Record<string, unknown>;
|
|
107
125
|
isCron?: boolean;
|
|
108
126
|
silent?: boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Named skill profile within the per-cwd `.skills/` directory. The SDK
|
|
129
|
+
* resolves the skill catalog source as:
|
|
130
|
+
*
|
|
131
|
+
* - `<cwd>/.skills/<skillKey>/` when set
|
|
132
|
+
* - `<cwd>/.skills/<MAESTRO_DEFAULT_SKILL_KEY>/` when omitted (literally
|
|
133
|
+
* `<cwd>/.skills/default/` — the constant is exported so hosts can
|
|
134
|
+
* reference it symbolically).
|
|
135
|
+
*
|
|
136
|
+
* Every skill lives under a named key — the SDK never loads from the
|
|
137
|
+
* `.skills/` root directly. This keeps the layout uniform so a caller
|
|
138
|
+
* scanning the filesystem can answer "which profiles exist?" with one
|
|
139
|
+
* `readdir`.
|
|
140
|
+
*
|
|
141
|
+
* Use case: one workspace, multiple disjoint skill sets. A topic /
|
|
142
|
+
* session passes a key (e.g. "legal", "coding"); the agent's catalog
|
|
143
|
+
* is whatever lives under that subdirectory. New skills the agent
|
|
144
|
+
* writes during the session naturally land in the same subdir — the
|
|
145
|
+
* keyed dir IS the loader root, so created skills stay scoped to the
|
|
146
|
+
* key without extra plumbing.
|
|
147
|
+
*
|
|
148
|
+
* This is the only knob the SDK exposes for skill-source routing —
|
|
149
|
+
* `(cwd, skillKey)` is a deterministic pair, so two sessions with the
|
|
150
|
+
* same pair load the same catalog and there's no env-var / explicit-
|
|
151
|
+
* dir precedence chain to reason about.
|
|
152
|
+
*/
|
|
153
|
+
skillKey?: string;
|
|
154
|
+
/**
|
|
155
|
+
* Whitelist of skill names this call may surface. When provided, the
|
|
156
|
+
* loaded catalog is filtered down to entries whose `name` matches one
|
|
157
|
+
* of the listed values BEFORE curation, index rendering, and
|
|
158
|
+
* `skill_view` registration. Unknown names in the list are silently
|
|
159
|
+
* ignored (no error) so a host can safely pass a superset.
|
|
160
|
+
*
|
|
161
|
+
* Omit (or pass `undefined`) to allow every loaded skill — the default
|
|
162
|
+
* pre-0.1.5 behavior.
|
|
163
|
+
*/
|
|
164
|
+
allowedSkills?: string[];
|
|
165
|
+
/**
|
|
166
|
+
* Opaque host-controlled bag persisted alongside the session as part of
|
|
167
|
+
* the rollout `_meta` header. The SDK reads and writes this verbatim and
|
|
168
|
+
* never interprets its shape — useful for round-tripping `topicId`,
|
|
169
|
+
* `groupId`, or any other host-side identifiers that should follow the
|
|
170
|
+
* session across persistence.
|
|
171
|
+
*/
|
|
172
|
+
sessionMetadata?: Record<string, unknown>;
|
|
109
173
|
}
|
|
110
174
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "maestro-agent-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Embeddable, provider-agnostic TypeScript agent SDK — pluggable providers, built-in tools, skills, memory, and MCP.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Yeonwoo Jeong <aadd4020@gmail.com>",
|
package/dist/state/todos.d.ts
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Per-session todo list backing TodoWrite.
|
|
3
|
-
*
|
|
4
|
-
* The model gets a single `todo_write` tool to upsert / mutate the list. There
|
|
5
|
-
* is no `todo_list` tool — read-side surfaces via the per-turn system
|
|
6
|
-
* reminder, which keeps the model from juggling two near-identical tools
|
|
7
|
-
* (and saves a per-turn round-trip for what is fundamentally a snapshot view).
|
|
8
|
-
*
|
|
9
|
-
* Persistence: one JSON file at `~/.maestro/sessions/<sid>.todos.json` — a
|
|
10
|
-
* snapshot of the current list, atomically written. Not JSONL: `todo_write`
|
|
11
|
-
* semantically OVERWRITES the list each call, so an append-only stream
|
|
12
|
-
* would accumulate dead entries the loader has to filter. A single JSON
|
|
13
|
-
* snapshot matches the actual semantics and is cheaper to read.
|
|
14
|
-
*
|
|
15
|
-
* Lifecycle:
|
|
16
|
-
* - `getTodoStore(sid)` lazy-creates the store and hydrates from disk if
|
|
17
|
-
* a prior turn wrote one.
|
|
18
|
-
* - `dropTodoStore(sid)` is called from `deleteMaestroSession` and
|
|
19
|
-
* `cleanupStaleMaestroSessions` (same pattern as `file-state.ts`) so the
|
|
20
|
-
* module-level map can't outlive its sessions.
|
|
21
|
-
*
|
|
22
|
-
* Invariants enforced at upsert time:
|
|
23
|
-
* - At most one entry is `in_progress`. Setting a second one to
|
|
24
|
-
* `in_progress` flips any prior one to `pending` and warns the caller
|
|
25
|
-
* via the tool result. Mirrors Claude Code's TodoWrite contract.
|
|
26
|
-
* - IDs are auto-assigned (`task-1`, `task-2`, …) when omitted. Short IDs
|
|
27
|
-
* so the model can refer back to them in prose without bloat.
|
|
28
|
-
*/
|
|
29
|
-
export type TodoStatus = "pending" | "in_progress" | "completed";
|
|
30
|
-
export interface TodoEntry {
|
|
31
|
-
id: string;
|
|
32
|
-
content: string;
|
|
33
|
-
status: TodoStatus;
|
|
34
|
-
/** Optional present-continuous form for spinner/status display
|
|
35
|
-
* ("Reading config" vs the imperative "Read config"). */
|
|
36
|
-
activeForm?: string;
|
|
37
|
-
}
|
|
38
|
-
export interface TodoUpsert {
|
|
39
|
-
id?: string;
|
|
40
|
-
content: string;
|
|
41
|
-
status: TodoStatus;
|
|
42
|
-
activeForm?: string;
|
|
43
|
-
}
|
|
44
|
-
export interface UpsertResult {
|
|
45
|
-
todos: TodoEntry[];
|
|
46
|
-
/** Set when the upsert had to flip a prior in_progress to pending to
|
|
47
|
-
* enforce the 1-in-progress invariant. The tool surfaces this in its
|
|
48
|
-
* result so the model knows the previously-active item was bumped. */
|
|
49
|
-
demotedId?: string;
|
|
50
|
-
}
|
|
51
|
-
export declare class TodoStore {
|
|
52
|
-
private readonly path;
|
|
53
|
-
private todos;
|
|
54
|
-
private nextCounter;
|
|
55
|
-
constructor(path: string);
|
|
56
|
-
/** Read the current list. Caller must not mutate. */
|
|
57
|
-
list(): readonly TodoEntry[];
|
|
58
|
-
/** True when the list is empty (no in-flight or pending work). */
|
|
59
|
-
isEmpty(): boolean;
|
|
60
|
-
/**
|
|
61
|
-
* Replace / upsert the entire list. Entries with an `id` that matches an
|
|
62
|
-
* existing one update that entry; entries without an id (or with an id
|
|
63
|
-
* not in the current list) become new entries with an auto-assigned id.
|
|
64
|
-
*
|
|
65
|
-
* The shape mirrors Claude Code's TodoWrite: the model passes a complete
|
|
66
|
-
* snapshot of "what I want the list to look like now," and we reconcile.
|
|
67
|
-
* That means an existing id NOT included in the incoming snapshot is
|
|
68
|
-
* dropped — TodoWrite is a snapshot replace, not a partial update.
|
|
69
|
-
*
|
|
70
|
-
* Returns `{todos, demotedId?}` so the tool can tell the model exactly
|
|
71
|
-
* what landed (incl. any in-progress demotion).
|
|
72
|
-
*/
|
|
73
|
-
upsert(incoming: TodoUpsert[]): UpsertResult;
|
|
74
|
-
/** Drop the on-disk file. Called by deleteMaestroSession via dropTodoStore. */
|
|
75
|
-
unlinkFile(): void;
|
|
76
|
-
/** Test-only: snapshot the path the store is backed by. */
|
|
77
|
-
__path(): string;
|
|
78
|
-
private nextId;
|
|
79
|
-
private hydrate;
|
|
80
|
-
/** Recover the counter from existing IDs when the file lacked the field
|
|
81
|
-
* (defensive — recent hydrate writes always include it). */
|
|
82
|
-
private deriveCounter;
|
|
83
|
-
private persist;
|
|
84
|
-
}
|
|
85
|
-
/** Resolve the absolute todos-file path for a session. Mirrors
|
|
86
|
-
* `maestroSessionPath` but with `.todos.json` instead of `.jsonl`. */
|
|
87
|
-
export declare function todosPathFor(sessionId: string): string;
|
|
88
|
-
export declare function getTodoStore(sessionId: string): TodoStore;
|
|
89
|
-
/** Drop a session's store + unlink its on-disk file. */
|
|
90
|
-
export declare function dropTodoStore(sessionId: string): void;
|
|
91
|
-
/** Test-only. Reset every store. */
|
|
92
|
-
export declare function __resetAllStores(): void;
|
|
93
|
-
/** Test-only. Count of currently-tracked sessions. */
|
|
94
|
-
export declare function __storeCount(): number;
|
|
95
|
-
//# sourceMappingURL=todos.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"todos.d.ts","sourceRoot":"","sources":["../../src/state/todos.ts"],"names":[],"mappings":"AAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;AAEjE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,CAAC;IACnB;8DAC0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AASD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB;;2EAEuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,SAAS;IAIR,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,WAAW,CAAK;gBAEK,IAAI,EAAE,MAAM;IAIzC,qDAAqD;IACrD,IAAI,IAAI,SAAS,SAAS,EAAE;IAI5B,kEAAkE;IAClE,OAAO,IAAI,OAAO;IAIlB;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,YAAY;IAwC5C,+EAA+E;IAC/E,UAAU,IAAI,IAAI;IAUlB,2DAA2D;IAC3D,MAAM,IAAI,MAAM;IAMhB,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,OAAO;IAgBf;iEAC6D;IAC7D,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,OAAO;CAQhB;AAqBD;uEACuE;AACvE,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtD;AAeD,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAOzD;AAED,wDAAwD;AACxD,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAMrD;AAED,oCAAoC;AACpC,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED,sDAAsD;AACtD,wBAAgB,YAAY,IAAI,MAAM,CAErC"}
|
package/dist/state/todos.js
DELETED
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
4
|
-
import { logger } from "../platform/logger.js";
|
|
5
|
-
/** Mirror of `maestroSessionsDir()` from session-store.ts — inlined here to
|
|
6
|
-
* avoid a circular import (session-store.ts needs to call
|
|
7
|
-
* `dropTodoStore` for cleanup). Two single-line copies are cheaper than
|
|
8
|
-
* extracting a shared util file for one path. */
|
|
9
|
-
function sessionsDir() {
|
|
10
|
-
return join(homedir(), ".maestro", "sessions");
|
|
11
|
-
}
|
|
12
|
-
export class TodoStore {
|
|
13
|
-
path;
|
|
14
|
-
todos = [];
|
|
15
|
-
nextCounter = 1;
|
|
16
|
-
constructor(path) {
|
|
17
|
-
this.path = path;
|
|
18
|
-
this.hydrate();
|
|
19
|
-
}
|
|
20
|
-
/** Read the current list. Caller must not mutate. */
|
|
21
|
-
list() {
|
|
22
|
-
return this.todos;
|
|
23
|
-
}
|
|
24
|
-
/** True when the list is empty (no in-flight or pending work). */
|
|
25
|
-
isEmpty() {
|
|
26
|
-
return this.todos.length === 0;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Replace / upsert the entire list. Entries with an `id` that matches an
|
|
30
|
-
* existing one update that entry; entries without an id (or with an id
|
|
31
|
-
* not in the current list) become new entries with an auto-assigned id.
|
|
32
|
-
*
|
|
33
|
-
* The shape mirrors Claude Code's TodoWrite: the model passes a complete
|
|
34
|
-
* snapshot of "what I want the list to look like now," and we reconcile.
|
|
35
|
-
* That means an existing id NOT included in the incoming snapshot is
|
|
36
|
-
* dropped — TodoWrite is a snapshot replace, not a partial update.
|
|
37
|
-
*
|
|
38
|
-
* Returns `{todos, demotedId?}` so the tool can tell the model exactly
|
|
39
|
-
* what landed (incl. any in-progress demotion).
|
|
40
|
-
*/
|
|
41
|
-
upsert(incoming) {
|
|
42
|
-
const out = [];
|
|
43
|
-
let demotedId;
|
|
44
|
-
// First pass: build the new list, assigning IDs to entries that need
|
|
45
|
-
// them. We do this BEFORE the 1-in-progress sweep so the auto-IDs are
|
|
46
|
-
// available for the warning message.
|
|
47
|
-
for (const item of incoming) {
|
|
48
|
-
const id = item.id?.trim() || this.nextId();
|
|
49
|
-
out.push({
|
|
50
|
-
id,
|
|
51
|
-
content: item.content,
|
|
52
|
-
status: item.status,
|
|
53
|
-
...(item.activeForm ? { activeForm: item.activeForm } : {}),
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
// Second pass: enforce 1-in-progress. Walk in incoming order; the LAST
|
|
57
|
-
// in_progress wins (mirrors how a model batch-updates and the final
|
|
58
|
-
// entry expresses current intent). Earlier in_progress entries are
|
|
59
|
-
// flipped to pending and surfaced via `demotedId`.
|
|
60
|
-
let lastInProgressIdx = -1;
|
|
61
|
-
for (let i = 0; i < out.length; i++) {
|
|
62
|
-
if (out[i].status === "in_progress")
|
|
63
|
-
lastInProgressIdx = i;
|
|
64
|
-
}
|
|
65
|
-
if (lastInProgressIdx >= 0) {
|
|
66
|
-
for (let i = 0; i < out.length; i++) {
|
|
67
|
-
if (i === lastInProgressIdx)
|
|
68
|
-
continue;
|
|
69
|
-
if (out[i].status === "in_progress") {
|
|
70
|
-
out[i] = { ...out[i], status: "pending" };
|
|
71
|
-
demotedId = out[i].id;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
this.todos = out;
|
|
76
|
-
this.persist();
|
|
77
|
-
return demotedId !== undefined ? { todos: out, demotedId } : { todos: out };
|
|
78
|
-
}
|
|
79
|
-
/** Drop the on-disk file. Called by deleteMaestroSession via dropTodoStore. */
|
|
80
|
-
unlinkFile() {
|
|
81
|
-
try {
|
|
82
|
-
unlinkSync(this.path);
|
|
83
|
-
}
|
|
84
|
-
catch (e) {
|
|
85
|
-
if (e?.code !== "ENOENT") {
|
|
86
|
-
logger.warn({ err: e, path: this.path }, "TodoStore.unlinkFile failed");
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
/** Test-only: snapshot the path the store is backed by. */
|
|
91
|
-
__path() {
|
|
92
|
-
return this.path;
|
|
93
|
-
}
|
|
94
|
-
// --- internals ---------------------------------------------------------
|
|
95
|
-
nextId() {
|
|
96
|
-
const id = `task-${this.nextCounter}`;
|
|
97
|
-
this.nextCounter++;
|
|
98
|
-
return id;
|
|
99
|
-
}
|
|
100
|
-
hydrate() {
|
|
101
|
-
if (!existsSync(this.path))
|
|
102
|
-
return;
|
|
103
|
-
try {
|
|
104
|
-
const raw = readFileSync(this.path, "utf8");
|
|
105
|
-
const parsed = JSON.parse(raw);
|
|
106
|
-
if (parsed.version !== 1 || !Array.isArray(parsed.todos)) {
|
|
107
|
-
logger.warn({ path: this.path }, "TodoStore.hydrate: unsupported schema, ignoring");
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
this.todos = parsed.todos.filter(isWellFormedEntry);
|
|
111
|
-
this.nextCounter = Math.max(1, parsed.nextCounter ?? this.deriveCounter());
|
|
112
|
-
}
|
|
113
|
-
catch (e) {
|
|
114
|
-
logger.warn({ err: e, path: this.path }, "TodoStore.hydrate: parse failed, starting empty");
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
/** Recover the counter from existing IDs when the file lacked the field
|
|
118
|
-
* (defensive — recent hydrate writes always include it). */
|
|
119
|
-
deriveCounter() {
|
|
120
|
-
let max = 0;
|
|
121
|
-
for (const t of this.todos) {
|
|
122
|
-
const m = /^task-(\d+)$/.exec(t.id);
|
|
123
|
-
if (m)
|
|
124
|
-
max = Math.max(max, Number.parseInt(m[1], 10));
|
|
125
|
-
}
|
|
126
|
-
return max + 1;
|
|
127
|
-
}
|
|
128
|
-
persist() {
|
|
129
|
-
const file = {
|
|
130
|
-
version: 1,
|
|
131
|
-
nextCounter: this.nextCounter,
|
|
132
|
-
todos: this.todos,
|
|
133
|
-
};
|
|
134
|
-
writeAtomic(this.path, file);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
/** Atomic write: tmp → rename. Same pattern as skills/usage.ts. */
|
|
138
|
-
function writeAtomic(path, contents) {
|
|
139
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
140
|
-
const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;
|
|
141
|
-
writeFileSync(tmp, JSON.stringify(contents, null, 2));
|
|
142
|
-
renameSync(tmp, path);
|
|
143
|
-
}
|
|
144
|
-
function isWellFormedEntry(v) {
|
|
145
|
-
if (!v || typeof v !== "object")
|
|
146
|
-
return false;
|
|
147
|
-
const o = v;
|
|
148
|
-
if (typeof o.id !== "string" || typeof o.content !== "string")
|
|
149
|
-
return false;
|
|
150
|
-
if (o.status !== "pending" && o.status !== "in_progress" && o.status !== "completed") {
|
|
151
|
-
return false;
|
|
152
|
-
}
|
|
153
|
-
if (o.activeForm !== undefined && typeof o.activeForm !== "string")
|
|
154
|
-
return false;
|
|
155
|
-
return true;
|
|
156
|
-
}
|
|
157
|
-
/** Resolve the absolute todos-file path for a session. Mirrors
|
|
158
|
-
* `maestroSessionPath` but with `.todos.json` instead of `.jsonl`. */
|
|
159
|
-
export function todosPathFor(sessionId) {
|
|
160
|
-
return join(sessionsDir(), `${sessionId}.todos.json`);
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Module-level registry — same pattern as `file-state.ts`.
|
|
164
|
-
*
|
|
165
|
-
* The maestroProvider rebuilds tools each turn but the sessionId persists
|
|
166
|
-
* across turns. A registry-local store would re-hydrate every turn (cheap
|
|
167
|
-
* but wasteful); a module-level cache keeps the in-memory list hot.
|
|
168
|
-
*
|
|
169
|
-
* Cleanup is wired into `deleteMaestroSession` and
|
|
170
|
-
* `cleanupStaleMaestroSessions` (see session-store.ts) so the map can't
|
|
171
|
-
* outlive its sessions.
|
|
172
|
-
*/
|
|
173
|
-
const stores = new Map();
|
|
174
|
-
export function getTodoStore(sessionId) {
|
|
175
|
-
let s = stores.get(sessionId);
|
|
176
|
-
if (!s) {
|
|
177
|
-
s = new TodoStore(todosPathFor(sessionId));
|
|
178
|
-
stores.set(sessionId, s);
|
|
179
|
-
}
|
|
180
|
-
return s;
|
|
181
|
-
}
|
|
182
|
-
/** Drop a session's store + unlink its on-disk file. */
|
|
183
|
-
export function dropTodoStore(sessionId) {
|
|
184
|
-
const s = stores.get(sessionId);
|
|
185
|
-
if (s) {
|
|
186
|
-
s.unlinkFile();
|
|
187
|
-
stores.delete(sessionId);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
/** Test-only. Reset every store. */
|
|
191
|
-
export function __resetAllStores() {
|
|
192
|
-
stores.clear();
|
|
193
|
-
}
|
|
194
|
-
/** Test-only. Count of currently-tracked sessions. */
|
|
195
|
-
export function __storeCount() {
|
|
196
|
-
return stores.size;
|
|
197
|
-
}
|
|
198
|
-
//# sourceMappingURL=todos.js.map
|
package/dist/state/todos.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"todos.js","sourceRoot":"","sources":["../../src/state/todos.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { TodoStore } from "../../state/todos.js";
|
|
2
|
-
import type { ToolHandler } from "../../tools/registry.js";
|
|
3
|
-
/**
|
|
4
|
-
* `todo_write` builtin — TodoWrite-style task tracking for maestro.
|
|
5
|
-
*
|
|
6
|
-
* One tool, snapshot-replace semantics: the model passes the COMPLETE list
|
|
7
|
-
* it wants in place, and the store reconciles (upsert by id, drop entries
|
|
8
|
-
* absent from the snapshot, auto-assign ids on new items).
|
|
9
|
-
*
|
|
10
|
-
* Claude Code parity:
|
|
11
|
-
* - No separate `todo_list`. Read-side surfaces via the per-turn system
|
|
12
|
-
* reminder, which renders the current list each turn — no extra
|
|
13
|
-
* round-trip + no decision surface for "which tool do I call?".
|
|
14
|
-
* - 1-in-progress invariant. The LAST `in_progress` in the incoming
|
|
15
|
-
* snapshot wins; earlier in_progress entries are flipped to `pending`
|
|
16
|
-
* and the demoted id is reported back so the model knows.
|
|
17
|
-
*
|
|
18
|
-
* Side-effecting: every call mutates the store + persists to disk.
|
|
19
|
-
* `parallelSafe: false` is the right default — running two `todo_write`
|
|
20
|
-
* calls in parallel would race the snapshot.
|
|
21
|
-
*/
|
|
22
|
-
export interface TodoWriteToolOptions {
|
|
23
|
-
/** Required. The per-session store. Built by maestroProvider via
|
|
24
|
-
* `getTodoStore(sessionId)` so the same instance is shared across
|
|
25
|
-
* every tool call in this turn. */
|
|
26
|
-
store: TodoStore;
|
|
27
|
-
}
|
|
28
|
-
export declare function createTodoWriteTool(opts: TodoWriteToolOptions): ToolHandler;
|
|
29
|
-
//# sourceMappingURL=todo_write.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"todo_write.d.ts","sourceRoot":"","sources":["../../../src/tools/builtin/todo_write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,eAAe,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,oBAAoB;IACnC;;wCAEoC;IACpC,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,WAAW,CA+E3E"}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
export function createTodoWriteTool(opts) {
|
|
2
|
-
const { store } = opts;
|
|
3
|
-
return {
|
|
4
|
-
parallelSafe: false,
|
|
5
|
-
schema: {
|
|
6
|
-
name: "todo_write",
|
|
7
|
-
description: "Write the current task list. Pass the COMPLETE snapshot of what you want the list " +
|
|
8
|
-
"to look like — entries with an existing `id` are updated, new entries (id omitted) " +
|
|
9
|
-
"get an auto-assigned id (task-N), and entries absent from the snapshot are dropped. " +
|
|
10
|
-
"At most one entry may have status `in_progress`; if you mark more than one, the LAST " +
|
|
11
|
-
"in_progress wins and the others are flipped to `pending`. The current list is " +
|
|
12
|
-
"surfaced to you in the system reminder each turn — call this whenever a multi-step " +
|
|
13
|
-
"plan starts, mid-flight when a step finishes, or to add/drop items.",
|
|
14
|
-
input_schema: {
|
|
15
|
-
type: "object",
|
|
16
|
-
properties: {
|
|
17
|
-
todos: {
|
|
18
|
-
type: "array",
|
|
19
|
-
description: "Complete snapshot of the task list. Each item: " +
|
|
20
|
-
"{id?: string, content: string, status: 'pending'|'in_progress'|'completed', " +
|
|
21
|
-
"activeForm?: string}. Include EVERY task you want to keep — omitting one drops it.",
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
required: ["todos"],
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
async execute(input) {
|
|
28
|
-
const raw = input.todos;
|
|
29
|
-
if (!Array.isArray(raw)) {
|
|
30
|
-
return JSON.stringify({
|
|
31
|
-
error: "todo_write: 'todos' must be an array",
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
const incoming = [];
|
|
35
|
-
for (let i = 0; i < raw.length; i++) {
|
|
36
|
-
const item = raw[i];
|
|
37
|
-
if (!item || typeof item !== "object") {
|
|
38
|
-
return JSON.stringify({
|
|
39
|
-
error: `todo_write: todos[${i}] must be an object`,
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
const obj = item;
|
|
43
|
-
const content = obj.content;
|
|
44
|
-
const status = obj.status;
|
|
45
|
-
if (typeof content !== "string" || content.length === 0) {
|
|
46
|
-
return JSON.stringify({
|
|
47
|
-
error: `todo_write: todos[${i}].content must be a non-empty string`,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
if (status !== "pending" && status !== "in_progress" && status !== "completed") {
|
|
51
|
-
return JSON.stringify({
|
|
52
|
-
error: `todo_write: todos[${i}].status must be 'pending', 'in_progress', or 'completed'`,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
const upsert = { content, status };
|
|
56
|
-
if (typeof obj.id === "string" && obj.id.length > 0)
|
|
57
|
-
upsert.id = obj.id;
|
|
58
|
-
if (typeof obj.activeForm === "string" && obj.activeForm.length > 0) {
|
|
59
|
-
upsert.activeForm = obj.activeForm;
|
|
60
|
-
}
|
|
61
|
-
incoming.push(upsert);
|
|
62
|
-
}
|
|
63
|
-
const result = store.upsert(incoming);
|
|
64
|
-
const summary = summarize(result.todos);
|
|
65
|
-
const parts = [
|
|
66
|
-
`Task list updated (${result.todos.length} item${result.todos.length === 1 ? "" : "s"}).`,
|
|
67
|
-
summary,
|
|
68
|
-
];
|
|
69
|
-
if (result.demotedId) {
|
|
70
|
-
parts.push(`Note: more than one item was marked in_progress; '${result.demotedId}' was flipped to pending so only the last in_progress entry stays active.`);
|
|
71
|
-
}
|
|
72
|
-
return parts.join("\n\n");
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Render a compact ascii summary of the list. Used in the tool result so
|
|
78
|
-
* the model immediately sees what landed (mirrors how Edit returns a
|
|
79
|
-
* preview after a successful write).
|
|
80
|
-
*
|
|
81
|
-
* Format:
|
|
82
|
-
* [✓] task-1 Done thing here
|
|
83
|
-
* [→] task-2 In-flight thing
|
|
84
|
-
* [ ] task-3 Pending thing
|
|
85
|
-
*/
|
|
86
|
-
function summarize(todos) {
|
|
87
|
-
if (todos.length === 0)
|
|
88
|
-
return "(list is empty)";
|
|
89
|
-
return todos
|
|
90
|
-
.map((t) => {
|
|
91
|
-
const mark = t.status === "completed" ? "✓" : t.status === "in_progress" ? "→" : " ";
|
|
92
|
-
return `[${mark}] ${t.id} ${t.content}`;
|
|
93
|
-
})
|
|
94
|
-
.join("\n");
|
|
95
|
-
}
|
|
96
|
-
//# sourceMappingURL=todo_write.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"todo_write.js","sourceRoot":"","sources":["../../../src/tools/builtin/todo_write.ts"],"names":[],"mappings":"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"}
|