@trim21/personal-pi-extensions 0.0.188 → 0.0.190

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/todowrite.ts +25 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trim21/personal-pi-extensions",
3
- "version": "0.0.188",
3
+ "version": "0.0.190",
4
4
  "type": "module",
5
5
  "description": "Custom pi coding-agent extensions: bwrap sandbox, workspace guard, opencode edit, and more",
6
6
  "keywords": [
package/src/todowrite.ts CHANGED
@@ -8,9 +8,9 @@
8
8
  * priority: high | medium | low
9
9
  *
10
10
  * 状态存在工具结果 details 里(跟随会话分支),同时把任务列表渲染成
11
- * pendant.markdown(与 vision-agent 相同的 pendant 约定),每次调用都用
12
- * 完整的 markdown 列表输出对应的任务 —— 取代原 todo-pendant.ts
13
- * setWidget widget 输出方式。
11
+ * pendant.markdown(与 vision-agent 相同的 pendant 约定),并用
12
+ * ctx.ui.setWidget 在编辑器上方渲染 widget(沿用原 todo-pendant.ts
13
+ * widget 输出方式,只是任务内容多了 priority)。
14
14
  *
15
15
  * 与 pi 内置 todo 工具(create/update/list/... 动作)不同,本工具没有
16
16
  * 单条增删改动作 —— 模型每次都要传完整的 todo 列表,语义与 opencode 对齐。
@@ -114,11 +114,16 @@ export function serializeTodos(todos: readonly TodoInfo[]): string {
114
114
 
115
115
  const STATUS_MARK: Record<TodoStatus, string> = {
116
116
  pending: " ",
117
- in_progress: ">",
117
+ in_progress: " ",
118
118
  completed: "x",
119
119
  cancelled: "-",
120
120
  };
121
121
 
122
+ /** 单条任务的渲染行,pendant markdown 与 widget 共用 */
123
+ function formatTodoLine(t: TodoInfo): string {
124
+ return `- [${STATUS_MARK[t.status]}] ${t.content} \`${t.priority}\``;
125
+ }
126
+
122
127
  /**
123
128
  * 把任务列表整理成 pendant 渲染用的 markdown。
124
129
  * 每个任务一行,与 vision-agent 的 pendant.markdown 约定一致。
@@ -129,13 +134,20 @@ export function buildTodoMarkdown(todos: readonly TodoInfo[]): string {
129
134
  lines.push("", "_No todos_");
130
135
  return lines.join("\n");
131
136
  }
132
- lines.push("");
133
- for (const t of todos) {
134
- lines.push(`- [${STATUS_MARK[t.status]}] ${t.content} \`${t.priority}\``);
135
- }
137
+ lines.push("", ...todos.map((t) => formatTodoLine(t)));
136
138
  return lines.join("\n");
137
139
  }
138
140
 
141
+ /**
142
+ * widget 渲染用的任务行(沿用原 todo-pendant.ts 的 setWidget 语义):
143
+ * 过滤 cancelled(对应旧版 deleted),全部被过滤时返回 undefined 以清除 widget。
144
+ */
145
+ export function buildTodoWidgetLines(todos: readonly TodoInfo[]): string[] | undefined {
146
+ const visible = todos.filter((t) => t.status !== "cancelled");
147
+ if (visible.length === 0) return undefined;
148
+ return visible.map((t) => formatTodoLine(t));
149
+ }
150
+
139
151
  // ── extension ────────────────────────────────────────────────────────────────
140
152
 
141
153
  export default function todowrite(pi: ExtensionAPI) {
@@ -145,17 +157,19 @@ export default function todowrite(pi: ExtensionAPI) {
145
157
  description: TODOWRITE_DESCRIPTION,
146
158
  parameters: todowriteSchema,
147
159
 
148
- execute(_toolCallId, params) {
160
+ execute(_toolCallId, params, _signal, _onUpdate, ctx) {
149
161
  // 整体替换(opencode 语义)。
150
- // 纯同步逻辑,用 Promise.resolve 满足 execute Promise 返回类型。
162
+ // widget 渲染沿用原 todo-pendantsetWidget 方式:过滤 cancelled,
163
+ // 全部被过滤(含空列表)时清除 widget。
151
164
  const todos = normalizeTodos(params.todos);
165
+ ctx.ui.setWidget(TOOL_NAME, buildTodoWidgetLines(todos));
152
166
  return Promise.resolve({
153
167
  content: [{ type: "text", text: serializeTodos(todos) }],
154
168
  details: {
155
169
  todos,
156
170
  pendant: {
157
171
  markdown: buildTodoMarkdown(todos),
158
- expanded: true,
172
+ expanded: false,
159
173
  },
160
174
  },
161
175
  });