@astralyn/pi 0.84.6 → 0.84.8
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/CHANGELOG.md +27 -0
- package/dist/core/compaction/compaction.d.ts +2 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +7 -7
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/extensions/background/index.d.ts.map +1 -1
- package/dist/extensions/background/index.js +48 -72
- package/dist/extensions/background/index.js.map +1 -1
- package/dist/extensions/background/manager.d.ts.map +1 -1
- package/dist/extensions/background/manager.js +5 -3
- package/dist/extensions/background/manager.js.map +1 -1
- package/dist/extensions/background/registry.d.ts +11 -13
- package/dist/extensions/background/registry.d.ts.map +1 -1
- package/dist/extensions/background/registry.js +71 -80
- package/dist/extensions/background/registry.js.map +1 -1
- package/dist/extensions/background/render.d.ts.map +1 -1
- package/dist/extensions/background/render.js +17 -4
- package/dist/extensions/background/render.js.map +1 -1
- package/dist/extensions/deepwiki/constants.d.ts +2 -2
- package/dist/extensions/deepwiki/constants.d.ts.map +1 -1
- package/dist/extensions/deepwiki/constants.js +5 -5
- package/dist/extensions/deepwiki/constants.js.map +1 -1
- package/dist/extensions/deepwiki/schema.js +1 -1
- package/dist/extensions/deepwiki/schema.js.map +1 -1
- package/dist/extensions/question/constants.d.ts +2 -2
- package/dist/extensions/question/constants.d.ts.map +1 -1
- package/dist/extensions/question/constants.js +5 -2
- package/dist/extensions/question/constants.js.map +1 -1
- package/dist/extensions/router/dialog-host.d.ts +60 -0
- package/dist/extensions/router/dialog-host.d.ts.map +1 -0
- package/dist/extensions/router/dialog-host.js +196 -0
- package/dist/extensions/router/dialog-host.js.map +1 -0
- package/dist/extensions/router/probe.d.ts.map +1 -1
- package/dist/extensions/router/probe.js +2 -0
- package/dist/extensions/router/probe.js.map +1 -1
- package/dist/extensions/router/ui.d.ts.map +1 -1
- package/dist/extensions/router/ui.js +117 -67
- package/dist/extensions/router/ui.js.map +1 -1
- package/dist/extensions/subagent/activity.d.ts +9 -0
- package/dist/extensions/subagent/activity.d.ts.map +1 -1
- package/dist/extensions/subagent/activity.js +21 -0
- package/dist/extensions/subagent/activity.js.map +1 -1
- package/dist/extensions/subagent/agents-command.d.ts.map +1 -1
- package/dist/extensions/subagent/agents-command.js +355 -71
- package/dist/extensions/subagent/agents-command.js.map +1 -1
- package/dist/extensions/subagent/agents.d.ts.map +1 -1
- package/dist/extensions/subagent/agents.js +7 -3
- package/dist/extensions/subagent/agents.js.map +1 -1
- package/dist/extensions/subagent/constants.d.ts +1 -0
- package/dist/extensions/subagent/constants.d.ts.map +1 -1
- package/dist/extensions/subagent/constants.js +4 -0
- package/dist/extensions/subagent/constants.js.map +1 -1
- package/dist/extensions/subagent/index.js +2 -2
- package/dist/extensions/subagent/index.js.map +1 -1
- package/dist/extensions/subagent/render.d.ts.map +1 -1
- package/dist/extensions/subagent/render.js +1 -7
- package/dist/extensions/subagent/render.js.map +1 -1
- package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
- package/dist/extensions/subagent/sdk-runner.js +19 -0
- package/dist/extensions/subagent/sdk-runner.js.map +1 -1
- package/dist/extensions/subagent/settings.d.ts.map +1 -1
- package/dist/extensions/subagent/settings.js +11 -4
- package/dist/extensions/subagent/settings.js.map +1 -1
- package/dist/extensions/subagent/state.d.ts +9 -0
- package/dist/extensions/subagent/state.d.ts.map +1 -1
- package/dist/extensions/subagent/state.js +33 -2
- package/dist/extensions/subagent/state.js.map +1 -1
- package/dist/extensions/subagent/ui/model-list.d.ts +1 -0
- package/dist/extensions/subagent/ui/model-list.d.ts.map +1 -1
- package/dist/extensions/subagent/ui/model-list.js +5 -0
- package/dist/extensions/subagent/ui/model-list.js.map +1 -1
- package/dist/extensions/todo/constants.d.ts +1 -1
- package/dist/extensions/todo/constants.d.ts.map +1 -1
- package/dist/extensions/todo/constants.js +10 -27
- package/dist/extensions/todo/constants.js.map +1 -1
- package/dist/extensions/todo/state.d.ts.map +1 -1
- package/dist/extensions/todo/state.js +27 -16
- package/dist/extensions/todo/state.js.map +1 -1
- package/dist/extensions/todo/view.d.ts.map +1 -1
- package/dist/extensions/todo/view.js +16 -5
- package/dist/extensions/todo/view.js.map +1 -1
- package/docs/bundled/extensions/background.md +3 -3
- package/docs/bundled/extensions/todo.md +2 -2
- package/docs/compaction.md +2 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -10,7 +10,7 @@ export declare const TODO_MAX_BATCH_ITEMS = 20;
|
|
|
10
10
|
/** Input limits keep task snapshots and model-facing output bounded. */
|
|
11
11
|
export declare const TODO_MAX_SUBJECT_LENGTH = 160;
|
|
12
12
|
export declare const TODO_MAX_DESCRIPTION_LENGTH = 500;
|
|
13
|
-
export declare const TODO_TOOL_DESCRIPTION = "Manage the conversation's task list for multi-step coding work
|
|
13
|
+
export declare const TODO_TOOL_DESCRIPTION = "Manage the conversation's task list for multi-step coding work. create atomically adds pending tasks; update edits one task by id and requires at least one of subject, description, or status; list returns every remaining task with its description, active first; delete removes tasks by ids. The list holds at most 20 tasks including completed ones, and ids are never reused. Exactly one task may be in_progress, so setting one demotes any other active task to pending; any transition is allowed, including reopening a completed task. A call that fails validation, including a delete naming an id that does not exist, leaves the list unchanged.\n\n{\"action\": \"create\", \"items\": [{\"subject\": \"Wire parser\", \"description\": \"Parser handles the config format\"}, {\"subject\": \"Test parser\", \"description\": \"Parser tests pass\"}]}\n{\"action\": \"update\", \"id\": 2, \"status\": \"in_progress\"}\n{\"action\": \"update\", \"id\": 2, \"status\": \"completed\", \"description\": \"Parser verified against config fixtures\"}\n{\"action\": \"delete\", \"ids\": [3]}";
|
|
14
14
|
export declare const TODO_PROMPT_SNIPPET = "Track multi-step coding work with a small outcome-oriented task list";
|
|
15
15
|
export declare const TODO_PROMPT_GUIDELINES: string[];
|
|
16
16
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/extensions/todo/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,cAAc,SAAS,CAAC;AACrC,eAAO,MAAM,eAAe,SAAS,CAAC;AACtC,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAE1C,0EAA0E;AAC1E,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,wEAAwE;AACxE,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,2BAA2B,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/extensions/todo/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,cAAc,SAAS,CAAC;AACrC,eAAO,MAAM,eAAe,SAAS,CAAC;AACtC,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAE1C,0EAA0E;AAC1E,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,wEAAwE;AACxE,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAM/C,eAAO,MAAM,qBAAqB,wjCAKD,CAAC;AAElC,eAAO,MAAM,mBAAmB,yEAAyE,CAAC;AAE1G,eAAO,MAAM,sBAAsB,UAKlC,CAAC"}
|
|
@@ -10,38 +10,21 @@ export const TODO_MAX_BATCH_ITEMS = 20;
|
|
|
10
10
|
/** Input limits keep task snapshots and model-facing output bounded. */
|
|
11
11
|
export const TODO_MAX_SUBJECT_LENGTH = 160;
|
|
12
12
|
export const TODO_MAX_DESCRIPTION_LENGTH = 500;
|
|
13
|
-
|
|
13
|
+
// Mechanism plus the cross-field rules TodoParamsSchema cannot state (total
|
|
14
|
+
// capacity, id reuse, the update-needs-one-field rule). Per-parameter bounds and
|
|
15
|
+
// wording live in the schema. The single-in_progress rule is stated in both
|
|
16
|
+
// places on purpose: it is the invariant models break most often.
|
|
17
|
+
export const TODO_TOOL_DESCRIPTION = `Manage the conversation's task list for multi-step coding work. create atomically adds pending tasks; update edits one task by id and requires at least one of subject, description, or status; list returns every remaining task with its description, active first; delete removes tasks by ids. The list holds at most 20 tasks including completed ones, and ids are never reused. Exactly one task may be in_progress, so setting one demotes any other active task to pending; any transition is allowed, including reopening a completed task. A call that fails validation, including a delete naming an id that does not exist, leaves the list unchanged.
|
|
14
18
|
|
|
15
|
-
## When to Use
|
|
16
|
-
- Work with three or more meaningful steps, a user-provided task list, or a long session where progress can drift
|
|
17
|
-
- Capture new user requirements as tasks right away; after completing a task, add follow-up tasks discovered during implementation
|
|
18
|
-
|
|
19
|
-
## When NOT to Use
|
|
20
|
-
- Trivial single-step tasks and simple Q&A — just do the work
|
|
21
|
-
|
|
22
|
-
## Actions
|
|
23
|
-
- create: atomically add one or many pending tasks from the ordered items array (1 to 20 items); each item needs a short imperative subject and a description of what done means
|
|
24
|
-
- update: edit one task by id — subject, description, or status; all transitions and reopens are allowed
|
|
25
|
-
- list: show every remaining task with its description, active first
|
|
26
|
-
- delete: remove obsolete tasks by ids (1 to 20, duplicates ignored)
|
|
27
|
-
- The current list holds at most 20 tasks; parameters that do not apply to the chosen action are rejected
|
|
28
|
-
|
|
29
|
-
## Status Workflow
|
|
30
|
-
pending -> in_progress -> completed. Keep exactly one task in_progress: marking one active demotes any other active task to pending. Mark a task in_progress BEFORE starting the work, and completed only when its description is satisfied and relevant checks pass; never with failing tests or partial work. Reopen instead of duplicating. When blocked, do not fake completion: return the task to pending, create a task for the blocker, and finish the blocker first.
|
|
31
|
-
|
|
32
|
-
## Examples
|
|
33
19
|
{"action": "create", "items": [{"subject": "Wire parser", "description": "Parser handles the config format"}, {"subject": "Test parser", "description": "Parser tests pass"}]}
|
|
34
20
|
{"action": "update", "id": 2, "status": "in_progress"}
|
|
35
21
|
{"action": "update", "id": 2, "status": "completed", "description": "Parser verified against config fixtures"}
|
|
36
|
-
{"action": "delete", "ids": [3]}
|
|
37
|
-
|
|
38
|
-
## Tips
|
|
39
|
-
- list before create to avoid duplicates; prefer working in id order — earlier tasks usually set up context for later ones
|
|
40
|
-
- delete obsolete tasks promptly so the list stays short and accurate`;
|
|
22
|
+
{"action": "delete", "ids": [3]}`;
|
|
41
23
|
export const TODO_PROMPT_SNIPPET = "Track multi-step coding work with a small outcome-oriented task list";
|
|
42
24
|
export const TODO_PROMPT_GUIDELINES = [
|
|
43
|
-
"Use `todo` for work with three or more meaningful steps, user-provided task lists,
|
|
44
|
-
"Keep exactly one `todo` task in_progress: mark it
|
|
45
|
-
"
|
|
25
|
+
"Use `todo` for work with three or more meaningful steps, for user-provided task lists, and in long sessions where progress can drift; skip it for trivial single-step tasks and simple Q&A.",
|
|
26
|
+
"Keep exactly one `todo` task in_progress: mark it before starting the work, and completed only after its description is satisfied — never while tests fail or work is partial.",
|
|
27
|
+
"When blocked, leave the `todo` task pending and create a task for the blocker instead of faking completion.",
|
|
28
|
+
"Keep the `todo` list short: list before create to avoid duplicates, work in id order, and delete obsolete tasks promptly.",
|
|
46
29
|
];
|
|
47
30
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/extensions/todo/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AACrC,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC;AACtC,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAE1C,0EAA0E;AAC1E,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEvC,wEAAwE;AACxE,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAC3C,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAE/C,MAAM,CAAC,MAAM,qBAAqB,GAAG
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/extensions/todo/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AACrC,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC;AACtC,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAE1C,0EAA0E;AAC1E,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEvC,wEAAwE;AACxE,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAC3C,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAE/C,4EAA4E;AAC5E,iFAAiF;AACjF,4EAA4E;AAC5E,kEAAkE;AAClE,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;iCAKJ,CAAC;AAElC,MAAM,CAAC,MAAM,mBAAmB,GAAG,sEAAsE,CAAC;AAE1G,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACrC,6LAA6L;IAC7L,gLAAgL;IAChL,6GAA6G;IAC7G,2HAA2H;CAC3H,CAAC","sourcesContent":["/**\n * todo/constants.ts — tool identity, command name, input bounds, and prompt copy.\n */\n\nexport const TODO_TOOL_NAME = \"todo\";\nexport const TODO_TOOL_LABEL = \"Todo\";\nexport const TODOS_COMMAND_NAME = \"todos\";\n\n/** Hard capacity of the task list and of a single create/delete batch. */\nexport const TODO_MAX_ITEMS = 20;\nexport const TODO_MAX_BATCH_ITEMS = 20;\n\n/** Input limits keep task snapshots and model-facing output bounded. */\nexport const TODO_MAX_SUBJECT_LENGTH = 160;\nexport const TODO_MAX_DESCRIPTION_LENGTH = 500;\n\n// Mechanism plus the cross-field rules TodoParamsSchema cannot state (total\n// capacity, id reuse, the update-needs-one-field rule). Per-parameter bounds and\n// wording live in the schema. The single-in_progress rule is stated in both\n// places on purpose: it is the invariant models break most often.\nexport const TODO_TOOL_DESCRIPTION = `Manage the conversation's task list for multi-step coding work. create atomically adds pending tasks; update edits one task by id and requires at least one of subject, description, or status; list returns every remaining task with its description, active first; delete removes tasks by ids. The list holds at most 20 tasks including completed ones, and ids are never reused. Exactly one task may be in_progress, so setting one demotes any other active task to pending; any transition is allowed, including reopening a completed task. A call that fails validation, including a delete naming an id that does not exist, leaves the list unchanged.\n\n{\"action\": \"create\", \"items\": [{\"subject\": \"Wire parser\", \"description\": \"Parser handles the config format\"}, {\"subject\": \"Test parser\", \"description\": \"Parser tests pass\"}]}\n{\"action\": \"update\", \"id\": 2, \"status\": \"in_progress\"}\n{\"action\": \"update\", \"id\": 2, \"status\": \"completed\", \"description\": \"Parser verified against config fixtures\"}\n{\"action\": \"delete\", \"ids\": [3]}`;\n\nexport const TODO_PROMPT_SNIPPET = \"Track multi-step coding work with a small outcome-oriented task list\";\n\nexport const TODO_PROMPT_GUIDELINES = [\n\t\"Use `todo` for work with three or more meaningful steps, for user-provided task lists, and in long sessions where progress can drift; skip it for trivial single-step tasks and simple Q&A.\",\n\t\"Keep exactly one `todo` task in_progress: mark it before starting the work, and completed only after its description is satisfied — never while tests fail or work is partial.\",\n\t\"When blocked, leave the `todo` task pending and create a task for the blocker instead of faking completion.\",\n\t\"Keep the `todo` list short: list before create to avoid duplicates, work in id order, and delete obsolete tasks promptly.\",\n];\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/extensions/todo/state.ts"],"names":[],"mappings":"AAYA,OAAO,EAIN,KAAK,UAAU,EACf,KAAK,WAAW,EAEhB,KAAK,UAAU,EACf,KAAK,SAAS,EAEd,MAAM,aAAa,CAAC;AAgErB,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAE1D;AAiGD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,CAe/E;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,UAAU,CA+BnG;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,GAAG,WAAW,CAElF;AAED,MAAM,WAAW,SAAS;IACzB,QAAQ,IAAI,SAAS,CAAC;IACtB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACrC,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,CAAC;CACzC;AAQD,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAiB9D;
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/extensions/todo/state.ts"],"names":[],"mappings":"AAYA,OAAO,EAIN,KAAK,UAAU,EACf,KAAK,WAAW,EAEhB,KAAK,UAAU,EACf,KAAK,SAAS,EAEd,MAAM,aAAa,CAAC;AAgErB,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAE1D;AAiGD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,CAe/E;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,UAAU,CA+BnG;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,GAAG,WAAW,CAElF;AAED,MAAM,WAAW,SAAS;IACzB,QAAQ,IAAI,SAAS,CAAC;IACtB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACrC,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,CAAC;CACzC;AAQD,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAiB9D;AAwCD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE;IAAE,cAAc,EAAE;QAAE,SAAS,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;CAAE,GAAG,SAAS,CAoB5G"}
|
|
@@ -73,7 +73,7 @@ function applyCreate(state, params) {
|
|
|
73
73
|
if (rawItems.length > TODO_MAX_BATCH_ITEMS)
|
|
74
74
|
throw new Error(`items exceeds ${TODO_MAX_BATCH_ITEMS} tasks`);
|
|
75
75
|
if (state.items.length + rawItems.length > TODO_MAX_ITEMS) {
|
|
76
|
-
throw new Error(`todo list is full (max ${TODO_MAX_ITEMS} tasks)`);
|
|
76
|
+
throw new Error(`todo list is full (max ${TODO_MAX_ITEMS} tasks); delete completed or obsolete tasks first`);
|
|
77
77
|
}
|
|
78
78
|
if (!Number.isSafeInteger(state.nextId) || state.nextId < 1)
|
|
79
79
|
throw new Error("next id is invalid");
|
|
@@ -188,10 +188,10 @@ export function applyTodoAction(state, params) {
|
|
|
188
188
|
/** Derive the operation model for one call from the before/after states. */
|
|
189
189
|
export function buildTodoChange(params, before, after) {
|
|
190
190
|
switch (params.action) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
191
|
+
// Derived from the validated before/after states rather than params.items,
|
|
192
|
+
// which is external input and could read differently on a second access.
|
|
193
|
+
case "create":
|
|
194
|
+
return { kind: "create", ids: after.items.slice(before.items.length).map((item) => item.id) };
|
|
195
195
|
case "update": {
|
|
196
196
|
const id = params.id;
|
|
197
197
|
if (!isPositiveSafeInteger(id))
|
|
@@ -245,7 +245,15 @@ export function createTodoStore(initial) {
|
|
|
245
245
|
},
|
|
246
246
|
};
|
|
247
247
|
}
|
|
248
|
-
/**
|
|
248
|
+
/**
|
|
249
|
+
* Validate an external v2 snapshot; returns undefined when malformed.
|
|
250
|
+
*
|
|
251
|
+
* Snapshot text must already be in normalizeText() form, which makes that
|
|
252
|
+
* function's output part of the v2 persistence contract: relaxing or changing
|
|
253
|
+
* it would silently invalidate every historical snapshot, falling back to an
|
|
254
|
+
* earlier one or to the empty state with no diagnostic. Change normalizeText
|
|
255
|
+
* only together with TODO_DETAILS_SCHEMA_VERSION.
|
|
256
|
+
*/
|
|
249
257
|
function normalizeSnapshotState(value) {
|
|
250
258
|
if (!isRecord(value) || !Array.isArray(value.items) || !isPositiveSafeInteger(value.nextId))
|
|
251
259
|
return undefined;
|
|
@@ -295,22 +303,25 @@ function normalizeSnapshotState(value) {
|
|
|
295
303
|
export function replayTodosFromBranch(ctx) {
|
|
296
304
|
const branch = Array.from(ctx.sessionManager.getBranch());
|
|
297
305
|
for (let index = branch.length - 1; index >= 0; index--) {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
const message = entry.message;
|
|
302
|
-
if (!isRecord(message) || message.role !== "toolResult" || message.toolName !== TODO_TOOL_NAME)
|
|
303
|
-
continue;
|
|
304
|
-
const details = message.details;
|
|
305
|
-
if (!isRecord(details) || details.schemaVersion !== TODO_DETAILS_SCHEMA_VERSION)
|
|
306
|
-
continue;
|
|
306
|
+
// Session history is external input, so every field read stays inside the
|
|
307
|
+
// guard: a hostile entry falls through to an earlier snapshot instead of
|
|
308
|
+
// escaping to the lifecycle handler.
|
|
307
309
|
try {
|
|
310
|
+
const entry = branch[index];
|
|
311
|
+
if (!isRecord(entry) || entry.type !== "message")
|
|
312
|
+
continue;
|
|
313
|
+
const message = entry.message;
|
|
314
|
+
if (!isRecord(message) || message.role !== "toolResult" || message.toolName !== TODO_TOOL_NAME)
|
|
315
|
+
continue;
|
|
316
|
+
const details = message.details;
|
|
317
|
+
if (!isRecord(details) || details.schemaVersion !== TODO_DETAILS_SCHEMA_VERSION)
|
|
318
|
+
continue;
|
|
308
319
|
const state = normalizeSnapshotState(details.state);
|
|
309
320
|
if (state)
|
|
310
321
|
return state;
|
|
311
322
|
}
|
|
312
323
|
catch {
|
|
313
|
-
//
|
|
324
|
+
// Keep scanning for an earlier valid v2 snapshot.
|
|
314
325
|
}
|
|
315
326
|
}
|
|
316
327
|
return cloneTodoState(EMPTY_TODO_STATE);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/extensions/todo/state.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * todo/state.ts — v2 pure state core: closure-scoped store, atomic actions,\n * snapshot cloning, and branch replay. No session registry, metadata,\n * dependency graph, tombstones, filters, or legacy normalizers.\n */\nimport {\n\tTODO_MAX_BATCH_ITEMS,\n\tTODO_MAX_DESCRIPTION_LENGTH,\n\tTODO_MAX_ITEMS,\n\tTODO_MAX_SUBJECT_LENGTH,\n\tTODO_TOOL_NAME,\n} from \"./constants.ts\";\nimport {\n\tEMPTY_TODO_STATE,\n\tTODO_DETAILS_SCHEMA_VERSION,\n\ttype TodoAction,\n\ttype TodoChange,\n\ttype TodoDetails,\n\ttype TodoItem,\n\ttype TodoParams,\n\ttype TodoState,\n\ttype TodoStatus,\n} from \"./schema.ts\";\n\nconst TODO_STATUSES: ReadonlySet<TodoStatus> = new Set([\"pending\", \"in_progress\", \"completed\"]);\nconst TODO_ACTIONS: ReadonlySet<TodoAction> = new Set([\"create\", \"update\", \"list\", \"delete\"]);\n\n/** Parameters each action accepts; anything else is rejected with guidance. */\nconst ACTION_PARAMS: Record<TodoAction, ReadonlySet<string>> = {\n\tcreate: new Set([\"items\"]),\n\tupdate: new Set([\"id\", \"subject\", \"description\", \"status\"]),\n\tlist: new Set([]),\n\tdelete: new Set([\"ids\"]),\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isPositiveSafeInteger(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isSafeInteger(value) && value >= 1;\n}\n\nfunction isTodoStatus(value: unknown): value is TodoStatus {\n\treturn typeof value === \"string\" && TODO_STATUSES.has(value as TodoStatus);\n}\n\nfunction isTodoAction(value: unknown): value is TodoAction {\n\treturn typeof value === \"string\" && TODO_ACTIONS.has(value as TodoAction);\n}\n\nfunction findItem(state: TodoState, id: number): TodoItem | undefined {\n\treturn state.items.find((item) => item.id === id);\n}\n\n/** De-duplicate ids preserving first-seen input order. */\nfunction dedupeIds(ids: number[]): number[] {\n\tconst seen: number[] = [];\n\tfor (const id of ids) {\n\t\tif (!seen.includes(id)) seen.push(id);\n\t}\n\treturn seen;\n}\n\n/** Trim and collapse every internal whitespace run to a single space. */\nfunction normalizeText(value: string): string {\n\treturn value.trim().replace(/\\s+/g, \" \");\n}\n\nfunction validateNormalizedText(value: unknown, label: string, maximum: number): string {\n\tif (typeof value !== \"string\") throw new Error(`${label} must be a string`);\n\tconst normalized = normalizeText(value);\n\tif (!normalized) throw new Error(`${label} cannot be empty`);\n\tif (normalized.length > maximum) throw new Error(`${label} exceeds ${maximum} characters`);\n\treturn normalized;\n}\n\nfunction findInapplicableParam(params: TodoParams): string | undefined {\n\tconst allowed = ACTION_PARAMS[params.action];\n\tfor (const [key, value] of Object.entries(params)) {\n\t\tif (key === \"action\" || value === undefined) continue;\n\t\tif (!allowed.has(key)) return `${key} does not apply to action ${params.action}`;\n\t}\n\treturn undefined;\n}\n\n/** Snapshot clone: items are plain string/number records, so a shallow copy is safe. */\nexport function cloneTodoState(state: TodoState): TodoState {\n\treturn { items: state.items.map((item) => ({ ...item })), nextId: state.nextId };\n}\n\nfunction applyCreate(state: TodoState, params: TodoParams): TodoState {\n\tconst rawItems = params.items;\n\tif (!Array.isArray(rawItems) || rawItems.length === 0) throw new Error(\"items required for create\");\n\tif (rawItems.length > TODO_MAX_BATCH_ITEMS) throw new Error(`items exceeds ${TODO_MAX_BATCH_ITEMS} tasks`);\n\tif (state.items.length + rawItems.length > TODO_MAX_ITEMS) {\n\t\tthrow new Error(`todo list is full (max ${TODO_MAX_ITEMS} tasks)`);\n\t}\n\tif (!Number.isSafeInteger(state.nextId) || state.nextId < 1) throw new Error(\"next id is invalid\");\n\tif (state.nextId > Number.MAX_SAFE_INTEGER - rawItems.length) throw new Error(\"next id is exhausted\");\n\n\tconst sources: Array<{ subject: string; description: string }> = [];\n\tfor (let index = 0; index < rawItems.length; index++) {\n\t\tconst raw = rawItems[index];\n\t\tif (!isRecord(raw)) throw new Error(`items[${index}] must be an object`);\n\t\tfor (const key of Object.keys(raw)) {\n\t\t\tif (key !== \"subject\" && key !== \"description\") {\n\t\t\t\tthrow new Error(`items[${index}].${key} does not apply to action create`);\n\t\t\t}\n\t\t}\n\t\tsources.push({\n\t\t\tsubject: validateNormalizedText(raw.subject, `items[${index}].subject`, TODO_MAX_SUBJECT_LENGTH),\n\t\t\tdescription: validateNormalizedText(\n\t\t\t\traw.description,\n\t\t\t\t`items[${index}].description`,\n\t\t\t\tTODO_MAX_DESCRIPTION_LENGTH,\n\t\t\t),\n\t\t});\n\t}\n\n\t// Atomic: everything above is validated before the new state is built.\n\tconst created = sources.map((source, index) => ({\n\t\tid: state.nextId + index,\n\t\tsubject: source.subject,\n\t\tdescription: source.description,\n\t\tstatus: \"pending\" as const,\n\t}));\n\treturn { items: [...state.items, ...created], nextId: state.nextId + created.length };\n}\n\nfunction applyUpdate(state: TodoState, params: TodoParams): TodoState {\n\tconst id = params.id;\n\tif (!isPositiveSafeInteger(id)) throw new Error(\"id required for update\");\n\tconst index = state.items.findIndex((item) => item.id === id);\n\tif (index === -1) throw new Error(`#${id} not found`);\n\tif (params.subject === undefined && params.description === undefined && params.status === undefined) {\n\t\tthrow new Error(\"update requires at least one of subject, description, or status\");\n\t}\n\tconst subject =\n\t\tparams.subject === undefined\n\t\t\t? undefined\n\t\t\t: validateNormalizedText(params.subject, \"subject\", TODO_MAX_SUBJECT_LENGTH);\n\tconst description =\n\t\tparams.description === undefined\n\t\t\t? undefined\n\t\t\t: validateNormalizedText(params.description, \"description\", TODO_MAX_DESCRIPTION_LENGTH);\n\tif (params.status !== undefined && !isTodoStatus(params.status)) throw new Error(\"status is invalid\");\n\n\tconst current = state.items[index];\n\tconst updated: TodoItem = {\n\t\tid: current.id,\n\t\tsubject: subject ?? current.subject,\n\t\tdescription: description ?? current.description,\n\t\tstatus: params.status ?? current.status,\n\t};\n\n\t// Exactly one in_progress: setting one demotes every other active task.\n\tconst items = state.items.map((item, itemIndex) => {\n\t\tif (itemIndex === index) return updated;\n\t\tif (updated.status === \"in_progress\" && item.status === \"in_progress\") {\n\t\t\treturn { ...item, status: \"pending\" as const };\n\t\t}\n\t\treturn item;\n\t});\n\treturn { items, nextId: state.nextId };\n}\n\nfunction applyDelete(state: TodoState, params: TodoParams): TodoState {\n\tconst rawIds = params.ids;\n\tif (!Array.isArray(rawIds) || rawIds.length === 0) throw new Error(\"ids required for delete\");\n\tif (rawIds.length > TODO_MAX_BATCH_ITEMS) throw new Error(`ids exceeds ${TODO_MAX_BATCH_ITEMS} ids`);\n\tconst ids: number[] = [];\n\tfor (const raw of rawIds) {\n\t\tif (!isPositiveSafeInteger(raw)) throw new Error(\"ids must contain positive integer ids\");\n\t\tids.push(raw);\n\t}\n\tconst idsToRemove = dedupeIds(ids);\n\t// Atomic: every id must exist before anything is removed.\n\tconst byId = new Map(state.items.map((item) => [item.id, item]));\n\tfor (const candidate of idsToRemove) {\n\t\tif (!byId.has(candidate)) throw new Error(`#${candidate} not found`);\n\t}\n\tconst remove = new Set(idsToRemove);\n\treturn { items: state.items.filter((item) => !remove.has(item.id)), nextId: state.nextId };\n}\n\n/**\n * Pure action application: validates every runtime input and inapplicable\n * parameter (tool args can be tampered after schema validation), throws on\n * any invalid call, and never mutates the input state.\n */\nexport function applyTodoAction(state: TodoState, params: TodoParams): TodoState {\n\tif (!isRecord(params)) throw new Error(\"todo params must be an object\");\n\tif (!isTodoAction(params.action)) throw new Error(`unknown todo action: ${String(params.action)}`);\n\tconst inapplicable = findInapplicableParam(params);\n\tif (inapplicable) throw new Error(inapplicable);\n\tswitch (params.action) {\n\t\tcase \"create\":\n\t\t\treturn applyCreate(state, params);\n\t\tcase \"update\":\n\t\t\treturn applyUpdate(state, params);\n\t\tcase \"list\":\n\t\t\treturn cloneTodoState(state);\n\t\tcase \"delete\":\n\t\t\treturn applyDelete(state, params);\n\t}\n}\n\n/** Derive the operation model for one call from the before/after states. */\nexport function buildTodoChange(params: TodoParams, before: TodoState, after: TodoState): TodoChange {\n\tswitch (params.action) {\n\t\tcase \"create\": {\n\t\t\tconst count = Array.isArray(params.items) ? params.items.length : 0;\n\t\t\treturn { kind: \"create\", ids: after.items.slice(after.items.length - count).map((item) => item.id) };\n\t\t}\n\t\tcase \"update\": {\n\t\t\tconst id = params.id;\n\t\t\tif (!isPositiveSafeInteger(id)) throw new Error(\"id required for update\");\n\t\t\tconst demotedId = before.items.find(\n\t\t\t\t(item) => item.id !== id && item.status === \"in_progress\" && findItem(after, item.id)?.status === \"pending\",\n\t\t\t)?.id;\n\t\t\treturn {\n\t\t\t\tkind: \"update\",\n\t\t\t\tid,\n\t\t\t\tfrom: findItem(before, id)?.status ?? \"pending\",\n\t\t\t\tto: findItem(after, id)?.status ?? \"pending\",\n\t\t\t\t...(demotedId !== undefined ? { demotedId } : {}),\n\t\t\t};\n\t\t}\n\t\tcase \"list\":\n\t\t\treturn { kind: \"list\" };\n\t\tcase \"delete\": {\n\t\t\tconst ids = Array.isArray(params.ids) ? dedupeIds(params.ids) : [];\n\t\t\tconst removed = ids\n\t\t\t\t.map((id) => findItem(before, id))\n\t\t\t\t.filter((item): item is TodoItem => item !== undefined)\n\t\t\t\t.map((item) => ({ id: item.id, subject: item.subject }));\n\t\t\treturn { kind: \"delete\", removed };\n\t\t}\n\t}\n}\n\nexport function buildTodoDetails(change: TodoChange, state: TodoState): TodoDetails {\n\treturn { schemaVersion: TODO_DETAILS_SCHEMA_VERSION, change, state: cloneTodoState(state) };\n}\n\nexport interface TodoStore {\n\tgetState(): TodoState;\n\treplaceState(state: TodoState): void;\n\texecute(params: TodoParams): TodoDetails;\n}\n\nfunction requireValidState(value: unknown): TodoState {\n\tconst state = normalizeSnapshotState(value);\n\tif (!state) throw new Error(\"todo state is invalid\");\n\treturn state;\n}\n\n/** Closure-scoped store: one list per store, no module-global session state. */\nexport function createTodoStore(initial?: TodoState): TodoStore {\n\tlet state = requireValidState(initial ?? EMPTY_TODO_STATE);\n\treturn {\n\t\tgetState() {\n\t\t\treturn cloneTodoState(state);\n\t\t},\n\t\treplaceState(next: TodoState) {\n\t\t\tstate = requireValidState(next);\n\t\t},\n\t\texecute(params: TodoParams): TodoDetails {\n\t\t\tconst before = state;\n\t\t\tconst after = applyTodoAction(before, params);\n\t\t\tconst details = buildTodoDetails(buildTodoChange(params, before, after), after);\n\t\t\tstate = after;\n\t\t\treturn details;\n\t\t},\n\t};\n}\n\n/** Validate an external v2 snapshot; returns undefined when malformed. */\nfunction normalizeSnapshotState(value: unknown): TodoState | undefined {\n\tif (!isRecord(value) || !Array.isArray(value.items) || !isPositiveSafeInteger(value.nextId)) return undefined;\n\tif (value.items.length > TODO_MAX_ITEMS) return undefined;\n\tconst items: TodoItem[] = [];\n\tconst ids = new Set<number>();\n\tlet maxId = 0;\n\tlet activeCount = 0;\n\tfor (const rawItem of value.items) {\n\t\tif (!isRecord(rawItem)) return undefined;\n\t\tconst id = rawItem.id;\n\t\tif (!isPositiveSafeInteger(id) || ids.has(id)) return undefined;\n\t\tconst subject = rawItem.subject;\n\t\tconst description = rawItem.description;\n\t\tconst status = rawItem.status;\n\t\tif (typeof subject !== \"string\" || typeof description !== \"string\") return undefined;\n\t\tif (subject !== normalizeText(subject) || description !== normalizeText(description)) return undefined;\n\t\tif (!subject || subject.length > TODO_MAX_SUBJECT_LENGTH) return undefined;\n\t\tif (!description || description.length > TODO_MAX_DESCRIPTION_LENGTH) return undefined;\n\t\tif (!isTodoStatus(status)) return undefined;\n\t\tids.add(id);\n\t\tif (id > maxId) maxId = id;\n\t\tif (status === \"in_progress\") activeCount++;\n\t\titems.push({ id, subject, description, status });\n\t}\n\tif (activeCount > 1) return undefined;\n\tif (value.nextId <= maxId) return undefined;\n\treturn { items, nextId: value.nextId };\n}\n\n/**\n * Replay the newest valid v2 todo snapshot from a branch, scanning tail to\n * head so a malformed latest snapshot falls back to an earlier valid one.\n * v1 details are ignored, and the `change` field is not validated.\n */\nexport function replayTodosFromBranch(ctx: { sessionManager: { getBranch(): Iterable<unknown> } }): TodoState {\n\tconst branch = Array.from(ctx.sessionManager.getBranch());\n\tfor (let index = branch.length - 1; index >= 0; index--) {\n\t\tconst entry = branch[index];\n\t\tif (!isRecord(entry) || entry.type !== \"message\") continue;\n\t\tconst message = entry.message;\n\t\tif (!isRecord(message) || message.role !== \"toolResult\" || message.toolName !== TODO_TOOL_NAME) continue;\n\t\tconst details = message.details;\n\t\tif (!isRecord(details) || details.schemaVersion !== TODO_DETAILS_SCHEMA_VERSION) continue;\n\t\ttry {\n\t\t\tconst state = normalizeSnapshotState(details.state);\n\t\t\tif (state) return state;\n\t\t} catch {\n\t\t\t// Session history is external input; keep scanning for an earlier valid v2.\n\t\t}\n\t}\n\treturn cloneTodoState(EMPTY_TODO_STATE);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/extensions/todo/state.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * todo/state.ts — v2 pure state core: closure-scoped store, atomic actions,\n * snapshot cloning, and branch replay. No session registry, metadata,\n * dependency graph, tombstones, filters, or legacy normalizers.\n */\nimport {\n\tTODO_MAX_BATCH_ITEMS,\n\tTODO_MAX_DESCRIPTION_LENGTH,\n\tTODO_MAX_ITEMS,\n\tTODO_MAX_SUBJECT_LENGTH,\n\tTODO_TOOL_NAME,\n} from \"./constants.ts\";\nimport {\n\tEMPTY_TODO_STATE,\n\tTODO_DETAILS_SCHEMA_VERSION,\n\ttype TodoAction,\n\ttype TodoChange,\n\ttype TodoDetails,\n\ttype TodoItem,\n\ttype TodoParams,\n\ttype TodoState,\n\ttype TodoStatus,\n} from \"./schema.ts\";\n\nconst TODO_STATUSES: ReadonlySet<TodoStatus> = new Set([\"pending\", \"in_progress\", \"completed\"]);\nconst TODO_ACTIONS: ReadonlySet<TodoAction> = new Set([\"create\", \"update\", \"list\", \"delete\"]);\n\n/** Parameters each action accepts; anything else is rejected with guidance. */\nconst ACTION_PARAMS: Record<TodoAction, ReadonlySet<string>> = {\n\tcreate: new Set([\"items\"]),\n\tupdate: new Set([\"id\", \"subject\", \"description\", \"status\"]),\n\tlist: new Set([]),\n\tdelete: new Set([\"ids\"]),\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isPositiveSafeInteger(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isSafeInteger(value) && value >= 1;\n}\n\nfunction isTodoStatus(value: unknown): value is TodoStatus {\n\treturn typeof value === \"string\" && TODO_STATUSES.has(value as TodoStatus);\n}\n\nfunction isTodoAction(value: unknown): value is TodoAction {\n\treturn typeof value === \"string\" && TODO_ACTIONS.has(value as TodoAction);\n}\n\nfunction findItem(state: TodoState, id: number): TodoItem | undefined {\n\treturn state.items.find((item) => item.id === id);\n}\n\n/** De-duplicate ids preserving first-seen input order. */\nfunction dedupeIds(ids: number[]): number[] {\n\tconst seen: number[] = [];\n\tfor (const id of ids) {\n\t\tif (!seen.includes(id)) seen.push(id);\n\t}\n\treturn seen;\n}\n\n/** Trim and collapse every internal whitespace run to a single space. */\nfunction normalizeText(value: string): string {\n\treturn value.trim().replace(/\\s+/g, \" \");\n}\n\nfunction validateNormalizedText(value: unknown, label: string, maximum: number): string {\n\tif (typeof value !== \"string\") throw new Error(`${label} must be a string`);\n\tconst normalized = normalizeText(value);\n\tif (!normalized) throw new Error(`${label} cannot be empty`);\n\tif (normalized.length > maximum) throw new Error(`${label} exceeds ${maximum} characters`);\n\treturn normalized;\n}\n\nfunction findInapplicableParam(params: TodoParams): string | undefined {\n\tconst allowed = ACTION_PARAMS[params.action];\n\tfor (const [key, value] of Object.entries(params)) {\n\t\tif (key === \"action\" || value === undefined) continue;\n\t\tif (!allowed.has(key)) return `${key} does not apply to action ${params.action}`;\n\t}\n\treturn undefined;\n}\n\n/** Snapshot clone: items are plain string/number records, so a shallow copy is safe. */\nexport function cloneTodoState(state: TodoState): TodoState {\n\treturn { items: state.items.map((item) => ({ ...item })), nextId: state.nextId };\n}\n\nfunction applyCreate(state: TodoState, params: TodoParams): TodoState {\n\tconst rawItems = params.items;\n\tif (!Array.isArray(rawItems) || rawItems.length === 0) throw new Error(\"items required for create\");\n\tif (rawItems.length > TODO_MAX_BATCH_ITEMS) throw new Error(`items exceeds ${TODO_MAX_BATCH_ITEMS} tasks`);\n\tif (state.items.length + rawItems.length > TODO_MAX_ITEMS) {\n\t\tthrow new Error(`todo list is full (max ${TODO_MAX_ITEMS} tasks); delete completed or obsolete tasks first`);\n\t}\n\tif (!Number.isSafeInteger(state.nextId) || state.nextId < 1) throw new Error(\"next id is invalid\");\n\tif (state.nextId > Number.MAX_SAFE_INTEGER - rawItems.length) throw new Error(\"next id is exhausted\");\n\n\tconst sources: Array<{ subject: string; description: string }> = [];\n\tfor (let index = 0; index < rawItems.length; index++) {\n\t\tconst raw = rawItems[index];\n\t\tif (!isRecord(raw)) throw new Error(`items[${index}] must be an object`);\n\t\tfor (const key of Object.keys(raw)) {\n\t\t\tif (key !== \"subject\" && key !== \"description\") {\n\t\t\t\tthrow new Error(`items[${index}].${key} does not apply to action create`);\n\t\t\t}\n\t\t}\n\t\tsources.push({\n\t\t\tsubject: validateNormalizedText(raw.subject, `items[${index}].subject`, TODO_MAX_SUBJECT_LENGTH),\n\t\t\tdescription: validateNormalizedText(\n\t\t\t\traw.description,\n\t\t\t\t`items[${index}].description`,\n\t\t\t\tTODO_MAX_DESCRIPTION_LENGTH,\n\t\t\t),\n\t\t});\n\t}\n\n\t// Atomic: everything above is validated before the new state is built.\n\tconst created = sources.map((source, index) => ({\n\t\tid: state.nextId + index,\n\t\tsubject: source.subject,\n\t\tdescription: source.description,\n\t\tstatus: \"pending\" as const,\n\t}));\n\treturn { items: [...state.items, ...created], nextId: state.nextId + created.length };\n}\n\nfunction applyUpdate(state: TodoState, params: TodoParams): TodoState {\n\tconst id = params.id;\n\tif (!isPositiveSafeInteger(id)) throw new Error(\"id required for update\");\n\tconst index = state.items.findIndex((item) => item.id === id);\n\tif (index === -1) throw new Error(`#${id} not found`);\n\tif (params.subject === undefined && params.description === undefined && params.status === undefined) {\n\t\tthrow new Error(\"update requires at least one of subject, description, or status\");\n\t}\n\tconst subject =\n\t\tparams.subject === undefined\n\t\t\t? undefined\n\t\t\t: validateNormalizedText(params.subject, \"subject\", TODO_MAX_SUBJECT_LENGTH);\n\tconst description =\n\t\tparams.description === undefined\n\t\t\t? undefined\n\t\t\t: validateNormalizedText(params.description, \"description\", TODO_MAX_DESCRIPTION_LENGTH);\n\tif (params.status !== undefined && !isTodoStatus(params.status)) throw new Error(\"status is invalid\");\n\n\tconst current = state.items[index];\n\tconst updated: TodoItem = {\n\t\tid: current.id,\n\t\tsubject: subject ?? current.subject,\n\t\tdescription: description ?? current.description,\n\t\tstatus: params.status ?? current.status,\n\t};\n\n\t// Exactly one in_progress: setting one demotes every other active task.\n\tconst items = state.items.map((item, itemIndex) => {\n\t\tif (itemIndex === index) return updated;\n\t\tif (updated.status === \"in_progress\" && item.status === \"in_progress\") {\n\t\t\treturn { ...item, status: \"pending\" as const };\n\t\t}\n\t\treturn item;\n\t});\n\treturn { items, nextId: state.nextId };\n}\n\nfunction applyDelete(state: TodoState, params: TodoParams): TodoState {\n\tconst rawIds = params.ids;\n\tif (!Array.isArray(rawIds) || rawIds.length === 0) throw new Error(\"ids required for delete\");\n\tif (rawIds.length > TODO_MAX_BATCH_ITEMS) throw new Error(`ids exceeds ${TODO_MAX_BATCH_ITEMS} ids`);\n\tconst ids: number[] = [];\n\tfor (const raw of rawIds) {\n\t\tif (!isPositiveSafeInteger(raw)) throw new Error(\"ids must contain positive integer ids\");\n\t\tids.push(raw);\n\t}\n\tconst idsToRemove = dedupeIds(ids);\n\t// Atomic: every id must exist before anything is removed.\n\tconst byId = new Map(state.items.map((item) => [item.id, item]));\n\tfor (const candidate of idsToRemove) {\n\t\tif (!byId.has(candidate)) throw new Error(`#${candidate} not found`);\n\t}\n\tconst remove = new Set(idsToRemove);\n\treturn { items: state.items.filter((item) => !remove.has(item.id)), nextId: state.nextId };\n}\n\n/**\n * Pure action application: validates every runtime input and inapplicable\n * parameter (tool args can be tampered after schema validation), throws on\n * any invalid call, and never mutates the input state.\n */\nexport function applyTodoAction(state: TodoState, params: TodoParams): TodoState {\n\tif (!isRecord(params)) throw new Error(\"todo params must be an object\");\n\tif (!isTodoAction(params.action)) throw new Error(`unknown todo action: ${String(params.action)}`);\n\tconst inapplicable = findInapplicableParam(params);\n\tif (inapplicable) throw new Error(inapplicable);\n\tswitch (params.action) {\n\t\tcase \"create\":\n\t\t\treturn applyCreate(state, params);\n\t\tcase \"update\":\n\t\t\treturn applyUpdate(state, params);\n\t\tcase \"list\":\n\t\t\treturn cloneTodoState(state);\n\t\tcase \"delete\":\n\t\t\treturn applyDelete(state, params);\n\t}\n}\n\n/** Derive the operation model for one call from the before/after states. */\nexport function buildTodoChange(params: TodoParams, before: TodoState, after: TodoState): TodoChange {\n\tswitch (params.action) {\n\t\t// Derived from the validated before/after states rather than params.items,\n\t\t// which is external input and could read differently on a second access.\n\t\tcase \"create\":\n\t\t\treturn { kind: \"create\", ids: after.items.slice(before.items.length).map((item) => item.id) };\n\t\tcase \"update\": {\n\t\t\tconst id = params.id;\n\t\t\tif (!isPositiveSafeInteger(id)) throw new Error(\"id required for update\");\n\t\t\tconst demotedId = before.items.find(\n\t\t\t\t(item) => item.id !== id && item.status === \"in_progress\" && findItem(after, item.id)?.status === \"pending\",\n\t\t\t)?.id;\n\t\t\treturn {\n\t\t\t\tkind: \"update\",\n\t\t\t\tid,\n\t\t\t\tfrom: findItem(before, id)?.status ?? \"pending\",\n\t\t\t\tto: findItem(after, id)?.status ?? \"pending\",\n\t\t\t\t...(demotedId !== undefined ? { demotedId } : {}),\n\t\t\t};\n\t\t}\n\t\tcase \"list\":\n\t\t\treturn { kind: \"list\" };\n\t\tcase \"delete\": {\n\t\t\tconst ids = Array.isArray(params.ids) ? dedupeIds(params.ids) : [];\n\t\t\tconst removed = ids\n\t\t\t\t.map((id) => findItem(before, id))\n\t\t\t\t.filter((item): item is TodoItem => item !== undefined)\n\t\t\t\t.map((item) => ({ id: item.id, subject: item.subject }));\n\t\t\treturn { kind: \"delete\", removed };\n\t\t}\n\t}\n}\n\nexport function buildTodoDetails(change: TodoChange, state: TodoState): TodoDetails {\n\treturn { schemaVersion: TODO_DETAILS_SCHEMA_VERSION, change, state: cloneTodoState(state) };\n}\n\nexport interface TodoStore {\n\tgetState(): TodoState;\n\treplaceState(state: TodoState): void;\n\texecute(params: TodoParams): TodoDetails;\n}\n\nfunction requireValidState(value: unknown): TodoState {\n\tconst state = normalizeSnapshotState(value);\n\tif (!state) throw new Error(\"todo state is invalid\");\n\treturn state;\n}\n\n/** Closure-scoped store: one list per store, no module-global session state. */\nexport function createTodoStore(initial?: TodoState): TodoStore {\n\tlet state = requireValidState(initial ?? EMPTY_TODO_STATE);\n\treturn {\n\t\tgetState() {\n\t\t\treturn cloneTodoState(state);\n\t\t},\n\t\treplaceState(next: TodoState) {\n\t\t\tstate = requireValidState(next);\n\t\t},\n\t\texecute(params: TodoParams): TodoDetails {\n\t\t\tconst before = state;\n\t\t\tconst after = applyTodoAction(before, params);\n\t\t\tconst details = buildTodoDetails(buildTodoChange(params, before, after), after);\n\t\t\tstate = after;\n\t\t\treturn details;\n\t\t},\n\t};\n}\n\n/**\n * Validate an external v2 snapshot; returns undefined when malformed.\n *\n * Snapshot text must already be in normalizeText() form, which makes that\n * function's output part of the v2 persistence contract: relaxing or changing\n * it would silently invalidate every historical snapshot, falling back to an\n * earlier one or to the empty state with no diagnostic. Change normalizeText\n * only together with TODO_DETAILS_SCHEMA_VERSION.\n */\nfunction normalizeSnapshotState(value: unknown): TodoState | undefined {\n\tif (!isRecord(value) || !Array.isArray(value.items) || !isPositiveSafeInteger(value.nextId)) return undefined;\n\tif (value.items.length > TODO_MAX_ITEMS) return undefined;\n\tconst items: TodoItem[] = [];\n\tconst ids = new Set<number>();\n\tlet maxId = 0;\n\tlet activeCount = 0;\n\tfor (const rawItem of value.items) {\n\t\tif (!isRecord(rawItem)) return undefined;\n\t\tconst id = rawItem.id;\n\t\tif (!isPositiveSafeInteger(id) || ids.has(id)) return undefined;\n\t\tconst subject = rawItem.subject;\n\t\tconst description = rawItem.description;\n\t\tconst status = rawItem.status;\n\t\tif (typeof subject !== \"string\" || typeof description !== \"string\") return undefined;\n\t\tif (subject !== normalizeText(subject) || description !== normalizeText(description)) return undefined;\n\t\tif (!subject || subject.length > TODO_MAX_SUBJECT_LENGTH) return undefined;\n\t\tif (!description || description.length > TODO_MAX_DESCRIPTION_LENGTH) return undefined;\n\t\tif (!isTodoStatus(status)) return undefined;\n\t\tids.add(id);\n\t\tif (id > maxId) maxId = id;\n\t\tif (status === \"in_progress\") activeCount++;\n\t\titems.push({ id, subject, description, status });\n\t}\n\tif (activeCount > 1) return undefined;\n\tif (value.nextId <= maxId) return undefined;\n\treturn { items, nextId: value.nextId };\n}\n\n/**\n * Replay the newest valid v2 todo snapshot from a branch, scanning tail to\n * head so a malformed latest snapshot falls back to an earlier valid one.\n * v1 details are ignored, and the `change` field is not validated.\n */\nexport function replayTodosFromBranch(ctx: { sessionManager: { getBranch(): Iterable<unknown> } }): TodoState {\n\tconst branch = Array.from(ctx.sessionManager.getBranch());\n\tfor (let index = branch.length - 1; index >= 0; index--) {\n\t\t// Session history is external input, so every field read stays inside the\n\t\t// guard: a hostile entry falls through to an earlier snapshot instead of\n\t\t// escaping to the lifecycle handler.\n\t\ttry {\n\t\t\tconst entry = branch[index];\n\t\t\tif (!isRecord(entry) || entry.type !== \"message\") continue;\n\t\t\tconst message = entry.message;\n\t\t\tif (!isRecord(message) || message.role !== \"toolResult\" || message.toolName !== TODO_TOOL_NAME) continue;\n\t\t\tconst details = message.details;\n\t\t\tif (!isRecord(details) || details.schemaVersion !== TODO_DETAILS_SCHEMA_VERSION) continue;\n\t\t\tconst state = normalizeSnapshotState(details.state);\n\t\t\tif (state) return state;\n\t\t} catch {\n\t\t\t// Keep scanning for an earlier valid v2 snapshot.\n\t\t}\n\t}\n\treturn cloneTodoState(EMPTY_TODO_STATE);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/extensions/todo/view.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAC;AAOpE,OAAO,EAEN,KAAK,UAAU,EAEf,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,UAAU,EACf,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAIlD,CAAC;AAmBF,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAEtD;AAgCD,8HAA8H;AAC9H,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAkExF;AAID,iFAAiF;AACjF,iBAAS,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAYhD;AAED,yFAAyF;AACzF,eAAO,MAAM,iBAAiB,uBAAiB,CAAC;AAEhD,uFAAuF;AACvF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAyB9E;AASD,KAAK,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/extensions/todo/view.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAC;AAOpE,OAAO,EAEN,KAAK,UAAU,EAEf,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,UAAU,EACf,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAIlD,CAAC;AAmBF,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAEtD;AAgCD,8HAA8H;AAC9H,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAkExF;AAID,iFAAiF;AACjF,iBAAS,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAYhD;AAED,yFAAyF;AACzF,eAAO,MAAM,iBAAiB,uBAAiB,CAAC;AAEhD,uFAAuF;AACvF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAyB9E;AASD,KAAK,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;AAsM/D,iFAAiF;AACjF,wBAAgB,cAAc,CAC7B,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,OAAO,EACjB,MAAM,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,GAC/B,MAAM,CAGR;AAyGD,MAAM,WAAW,sBAAsB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;CAClC;AAED,4EAA4E;AAC5E,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,sBAAsB,GAC7B,MAAM,CAwBR"}
|
|
@@ -276,9 +276,11 @@ function descriptionPreview(value) {
|
|
|
276
276
|
}
|
|
277
277
|
/** At most two subjects, each truncated to the preview width, plus `+N more`. */
|
|
278
278
|
function formatSubjectPreview(subjects, total) {
|
|
279
|
+
// Filter before slicing so an empty subject (streaming args) does not consume
|
|
280
|
+
// a preview slot.
|
|
279
281
|
const shown = subjects
|
|
280
|
-
.slice(0, CALL_SUBJECT_PREVIEW_COUNT)
|
|
281
282
|
.filter(Boolean)
|
|
283
|
+
.slice(0, CALL_SUBJECT_PREVIEW_COUNT)
|
|
282
284
|
.map((subject) => truncateToWidth(subject, CALL_SUBJECT_PREVIEW_WIDTH, "…"));
|
|
283
285
|
if (!shown.length)
|
|
284
286
|
return "";
|
|
@@ -307,6 +309,13 @@ function createResultIds(result, count) {
|
|
|
307
309
|
const ids = readIds(safeValue(details.change, "ids"), true);
|
|
308
310
|
return ids?.length === count ? ids : undefined;
|
|
309
311
|
}
|
|
312
|
+
/** Removed entries for an expanded delete; absent until a v2 delete result arrives. */
|
|
313
|
+
function deleteResultRemoved(result) {
|
|
314
|
+
const details = todoDetails(result?.details);
|
|
315
|
+
if (!details || safeString(safeValue(details.change, "kind")) !== "delete")
|
|
316
|
+
return undefined;
|
|
317
|
+
return removedEntries(safeValue(details.change, "removed"));
|
|
318
|
+
}
|
|
310
319
|
/** Headline plus the parameters the result never echoes as detail lines. */
|
|
311
320
|
function formatCallParts(args, theme, result) {
|
|
312
321
|
const action = clipText(args?.action, TODO_MAX_SUBJECT_LENGTH);
|
|
@@ -348,10 +357,12 @@ function formatCallParts(args, theme, result) {
|
|
|
348
357
|
}
|
|
349
358
|
else if (verb === "delete") {
|
|
350
359
|
const ids = readIds(args?.ids, false) ?? [];
|
|
351
|
-
if (ids.length)
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
360
|
+
if (ids.length)
|
|
361
|
+
headline.push(theme.fg("accent", ids.map((id) => `#${id}`).join(", ")));
|
|
362
|
+
// The headline already carries the ids, so details only earn their line
|
|
363
|
+
// once the result names what was actually removed.
|
|
364
|
+
for (const entry of deleteResultRemoved(result) ?? []) {
|
|
365
|
+
details.push(`${theme.fg("accent", `#${entry.id}`)} ${theme.fg("text", entry.subject)}`);
|
|
355
366
|
}
|
|
356
367
|
}
|
|
357
368
|
return { headline: headline.join(" "), details };
|