@astralyn/pi 0.87.4 → 0.87.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/CHANGELOG.md +12 -0
- package/dist/bundle/chunks/{chunk-ANT4TSUE.js → chunk-APQ4ACY3.js} +1 -1
- package/dist/bundle/chunks/{chunk-CUDKRZ2V.js → chunk-EWLAVDVN.js} +4 -4
- package/dist/bundle/chunks/{virtual-modules-Y2YZRMU3.js → virtual-modules-W3OGMIX7.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +5 -2
- package/dist/core/tools/tool-definition-wrapper.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 +2 -2
- package/dist/extensions/todo/constants.js.map +1 -1
- package/dist/extensions/todo/schema.d.ts +1 -0
- package/dist/extensions/todo/schema.d.ts.map +1 -1
- package/dist/extensions/todo/schema.js +1 -1
- package/dist/extensions/todo/schema.js.map +1 -1
- package/dist/extensions/todo/state.d.ts.map +1 -1
- package/dist/extensions/todo/state.js +15 -5
- package/dist/extensions/todo/state.js.map +1 -1
- package/dist/extensions/todo/view.d.ts +1 -1
- package/dist/extensions/todo/view.d.ts.map +1 -1
- package/dist/extensions/todo/view.js +4 -24
- package/dist/extensions/todo/view.js.map +1 -1
- package/docs/bundled/extensions/todo.md +5 -5
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-definition-wrapper.js","sourceRoot":"","sources":["../../../src/core/tools/tool-definition-wrapper.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport { type JsonObject, validateToolArguments } from \"@earendil-works/pi-ai\";\nimport type { Static, TSchema } from \"typebox\";\nimport type { ExtensionContext, ToolDefinition } from \"../extensions/types.ts\";\nimport { truncateHead } from \"./truncate.ts\";\n\ntype PresentableAgentTool<TParams extends TSchema = TSchema, TDetails = unknown> = AgentTool<TParams, TDetails> & {\n\ttoolGroup?: string;\n};\n\nconst RECEIVED_ARGUMENTS_MARKER = \"\\n\\nReceived arguments:\\n\";\nconst HINT_MARKER = \"\\n\\nHint: \";\nconst RECEIVED_ARGUMENTS_MAX_BYTES = 2 * 1024;\nconst RECEIVED_ARGUMENTS_MAX_LINES = 40;\nconst FIELD_HINTS_MAX = 10;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/**\n * Walk schema and arguments in sync to name, at every object with\n * `additionalProperties: false`, the non-null fields the schema does not\n * declare, and at every object, the required fields the arguments lack. The\n * validator's own report says where validation failed; these hints say what\n * the legal shape is. Union variants (`anyOf`, e.g. a nullable field) are\n * walked through so nested shapes still get hints. Paths use the validator's\n * dotted style\n * (`tasks[0].prompt`). Non-null unknown fields are reported rather than\n * silently dropped: a field like `prompt_extra` may carry briefing content\n * the caller intended to send.\n */\nfunction collectFieldHints(schema: unknown, args: unknown): string[] {\n\tconst hints: string[] = [];\n\tconst visit = (node: unknown, value: unknown, path: string): void => {\n\t\tif (hints.length >= FIELD_HINTS_MAX || !isRecord(node)) return;\n\t\tif (Array.isArray(node.anyOf)) {\n\t\t\tfor (const variant of node.anyOf) visit(variant, value, path);\n\t\t\treturn;\n\t\t}\n\t\tif (node.type === \"array\" && Array.isArray(value)) {\n\t\t\tfor (let index = 0; index < value.length; index++) {\n\t\t\t\tvisit(node.items, value[index], `${path}[${index}]`);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (node.type !== \"object\" || !isRecord(value)) return;\n\t\tconst properties = isRecord(node.properties) ? node.properties : {};\n\t\tconst fields = Object.keys(properties);\n\t\tconst where = path || \"root\";\n\t\tif (node.additionalProperties === false) {\n\t\t\tfor (const [key, entry] of Object.entries(value)) {\n\t\t\t\tif (entry !== null && !(key in properties) && hints.length < FIELD_HINTS_MAX) {\n\t\t\t\t\tconst subject = path ? `${path}.${key}` : key;\n\t\t\t\t\thints.push(`${subject} is not a field; fields at ${where}: ${fields.join(\", \")}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (Array.isArray(node.required)) {\n\t\t\tfor (const key of node.required) {\n\t\t\t\tif (typeof key === \"string\" && value[key] === undefined && hints.length < FIELD_HINTS_MAX) {\n\t\t\t\t\tconst subject = path ? `${path}.${key}` : key;\n\t\t\t\t\thints.push(`${subject} is required; fields at ${where}: ${fields.join(\", \")}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const key of fields) {\n\t\t\tif (value[key] !== undefined && value[key] !== null) {\n\t\t\t\tvisit(properties[key], value[key], path ? `${path}.${key}` : key);\n\t\t\t}\n\t\t}\n\t};\n\tvisit(schema, args, \"\");\n\treturn hints;\n}\n\n/**\n * Rebuild pi-ai's validation error so a model can self-correct: the legal\n * fields are named next to each offending one, and the echoed arguments are\n * bounded (a 50KB subagent prompt must not be reflected whole into context).\n * The `Validation failed for tool \"<name>\":` prefix stays intact — the\n * question tool's renderer parses it.\n */\nfunction enrichValidationError(error: unknown, parameters: TSchema, args: unknown): Error {\n\tconst message = error instanceof Error ? error.message : String(error);\n\t// A definition synthesized from an already-wrapped tool enriches on the\n\t// inside; do not stack a second layer of hints on the same failure.\n\tif (message.includes(HINT_MARKER)) return error instanceof Error ? error : new Error(message);\n\tconst hints = collectFieldHints(parameters, args);\n\tconst markerIndex = message.indexOf(RECEIVED_ARGUMENTS_MARKER);\n\tconst head = markerIndex === -1 ? message : message.slice(0, markerIndex);\n\tconst received = markerIndex === -1 ? \"\" : message.slice(markerIndex + RECEIVED_ARGUMENTS_MARKER.length);\n\tlet enriched = hints.length > 0 ? `${head}\\n\\nHint: ${hints.join(\"\\nHint: \")}` : head;\n\tif (markerIndex !== -1) {\n\t\tconst bounded = truncateHead(received, {\n\t\t\tmaxBytes: RECEIVED_ARGUMENTS_MAX_BYTES,\n\t\t\tmaxLines: RECEIVED_ARGUMENTS_MAX_LINES,\n\t\t});\n\t\tenriched += `${RECEIVED_ARGUMENTS_MARKER}${bounded.content}`;\n\t\tif (bounded.truncated) enriched += \"\\n… (arguments truncated)\";\n\t}\n\treturn new Error(enriched);\n}\n\n/**\n * Pre-validate prepared arguments so a validation failure reaches the model\n * with field-level hints. Valid arguments pass through untouched and are\n * validated again by the agent loop as before.\n */\nfunction wrapPrepareArguments<TParams extends TSchema, TDetails>(\n\tdefinition: ToolDefinition<TParams, TDetails>,\n): (raw: unknown) => Static<TParams> {\n\tconst tool = { name: definition.name, description: definition.description, parameters: definition.parameters };\n\treturn (raw: unknown): Static<TParams> => {\n\t\tconst args = definition.prepareArguments ? definition.prepareArguments(raw) : raw;\n\t\ttry {\n\t\t\tvalidateToolArguments(tool, {\n\t\t\t\ttype: \"toolCall\",\n\t\t\t\tid: \"\",\n\t\t\t\tname: definition.name,\n\t\t\t\targuments: args as JsonObject,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthrow enrichValidationError(error, definition.parameters, args);\n\t\t}\n\t\treturn args as Static<TParams>;\n\t};\n}\n\n/** Wrap a ToolDefinition into an AgentTool for the core runtime. */\nexport function wrapToolDefinition<TParams extends TSchema, TDetails = unknown>(\n\tdefinition: ToolDefinition<TParams, TDetails>,\n\tctxFactory?: () => ExtensionContext,\n): PresentableAgentTool<TParams, TDetails> {\n\treturn {\n\t\tname: definition.name,\n\t\tlabel: definition.label,\n\t\tdescription: definition.description,\n\t\tparameters: definition.parameters,\n\t\tconstrainedSampling: definition.constrainedSampling,\n\t\ttoolGroup: definition.toolGroup,\n\t\tprepareArguments: wrapPrepareArguments(definition),\n\t\texecutionMode: definition.executionMode,\n\t\texecute: (toolCallId, params, signal, onUpdate, ctx?: ExtensionContext) =>\n\t\t\tdefinition.execute(toolCallId, params, signal, onUpdate, ctx ?? (ctxFactory?.() as ExtensionContext)),\n\t};\n}\n\n/** Wrap multiple ToolDefinitions into AgentTools for the core runtime. */\nexport function wrapToolDefinitions(\n\tdefinitions: ToolDefinition<any, any>[],\n\tctxFactory?: () => ExtensionContext,\n): AgentTool<any>[] {\n\treturn definitions.map((definition) => wrapToolDefinition(definition, ctxFactory));\n}\n\n/**\n * Synthesize a minimal ToolDefinition from an AgentTool.\n *\n * This keeps AgentSession's internal registry definition-first even when a caller\n * provides plain AgentTool overrides that do not include prompt metadata or renderers.\n */\nexport function createToolDefinitionFromAgentTool<TParams extends TSchema, TDetails>(\n\ttool: PresentableAgentTool<TParams, TDetails>,\n): ToolDefinition<TParams, TDetails> {\n\treturn {\n\t\tname: tool.name,\n\t\tlabel: tool.label,\n\t\tdescription: tool.description,\n\t\tparameters: tool.parameters,\n\t\tconstrainedSampling: tool.constrainedSampling,\n\t\ttoolGroup: tool.toolGroup,\n\t\tprepareArguments: tool.prepareArguments,\n\t\texecutionMode: tool.executionMode,\n\t\texecute: async (toolCallId, params, signal, onUpdate) => tool.execute(toolCallId, params, signal, onUpdate),\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tool-definition-wrapper.js","sourceRoot":"","sources":["../../../src/core/tools/tool-definition-wrapper.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport { type JsonObject, validateToolArguments } from \"@earendil-works/pi-ai\";\nimport type { Static, TSchema } from \"typebox\";\nimport type { ExtensionContext, ToolDefinition } from \"../extensions/types.ts\";\nimport { truncateHead } from \"./truncate.ts\";\n\ntype PresentableAgentTool<TParams extends TSchema = TSchema, TDetails = unknown> = AgentTool<TParams, TDetails> & {\n\ttoolGroup?: string;\n};\n\nconst RECEIVED_ARGUMENTS_MARKER = \"\\n\\nReceived arguments:\\n\";\nconst HINT_MARKER = \"\\n\\nHint: \";\nconst RECEIVED_ARGUMENTS_MAX_BYTES = 2 * 1024;\nconst RECEIVED_ARGUMENTS_MAX_LINES = 40;\nconst FIELD_HINTS_MAX = 10;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/**\n * Walk schema and arguments in sync to name, at every object with\n * `additionalProperties: false`, the non-null fields the schema does not\n * declare, and at every object, the required fields the arguments lack. The\n * validator's own report says where validation failed; these hints say what\n * the legal shape is. Union variants (`anyOf`, e.g. a nullable field) are\n * walked through so nested shapes still get hints. Paths use the validator's\n * dotted style\n * (`tasks[0].prompt`). Non-null unknown fields are reported rather than\n * silently dropped: a field like `prompt_extra` may carry briefing content\n * the caller intended to send.\n */\nfunction collectFieldHints(schema: unknown, args: unknown): string[] {\n\tconst hints: string[] = [];\n\tconst visit = (node: unknown, value: unknown, path: string): void => {\n\t\tif (hints.length >= FIELD_HINTS_MAX || !isRecord(node)) return;\n\t\tif (Array.isArray(node.anyOf)) {\n\t\t\t// Only nullable single-shape unions have unambiguous field requirements.\n\t\t\t// Alternative object shapes must not contribute contradictory hints.\n\t\t\tconst variants = node.anyOf.filter((variant: unknown) => !isRecord(variant) || variant.type !== \"null\");\n\t\t\tif (value !== null && variants.length === 1) visit(variants[0], value, path);\n\t\t\treturn;\n\t\t}\n\t\tif (node.type === \"array\" && Array.isArray(value)) {\n\t\t\tfor (let index = 0; index < value.length; index++) {\n\t\t\t\tvisit(node.items, value[index], `${path}[${index}]`);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (node.type !== \"object\" || !isRecord(value)) return;\n\t\tconst properties = isRecord(node.properties) ? node.properties : {};\n\t\tconst fields = Object.keys(properties);\n\t\tconst where = path || \"root\";\n\t\tif (node.additionalProperties === false) {\n\t\t\tfor (const [key, entry] of Object.entries(value)) {\n\t\t\t\tif (entry !== null && !(key in properties) && hints.length < FIELD_HINTS_MAX) {\n\t\t\t\t\tconst subject = path ? `${path}.${key}` : key;\n\t\t\t\t\thints.push(`${subject} is not a field; fields at ${where}: ${fields.join(\", \")}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (Array.isArray(node.required)) {\n\t\t\tfor (const key of node.required) {\n\t\t\t\tif (typeof key === \"string\" && value[key] === undefined && hints.length < FIELD_HINTS_MAX) {\n\t\t\t\t\tconst subject = path ? `${path}.${key}` : key;\n\t\t\t\t\thints.push(`${subject} is required; fields at ${where}: ${fields.join(\", \")}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const key of fields) {\n\t\t\tif (value[key] !== undefined && value[key] !== null) {\n\t\t\t\tvisit(properties[key], value[key], path ? `${path}.${key}` : key);\n\t\t\t}\n\t\t}\n\t};\n\tvisit(schema, args, \"\");\n\treturn hints;\n}\n\n/**\n * Rebuild pi-ai's validation error so a model can self-correct: the legal\n * fields are named next to each offending one, and the echoed arguments are\n * bounded (a 50KB subagent prompt must not be reflected whole into context).\n * The `Validation failed for tool \"<name>\":` prefix stays intact — the\n * question tool's renderer parses it.\n */\nfunction enrichValidationError(error: unknown, parameters: TSchema, args: unknown): Error {\n\tconst message = error instanceof Error ? error.message : String(error);\n\t// A definition synthesized from an already-wrapped tool enriches on the\n\t// inside; do not stack a second layer of hints on the same failure.\n\tif (message.includes(HINT_MARKER)) return error instanceof Error ? error : new Error(message);\n\tconst hints = collectFieldHints(parameters, args);\n\tconst markerIndex = message.indexOf(RECEIVED_ARGUMENTS_MARKER);\n\tconst head = markerIndex === -1 ? message : message.slice(0, markerIndex);\n\tconst received = markerIndex === -1 ? \"\" : message.slice(markerIndex + RECEIVED_ARGUMENTS_MARKER.length);\n\tlet enriched = hints.length > 0 ? `${head}\\n\\nHint: ${hints.join(\"\\nHint: \")}` : head;\n\tif (markerIndex !== -1) {\n\t\tconst bounded = truncateHead(received, {\n\t\t\tmaxBytes: RECEIVED_ARGUMENTS_MAX_BYTES,\n\t\t\tmaxLines: RECEIVED_ARGUMENTS_MAX_LINES,\n\t\t});\n\t\tenriched += `${RECEIVED_ARGUMENTS_MARKER}${bounded.content}`;\n\t\tif (bounded.truncated) enriched += \"\\n… (arguments truncated)\";\n\t}\n\treturn new Error(enriched);\n}\n\n/**\n * Pre-validate prepared arguments so a validation failure reaches the model\n * with field-level hints. Valid arguments pass through untouched and are\n * validated again by the agent loop as before.\n */\nfunction wrapPrepareArguments<TParams extends TSchema, TDetails>(\n\tdefinition: ToolDefinition<TParams, TDetails>,\n): (raw: unknown) => Static<TParams> {\n\tconst tool = { name: definition.name, description: definition.description, parameters: definition.parameters };\n\treturn (raw: unknown): Static<TParams> => {\n\t\tconst args = definition.prepareArguments ? definition.prepareArguments(raw) : raw;\n\t\ttry {\n\t\t\tvalidateToolArguments(tool, {\n\t\t\t\ttype: \"toolCall\",\n\t\t\t\tid: \"\",\n\t\t\t\tname: definition.name,\n\t\t\t\targuments: args as JsonObject,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthrow enrichValidationError(error, definition.parameters, args);\n\t\t}\n\t\treturn args as Static<TParams>;\n\t};\n}\n\n/** Wrap a ToolDefinition into an AgentTool for the core runtime. */\nexport function wrapToolDefinition<TParams extends TSchema, TDetails = unknown>(\n\tdefinition: ToolDefinition<TParams, TDetails>,\n\tctxFactory?: () => ExtensionContext,\n): PresentableAgentTool<TParams, TDetails> {\n\treturn {\n\t\tname: definition.name,\n\t\tlabel: definition.label,\n\t\tdescription: definition.description,\n\t\tparameters: definition.parameters,\n\t\tconstrainedSampling: definition.constrainedSampling,\n\t\ttoolGroup: definition.toolGroup,\n\t\tprepareArguments: wrapPrepareArguments(definition),\n\t\texecutionMode: definition.executionMode,\n\t\texecute: (toolCallId, params, signal, onUpdate, ctx?: ExtensionContext) =>\n\t\t\tdefinition.execute(toolCallId, params, signal, onUpdate, ctx ?? (ctxFactory?.() as ExtensionContext)),\n\t};\n}\n\n/** Wrap multiple ToolDefinitions into AgentTools for the core runtime. */\nexport function wrapToolDefinitions(\n\tdefinitions: ToolDefinition<any, any>[],\n\tctxFactory?: () => ExtensionContext,\n): AgentTool<any>[] {\n\treturn definitions.map((definition) => wrapToolDefinition(definition, ctxFactory));\n}\n\n/**\n * Synthesize a minimal ToolDefinition from an AgentTool.\n *\n * This keeps AgentSession's internal registry definition-first even when a caller\n * provides plain AgentTool overrides that do not include prompt metadata or renderers.\n */\nexport function createToolDefinitionFromAgentTool<TParams extends TSchema, TDetails>(\n\ttool: PresentableAgentTool<TParams, TDetails>,\n): ToolDefinition<TParams, TDetails> {\n\treturn {\n\t\tname: tool.name,\n\t\tlabel: tool.label,\n\t\tdescription: tool.description,\n\t\tparameters: tool.parameters,\n\t\tconstrainedSampling: tool.constrainedSampling,\n\t\ttoolGroup: tool.toolGroup,\n\t\tprepareArguments: tool.prepareArguments,\n\t\texecutionMode: tool.executionMode,\n\t\texecute: async (toolCallId, params, signal, onUpdate) => tool.execute(toolCallId, params, signal, onUpdate),\n\t};\n}\n"]}
|
|
@@ -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. One call applies a patch: create adds tasks (status defaults to pending), update edits tasks by id (blank or omitted fields are kept), delete removes tasks by id. Omit or leave empty any group you do not need; call with {} to list every task with its description.
|
|
13
|
+
export declare const TODO_TOOL_DESCRIPTION = "Manage the conversation's task list for multi-step coding work. One call applies a patch: create adds tasks (status defaults to pending), update edits tasks by id (blank or omitted fields are kept), delete removes tasks by id. Omit or leave empty any group you do not need; call with {} to list every task with its description. At most one task may be in_progress: setting one demotes the others. The list holds 20 tasks; when full, the oldest completed tasks are removed automatically, except tasks created or updated in this call. Delete existing tasks in the same patch to free space; an id cannot be both updated and deleted. A call that fails validation leaves the list unchanged.\n\n{\"create\": [{\"subject\": \"Wire parser\", \"description\": \"Parser handles the config format\", \"status\": \"in_progress\"}]}\n{\"update\": [{\"id\": 1, \"status\": \"completed\"}, {\"id\": 2, \"status\": \"in_progress\"}]}\n{\"delete\": [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;AAO/C,eAAO,MAAM,qBAAqB,
|
|
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;AAO/C,eAAO,MAAM,qBAAqB,66BAIlB,CAAC;AAEjB,eAAO,MAAM,mBAAmB,yEAAyE,CAAC;AAE1G,eAAO,MAAM,sBAAsB,UAKlC,CAAC"}
|
|
@@ -15,7 +15,7 @@ export const TODO_MAX_DESCRIPTION_LENGTH = 500;
|
|
|
15
15
|
// Per-parameter bounds and wording live in the schema. The single-in_progress
|
|
16
16
|
// rule is stated in both places on purpose: it is the invariant models break
|
|
17
17
|
// most often.
|
|
18
|
-
export const TODO_TOOL_DESCRIPTION = `Manage the conversation's task list for multi-step coding work. One call applies a patch: create adds tasks (status defaults to pending), update edits tasks by id (blank or omitted fields are kept), delete removes tasks by id. Omit or leave empty any group you do not need; call with {} to list every task with its description.
|
|
18
|
+
export const TODO_TOOL_DESCRIPTION = `Manage the conversation's task list for multi-step coding work. One call applies a patch: create adds tasks (status defaults to pending), update edits tasks by id (blank or omitted fields are kept), delete removes tasks by id. Omit or leave empty any group you do not need; call with {} to list every task with its description. At most one task may be in_progress: setting one demotes the others. The list holds 20 tasks; when full, the oldest completed tasks are removed automatically, except tasks created or updated in this call. Delete existing tasks in the same patch to free space; an id cannot be both updated and deleted. A call that fails validation leaves the list unchanged.
|
|
19
19
|
|
|
20
20
|
{"create": [{"subject": "Wire parser", "description": "Parser handles the config format", "status": "in_progress"}]}
|
|
21
21
|
{"update": [{"id": 1, "status": "completed"}, {"id": 2, "status": "in_progress"}]}
|
|
@@ -23,7 +23,7 @@ export const TODO_TOOL_DESCRIPTION = `Manage the conversation's task list for mu
|
|
|
23
23
|
export const TODO_PROMPT_SNIPPET = "Track multi-step coding work with a small outcome-oriented task list";
|
|
24
24
|
export const TODO_PROMPT_GUIDELINES = [
|
|
25
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
|
-
"
|
|
26
|
+
"Mark the `todo` task you are working on in_progress before starting, and completed only after its description is satisfied. Leave no task in_progress when waiting or when all work is done.",
|
|
27
27
|
"When blocked, leave the `todo` task pending and create a task for the blocker instead of faking completion.",
|
|
28
28
|
"Keep the `todo` list short: list before create to avoid duplicates, work in id order, and delete obsolete tasks promptly.",
|
|
29
29
|
];
|
|
@@ -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,4EAA4E;AAC5E,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,cAAc;AACd,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;gBAIrB,CAAC;AAEjB,MAAM,CAAC,MAAM,mBAAmB,GAAG,sEAAsE,CAAC;AAE1G,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACrC,6LAA6L;IAC7L,
|
|
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,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,cAAc;AACd,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;gBAIrB,CAAC;AAEjB,MAAM,CAAC,MAAM,mBAAmB,GAAG,sEAAsE,CAAC;AAE1G,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACrC,6LAA6L;IAC7L,8LAA8L;IAC9L,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 with automatic reclaim, the single-in_progress rule, atomicity).\n// Per-parameter bounds and wording live in the schema. The single-in_progress\n// rule is stated in both places on purpose: it is the invariant models break\n// most often.\nexport const TODO_TOOL_DESCRIPTION = `Manage the conversation's task list for multi-step coding work. One call applies a patch: create adds tasks (status defaults to pending), update edits tasks by id (blank or omitted fields are kept), delete removes tasks by id. Omit or leave empty any group you do not need; call with {} to list every task with its description. At most one task may be in_progress: setting one demotes the others. The list holds 20 tasks; when full, the oldest completed tasks are removed automatically, except tasks created or updated in this call. Delete existing tasks in the same patch to free space; an id cannot be both updated and deleted. A call that fails validation leaves the list unchanged.\n\n{\"create\": [{\"subject\": \"Wire parser\", \"description\": \"Parser handles the config format\", \"status\": \"in_progress\"}]}\n{\"update\": [{\"id\": 1, \"status\": \"completed\"}, {\"id\": 2, \"status\": \"in_progress\"}]}\n{\"delete\": [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\"Mark the `todo` task you are working on in_progress before starting, and completed only after its description is satisfied. Leave no task in_progress when waiting or when all work is done.\",\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":"schema.d.ts","sourceRoot":"","sources":["../../../src/extensions/todo/schema.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;AAEjE,MAAM,WAAW,QAAQ;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACzB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CACf;AAED,+DAA+D;AAC/D,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C;;;;GAIG;AACH,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAC;QAAC,EAAE,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;IACjE,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC3B,aAAa,EAAE,OAAO,2BAA2B,CAAC;IAClD,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;CACjB;AA4CD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;EAsB5B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEzD,eAAO,MAAM,gBAAgB,EAAE,SAAoC,CAAC"}
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/extensions/todo/schema.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;AAEjE,MAAM,WAAW,QAAQ;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACzB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CACf;AAED,+DAA+D;AAC/D,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C;;;;GAIG;AACH,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,sFAAsF;IACtF,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAC;QAAC,EAAE,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;IACjE,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC3B,aAAa,EAAE,OAAO,2BAA2B,CAAC;IAClD,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;CACjB;AA4CD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;EAsB5B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEzD,eAAO,MAAM,gBAAgB,EAAE,SAAoC,CAAC"}
|
|
@@ -12,7 +12,7 @@ import { TODO_MAX_BATCH_ITEMS, TODO_MAX_DESCRIPTION_LENGTH, TODO_MAX_SUBJECT_LEN
|
|
|
12
12
|
/** Current shape of snapshots written to todo tool results. */
|
|
13
13
|
export const TODO_DETAILS_SCHEMA_VERSION = 3;
|
|
14
14
|
const StatusSchema = StringEnum(["pending", "in_progress", "completed"], {
|
|
15
|
-
description: "Task status: pending for future work, in_progress for the single active task, completed for verified done work.
|
|
15
|
+
description: "Task status: pending for future work, in_progress for the single active task, completed for verified done work. At most one task may be in_progress; setting one demotes any other active task to pending.",
|
|
16
16
|
});
|
|
17
17
|
const TaskIdSchema = Type.Integer({ minimum: 1, description: "Positive task id." });
|
|
18
18
|
const CreateItemSchema = Type.Object({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/extensions/todo/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAgB5G,+DAA+D;AAC/D,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/extensions/todo/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAgB5G,+DAA+D;AAC/D,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC;AAuB7C,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,SAAS,EAAE,aAAa,EAAE,WAAW,CAAU,EAAE;IACjF,WAAW,EACV,4MAA4M;CAC7M,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC,CAAC;AAEpF,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CACnC;IACC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;QACpB,SAAS,EAAE,uBAAuB;QAClC,WAAW,EAAE,2DAA2D;KACxE,CAAC;IACF,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC;QACxB,SAAS,EAAE,2BAA2B;QACtC,WAAW,EAAE,4EAA4E;KACzF,CAAC;IACF,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;CACnC,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC;AAEF,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CACnC;IACC,EAAE,EAAE,YAAY;IAChB,OAAO,EAAE,IAAI,CAAC,QAAQ,CACrB,IAAI,CAAC,MAAM,CAAC;QACX,SAAS,EAAE,uBAAuB;QAClC,WAAW,EAAE,8DAA8D;KAC3E,CAAC,CACF;IACD,WAAW,EAAE,IAAI,CAAC,QAAQ,CACzB,IAAI,CAAC,MAAM,CAAC;QACX,SAAS,EAAE,2BAA2B;QACtC,WAAW,EAAE,oFAAoF;KACjG,CAAC,CACF;IACD,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;CACnC,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAC1C;IACC,MAAM,EAAE,IAAI,CAAC,QAAQ,CACpB,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE;QAC5B,QAAQ,EAAE,oBAAoB;QAC9B,WAAW,EAAE,8EAA8E;KAC3F,CAAC,CACF;IACD,MAAM,EAAE,IAAI,CAAC,QAAQ,CACpB,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE;QAC5B,QAAQ,EAAE,oBAAoB;QAC9B,WAAW,EAAE,sEAAsE;KACnF,CAAC,CACF;IACD,MAAM,EAAE,IAAI,CAAC,QAAQ,CACpB,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE;QACxB,QAAQ,EAAE,oBAAoB;QAC9B,WAAW,EAAE,wFAAwF;KACrG,CAAC,CACF;CACD,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC;AAIF,MAAM,CAAC,MAAM,gBAAgB,GAAc,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC","sourcesContent":["/**\n * todo/schema.ts — v3 tool parameters, state shape, and operation model.\n *\n * One call is one patch: the three group fields (create, update, delete) are\n * applied together, there is no action discriminator. The shape is built for\n * strict constrained sampling: optional groups can be null or empty and every\n * filler value a strict sampler may emit ([], \"\", null) is a harmless no-op.\n */\nimport { StringEnum } from \"@earendil-works/pi-ai\";\nimport { type Static, Type } from \"typebox\";\nimport { TODO_MAX_BATCH_ITEMS, TODO_MAX_DESCRIPTION_LENGTH, TODO_MAX_SUBJECT_LENGTH } from \"./constants.ts\";\n\nexport type TodoStatus = \"pending\" | \"in_progress\" | \"completed\";\n\nexport interface TodoItem {\n\tid: number;\n\tsubject: string;\n\tdescription: string;\n\tstatus: TodoStatus;\n}\n\nexport interface TodoState {\n\titems: TodoItem[];\n\tnextId: number;\n}\n\n/** Current shape of snapshots written to todo tool results. */\nexport const TODO_DETAILS_SCHEMA_VERSION = 3;\n\n/**\n * What one call changed, as a flat patch record. Every list is empty for a\n * pure list call; `demotedId` is present only when an activation pushed the\n * previously active task back to pending.\n */\nexport interface TodoChange {\n\tcreated: number[];\n\t/** Explicitly updated tasks, from their prior status to the final snapshot status. */\n\tupdated: Array<{ id: number; from: TodoStatus; to: TodoStatus }>;\n\tdeleted: Array<{ id: number; subject: string }>;\n\tabsent: number[];\n\tevicted: Array<{ id: number; subject: string }>;\n\tdemotedId?: number;\n}\n\nexport interface TodoDetails {\n\tschemaVersion: typeof TODO_DETAILS_SCHEMA_VERSION;\n\tchange: TodoChange;\n\tstate: TodoState;\n}\n\nconst StatusSchema = StringEnum([\"pending\", \"in_progress\", \"completed\"] as const, {\n\tdescription:\n\t\t\"Task status: pending for future work, in_progress for the single active task, completed for verified done work. At most one task may be in_progress; setting one demotes any other active task to pending.\",\n});\n\nconst TaskIdSchema = Type.Integer({ minimum: 1, description: \"Positive task id.\" });\n\nconst CreateItemSchema = Type.Object(\n\t{\n\t\tsubject: Type.String({\n\t\t\tmaxLength: TODO_MAX_SUBJECT_LENGTH,\n\t\t\tdescription: \"Short imperative task subject; a reviewable unit of work.\",\n\t\t}),\n\t\tdescription: Type.String({\n\t\t\tmaxLength: TODO_MAX_DESCRIPTION_LENGTH,\n\t\t\tdescription: \"What done means for this task: acceptance criteria or verification detail.\",\n\t\t}),\n\t\tstatus: Type.Optional(StatusSchema),\n\t},\n\t{ additionalProperties: false },\n);\n\nconst UpdateItemSchema = Type.Object(\n\t{\n\t\tid: TaskIdSchema,\n\t\tsubject: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tmaxLength: TODO_MAX_SUBJECT_LENGTH,\n\t\t\t\tdescription: \"Replacement subject; blank or omitted keeps the current one.\",\n\t\t\t}),\n\t\t),\n\t\tdescription: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tmaxLength: TODO_MAX_DESCRIPTION_LENGTH,\n\t\t\t\tdescription: \"Replacement description (what done means); blank or omitted keeps the current one.\",\n\t\t\t}),\n\t\t),\n\t\tstatus: Type.Optional(StatusSchema),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport const TodoParamsSchema = Type.Object(\n\t{\n\t\tcreate: Type.Optional(\n\t\t\tType.Array(CreateItemSchema, {\n\t\t\t\tmaxItems: TODO_MAX_BATCH_ITEMS,\n\t\t\t\tdescription: \"Tasks to add, created atomically in input order; status defaults to pending.\",\n\t\t\t}),\n\t\t),\n\t\tupdate: Type.Optional(\n\t\t\tType.Array(UpdateItemSchema, {\n\t\t\t\tmaxItems: TODO_MAX_BATCH_ITEMS,\n\t\t\t\tdescription: \"Task edits by id; blank or omitted fields keep their current values.\",\n\t\t\t}),\n\t\t),\n\t\tdelete: Type.Optional(\n\t\t\tType.Array(TaskIdSchema, {\n\t\t\t\tmaxItems: TODO_MAX_BATCH_ITEMS,\n\t\t\t\tdescription: \"Ids to remove from the current list; deleting an id that is already absent is a no-op.\",\n\t\t\t}),\n\t\t),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport type TodoParams = Static<typeof TodoParamsSchema>;\n\nexport const EMPTY_TODO_STATE: TodoState = { items: [], nextId: 1 };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/extensions/todo/state.ts"],"names":[],"mappings":"AAkBA,OAAO,EAGN,KAAK,UAAU,EACf,KAAK,WAAW,EAEhB,KAAK,UAAU,EACf,KAAK,SAAS,EAEd,MAAM,aAAa,CAAC;AAuJrB,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAE1D;AAED,MAAM,WAAW,SAAS;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/extensions/todo/state.ts"],"names":[],"mappings":"AAkBA,OAAO,EAGN,KAAK,UAAU,EACf,KAAK,WAAW,EAEhB,KAAK,UAAU,EACf,KAAK,SAAS,EAEd,MAAM,aAAa,CAAC;AAuJrB,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAE1D;AAED,MAAM,WAAW,SAAS;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,CAoJ/E;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,CAgB9D;AAwCD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE;IAAE,cAAc,EAAE;QAAE,SAAS,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;CAAE,GAAG,SAAS,CAoB5G"}
|
|
@@ -185,7 +185,7 @@ export function applyTodoPatch(before, params) {
|
|
|
185
185
|
if (deleteSet.has(entry.id))
|
|
186
186
|
throw new Error(`#${entry.id} cannot be in both update and delete`);
|
|
187
187
|
}
|
|
188
|
-
//
|
|
188
|
+
// At most one activation per call: more than one is a real contradiction,
|
|
189
189
|
// since a single task can be in_progress at any time.
|
|
190
190
|
const activations = [];
|
|
191
191
|
createEntries.forEach((entry, index) => {
|
|
@@ -222,7 +222,6 @@ export function applyTodoPatch(before, params) {
|
|
|
222
222
|
}
|
|
223
223
|
let items = before.items.filter((item) => !deleteSet.has(item.id));
|
|
224
224
|
// --- Apply: update -------------------------------------------------------
|
|
225
|
-
const updated = [];
|
|
226
225
|
if (updateEntries.length > 0) {
|
|
227
226
|
const entriesById = new Map(updateEntries.map((entry) => [entry.id, entry]));
|
|
228
227
|
items = items.map((item) => {
|
|
@@ -235,7 +234,6 @@ export function applyTodoPatch(before, params) {
|
|
|
235
234
|
description: entry.description ?? item.description,
|
|
236
235
|
status: entry.status ?? item.status,
|
|
237
236
|
};
|
|
238
|
-
updated.push({ id: item.id, from: item.status, to: next.status });
|
|
239
237
|
return next;
|
|
240
238
|
});
|
|
241
239
|
}
|
|
@@ -294,10 +292,22 @@ export function applyTodoPatch(before, params) {
|
|
|
294
292
|
evicted.push({ id: item.id, subject: item.subject });
|
|
295
293
|
overflow--;
|
|
296
294
|
}
|
|
297
|
-
if (overflow > 0)
|
|
298
|
-
|
|
295
|
+
if (overflow > 0) {
|
|
296
|
+
const completedIds = before.items.filter((item) => item.status === "completed").map((item) => `#${item.id}`);
|
|
297
|
+
throw new Error(`at most ${TODO_MAX_ITEMS} tasks; complete or delete some first. Patch not applied. Tasks created or updated in this call are not reclaimed. ` +
|
|
298
|
+
`Delete existing tasks in the same patch to free space (remove those ids from update), or complete tasks in a separate call before creating more. ` +
|
|
299
|
+
`Completed ids before this call: ${completedIds.join(", ") || "none"}.`);
|
|
300
|
+
}
|
|
299
301
|
items = items.filter((item) => !evictIds.has(item.id));
|
|
300
302
|
}
|
|
303
|
+
// Report transitions only after activation and capacity have settled the snapshot.
|
|
304
|
+
const updated = items
|
|
305
|
+
.filter((item) => updatedIds.has(item.id))
|
|
306
|
+
.map((item) => ({
|
|
307
|
+
id: item.id,
|
|
308
|
+
from: byId.get(item.id).status,
|
|
309
|
+
to: item.status,
|
|
310
|
+
}));
|
|
301
311
|
const change = { created, updated, deleted, absent, evicted };
|
|
302
312
|
if (demotedId !== undefined)
|
|
303
313
|
change.demotedId = demotedId;
|
|
@@ -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 — v3 pure state core: closure-scoped store, atomic patch\n * application (delete, then update, then create), snapshot cloning, and\n * branch replay. No session registry, metadata, dependency graph, tombstones,\n * filters, or legacy normalizers.\n *\n * The patch shape is designed so every value a strict sampler may fill in for\n * an unused field ([], \"\", null already stripped by validation) is a no-op:\n * empty groups do nothing, blank update text keeps the current value, and\n * deleting an absent id is recorded rather than rejected.\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 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 GROUP_FIELDS: ReadonlySet<string> = new Set([\"create\", \"update\", \"delete\"]);\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\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\n/** Required text (create): normalized, non-empty, within the limit. */\nfunction validateRequiredText(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\n/**\n * Optional text (update): normalized and within the limit, where blank means\n * \"keep the current value\" (undefined) so strict-mode filler stays harmless.\n */\nfunction validateOptionalText(value: unknown, label: string, maximum: number): string | undefined {\n\tif (value === undefined) return undefined;\n\tif (typeof value !== \"string\") throw new Error(`${label} must be a string`);\n\tconst normalized = normalizeText(value);\n\tif (!normalized) return undefined;\n\tif (normalized.length > maximum) throw new Error(`${label} exceeds ${maximum} characters`);\n\treturn normalized;\n}\n\nfunction validateOptionalStatus(value: unknown, label: string): TodoStatus | undefined {\n\tif (value === undefined) return undefined;\n\tif (!isTodoStatus(value)) throw new Error(`${label} is invalid`);\n\treturn value;\n}\n\ninterface CreateEntry {\n\tsubject: string;\n\tdescription: string;\n\tstatus?: TodoStatus;\n}\n\ninterface UpdateEntry {\n\tid: number;\n\tsubject?: string;\n\tdescription?: string;\n\tstatus?: TodoStatus;\n}\n\nfunction readCreateEntries(raw: unknown): CreateEntry[] {\n\tif (raw === undefined) return [];\n\tif (!Array.isArray(raw)) throw new Error(\"create must be an array\");\n\tif (raw.length > TODO_MAX_BATCH_ITEMS) throw new Error(`create exceeds ${TODO_MAX_BATCH_ITEMS} tasks`);\n\tconst entries: CreateEntry[] = [];\n\tfor (let index = 0; index < raw.length; index++) {\n\t\tconst item = raw[index];\n\t\tif (!isRecord(item)) throw new Error(`create[${index}] must be an object`);\n\t\tfor (const key of Object.keys(item)) {\n\t\t\tif (key !== \"subject\" && key !== \"description\" && key !== \"status\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`create[${index}].${key} is not a create field; valid fields: subject, description, status`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tconst entry: CreateEntry = {\n\t\t\tsubject: validateRequiredText(item.subject, `create[${index}].subject`, TODO_MAX_SUBJECT_LENGTH),\n\t\t\tdescription: validateRequiredText(\n\t\t\t\titem.description,\n\t\t\t\t`create[${index}].description`,\n\t\t\t\tTODO_MAX_DESCRIPTION_LENGTH,\n\t\t\t),\n\t\t};\n\t\tconst status = validateOptionalStatus(item.status, `create[${index}].status`);\n\t\tif (status !== undefined) entry.status = status;\n\t\tentries.push(entry);\n\t}\n\treturn entries;\n}\n\nfunction readUpdateEntries(raw: unknown): UpdateEntry[] {\n\tif (raw === undefined) return [];\n\tif (!Array.isArray(raw)) throw new Error(\"update must be an array\");\n\tif (raw.length > TODO_MAX_BATCH_ITEMS) throw new Error(`update exceeds ${TODO_MAX_BATCH_ITEMS} tasks`);\n\tconst entries: UpdateEntry[] = [];\n\tfor (let index = 0; index < raw.length; index++) {\n\t\tconst item = raw[index];\n\t\tif (!isRecord(item)) throw new Error(`update[${index}] must be an object`);\n\t\tfor (const key of Object.keys(item)) {\n\t\t\tif (key !== \"id\" && key !== \"subject\" && key !== \"description\" && key !== \"status\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`update[${index}].${key} is not an update field; valid fields: id, subject, description, status`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (!isPositiveSafeInteger(item.id)) throw new Error(`update[${index}].id must be a positive integer`);\n\t\tconst entry: UpdateEntry = { id: item.id };\n\t\tconst subject = validateOptionalText(item.subject, `update[${index}].subject`, TODO_MAX_SUBJECT_LENGTH);\n\t\tif (subject !== undefined) entry.subject = subject;\n\t\tconst description = validateOptionalText(\n\t\t\titem.description,\n\t\t\t`update[${index}].description`,\n\t\t\tTODO_MAX_DESCRIPTION_LENGTH,\n\t\t);\n\t\tif (description !== undefined) entry.description = description;\n\t\tconst status = validateOptionalStatus(item.status, `update[${index}].status`);\n\t\tif (status !== undefined) entry.status = status;\n\t\tentries.push(entry);\n\t}\n\treturn entries;\n}\n\nfunction readDeleteIds(raw: unknown): number[] {\n\tif (raw === undefined) return [];\n\tif (!Array.isArray(raw)) throw new Error(\"delete must be an array\");\n\tif (raw.length > TODO_MAX_BATCH_ITEMS) throw new Error(`delete exceeds ${TODO_MAX_BATCH_ITEMS} ids`);\n\tconst ids: number[] = [];\n\tfor (let index = 0; index < raw.length; index++) {\n\t\tif (!isPositiveSafeInteger(raw[index])) throw new Error(`delete[${index}] must be a positive integer id`);\n\t\tids.push(raw[index]);\n\t}\n\treturn ids;\n}\n\nfunction currentIdsLabel(state: TodoState): string {\n\tif (state.items.length === 0) return \"the list is empty\";\n\treturn `current ids: ${state.items.map((item) => `#${item.id}`).join(\", \")}`;\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\nexport interface TodoPatch {\n\tstate: TodoState;\n\tchange: TodoChange;\n}\n\n/**\n * Pure patch application: validates every runtime input (tool args can be\n * tampered after schema validation), throws on any invalid call, and never\n * mutates the input state. Application order is delete, then update, then\n * create, so a delete in the same call frees capacity for the create.\n */\nexport function applyTodoPatch(before: TodoState, params: TodoParams): TodoPatch {\n\tif (!isRecord(params)) throw new Error(\"todo params must be an object\");\n\tfor (const key of Object.keys(params)) {\n\t\tif (!GROUP_FIELDS.has(key)) throw new Error(`unknown todo field \"${key}\"; valid fields: create, update, delete`);\n\t}\n\n\t// Everything above the apply phase is validation: any throw leaves the\n\t// caller's state untouched.\n\tconst createEntries = readCreateEntries(params.create);\n\tconst updateEntries = readUpdateEntries(params.update);\n\tconst deleteIds = readDeleteIds(params.delete);\n\n\t// Conflicts: one edit per task per call, and a task cannot be both edited\n\t// and removed in the same call.\n\tconst updatedIds = new Set<number>();\n\tfor (const entry of updateEntries) {\n\t\tif (updatedIds.has(entry.id)) throw new Error(`#${entry.id} appears more than once in update`);\n\t\tupdatedIds.add(entry.id);\n\t}\n\tconst deleteSet = new Set(deleteIds);\n\tfor (const entry of updateEntries) {\n\t\tif (deleteSet.has(entry.id)) throw new Error(`#${entry.id} cannot be in both update and delete`);\n\t}\n\n\t// Exactly one activation per call: more than one is a real contradiction,\n\t// since a single task can be in_progress at any time.\n\tconst activations: string[] = [];\n\tcreateEntries.forEach((entry, index) => {\n\t\tif (entry.status === \"in_progress\") activations.push(`create[${index}]`);\n\t});\n\tfor (const entry of updateEntries) {\n\t\tif (entry.status === \"in_progress\") activations.push(`#${entry.id}`);\n\t}\n\tif (activations.length > 1) {\n\t\tthrow new Error(`at most one task may be set in_progress per call; got ${activations.join(\" and \")}`);\n\t}\n\n\tconst byId = new Map(before.items.map((item) => [item.id, item]));\n\tfor (const entry of updateEntries) {\n\t\tif (!byId.has(entry.id)) throw new Error(`#${entry.id} not found; ${currentIdsLabel(before)}`);\n\t}\n\n\tif (createEntries.length > 0) {\n\t\tif (!Number.isSafeInteger(before.nextId) || before.nextId < 1) throw new Error(\"next id is invalid\");\n\t\tif (before.nextId > Number.MAX_SAFE_INTEGER - createEntries.length) throw new Error(\"next id is exhausted\");\n\t}\n\n\t// --- Apply: delete -------------------------------------------------------\n\tconst deleted: Array<{ id: number; subject: string }> = [];\n\tconst absent: number[] = [];\n\tfor (const id of dedupeIds(deleteIds)) {\n\t\tconst item = byId.get(id);\n\t\tif (item) deleted.push({ id: item.id, subject: item.subject });\n\t\telse absent.push(id);\n\t}\n\tlet items = before.items.filter((item) => !deleteSet.has(item.id));\n\n\t// --- Apply: update -------------------------------------------------------\n\tconst updated: Array<{ id: number; from: TodoStatus; to: TodoStatus }> = [];\n\tif (updateEntries.length > 0) {\n\t\tconst entriesById = new Map(updateEntries.map((entry) => [entry.id, entry]));\n\t\titems = items.map((item) => {\n\t\t\tconst entry = entriesById.get(item.id);\n\t\t\tif (!entry) return item;\n\t\t\tconst next: TodoItem = {\n\t\t\t\tid: item.id,\n\t\t\t\tsubject: entry.subject ?? item.subject,\n\t\t\t\tdescription: entry.description ?? item.description,\n\t\t\t\tstatus: entry.status ?? item.status,\n\t\t\t};\n\t\t\tupdated.push({ id: item.id, from: item.status, to: next.status });\n\t\t\treturn next;\n\t\t});\n\t}\n\n\t// --- Apply: create -------------------------------------------------------\n\tconst created: number[] = [];\n\tif (createEntries.length > 0) {\n\t\tconst newItems = createEntries.map((entry, index) => {\n\t\t\tconst item: TodoItem = {\n\t\t\t\tid: before.nextId + index,\n\t\t\t\tsubject: entry.subject,\n\t\t\t\tdescription: entry.description,\n\t\t\t\tstatus: entry.status ?? \"pending\",\n\t\t\t};\n\t\t\treturn item;\n\t\t});\n\t\tfor (const item of newItems) created.push(item.id);\n\t\titems = [...items, ...newItems];\n\t}\n\n\t// --- Single in_progress: the one task this call activates demotes the rest.\n\tlet demotedId: number | undefined;\n\tlet activatedId: number | undefined;\n\tfor (const entry of updateEntries) {\n\t\tif (entry.status === \"in_progress\") activatedId = entry.id;\n\t}\n\tif (activatedId === undefined) {\n\t\tcreateEntries.forEach((entry, index) => {\n\t\t\tif (entry.status === \"in_progress\") activatedId = before.nextId + index;\n\t\t});\n\t}\n\tif (activatedId !== undefined) {\n\t\tconst demoted = items.find((item) => item.id !== activatedId && item.status === \"in_progress\");\n\t\tif (demoted) {\n\t\t\tdemotedId = demoted.id;\n\t\t\titems = items.map((item) => (item.id === demoted.id ? { ...item, status: \"pending\" as const } : item));\n\t\t}\n\t}\n\n\t// --- Capacity: completed tasks are reclaimed oldest-first before a call\n\t// may fail for space; only a list that stays over the cap is rejected.\n\t// Tasks this call created or updated are never reclaimed: silently dropping\n\t// a task would be confusing when the same result reports it as touched.\n\tconst evicted: Array<{ id: number; subject: string }> = [];\n\tif (items.length > TODO_MAX_ITEMS) {\n\t\tlet overflow = items.length - TODO_MAX_ITEMS;\n\t\tconst evictIds = new Set<number>();\n\t\tconst touched = new Set<number>([...created, ...updatedIds]);\n\t\tconst completedOldestFirst = items\n\t\t\t.filter((item) => item.status === \"completed\" && !touched.has(item.id))\n\t\t\t.sort((first, second) => first.id - second.id);\n\t\tfor (const item of completedOldestFirst) {\n\t\t\tif (overflow <= 0) break;\n\t\t\tevictIds.add(item.id);\n\t\t\tevicted.push({ id: item.id, subject: item.subject });\n\t\t\toverflow--;\n\t\t}\n\t\tif (overflow > 0) throw new Error(`at most ${TODO_MAX_ITEMS} tasks; complete or delete some first`);\n\t\titems = items.filter((item) => !evictIds.has(item.id));\n\t}\n\n\tconst change: TodoChange = { created, updated, deleted, absent, evicted };\n\tif (demotedId !== undefined) change.demotedId = demotedId;\n\treturn { state: { items, nextId: before.nextId + created.length }, change };\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 patch = applyTodoPatch(state, params);\n\t\t\tconst details = buildTodoDetails(patch.change, patch.state);\n\t\t\tstate = patch.state;\n\t\t\treturn details;\n\t\t},\n\t};\n}\n\n/**\n * Validate an external v3 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 v3 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 v3 todo snapshot from a branch, scanning tail to\n * head so a malformed latest snapshot falls back to an earlier valid one.\n * Older schema versions (v1/v2) are ignored: restoring a session written\n * before v3 starts from an empty list.\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 v3 snapshot.\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 — v3 pure state core: closure-scoped store, atomic patch\n * application (delete, then update, then create), snapshot cloning, and\n * branch replay. No session registry, metadata, dependency graph, tombstones,\n * filters, or legacy normalizers.\n *\n * The patch shape is designed so every value a strict sampler may fill in for\n * an unused field ([], \"\", null already stripped by validation) is a no-op:\n * empty groups do nothing, blank update text keeps the current value, and\n * deleting an absent id is recorded rather than rejected.\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 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 GROUP_FIELDS: ReadonlySet<string> = new Set([\"create\", \"update\", \"delete\"]);\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\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\n/** Required text (create): normalized, non-empty, within the limit. */\nfunction validateRequiredText(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\n/**\n * Optional text (update): normalized and within the limit, where blank means\n * \"keep the current value\" (undefined) so strict-mode filler stays harmless.\n */\nfunction validateOptionalText(value: unknown, label: string, maximum: number): string | undefined {\n\tif (value === undefined) return undefined;\n\tif (typeof value !== \"string\") throw new Error(`${label} must be a string`);\n\tconst normalized = normalizeText(value);\n\tif (!normalized) return undefined;\n\tif (normalized.length > maximum) throw new Error(`${label} exceeds ${maximum} characters`);\n\treturn normalized;\n}\n\nfunction validateOptionalStatus(value: unknown, label: string): TodoStatus | undefined {\n\tif (value === undefined) return undefined;\n\tif (!isTodoStatus(value)) throw new Error(`${label} is invalid`);\n\treturn value;\n}\n\ninterface CreateEntry {\n\tsubject: string;\n\tdescription: string;\n\tstatus?: TodoStatus;\n}\n\ninterface UpdateEntry {\n\tid: number;\n\tsubject?: string;\n\tdescription?: string;\n\tstatus?: TodoStatus;\n}\n\nfunction readCreateEntries(raw: unknown): CreateEntry[] {\n\tif (raw === undefined) return [];\n\tif (!Array.isArray(raw)) throw new Error(\"create must be an array\");\n\tif (raw.length > TODO_MAX_BATCH_ITEMS) throw new Error(`create exceeds ${TODO_MAX_BATCH_ITEMS} tasks`);\n\tconst entries: CreateEntry[] = [];\n\tfor (let index = 0; index < raw.length; index++) {\n\t\tconst item = raw[index];\n\t\tif (!isRecord(item)) throw new Error(`create[${index}] must be an object`);\n\t\tfor (const key of Object.keys(item)) {\n\t\t\tif (key !== \"subject\" && key !== \"description\" && key !== \"status\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`create[${index}].${key} is not a create field; valid fields: subject, description, status`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tconst entry: CreateEntry = {\n\t\t\tsubject: validateRequiredText(item.subject, `create[${index}].subject`, TODO_MAX_SUBJECT_LENGTH),\n\t\t\tdescription: validateRequiredText(\n\t\t\t\titem.description,\n\t\t\t\t`create[${index}].description`,\n\t\t\t\tTODO_MAX_DESCRIPTION_LENGTH,\n\t\t\t),\n\t\t};\n\t\tconst status = validateOptionalStatus(item.status, `create[${index}].status`);\n\t\tif (status !== undefined) entry.status = status;\n\t\tentries.push(entry);\n\t}\n\treturn entries;\n}\n\nfunction readUpdateEntries(raw: unknown): UpdateEntry[] {\n\tif (raw === undefined) return [];\n\tif (!Array.isArray(raw)) throw new Error(\"update must be an array\");\n\tif (raw.length > TODO_MAX_BATCH_ITEMS) throw new Error(`update exceeds ${TODO_MAX_BATCH_ITEMS} tasks`);\n\tconst entries: UpdateEntry[] = [];\n\tfor (let index = 0; index < raw.length; index++) {\n\t\tconst item = raw[index];\n\t\tif (!isRecord(item)) throw new Error(`update[${index}] must be an object`);\n\t\tfor (const key of Object.keys(item)) {\n\t\t\tif (key !== \"id\" && key !== \"subject\" && key !== \"description\" && key !== \"status\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`update[${index}].${key} is not an update field; valid fields: id, subject, description, status`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (!isPositiveSafeInteger(item.id)) throw new Error(`update[${index}].id must be a positive integer`);\n\t\tconst entry: UpdateEntry = { id: item.id };\n\t\tconst subject = validateOptionalText(item.subject, `update[${index}].subject`, TODO_MAX_SUBJECT_LENGTH);\n\t\tif (subject !== undefined) entry.subject = subject;\n\t\tconst description = validateOptionalText(\n\t\t\titem.description,\n\t\t\t`update[${index}].description`,\n\t\t\tTODO_MAX_DESCRIPTION_LENGTH,\n\t\t);\n\t\tif (description !== undefined) entry.description = description;\n\t\tconst status = validateOptionalStatus(item.status, `update[${index}].status`);\n\t\tif (status !== undefined) entry.status = status;\n\t\tentries.push(entry);\n\t}\n\treturn entries;\n}\n\nfunction readDeleteIds(raw: unknown): number[] {\n\tif (raw === undefined) return [];\n\tif (!Array.isArray(raw)) throw new Error(\"delete must be an array\");\n\tif (raw.length > TODO_MAX_BATCH_ITEMS) throw new Error(`delete exceeds ${TODO_MAX_BATCH_ITEMS} ids`);\n\tconst ids: number[] = [];\n\tfor (let index = 0; index < raw.length; index++) {\n\t\tif (!isPositiveSafeInteger(raw[index])) throw new Error(`delete[${index}] must be a positive integer id`);\n\t\tids.push(raw[index]);\n\t}\n\treturn ids;\n}\n\nfunction currentIdsLabel(state: TodoState): string {\n\tif (state.items.length === 0) return \"the list is empty\";\n\treturn `current ids: ${state.items.map((item) => `#${item.id}`).join(\", \")}`;\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\nexport interface TodoPatch {\n\tstate: TodoState;\n\tchange: TodoChange;\n}\n\n/**\n * Pure patch application: validates every runtime input (tool args can be\n * tampered after schema validation), throws on any invalid call, and never\n * mutates the input state. Application order is delete, then update, then\n * create, so a delete in the same call frees capacity for the create.\n */\nexport function applyTodoPatch(before: TodoState, params: TodoParams): TodoPatch {\n\tif (!isRecord(params)) throw new Error(\"todo params must be an object\");\n\tfor (const key of Object.keys(params)) {\n\t\tif (!GROUP_FIELDS.has(key)) throw new Error(`unknown todo field \"${key}\"; valid fields: create, update, delete`);\n\t}\n\n\t// Everything above the apply phase is validation: any throw leaves the\n\t// caller's state untouched.\n\tconst createEntries = readCreateEntries(params.create);\n\tconst updateEntries = readUpdateEntries(params.update);\n\tconst deleteIds = readDeleteIds(params.delete);\n\n\t// Conflicts: one edit per task per call, and a task cannot be both edited\n\t// and removed in the same call.\n\tconst updatedIds = new Set<number>();\n\tfor (const entry of updateEntries) {\n\t\tif (updatedIds.has(entry.id)) throw new Error(`#${entry.id} appears more than once in update`);\n\t\tupdatedIds.add(entry.id);\n\t}\n\tconst deleteSet = new Set(deleteIds);\n\tfor (const entry of updateEntries) {\n\t\tif (deleteSet.has(entry.id)) throw new Error(`#${entry.id} cannot be in both update and delete`);\n\t}\n\n\t// At most one activation per call: more than one is a real contradiction,\n\t// since a single task can be in_progress at any time.\n\tconst activations: string[] = [];\n\tcreateEntries.forEach((entry, index) => {\n\t\tif (entry.status === \"in_progress\") activations.push(`create[${index}]`);\n\t});\n\tfor (const entry of updateEntries) {\n\t\tif (entry.status === \"in_progress\") activations.push(`#${entry.id}`);\n\t}\n\tif (activations.length > 1) {\n\t\tthrow new Error(`at most one task may be set in_progress per call; got ${activations.join(\" and \")}`);\n\t}\n\n\tconst byId = new Map(before.items.map((item) => [item.id, item]));\n\tfor (const entry of updateEntries) {\n\t\tif (!byId.has(entry.id)) throw new Error(`#${entry.id} not found; ${currentIdsLabel(before)}`);\n\t}\n\n\tif (createEntries.length > 0) {\n\t\tif (!Number.isSafeInteger(before.nextId) || before.nextId < 1) throw new Error(\"next id is invalid\");\n\t\tif (before.nextId > Number.MAX_SAFE_INTEGER - createEntries.length) throw new Error(\"next id is exhausted\");\n\t}\n\n\t// --- Apply: delete -------------------------------------------------------\n\tconst deleted: Array<{ id: number; subject: string }> = [];\n\tconst absent: number[] = [];\n\tfor (const id of dedupeIds(deleteIds)) {\n\t\tconst item = byId.get(id);\n\t\tif (item) deleted.push({ id: item.id, subject: item.subject });\n\t\telse absent.push(id);\n\t}\n\tlet items = before.items.filter((item) => !deleteSet.has(item.id));\n\n\t// --- Apply: update -------------------------------------------------------\n\tif (updateEntries.length > 0) {\n\t\tconst entriesById = new Map(updateEntries.map((entry) => [entry.id, entry]));\n\t\titems = items.map((item) => {\n\t\t\tconst entry = entriesById.get(item.id);\n\t\t\tif (!entry) return item;\n\t\t\tconst next: TodoItem = {\n\t\t\t\tid: item.id,\n\t\t\t\tsubject: entry.subject ?? item.subject,\n\t\t\t\tdescription: entry.description ?? item.description,\n\t\t\t\tstatus: entry.status ?? item.status,\n\t\t\t};\n\t\t\treturn next;\n\t\t});\n\t}\n\n\t// --- Apply: create -------------------------------------------------------\n\tconst created: number[] = [];\n\tif (createEntries.length > 0) {\n\t\tconst newItems = createEntries.map((entry, index) => {\n\t\t\tconst item: TodoItem = {\n\t\t\t\tid: before.nextId + index,\n\t\t\t\tsubject: entry.subject,\n\t\t\t\tdescription: entry.description,\n\t\t\t\tstatus: entry.status ?? \"pending\",\n\t\t\t};\n\t\t\treturn item;\n\t\t});\n\t\tfor (const item of newItems) created.push(item.id);\n\t\titems = [...items, ...newItems];\n\t}\n\n\t// --- Single in_progress: the one task this call activates demotes the rest.\n\tlet demotedId: number | undefined;\n\tlet activatedId: number | undefined;\n\tfor (const entry of updateEntries) {\n\t\tif (entry.status === \"in_progress\") activatedId = entry.id;\n\t}\n\tif (activatedId === undefined) {\n\t\tcreateEntries.forEach((entry, index) => {\n\t\t\tif (entry.status === \"in_progress\") activatedId = before.nextId + index;\n\t\t});\n\t}\n\tif (activatedId !== undefined) {\n\t\tconst demoted = items.find((item) => item.id !== activatedId && item.status === \"in_progress\");\n\t\tif (demoted) {\n\t\t\tdemotedId = demoted.id;\n\t\t\titems = items.map((item) => (item.id === demoted.id ? { ...item, status: \"pending\" as const } : item));\n\t\t}\n\t}\n\n\t// --- Capacity: completed tasks are reclaimed oldest-first before a call\n\t// may fail for space; only a list that stays over the cap is rejected.\n\t// Tasks this call created or updated are never reclaimed: silently dropping\n\t// a task would be confusing when the same result reports it as touched.\n\tconst evicted: Array<{ id: number; subject: string }> = [];\n\tif (items.length > TODO_MAX_ITEMS) {\n\t\tlet overflow = items.length - TODO_MAX_ITEMS;\n\t\tconst evictIds = new Set<number>();\n\t\tconst touched = new Set<number>([...created, ...updatedIds]);\n\t\tconst completedOldestFirst = items\n\t\t\t.filter((item) => item.status === \"completed\" && !touched.has(item.id))\n\t\t\t.sort((first, second) => first.id - second.id);\n\t\tfor (const item of completedOldestFirst) {\n\t\t\tif (overflow <= 0) break;\n\t\t\tevictIds.add(item.id);\n\t\t\tevicted.push({ id: item.id, subject: item.subject });\n\t\t\toverflow--;\n\t\t}\n\t\tif (overflow > 0) {\n\t\t\tconst completedIds = before.items.filter((item) => item.status === \"completed\").map((item) => `#${item.id}`);\n\t\t\tthrow new Error(\n\t\t\t\t`at most ${TODO_MAX_ITEMS} tasks; complete or delete some first. Patch not applied. Tasks created or updated in this call are not reclaimed. ` +\n\t\t\t\t\t`Delete existing tasks in the same patch to free space (remove those ids from update), or complete tasks in a separate call before creating more. ` +\n\t\t\t\t\t`Completed ids before this call: ${completedIds.join(\", \") || \"none\"}.`,\n\t\t\t);\n\t\t}\n\t\titems = items.filter((item) => !evictIds.has(item.id));\n\t}\n\n\t// Report transitions only after activation and capacity have settled the snapshot.\n\tconst updated = items\n\t\t.filter((item) => updatedIds.has(item.id))\n\t\t.map((item) => ({\n\t\t\tid: item.id,\n\t\t\tfrom: byId.get(item.id)!.status,\n\t\t\tto: item.status,\n\t\t}));\n\tconst change: TodoChange = { created, updated, deleted, absent, evicted };\n\tif (demotedId !== undefined) change.demotedId = demotedId;\n\treturn { state: { items, nextId: before.nextId + created.length }, change };\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 patch = applyTodoPatch(state, params);\n\t\t\tconst details = buildTodoDetails(patch.change, patch.state);\n\t\t\tstate = patch.state;\n\t\t\treturn details;\n\t\t},\n\t};\n}\n\n/**\n * Validate an external v3 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 v3 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 v3 todo snapshot from a branch, scanning tail to\n * head so a malformed latest snapshot falls back to an earlier valid one.\n * Older schema versions (v1/v2) are ignored: restoring a session written\n * before v3 starts from an empty list.\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 v3 snapshot.\n\t\t}\n\t}\n\treturn cloneTodoState(EMPTY_TODO_STATE);\n}\n"]}
|
|
@@ -10,7 +10,7 @@ import { type TodoChange, type TodoParams, type TodoState, type TodoStatus } fro
|
|
|
10
10
|
export declare const STATUS_MARK: Record<TodoStatus, string>;
|
|
11
11
|
/** True while any open task exists; the widget is registered only in that case. */
|
|
12
12
|
export declare function hasOpenTodos(state: TodoState): boolean;
|
|
13
|
-
/** One-line widget: `Todos 2/6 · [>] #4 s [ ] #5 s +N more
|
|
13
|
+
/** One-line widget: `Todos 2/6 · [>] #4 s [ ] #5 s +N more`; only hidden open tasks count in the overflow. */
|
|
14
14
|
export declare function renderWidgetLine(state: TodoState, theme: Theme, width: number): string[];
|
|
15
15
|
/** `Todos: X in progress, Y pending, Z completed` header plus two-line tasks. */
|
|
16
16
|
declare function formatTodoList(state: TodoState): string;
|
|
@@ -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;
|
|
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;AAsBD,gHAAgH;AAChH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAwDxF;AAID,iFAAiF;AACjF,iBAAS,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAYhD;AAED,yFAAyF;AACzF,eAAO,MAAM,iBAAiB,uBAAiB,CAAC;AAUhD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CA+B9E;AASD,KAAK,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;AAkR/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;AAiID,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"}
|
|
@@ -49,16 +49,7 @@ function widgetLine(header, segments, overflow) {
|
|
|
49
49
|
const body = [...segments, ...(overflow ? [overflow] : [])].join(WIDGET_ITEM_SEPARATOR);
|
|
50
50
|
return body ? `${header}${WIDGET_HEADER_SEPARATOR}${body}` : header;
|
|
51
51
|
}
|
|
52
|
-
/**
|
|
53
|
-
function widgetOverflowLong(remaining, counts) {
|
|
54
|
-
const parts = [
|
|
55
|
-
counts.active > 0 ? `${counts.active} active` : "",
|
|
56
|
-
counts.pending > 0 ? `${counts.pending} pending` : "",
|
|
57
|
-
counts.completed > 0 ? `${counts.completed} completed` : "",
|
|
58
|
-
].filter(Boolean);
|
|
59
|
-
return `+${remaining} more${parts.length ? ` (${parts.join(", ")})` : ""}`;
|
|
60
|
-
}
|
|
61
|
-
/** One-line widget: `Todos 2/6 · [>] #4 s [ ] #5 s +N more (…)`; completed tasks are hidden but counted in the overflow. */
|
|
52
|
+
/** One-line widget: `Todos 2/6 · [>] #4 s [ ] #5 s +N more`; only hidden open tasks count in the overflow. */
|
|
62
53
|
export function renderWidgetLine(state, theme, width) {
|
|
63
54
|
const safeWidth = Math.max(1, width);
|
|
64
55
|
const items = state.items;
|
|
@@ -70,25 +61,14 @@ export function renderWidgetLine(state, theme, width) {
|
|
|
70
61
|
const total = items.length;
|
|
71
62
|
const completed = items.filter((item) => item.status === "completed").length;
|
|
72
63
|
const header = `${theme.fg("accent", "Todos")} ${theme.fg("dim", `${completed}/${total}`)}`;
|
|
73
|
-
const counts = widgetCounts(state);
|
|
74
64
|
const shown = [];
|
|
75
65
|
let overflow = "";
|
|
76
|
-
//
|
|
77
|
-
// the short `+N more` form otherwise, undefined when even that overflows.
|
|
66
|
+
// Count only open tasks not shown by the trial segments.
|
|
78
67
|
const bestOverflow = (trial) => {
|
|
79
|
-
const remaining =
|
|
68
|
+
const remaining = candidates.length - trial.length;
|
|
80
69
|
const segments = trial.map((entry) => widgetSegment(entry.item, entry.subject, theme));
|
|
81
|
-
const activeShown = trial.some((entry) => entry.item.status === "in_progress") ? 1 : 0;
|
|
82
|
-
const hidden = {
|
|
83
|
-
active: counts.active - activeShown,
|
|
84
|
-
pending: counts.pending - (trial.length - activeShown),
|
|
85
|
-
completed: counts.completed,
|
|
86
|
-
};
|
|
87
70
|
if (remaining <= 0)
|
|
88
71
|
return visibleWidth(widgetLine(header, segments, "")) <= safeWidth ? "" : undefined;
|
|
89
|
-
const long = theme.fg("dim", widgetOverflowLong(remaining, hidden));
|
|
90
|
-
if (visibleWidth(widgetLine(header, segments, long)) <= safeWidth)
|
|
91
|
-
return long;
|
|
92
72
|
const short = theme.fg("dim", `+${remaining} more`);
|
|
93
73
|
return visibleWidth(widgetLine(header, segments, short)) <= safeWidth ? short : undefined;
|
|
94
74
|
};
|
|
@@ -112,7 +92,7 @@ export function renderWidgetLine(state, theme, width) {
|
|
|
112
92
|
}
|
|
113
93
|
if (candidate.status !== "in_progress")
|
|
114
94
|
break;
|
|
115
|
-
const remaining =
|
|
95
|
+
const remaining = candidates.length - shown.length - 1;
|
|
116
96
|
const suffix = remaining > 0 ? `${WIDGET_ITEM_SEPARATOR}+${remaining} more` : "";
|
|
117
97
|
const prefix = `${header}${WIDGET_HEADER_SEPARATOR}${widgetSegment(candidate, "", theme)}${suffix}`;
|
|
118
98
|
const available = safeWidth - visibleWidth(prefix);
|