pi-harness-runtime 0.10.4 → 0.10.6

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 (82) hide show
  1. package/index.ts +24 -0
  2. package/package.json +1 -1
  3. package/packages/a2a-adapter/package.json +1 -1
  4. package/packages/auth/package.json +1 -1
  5. package/packages/autonomous-refactor/package.json +1 -1
  6. package/packages/autonomous-runtime/package.json +1 -1
  7. package/packages/cache-strategy/package.json +1 -1
  8. package/packages/capability-registry/package.json +1 -1
  9. package/packages/checkpoint/package.json +1 -1
  10. package/packages/cli-plugin-sdk/package.json +1 -1
  11. package/packages/clipboard/package.json +1 -1
  12. package/packages/code-generation/package.json +1 -1
  13. package/packages/code-review/package.json +1 -1
  14. package/packages/codex-adapter/package.json +1 -1
  15. package/packages/config-capture/package.json +23 -0
  16. package/packages/config-capture/src/index.ts +357 -0
  17. package/packages/context-compiler/package.json +1 -1
  18. package/packages/context-discovery/package.json +1 -1
  19. package/packages/context-manager/package.json +1 -1
  20. package/packages/cookie-sanitizer/package.json +1 -1
  21. package/packages/cost-optimizer/package.json +1 -1
  22. package/packages/dependency-analyzer/package.json +1 -1
  23. package/packages/django-plugin/package.json +1 -1
  24. package/packages/doc-generator/package.json +1 -1
  25. package/packages/evaluation-engine/package.json +1 -1
  26. package/packages/evaluation-runner/package.json +1 -1
  27. package/packages/event-bus/package.json +1 -1
  28. package/packages/event-store/package.json +1 -1
  29. package/packages/experience-replay/package.json +1 -1
  30. package/packages/feedback-collector/package.json +1 -1
  31. package/packages/framework-detector/package.json +1 -1
  32. package/packages/framework-plugin-sdk/package.json +1 -1
  33. package/packages/frappe-plugin/package.json +1 -1
  34. package/packages/generic-web-plugin/package.json +1 -1
  35. package/packages/health-monitor/package.json +1 -1
  36. package/packages/intent-analyzer/package.json +1 -1
  37. package/packages/laravel-plugin/package.json +1 -1
  38. package/packages/learning-engine/package.json +1 -1
  39. package/packages/mcp-adapter/package.json +1 -1
  40. package/packages/memory-engine/package.json +1 -1
  41. package/packages/model-registry/package.json +1 -1
  42. package/packages/nextjs-plugin/package.json +1 -1
  43. package/packages/notification/package.json +1 -1
  44. package/packages/observability/package.json +1 -1
  45. package/packages/performance-optimizer/package.json +1 -1
  46. package/packages/privilege-broker/package.json +1 -1
  47. package/packages/project-analyzer/package.json +1 -1
  48. package/packages/projection-engine/package.json +1 -1
  49. package/packages/prompt-compiler/package.json +1 -1
  50. package/packages/prompt-versioning/package.json +1 -1
  51. package/packages/provider-adapter-sdk/package.json +1 -1
  52. package/packages/provider-router/package.json +1 -1
  53. package/packages/provider-selector/package.json +1 -1
  54. package/packages/providers/package.json +1 -1
  55. package/packages/quota-manager/package.json +1 -1
  56. package/packages/rate-limiter/package.json +1 -1
  57. package/packages/react-vite-plugin/package.json +1 -1
  58. package/packages/release-manager/package.json +1 -1
  59. package/packages/requirement-compiler/package.json +1 -1
  60. package/packages/runtime/package.json +1 -1
  61. package/packages/scheduler/package.json +1 -1
  62. package/packages/scheduler-adapter/package.json +1 -1
  63. package/packages/session/package.json +1 -1
  64. package/packages/session-api/package.json +1 -1
  65. package/packages/session-export/package.json +1 -1
  66. package/packages/shared-context/package.json +1 -1
  67. package/packages/skill-registry/package.json +1 -1
  68. package/packages/sprint-planner/package.json +1 -1
  69. package/packages/subscription-engine/package.json +1 -1
  70. package/packages/task-compiler/package.json +1 -1
  71. package/packages/test-data-generator/package.json +1 -1
  72. package/packages/test-generator/package.json +1 -1
  73. package/packages/todo-bd-sync/package.json +1 -1
  74. package/packages/todo-bd-sync/src/extension.ts +47 -71
  75. package/packages/todo-bd-sync/src/task-analyzer.ts +266 -0
  76. package/packages/token-estimation/package.json +1 -1
  77. package/packages/token-optimizer/package.json +1 -1
  78. package/packages/tui/package.json +1 -1
  79. package/packages/types/package.json +1 -1
  80. package/packages/workflow-events/package.json +1 -1
  81. package/packages/workspace-scanner/package.json +1 -1
  82. package/packages/worktree/package.json +1 -1
