@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,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Critic Scoring — pure algorithms for retry guidance.
|
|
3
|
+
*
|
|
4
|
+
* When QA fails or a plan is rejected, these functions analyze structured
|
|
5
|
+
* learnings to build targeted guidance for the retry prompt.
|
|
6
|
+
*
|
|
7
|
+
* No I/O — callers provide learnings and failure context.
|
|
8
|
+
*/
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Scoring
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/**
|
|
13
|
+
* Compute retry risk based on learnings overlap with the failing ticket.
|
|
14
|
+
*/
|
|
15
|
+
export function computeRetryRisk(ticketPaths, ticketCommands, learnings, failureContext) {
|
|
16
|
+
const signals = [];
|
|
17
|
+
let score = failureContext.attempt * 20;
|
|
18
|
+
const pathSet = new Set(ticketPaths.map(p => p.replace(/\/?\*\*?$/, '')));
|
|
19
|
+
for (const l of learnings) {
|
|
20
|
+
if (!l.structured)
|
|
21
|
+
continue;
|
|
22
|
+
const sk = l.structured;
|
|
23
|
+
// Fragile path overlap
|
|
24
|
+
if (sk.fragile_paths) {
|
|
25
|
+
for (const fp of sk.fragile_paths) {
|
|
26
|
+
if (pathSet.has(fp) || [...pathSet].some(p => fp.startsWith(p + '/') || p.startsWith(fp + '/'))) {
|
|
27
|
+
score += 15;
|
|
28
|
+
signals.push(`Fragile: ${fp}`);
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Error signature match
|
|
34
|
+
if (sk.failure_context?.error_signature && failureContext.error_output) {
|
|
35
|
+
if (failureContext.error_output.includes(sk.failure_context.error_signature) ||
|
|
36
|
+
sk.failure_context.error_signature.includes(failureContext.error_output.slice(0, 80))) {
|
|
37
|
+
score += 20;
|
|
38
|
+
signals.push(`Known error: ${sk.failure_context.error_signature.slice(0, 60)}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Cochange files not in allowed paths
|
|
42
|
+
if (sk.cochange_files) {
|
|
43
|
+
for (const cf of sk.cochange_files) {
|
|
44
|
+
const cfClean = cf.replace(/\/?\*\*?$/, '');
|
|
45
|
+
if (!pathSet.has(cfClean) && ![...pathSet].some(p => cfClean.startsWith(p + '/'))) {
|
|
46
|
+
score += 10;
|
|
47
|
+
signals.push(`Missing cochange: ${cf}`);
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
score = Math.min(100, score);
|
|
54
|
+
const level = score < 30 ? 'low' : score <= 60 ? 'medium' : 'high';
|
|
55
|
+
return { score, level, signals };
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Generate ranked strategies for a retry based on learnings.
|
|
59
|
+
* Returns top 3 by confidence.
|
|
60
|
+
*/
|
|
61
|
+
export function scoreStrategies(ticketPaths, failureContext, learnings) {
|
|
62
|
+
const strategies = [];
|
|
63
|
+
const pathSet = new Set(ticketPaths.map(p => p.replace(/\/?\*\*?$/, '')));
|
|
64
|
+
for (const l of learnings) {
|
|
65
|
+
if (!l.structured)
|
|
66
|
+
continue;
|
|
67
|
+
const sk = l.structured;
|
|
68
|
+
// "Apply known fix" — if a learning has fix_applied
|
|
69
|
+
if (sk.failure_context?.fix_applied) {
|
|
70
|
+
strategies.push({
|
|
71
|
+
label: 'Apply known fix',
|
|
72
|
+
instruction: sk.failure_context.fix_applied,
|
|
73
|
+
confidence: l.weight,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// "Include cochange files" — if cochange_files overlap
|
|
77
|
+
if (sk.cochange_files) {
|
|
78
|
+
const missing = sk.cochange_files.filter(cf => {
|
|
79
|
+
const cfClean = cf.replace(/\/?\*\*?$/, '');
|
|
80
|
+
return !pathSet.has(cfClean) && ![...pathSet].some(p => cfClean.startsWith(p + '/'));
|
|
81
|
+
});
|
|
82
|
+
if (missing.length > 0) {
|
|
83
|
+
strategies.push({
|
|
84
|
+
label: 'Include cochange files',
|
|
85
|
+
instruction: `${missing.join(', ')} often change together with the ticket files`,
|
|
86
|
+
confidence: Math.round(l.weight * 0.8),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// "Avoid antipattern" — if antipattern learning matches
|
|
91
|
+
if (sk.pattern_type === 'antipattern') {
|
|
92
|
+
strategies.push({
|
|
93
|
+
label: 'Avoid antipattern',
|
|
94
|
+
instruction: l.text,
|
|
95
|
+
confidence: Math.round(l.weight * 0.7),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// "Different approach" fallback on attempt >= 2
|
|
100
|
+
if (failureContext.attempt >= 2) {
|
|
101
|
+
strategies.push({
|
|
102
|
+
label: 'Different approach',
|
|
103
|
+
instruction: 'The previous approach failed. Try a fundamentally different implementation strategy.',
|
|
104
|
+
confidence: 30,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
// Deduplicate by label (keep highest confidence)
|
|
108
|
+
const best = new Map();
|
|
109
|
+
for (const s of strategies) {
|
|
110
|
+
const existing = best.get(s.label);
|
|
111
|
+
if (!existing || s.confidence > existing.confidence) {
|
|
112
|
+
best.set(s.label, s);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return [...best.values()]
|
|
116
|
+
.sort((a, b) => b.confidence - a.confidence)
|
|
117
|
+
.slice(0, 3);
|
|
118
|
+
}
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
// Block builders
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
/**
|
|
123
|
+
* Build a critic review block for QA retry prompts.
|
|
124
|
+
* Returns empty string if risk is low and no high-confidence strategies exist.
|
|
125
|
+
*/
|
|
126
|
+
export function buildCriticBlock(failureContext, risk, strategies, _learnings) {
|
|
127
|
+
// Skip prompt bloat when risk is low and no strategies are confident
|
|
128
|
+
if (risk.level === 'low' && !strategies.some(s => s.confidence > 50)) {
|
|
129
|
+
return '';
|
|
130
|
+
}
|
|
131
|
+
const lines = [
|
|
132
|
+
'<critic-review>',
|
|
133
|
+
`## Retry Guidance (attempt ${failureContext.attempt}/${failureContext.max_attempts})`,
|
|
134
|
+
'',
|
|
135
|
+
'### What Went Wrong',
|
|
136
|
+
];
|
|
137
|
+
for (const cmd of failureContext.failed_commands) {
|
|
138
|
+
lines.push(`- Failed: \`${cmd}\``);
|
|
139
|
+
}
|
|
140
|
+
if (failureContext.error_output) {
|
|
141
|
+
const truncated = failureContext.error_output.slice(0, 200);
|
|
142
|
+
lines.push(`- Error: ${truncated}`);
|
|
143
|
+
}
|
|
144
|
+
lines.push('');
|
|
145
|
+
lines.push(`### Risk: ${risk.level.toUpperCase()} (score: ${risk.score})`);
|
|
146
|
+
for (const sig of risk.signals) {
|
|
147
|
+
lines.push(`- ${sig}`);
|
|
148
|
+
}
|
|
149
|
+
if (strategies.length > 0) {
|
|
150
|
+
lines.push('');
|
|
151
|
+
lines.push('### Recommended Approach');
|
|
152
|
+
for (const s of strategies) {
|
|
153
|
+
lines.push(`${s.confidence}. [${s.confidence}] ${s.label}: ${s.instruction}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
lines.push('</critic-review>');
|
|
157
|
+
return lines.join('\n');
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Build a critic block for plan rejection retries.
|
|
161
|
+
* Returns empty string if no actionable guidance exists.
|
|
162
|
+
*/
|
|
163
|
+
export function buildPlanRejectionCriticBlock(context, learnings, ticketPaths) {
|
|
164
|
+
const pathSet = new Set(ticketPaths.map(p => p.replace(/\/?\*\*?$/, '')));
|
|
165
|
+
const relevantLearnings = learnings.filter(l => {
|
|
166
|
+
if (!l.structured)
|
|
167
|
+
return false;
|
|
168
|
+
if (l.source.type !== 'plan_rejection' && l.source.type !== 'scope_violation')
|
|
169
|
+
return false;
|
|
170
|
+
// Check path overlap
|
|
171
|
+
for (const tag of l.tags) {
|
|
172
|
+
if (tag.startsWith('path:')) {
|
|
173
|
+
const lPath = tag.slice(5);
|
|
174
|
+
if (pathSet.has(lPath) || [...pathSet].some(p => lPath.startsWith(p + '/') || p.startsWith(lPath + '/'))) {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return false;
|
|
180
|
+
});
|
|
181
|
+
if (relevantLearnings.length === 0 && !context.rejection_reason) {
|
|
182
|
+
return '';
|
|
183
|
+
}
|
|
184
|
+
const lines = [
|
|
185
|
+
'<critic-review>',
|
|
186
|
+
`## Plan Revision Guidance (attempt ${context.attempt}/${context.max_attempts})`,
|
|
187
|
+
'',
|
|
188
|
+
`### Rejection Reason`,
|
|
189
|
+
context.rejection_reason,
|
|
190
|
+
'',
|
|
191
|
+
];
|
|
192
|
+
if (relevantLearnings.length > 0) {
|
|
193
|
+
lines.push('### Previous Plan Rejections in These Files');
|
|
194
|
+
for (const l of relevantLearnings.slice(0, 3)) {
|
|
195
|
+
lines.push(`- ${l.text}`);
|
|
196
|
+
if (l.structured?.root_cause) {
|
|
197
|
+
lines.push(` Cause: ${l.structured.root_cause}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
lines.push('</critic-review>');
|
|
202
|
+
return lines.join('\n');
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/critic/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DatabaseAdapter - Abstract interface for database operations
|
|
3
|
+
*
|
|
4
|
+
* This interface allows PromptWheel to work with different database backends:
|
|
5
|
+
* - PostgreSQL (for teams/cloud)
|
|
6
|
+
* - SQLite (for individual developers, zero-config)
|
|
7
|
+
*
|
|
8
|
+
* Implementations must handle:
|
|
9
|
+
* - Connection management
|
|
10
|
+
* - Query execution with parameterized queries
|
|
11
|
+
* - Transaction support
|
|
12
|
+
* - Schema migrations
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Result of a database query
|
|
16
|
+
*/
|
|
17
|
+
export interface QueryResult<T = Record<string, unknown>> {
|
|
18
|
+
/** Array of rows returned by the query */
|
|
19
|
+
rows: T[];
|
|
20
|
+
/** Number of rows affected (for INSERT/UPDATE/DELETE) */
|
|
21
|
+
rowCount: number | null;
|
|
22
|
+
/** Column metadata (optional, Postgres-specific) */
|
|
23
|
+
fields?: Array<{
|
|
24
|
+
name: string;
|
|
25
|
+
dataTypeID?: number;
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Transaction client interface
|
|
30
|
+
* Passed to transaction callbacks to execute queries within the transaction
|
|
31
|
+
*/
|
|
32
|
+
export interface TransactionClient {
|
|
33
|
+
/**
|
|
34
|
+
* Execute a query within the transaction
|
|
35
|
+
*/
|
|
36
|
+
query<T = Record<string, unknown>>(text: string, params?: unknown[]): Promise<QueryResult<T>>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Migration definition
|
|
40
|
+
*/
|
|
41
|
+
export interface Migration {
|
|
42
|
+
/** Unique migration identifier (e.g., "001_initial") */
|
|
43
|
+
id: string;
|
|
44
|
+
/** SQL to apply the migration */
|
|
45
|
+
up: string;
|
|
46
|
+
/** SQL to rollback the migration (optional) */
|
|
47
|
+
down?: string;
|
|
48
|
+
/** Checksum for integrity validation */
|
|
49
|
+
checksum: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Migration result
|
|
53
|
+
*/
|
|
54
|
+
export interface MigrationResult {
|
|
55
|
+
/** Migrations that were applied */
|
|
56
|
+
applied: string[];
|
|
57
|
+
/** Migrations that were skipped (already applied) */
|
|
58
|
+
skipped: string[];
|
|
59
|
+
/** Whether this was a dry run */
|
|
60
|
+
dryRun: boolean;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Query logging configuration
|
|
64
|
+
*/
|
|
65
|
+
export interface QueryLogConfig {
|
|
66
|
+
/** Log all queries (verbose) */
|
|
67
|
+
logAll: boolean;
|
|
68
|
+
/** Log queries slower than this threshold (ms) */
|
|
69
|
+
slowQueryThresholdMs: number;
|
|
70
|
+
/** Log query parameters (may expose sensitive data) */
|
|
71
|
+
logParams: boolean;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Query statistics for monitoring
|
|
75
|
+
*/
|
|
76
|
+
export interface QueryStats {
|
|
77
|
+
totalQueries: number;
|
|
78
|
+
totalErrors: number;
|
|
79
|
+
totalDurationMs: number;
|
|
80
|
+
byType: Record<string, {
|
|
81
|
+
count: number;
|
|
82
|
+
errors: number;
|
|
83
|
+
durationMs: number;
|
|
84
|
+
}>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Database adapter interface
|
|
88
|
+
*
|
|
89
|
+
* All database operations in PromptWheel go through this interface,
|
|
90
|
+
* allowing seamless switching between backends.
|
|
91
|
+
*/
|
|
92
|
+
export interface DatabaseAdapter {
|
|
93
|
+
/**
|
|
94
|
+
* Adapter name for logging/debugging
|
|
95
|
+
*/
|
|
96
|
+
readonly name: string;
|
|
97
|
+
/**
|
|
98
|
+
* Whether the adapter is connected
|
|
99
|
+
*/
|
|
100
|
+
readonly connected: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Execute a parameterized query
|
|
103
|
+
*
|
|
104
|
+
* @param text - SQL query with $1, $2, etc. placeholders
|
|
105
|
+
* @param params - Parameter values
|
|
106
|
+
* @returns Query result with rows and metadata
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* const result = await adapter.query<UserRow>(
|
|
110
|
+
* 'SELECT * FROM users WHERE id = $1',
|
|
111
|
+
* [userId]
|
|
112
|
+
* );
|
|
113
|
+
*/
|
|
114
|
+
query<T = Record<string, unknown>>(text: string, params?: unknown[]): Promise<QueryResult<T>>;
|
|
115
|
+
/**
|
|
116
|
+
* Execute a function within a database transaction
|
|
117
|
+
*
|
|
118
|
+
* The transaction is automatically committed on success,
|
|
119
|
+
* or rolled back on error.
|
|
120
|
+
*
|
|
121
|
+
* @param fn - Function to execute within the transaction
|
|
122
|
+
* @returns Result of the function
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* await adapter.withTransaction(async (tx) => {
|
|
126
|
+
* await tx.query('INSERT INTO orders ...', [...]);
|
|
127
|
+
* await tx.query('UPDATE inventory ...', [...]);
|
|
128
|
+
* });
|
|
129
|
+
*/
|
|
130
|
+
withTransaction<T>(fn: (client: TransactionClient) => Promise<T>): Promise<T>;
|
|
131
|
+
/**
|
|
132
|
+
* Run pending migrations
|
|
133
|
+
*
|
|
134
|
+
* @param options - Migration options
|
|
135
|
+
* @returns Migration result
|
|
136
|
+
*/
|
|
137
|
+
migrate(options?: {
|
|
138
|
+
dryRun?: boolean;
|
|
139
|
+
target?: string;
|
|
140
|
+
verbose?: boolean;
|
|
141
|
+
}): Promise<MigrationResult>;
|
|
142
|
+
/**
|
|
143
|
+
* Close the database connection
|
|
144
|
+
*
|
|
145
|
+
* Should be called when shutting down the application.
|
|
146
|
+
*/
|
|
147
|
+
close(): Promise<void>;
|
|
148
|
+
/**
|
|
149
|
+
* Configure query logging
|
|
150
|
+
*/
|
|
151
|
+
configureLogging?(config: Partial<QueryLogConfig>): void;
|
|
152
|
+
/**
|
|
153
|
+
* Get query statistics
|
|
154
|
+
*/
|
|
155
|
+
getStats?(): Readonly<QueryStats>;
|
|
156
|
+
/**
|
|
157
|
+
* Reset query statistics
|
|
158
|
+
*/
|
|
159
|
+
resetStats?(): void;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Factory function type for creating database adapters
|
|
163
|
+
*/
|
|
164
|
+
export type DatabaseAdapterFactory = (config: DatabaseConfig) => Promise<DatabaseAdapter>;
|
|
165
|
+
/**
|
|
166
|
+
* Database configuration
|
|
167
|
+
*/
|
|
168
|
+
export interface DatabaseConfig {
|
|
169
|
+
/** Connection URL (postgres://, sqlite://, or file path) */
|
|
170
|
+
url: string;
|
|
171
|
+
/** Maximum connections in pool (Postgres) */
|
|
172
|
+
maxConnections?: number;
|
|
173
|
+
/** Idle timeout in ms */
|
|
174
|
+
idleTimeoutMs?: number;
|
|
175
|
+
/** Connection timeout in ms */
|
|
176
|
+
connectionTimeoutMs?: number;
|
|
177
|
+
/** Enable WAL mode (SQLite) */
|
|
178
|
+
walMode?: boolean;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Detect database type from URL
|
|
182
|
+
*/
|
|
183
|
+
export declare function detectDatabaseType(url: string): 'postgres' | 'sqlite' | 'unknown';
|
|
184
|
+
/**
|
|
185
|
+
* Default database URL based on environment
|
|
186
|
+
*
|
|
187
|
+
* - If DATABASE_URL is set, use it (Postgres)
|
|
188
|
+
* - Otherwise, default to SQLite at ~/.promptwheel/data.db
|
|
189
|
+
*/
|
|
190
|
+
export declare function getDefaultDatabaseUrl(): string;
|
|
191
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/db/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DatabaseAdapter - Abstract interface for database operations
|
|
3
|
+
*
|
|
4
|
+
* This interface allows PromptWheel to work with different database backends:
|
|
5
|
+
* - PostgreSQL (for teams/cloud)
|
|
6
|
+
* - SQLite (for individual developers, zero-config)
|
|
7
|
+
*
|
|
8
|
+
* Implementations must handle:
|
|
9
|
+
* - Connection management
|
|
10
|
+
* - Query execution with parameterized queries
|
|
11
|
+
* - Transaction support
|
|
12
|
+
* - Schema migrations
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Detect database type from URL
|
|
16
|
+
*/
|
|
17
|
+
export function detectDatabaseType(url) {
|
|
18
|
+
if (url.startsWith('postgres://') || url.startsWith('postgresql://')) {
|
|
19
|
+
return 'postgres';
|
|
20
|
+
}
|
|
21
|
+
if (url.startsWith('sqlite://') || url.startsWith('file:') || url.endsWith('.db') || url.endsWith('.sqlite')) {
|
|
22
|
+
return 'sqlite';
|
|
23
|
+
}
|
|
24
|
+
return 'unknown';
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Default database URL based on environment
|
|
28
|
+
*
|
|
29
|
+
* - If DATABASE_URL is set, use it (Postgres)
|
|
30
|
+
* - Otherwise, default to SQLite at ~/.promptwheel/data.db
|
|
31
|
+
*/
|
|
32
|
+
export function getDefaultDatabaseUrl() {
|
|
33
|
+
if (process.env.DATABASE_URL) {
|
|
34
|
+
return process.env.DATABASE_URL;
|
|
35
|
+
}
|
|
36
|
+
// Default to SQLite for zero-config mode
|
|
37
|
+
const home = process.env.HOME || process.env.USERPROFILE || '.';
|
|
38
|
+
return `${home}/.promptwheel/data.db`;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/db/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAwLH;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,IAAI,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACrE,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,IAAI,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7G,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB;IACnC,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC7B,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAClC,CAAC;IAED,yCAAyC;IACzC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC;IAChE,OAAO,GAAG,IAAI,uBAAuB,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Adapter Contract Tests
|
|
3
|
+
*
|
|
4
|
+
* This module exports a test harness that validates any DatabaseAdapter
|
|
5
|
+
* implementation behaves correctly. Run these tests against both SQLite
|
|
6
|
+
* and Postgres adapters to ensure consistent behavior.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* import { runAdapterContract } from '@promptwheel/core/db/contract';
|
|
10
|
+
* import { createSQLiteAdapter } from '@promptwheel/sqlite';
|
|
11
|
+
*
|
|
12
|
+
* describe('SQLite Adapter', () => {
|
|
13
|
+
* runAdapterContract(() => createSQLiteAdapter({ url: ':memory:' }));
|
|
14
|
+
* });
|
|
15
|
+
*/
|
|
16
|
+
import type { DatabaseAdapter } from './adapter.js';
|
|
17
|
+
/**
|
|
18
|
+
* Test result
|
|
19
|
+
*/
|
|
20
|
+
export interface ContractTestResult {
|
|
21
|
+
name: string;
|
|
22
|
+
passed: boolean;
|
|
23
|
+
error?: string;
|
|
24
|
+
durationMs: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Contract test suite result
|
|
28
|
+
*/
|
|
29
|
+
export interface ContractSuiteResult {
|
|
30
|
+
adapter: string;
|
|
31
|
+
total: number;
|
|
32
|
+
passed: number;
|
|
33
|
+
failed: number;
|
|
34
|
+
results: ContractTestResult[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Run the adapter contract test suite
|
|
38
|
+
*
|
|
39
|
+
* @param createAdapter - Factory function to create a fresh adapter for each test
|
|
40
|
+
* @returns Test results
|
|
41
|
+
*/
|
|
42
|
+
export declare function runAdapterContract(createAdapter: () => Promise<DatabaseAdapter>): Promise<ContractSuiteResult>;
|
|
43
|
+
/**
|
|
44
|
+
* Format contract test results for console output
|
|
45
|
+
*/
|
|
46
|
+
export declare function formatContractResults(suite: ContractSuiteResult): string;
|
|
47
|
+
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/db/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAWpD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,GAC5C,OAAO,CAAC,mBAAmB,CAAC,CAwR9B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAmBxE"}
|