sqlew 3.2.4 → 3.5.3
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 +843 -0
- package/README.md +53 -2
- package/assets/schema.sql +6 -1
- package/dist/config/loader.d.ts +46 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +151 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/types.d.ts +77 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +28 -0
- package/dist/config/types.js.map +1 -0
- package/dist/constants.d.ts +9 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +10 -0
- package/dist/constants.js.map +1 -1
- package/dist/database.d.ts +1 -1
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +84 -15
- package/dist/database.js.map +1 -1
- package/dist/index.js +21 -3
- package/dist/index.js.map +1 -1
- package/dist/migrations/add-v3.5.0-pruned-files.d.ts +26 -0
- package/dist/migrations/add-v3.5.0-pruned-files.d.ts.map +1 -0
- package/dist/migrations/add-v3.5.0-pruned-files.js +107 -0
- package/dist/migrations/add-v3.5.0-pruned-files.js.map +1 -0
- package/dist/migrations/index.d.ts +2 -1
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +16 -1
- package/dist/migrations/index.js.map +1 -1
- package/dist/tests/git-aware-completion.test.d.ts +6 -0
- package/dist/tests/git-aware-completion.test.d.ts.map +1 -0
- package/dist/tests/git-aware-completion.test.js +141 -0
- package/dist/tests/git-aware-completion.test.js.map +1 -0
- package/dist/tests/tasks.auto-pruning-decision-link.test.d.ts +6 -0
- package/dist/tests/tasks.auto-pruning-decision-link.test.d.ts.map +1 -0
- package/dist/tests/tasks.auto-pruning-decision-link.test.js +250 -0
- package/dist/tests/tasks.auto-pruning-decision-link.test.js.map +1 -0
- package/dist/tests/tasks.auto-pruning-partial.test.d.ts +6 -0
- package/dist/tests/tasks.auto-pruning-partial.test.d.ts.map +1 -0
- package/dist/tests/tasks.auto-pruning-partial.test.js +274 -0
- package/dist/tests/tasks.auto-pruning-partial.test.js.map +1 -0
- package/dist/tests/tasks.auto-pruning-persistence.test.d.ts +6 -0
- package/dist/tests/tasks.auto-pruning-persistence.test.d.ts.map +1 -0
- package/dist/tests/tasks.auto-pruning-persistence.test.js +232 -0
- package/dist/tests/tasks.auto-pruning-persistence.test.js.map +1 -0
- package/dist/tests/tasks.auto-pruning-safety.test.d.ts +12 -0
- package/dist/tests/tasks.auto-pruning-safety.test.d.ts.map +1 -0
- package/dist/tests/tasks.auto-pruning-safety.test.js +196 -0
- package/dist/tests/tasks.auto-pruning-safety.test.js.map +1 -0
- package/dist/tests/tasks.link-file-backward-compat.test.d.ts +6 -0
- package/dist/tests/tasks.link-file-backward-compat.test.d.ts.map +1 -0
- package/dist/tests/tasks.link-file-backward-compat.test.js +235 -0
- package/dist/tests/tasks.link-file-backward-compat.test.js.map +1 -0
- package/dist/tests/tasks.watch-files-action.test.d.ts +6 -0
- package/dist/tests/tasks.watch-files-action.test.d.ts.map +1 -0
- package/dist/tests/tasks.watch-files-action.test.js +351 -0
- package/dist/tests/tasks.watch-files-action.test.js.map +1 -0
- package/dist/tests/tasks.watch-files-parameter.test.d.ts +6 -0
- package/dist/tests/tasks.watch-files-parameter.test.d.ts.map +1 -0
- package/dist/tests/tasks.watch-files-parameter.test.js +249 -0
- package/dist/tests/tasks.watch-files-parameter.test.js.map +1 -0
- package/dist/tests/two-step-git-completion.test.d.ts +6 -0
- package/dist/tests/two-step-git-completion.test.d.ts.map +1 -0
- package/dist/tests/two-step-git-completion.test.js +283 -0
- package/dist/tests/two-step-git-completion.test.js.map +1 -0
- package/dist/tests/vcs-staging.test.d.ts +6 -0
- package/dist/tests/vcs-staging.test.d.ts.map +1 -0
- package/dist/tests/vcs-staging.test.js +137 -0
- package/dist/tests/vcs-staging.test.js.map +1 -0
- package/dist/tools/config.d.ts +4 -2
- package/dist/tools/config.d.ts.map +1 -1
- package/dist/tools/config.js +13 -11
- package/dist/tools/config.js.map +1 -1
- package/dist/tools/constraints.d.ts +7 -4
- package/dist/tools/constraints.d.ts.map +1 -1
- package/dist/tools/constraints.js +19 -16
- package/dist/tools/constraints.js.map +1 -1
- package/dist/tools/context.d.ts +33 -17
- package/dist/tools/context.d.ts.map +1 -1
- package/dist/tools/context.js +84 -68
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/files.d.ts +9 -5
- package/dist/tools/files.d.ts.map +1 -1
- package/dist/tools/files.js +19 -15
- package/dist/tools/files.js.map +1 -1
- package/dist/tools/messaging.d.ts +9 -5
- package/dist/tools/messaging.d.ts.map +1 -1
- package/dist/tools/messaging.js +20 -16
- package/dist/tools/messaging.js.map +1 -1
- package/dist/tools/tasks.d.ts +40 -12
- package/dist/tools/tasks.d.ts.map +1 -1
- package/dist/tools/tasks.js +475 -87
- package/dist/tools/tasks.js.map +1 -1
- package/dist/tools/utils.d.ts +11 -6
- package/dist/tools/utils.d.ts.map +1 -1
- package/dist/tools/utils.js +56 -44
- package/dist/tools/utils.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/file-pruning.d.ts +69 -0
- package/dist/utils/file-pruning.d.ts.map +1 -0
- package/dist/utils/file-pruning.js +185 -0
- package/dist/utils/file-pruning.js.map +1 -0
- package/dist/utils/quality-checks.d.ts +60 -0
- package/dist/utils/quality-checks.d.ts.map +1 -0
- package/dist/utils/quality-checks.js +228 -0
- package/dist/utils/quality-checks.js.map +1 -0
- package/dist/utils/retention.d.ts +8 -0
- package/dist/utils/retention.d.ts.map +1 -1
- package/dist/utils/retention.js +12 -0
- package/dist/utils/retention.js.map +1 -1
- package/dist/utils/task-stale-detection.d.ts +69 -1
- package/dist/utils/task-stale-detection.d.ts.map +1 -1
- package/dist/utils/task-stale-detection.js +494 -17
- package/dist/utils/task-stale-detection.js.map +1 -1
- package/dist/utils/validators.d.ts +2 -2
- package/dist/utils/validators.d.ts.map +1 -1
- package/dist/utils/validators.js +11 -2
- package/dist/utils/validators.js.map +1 -1
- package/dist/utils/vcs-adapter.d.ts +68 -0
- package/dist/utils/vcs-adapter.d.ts.map +1 -0
- package/dist/utils/vcs-adapter.js +187 -0
- package/dist/utils/vcs-adapter.js.map +1 -0
- package/dist/watcher/file-watcher.d.ts +54 -4
- package/dist/watcher/file-watcher.d.ts.map +1 -1
- package/dist/watcher/file-watcher.js +312 -30
- package/dist/watcher/file-watcher.js.map +1 -1
- package/dist/watcher/gitignore-parser.d.ts +70 -0
- package/dist/watcher/gitignore-parser.d.ts.map +1 -0
- package/dist/watcher/gitignore-parser.js +191 -0
- package/dist/watcher/gitignore-parser.js.map +1 -0
- package/dist/watcher/index.d.ts +1 -0
- package/dist/watcher/index.d.ts.map +1 -1
- package/dist/watcher/index.js +1 -0
- package/dist/watcher/index.js.map +1 -1
- package/docs/AI_AGENT_GUIDE.md +1 -1
- package/docs/ARCHITECTURE.md +12 -0
- package/docs/AUTO_FILE_TRACKING.md +486 -82
- package/docs/CONFIGURATION.md +908 -0
- package/docs/GIT_AWARE_AUTO_COMPLETE.md +645 -0
- package/docs/MIGRATION_v3.3.md +602 -0
- package/docs/SHARED_CONCEPTS.md +2 -1
- package/docs/TASK_ACTIONS.md +12 -0
- package/docs/TASK_OVERVIEW.md +124 -23
- package/docs/TASK_PRUNING.md +589 -0
- package/docs/TASK_SYSTEM.md +83 -13
- package/docs/TOOL_REFERENCE.md +94 -6
- package/package.json +8 -6
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git-Aware Auto-Complete Tests (v3.4.0)
|
|
3
|
+
* Tests for detectAndCompleteReviewedTasks function
|
|
4
|
+
*/
|
|
5
|
+
import { describe, it, before, after } from 'node:test';
|
|
6
|
+
import assert from 'node:assert';
|
|
7
|
+
import Database from 'better-sqlite3';
|
|
8
|
+
import { unlinkSync, existsSync, mkdirSync } from 'fs';
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
import { execSync } from 'child_process';
|
|
11
|
+
import { initializeSchema } from '../schema.js';
|
|
12
|
+
import { detectAndCompleteReviewedTasks } from '../utils/task-stale-detection.js';
|
|
13
|
+
const TEST_DB_PATH = join(process.cwd(), 'test-git-aware.db');
|
|
14
|
+
const TEST_DIR = join(process.cwd(), 'test-tracking');
|
|
15
|
+
// Helper to clean up test database
|
|
16
|
+
function cleanupTestDb() {
|
|
17
|
+
if (existsSync(TEST_DB_PATH)) {
|
|
18
|
+
unlinkSync(TEST_DB_PATH);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
describe('Git-Aware Auto-Complete', () => {
|
|
22
|
+
let db;
|
|
23
|
+
before(() => {
|
|
24
|
+
// Clean up before tests
|
|
25
|
+
cleanupTestDb();
|
|
26
|
+
// Create test database
|
|
27
|
+
db = new Database(TEST_DB_PATH);
|
|
28
|
+
db.pragma('foreign_keys = ON');
|
|
29
|
+
// Initialize schema
|
|
30
|
+
initializeSchema(db);
|
|
31
|
+
// Add test config for git auto-complete
|
|
32
|
+
db.prepare('INSERT OR REPLACE INTO m_config (key, value) VALUES (?, ?)').run('git_auto_complete_enabled', '1');
|
|
33
|
+
db.prepare('INSERT OR REPLACE INTO m_config (key, value) VALUES (?, ?)').run('require_all_files_committed', '1');
|
|
34
|
+
// Create test directory
|
|
35
|
+
if (!existsSync(TEST_DIR)) {
|
|
36
|
+
mkdirSync(TEST_DIR, { recursive: true });
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
after(() => {
|
|
40
|
+
// Close database
|
|
41
|
+
if (db) {
|
|
42
|
+
db.close();
|
|
43
|
+
}
|
|
44
|
+
// Clean up test database and directory
|
|
45
|
+
cleanupTestDb();
|
|
46
|
+
});
|
|
47
|
+
it('should auto-complete task when all watched files are committed', async () => {
|
|
48
|
+
// 1. Create a task in waiting_review status with watched files
|
|
49
|
+
const agentId = db.prepare('INSERT INTO m_agents (name) VALUES (?)').run('test-agent').lastInsertRowid;
|
|
50
|
+
const statusId = db.prepare('SELECT id FROM m_task_statuses WHERE name = ?').get('waiting_review');
|
|
51
|
+
const taskId = db.prepare(`
|
|
52
|
+
INSERT INTO t_tasks (assigned_agent_id, status_id, priority, created_ts, updated_ts)
|
|
53
|
+
VALUES (?, ?, 2, unixepoch(), unixepoch())
|
|
54
|
+
`).run(agentId, statusId.id).lastInsertRowid;
|
|
55
|
+
db.prepare('INSERT INTO t_task_details (task_id, title) VALUES (?, ?)').run(taskId, 'Test git-aware task');
|
|
56
|
+
// 2. Add watched files
|
|
57
|
+
const file1Id = db.prepare('INSERT INTO m_files (path) VALUES (?)').run('test-tracking/file1.ts').lastInsertRowid;
|
|
58
|
+
const file2Id = db.prepare('INSERT INTO m_files (path) VALUES (?)').run('test-tracking/file2.ts').lastInsertRowid;
|
|
59
|
+
db.prepare('INSERT INTO t_task_file_links (task_id, file_id, link_type) VALUES (?, ?, ?)').run(taskId, file1Id, 'watch');
|
|
60
|
+
db.prepare('INSERT INTO t_task_file_links (task_id, file_id, link_type) VALUES (?, ?, ?)').run(taskId, file2Id, 'watch');
|
|
61
|
+
// 3. Commit the files to git
|
|
62
|
+
execSync(`touch ${TEST_DIR}/file1.ts`);
|
|
63
|
+
execSync(`touch ${TEST_DIR}/file2.ts`);
|
|
64
|
+
execSync(`git add ${TEST_DIR}/file1.ts ${TEST_DIR}/file2.ts`);
|
|
65
|
+
execSync(`git commit -m "Test commit for git-aware completion"`);
|
|
66
|
+
// 4. Run git-aware auto-complete
|
|
67
|
+
const completedCount = await detectAndCompleteReviewedTasks(db);
|
|
68
|
+
// 5. Verify task was auto-completed
|
|
69
|
+
assert.strictEqual(completedCount, 1, 'Should auto-complete 1 task');
|
|
70
|
+
const task = db.prepare('SELECT status_id FROM t_tasks WHERE id = ?').get(taskId);
|
|
71
|
+
const doneStatusId = db.prepare('SELECT id FROM m_task_statuses WHERE name = ?').get('done');
|
|
72
|
+
assert.strictEqual(task.status_id, doneStatusId.id, 'Task should be in done status');
|
|
73
|
+
});
|
|
74
|
+
it('should NOT auto-complete task when only some files are committed', async () => {
|
|
75
|
+
// 1. Create a task in waiting_review
|
|
76
|
+
const agentId = db.prepare('SELECT id FROM m_agents WHERE name = ?').get('test-agent');
|
|
77
|
+
const statusId = db.prepare('SELECT id FROM m_task_statuses WHERE name = ?').get('waiting_review');
|
|
78
|
+
const taskId = db.prepare(`
|
|
79
|
+
INSERT INTO t_tasks (assigned_agent_id, status_id, priority, created_ts, updated_ts)
|
|
80
|
+
VALUES (?, ?, 2, unixepoch(), unixepoch())
|
|
81
|
+
`).run(agentId.id, statusId.id).lastInsertRowid;
|
|
82
|
+
db.prepare('INSERT INTO t_task_details (task_id, title) VALUES (?, ?)').run(taskId, 'Partial commit task');
|
|
83
|
+
// 2. Add watched files
|
|
84
|
+
const file3Id = db.prepare('INSERT INTO m_files (path) VALUES (?)').run('test-tracking/file3.ts').lastInsertRowid;
|
|
85
|
+
const file4Id = db.prepare('INSERT INTO m_files (path) VALUES (?)').run('test-tracking/file4.ts').lastInsertRowid;
|
|
86
|
+
db.prepare('INSERT INTO t_task_file_links (task_id, file_id, link_type) VALUES (?, ?, ?)').run(taskId, file3Id, 'watch');
|
|
87
|
+
db.prepare('INSERT INTO t_task_file_links (task_id, file_id, link_type) VALUES (?, ?, ?)').run(taskId, file4Id, 'watch');
|
|
88
|
+
// 3. Commit only ONE file
|
|
89
|
+
execSync(`touch ${TEST_DIR}/file3.ts`);
|
|
90
|
+
execSync(`git add ${TEST_DIR}/file3.ts`);
|
|
91
|
+
execSync(`git commit -m "Partial commit - only file3"`);
|
|
92
|
+
// 4. Run git-aware auto-complete
|
|
93
|
+
const completedCount = await detectAndCompleteReviewedTasks(db);
|
|
94
|
+
// 5. Verify task was NOT auto-completed (still in waiting_review)
|
|
95
|
+
assert.strictEqual(completedCount, 0, 'Should NOT auto-complete task with partial commits');
|
|
96
|
+
const task = db.prepare('SELECT status_id FROM t_tasks WHERE id = ?').get(taskId);
|
|
97
|
+
const waitingReviewStatusId = db.prepare('SELECT id FROM m_task_statuses WHERE name = ?').get('waiting_review');
|
|
98
|
+
assert.strictEqual(task.status_id, waitingReviewStatusId.id, 'Task should still be in waiting_review status');
|
|
99
|
+
});
|
|
100
|
+
it('should skip tasks with no watched files', async () => {
|
|
101
|
+
// 1. Create a task in waiting_review with NO watched files
|
|
102
|
+
const agentId = db.prepare('SELECT id FROM m_agents WHERE name = ?').get('test-agent');
|
|
103
|
+
const statusId = db.prepare('SELECT id FROM m_task_statuses WHERE name = ?').get('waiting_review');
|
|
104
|
+
const taskId = db.prepare(`
|
|
105
|
+
INSERT INTO t_tasks (assigned_agent_id, status_id, priority, created_ts, updated_ts)
|
|
106
|
+
VALUES (?, ?, 2, unixepoch(), unixepoch())
|
|
107
|
+
`).run(agentId.id, statusId.id).lastInsertRowid;
|
|
108
|
+
db.prepare('INSERT INTO t_task_details (task_id, title) VALUES (?, ?)').run(taskId, 'No watched files task');
|
|
109
|
+
// 2. Run git-aware auto-complete
|
|
110
|
+
const completedCount = await detectAndCompleteReviewedTasks(db);
|
|
111
|
+
// 3. Verify no tasks were auto-completed
|
|
112
|
+
assert.strictEqual(completedCount, 0, 'Should skip tasks with no watched files');
|
|
113
|
+
const task = db.prepare('SELECT status_id FROM t_tasks WHERE id = ?').get(taskId);
|
|
114
|
+
const waitingReviewStatusId = db.prepare('SELECT id FROM m_task_statuses WHERE name = ?').get('waiting_review');
|
|
115
|
+
assert.strictEqual(task.status_id, waitingReviewStatusId.id, 'Task should still be in waiting_review status');
|
|
116
|
+
});
|
|
117
|
+
it('should respect git_auto_complete_enabled config', async () => {
|
|
118
|
+
// 1. Disable git auto-complete
|
|
119
|
+
db.prepare('UPDATE m_config SET value = ? WHERE key = ?').run('0', 'git_auto_complete_enabled');
|
|
120
|
+
// 2. Create a task with all files committed
|
|
121
|
+
const agentId = db.prepare('SELECT id FROM m_agents WHERE name = ?').get('test-agent');
|
|
122
|
+
const statusId = db.prepare('SELECT id FROM m_task_statuses WHERE name = ?').get('waiting_review');
|
|
123
|
+
const taskId = db.prepare(`
|
|
124
|
+
INSERT INTO t_tasks (assigned_agent_id, status_id, priority, created_ts, updated_ts)
|
|
125
|
+
VALUES (?, ?, 2, unixepoch(), unixepoch())
|
|
126
|
+
`).run(agentId.id, statusId.id).lastInsertRowid;
|
|
127
|
+
db.prepare('INSERT INTO t_task_details (task_id, title) VALUES (?, ?)').run(taskId, 'Config disabled task');
|
|
128
|
+
const file5Id = db.prepare('INSERT INTO m_files (path) VALUES (?)').run('test-tracking/file5.ts').lastInsertRowid;
|
|
129
|
+
db.prepare('INSERT INTO t_task_file_links (task_id, file_id, link_type) VALUES (?, ?, ?)').run(taskId, file5Id, 'watch');
|
|
130
|
+
execSync(`touch ${TEST_DIR}/file5.ts`);
|
|
131
|
+
execSync(`git add ${TEST_DIR}/file5.ts`);
|
|
132
|
+
execSync(`git commit -m "Test with config disabled"`);
|
|
133
|
+
// 3. Run git-aware auto-complete (should skip due to config)
|
|
134
|
+
const completedCount = await detectAndCompleteReviewedTasks(db);
|
|
135
|
+
// 4. Verify no tasks were auto-completed
|
|
136
|
+
assert.strictEqual(completedCount, 0, 'Should respect disabled config');
|
|
137
|
+
// Re-enable for other tests
|
|
138
|
+
db.prepare('UPDATE m_config SET value = ? WHERE key = ?').run('1', 'git_auto_complete_enabled');
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
//# sourceMappingURL=git-aware-completion.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-aware-completion.test.js","sourceRoot":"","sources":["../../src/tests/git-aware-completion.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration tests for Decision Linking to Pruned Files (v3.5.0 Auto-Pruning)
|
|
3
|
+
* Tests the workflow of linking decisions to pruned files for WHY reasoning (project archaeology)
|
|
4
|
+
*/
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=tasks.auto-pruning-decision-link.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.auto-pruning-decision-link.test.d.ts","sourceRoot":"","sources":["../../src/tests/tasks.auto-pruning-decision-link.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration tests for Decision Linking to Pruned Files (v3.5.0 Auto-Pruning)
|
|
3
|
+
* Tests the workflow of linking decisions to pruned files for WHY reasoning (project archaeology)
|
|
4
|
+
*/
|
|
5
|
+
import { describe, it, beforeEach } from 'node:test';
|
|
6
|
+
import assert from 'node:assert/strict';
|
|
7
|
+
import Database from 'better-sqlite3';
|
|
8
|
+
import { initializeSchema } from '../schema.js';
|
|
9
|
+
import { runAllMigrations } from '../migrations/index.js';
|
|
10
|
+
import { getOrCreateAgent } from '../database.js';
|
|
11
|
+
import { setDecision } from '../tools/context.js';
|
|
12
|
+
import { getPrunedFiles, linkPrunedFile } from '../tools/tasks.js';
|
|
13
|
+
/**
|
|
14
|
+
* Test database instance
|
|
15
|
+
*/
|
|
16
|
+
let testDb;
|
|
17
|
+
/**
|
|
18
|
+
* Create an in-memory test database
|
|
19
|
+
*/
|
|
20
|
+
function createTestDatabase() {
|
|
21
|
+
const db = new Database(':memory:');
|
|
22
|
+
db.pragma('foreign_keys = ON');
|
|
23
|
+
initializeSchema(db);
|
|
24
|
+
runAllMigrations(db);
|
|
25
|
+
return db;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Helper: Create a test task
|
|
29
|
+
*/
|
|
30
|
+
function createTestTask(db, title) {
|
|
31
|
+
const agentId = getOrCreateAgent(db, 'test-agent');
|
|
32
|
+
const statusId = 2; // in_progress
|
|
33
|
+
const result = db.prepare(`
|
|
34
|
+
INSERT INTO t_tasks (title, status_id, priority, created_by_agent_id, assigned_agent_id)
|
|
35
|
+
VALUES (?, ?, 2, ?, ?)
|
|
36
|
+
`).run(title, statusId, agentId, agentId);
|
|
37
|
+
return result.lastInsertRowid;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Helper: Create a pruned file record
|
|
41
|
+
*/
|
|
42
|
+
function createPrunedFileRecord(db, taskId, filePath) {
|
|
43
|
+
const result = db.prepare(`
|
|
44
|
+
INSERT INTO t_task_pruned_files (task_id, file_path, pruned_ts)
|
|
45
|
+
VALUES (?, ?, unixepoch())
|
|
46
|
+
`).run(taskId, filePath);
|
|
47
|
+
return result.lastInsertRowid;
|
|
48
|
+
}
|
|
49
|
+
describe('Auto-pruning: Decision linking workflow', () => {
|
|
50
|
+
beforeEach(() => {
|
|
51
|
+
testDb = createTestDatabase();
|
|
52
|
+
});
|
|
53
|
+
it('should link decisions to pruned files for WHY reasoning', () => {
|
|
54
|
+
// 1. Setup: Create task with pruned file
|
|
55
|
+
const taskId = createTestTask(testDb, 'Implement OAuth authentication');
|
|
56
|
+
const prunedFileId = createPrunedFileRecord(testDb, taskId, 'src/auth/oauth-handler.ts');
|
|
57
|
+
// 2. Create decision explaining why file wasn't created
|
|
58
|
+
const decisionResult = setDecision({
|
|
59
|
+
key: 'oauth-not-implemented',
|
|
60
|
+
value: 'Decided to use API key auth instead of OAuth for simplicity',
|
|
61
|
+
tags: ['architecture', 'authentication'],
|
|
62
|
+
status: 'active'
|
|
63
|
+
}, testDb);
|
|
64
|
+
assert.ok(decisionResult.success, 'Decision creation should succeed');
|
|
65
|
+
assert.strictEqual(decisionResult.key, 'oauth-not-implemented');
|
|
66
|
+
// 3. Link decision to pruned file
|
|
67
|
+
const linkResult = linkPrunedFile({
|
|
68
|
+
pruned_file_id: prunedFileId,
|
|
69
|
+
decision_key: 'oauth-not-implemented'
|
|
70
|
+
}, testDb);
|
|
71
|
+
assert.ok(linkResult.success, 'Decision linking should succeed');
|
|
72
|
+
assert.strictEqual(linkResult.pruned_file_id, prunedFileId);
|
|
73
|
+
assert.strictEqual(linkResult.decision_key, 'oauth-not-implemented');
|
|
74
|
+
assert.strictEqual(linkResult.task_id, taskId);
|
|
75
|
+
assert.strictEqual(linkResult.file_path, 'src/auth/oauth-handler.ts');
|
|
76
|
+
// 4. Verify link in database directly
|
|
77
|
+
const linkedDecisionId = testDb.prepare(`
|
|
78
|
+
SELECT linked_decision_key_id FROM t_task_pruned_files WHERE id = ?
|
|
79
|
+
`).get(prunedFileId);
|
|
80
|
+
assert.ok(linkedDecisionId, 'Pruned file record should exist');
|
|
81
|
+
assert.ok(linkedDecisionId.linked_decision_key_id !== null, 'Decision key ID should be linked');
|
|
82
|
+
// 5. Query pruned files - decision key should be returned
|
|
83
|
+
const getPrunedResult = getPrunedFiles({
|
|
84
|
+
task_id: taskId,
|
|
85
|
+
limit: 100
|
|
86
|
+
}, testDb);
|
|
87
|
+
assert.ok(getPrunedResult.success, 'get_pruned_files should succeed');
|
|
88
|
+
assert.strictEqual(getPrunedResult.task_id, taskId);
|
|
89
|
+
assert.strictEqual(getPrunedResult.count, 1, 'Should return 1 pruned file');
|
|
90
|
+
assert.strictEqual(getPrunedResult.pruned_files.length, 1, 'pruned_files array should have 1 item');
|
|
91
|
+
const prunedFile = getPrunedResult.pruned_files[0];
|
|
92
|
+
assert.strictEqual(prunedFile.id, prunedFileId, 'Pruned file ID should match');
|
|
93
|
+
assert.strictEqual(prunedFile.file_path, 'src/auth/oauth-handler.ts', 'File path should match');
|
|
94
|
+
assert.ok(prunedFile.pruned_at, 'Should have pruned_at timestamp');
|
|
95
|
+
assert.ok(prunedFile.linked_decision, 'Should have linked_decision key');
|
|
96
|
+
assert.strictEqual(prunedFile.linked_decision, 'oauth-not-implemented', 'Linked decision key should match');
|
|
97
|
+
});
|
|
98
|
+
it('should handle multiple pruned files with different decisions', () => {
|
|
99
|
+
const taskId = createTestTask(testDb, 'Feature implementation');
|
|
100
|
+
// Create pruned files
|
|
101
|
+
const prunedFileId1 = createPrunedFileRecord(testDb, taskId, 'src/oauth-handler.ts');
|
|
102
|
+
const prunedFileId2 = createPrunedFileRecord(testDb, taskId, 'src/ldap-connector.ts');
|
|
103
|
+
// Create decisions
|
|
104
|
+
setDecision({
|
|
105
|
+
key: 'no-oauth',
|
|
106
|
+
value: 'OAuth not needed for MVP',
|
|
107
|
+
status: 'active'
|
|
108
|
+
}, testDb);
|
|
109
|
+
setDecision({
|
|
110
|
+
key: 'no-ldap',
|
|
111
|
+
value: 'LDAP integration deferred to Phase 2',
|
|
112
|
+
status: 'active'
|
|
113
|
+
}, testDb);
|
|
114
|
+
// Link decisions
|
|
115
|
+
linkPrunedFile({
|
|
116
|
+
pruned_file_id: prunedFileId1,
|
|
117
|
+
decision_key: 'no-oauth'
|
|
118
|
+
}, testDb);
|
|
119
|
+
linkPrunedFile({
|
|
120
|
+
pruned_file_id: prunedFileId2,
|
|
121
|
+
decision_key: 'no-ldap'
|
|
122
|
+
}, testDb);
|
|
123
|
+
// Verify
|
|
124
|
+
const getPrunedResult = getPrunedFiles({
|
|
125
|
+
task_id: taskId
|
|
126
|
+
}, testDb);
|
|
127
|
+
assert.strictEqual(getPrunedResult.count, 2, 'Should have 2 pruned files');
|
|
128
|
+
const file1 = getPrunedResult.pruned_files.find((f) => f.file_path === 'src/oauth-handler.ts');
|
|
129
|
+
const file2 = getPrunedResult.pruned_files.find((f) => f.file_path === 'src/ldap-connector.ts');
|
|
130
|
+
assert.ok(file1, 'Should find oauth-handler.ts');
|
|
131
|
+
assert.ok(file2, 'Should find ldap-connector.ts');
|
|
132
|
+
assert.strictEqual(file1?.linked_decision, 'no-oauth');
|
|
133
|
+
assert.strictEqual(file2?.linked_decision, 'no-ldap');
|
|
134
|
+
});
|
|
135
|
+
it('should handle pruned files without linked decisions', () => {
|
|
136
|
+
const taskId = createTestTask(testDb, 'Task with unlinked pruned files');
|
|
137
|
+
createPrunedFileRecord(testDb, taskId, 'src/temp-file.ts');
|
|
138
|
+
const getPrunedResult = getPrunedFiles({
|
|
139
|
+
task_id: taskId
|
|
140
|
+
}, testDb);
|
|
141
|
+
assert.ok(getPrunedResult.success);
|
|
142
|
+
assert.strictEqual(getPrunedResult.count, 1);
|
|
143
|
+
const prunedFile = getPrunedResult.pruned_files[0];
|
|
144
|
+
assert.strictEqual(prunedFile.linked_decision, null, 'Unlinked file should have null decision');
|
|
145
|
+
});
|
|
146
|
+
it('should handle linking to non-existent decision gracefully', () => {
|
|
147
|
+
const taskId = createTestTask(testDb, 'Task for error test');
|
|
148
|
+
const prunedFileId = createPrunedFileRecord(testDb, taskId, 'src/test.ts');
|
|
149
|
+
// Attempt to link non-existent decision
|
|
150
|
+
assert.throws(() => {
|
|
151
|
+
linkPrunedFile({
|
|
152
|
+
pruned_file_id: prunedFileId,
|
|
153
|
+
decision_key: 'does-not-exist'
|
|
154
|
+
}, testDb);
|
|
155
|
+
}, /Decision not found: does-not-exist/, 'Should throw error for non-existent decision');
|
|
156
|
+
});
|
|
157
|
+
it('should handle linking to non-existent pruned file gracefully', () => {
|
|
158
|
+
// Create decision
|
|
159
|
+
setDecision({
|
|
160
|
+
key: 'test-decision',
|
|
161
|
+
value: 'Test decision value',
|
|
162
|
+
status: 'active'
|
|
163
|
+
}, testDb);
|
|
164
|
+
// Attempt to link non-existent pruned file
|
|
165
|
+
assert.throws(() => {
|
|
166
|
+
linkPrunedFile({
|
|
167
|
+
pruned_file_id: 99999,
|
|
168
|
+
decision_key: 'test-decision'
|
|
169
|
+
}, testDb);
|
|
170
|
+
}, /Pruned file record not found: 99999/, 'Should throw error for non-existent pruned file');
|
|
171
|
+
});
|
|
172
|
+
it('should validate required parameters for linkPrunedFile', () => {
|
|
173
|
+
// Missing pruned_file_id
|
|
174
|
+
assert.throws(() => {
|
|
175
|
+
linkPrunedFile({
|
|
176
|
+
pruned_file_id: 0,
|
|
177
|
+
decision_key: 'test'
|
|
178
|
+
}, testDb);
|
|
179
|
+
}, /pruned_file_id is required and must be a number/, 'Should throw for invalid pruned_file_id');
|
|
180
|
+
// Missing decision_key
|
|
181
|
+
assert.throws(() => {
|
|
182
|
+
linkPrunedFile({
|
|
183
|
+
pruned_file_id: 1,
|
|
184
|
+
decision_key: ''
|
|
185
|
+
}, testDb);
|
|
186
|
+
}, /decision_key is required and must be a string/, 'Should throw for empty decision_key');
|
|
187
|
+
});
|
|
188
|
+
it('should validate required parameters for getPrunedFiles', () => {
|
|
189
|
+
// Missing task_id
|
|
190
|
+
assert.throws(() => {
|
|
191
|
+
getPrunedFiles({
|
|
192
|
+
task_id: 0
|
|
193
|
+
}, testDb);
|
|
194
|
+
}, /task_id is required and must be a number/, 'Should throw for invalid task_id');
|
|
195
|
+
// Non-existent task
|
|
196
|
+
assert.throws(() => {
|
|
197
|
+
getPrunedFiles({
|
|
198
|
+
task_id: 99999
|
|
199
|
+
}, testDb);
|
|
200
|
+
}, /Task not found: 99999/, 'Should throw for non-existent task');
|
|
201
|
+
});
|
|
202
|
+
it('should allow updating linked decision for a pruned file', () => {
|
|
203
|
+
const taskId = createTestTask(testDb, 'Task for update test');
|
|
204
|
+
const prunedFileId = createPrunedFileRecord(testDb, taskId, 'src/feature.ts');
|
|
205
|
+
// Create two decisions
|
|
206
|
+
setDecision({
|
|
207
|
+
key: 'decision-v1',
|
|
208
|
+
value: 'Initial decision',
|
|
209
|
+
status: 'active'
|
|
210
|
+
}, testDb);
|
|
211
|
+
setDecision({
|
|
212
|
+
key: 'decision-v2',
|
|
213
|
+
value: 'Updated decision',
|
|
214
|
+
status: 'active'
|
|
215
|
+
}, testDb);
|
|
216
|
+
// Link first decision
|
|
217
|
+
linkPrunedFile({
|
|
218
|
+
pruned_file_id: prunedFileId,
|
|
219
|
+
decision_key: 'decision-v1'
|
|
220
|
+
}, testDb);
|
|
221
|
+
// Verify first link
|
|
222
|
+
let getPrunedResult = getPrunedFiles({ task_id: taskId }, testDb);
|
|
223
|
+
assert.strictEqual(getPrunedResult.pruned_files[0].linked_decision, 'decision-v1');
|
|
224
|
+
// Update to second decision
|
|
225
|
+
linkPrunedFile({
|
|
226
|
+
pruned_file_id: prunedFileId,
|
|
227
|
+
decision_key: 'decision-v2'
|
|
228
|
+
}, testDb);
|
|
229
|
+
// Verify updated link
|
|
230
|
+
getPrunedResult = getPrunedFiles({ task_id: taskId }, testDb);
|
|
231
|
+
assert.strictEqual(getPrunedResult.pruned_files[0].linked_decision, 'decision-v2');
|
|
232
|
+
});
|
|
233
|
+
it('should respect limit parameter in getPrunedFiles', () => {
|
|
234
|
+
const taskId = createTestTask(testDb, 'Task with many pruned files');
|
|
235
|
+
// Create 5 pruned files
|
|
236
|
+
for (let i = 1; i <= 5; i++) {
|
|
237
|
+
createPrunedFileRecord(testDb, taskId, `src/file${i}.ts`);
|
|
238
|
+
}
|
|
239
|
+
// Query with limit
|
|
240
|
+
const getPrunedResult = getPrunedFiles({
|
|
241
|
+
task_id: taskId,
|
|
242
|
+
limit: 3
|
|
243
|
+
}, testDb);
|
|
244
|
+
assert.ok(getPrunedResult.success);
|
|
245
|
+
assert.strictEqual(getPrunedResult.count, 3, 'Should respect limit parameter');
|
|
246
|
+
assert.strictEqual(getPrunedResult.pruned_files.length, 3);
|
|
247
|
+
});
|
|
248
|
+
console.log('\n✅ All decision linking to pruned files tests passed!\n');
|
|
249
|
+
});
|
|
250
|
+
//# sourceMappingURL=tasks.auto-pruning-decision-link.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.auto-pruning-decision-link.test.js","sourceRoot":"","sources":["../../src/tests/tasks.auto-pruning-decision-link.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.auto-pruning-partial.test.d.ts","sourceRoot":"","sources":["../../src/tests/tasks.auto-pruning-partial.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|