pi-harness-runtime 0.10.21 → 0.10.22
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
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.10.22](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v0.10.14...v0.10.22) (2026-08-09)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* align TS formatting with main (remove 3-line logError) ([2515ad5](https://github.com/ManotLuijiu/pi-harness-runtime/commit/2515ad54f43f0566123c686d3ec4f92ad363ea13))
|
|
11
|
+
* correct import paths for notification-center dist files ([f248722](https://github.com/ManotLuijiu/pi-harness-runtime/commit/f24872240c07bf115f69530a3bdabedf73e3c858))
|
|
12
|
+
* handle array/object content in pi-usage-status build detection ([68b07a8](https://github.com/ManotLuijiu/pi-harness-runtime/commit/68b07a8e8167a95ab1b519782a07ec3a582eec5a))
|
|
13
|
+
* skip publish-time scripts in release workflow ([b385148](https://github.com/ManotLuijiu/pi-harness-runtime/commit/b38514835dc3f6fd717ca8c71dbb6d131de4887f))
|
|
14
|
+
* suppress noisy stack traces in harness agents ([34bbe98](https://github.com/ManotLuijiu/pi-harness-runtime/commit/34bbe98f59e740fcfcd8622f1dcc09c379f6f3df))
|
|
15
|
+
* **todo-bd-sync:** disable auto-injection completely - was causing noisy output ([699d6de](https://github.com/ManotLuijiu/pi-harness-runtime/commit/699d6de5e7f3b062799a0f791b386d1ecd452b00))
|
|
16
|
+
* **todo-bd-sync:** silence all console output - no startup warnings ([2d29bcf](https://github.com/ManotLuijiu/pi-harness-runtime/commit/2d29bcf51b25fe1b1253aa965e370852f3cae289))
|
|
17
|
+
|
|
5
18
|
### [0.10.21](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v0.10.14...v0.10.21) (2026-08-08)
|
|
6
19
|
|
|
7
20
|
|
package/package.json
CHANGED
|
@@ -1,372 +1,5 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
|
-
|
|
4
|
-
// packages/todo-bd-sync/src/detector.js
|
|
5
|
-
import { execSync } from "node:child_process";
|
|
6
|
-
import { existsSync } from "node:fs";
|
|
7
|
-
import { join } from "node:path";
|
|
8
|
-
import { homedir } from "node:os";
|
|
9
|
-
function isRpivTodoInstalled() {
|
|
10
|
-
try {
|
|
11
|
-
const output = execSync("npm list -g @juicesharp/rpiv-todo 2>/dev/null || echo 'NOT_FOUND'", {
|
|
12
|
-
encoding: "utf8",
|
|
13
|
-
timeout: 5000
|
|
14
|
-
});
|
|
15
|
-
return output.includes("@juicesharp/rpiv-todo") && !output.includes("NOT_FOUND");
|
|
16
|
-
} catch {
|
|
17
|
-
return false;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
function isRpivTodoLoaded() {
|
|
21
|
-
const extensionsDir = join(homedir(), ".pi", "agent", "extensions");
|
|
22
|
-
const possiblePaths = [
|
|
23
|
-
join(extensionsDir, "rpiv-todo"),
|
|
24
|
-
join(extensionsDir, "@juicesharp", "rpiv-todo"),
|
|
25
|
-
join(extensionsDir, "node_modules", "@juicesharp", "rpiv-todo")
|
|
26
|
-
];
|
|
27
|
-
for (const path of possiblePaths) {
|
|
28
|
-
if (existsSync(path)) {
|
|
29
|
-
return true;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
try {
|
|
33
|
-
__require.resolve("@juicesharp/rpiv-todo");
|
|
34
|
-
return true;
|
|
35
|
-
} catch {}
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
function getRpivTodoVersion() {
|
|
39
|
-
try {
|
|
40
|
-
const output = execSync(`npm list -g @juicesharp/rpiv-todo --json 2>/dev/null | grep '"version"' | head -1`, { encoding: "utf8", timeout: 5000 });
|
|
41
|
-
const match = output.match(/"version":\s*"([^"]+)"/);
|
|
42
|
-
return match ? match[1] : null;
|
|
43
|
-
} catch {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
function isBdInstalled() {
|
|
48
|
-
try {
|
|
49
|
-
const output = execSync("which bd 2>/dev/null || echo 'NOT_FOUND'", {
|
|
50
|
-
encoding: "utf8",
|
|
51
|
-
timeout: 5000
|
|
52
|
-
});
|
|
53
|
-
return output.includes("bd") && !output.includes("NOT_FOUND");
|
|
54
|
-
} catch {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
function isBdInitialized(cwd) {
|
|
59
|
-
const projectDir = cwd || process.cwd();
|
|
60
|
-
const beadsDir = join(projectDir, ".beads");
|
|
61
|
-
return existsSync(beadsDir);
|
|
62
|
-
}
|
|
63
|
-
function getBdVersion() {
|
|
64
|
-
try {
|
|
65
|
-
const output = execSync("bd --version 2>/dev/null || echo 'unknown'", {
|
|
66
|
-
encoding: "utf8",
|
|
67
|
-
timeout: 5000
|
|
68
|
-
});
|
|
69
|
-
return output.trim().replace("bd version ", "");
|
|
70
|
-
} catch {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
function getDependencyStatus(cwd) {
|
|
75
|
-
const installed = isBdInstalled();
|
|
76
|
-
return {
|
|
77
|
-
rpivTodo: {
|
|
78
|
-
installed: isRpivTodoInstalled(),
|
|
79
|
-
version: getRpivTodoVersion(),
|
|
80
|
-
loaded: isRpivTodoLoaded()
|
|
81
|
-
},
|
|
82
|
-
bd: {
|
|
83
|
-
installed,
|
|
84
|
-
version: installed ? getBdVersion() : null,
|
|
85
|
-
initialized: installed ? isBdInitialized(cwd) : false,
|
|
86
|
-
installUrl: "https://github.com/gastownhall/beads"
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// packages/todo-bd-sync/src/sync.js
|
|
92
|
-
import { execSync as execSync2 } from "node:child_process";
|
|
93
|
-
|
|
94
|
-
// packages/todo-bd-sync/src/types.js
|
|
95
|
-
class IdMappingRegistry {
|
|
96
|
-
mappings = new Map;
|
|
97
|
-
bdMappings = new Map;
|
|
98
|
-
set(todoId, bdId) {
|
|
99
|
-
const now = Date.now();
|
|
100
|
-
const mapping = {
|
|
101
|
-
todoId,
|
|
102
|
-
bdId,
|
|
103
|
-
createdAt: now,
|
|
104
|
-
lastSync: now
|
|
105
|
-
};
|
|
106
|
-
this.mappings.set(todoId, mapping);
|
|
107
|
-
this.bdMappings.set(bdId, todoId);
|
|
108
|
-
}
|
|
109
|
-
getByTodoId(todoId) {
|
|
110
|
-
return this.mappings.get(todoId);
|
|
111
|
-
}
|
|
112
|
-
getByBdId(bdId) {
|
|
113
|
-
const todoId = this.bdMappings.get(bdId);
|
|
114
|
-
return todoId !== undefined ? this.mappings.get(todoId) : undefined;
|
|
115
|
-
}
|
|
116
|
-
hasTodoId(todoId) {
|
|
117
|
-
return this.mappings.has(todoId);
|
|
118
|
-
}
|
|
119
|
-
hasBdId(bdId) {
|
|
120
|
-
return this.bdMappings.has(bdId);
|
|
121
|
-
}
|
|
122
|
-
updateLastSync(todoId) {
|
|
123
|
-
const mapping = this.mappings.get(todoId);
|
|
124
|
-
if (mapping) {
|
|
125
|
-
mapping.lastSync = Date.now();
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
delete(todoId) {
|
|
129
|
-
const mapping = this.mappings.get(todoId);
|
|
130
|
-
if (mapping) {
|
|
131
|
-
this.bdMappings.delete(mapping.bdId);
|
|
132
|
-
this.mappings.delete(todoId);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
getAll() {
|
|
136
|
-
return Array.from(this.mappings.values());
|
|
137
|
-
}
|
|
138
|
-
clear() {
|
|
139
|
-
this.mappings.clear();
|
|
140
|
-
this.bdMappings.clear();
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// packages/todo-bd-sync/src/sync.js
|
|
145
|
-
var mappingRegistry = new IdMappingRegistry;
|
|
146
|
-
function execBdCommand(command) {
|
|
147
|
-
try {
|
|
148
|
-
return execSync2(command, {
|
|
149
|
-
encoding: "utf8",
|
|
150
|
-
timeout: 1e4,
|
|
151
|
-
cwd: process.cwd()
|
|
152
|
-
});
|
|
153
|
-
} catch (error) {
|
|
154
|
-
const err = error;
|
|
155
|
-
return err.stderr || err.message || "";
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
function getOpenBdIssues() {
|
|
159
|
-
try {
|
|
160
|
-
const output = execBdCommand("bd ready --json");
|
|
161
|
-
const issues = JSON.parse(output);
|
|
162
|
-
return issues.map((issue) => ({
|
|
163
|
-
id: issue.id,
|
|
164
|
-
title: issue.title,
|
|
165
|
-
status: issue.status,
|
|
166
|
-
priority: issue.priority,
|
|
167
|
-
createdAt: issue.created_at,
|
|
168
|
-
updatedAt: issue.updated_at
|
|
169
|
-
}));
|
|
170
|
-
} catch {
|
|
171
|
-
return [];
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// packages/todo-bd-sync/src/task-analyzer.js
|
|
176
|
-
var COMPLEX_KEYWORDS = [
|
|
177
|
-
"complicated",
|
|
178
|
-
"complex",
|
|
179
|
-
"tricky",
|
|
180
|
-
"difficult",
|
|
181
|
-
"refactor",
|
|
182
|
-
"architecture",
|
|
183
|
-
"design",
|
|
184
|
-
"implement from scratch",
|
|
185
|
-
"rewrite",
|
|
186
|
-
"investigate",
|
|
187
|
-
"debug",
|
|
188
|
-
"fix the bug",
|
|
189
|
-
"performance"
|
|
190
|
-
];
|
|
191
|
-
var RESEARCH_KEYWORDS = [
|
|
192
|
-
"search",
|
|
193
|
-
"look up",
|
|
194
|
-
"find",
|
|
195
|
-
"research",
|
|
196
|
-
"check",
|
|
197
|
-
"verify",
|
|
198
|
-
"how to",
|
|
199
|
-
"best practice",
|
|
200
|
-
"compare",
|
|
201
|
-
"evaluate",
|
|
202
|
-
"review"
|
|
203
|
-
];
|
|
204
|
-
var SUBTASK_KEYWORDS = [
|
|
205
|
-
"also",
|
|
206
|
-
"plus",
|
|
207
|
-
"and also",
|
|
208
|
-
"while you're at it",
|
|
209
|
-
"on top of that",
|
|
210
|
-
"additionally",
|
|
211
|
-
"another thing",
|
|
212
|
-
"don't forget",
|
|
213
|
-
"should also"
|
|
214
|
-
];
|
|
215
|
-
function analyzeTaskSignals(userMessage) {
|
|
216
|
-
const lower = userMessage.toLowerCase();
|
|
217
|
-
const actionVerbs = [
|
|
218
|
-
"create",
|
|
219
|
-
"build",
|
|
220
|
-
"implement",
|
|
221
|
-
"design",
|
|
222
|
-
"setup",
|
|
223
|
-
"configure",
|
|
224
|
-
"migrate",
|
|
225
|
-
"convert",
|
|
226
|
-
"refactor",
|
|
227
|
-
"optimize",
|
|
228
|
-
"fix",
|
|
229
|
-
"update",
|
|
230
|
-
"add",
|
|
231
|
-
"remove",
|
|
232
|
-
"delete",
|
|
233
|
-
"modify",
|
|
234
|
-
"change",
|
|
235
|
-
"replace"
|
|
236
|
-
];
|
|
237
|
-
const stepCount = Math.max(1, actionVerbs.filter((v) => lower.includes(v)).length);
|
|
238
|
-
const filePatterns = /[\w-]+\.(ts|js|py|json|md|yaml|yml|tsx|jsx|html|css|sql)/g;
|
|
239
|
-
const fileMatches = userMessage.match(filePatterns) || [];
|
|
240
|
-
const explicitFiles = fileMatches.length;
|
|
241
|
-
const dirPatterns = /(?:src|lib|packages|apps|components|hooks|utils|api)\/[\w/-]+/g;
|
|
242
|
-
const dirMatches = userMessage.match(dirPatterns) || [];
|
|
243
|
-
const multiTaskIndicator = (lower.match(/and also|also|\+/g) || []).length;
|
|
244
|
-
const estimatedFiles = Math.max(1, explicitFiles + dirMatches.length + multiTaskIndicator);
|
|
245
|
-
return {
|
|
246
|
-
stepCount,
|
|
247
|
-
fileCount: estimatedFiles,
|
|
248
|
-
needsResearch: RESEARCH_KEYWORDS.some((k) => lower.includes(k)),
|
|
249
|
-
createsFiles: lower.includes("create") || lower.includes("add") || lower.includes("new"),
|
|
250
|
-
explicitlyComplex: COMPLEX_KEYWORDS.some((k) => lower.includes(k)),
|
|
251
|
-
likelySubtasks: SUBTASK_KEYWORDS.some((k) => lower.includes(k)) || multiTaskIndicator >= 2
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
function decideAutoTodo(userMessage, options = {}) {
|
|
255
|
-
const signals = analyzeTaskSignals(userMessage);
|
|
256
|
-
const pendingTasks = getOpenBdIssues().filter((i) => i.status !== "closed");
|
|
257
|
-
const pendingCount = pendingTasks.length;
|
|
258
|
-
const simplePatterns = [
|
|
259
|
-
/^simply\s/i,
|
|
260
|
-
/^just\s/i,
|
|
261
|
-
/^quick\s/i,
|
|
262
|
-
/^can you\s+(grep|find|cat|ls|echo)/i,
|
|
263
|
-
/^(grep|find|cat|ls)\s+[\w.-]+/i,
|
|
264
|
-
/^what('s| is) the\s+\w+\s+\?$/i,
|
|
265
|
-
/^how do i\s+\w+\s*\?$/i
|
|
266
|
-
];
|
|
267
|
-
if (simplePatterns.some((p) => p.test(userMessage.trim()))) {
|
|
268
|
-
return {
|
|
269
|
-
shouldCreate: false,
|
|
270
|
-
reason: "Simple request (lookup/one-liner)",
|
|
271
|
-
confidence: "high",
|
|
272
|
-
skipReason: "Task is too simple to warrant tracking"
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
const isTrivial = signals.stepCount === 1 && signals.fileCount <= 1 && !signals.needsResearch && !signals.createsFiles && !signals.explicitlyComplex && pendingCount === 0 && !signals.likelySubtasks;
|
|
276
|
-
if (isTrivial) {
|
|
277
|
-
return {
|
|
278
|
-
shouldCreate: false,
|
|
279
|
-
reason: "Trivial request (single action)",
|
|
280
|
-
confidence: "high",
|
|
281
|
-
skipReason: "Task is trivial"
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
if (options.forceMode) {
|
|
285
|
-
return {
|
|
286
|
-
shouldCreate: true,
|
|
287
|
-
reason: "Force mode enabled",
|
|
288
|
-
confidence: "high"
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
if (options.skipMode) {
|
|
292
|
-
return {
|
|
293
|
-
shouldCreate: false,
|
|
294
|
-
reason: "Skip mode enabled",
|
|
295
|
-
confidence: "high",
|
|
296
|
-
skipReason: "User requested skip"
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
const reasons = [];
|
|
300
|
-
if (signals.explicitlyComplex) {
|
|
301
|
-
reasons.push("explicitly complex");
|
|
302
|
-
}
|
|
303
|
-
if (signals.stepCount >= 2) {
|
|
304
|
-
reasons.push(`${signals.stepCount} steps implied`);
|
|
305
|
-
}
|
|
306
|
-
if (signals.fileCount >= 2) {
|
|
307
|
-
reasons.push(`${signals.fileCount} files involved`);
|
|
308
|
-
}
|
|
309
|
-
if (signals.needsResearch) {
|
|
310
|
-
reasons.push("needs research");
|
|
311
|
-
}
|
|
312
|
-
if (signals.createsFiles) {
|
|
313
|
-
reasons.push("creates files");
|
|
314
|
-
}
|
|
315
|
-
if (signals.likelySubtasks) {
|
|
316
|
-
reasons.push("likely has subtasks");
|
|
317
|
-
}
|
|
318
|
-
if (pendingCount >= 1) {
|
|
319
|
-
reasons.push(`${pendingCount} pending tasks`);
|
|
320
|
-
}
|
|
321
|
-
if (reasons.length === 0) {
|
|
322
|
-
reasons.push("multi-step task detected");
|
|
323
|
-
}
|
|
324
|
-
const shouldCreate = reasons.length >= 1 || pendingCount >= 1;
|
|
325
|
-
return {
|
|
326
|
-
shouldCreate,
|
|
327
|
-
reason: reasons.join(", "),
|
|
328
|
-
confidence: reasons.length >= 2 ? "high" : "medium"
|
|
329
|
-
};
|
|
330
|
-
}
|
|
331
|
-
|
|
332
1
|
// packages/todo-bd-sync/src/extension.ts
|
|
333
|
-
function registerTodoBdSync(
|
|
334
|
-
const deps = getDependencyStatus();
|
|
335
|
-
if (!deps.bd.installed || !deps.bd.initialized) {
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
pi.on("input", (event) => {
|
|
339
|
-
if (event.source !== "interactive") {
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
const text = event.text.trim();
|
|
343
|
-
if (!text || text.length < 5) {
|
|
344
|
-
return;
|
|
345
|
-
}
|
|
346
|
-
const decision = decideAutoTodo(text);
|
|
347
|
-
if (decision.shouldCreate) {
|
|
348
|
-
const hasExplicitTodo = text.toLowerCase().includes("use the todo") || text.toLowerCase().includes("add to todo") || text.toLowerCase().includes("track as todo") || text.toLowerCase().includes("todo list") || text.toLowerCase().includes("create todo");
|
|
349
|
-
if (!hasExplicitTodo) {
|
|
350
|
-
const injection = `
|
|
351
|
-
|
|
352
|
-
IMPORTANT: Use the \`todo\` tool to track this task:
|
|
353
|
-
1. Create a todo item with subject: "${text.slice(0, 80)}${text.length > 80 ? "..." : ""}"
|
|
354
|
-
2. Mark it as in_progress
|
|
355
|
-
3. Track your progress as you work
|
|
356
|
-
|
|
357
|
-
\`\`\`json
|
|
358
|
-
{"action": "create", "subject": "${text.slice(0, 80)}${text.length > 80 ? "..." : ""}", "activeForm": "working on task"}
|
|
359
|
-
\`\`\`
|
|
360
|
-
`;
|
|
361
|
-
return {
|
|
362
|
-
action: "transform",
|
|
363
|
-
text: text + injection
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
return;
|
|
368
|
-
});
|
|
369
|
-
}
|
|
2
|
+
function registerTodoBdSync(_pi) {}
|
|
370
3
|
function todoBdSyncExtension(pi) {
|
|
371
4
|
registerTodoBdSync(pi);
|
|
372
5
|
}
|
|
@@ -1,85 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* todo-bd-sync extension entry point
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* 2. Auto-injects todo tool call when task is complex
|
|
7
|
-
* 3. Provides two-way sync between rpiv-todo and bd (via rpiv-todo)
|
|
4
|
+
* NOTE: Auto-injection disabled - was causing noisy output.
|
|
5
|
+
* Only provides dependency detection status.
|
|
8
6
|
*/
|
|
9
7
|
|
|
10
|
-
import type {
|
|
11
|
-
ExtensionAPI,
|
|
12
|
-
InputEvent,
|
|
13
|
-
InputEventResult,
|
|
14
|
-
} from "@earendil-works/pi-coding-agent";
|
|
15
|
-
import { getDependencyStatus } from "./detector.js";
|
|
16
|
-
import { decideAutoTodo } from "./task-analyzer.js";
|
|
8
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
17
9
|
|
|
18
10
|
/**
|
|
19
11
|
* Register the todo-bd-sync extension
|
|
12
|
+
*
|
|
13
|
+
* NOTE: Auto-injection disabled - was causing issues with bd working.
|
|
14
|
+
* The todo tool call injection has been removed.
|
|
20
15
|
*/
|
|
21
|
-
export function registerTodoBdSync(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// Silently skip if bd is not installed or initialized
|
|
25
|
-
if (!deps.bd.installed || !deps.bd.initialized) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// ── Smart Auto-Todo Injection ──────────────────────────────────────────
|
|
30
|
-
// Listen to user input and inject todo tool call when task is complex
|
|
31
|
-
|
|
32
|
-
pi.on("input", (event: InputEvent): InputEventResult | undefined => {
|
|
33
|
-
// Only process user input (not from extensions or RPC)
|
|
34
|
-
if (event.source !== "interactive") {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const text = event.text.trim();
|
|
39
|
-
if (!text || text.length < 5) {
|
|
40
|
-
return; // Skip very short inputs
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const decision = decideAutoTodo(text);
|
|
44
|
-
|
|
45
|
-
// If should create todo and phrase not already present
|
|
46
|
-
if (decision.shouldCreate) {
|
|
47
|
-
// Check if already has explicit todo instruction
|
|
48
|
-
const hasExplicitTodo =
|
|
49
|
-
text.toLowerCase().includes("use the todo") ||
|
|
50
|
-
text.toLowerCase().includes("add to todo") ||
|
|
51
|
-
text.toLowerCase().includes("track as todo") ||
|
|
52
|
-
text.toLowerCase().includes("todo list") ||
|
|
53
|
-
text.toLowerCase().includes("create todo");
|
|
54
|
-
|
|
55
|
-
if (!hasExplicitTodo) {
|
|
56
|
-
// Silently inject - no console noise
|
|
57
|
-
|
|
58
|
-
// Clearer instruction that explicitly tells LLM to use todo tool
|
|
59
|
-
// This is more direct than just adding text - it tells LLM to CALL the todo tool
|
|
60
|
-
const injection = `
|
|
61
|
-
|
|
62
|
-
IMPORTANT: Use the \`todo\` tool to track this task:
|
|
63
|
-
1. Create a todo item with subject: "${text.slice(0, 80)}${text.length > 80 ? "..." : ""}"
|
|
64
|
-
2. Mark it as in_progress
|
|
65
|
-
3. Track your progress as you work
|
|
66
|
-
|
|
67
|
-
\`\`\`json
|
|
68
|
-
{"action": "create", "subject": "${text.slice(0, 80)}${text.length > 80 ? "..." : ""}", "activeForm": "working on task"}
|
|
69
|
-
\`\`\`
|
|
70
|
-
`;
|
|
71
|
-
|
|
72
|
-
return {
|
|
73
|
-
action: "transform",
|
|
74
|
-
text: text + injection,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return;
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
// Silent startup - no console noise
|
|
16
|
+
export function registerTodoBdSync(_pi: ExtensionAPI): void {
|
|
17
|
+
// Silent - no registration, no injection, no console output
|
|
83
18
|
}
|
|
84
19
|
|
|
85
20
|
// Default export for pi extension loading
|