@promptwheel/core 0.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/dist/codebase-index/index.d.ts +23 -0
- package/dist/codebase-index/index.d.ts.map +1 -0
- package/dist/codebase-index/index.js +361 -0
- package/dist/codebase-index/index.js.map +1 -0
- package/dist/codebase-index/shared.d.ts +95 -0
- package/dist/codebase-index/shared.d.ts.map +1 -0
- package/dist/codebase-index/shared.js +319 -0
- package/dist/codebase-index/shared.js.map +1 -0
- package/dist/config/defaults.d.ts +45 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +79 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/critic/shared.d.ts +49 -0
- package/dist/critic/shared.d.ts.map +1 -0
- package/dist/critic/shared.js +204 -0
- package/dist/critic/shared.js.map +1 -0
- package/dist/db/adapter.d.ts +191 -0
- package/dist/db/adapter.d.ts.map +1 -0
- package/dist/db/adapter.js +40 -0
- package/dist/db/adapter.js.map +1 -0
- package/dist/db/contract.d.ts +47 -0
- package/dist/db/contract.d.ts.map +1 -0
- package/dist/db/contract.js +258 -0
- package/dist/db/contract.js.map +1 -0
- package/dist/db/index.d.ts +6 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +7 -0
- package/dist/db/index.js.map +1 -0
- package/dist/dedup/shared.d.ts +82 -0
- package/dist/dedup/shared.d.ts.map +1 -0
- package/dist/dedup/shared.js +215 -0
- package/dist/dedup/shared.js.map +1 -0
- package/dist/exec/index.d.ts +5 -0
- package/dist/exec/index.d.ts.map +1 -0
- package/dist/exec/index.js +5 -0
- package/dist/exec/index.js.map +1 -0
- package/dist/exec/types.d.ts +64 -0
- package/dist/exec/types.d.ts.map +1 -0
- package/dist/exec/types.js +8 -0
- package/dist/exec/types.js.map +1 -0
- package/dist/formulas/shared.d.ts +42 -0
- package/dist/formulas/shared.d.ts.map +1 -0
- package/dist/formulas/shared.js +204 -0
- package/dist/formulas/shared.js.map +1 -0
- package/dist/guidelines/shared.d.ts +46 -0
- package/dist/guidelines/shared.d.ts.map +1 -0
- package/dist/guidelines/shared.js +128 -0
- package/dist/guidelines/shared.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/learnings/shared.d.ts +112 -0
- package/dist/learnings/shared.d.ts.map +1 -0
- package/dist/learnings/shared.js +402 -0
- package/dist/learnings/shared.js.map +1 -0
- package/dist/proposals/shared.d.ts +137 -0
- package/dist/proposals/shared.d.ts.map +1 -0
- package/dist/proposals/shared.js +254 -0
- package/dist/proposals/shared.js.map +1 -0
- package/dist/repos/index.d.ts +15 -0
- package/dist/repos/index.d.ts.map +1 -0
- package/dist/repos/index.js +11 -0
- package/dist/repos/index.js.map +1 -0
- package/dist/repos/projects.d.ts +41 -0
- package/dist/repos/projects.d.ts.map +1 -0
- package/dist/repos/projects.js +75 -0
- package/dist/repos/projects.js.map +1 -0
- package/dist/repos/run_steps.d.ts +152 -0
- package/dist/repos/run_steps.d.ts.map +1 -0
- package/dist/repos/run_steps.js +328 -0
- package/dist/repos/run_steps.js.map +1 -0
- package/dist/repos/runs.d.ts +92 -0
- package/dist/repos/runs.d.ts.map +1 -0
- package/dist/repos/runs.js +185 -0
- package/dist/repos/runs.js.map +1 -0
- package/dist/repos/tickets.d.ts +71 -0
- package/dist/repos/tickets.d.ts.map +1 -0
- package/dist/repos/tickets.js +158 -0
- package/dist/repos/tickets.js.map +1 -0
- package/dist/scope/shared.d.ts +67 -0
- package/dist/scope/shared.d.ts.map +1 -0
- package/dist/scope/shared.js +355 -0
- package/dist/scope/shared.js.map +1 -0
- package/dist/scout/index.d.ts +18 -0
- package/dist/scout/index.d.ts.map +1 -0
- package/dist/scout/index.js +445 -0
- package/dist/scout/index.js.map +1 -0
- package/dist/scout/kimi-runner.d.ts +21 -0
- package/dist/scout/kimi-runner.d.ts.map +1 -0
- package/dist/scout/kimi-runner.js +76 -0
- package/dist/scout/kimi-runner.js.map +1 -0
- package/dist/scout/mcp-batch-server.d.ts +37 -0
- package/dist/scout/mcp-batch-server.d.ts.map +1 -0
- package/dist/scout/mcp-batch-server.js +144 -0
- package/dist/scout/mcp-batch-server.js.map +1 -0
- package/dist/scout/openai-local-runner.d.ts +20 -0
- package/dist/scout/openai-local-runner.d.ts.map +1 -0
- package/dist/scout/openai-local-runner.js +82 -0
- package/dist/scout/openai-local-runner.js.map +1 -0
- package/dist/scout/prompt.d.ts +49 -0
- package/dist/scout/prompt.d.ts.map +1 -0
- package/dist/scout/prompt.js +153 -0
- package/dist/scout/prompt.js.map +1 -0
- package/dist/scout/runner.d.ts +101 -0
- package/dist/scout/runner.d.ts.map +1 -0
- package/dist/scout/runner.js +521 -0
- package/dist/scout/runner.js.map +1 -0
- package/dist/scout/scanner.d.ts +61 -0
- package/dist/scout/scanner.d.ts.map +1 -0
- package/dist/scout/scanner.js +315 -0
- package/dist/scout/scanner.js.map +1 -0
- package/dist/scout/types.d.ts +221 -0
- package/dist/scout/types.d.ts.map +1 -0
- package/dist/scout/types.js +44 -0
- package/dist/scout/types.js.map +1 -0
- package/dist/sectors/shared.d.ts +146 -0
- package/dist/sectors/shared.d.ts.map +1 -0
- package/dist/sectors/shared.js +408 -0
- package/dist/sectors/shared.js.map +1 -0
- package/dist/services/index.d.ts +10 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +9 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/qa.d.ts +76 -0
- package/dist/services/qa.d.ts.map +1 -0
- package/dist/services/qa.js +228 -0
- package/dist/services/qa.js.map +1 -0
- package/dist/services/scout.d.ts +164 -0
- package/dist/services/scout.d.ts.map +1 -0
- package/dist/services/scout.js +215 -0
- package/dist/services/scout.js.map +1 -0
- package/dist/spindle/shared.d.ts +14 -0
- package/dist/spindle/shared.d.ts.map +1 -0
- package/dist/spindle/shared.js +65 -0
- package/dist/spindle/shared.js.map +1 -0
- package/dist/tools/shared.d.ts +35 -0
- package/dist/tools/shared.d.ts.map +1 -0
- package/dist/tools/shared.js +247 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/trace/shared.d.ts +147 -0
- package/dist/trace/shared.d.ts.map +1 -0
- package/dist/trace/shared.js +414 -0
- package/dist/trace/shared.js.map +1 -0
- package/dist/trajectory/shared.d.ts +69 -0
- package/dist/trajectory/shared.d.ts.map +1 -0
- package/dist/trajectory/shared.js +336 -0
- package/dist/trajectory/shared.js.map +1 -0
- package/dist/utils/id.d.ts +12 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +24 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/utils/id.test.d.ts +5 -0
- package/dist/utils/id.test.d.ts.map +1 -0
- package/dist/utils/id.test.js +173 -0
- package/dist/utils/id.test.js.map +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/json.d.ts +9 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +19 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/waves/shared.d.ts +106 -0
- package/dist/waves/shared.d.ts.map +1 -0
- package/dist/waves/shared.js +356 -0
- package/dist/waves/shared.js.map +1 -0
- package/package.json +126 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run repository - Database operations for runs
|
|
3
|
+
*/
|
|
4
|
+
import { nanoid } from '../utils/id.js';
|
|
5
|
+
function rowToRun(row) {
|
|
6
|
+
return {
|
|
7
|
+
id: row.id,
|
|
8
|
+
ticketId: row.ticket_id,
|
|
9
|
+
projectId: row.project_id,
|
|
10
|
+
type: row.type,
|
|
11
|
+
status: row.status,
|
|
12
|
+
iteration: row.iteration,
|
|
13
|
+
maxIterations: row.max_iterations,
|
|
14
|
+
startedAt: row.started_at ? new Date(row.started_at) : null,
|
|
15
|
+
completedAt: row.completed_at ? new Date(row.completed_at) : null,
|
|
16
|
+
error: row.error,
|
|
17
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : {},
|
|
18
|
+
createdAt: new Date(row.created_at),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get run by ID
|
|
23
|
+
*/
|
|
24
|
+
export async function getById(db, id) {
|
|
25
|
+
const result = await db.query('SELECT * FROM runs WHERE id = $1', [id]);
|
|
26
|
+
return result.rows[0] ? rowToRun(result.rows[0]) : null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create a new run
|
|
30
|
+
*/
|
|
31
|
+
export async function create(db, opts) {
|
|
32
|
+
const id = `run_${nanoid(12)}`;
|
|
33
|
+
await db.query(`INSERT INTO runs (
|
|
34
|
+
id, ticket_id, project_id, type, status,
|
|
35
|
+
max_iterations, metadata, started_at
|
|
36
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, datetime('now'))`, [
|
|
37
|
+
id,
|
|
38
|
+
opts.ticketId ?? null,
|
|
39
|
+
opts.projectId,
|
|
40
|
+
opts.type,
|
|
41
|
+
'running',
|
|
42
|
+
opts.maxIterations ?? 10,
|
|
43
|
+
JSON.stringify(opts.metadata ?? {}),
|
|
44
|
+
]);
|
|
45
|
+
const run = await getById(db, id);
|
|
46
|
+
if (!run) {
|
|
47
|
+
throw new Error('Failed to create run');
|
|
48
|
+
}
|
|
49
|
+
return run;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Mark run as successful
|
|
53
|
+
*/
|
|
54
|
+
export async function markSuccess(db, id, metadata) {
|
|
55
|
+
return db.withTransaction(async (tx) => {
|
|
56
|
+
const result = await tx.query('SELECT * FROM runs WHERE id = $1', [id]);
|
|
57
|
+
if (!result.rows[0])
|
|
58
|
+
return null;
|
|
59
|
+
const existing = rowToRun(result.rows[0]);
|
|
60
|
+
const merged = { ...existing.metadata, ...metadata };
|
|
61
|
+
await tx.query(`UPDATE runs SET
|
|
62
|
+
status = 'success',
|
|
63
|
+
completed_at = datetime('now'),
|
|
64
|
+
metadata = $1
|
|
65
|
+
WHERE id = $2`, [JSON.stringify(merged), id]);
|
|
66
|
+
const updated = await tx.query('SELECT * FROM runs WHERE id = $1', [id]);
|
|
67
|
+
return updated.rows[0] ? rowToRun(updated.rows[0]) : null;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Mark run as failed
|
|
72
|
+
*/
|
|
73
|
+
export async function markFailure(db, id, error, metadata) {
|
|
74
|
+
return db.withTransaction(async (tx) => {
|
|
75
|
+
const result = await tx.query('SELECT * FROM runs WHERE id = $1', [id]);
|
|
76
|
+
if (!result.rows[0])
|
|
77
|
+
return null;
|
|
78
|
+
const existing = rowToRun(result.rows[0]);
|
|
79
|
+
const merged = { ...existing.metadata, ...metadata };
|
|
80
|
+
const errorMsg = error instanceof Error ? error.message : error;
|
|
81
|
+
await tx.query(`UPDATE runs SET
|
|
82
|
+
status = 'failure',
|
|
83
|
+
completed_at = datetime('now'),
|
|
84
|
+
error = $1,
|
|
85
|
+
metadata = $2
|
|
86
|
+
WHERE id = $3`, [errorMsg, JSON.stringify(merged), id]);
|
|
87
|
+
const updated = await tx.query('SELECT * FROM runs WHERE id = $1', [id]);
|
|
88
|
+
return updated.rows[0] ? rowToRun(updated.rows[0]) : null;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* List runs for a project
|
|
93
|
+
*/
|
|
94
|
+
export async function listByProject(db, projectId, opts) {
|
|
95
|
+
let sql = 'SELECT * FROM runs WHERE project_id = $1';
|
|
96
|
+
const params = [projectId];
|
|
97
|
+
let paramIndex = 2;
|
|
98
|
+
if (opts?.type) {
|
|
99
|
+
sql += ` AND type = $${paramIndex++}`;
|
|
100
|
+
params.push(opts.type);
|
|
101
|
+
}
|
|
102
|
+
if (opts?.status) {
|
|
103
|
+
const statuses = Array.isArray(opts.status) ? opts.status : [opts.status];
|
|
104
|
+
const placeholders = statuses.map(() => `$${paramIndex++}`).join(', ');
|
|
105
|
+
sql += ` AND status IN (${placeholders})`;
|
|
106
|
+
params.push(...statuses);
|
|
107
|
+
}
|
|
108
|
+
sql += ' ORDER BY created_at DESC';
|
|
109
|
+
if (opts?.limit !== undefined) {
|
|
110
|
+
sql += ` LIMIT $${paramIndex}`;
|
|
111
|
+
params.push(opts.limit);
|
|
112
|
+
}
|
|
113
|
+
const result = await db.query(sql, params);
|
|
114
|
+
return result.rows.map(rowToRun);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Count active runs
|
|
118
|
+
*/
|
|
119
|
+
export async function countActive(db, projectId) {
|
|
120
|
+
const sql = projectId
|
|
121
|
+
? `SELECT COUNT(*) as count FROM runs WHERE status IN ('pending', 'running') AND project_id = $1`
|
|
122
|
+
: `SELECT COUNT(*) as count FROM runs WHERE status IN ('pending', 'running')`;
|
|
123
|
+
const result = await db.query(sql, projectId ? [projectId] : []);
|
|
124
|
+
return parseInt(result.rows[0]?.count ?? '0', 10);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Get the latest run of a specific type for a project
|
|
128
|
+
*/
|
|
129
|
+
export async function getLatestByType(db, projectId, type) {
|
|
130
|
+
const result = await db.query(`SELECT * FROM runs
|
|
131
|
+
WHERE project_id = $1 AND type = $2
|
|
132
|
+
ORDER BY created_at DESC
|
|
133
|
+
LIMIT 1`, [projectId, type]);
|
|
134
|
+
return result.rows[0] ? rowToRun(result.rows[0]) : null;
|
|
135
|
+
}
|
|
136
|
+
export async function getSummary(db, projectId) {
|
|
137
|
+
const [lastScoutRun, lastQaRun, lastExecuteRun, activeCount] = await Promise.all([
|
|
138
|
+
getLatestByType(db, projectId, 'scout'),
|
|
139
|
+
getLatestByType(db, projectId, 'qa'),
|
|
140
|
+
getLatestByType(db, projectId, 'worker'),
|
|
141
|
+
countActive(db, projectId),
|
|
142
|
+
]);
|
|
143
|
+
// For QA runs, get step counts from run_steps table
|
|
144
|
+
let qaStepsPassed = 0;
|
|
145
|
+
let qaStepsFailed = 0;
|
|
146
|
+
if (lastQaRun) {
|
|
147
|
+
const stepCounts = await db.query(`SELECT
|
|
148
|
+
SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) AS passed,
|
|
149
|
+
SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) AS failed
|
|
150
|
+
FROM run_steps
|
|
151
|
+
WHERE run_id = $1`, [lastQaRun.id]);
|
|
152
|
+
qaStepsPassed = parseInt(stepCounts.rows[0]?.passed ?? '0', 10);
|
|
153
|
+
qaStepsFailed = parseInt(stepCounts.rows[0]?.failed ?? '0', 10);
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
lastScout: lastScoutRun ? {
|
|
157
|
+
id: lastScoutRun.id,
|
|
158
|
+
status: lastScoutRun.status,
|
|
159
|
+
completedAt: lastScoutRun.completedAt,
|
|
160
|
+
proposalCount: lastScoutRun.metadata.proposalCount ?? 0,
|
|
161
|
+
ticketCount: lastScoutRun.metadata.ticketCount ?? 0,
|
|
162
|
+
scannedFiles: lastScoutRun.metadata.scannedFiles ?? 0,
|
|
163
|
+
durationMs: lastScoutRun.metadata.durationMs ?? 0,
|
|
164
|
+
} : null,
|
|
165
|
+
lastQa: lastQaRun ? {
|
|
166
|
+
id: lastQaRun.id,
|
|
167
|
+
status: lastQaRun.status,
|
|
168
|
+
completedAt: lastQaRun.completedAt,
|
|
169
|
+
stepsPassed: qaStepsPassed,
|
|
170
|
+
stepsFailed: qaStepsFailed,
|
|
171
|
+
durationMs: lastQaRun.metadata.durationMs ?? 0,
|
|
172
|
+
} : null,
|
|
173
|
+
lastExecute: lastExecuteRun ? {
|
|
174
|
+
id: lastExecuteRun.id,
|
|
175
|
+
ticketId: lastExecuteRun.ticketId,
|
|
176
|
+
status: lastExecuteRun.status,
|
|
177
|
+
completedAt: lastExecuteRun.completedAt,
|
|
178
|
+
branchName: lastExecuteRun.metadata.branchName ?? null,
|
|
179
|
+
prUrl: lastExecuteRun.metadata.prUrl ?? null,
|
|
180
|
+
durationMs: lastExecuteRun.metadata.durationMs ?? 0,
|
|
181
|
+
} : null,
|
|
182
|
+
activeRuns: activeCount,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=runs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/repos/runs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ticket repository - Database operations for tickets
|
|
3
|
+
*/
|
|
4
|
+
import type { DatabaseAdapter } from '../db/adapter.js';
|
|
5
|
+
export type TicketStatus = 'backlog' | 'ready' | 'leased' | 'in_progress' | 'in_review' | 'done' | 'blocked' | 'aborted';
|
|
6
|
+
export type TicketCategory = 'refactor' | 'docs' | 'test' | 'perf' | 'security' | 'fix' | 'cleanup' | 'types';
|
|
7
|
+
export interface Ticket {
|
|
8
|
+
id: string;
|
|
9
|
+
projectId: string;
|
|
10
|
+
title: string;
|
|
11
|
+
description: string | null;
|
|
12
|
+
status: TicketStatus;
|
|
13
|
+
priority: number;
|
|
14
|
+
shard: string | null;
|
|
15
|
+
category: TicketCategory | null;
|
|
16
|
+
allowedPaths: string[];
|
|
17
|
+
forbiddenPaths: string[];
|
|
18
|
+
verificationCommands: string[];
|
|
19
|
+
maxRetries: number;
|
|
20
|
+
retryCount: number;
|
|
21
|
+
createdAt: Date;
|
|
22
|
+
updatedAt: Date;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get ticket by ID
|
|
26
|
+
*/
|
|
27
|
+
export declare function getById(db: DatabaseAdapter, id: string): Promise<Ticket | null>;
|
|
28
|
+
/**
|
|
29
|
+
* Create a new ticket
|
|
30
|
+
*/
|
|
31
|
+
export declare function create(db: DatabaseAdapter, opts: {
|
|
32
|
+
projectId: string;
|
|
33
|
+
title: string;
|
|
34
|
+
description?: string;
|
|
35
|
+
status?: TicketStatus;
|
|
36
|
+
priority?: number;
|
|
37
|
+
shard?: string;
|
|
38
|
+
category?: TicketCategory;
|
|
39
|
+
allowedPaths?: string[];
|
|
40
|
+
forbiddenPaths?: string[];
|
|
41
|
+
verificationCommands?: string[];
|
|
42
|
+
maxRetries?: number;
|
|
43
|
+
}): Promise<Ticket>;
|
|
44
|
+
/**
|
|
45
|
+
* Create multiple tickets in a transaction
|
|
46
|
+
*/
|
|
47
|
+
export declare function createMany(db: DatabaseAdapter, tickets: Array<Parameters<typeof create>[1]>): Promise<Ticket[]>;
|
|
48
|
+
/**
|
|
49
|
+
* Update ticket status
|
|
50
|
+
*/
|
|
51
|
+
export declare function updateStatus(db: DatabaseAdapter, id: string, status: TicketStatus): Promise<Ticket | null>;
|
|
52
|
+
/**
|
|
53
|
+
* List tickets for a project
|
|
54
|
+
*/
|
|
55
|
+
export declare function listByProject(db: DatabaseAdapter, projectId: string, opts?: {
|
|
56
|
+
status?: TicketStatus | TicketStatus[];
|
|
57
|
+
limit?: number;
|
|
58
|
+
}): Promise<Ticket[]>;
|
|
59
|
+
/**
|
|
60
|
+
* Get recently completed tickets (for dedup context)
|
|
61
|
+
*/
|
|
62
|
+
export declare function getRecentlyCompleted(db: DatabaseAdapter, projectId: string, limit?: number): Promise<Ticket[]>;
|
|
63
|
+
/**
|
|
64
|
+
* Count tickets by status
|
|
65
|
+
*/
|
|
66
|
+
export declare function countByStatus(db: DatabaseAdapter, projectId: string): Promise<Record<TicketStatus, number>>;
|
|
67
|
+
/**
|
|
68
|
+
* Find similar ticket by title (for dedup)
|
|
69
|
+
*/
|
|
70
|
+
export declare function findSimilarByTitle(db: DatabaseAdapter, projectId: string, title: string): Promise<Ticket | null>;
|
|
71
|
+
//# sourceMappingURL=tickets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tickets.d.ts","sourceRoot":"","sources":["../../src/repos/tickets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ticket repository - Database operations for tickets
|
|
3
|
+
*/
|
|
4
|
+
import { nanoid, parseJsonArray } from '../utils/index.js';
|
|
5
|
+
function rowToTicket(row) {
|
|
6
|
+
return {
|
|
7
|
+
id: row.id,
|
|
8
|
+
projectId: row.project_id,
|
|
9
|
+
title: row.title,
|
|
10
|
+
description: row.description,
|
|
11
|
+
status: row.status,
|
|
12
|
+
priority: row.priority,
|
|
13
|
+
shard: row.shard,
|
|
14
|
+
category: row.category,
|
|
15
|
+
allowedPaths: parseJsonArray(row.allowed_paths),
|
|
16
|
+
forbiddenPaths: parseJsonArray(row.forbidden_paths),
|
|
17
|
+
verificationCommands: parseJsonArray(row.verification_commands),
|
|
18
|
+
maxRetries: row.max_retries,
|
|
19
|
+
retryCount: row.retry_count,
|
|
20
|
+
createdAt: new Date(row.created_at),
|
|
21
|
+
updatedAt: new Date(row.updated_at),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get ticket by ID
|
|
26
|
+
*/
|
|
27
|
+
export async function getById(db, id) {
|
|
28
|
+
const result = await db.query('SELECT * FROM tickets WHERE id = $1', [id]);
|
|
29
|
+
return result.rows[0] ? rowToTicket(result.rows[0]) : null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create a new ticket
|
|
33
|
+
*/
|
|
34
|
+
export async function create(db, opts) {
|
|
35
|
+
const id = `tkt_${nanoid(12)}`;
|
|
36
|
+
await db.query(`INSERT INTO tickets (
|
|
37
|
+
id, project_id, title, description, status, priority,
|
|
38
|
+
shard, category, allowed_paths, forbidden_paths,
|
|
39
|
+
verification_commands, max_retries
|
|
40
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, [
|
|
41
|
+
id,
|
|
42
|
+
opts.projectId,
|
|
43
|
+
opts.title,
|
|
44
|
+
opts.description ?? null,
|
|
45
|
+
opts.status ?? 'ready',
|
|
46
|
+
opts.priority ?? 0,
|
|
47
|
+
opts.shard ?? null,
|
|
48
|
+
opts.category ?? null,
|
|
49
|
+
JSON.stringify(opts.allowedPaths ?? []),
|
|
50
|
+
JSON.stringify(opts.forbiddenPaths ?? []),
|
|
51
|
+
JSON.stringify(opts.verificationCommands ?? []),
|
|
52
|
+
opts.maxRetries ?? 3,
|
|
53
|
+
]);
|
|
54
|
+
const ticket = await getById(db, id);
|
|
55
|
+
if (!ticket) {
|
|
56
|
+
throw new Error('Failed to create ticket');
|
|
57
|
+
}
|
|
58
|
+
return ticket;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Create multiple tickets in a transaction
|
|
62
|
+
*/
|
|
63
|
+
export async function createMany(db, tickets) {
|
|
64
|
+
return db.withTransaction(async (tx) => {
|
|
65
|
+
const created = [];
|
|
66
|
+
for (const opts of tickets) {
|
|
67
|
+
const id = `tkt_${nanoid(12)}`;
|
|
68
|
+
await tx.query(`INSERT INTO tickets (
|
|
69
|
+
id, project_id, title, description, status, priority,
|
|
70
|
+
shard, category, allowed_paths, forbidden_paths,
|
|
71
|
+
verification_commands, max_retries
|
|
72
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, [
|
|
73
|
+
id,
|
|
74
|
+
opts.projectId,
|
|
75
|
+
opts.title,
|
|
76
|
+
opts.description ?? null,
|
|
77
|
+
opts.status ?? 'ready',
|
|
78
|
+
opts.priority ?? 0,
|
|
79
|
+
opts.shard ?? null,
|
|
80
|
+
opts.category ?? null,
|
|
81
|
+
JSON.stringify(opts.allowedPaths ?? []),
|
|
82
|
+
JSON.stringify(opts.forbiddenPaths ?? []),
|
|
83
|
+
JSON.stringify(opts.verificationCommands ?? []),
|
|
84
|
+
opts.maxRetries ?? 3,
|
|
85
|
+
]);
|
|
86
|
+
const result = await tx.query('SELECT * FROM tickets WHERE id = $1', [id]);
|
|
87
|
+
if (!result.rows[0])
|
|
88
|
+
throw new Error('Failed to create ticket');
|
|
89
|
+
created.push(rowToTicket(result.rows[0]));
|
|
90
|
+
}
|
|
91
|
+
return created;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Update ticket status
|
|
96
|
+
*/
|
|
97
|
+
export async function updateStatus(db, id, status) {
|
|
98
|
+
await db.query(`UPDATE tickets SET status = $1, updated_at = datetime('now') WHERE id = $2`, [status, id]);
|
|
99
|
+
return getById(db, id);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* List tickets for a project
|
|
103
|
+
*/
|
|
104
|
+
export async function listByProject(db, projectId, opts) {
|
|
105
|
+
let sql = 'SELECT * FROM tickets WHERE project_id = $1';
|
|
106
|
+
const params = [projectId];
|
|
107
|
+
if (opts?.status) {
|
|
108
|
+
const statuses = Array.isArray(opts.status) ? opts.status : [opts.status];
|
|
109
|
+
const placeholders = statuses.map((_, i) => `$${i + 2}`).join(', ');
|
|
110
|
+
sql += ` AND status IN (${placeholders})`;
|
|
111
|
+
params.push(...statuses);
|
|
112
|
+
}
|
|
113
|
+
sql += ' ORDER BY priority DESC, created_at DESC';
|
|
114
|
+
if (opts?.limit !== undefined) {
|
|
115
|
+
const paramIndex = params.length + 1;
|
|
116
|
+
sql += ` LIMIT $${paramIndex}`;
|
|
117
|
+
params.push(opts.limit);
|
|
118
|
+
}
|
|
119
|
+
const result = await db.query(sql, params);
|
|
120
|
+
return result.rows.map(rowToTicket);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get recently completed tickets (for dedup context)
|
|
124
|
+
*/
|
|
125
|
+
export async function getRecentlyCompleted(db, projectId, limit = 20) {
|
|
126
|
+
return listByProject(db, projectId, { status: 'done', limit });
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Count tickets by status
|
|
130
|
+
*/
|
|
131
|
+
export async function countByStatus(db, projectId) {
|
|
132
|
+
const result = await db.query(`SELECT status, COUNT(*) as count FROM tickets
|
|
133
|
+
WHERE project_id = $1 GROUP BY status`, [projectId]);
|
|
134
|
+
const counts = {
|
|
135
|
+
backlog: 0,
|
|
136
|
+
ready: 0,
|
|
137
|
+
leased: 0,
|
|
138
|
+
in_progress: 0,
|
|
139
|
+
in_review: 0,
|
|
140
|
+
done: 0,
|
|
141
|
+
blocked: 0,
|
|
142
|
+
aborted: 0,
|
|
143
|
+
};
|
|
144
|
+
for (const row of result.rows) {
|
|
145
|
+
counts[row.status] = parseInt(row.count, 10);
|
|
146
|
+
}
|
|
147
|
+
return counts;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Find similar ticket by title (for dedup)
|
|
151
|
+
*/
|
|
152
|
+
export async function findSimilarByTitle(db, projectId, title) {
|
|
153
|
+
const result = await db.query(`SELECT * FROM tickets
|
|
154
|
+
WHERE project_id = $1 AND LOWER(title) = LOWER($2)
|
|
155
|
+
LIMIT 1`, [projectId, title]);
|
|
156
|
+
return result.rows[0] ? rowToTicket(result.rows[0]) : null;
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=tickets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tickets.js","sourceRoot":"","sources":["../../src/repos/tickets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure scope algorithms — no filesystem, no external dependencies.
|
|
3
|
+
*
|
|
4
|
+
* Shared by both @promptwheel/cli and @promptwheel/mcp.
|
|
5
|
+
* CLI keeps its proposal-level scope checking wrapper.
|
|
6
|
+
* MCP keeps its minimatch-based policy enforcement + file I/O.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ALWAYS_DENIED: string[];
|
|
9
|
+
export declare const CREDENTIAL_PATTERNS: RegExp[];
|
|
10
|
+
export declare const FILE_DENY_PATTERNS: RegExp[];
|
|
11
|
+
/**
|
|
12
|
+
* Normalize a file path for consistent matching.
|
|
13
|
+
*/
|
|
14
|
+
export declare function normalizePath(filePath: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Detect if a path appears to be hallucinated by an LLM.
|
|
17
|
+
* Common patterns: repeated segments like 'foo/foo/'.
|
|
18
|
+
*/
|
|
19
|
+
export declare function detectHallucinatedPath(filePath: string): {
|
|
20
|
+
isHallucinated: boolean;
|
|
21
|
+
reason?: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Check file content for credential patterns.
|
|
25
|
+
* Returns a description of the first match, or null if clean.
|
|
26
|
+
*/
|
|
27
|
+
export declare function detectCredentialInContent(content: string): string | null;
|
|
28
|
+
/**
|
|
29
|
+
* Check if a file path matches credential/sensitive file patterns.
|
|
30
|
+
*/
|
|
31
|
+
export declare function detectCredentialPattern(filePath: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Simple glob-style pattern matching.
|
|
34
|
+
* Supports: * (any chars), ** (any path segments), ? (single char)
|
|
35
|
+
*/
|
|
36
|
+
export declare function matchesPattern(filePath: string, pattern: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Check if a path is allowed given allow/deny lists using built-in glob matching.
|
|
39
|
+
* When allowed is empty, everything not denied is allowed.
|
|
40
|
+
*/
|
|
41
|
+
export declare function isPathAllowed(filePath: string, allowed: string[], denied: string[]): boolean;
|
|
42
|
+
export interface ScopeViolation {
|
|
43
|
+
file: string;
|
|
44
|
+
violation: 'not_in_allowed' | 'in_forbidden';
|
|
45
|
+
pattern?: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check if changed files violate scope constraints.
|
|
49
|
+
*/
|
|
50
|
+
export declare function checkScopeViolations(changedFiles: string[], allowedPaths: string[], forbiddenPaths: string[]): ScopeViolation[];
|
|
51
|
+
export interface ScopeExpansionResult {
|
|
52
|
+
canExpand: boolean;
|
|
53
|
+
expandedPaths: string[];
|
|
54
|
+
addedPaths: string[];
|
|
55
|
+
reason?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Analyze violations and determine if paths can be auto-expanded.
|
|
59
|
+
* Allows expansion for sibling files, test files, type definitions,
|
|
60
|
+
* index files, subdirectories, and root configs.
|
|
61
|
+
*/
|
|
62
|
+
export declare function analyzeViolationsForExpansion(violations: ScopeViolation[], currentAllowedPaths: string[], maxExpansions?: number): ScopeExpansionResult;
|
|
63
|
+
/**
|
|
64
|
+
* Parse git status --porcelain output to get changed file paths.
|
|
65
|
+
*/
|
|
66
|
+
export declare function parseChangedFiles(statusOutput: string): string[];
|
|
67
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/scope/shared.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,eAAO,MAAM,aAAa,EAAE,MAAM,EAMjC,CAAC;AAMF,eAAO,MAAM,mBAAmB,EAAE,MAAM,EAYvC,CAAC;AAMF,eAAO,MAAM,kBAAkB,EAAE,MAAM,EAItC,CAAC;AAMF;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMtD;AAMD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG;IACxD,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAuBA;AAMD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQxE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAKjE;AAMD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAqBzE;AAMD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAeT;AAMD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,gBAAgB,GAAG,cAAc,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EAAE,EACtB,YAAY,EAAE,MAAM,EAAE,EACtB,cAAc,EAAE,MAAM,EAAE,GACvB,cAAc,EAAE,CA6ClB;AAMD,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,cAAc,EAAE,EAC5B,mBAAmB,EAAE,MAAM,EAAE,EAC7B,aAAa,GAAE,MAAW,GACzB,oBAAoB,CAgJtB;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAchE"}
|