@hasnaxyz/hook-checktasks 1.0.8 → 1.0.9
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/dist/cli.js +156 -31
- package/dist/hook.js +84 -21
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -93,19 +93,79 @@ function getAllTaskLists() {
|
|
|
93
93
|
return [];
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
+
function getProjectIdentifiers(cwd) {
|
|
97
|
+
const genericSegments = new Set([
|
|
98
|
+
"users",
|
|
99
|
+
"home",
|
|
100
|
+
"workspace",
|
|
101
|
+
"workspaces",
|
|
102
|
+
"projects",
|
|
103
|
+
"repos",
|
|
104
|
+
"src",
|
|
105
|
+
"lib",
|
|
106
|
+
"app",
|
|
107
|
+
"apps",
|
|
108
|
+
"packages",
|
|
109
|
+
"platform",
|
|
110
|
+
"service",
|
|
111
|
+
"services",
|
|
112
|
+
"web",
|
|
113
|
+
"api",
|
|
114
|
+
"server",
|
|
115
|
+
"client",
|
|
116
|
+
"frontend",
|
|
117
|
+
"backend",
|
|
118
|
+
"dev",
|
|
119
|
+
"development",
|
|
120
|
+
"prod",
|
|
121
|
+
"staging",
|
|
122
|
+
"tmp",
|
|
123
|
+
"temp",
|
|
124
|
+
"var",
|
|
125
|
+
"opt",
|
|
126
|
+
"usr",
|
|
127
|
+
"volumes"
|
|
128
|
+
]);
|
|
129
|
+
const segments = cwd.split("/").filter(Boolean);
|
|
130
|
+
const identifiers = [];
|
|
131
|
+
for (let i = segments.length - 1;i >= 0; i--) {
|
|
132
|
+
const seg = segments[i];
|
|
133
|
+
if (seg.length < 3)
|
|
134
|
+
continue;
|
|
135
|
+
if (genericSegments.has(seg.toLowerCase()))
|
|
136
|
+
continue;
|
|
137
|
+
if (i <= 2)
|
|
138
|
+
continue;
|
|
139
|
+
identifiers.push(seg);
|
|
140
|
+
}
|
|
141
|
+
return identifiers;
|
|
142
|
+
}
|
|
96
143
|
function getProjectTaskLists(cwd) {
|
|
97
144
|
const allLists = getAllTaskLists();
|
|
98
|
-
const
|
|
99
|
-
const
|
|
145
|
+
const identifiers = getProjectIdentifiers(cwd);
|
|
146
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
147
|
+
const namedLists = allLists.filter((list) => !uuidRegex.test(list));
|
|
148
|
+
if (namedLists.length === 0 || identifiers.length === 0)
|
|
149
|
+
return [];
|
|
150
|
+
const scored = [];
|
|
151
|
+
for (const list of namedLists) {
|
|
100
152
|
const listLower = list.toLowerCase();
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
153
|
+
let bestScore = 0;
|
|
154
|
+
for (let i = 0;i < identifiers.length; i++) {
|
|
155
|
+
const idLower = identifiers[i].toLowerCase();
|
|
156
|
+
const priorityWeight = identifiers.length - i;
|
|
157
|
+
if (listLower === idLower) {
|
|
158
|
+
bestScore = Math.max(bestScore, priorityWeight * 100);
|
|
159
|
+
} else if (listLower.startsWith(idLower + "-")) {
|
|
160
|
+
bestScore = Math.max(bestScore, priorityWeight * 10);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (bestScore > 0) {
|
|
164
|
+
scored.push({ list, score: bestScore });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
scored.sort((a, b) => b.score - a.score);
|
|
168
|
+
return scored.map((s) => s.list);
|
|
109
169
|
}
|
|
110
170
|
function getTasksFromList(listId) {
|
|
111
171
|
const tasksDir = join(homedir(), ".claude", "tasks", listId);
|
|
@@ -136,16 +196,7 @@ function run() {
|
|
|
136
196
|
if (config.enabled === false) {
|
|
137
197
|
approve();
|
|
138
198
|
}
|
|
139
|
-
let sessionName = null;
|
|
140
|
-
if (hookInput?.transcript_path) {
|
|
141
|
-
sessionName = getSessionName(hookInput.transcript_path);
|
|
142
|
-
}
|
|
143
|
-
const nameToCheck = sessionName || config.taskListId || "";
|
|
144
199
|
const keywords = config.keywords || ["dev"];
|
|
145
|
-
const matchesKeyword = keywords.some((keyword) => nameToCheck.toLowerCase().includes(keyword.toLowerCase()));
|
|
146
|
-
if (!matchesKeyword && keywords.length > 0 && nameToCheck) {
|
|
147
|
-
approve();
|
|
148
|
-
}
|
|
149
200
|
let listsToCheck = [];
|
|
150
201
|
if (config.taskListId) {
|
|
151
202
|
listsToCheck = [config.taskListId];
|
|
@@ -153,7 +204,8 @@ function run() {
|
|
|
153
204
|
const projectLists = getProjectTaskLists(cwd);
|
|
154
205
|
if (projectLists.length > 0) {
|
|
155
206
|
if (keywords.length > 0) {
|
|
156
|
-
|
|
207
|
+
const keywordMatched = projectLists.filter((list) => keywords.some((keyword) => list.toLowerCase().includes(keyword.toLowerCase())));
|
|
208
|
+
listsToCheck = keywordMatched.length > 0 ? keywordMatched : projectLists;
|
|
157
209
|
} else {
|
|
158
210
|
listsToCheck = projectLists;
|
|
159
211
|
}
|
|
@@ -162,6 +214,17 @@ function run() {
|
|
|
162
214
|
if (listsToCheck.length === 0) {
|
|
163
215
|
approve();
|
|
164
216
|
}
|
|
217
|
+
let sessionName = null;
|
|
218
|
+
if (hookInput?.transcript_path) {
|
|
219
|
+
sessionName = getSessionName(hookInput.transcript_path);
|
|
220
|
+
}
|
|
221
|
+
if (sessionName && keywords.length > 0) {
|
|
222
|
+
const sessionMatchesKeyword = keywords.some((keyword) => sessionName.toLowerCase().includes(keyword.toLowerCase()));
|
|
223
|
+
const listMatchesKeyword = config.taskListId ? keywords.some((keyword) => config.taskListId.toLowerCase().includes(keyword.toLowerCase())) : true;
|
|
224
|
+
if (!sessionMatchesKeyword && !listMatchesKeyword) {
|
|
225
|
+
approve();
|
|
226
|
+
}
|
|
227
|
+
}
|
|
165
228
|
let allPending = [];
|
|
166
229
|
let allInProgress = [];
|
|
167
230
|
let allCompleted = [];
|
|
@@ -186,7 +249,7 @@ function run() {
|
|
|
186
249
|
const prompt = `
|
|
187
250
|
STOP BLOCKED: You have ${remainingCount} tasks remaining${listInfo} (${allPending.length} pending, ${allInProgress.length} in progress, ${allCompleted.length} completed).
|
|
188
251
|
|
|
189
|
-
|
|
252
|
+
DO NOT STOP. DO NOT ASK QUESTIONS. DO NOT WAIT FOR USER INPUT.
|
|
190
253
|
|
|
191
254
|
You MUST continue working AUTONOMOUSLY until ALL tasks are completed.
|
|
192
255
|
|
|
@@ -365,19 +428,81 @@ function getAllTaskLists2() {
|
|
|
365
428
|
return [];
|
|
366
429
|
}
|
|
367
430
|
}
|
|
431
|
+
function getProjectIdentifiers2(projectPath) {
|
|
432
|
+
const genericSegments = new Set([
|
|
433
|
+
"users",
|
|
434
|
+
"home",
|
|
435
|
+
"workspace",
|
|
436
|
+
"workspaces",
|
|
437
|
+
"projects",
|
|
438
|
+
"repos",
|
|
439
|
+
"src",
|
|
440
|
+
"lib",
|
|
441
|
+
"app",
|
|
442
|
+
"apps",
|
|
443
|
+
"packages",
|
|
444
|
+
"platform",
|
|
445
|
+
"service",
|
|
446
|
+
"services",
|
|
447
|
+
"web",
|
|
448
|
+
"api",
|
|
449
|
+
"server",
|
|
450
|
+
"client",
|
|
451
|
+
"frontend",
|
|
452
|
+
"backend",
|
|
453
|
+
"dev",
|
|
454
|
+
"development",
|
|
455
|
+
"prod",
|
|
456
|
+
"staging",
|
|
457
|
+
"tmp",
|
|
458
|
+
"temp",
|
|
459
|
+
"var",
|
|
460
|
+
"opt",
|
|
461
|
+
"usr",
|
|
462
|
+
"volumes"
|
|
463
|
+
]);
|
|
464
|
+
const segments = projectPath.split("/").filter(Boolean);
|
|
465
|
+
const identifiers = [];
|
|
466
|
+
for (let i = segments.length - 1;i >= 0; i--) {
|
|
467
|
+
const seg = segments[i];
|
|
468
|
+
if (seg.length < 3)
|
|
469
|
+
continue;
|
|
470
|
+
if (genericSegments.has(seg.toLowerCase()))
|
|
471
|
+
continue;
|
|
472
|
+
if (i <= 2)
|
|
473
|
+
continue;
|
|
474
|
+
identifiers.push(seg);
|
|
475
|
+
}
|
|
476
|
+
return identifiers;
|
|
477
|
+
}
|
|
368
478
|
function getProjectTaskLists2(projectPath) {
|
|
369
479
|
const allLists = getAllTaskLists2();
|
|
370
|
-
const
|
|
371
|
-
const
|
|
480
|
+
const identifiers = getProjectIdentifiers2(projectPath);
|
|
481
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
482
|
+
const namedLists = allLists.filter((list) => !uuidRegex.test(list));
|
|
483
|
+
if (namedLists.length === 0 || identifiers.length === 0)
|
|
484
|
+
return [];
|
|
485
|
+
const scored = [];
|
|
486
|
+
for (const list of namedLists) {
|
|
372
487
|
const listLower = list.toLowerCase();
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
488
|
+
let bestScore = 0;
|
|
489
|
+
for (let i = 0;i < identifiers.length; i++) {
|
|
490
|
+
const idLower = identifiers[i].toLowerCase();
|
|
491
|
+
const priorityWeight = identifiers.length - i;
|
|
492
|
+
if (listLower === idLower) {
|
|
493
|
+
bestScore = Math.max(bestScore, priorityWeight * 100);
|
|
494
|
+
} else if (listLower.startsWith(idLower + "-")) {
|
|
495
|
+
bestScore = Math.max(bestScore, priorityWeight * 10);
|
|
496
|
+
} else if (listLower.includes(idLower)) {
|
|
497
|
+
bestScore = Math.max(bestScore, priorityWeight * 1);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
if (bestScore > 0) {
|
|
501
|
+
scored.push({ list, score: bestScore });
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
scored.sort((a, b) => b.score - a.score);
|
|
505
|
+
return scored.map((s) => s.list);
|
|
381
506
|
}
|
|
382
507
|
function parseInstallArgs(args) {
|
|
383
508
|
const options = {};
|
package/dist/hook.js
CHANGED
|
@@ -89,19 +89,79 @@ function getAllTaskLists() {
|
|
|
89
89
|
return [];
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
+
function getProjectIdentifiers(cwd) {
|
|
93
|
+
const genericSegments = new Set([
|
|
94
|
+
"users",
|
|
95
|
+
"home",
|
|
96
|
+
"workspace",
|
|
97
|
+
"workspaces",
|
|
98
|
+
"projects",
|
|
99
|
+
"repos",
|
|
100
|
+
"src",
|
|
101
|
+
"lib",
|
|
102
|
+
"app",
|
|
103
|
+
"apps",
|
|
104
|
+
"packages",
|
|
105
|
+
"platform",
|
|
106
|
+
"service",
|
|
107
|
+
"services",
|
|
108
|
+
"web",
|
|
109
|
+
"api",
|
|
110
|
+
"server",
|
|
111
|
+
"client",
|
|
112
|
+
"frontend",
|
|
113
|
+
"backend",
|
|
114
|
+
"dev",
|
|
115
|
+
"development",
|
|
116
|
+
"prod",
|
|
117
|
+
"staging",
|
|
118
|
+
"tmp",
|
|
119
|
+
"temp",
|
|
120
|
+
"var",
|
|
121
|
+
"opt",
|
|
122
|
+
"usr",
|
|
123
|
+
"volumes"
|
|
124
|
+
]);
|
|
125
|
+
const segments = cwd.split("/").filter(Boolean);
|
|
126
|
+
const identifiers = [];
|
|
127
|
+
for (let i = segments.length - 1;i >= 0; i--) {
|
|
128
|
+
const seg = segments[i];
|
|
129
|
+
if (seg.length < 3)
|
|
130
|
+
continue;
|
|
131
|
+
if (genericSegments.has(seg.toLowerCase()))
|
|
132
|
+
continue;
|
|
133
|
+
if (i <= 2)
|
|
134
|
+
continue;
|
|
135
|
+
identifiers.push(seg);
|
|
136
|
+
}
|
|
137
|
+
return identifiers;
|
|
138
|
+
}
|
|
92
139
|
function getProjectTaskLists(cwd) {
|
|
93
140
|
const allLists = getAllTaskLists();
|
|
94
|
-
const
|
|
95
|
-
const
|
|
141
|
+
const identifiers = getProjectIdentifiers(cwd);
|
|
142
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
143
|
+
const namedLists = allLists.filter((list) => !uuidRegex.test(list));
|
|
144
|
+
if (namedLists.length === 0 || identifiers.length === 0)
|
|
145
|
+
return [];
|
|
146
|
+
const scored = [];
|
|
147
|
+
for (const list of namedLists) {
|
|
96
148
|
const listLower = list.toLowerCase();
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
149
|
+
let bestScore = 0;
|
|
150
|
+
for (let i = 0;i < identifiers.length; i++) {
|
|
151
|
+
const idLower = identifiers[i].toLowerCase();
|
|
152
|
+
const priorityWeight = identifiers.length - i;
|
|
153
|
+
if (listLower === idLower) {
|
|
154
|
+
bestScore = Math.max(bestScore, priorityWeight * 100);
|
|
155
|
+
} else if (listLower.startsWith(idLower + "-")) {
|
|
156
|
+
bestScore = Math.max(bestScore, priorityWeight * 10);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (bestScore > 0) {
|
|
160
|
+
scored.push({ list, score: bestScore });
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
scored.sort((a, b) => b.score - a.score);
|
|
164
|
+
return scored.map((s) => s.list);
|
|
105
165
|
}
|
|
106
166
|
function getTasksFromList(listId) {
|
|
107
167
|
const tasksDir = join(homedir(), ".claude", "tasks", listId);
|
|
@@ -132,16 +192,7 @@ function run() {
|
|
|
132
192
|
if (config.enabled === false) {
|
|
133
193
|
approve();
|
|
134
194
|
}
|
|
135
|
-
let sessionName = null;
|
|
136
|
-
if (hookInput?.transcript_path) {
|
|
137
|
-
sessionName = getSessionName(hookInput.transcript_path);
|
|
138
|
-
}
|
|
139
|
-
const nameToCheck = sessionName || config.taskListId || "";
|
|
140
195
|
const keywords = config.keywords || ["dev"];
|
|
141
|
-
const matchesKeyword = keywords.some((keyword) => nameToCheck.toLowerCase().includes(keyword.toLowerCase()));
|
|
142
|
-
if (!matchesKeyword && keywords.length > 0 && nameToCheck) {
|
|
143
|
-
approve();
|
|
144
|
-
}
|
|
145
196
|
let listsToCheck = [];
|
|
146
197
|
if (config.taskListId) {
|
|
147
198
|
listsToCheck = [config.taskListId];
|
|
@@ -149,7 +200,8 @@ function run() {
|
|
|
149
200
|
const projectLists = getProjectTaskLists(cwd);
|
|
150
201
|
if (projectLists.length > 0) {
|
|
151
202
|
if (keywords.length > 0) {
|
|
152
|
-
|
|
203
|
+
const keywordMatched = projectLists.filter((list) => keywords.some((keyword) => list.toLowerCase().includes(keyword.toLowerCase())));
|
|
204
|
+
listsToCheck = keywordMatched.length > 0 ? keywordMatched : projectLists;
|
|
153
205
|
} else {
|
|
154
206
|
listsToCheck = projectLists;
|
|
155
207
|
}
|
|
@@ -158,6 +210,17 @@ function run() {
|
|
|
158
210
|
if (listsToCheck.length === 0) {
|
|
159
211
|
approve();
|
|
160
212
|
}
|
|
213
|
+
let sessionName = null;
|
|
214
|
+
if (hookInput?.transcript_path) {
|
|
215
|
+
sessionName = getSessionName(hookInput.transcript_path);
|
|
216
|
+
}
|
|
217
|
+
if (sessionName && keywords.length > 0) {
|
|
218
|
+
const sessionMatchesKeyword = keywords.some((keyword) => sessionName.toLowerCase().includes(keyword.toLowerCase()));
|
|
219
|
+
const listMatchesKeyword = config.taskListId ? keywords.some((keyword) => config.taskListId.toLowerCase().includes(keyword.toLowerCase())) : true;
|
|
220
|
+
if (!sessionMatchesKeyword && !listMatchesKeyword) {
|
|
221
|
+
approve();
|
|
222
|
+
}
|
|
223
|
+
}
|
|
161
224
|
let allPending = [];
|
|
162
225
|
let allInProgress = [];
|
|
163
226
|
let allCompleted = [];
|
|
@@ -182,7 +245,7 @@ function run() {
|
|
|
182
245
|
const prompt = `
|
|
183
246
|
STOP BLOCKED: You have ${remainingCount} tasks remaining${listInfo} (${allPending.length} pending, ${allInProgress.length} in progress, ${allCompleted.length} completed).
|
|
184
247
|
|
|
185
|
-
|
|
248
|
+
DO NOT STOP. DO NOT ASK QUESTIONS. DO NOT WAIT FOR USER INPUT.
|
|
186
249
|
|
|
187
250
|
You MUST continue working AUTONOMOUSLY until ALL tasks are completed.
|
|
188
251
|
|