@masslessai/push-todo 3.6.2 → 3.6.4
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/lib/daemon.js +11 -115
- package/package.json +1 -1
package/lib/daemon.js
CHANGED
|
@@ -8,12 +8,7 @@
|
|
|
8
8
|
* Architecture:
|
|
9
9
|
* - Git branch = worktree = Claude session (1:1:1 mapping)
|
|
10
10
|
* - Uses Claude's --continue to resume sessions in worktrees
|
|
11
|
-
* -
|
|
12
|
-
*
|
|
13
|
-
* Certainty-Based Execution:
|
|
14
|
-
* - High certainty (>= 0.7): Execute immediately in standard mode
|
|
15
|
-
* - Medium certainty (0.4-0.7): Execute with --plan flag (planning mode first)
|
|
16
|
-
* - Low certainty (< 0.4): Update todo with clarification questions, skip execution
|
|
11
|
+
* - All tasks execute with bypassPermissions mode
|
|
17
12
|
*
|
|
18
13
|
* Ported from: plugins/push-todo/scripts/daemon.py
|
|
19
14
|
*/
|
|
@@ -238,57 +233,6 @@ function decryptTaskFields(task) {
|
|
|
238
233
|
return decrypted;
|
|
239
234
|
}
|
|
240
235
|
|
|
241
|
-
// ==================== Certainty Analysis ====================
|
|
242
|
-
|
|
243
|
-
let CertaintyAnalyzer = null;
|
|
244
|
-
let getExecutionMode = null;
|
|
245
|
-
|
|
246
|
-
try {
|
|
247
|
-
const certainty = await import('./certainty.js');
|
|
248
|
-
CertaintyAnalyzer = certainty.CertaintyAnalyzer;
|
|
249
|
-
getExecutionMode = certainty.getExecutionMode;
|
|
250
|
-
} catch {
|
|
251
|
-
// Certainty analysis not available
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
function analyzeTaskCertainty(task) {
|
|
255
|
-
if (!CertaintyAnalyzer) {
|
|
256
|
-
log('Certainty analysis not available, executing directly');
|
|
257
|
-
return null;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
const content = task.normalizedContent || task.normalized_content ||
|
|
261
|
-
task.content || task.summary || '';
|
|
262
|
-
const summary = task.summary;
|
|
263
|
-
const transcript = task.originalTranscript || task.original_transcript;
|
|
264
|
-
|
|
265
|
-
try {
|
|
266
|
-
const analyzer = new CertaintyAnalyzer();
|
|
267
|
-
const analysis = analyzer.analyze(content, summary, transcript);
|
|
268
|
-
|
|
269
|
-
const displayNum = task.displayNumber || task.display_number;
|
|
270
|
-
log(`Task #${displayNum} certainty: ${analysis.score} (${analysis.level})`);
|
|
271
|
-
|
|
272
|
-
if (analysis.reasons && analysis.reasons.length > 0) {
|
|
273
|
-
for (const reason of analysis.reasons.slice(0, 3)) {
|
|
274
|
-
log(` - ${reason.factor}: ${reason.explanation}`);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
return analysis;
|
|
279
|
-
} catch (e) {
|
|
280
|
-
log(`Certainty analysis failed: ${e.message}`);
|
|
281
|
-
return null;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
function determineExecutionMode(analysis) {
|
|
286
|
-
if (!analysis || !getExecutionMode) {
|
|
287
|
-
return 'immediate';
|
|
288
|
-
}
|
|
289
|
-
return getExecutionMode(analysis);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
236
|
// ==================== API ====================
|
|
293
237
|
|
|
294
238
|
function isRetryableError(error) {
|
|
@@ -813,25 +757,13 @@ function executeTask(task) {
|
|
|
813
757
|
taskId: task.id || task.todo_id || '',
|
|
814
758
|
summary,
|
|
815
759
|
status: 'running',
|
|
816
|
-
phase: '
|
|
817
|
-
detail: '
|
|
760
|
+
phase: 'starting',
|
|
761
|
+
detail: 'Starting Claude...',
|
|
818
762
|
startedAt: Date.now(),
|
|
819
763
|
gitRemote
|
|
820
764
|
});
|
|
821
765
|
|
|
822
|
-
log(`
|
|
823
|
-
|
|
824
|
-
// Analyze certainty
|
|
825
|
-
const analysis = analyzeTaskCertainty(task);
|
|
826
|
-
let executionMode = determineExecutionMode(analysis);
|
|
827
|
-
|
|
828
|
-
log(`Task #${displayNumber} execution mode: ${executionMode}`);
|
|
829
|
-
|
|
830
|
-
// Low-certainty tasks: run in planning mode instead of blocking
|
|
831
|
-
if (executionMode === 'clarify') {
|
|
832
|
-
log(`Task #${displayNumber} low certainty - running in planning mode instead of blocking`);
|
|
833
|
-
executionMode = 'planning';
|
|
834
|
-
}
|
|
766
|
+
log(`Executing task #${displayNumber}: ${content.slice(0, 60)}...`);
|
|
835
767
|
|
|
836
768
|
// Create worktree
|
|
837
769
|
const worktreePath = createWorktree(displayNumber, projectPath);
|
|
@@ -844,38 +776,16 @@ function executeTask(task) {
|
|
|
844
776
|
taskProjectPaths.set(displayNumber, projectPath);
|
|
845
777
|
|
|
846
778
|
// Build prompt
|
|
847
|
-
|
|
848
|
-
if (executionMode === 'planning') {
|
|
849
|
-
const reasonsText = analysis?.reasons?.slice(0, 3).map(r => `- ${r.explanation}`).join('\n') || '';
|
|
850
|
-
prompt = `Work on Push task #${displayNumber}:
|
|
851
|
-
|
|
852
|
-
${content}
|
|
853
|
-
|
|
854
|
-
IMPORTANT: This task has medium certainty (score: ${analysis?.score ?? 'N/A'}).
|
|
855
|
-
Please START BY ENTERING PLAN MODE to clarify the approach before implementing.
|
|
856
|
-
|
|
857
|
-
Reasons for lower certainty:
|
|
858
|
-
${reasonsText}
|
|
859
|
-
|
|
860
|
-
After your plan is approved, implement the changes.
|
|
861
|
-
|
|
862
|
-
When you're done, the SessionEnd hook will automatically report completion to Supabase.
|
|
863
|
-
|
|
864
|
-
If you need to understand the codebase, start by reading the CLAUDE.md file if it exists.`;
|
|
865
|
-
} else {
|
|
866
|
-
prompt = `Work on Push task #${displayNumber}:
|
|
779
|
+
const prompt = `Work on Push task #${displayNumber}:
|
|
867
780
|
|
|
868
781
|
${content}
|
|
869
782
|
|
|
870
783
|
IMPORTANT: When you're done, the SessionEnd hook will automatically report completion to Supabase.
|
|
871
784
|
|
|
872
785
|
If you need to understand the codebase, start by reading the CLAUDE.md file if it exists.`;
|
|
873
|
-
}
|
|
874
786
|
|
|
875
787
|
// Update status to running
|
|
876
|
-
updateTaskStatus(displayNumber, 'running'
|
|
877
|
-
certaintyScore: analysis?.score
|
|
878
|
-
});
|
|
788
|
+
updateTaskStatus(displayNumber, 'running');
|
|
879
789
|
|
|
880
790
|
// Build Claude command
|
|
881
791
|
const allowedTools = [
|
|
@@ -889,13 +799,10 @@ If you need to understand the codebase, start by reading the CLAUDE.md file if i
|
|
|
889
799
|
const claudeArgs = [
|
|
890
800
|
'-p', prompt,
|
|
891
801
|
'--allowedTools', allowedTools,
|
|
892
|
-
'--output-format', 'json'
|
|
802
|
+
'--output-format', 'json',
|
|
803
|
+
'--permission-mode', 'bypassPermissions'
|
|
893
804
|
];
|
|
894
805
|
|
|
895
|
-
if (executionMode === 'planning') {
|
|
896
|
-
claudeArgs.push('--permission-mode', 'plan');
|
|
897
|
-
}
|
|
898
|
-
|
|
899
806
|
try {
|
|
900
807
|
const child = spawn('claude', claudeArgs, {
|
|
901
808
|
cwd: worktreePath,
|
|
@@ -912,8 +819,7 @@ If you need to understand the codebase, start by reading the CLAUDE.md file if i
|
|
|
912
819
|
task,
|
|
913
820
|
displayNumber,
|
|
914
821
|
startTime: Date.now(),
|
|
915
|
-
projectPath
|
|
916
|
-
executionMode
|
|
822
|
+
projectPath
|
|
917
823
|
};
|
|
918
824
|
|
|
919
825
|
runningTasks.set(displayNumber, taskInfo);
|
|
@@ -956,22 +862,13 @@ If you need to understand the codebase, start by reading the CLAUDE.md file if i
|
|
|
956
862
|
updateStatusFile();
|
|
957
863
|
});
|
|
958
864
|
|
|
959
|
-
const modeDesc = executionMode === 'planning' ? 'planning mode' : 'standard mode';
|
|
960
865
|
updateTaskDetail(displayNumber, {
|
|
961
866
|
phase: 'executing',
|
|
962
|
-
detail:
|
|
867
|
+
detail: 'Running Claude...',
|
|
963
868
|
claudePid: child.pid
|
|
964
869
|
});
|
|
965
870
|
|
|
966
|
-
log(`Started Claude for task #${displayNumber}
|
|
967
|
-
|
|
968
|
-
if (executionMode === 'planning') {
|
|
969
|
-
sendMacNotification(
|
|
970
|
-
`Task #${displayNumber} started (planning)`,
|
|
971
|
-
`${summary.slice(0, 60)}...`,
|
|
972
|
-
'default'
|
|
973
|
-
);
|
|
974
|
-
}
|
|
871
|
+
log(`Started Claude for task #${displayNumber} (PID: ${child.pid})`);
|
|
975
872
|
|
|
976
873
|
return taskInfo;
|
|
977
874
|
} catch (error) {
|
|
@@ -1261,7 +1158,6 @@ async function mainLoop() {
|
|
|
1261
1158
|
log(`Polling interval: ${POLL_INTERVAL / 1000}s`);
|
|
1262
1159
|
log(`Max concurrent tasks: ${MAX_CONCURRENT_TASKS}`);
|
|
1263
1160
|
log(`E2EE: ${e2eeAvailable ? 'Available' : 'Not available'}`);
|
|
1264
|
-
log(`Certainty analysis: ${CertaintyAnalyzer ? 'Available' : 'Not available'}`);
|
|
1265
1161
|
log(`Log file: ${LOG_FILE}`);
|
|
1266
1162
|
|
|
1267
1163
|
// Show registered projects
|