sqlew 3.5.3 → 3.6.0
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 +247 -1772
- package/README.md +70 -304
- package/assets/config.example.toml +97 -0
- package/dist/adapters/index.d.ts +11 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +21 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/mysql-adapter.d.ts +31 -0
- package/dist/adapters/mysql-adapter.d.ts.map +1 -0
- package/dist/adapters/mysql-adapter.js +63 -0
- package/dist/adapters/mysql-adapter.js.map +1 -0
- package/dist/adapters/postgresql-adapter.d.ts +31 -0
- package/dist/adapters/postgresql-adapter.d.ts.map +1 -0
- package/dist/adapters/postgresql-adapter.js +63 -0
- package/dist/adapters/postgresql-adapter.js.map +1 -0
- package/dist/adapters/sqlite-adapter.d.ts +37 -0
- package/dist/adapters/sqlite-adapter.d.ts.map +1 -0
- package/dist/adapters/sqlite-adapter.js +129 -0
- package/dist/adapters/sqlite-adapter.js.map +1 -0
- package/dist/adapters/types.d.ts +33 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +2 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/cli.js +55 -54
- package/dist/cli.js.map +1 -1
- package/dist/config/example-generator.d.ts +11 -0
- package/dist/config/example-generator.d.ts.map +1 -0
- package/dist/config/example-generator.js +48 -0
- package/dist/config/example-generator.js.map +1 -0
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +4 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/types.d.ts +9 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/database.d.ts +44 -122
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +145 -416
- package/dist/database.js.map +1 -1
- package/dist/index.js +215 -185
- package/dist/index.js.map +1 -1
- package/dist/knexfile.d.ts +6 -0
- package/dist/knexfile.d.ts.map +1 -0
- package/dist/knexfile.js +85 -0
- package/dist/knexfile.js.map +1 -0
- package/dist/migrations/add-help-system-tables.d.ts +35 -0
- package/dist/migrations/add-help-system-tables.d.ts.map +1 -0
- package/dist/migrations/add-help-system-tables.js +206 -0
- package/dist/migrations/add-help-system-tables.js.map +1 -0
- package/dist/migrations/add-token-tracking.d.ts +28 -0
- package/dist/migrations/add-token-tracking.d.ts.map +1 -0
- package/dist/migrations/add-token-tracking.js +108 -0
- package/dist/migrations/add-token-tracking.js.map +1 -0
- package/dist/migrations/index.d.ts +25 -12
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +147 -20
- package/dist/migrations/index.js.map +1 -1
- package/dist/migrations/knex/20251025020452_create_master_tables.d.ts +4 -0
- package/dist/migrations/knex/20251025020452_create_master_tables.d.ts.map +1 -0
- package/dist/migrations/knex/20251025020452_create_master_tables.js +65 -0
- package/dist/migrations/knex/20251025020452_create_master_tables.js.map +1 -0
- package/dist/migrations/knex/20251025021152_create_transaction_tables.d.ts +4 -0
- package/dist/migrations/knex/20251025021152_create_transaction_tables.d.ts.map +1 -0
- package/dist/migrations/knex/20251025021152_create_transaction_tables.js +235 -0
- package/dist/migrations/knex/20251025021152_create_transaction_tables.js.map +1 -0
- package/dist/migrations/knex/20251025021351_create_indexes.d.ts +4 -0
- package/dist/migrations/knex/20251025021351_create_indexes.d.ts.map +1 -0
- package/dist/migrations/knex/20251025021351_create_indexes.js +62 -0
- package/dist/migrations/knex/20251025021351_create_indexes.js.map +1 -0
- package/dist/migrations/knex/20251025021416_seed_master_data.d.ts +4 -0
- package/dist/migrations/knex/20251025021416_seed_master_data.d.ts.map +1 -0
- package/dist/migrations/knex/20251025021416_seed_master_data.js +58 -0
- package/dist/migrations/knex/20251025021416_seed_master_data.js.map +1 -0
- package/dist/migrations/knex/20251025070349_create_views.d.ts +4 -0
- package/dist/migrations/knex/20251025070349_create_views.d.ts.map +1 -0
- package/dist/migrations/knex/20251025070349_create_views.js +143 -0
- package/dist/migrations/knex/20251025070349_create_views.js.map +1 -0
- package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.d.ts +4 -0
- package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.d.ts.map +1 -0
- package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.js +15 -0
- package/dist/migrations/knex/20251025081221_add_link_type_to_task_decision_links.js.map +1 -0
- package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.d.ts +8 -0
- package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.d.ts.map +1 -0
- package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.js +12 -0
- package/dist/migrations/knex/20251025082220_fix_task_dependencies_columns.js.map +1 -0
- package/dist/migrations/knex/20251025090000_create_help_system_tables.d.ts +19 -0
- package/dist/migrations/knex/20251025090000_create_help_system_tables.d.ts.map +1 -0
- package/dist/migrations/knex/20251025090000_create_help_system_tables.js +115 -0
- package/dist/migrations/knex/20251025090000_create_help_system_tables.js.map +1 -0
- package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.d.ts +13 -0
- package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.d.ts.map +1 -0
- package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.js +377 -0
- package/dist/migrations/knex/20251025090100_seed_help_categories_and_use_cases.js.map +1 -0
- package/dist/migrations/knex/20251025100000_seed_help_metadata.d.ts +15 -0
- package/dist/migrations/knex/20251025100000_seed_help_metadata.d.ts.map +1 -0
- package/dist/migrations/knex/20251025100000_seed_help_metadata.js +253 -0
- package/dist/migrations/knex/20251025100000_seed_help_metadata.js.map +1 -0
- package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.d.ts +16 -0
- package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.d.ts.map +1 -0
- package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.js +276 -0
- package/dist/migrations/knex/20251025100100_seed_remaining_use_cases.js.map +1 -0
- package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.d.ts +8 -0
- package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.d.ts.map +1 -0
- package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.js +64 -0
- package/dist/migrations/knex/20251025120000_add_cascade_to_task_dependencies.js.map +1 -0
- package/dist/migrations/seed-help-data.d.ts +48 -0
- package/dist/migrations/seed-help-data.d.ts.map +1 -0
- package/dist/migrations/seed-help-data.js +1466 -0
- package/dist/migrations/seed-help-data.js.map +1 -0
- package/dist/migrations/seed-tool-metadata.d.ts +24 -0
- package/dist/migrations/seed-tool-metadata.d.ts.map +1 -0
- package/dist/migrations/seed-tool-metadata.js +392 -0
- package/dist/migrations/seed-tool-metadata.js.map +1 -0
- package/dist/migrations/v3.6.0-help-system-refactor.d.ts +46 -0
- package/dist/migrations/v3.6.0-help-system-refactor.d.ts.map +1 -0
- package/dist/migrations/v3.6.0-help-system-refactor.js +223 -0
- package/dist/migrations/v3.6.0-help-system-refactor.js.map +1 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +2 -0
- package/dist/schema.js.map +1 -1
- package/dist/tests/git-aware-completion.test.js +89 -70
- package/dist/tests/git-aware-completion.test.js.map +1 -1
- package/dist/tests/help-system.test.d.ts +23 -0
- package/dist/tests/help-system.test.d.ts.map +1 -0
- package/dist/tests/help-system.test.js +374 -0
- package/dist/tests/help-system.test.js.map +1 -0
- package/dist/tests/tasks.auto-pruning-decision-link.test.js +92 -78
- package/dist/tests/tasks.auto-pruning-decision-link.test.js.map +1 -1
- package/dist/tests/tasks.auto-pruning-partial.test.js +106 -95
- package/dist/tests/tasks.auto-pruning-partial.test.js.map +1 -1
- package/dist/tests/tasks.auto-pruning-persistence.test.js +115 -97
- package/dist/tests/tasks.auto-pruning-persistence.test.js.map +1 -1
- package/dist/tests/tasks.auto-pruning-safety.test.js +124 -103
- package/dist/tests/tasks.auto-pruning-safety.test.js.map +1 -1
- package/dist/tests/tasks.dependencies.test.js +338 -307
- package/dist/tests/tasks.dependencies.test.js.map +1 -1
- package/dist/tests/tasks.link-file-backward-compat.test.js +116 -104
- package/dist/tests/tasks.link-file-backward-compat.test.js.map +1 -1
- package/dist/tests/tasks.watch-files-action.test.js +122 -101
- package/dist/tests/tasks.watch-files-action.test.js.map +1 -1
- package/dist/tests/tasks.watch-files-parameter.test.js +105 -94
- package/dist/tests/tasks.watch-files-parameter.test.js.map +1 -1
- package/dist/tests/two-step-git-completion.test.js +176 -133
- package/dist/tests/two-step-git-completion.test.js.map +1 -1
- package/dist/tests/vcs-staging.test.js +1 -1
- package/dist/tests/vcs-staging.test.js.map +1 -1
- package/dist/tools/config.d.ts +9 -6
- package/dist/tools/config.d.ts.map +1 -1
- package/dist/tools/config.js +16 -14
- package/dist/tools/config.js.map +1 -1
- package/dist/tools/constraints.d.ts +10 -7
- package/dist/tools/constraints.d.ts.map +1 -1
- package/dist/tools/constraints.js +66 -48
- package/dist/tools/constraints.js.map +1 -1
- package/dist/tools/context.d.ts +36 -33
- package/dist/tools/context.d.ts.map +1 -1
- package/dist/tools/context.js +374 -330
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/files.d.ts +12 -9
- package/dist/tools/files.d.ts.map +1 -1
- package/dist/tools/files.js +173 -95
- package/dist/tools/files.js.map +1 -1
- package/dist/tools/help-queries.d.ts +130 -0
- package/dist/tools/help-queries.d.ts.map +1 -0
- package/dist/tools/help-queries.js +393 -0
- package/dist/tools/help-queries.js.map +1 -0
- package/dist/tools/messaging.d.ts +14 -11
- package/dist/tools/messaging.d.ts.map +1 -1
- package/dist/tools/messaging.js +217 -133
- package/dist/tools/messaging.js.map +1 -1
- package/dist/tools/tasks.d.ts +18 -16
- package/dist/tools/tasks.d.ts.map +1 -1
- package/dist/tools/tasks.js +513 -439
- package/dist/tools/tasks.js.map +1 -1
- package/dist/tools/utils.d.ts +14 -11
- package/dist/tools/utils.d.ts.map +1 -1
- package/dist/tools/utils.js +86 -121
- package/dist/tools/utils.js.map +1 -1
- package/dist/utils/activity-logging.d.ts +114 -0
- package/dist/utils/activity-logging.d.ts.map +1 -0
- package/dist/utils/activity-logging.js +162 -0
- package/dist/utils/activity-logging.js.map +1 -0
- package/dist/utils/batch.d.ts +2 -2
- package/dist/utils/batch.d.ts.map +1 -1
- package/dist/utils/batch.js +8 -8
- package/dist/utils/batch.js.map +1 -1
- package/dist/utils/cleanup.d.ts +21 -13
- package/dist/utils/cleanup.d.ts.map +1 -1
- package/dist/utils/cleanup.js +31 -24
- package/dist/utils/cleanup.js.map +1 -1
- package/dist/utils/debug-logger.d.ts +44 -0
- package/dist/utils/debug-logger.d.ts.map +1 -0
- package/dist/utils/debug-logger.js +116 -0
- package/dist/utils/debug-logger.js.map +1 -0
- package/dist/utils/help-tracking.d.ts +55 -0
- package/dist/utils/help-tracking.d.ts.map +1 -0
- package/dist/utils/help-tracking.js +88 -0
- package/dist/utils/help-tracking.js.map +1 -0
- package/dist/utils/retention.d.ts +7 -7
- package/dist/utils/retention.d.ts.map +1 -1
- package/dist/utils/retention.js +12 -12
- package/dist/utils/retention.js.map +1 -1
- package/dist/utils/task-stale-detection.d.ts +15 -13
- package/dist/utils/task-stale-detection.d.ts.map +1 -1
- package/dist/utils/task-stale-detection.js +100 -302
- package/dist/utils/task-stale-detection.js.map +1 -1
- package/dist/utils/token-estimation.d.ts +72 -0
- package/dist/utils/token-estimation.d.ts.map +1 -0
- package/dist/utils/token-estimation.js +71 -0
- package/dist/utils/token-estimation.js.map +1 -0
- package/dist/utils/token-logging.d.ts +48 -0
- package/dist/utils/token-logging.d.ts.map +1 -0
- package/dist/utils/token-logging.js +112 -0
- package/dist/utils/token-logging.js.map +1 -0
- package/dist/utils/view-queries.d.ts +34 -0
- package/dist/utils/view-queries.d.ts.map +1 -0
- package/dist/utils/view-queries.js +192 -0
- package/dist/utils/view-queries.js.map +1 -0
- package/dist/watcher/file-watcher.d.ts.map +1 -1
- package/dist/watcher/file-watcher.js +25 -11
- package/dist/watcher/file-watcher.js.map +1 -1
- package/docs/BEST_PRACTICES.md +56 -448
- package/docs/MIGRATION_v3.6.0.md +170 -0
- package/docs/SHARED_CONCEPTS.md +63 -208
- package/docs/TASK_OVERVIEW.md +2 -2
- package/docs/TOOL_SELECTION.md +41 -248
- package/package.json +16 -4
|
@@ -4,31 +4,29 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
6
6
|
import assert from 'node:assert/strict';
|
|
7
|
-
import
|
|
8
|
-
import { initializeSchema } from '../schema.js';
|
|
9
|
-
import { runAllMigrations } from '../migrations/index.js';
|
|
7
|
+
import { initializeDatabase, getOrCreateAgent, getOrCreateFile, closeDatabase } from '../database.js';
|
|
10
8
|
import { detectAndTransitionToReview } from '../utils/task-stale-detection.js';
|
|
11
|
-
import { getOrCreateAgent, getOrCreateFile } from '../database.js';
|
|
12
9
|
import fs from 'fs';
|
|
13
10
|
import path from 'path';
|
|
14
11
|
import os from 'os';
|
|
15
12
|
describe('Auto-pruning: Partial file existence', () => {
|
|
16
13
|
let db;
|
|
17
14
|
let tempDir;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
initializeSchema(db);
|
|
22
|
-
runAllMigrations(db);
|
|
23
|
-
// Skip the explicit migration result check
|
|
24
|
-
if (false) {
|
|
25
|
-
throw new Error(`Migration failed`);
|
|
26
|
-
}
|
|
27
|
-
// Create temp directory for test files
|
|
15
|
+
let tempDbPath;
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
// Create temp directory for test files and database
|
|
28
18
|
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'sqlew-test-'));
|
|
19
|
+
tempDbPath = path.join(tempDir, 'test.db');
|
|
20
|
+
// Initialize database with Knex adapter
|
|
21
|
+
db = await initializeDatabase({
|
|
22
|
+
databaseType: 'sqlite',
|
|
23
|
+
connection: {
|
|
24
|
+
filename: tempDbPath,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
29
27
|
});
|
|
30
|
-
afterEach(() => {
|
|
31
|
-
|
|
28
|
+
afterEach(async () => {
|
|
29
|
+
await closeDatabase();
|
|
32
30
|
// Cleanup temp directory
|
|
33
31
|
if (fs.existsSync(tempDir)) {
|
|
34
32
|
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
@@ -36,7 +34,7 @@ describe('Auto-pruning: Partial file existence', () => {
|
|
|
36
34
|
});
|
|
37
35
|
it('should prune non-existent files and keep existing ones', async () => {
|
|
38
36
|
// 1. Create test task
|
|
39
|
-
const taskId = createTestTask(db);
|
|
37
|
+
const taskId = await createTestTask(db);
|
|
40
38
|
// 2. Create 4 watched files (2 exist, 2 don't)
|
|
41
39
|
const existingFile1 = path.join(tempDir, 'exists1.ts');
|
|
42
40
|
const existingFile2 = path.join(tempDir, 'exists2.ts');
|
|
@@ -46,7 +44,7 @@ describe('Auto-pruning: Partial file existence', () => {
|
|
|
46
44
|
fs.writeFileSync(existingFile2, '// test file 2');
|
|
47
45
|
// Don't create nonExistentFile1 and nonExistentFile2
|
|
48
46
|
// Add all 4 files to watch list
|
|
49
|
-
addWatchedFiles(db, taskId, [
|
|
47
|
+
await addWatchedFiles(db, taskId, [
|
|
50
48
|
existingFile1,
|
|
51
49
|
existingFile2,
|
|
52
50
|
nonExistentFile1,
|
|
@@ -55,11 +53,13 @@ describe('Auto-pruning: Partial file existence', () => {
|
|
|
55
53
|
// Set task to in_progress status and update timestamp to be old enough
|
|
56
54
|
// for auto-transition (older than 15 minutes, which is the default review_idle_minutes)
|
|
57
55
|
const fifteenMinutesAgo = Math.floor(Date.now() / 1000) - (15 * 60 + 10);
|
|
58
|
-
db.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
const knex = db.getKnex();
|
|
57
|
+
await knex('t_tasks')
|
|
58
|
+
.where({ id: taskId })
|
|
59
|
+
.update({
|
|
60
|
+
status_id: 2,
|
|
61
|
+
updated_ts: fifteenMinutesAgo,
|
|
62
|
+
});
|
|
63
63
|
// 3. Trigger auto-pruning by detecting ready for review
|
|
64
64
|
// Change cwd to tempDir so file existence checks work correctly
|
|
65
65
|
const originalCwd = process.cwd();
|
|
@@ -70,25 +70,23 @@ describe('Auto-pruning: Partial file existence', () => {
|
|
|
70
70
|
assert.equal(transitioned, 1, 'Should have transitioned 1 task');
|
|
71
71
|
// 4. Verify results
|
|
72
72
|
// Check watch list - should have only 2 files (the existing ones)
|
|
73
|
-
const watchedFiles = getWatchedFiles(db, taskId);
|
|
73
|
+
const watchedFiles = await getWatchedFiles(db, taskId);
|
|
74
74
|
assert.equal(watchedFiles.length, 2, 'Should have 2 files in watch list');
|
|
75
75
|
assert.ok(watchedFiles.includes('exists1.ts'), 'Should keep existing file 1');
|
|
76
76
|
assert.ok(watchedFiles.includes('exists2.ts'), 'Should keep existing file 2');
|
|
77
77
|
// Check pruned files table - should have 2 records
|
|
78
|
-
const prunedFiles =
|
|
79
|
-
.
|
|
80
|
-
|
|
81
|
-
`)
|
|
82
|
-
.all(taskId);
|
|
78
|
+
const prunedFiles = await knex('t_task_pruned_files')
|
|
79
|
+
.where({ task_id: taskId })
|
|
80
|
+
.select('file_path');
|
|
83
81
|
assert.equal(prunedFiles.length, 2, 'Should have 2 pruned file records');
|
|
84
82
|
// Verify pruned files are the correct ones
|
|
85
83
|
const prunedPaths = prunedFiles.map((f) => f.file_path);
|
|
86
84
|
assert.ok(prunedPaths.includes('missing1.ts'), 'Should have pruned missing1.ts');
|
|
87
85
|
assert.ok(prunedPaths.includes('missing2.ts'), 'Should have pruned missing2.ts');
|
|
88
86
|
// Check task status transitioned to waiting_review
|
|
89
|
-
const task =
|
|
90
|
-
.
|
|
91
|
-
.
|
|
87
|
+
const task = await knex('t_tasks')
|
|
88
|
+
.where({ id: taskId })
|
|
89
|
+
.first('status_id');
|
|
92
90
|
assert.equal(task.status_id, 3, 'Task should be in waiting_review status (3)');
|
|
93
91
|
}
|
|
94
92
|
finally {
|
|
@@ -98,20 +96,22 @@ describe('Auto-pruning: Partial file existence', () => {
|
|
|
98
96
|
});
|
|
99
97
|
it('should not transition if all files are non-existent', async () => {
|
|
100
98
|
// 1. Create test task
|
|
101
|
-
const taskId = createTestTask(db);
|
|
99
|
+
const taskId = await createTestTask(db);
|
|
102
100
|
// 2. Create 2 watched files that don't exist
|
|
103
101
|
const nonExistentFile1 = path.join(tempDir, 'missing1.ts');
|
|
104
102
|
const nonExistentFile2 = path.join(tempDir, 'missing2.ts');
|
|
105
103
|
// Don't create these files
|
|
106
104
|
// Add files to watch list
|
|
107
|
-
addWatchedFiles(db, taskId, [nonExistentFile1, nonExistentFile2]);
|
|
105
|
+
await addWatchedFiles(db, taskId, [nonExistentFile1, nonExistentFile2]);
|
|
108
106
|
// Set task to in_progress status and update timestamp to be old enough
|
|
109
107
|
const fifteenMinutesAgo = Math.floor(Date.now() / 1000) - (15 * 60 + 10);
|
|
110
|
-
db.
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
108
|
+
const knex = db.getKnex();
|
|
109
|
+
await knex('t_tasks')
|
|
110
|
+
.where({ id: taskId })
|
|
111
|
+
.update({
|
|
112
|
+
status_id: 2,
|
|
113
|
+
updated_ts: fifteenMinutesAgo,
|
|
114
|
+
});
|
|
115
115
|
// 3. Trigger auto-pruning
|
|
116
116
|
const originalCwd = process.cwd();
|
|
117
117
|
try {
|
|
@@ -120,14 +120,16 @@ describe('Auto-pruning: Partial file existence', () => {
|
|
|
120
120
|
// Task should NOT have transitioned (safety check prevents it)
|
|
121
121
|
assert.equal(transitioned, 0, 'Should not have transitioned any tasks');
|
|
122
122
|
// 4. Verify task is still in in_progress
|
|
123
|
-
const task =
|
|
124
|
-
.
|
|
125
|
-
.
|
|
123
|
+
const task = await knex('t_tasks')
|
|
124
|
+
.where({ id: taskId })
|
|
125
|
+
.first('status_id');
|
|
126
126
|
assert.equal(task.status_id, 2, 'Task should still be in in_progress (2)');
|
|
127
127
|
// 5. Verify no pruning occurred (safety check blocked it)
|
|
128
|
-
const prunedFiles =
|
|
129
|
-
.
|
|
130
|
-
.
|
|
128
|
+
const prunedFiles = await knex('t_task_pruned_files')
|
|
129
|
+
.where({ task_id: taskId })
|
|
130
|
+
.count('* as count')
|
|
131
|
+
.first();
|
|
132
|
+
assert.ok(prunedFiles, 'Should have pruned files result');
|
|
131
133
|
assert.equal(prunedFiles.count, 0, 'Should have 0 pruned records (safety check prevented pruning)');
|
|
132
134
|
}
|
|
133
135
|
finally {
|
|
@@ -136,7 +138,7 @@ describe('Auto-pruning: Partial file existence', () => {
|
|
|
136
138
|
});
|
|
137
139
|
it('should not prune when all files exist', async () => {
|
|
138
140
|
// 1. Create test task
|
|
139
|
-
const taskId = createTestTask(db);
|
|
141
|
+
const taskId = await createTestTask(db);
|
|
140
142
|
// 2. Create 3 watched files that all exist
|
|
141
143
|
const existingFile1 = path.join(tempDir, 'exists1.ts');
|
|
142
144
|
const existingFile2 = path.join(tempDir, 'exists2.ts');
|
|
@@ -145,18 +147,20 @@ describe('Auto-pruning: Partial file existence', () => {
|
|
|
145
147
|
fs.writeFileSync(existingFile2, '// test file 2');
|
|
146
148
|
fs.writeFileSync(existingFile3, '// test file 3');
|
|
147
149
|
// Add files to watch list
|
|
148
|
-
addWatchedFiles(db, taskId, [
|
|
150
|
+
await addWatchedFiles(db, taskId, [
|
|
149
151
|
existingFile1,
|
|
150
152
|
existingFile2,
|
|
151
153
|
existingFile3,
|
|
152
154
|
]);
|
|
153
155
|
// Set task to in_progress status and update timestamp to be old enough
|
|
154
156
|
const fifteenMinutesAgo = Math.floor(Date.now() / 1000) - (15 * 60 + 10);
|
|
155
|
-
db.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
const knex = db.getKnex();
|
|
158
|
+
await knex('t_tasks')
|
|
159
|
+
.where({ id: taskId })
|
|
160
|
+
.update({
|
|
161
|
+
status_id: 2,
|
|
162
|
+
updated_ts: fifteenMinutesAgo,
|
|
163
|
+
});
|
|
160
164
|
// 3. Trigger auto-pruning
|
|
161
165
|
const originalCwd = process.cwd();
|
|
162
166
|
try {
|
|
@@ -165,17 +169,19 @@ describe('Auto-pruning: Partial file existence', () => {
|
|
|
165
169
|
// Task should have transitioned (all files exist)
|
|
166
170
|
assert.equal(transitioned, 1, 'Should have transitioned 1 task');
|
|
167
171
|
// 4. Verify no pruning occurred
|
|
168
|
-
const prunedFiles =
|
|
169
|
-
.
|
|
170
|
-
.
|
|
172
|
+
const prunedFiles = await knex('t_task_pruned_files')
|
|
173
|
+
.where({ task_id: taskId })
|
|
174
|
+
.count('* as count')
|
|
175
|
+
.first();
|
|
176
|
+
assert.ok(prunedFiles, 'Should have pruned files result');
|
|
171
177
|
assert.equal(prunedFiles.count, 0, 'Should have 0 pruned records');
|
|
172
178
|
// 5. Verify all files still in watch list
|
|
173
|
-
const watchedFiles = getWatchedFiles(db, taskId);
|
|
179
|
+
const watchedFiles = await getWatchedFiles(db, taskId);
|
|
174
180
|
assert.equal(watchedFiles.length, 3, 'Should still have 3 files in watch list');
|
|
175
181
|
// 6. Verify task transitioned to waiting_review
|
|
176
|
-
const task =
|
|
177
|
-
.
|
|
178
|
-
.
|
|
182
|
+
const task = await knex('t_tasks')
|
|
183
|
+
.where({ id: taskId })
|
|
184
|
+
.first('status_id');
|
|
179
185
|
assert.equal(task.status_id, 3, 'Task should be in waiting_review status (3)');
|
|
180
186
|
}
|
|
181
187
|
finally {
|
|
@@ -184,7 +190,7 @@ describe('Auto-pruning: Partial file existence', () => {
|
|
|
184
190
|
});
|
|
185
191
|
it('should handle mixed ratios (3 exist, 1 missing)', async () => {
|
|
186
192
|
// 1. Create test task
|
|
187
|
-
const taskId = createTestTask(db);
|
|
193
|
+
const taskId = await createTestTask(db);
|
|
188
194
|
// 2. Create 4 watched files (3 exist, 1 doesn't)
|
|
189
195
|
const existingFile1 = path.join(tempDir, 'exists1.ts');
|
|
190
196
|
const existingFile2 = path.join(tempDir, 'exists2.ts');
|
|
@@ -195,7 +201,7 @@ describe('Auto-pruning: Partial file existence', () => {
|
|
|
195
201
|
fs.writeFileSync(existingFile3, '// test file 3');
|
|
196
202
|
// Don't create nonExistentFile
|
|
197
203
|
// Add all files to watch list
|
|
198
|
-
addWatchedFiles(db, taskId, [
|
|
204
|
+
await addWatchedFiles(db, taskId, [
|
|
199
205
|
existingFile1,
|
|
200
206
|
existingFile2,
|
|
201
207
|
existingFile3,
|
|
@@ -203,11 +209,13 @@ describe('Auto-pruning: Partial file existence', () => {
|
|
|
203
209
|
]);
|
|
204
210
|
// Set task to in_progress status and update timestamp to be old enough
|
|
205
211
|
const fifteenMinutesAgo = Math.floor(Date.now() / 1000) - (15 * 60 + 10);
|
|
206
|
-
db.
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
212
|
+
const knex = db.getKnex();
|
|
213
|
+
await knex('t_tasks')
|
|
214
|
+
.where({ id: taskId })
|
|
215
|
+
.update({
|
|
216
|
+
status_id: 2,
|
|
217
|
+
updated_ts: fifteenMinutesAgo,
|
|
218
|
+
});
|
|
211
219
|
// 3. Trigger auto-pruning
|
|
212
220
|
const originalCwd = process.cwd();
|
|
213
221
|
try {
|
|
@@ -216,11 +224,11 @@ describe('Auto-pruning: Partial file existence', () => {
|
|
|
216
224
|
// Task should have transitioned
|
|
217
225
|
assert.equal(transitioned, 1, 'Should have transitioned 1 task');
|
|
218
226
|
// 4. Verify results
|
|
219
|
-
const watchedFiles = getWatchedFiles(db, taskId);
|
|
227
|
+
const watchedFiles = await getWatchedFiles(db, taskId);
|
|
220
228
|
assert.equal(watchedFiles.length, 3, 'Should have 3 files in watch list');
|
|
221
|
-
const prunedFiles =
|
|
222
|
-
.
|
|
223
|
-
.
|
|
229
|
+
const prunedFiles = await knex('t_task_pruned_files')
|
|
230
|
+
.where({ task_id: taskId })
|
|
231
|
+
.select('file_path');
|
|
224
232
|
assert.equal(prunedFiles.length, 1, 'Should have 1 pruned file record');
|
|
225
233
|
assert.equal(prunedFiles[0].file_path, 'missing.ts', 'Should have pruned missing.ts');
|
|
226
234
|
}
|
|
@@ -233,42 +241,45 @@ describe('Auto-pruning: Partial file existence', () => {
|
|
|
233
241
|
/**
|
|
234
242
|
* Create a test task in in_progress status
|
|
235
243
|
*/
|
|
236
|
-
function createTestTask(db) {
|
|
237
|
-
const agentId = getOrCreateAgent(db, 'test-agent');
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
244
|
+
async function createTestTask(db) {
|
|
245
|
+
const agentId = await getOrCreateAgent(db, 'test-agent');
|
|
246
|
+
const knex = db.getKnex();
|
|
247
|
+
const [taskId] = await knex('t_tasks').insert({
|
|
248
|
+
title: 'Test Task for Auto-Pruning',
|
|
249
|
+
status_id: 2,
|
|
250
|
+
priority: 2,
|
|
251
|
+
created_by_agent_id: agentId,
|
|
252
|
+
assigned_agent_id: agentId,
|
|
253
|
+
});
|
|
254
|
+
return taskId;
|
|
245
255
|
}
|
|
246
256
|
/**
|
|
247
257
|
* Add watched files to a task
|
|
248
258
|
*/
|
|
249
|
-
function addWatchedFiles(db, taskId, filePaths) {
|
|
250
|
-
const
|
|
251
|
-
INSERT OR IGNORE INTO t_task_file_links (task_id, file_id)
|
|
252
|
-
VALUES (?, ?)
|
|
253
|
-
`);
|
|
259
|
+
async function addWatchedFiles(db, taskId, filePaths) {
|
|
260
|
+
const knex = db.getKnex();
|
|
254
261
|
for (const filePath of filePaths) {
|
|
255
262
|
// Extract just the filename (last segment) for relative paths
|
|
256
263
|
const fileName = path.basename(filePath);
|
|
257
|
-
const fileId = getOrCreateFile(db, fileName);
|
|
258
|
-
|
|
264
|
+
const fileId = await getOrCreateFile(db, fileName);
|
|
265
|
+
await knex('t_task_file_links')
|
|
266
|
+
.insert({
|
|
267
|
+
task_id: taskId,
|
|
268
|
+
file_id: fileId,
|
|
269
|
+
})
|
|
270
|
+
.onConflict(['task_id', 'file_id'])
|
|
271
|
+
.ignore();
|
|
259
272
|
}
|
|
260
273
|
}
|
|
261
274
|
/**
|
|
262
275
|
* Get watched files for a task
|
|
263
276
|
*/
|
|
264
|
-
function getWatchedFiles(db, taskId) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
`)
|
|
272
|
-
.all(taskId).map((row) => row.path);
|
|
277
|
+
async function getWatchedFiles(db, taskId) {
|
|
278
|
+
const knex = db.getKnex();
|
|
279
|
+
const files = await knex('t_task_file_links as tfl')
|
|
280
|
+
.join('m_files as mf', 'tfl.file_id', 'mf.id')
|
|
281
|
+
.where('tfl.task_id', taskId)
|
|
282
|
+
.select('mf.path');
|
|
283
|
+
return files.map((row) => row.path);
|
|
273
284
|
}
|
|
274
285
|
//# sourceMappingURL=tasks.auto-pruning-partial.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.auto-pruning-partial.test.js","sourceRoot":"","sources":["../../src/tests/tasks.auto-pruning-partial.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,
|
|
1
|
+
{"version":3,"file":"tasks.auto-pruning-partial.test.js","sourceRoot":"","sources":["../../src/tests/tasks.auto-pruning-partial.test.ts"],"names":[],"mappings":"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"}
|