@@ -0,0 +1,266 @@
1
+ /**
2
+ * Smart Auto-Todo Task Analyzer
3
+ *
4
+ * Decides when to automatically create bd issues based on:
5
+ * 1. Task complexity signals
6
+ * 2. Session state (pending task count)
7
+ *
8
+ * Philosophy:
9
+ * - Simple tasks (grep, quick edit) -> NO todo (avoid noise)
10
+ * - Complex tasks OR multiple pending tasks -> AUTO-CREATE todo
11
+ */
12
+
13
+ import { getOpenBdIssues } from "./sync.js";
14
+
15
+ // ─── Complexity Signals ─────────────────────────────────────────────────────────
16
+
17
+ interface TaskSignals {
18
+ /** Estimated number of steps required */
19
+ stepCount: number;
20
+ /** Number of files likely involved */
21
+ fileCount: number;
22
+ /** Requires research (web search, docs lookup) */
23
+ needsResearch: boolean;
24
+ /** Creates new files */
25
+ createsFiles: boolean;
26
+ /** User explicitly says task is complex */
27
+ explicitlyComplex: boolean;
28
+ /** Likely to have subtasks discovered during work */
29
+ likelySubtasks: boolean;
30
+ }
31
+
32
+ const COMPLEX_KEYWORDS = [
33
+ "complicated", "complex", "tricky", "difficult", "refactor",
34
+ "architecture", "design", "implement from scratch", "rewrite",
35
+ "investigate", "debug", "fix the bug", "performance",
36
+ ];
37
+
38
+ const RESEARCH_KEYWORDS = [
39
+ "search", "look up", "find", "research", "check", "verify",
40
+ "how to", "best practice", "compare", "evaluate", "review",
41
+ ];
42
+
43
+ const SUBTASK_KEYWORDS = [
44
+ "also", "plus", "and also", "while you're at it", "on top of that",
45
+ "additionally", "another thing", "don't forget", "should also",
46
+ ];
47
+
48
+ /**
49
+ * Analyze user request text for complexity signals
50
+ */
51
+ export function analyzeTaskSignals(userMessage: string): TaskSignals {
52
+ const lower = userMessage.toLowerCase();
53
+
54
+ // Count implied steps from action verbs
55
+ const actionVerbs = [
56
+ "create", "build", "implement", "design", "setup", "configure",
57
+ "migrate", "convert", "refactor", "optimize", "fix", "update",
58
+ "add", "remove", "delete", "modify", "change", "replace",
59
+ ];
60
+ const stepCount = Math.max(1, actionVerbs.filter(v => lower.includes(v)).length);
61
+
62
+ // Estimate file count from file paths and extensions
63
+ const filePatterns = /[\w-]+\.(ts|js|py|json|md|yaml|yml|tsx|jsx|html|css|sql)/g;
64
+ const fileMatches = userMessage.match(filePatterns) || [];
65
+ const explicitFiles = fileMatches.length;
66
+
67
+ // Check for directory patterns
68
+ const dirPatterns = /(?:src|lib|packages|apps|components|hooks|utils|api)\/[\w/-]+/g;
69
+ const dirMatches = userMessage.match(dirPatterns) || [];
70
+
71
+ // Count "and", "also", "+" for multi-task indicators
72
+ const multiTaskIndicator = (lower.match(/and also|also|\+/g) || []).length;
73
+ const estimatedFiles = Math.max(1, explicitFiles + dirMatches.length + multiTaskIndicator);
74
+
75
+ return {
76
+ stepCount,
77
+ fileCount: estimatedFiles,
78
+ needsResearch: RESEARCH_KEYWORDS.some(k => lower.includes(k)),
79
+ createsFiles: lower.includes("create") || lower.includes("add") || lower.includes("new"),
80
+ explicitlyComplex: COMPLEX_KEYWORDS.some(k => lower.includes(k)),
81
+ likelySubtasks: SUBTASK_KEYWORDS.some(k => lower.includes(k)) || multiTaskIndicator >= 2,
82
+ };
83
+ }
84
+
85
+ // ─── Decision Logic ───────────────────────────────────────────────────────────
86
+
87
+ export interface AutoTodoDecision {
88
+ shouldCreate: boolean;
89
+ reason: string;
90
+ confidence: "high" | "medium" | "low";
91
+ skipReason?: string;
92
+ }
93
+
94
+ /**
95
+ * Decide whether to auto-create a todo for the given task
96
+ */
97
+ export function decideAutoTodo(
98
+ userMessage: string,
99
+ options: {
100
+ forceMode?: boolean;
101
+ skipMode?: boolean;
102
+ } = {},
103
+ ): AutoTodoDecision {
104
+ const signals = analyzeTaskSignals(userMessage);
105
+ const pendingTasks = getOpenBdIssues().filter(i => i.status !== "closed");
106
+ const pendingCount = pendingTasks.length;
107
+
108
+ // ── Skip Conditions ────────────────────────────────────────────────────
109
+ // Never create todos for these
110
+
111
+ const simplePatterns = [
112
+ /^simply\s/i,
113
+ /^just\s/i,
114
+ /^quick\s/i,
115
+ /^can you\s+(grep|find|cat|ls|echo)/i,
116
+ /^(grep|find|cat|ls)\s+[\w.-]+/i,
117
+ /^what('s| is) the\s+\w+\s+\?$/i,
118
+ /^how do i\s+\w+\s*\?$/i,
119
+ ];
120
+
121
+ if (simplePatterns.some(p => p.test(userMessage.trim()))) {
122
+ return {
123
+ shouldCreate: false,
124
+ reason: "Simple request (lookup/one-liner)",
125
+ confidence: "high",
126
+ skipReason: "Task is too simple to warrant tracking",
127
+ };
128
+ }
129
+
130
+ // Check for single file, single action with no complexity
131
+ if (
132
+ signals.stepCount === 1 &&
133
+ signals.fileCount <= 1 &&
134
+ !signals.needsResearch &&
135
+ !signals.createsFiles &&
136
+ !signals.explicitlyComplex &&
137
+ pendingCount === 0
138
+ ) {
139
+ return {
140
+ shouldCreate: false,
141
+ reason: "Single action, single file, no research needed",
142
+ confidence: "high",
143
+ skipReason: "Task is straightforward",
144
+ };
145
+ }
146
+
147
+ // ── Force Modes ──────────────────────────────────────────────────────
148
+ if (options.forceMode) {
149
+ return {
150
+ shouldCreate: true,
151
+ reason: "Force mode enabled",
152
+ confidence: "high",
153
+ };
154
+ }
155
+
156
+ if (options.skipMode) {
157
+ return {
158
+ shouldCreate: false,
159
+ reason: "Skip mode enabled",
160
+ confidence: "high",
161
+ skipReason: "User requested skip",
162
+ };
163
+ }
164
+
165
+ // ── Auto-Create Conditions ──────────────────────────────────────────
166
+ const reasons: string[] = [];
167
+
168
+ // HIGH CONFIDENCE: Task explicitly complex
169
+ if (signals.explicitlyComplex) {
170
+ reasons.push("explicitly complex");
171
+ }
172
+
173
+ // HIGH CONFIDENCE: Multiple steps
174
+ if (signals.stepCount >= 3) {
175
+ reasons.push(`${signals.stepCount} steps implied`);
176
+ }
177
+
178
+ // HIGH CONFIDENCE: Multiple files
179
+ if (signals.fileCount >= 3) {
180
+ reasons.push(`${signals.fileCount} files involved`);
181
+ }
182
+
183
+ // MEDIUM CONFIDENCE: Research needed
184
+ if (signals.needsResearch && signals.stepCount >= 2) {
185
+ reasons.push("research + action");
186
+ }
187
+
188
+ // MEDIUM CONFIDENCE: Creates files + action
189
+ if (signals.createsFiles && signals.fileCount >= 2) {
190
+ reasons.push("creates multiple files");
191
+ }
192
+
193
+ // MEDIUM CONFIDENCE: Likely subtasks
194
+ if (signals.likelySubtasks) {
195
+ reasons.push("likely has subtasks");
196
+ }
197
+
198
+ // HIGH CONFIDENCE: Already 2+ pending tasks (session overload)
199
+ if (pendingCount >= 2) {
200
+ reasons.push(`${pendingCount} pending tasks in session`);
201
+ }
202
+
203
+ // HIGH CONFIDENCE: 3+ pending tasks
204
+ if (pendingCount >= 3) {
205
+ reasons.push("session overwhelmed (3+ pending)");
206
+ }
207
+
208
+ if (reasons.length === 0) {
209
+ return {
210
+ shouldCreate: false,
211
+ reason: "No strong complexity signals",
212
+ confidence: "low",
213
+ skipReason: "Task doesn't meet auto-create threshold",
214
+ };
215
+ }
216
+
217
+ // Need at least 2 signals OR high-pending count
218
+ const highConfidenceReasons = ["explicitly complex", "pending tasks in session", "session overwhelmed"];
219
+ const hasHighConfidence = reasons.some(r => highConfidenceReasons.some(h => r.includes(h)));
220
+ const shouldCreate = reasons.length >= 2 || hasHighConfidence || pendingCount >= 2;
221
+
222
+ return {
223
+ shouldCreate,
224
+ reason: reasons.join(", "),
225
+ confidence: hasHighConfidence ? "high" : reasons.length >= 2 ? "medium" : "low",
226
+ };
227
+ }
228
+
229
+ // ─── Quick Score ─────────────────────────────────────────────────────────────
230
+
231
+ /**
232
+ * Quick numeric score (0-100) for task complexity
233
+ * Higher = more likely to need a todo
234
+ */
235
+ export function getTaskComplexityScore(userMessage: string): number {
236
+ const signals = analyzeTaskSignals(userMessage);
237
+ const pendingTasks = getOpenBdIssues().filter(i => i.status !== "closed");
238
+
239
+ let score = 0;
240
+
241
+ // Step count (0-25)
242
+ score += Math.min(25, signals.stepCount * 8);
243
+
244
+ // File count (0-20)
245
+ score += Math.min(20, signals.fileCount * 5);
246
+
247
+ // Research needed (0-15)
248
+ if (signals.needsResearch) score += 15;
249
+
250
+ // Creates files (0-10)
251
+ if (signals.createsFiles) score += 10;
252
+
253
+ // Explicitly complex (0-20)
254
+ if (signals.explicitlyComplex) score += 20;
255
+
256
+ // Likely subtasks (0-10)
257
+ if (signals.likelySubtasks) score += 10;
258
+
259
+ // Pending task overload (0-25)
260
+ const pendingCount = pendingTasks.length;
261
+ if (pendingCount >= 3) score += 25;
262
+ else if (pendingCount >= 2) score += 15;
263
+ else if (pendingCount >= 1) score += 5;
264
+
265
+ return Math.min(100, score);
266
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/token-estimation",
3
- "version": "0.10.4",
3
+ "version": "0.10.6",
4
4
  "description": "pi-harness-runtime — token-estimation",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/token-optimizer",
3
- "version": "0.10.4",
3
+ "version": "0.10.6",
4
4
  "description": "Token Budget Optimizer — maximize prompt value within token limits (RFC-0011)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/tui",
3
- "version": "0.10.4",
3
+ "version": "0.10.6",
4
4
  "description": "pi-harness-runtime — tui",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/types",
3
- "version": "0.10.4",
3
+ "version": "0.10.6",
4
4
  "description": "Shared TypeScript types for pi-harness-runtime packages",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/workflow-events",
3
- "version": "0.10.4",
3
+ "version": "0.10.6",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/workspace-scanner",
3
- "version": "0.10.4",
3
+ "version": "0.10.6",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/worktree",
3
- "version": "0.10.4",
3
+ "version": "0.10.6",
4
4
  "description": "pi-harness-runtime — worktree",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",