@adminiumjs/llm 0.1.0-rc.1
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/LICENSE +661 -0
- package/dist/apply/diff.d.ts +79 -0
- package/dist/apply/diff.d.ts.map +1 -0
- package/dist/apply/diff.js +459 -0
- package/dist/apply/diff.js.map +1 -0
- package/dist/apply/index.d.ts +6 -0
- package/dist/apply/index.d.ts.map +1 -0
- package/dist/apply/index.js +6 -0
- package/dist/apply/index.js.map +1 -0
- package/dist/apply/normalize.d.ts +55 -0
- package/dist/apply/normalize.d.ts.map +1 -0
- package/dist/apply/normalize.js +232 -0
- package/dist/apply/normalize.js.map +1 -0
- package/dist/apply/plan.d.ts +206 -0
- package/dist/apply/plan.d.ts.map +1 -0
- package/dist/apply/plan.js +422 -0
- package/dist/apply/plan.js.map +1 -0
- package/dist/apply/suggestion-id.d.ts +103 -0
- package/dist/apply/suggestion-id.d.ts.map +1 -0
- package/dist/apply/suggestion-id.js +121 -0
- package/dist/apply/suggestion-id.js.map +1 -0
- package/dist/crypto.d.ts +48 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +35 -0
- package/dist/crypto.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/prompt/builder.d.ts +27 -0
- package/dist/prompt/builder.d.ts.map +1 -0
- package/dist/prompt/builder.js +263 -0
- package/dist/prompt/builder.js.map +1 -0
- package/dist/prompt/chunker.d.ts +89 -0
- package/dist/prompt/chunker.d.ts.map +1 -0
- package/dist/prompt/chunker.js +383 -0
- package/dist/prompt/chunker.js.map +1 -0
- package/dist/prompt/index.d.ts +14 -0
- package/dist/prompt/index.d.ts.map +1 -0
- package/dist/prompt/index.js +14 -0
- package/dist/prompt/index.js.map +1 -0
- package/dist/prompt/serializer.d.ts +138 -0
- package/dist/prompt/serializer.d.ts.map +1 -0
- package/dist/prompt/serializer.js +178 -0
- package/dist/prompt/serializer.js.map +1 -0
- package/dist/prompt/templates/v1.d.ts +41 -0
- package/dist/prompt/templates/v1.d.ts.map +1 -0
- package/dist/prompt/templates/v1.js +312 -0
- package/dist/prompt/templates/v1.js.map +1 -0
- package/dist/prompt/token-estimate.d.ts +16 -0
- package/dist/prompt/token-estimate.d.ts.map +1 -0
- package/dist/prompt/token-estimate.js +20 -0
- package/dist/prompt/token-estimate.js.map +1 -0
- package/dist/prompt/types.d.ts +134 -0
- package/dist/prompt/types.d.ts.map +1 -0
- package/dist/prompt/types.js +44 -0
- package/dist/prompt/types.js.map +1 -0
- package/dist/providers/anthropic.d.ts +3 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +65 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/factory.d.ts +3 -0
- package/dist/providers/factory.d.ts.map +1 -0
- package/dist/providers/factory.js +37 -0
- package/dist/providers/factory.js.map +1 -0
- package/dist/providers/http.d.ts +56 -0
- package/dist/providers/http.d.ts.map +1 -0
- package/dist/providers/http.js +148 -0
- package/dist/providers/http.js.map +1 -0
- package/dist/providers/index.d.ts +15 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +15 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/model-catalog.d.ts +21 -0
- package/dist/providers/model-catalog.d.ts.map +1 -0
- package/dist/providers/model-catalog.js +121 -0
- package/dist/providers/model-catalog.js.map +1 -0
- package/dist/providers/ollama.d.ts +3 -0
- package/dist/providers/ollama.d.ts.map +1 -0
- package/dist/providers/ollama.js +55 -0
- package/dist/providers/ollama.js.map +1 -0
- package/dist/providers/openai-compatible.d.ts +3 -0
- package/dist/providers/openai-compatible.d.ts.map +1 -0
- package/dist/providers/openai-compatible.js +50 -0
- package/dist/providers/openai-compatible.js.map +1 -0
- package/dist/providers/openai.d.ts +18 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +68 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/types.d.ts +112 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +55 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/response/errors.d.ts +60 -0
- package/dist/response/errors.d.ts.map +1 -0
- package/dist/response/errors.js +101 -0
- package/dist/response/errors.js.map +1 -0
- package/dist/response/extract.d.ts +38 -0
- package/dist/response/extract.d.ts.map +1 -0
- package/dist/response/extract.js +77 -0
- package/dist/response/extract.js.map +1 -0
- package/dist/response/index.d.ts +8 -0
- package/dist/response/index.d.ts.map +1 -0
- package/dist/response/index.js +8 -0
- package/dist/response/index.js.map +1 -0
- package/dist/response/merge.d.ts +53 -0
- package/dist/response/merge.d.ts.map +1 -0
- package/dist/response/merge.js +348 -0
- package/dist/response/merge.js.map +1 -0
- package/dist/response/referential.d.ts +113 -0
- package/dist/response/referential.d.ts.map +1 -0
- package/dist/response/referential.js +556 -0
- package/dist/response/referential.js.map +1 -0
- package/dist/response/schema.d.ts +506 -0
- package/dist/response/schema.d.ts.map +1 -0
- package/dist/response/schema.js +191 -0
- package/dist/response/schema.js.map +1 -0
- package/dist/response/validate.d.ts +29 -0
- package/dist/response/validate.d.ts.map +1 -0
- package/dist/response/validate.js +167 -0
- package/dist/response/validate.js.map +1 -0
- package/dist/types.d.ts +95 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +49 -0
- package/dist/types.js.map +1 -0
- package/package.json +30 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
import { widgetId } from './suggestion-id.js';
|
|
2
|
+
// ─── Span → grid heuristic (§5 / 04-widget-registry.md §6.1) ─────────────────
|
|
3
|
+
/** KPI cards are 3 half-rows (120px); every other widget is 8 (320px). */
|
|
4
|
+
const KPI_HEIGHT = 3;
|
|
5
|
+
const CHART_HEIGHT = 8;
|
|
6
|
+
const GRID_COLUMNS = 12;
|
|
7
|
+
function clampSpan(span) {
|
|
8
|
+
if (!Number.isFinite(span))
|
|
9
|
+
return 6;
|
|
10
|
+
return Math.min(GRID_COLUMNS, Math.max(1, Math.trunc(span)));
|
|
11
|
+
}
|
|
12
|
+
function widgetHeight(width) {
|
|
13
|
+
return width <= KPI_HEIGHT ? KPI_HEIGHT : CHART_HEIGHT;
|
|
14
|
+
}
|
|
15
|
+
function isRecord(value) {
|
|
16
|
+
return value !== null && typeof value === 'object';
|
|
17
|
+
}
|
|
18
|
+
// ─── Query-descriptor binding (04-widget-registry.md §5.1) ───────────────────
|
|
19
|
+
/** Split a qualified `"schema.table"` into a query-descriptor `source` block. */
|
|
20
|
+
function tableSource(qualified) {
|
|
21
|
+
const dot = qualified.indexOf('.');
|
|
22
|
+
if (dot <= 0)
|
|
23
|
+
return { name: qualified, type: 'table' };
|
|
24
|
+
return { schema: qualified.slice(0, dot), name: qualified.slice(dot + 1), type: 'table' };
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build a declarative query-descriptor binding for one accepted widget, shaped
|
|
28
|
+
* from its bound columns: a `timeColumn` ⇒ `timeseries` (month buckets); else a
|
|
29
|
+
* `dimensionColumn` ⇒ `categorical` (group-by); else `single-metric`. The
|
|
30
|
+
* aggregation defaults to `sum` when a metric column is bound, else `count(*)`.
|
|
31
|
+
*/
|
|
32
|
+
function buildBinding(connectionId, w) {
|
|
33
|
+
const source = tableSource(w.table);
|
|
34
|
+
const fn = w.agg ?? (w.metricColumn !== undefined ? 'sum' : 'count');
|
|
35
|
+
const aggregation = { fn, alias: 'value' };
|
|
36
|
+
if (w.metricColumn !== undefined)
|
|
37
|
+
aggregation['column'] = w.metricColumn;
|
|
38
|
+
const binding = {
|
|
39
|
+
kind: 'table-query',
|
|
40
|
+
connectionId,
|
|
41
|
+
source,
|
|
42
|
+
aggregations: [aggregation],
|
|
43
|
+
};
|
|
44
|
+
if (w.timeColumn !== undefined) {
|
|
45
|
+
binding['shape'] = 'timeseries';
|
|
46
|
+
binding['bucket'] = { column: w.timeColumn, unit: 'month' };
|
|
47
|
+
}
|
|
48
|
+
else if (w.dimensionColumn !== undefined) {
|
|
49
|
+
binding['shape'] = 'categorical';
|
|
50
|
+
binding['groupBy'] = [w.dimensionColumn];
|
|
51
|
+
binding['limit'] = 8;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
binding['shape'] = 'single-metric';
|
|
55
|
+
}
|
|
56
|
+
return binding;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Pack accepted widgets left-to-right on the 12-column grid in rank order,
|
|
60
|
+
* wrapping to a new shelf when the current row overflows. Pure and deterministic
|
|
61
|
+
* — widths come from the §5 span heuristic, heights from {@link widgetHeight}.
|
|
62
|
+
*/
|
|
63
|
+
function planLayout(connectionId, dashboardSlug, widgets, accepted) {
|
|
64
|
+
const chosen = widgets
|
|
65
|
+
.filter((w) => accepted.has(widgetId(dashboardSlug, w.widget, w.rank)))
|
|
66
|
+
.slice()
|
|
67
|
+
.sort((a, b) => a.rank - b.rank);
|
|
68
|
+
const items = [];
|
|
69
|
+
const widgetIds = [];
|
|
70
|
+
let x = 0;
|
|
71
|
+
let y = 0;
|
|
72
|
+
let rowHeight = 0;
|
|
73
|
+
for (const w of chosen) {
|
|
74
|
+
const width = clampSpan(w.span);
|
|
75
|
+
const height = widgetHeight(width);
|
|
76
|
+
if (x + width > GRID_COLUMNS) {
|
|
77
|
+
x = 0;
|
|
78
|
+
y += rowHeight;
|
|
79
|
+
rowHeight = 0;
|
|
80
|
+
}
|
|
81
|
+
const id = widgetId(dashboardSlug, w.widget, w.rank);
|
|
82
|
+
items.push({
|
|
83
|
+
i: id,
|
|
84
|
+
widget: w.widget,
|
|
85
|
+
x,
|
|
86
|
+
y,
|
|
87
|
+
w: width,
|
|
88
|
+
h: height,
|
|
89
|
+
config: { title: w.titleEn, binding: buildBinding(connectionId, w) },
|
|
90
|
+
});
|
|
91
|
+
widgetIds.push(id);
|
|
92
|
+
x += width;
|
|
93
|
+
rowHeight = Math.max(rowHeight, height);
|
|
94
|
+
}
|
|
95
|
+
return { layout: { version: 1, items }, widgetIds };
|
|
96
|
+
}
|
|
97
|
+
// ─── Per-category descriptor emitters ────────────────────────────────────────
|
|
98
|
+
/** Table-label vs column-label: `label:<table>` is table-scoped, else column. */
|
|
99
|
+
function labelWrite(row) {
|
|
100
|
+
const value = row.llmValue;
|
|
101
|
+
if (!isRecord(value) || row.table === undefined)
|
|
102
|
+
return null;
|
|
103
|
+
const bundle = value;
|
|
104
|
+
const body = row.id.slice('label:'.length);
|
|
105
|
+
const column = body === row.table ? null : body.slice(row.table.length + 1) || null;
|
|
106
|
+
const json = { label: bundle.label };
|
|
107
|
+
if (bundle.description !== undefined)
|
|
108
|
+
json['description'] = bundle.description;
|
|
109
|
+
// icon rides with the table-label bundle only (§8.1); columns carry no icon.
|
|
110
|
+
if (column === null && bundle.icon !== undefined)
|
|
111
|
+
json['icon'] = bundle.icon;
|
|
112
|
+
return override(row, 'label', row.table, column, json);
|
|
113
|
+
}
|
|
114
|
+
function keyWrite(row) {
|
|
115
|
+
const value = row.llmValue;
|
|
116
|
+
if (!isRecord(value) || row.table === undefined)
|
|
117
|
+
return null;
|
|
118
|
+
const bundle = value;
|
|
119
|
+
return override(row, 'key', row.table, null, {
|
|
120
|
+
displayColumn: bundle.displayColumn ?? null,
|
|
121
|
+
naturalKey: bundle.naturalKey ?? null,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
function enumWrite(row) {
|
|
125
|
+
const value = row.llmValue;
|
|
126
|
+
if (!isRecord(value) || row.table === undefined)
|
|
127
|
+
return null;
|
|
128
|
+
const e = value;
|
|
129
|
+
const column = row.id.slice(`enum:${row.table}.`.length);
|
|
130
|
+
return override(row, 'enum_semantics', row.table, column, {
|
|
131
|
+
kind: e.kind,
|
|
132
|
+
order: e.order,
|
|
133
|
+
terminal: e.terminal ?? null,
|
|
134
|
+
tones: e.tones,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Per-relation discriminator for the override upsert key. A `fromTable` can carry
|
|
139
|
+
* more than one relation (a junction/denormalized table with several undeclared
|
|
140
|
+
* FKs), and every relation override shares `field`+`table`+`column=null`, so
|
|
141
|
+
* without this the upsert key `(connection, op, table, column)` collides and all
|
|
142
|
+
* but the last relation is silently dropped. Encoding the full relation
|
|
143
|
+
* coordinates (mirroring the §8.1 suggestion id) keeps each distinct relation on
|
|
144
|
+
* its own row while staying deterministic — re-applying the same run upserts in
|
|
145
|
+
* place (idempotent), it never inserts a duplicate.
|
|
146
|
+
*/
|
|
147
|
+
function relationColumnKey(fromColumns, toTable, toColumns) {
|
|
148
|
+
return `${fromColumns.join(',')}->${toTable}.${toColumns.join(',')}`;
|
|
149
|
+
}
|
|
150
|
+
function relationWrite(row) {
|
|
151
|
+
const value = row.llmValue;
|
|
152
|
+
if (!isRecord(value) || row.table === undefined)
|
|
153
|
+
return null;
|
|
154
|
+
if (row.status === 'rejects-heuristic') {
|
|
155
|
+
// A confirmed relation the LLM rejects (`correct: false`) → suppress the FK.
|
|
156
|
+
const rel = value;
|
|
157
|
+
return override(row, 'relation_suppressed', row.table, relationColumnKey(rel.fromColumns, rel.toTable, rel.toColumns), {
|
|
158
|
+
fromColumns: rel.fromColumns,
|
|
159
|
+
toTable: rel.toTable,
|
|
160
|
+
toColumns: rel.toColumns,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
// An inferred relation the engine should treat as a real FK (§8.3).
|
|
164
|
+
const rel = value;
|
|
165
|
+
const json = {
|
|
166
|
+
fromColumns: rel.fromColumns,
|
|
167
|
+
toTable: rel.toTable,
|
|
168
|
+
toColumns: rel.toColumns,
|
|
169
|
+
kind: rel.kind,
|
|
170
|
+
};
|
|
171
|
+
if (rel.viaTable !== undefined)
|
|
172
|
+
json['viaTable'] = rel.viaTable;
|
|
173
|
+
return override(row, 'virtual_relation', row.table, relationColumnKey(rel.fromColumns, rel.toTable, rel.toColumns), json);
|
|
174
|
+
}
|
|
175
|
+
function piiWrite(row) {
|
|
176
|
+
if (row.table === undefined)
|
|
177
|
+
return null;
|
|
178
|
+
const column = row.id.slice(`pii:${row.table}.`.length);
|
|
179
|
+
if (row.status === 'rejects-heuristic') {
|
|
180
|
+
// Explicit `pii: null` over a heuristic flag → an explicit clear (§8.3).
|
|
181
|
+
return override(row, 'pii', row.table, column, null);
|
|
182
|
+
}
|
|
183
|
+
const value = row.llmValue;
|
|
184
|
+
if (!isRecord(value))
|
|
185
|
+
return null;
|
|
186
|
+
return override(row, 'pii', row.table, column, { ...value });
|
|
187
|
+
}
|
|
188
|
+
function copyWrite(row) {
|
|
189
|
+
const value = row.llmValue;
|
|
190
|
+
if (!isRecord(value) || row.table === undefined)
|
|
191
|
+
return null;
|
|
192
|
+
return override(row, 'copy', row.table, null, { ...value });
|
|
193
|
+
}
|
|
194
|
+
function groupWrite(row) {
|
|
195
|
+
const value = row.llmValue;
|
|
196
|
+
if (!isRecord(value))
|
|
197
|
+
return null;
|
|
198
|
+
const g = value;
|
|
199
|
+
return {
|
|
200
|
+
target: 'page',
|
|
201
|
+
kind: 'nav-group',
|
|
202
|
+
suggestionId: row.id,
|
|
203
|
+
group: g.id,
|
|
204
|
+
navOrder: g.order,
|
|
205
|
+
label: g.label,
|
|
206
|
+
icon: g.icon,
|
|
207
|
+
tables: [...g.tables],
|
|
208
|
+
source: 'llm',
|
|
209
|
+
confidence: row.confidence,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
function templateWrite(row, connectionId) {
|
|
213
|
+
const value = row.llmValue;
|
|
214
|
+
if (!isRecord(value) || row.table === undefined)
|
|
215
|
+
return null;
|
|
216
|
+
const t = value;
|
|
217
|
+
return {
|
|
218
|
+
target: 'page',
|
|
219
|
+
kind: 'template-page',
|
|
220
|
+
suggestionId: row.id,
|
|
221
|
+
template: t.template,
|
|
222
|
+
table: row.table,
|
|
223
|
+
rank: t.rank,
|
|
224
|
+
config: { source: { connectionId, table: row.table } },
|
|
225
|
+
source: 'llm',
|
|
226
|
+
confidence: row.confidence,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function dashboardWrite(row, connectionId, accepted) {
|
|
230
|
+
const value = row.llmValue;
|
|
231
|
+
if (!isRecord(value))
|
|
232
|
+
return null;
|
|
233
|
+
const d = value;
|
|
234
|
+
const { layout, widgetIds } = planLayout(connectionId, d.id, d.widgets ?? [], accepted);
|
|
235
|
+
return {
|
|
236
|
+
target: 'page',
|
|
237
|
+
kind: 'dashboard-page',
|
|
238
|
+
suggestionId: row.id,
|
|
239
|
+
dashboard: d.id,
|
|
240
|
+
domain: d.domain,
|
|
241
|
+
label: d.label,
|
|
242
|
+
navOrder: d.order,
|
|
243
|
+
tables: [...d.tables],
|
|
244
|
+
layout,
|
|
245
|
+
widgetIds,
|
|
246
|
+
source: 'llm',
|
|
247
|
+
confidence: row.confidence,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
/** Build an {@link OverrideWrite}, omitting `column` semantics via an explicit null. */
|
|
251
|
+
function override(row, field, table, column, value) {
|
|
252
|
+
return {
|
|
253
|
+
target: 'override',
|
|
254
|
+
suggestionId: row.id,
|
|
255
|
+
field,
|
|
256
|
+
table,
|
|
257
|
+
column,
|
|
258
|
+
value,
|
|
259
|
+
source: 'llm',
|
|
260
|
+
confidence: row.confidence,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
// ─── The planner ─────────────────────────────────────────────────────────────
|
|
264
|
+
/** Categories that never produce a standalone descriptor (widgets fold into dashboards). */
|
|
265
|
+
const FOLDED = new Set(['widget']);
|
|
266
|
+
/** Statuses that carry no LLM value to apply — nothing to write. */
|
|
267
|
+
const NON_ACTIONABLE = new Set([
|
|
268
|
+
'heuristic-only',
|
|
269
|
+
]);
|
|
270
|
+
/**
|
|
271
|
+
* Build the ordered {@link ApplyPlan} for the accepted subset of a reviewed diff
|
|
272
|
+
* (§8.3). Emits one descriptor per accepted suggestion (widgets fold into their
|
|
273
|
+
* dashboard), excludes `user-locked` targets (provenance), and turns
|
|
274
|
+
* `rejects-heuristic` acceptances into suppression descriptors.
|
|
275
|
+
*/
|
|
276
|
+
export function buildApplyPlan(diff, acceptedIds, opts) {
|
|
277
|
+
const accepted = new Set(acceptedIds);
|
|
278
|
+
const writes = [];
|
|
279
|
+
const excludedUserLocked = [];
|
|
280
|
+
for (const row of diff) {
|
|
281
|
+
if (!accepted.has(row.id))
|
|
282
|
+
continue;
|
|
283
|
+
// Provenance user > llm > heuristic: never write over a user edit (§8.3).
|
|
284
|
+
if (row.status === 'user-locked') {
|
|
285
|
+
excludedUserLocked.push(row.id);
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (NON_ACTIONABLE.has(row.status))
|
|
289
|
+
continue;
|
|
290
|
+
if (FOLDED.has(row.category))
|
|
291
|
+
continue; // widgets materialize inside dashboards
|
|
292
|
+
const write = emit(row, opts.connectionId, accepted);
|
|
293
|
+
if (write !== null)
|
|
294
|
+
writes.push(write);
|
|
295
|
+
}
|
|
296
|
+
const plan = { connectionId: opts.connectionId, writes, excludedUserLocked };
|
|
297
|
+
if (opts.llmRunId !== undefined)
|
|
298
|
+
plan.llmRunId = opts.llmRunId;
|
|
299
|
+
return plan;
|
|
300
|
+
}
|
|
301
|
+
function emit(row, connectionId, accepted) {
|
|
302
|
+
switch (row.category) {
|
|
303
|
+
case 'label':
|
|
304
|
+
return labelWrite(row);
|
|
305
|
+
case 'key':
|
|
306
|
+
return keyWrite(row);
|
|
307
|
+
case 'enum':
|
|
308
|
+
return enumWrite(row);
|
|
309
|
+
case 'relation':
|
|
310
|
+
return relationWrite(row);
|
|
311
|
+
case 'pii':
|
|
312
|
+
return piiWrite(row);
|
|
313
|
+
case 'copy':
|
|
314
|
+
return copyWrite(row);
|
|
315
|
+
case 'group':
|
|
316
|
+
return groupWrite(row);
|
|
317
|
+
case 'template':
|
|
318
|
+
return templateWrite(row, connectionId);
|
|
319
|
+
case 'dashboard':
|
|
320
|
+
return dashboardWrite(row, connectionId, accepted);
|
|
321
|
+
case 'widget':
|
|
322
|
+
return null; // folded — handled above
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
/** Human counts for the review confirmation modal (§10.3, task step 3). */
|
|
326
|
+
export function applyPlanSummary(plan) {
|
|
327
|
+
const s = {
|
|
328
|
+
totalWrites: plan.writes.length,
|
|
329
|
+
overrides: 0,
|
|
330
|
+
pages: 0,
|
|
331
|
+
labels: 0,
|
|
332
|
+
keys: 0,
|
|
333
|
+
pii: 0,
|
|
334
|
+
enums: 0,
|
|
335
|
+
relations: 0,
|
|
336
|
+
microcopy: 0,
|
|
337
|
+
navGroups: 0,
|
|
338
|
+
templatePages: 0,
|
|
339
|
+
dashboardPages: 0,
|
|
340
|
+
widgets: 0,
|
|
341
|
+
};
|
|
342
|
+
for (const w of plan.writes) {
|
|
343
|
+
if (w.target === 'override') {
|
|
344
|
+
s.overrides += 1;
|
|
345
|
+
switch (w.field) {
|
|
346
|
+
case 'label':
|
|
347
|
+
s.labels += 1;
|
|
348
|
+
break;
|
|
349
|
+
case 'key':
|
|
350
|
+
s.keys += 1;
|
|
351
|
+
break;
|
|
352
|
+
case 'pii':
|
|
353
|
+
s.pii += 1;
|
|
354
|
+
break;
|
|
355
|
+
case 'enum_semantics':
|
|
356
|
+
s.enums += 1;
|
|
357
|
+
break;
|
|
358
|
+
case 'virtual_relation':
|
|
359
|
+
case 'relation_suppressed':
|
|
360
|
+
s.relations += 1;
|
|
361
|
+
break;
|
|
362
|
+
case 'copy':
|
|
363
|
+
s.microcopy += 1;
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
s.pages += 1;
|
|
369
|
+
if (w.kind === 'nav-group')
|
|
370
|
+
s.navGroups += 1;
|
|
371
|
+
else if (w.kind === 'template-page')
|
|
372
|
+
s.templatePages += 1;
|
|
373
|
+
else {
|
|
374
|
+
s.dashboardPages += 1;
|
|
375
|
+
s.widgets += w.widgetIds.length;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return { ...s, text: summaryText(s) };
|
|
380
|
+
}
|
|
381
|
+
function summaryText(s) {
|
|
382
|
+
const creates = [];
|
|
383
|
+
if (s.dashboardPages > 0) {
|
|
384
|
+
creates.push(`${s.dashboardPages} dashboard ${plural(s.dashboardPages, 'page')} (${s.widgets} ${plural(s.widgets, 'widget')})`);
|
|
385
|
+
}
|
|
386
|
+
if (s.templatePages > 0)
|
|
387
|
+
creates.push(`${s.templatePages} template ${plural(s.templatePages, 'page')}`);
|
|
388
|
+
const updates = [];
|
|
389
|
+
if (s.labels > 0)
|
|
390
|
+
updates.push(`${s.labels} ${plural(s.labels, 'label')}`);
|
|
391
|
+
if (s.keys > 0)
|
|
392
|
+
updates.push(`${s.keys} key ${plural(s.keys, 'column')}`);
|
|
393
|
+
if (s.enums > 0)
|
|
394
|
+
updates.push(`${s.enums} enum ${plural(s.enums, 'semantic')}`);
|
|
395
|
+
if (s.relations > 0)
|
|
396
|
+
updates.push(`${s.relations} ${plural(s.relations, 'relation')}`);
|
|
397
|
+
if (s.pii > 0)
|
|
398
|
+
updates.push(`${s.pii} PII ${plural(s.pii, 'flag')}`);
|
|
399
|
+
if (s.microcopy > 0)
|
|
400
|
+
updates.push(`${s.microcopy} micro-copy ${plural(s.microcopy, 'block')}`);
|
|
401
|
+
if (s.navGroups > 0)
|
|
402
|
+
updates.push(`${s.navGroups} nav ${plural(s.navGroups, 'group')}`);
|
|
403
|
+
const clauses = [];
|
|
404
|
+
if (creates.length > 0)
|
|
405
|
+
clauses.push(`Creates ${joinList(creates)}`);
|
|
406
|
+
if (updates.length > 0)
|
|
407
|
+
clauses.push(`${creates.length > 0 ? 'updates' : 'Updates'} ${joinList(updates)}`);
|
|
408
|
+
if (clauses.length === 0)
|
|
409
|
+
return 'No changes to apply.';
|
|
410
|
+
return `${clauses.join('; ')}.`;
|
|
411
|
+
}
|
|
412
|
+
function plural(n, word) {
|
|
413
|
+
return n === 1 ? word : `${word}s`;
|
|
414
|
+
}
|
|
415
|
+
function joinList(parts) {
|
|
416
|
+
if (parts.length <= 1)
|
|
417
|
+
return parts.join('');
|
|
418
|
+
if (parts.length === 2)
|
|
419
|
+
return `${parts[0]} and ${parts[1]}`;
|
|
420
|
+
return `${parts.slice(0, -1).join(', ')} and ${parts[parts.length - 1]}`;
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/apply/plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable suggestion identity (06-llm-assist.md §8.1).
|
|
3
|
+
*
|
|
4
|
+
* Every atomic suggestion gets a deterministic id so accept/reject state
|
|
5
|
+
* survives a reload and re-application is idempotent. Ids are pure functions of
|
|
6
|
+
* the suggestion's coordinates — no timestamps, no counters, no ordering — so
|
|
7
|
+
* the same suggestion always maps to the same id regardless of when or in what
|
|
8
|
+
* order it is produced.
|
|
9
|
+
*
|
|
10
|
+
* Scheme (§8.1):
|
|
11
|
+
* label:public.orders table label+description+icon bundle
|
|
12
|
+
* label:public.orders.total_cents column label+description bundle
|
|
13
|
+
* key:public.orders displayColumn + naturalKey
|
|
14
|
+
* enum:public.orders.status
|
|
15
|
+
* relation:public.orders.product_id->public.products.id
|
|
16
|
+
* pii:public.customers.email
|
|
17
|
+
* template:public.orders:page-queue-inbox
|
|
18
|
+
* group:sales
|
|
19
|
+
* dashboard:revenue
|
|
20
|
+
* widget:revenue:chart-line-area:3 dashboardId:widgetId:rank
|
|
21
|
+
* copy:public.orders microcopy bundle
|
|
22
|
+
*/
|
|
23
|
+
/** The id-prefix vocabulary. `label` is shared by table- and column-label ids. */
|
|
24
|
+
export declare const SUGGESTION_ID_PREFIXES: readonly ["label", "key", "enum", "relation", "pii", "template", "group", "dashboard", "widget", "copy"];
|
|
25
|
+
export type SuggestionIdPrefix = (typeof SUGGESTION_ID_PREFIXES)[number];
|
|
26
|
+
/** `label:<table>` — the table's label + description + icon bundle. */
|
|
27
|
+
export declare function tableLabelId(table: string): string;
|
|
28
|
+
/** `label:<table>.<column>` — a column's label + description bundle. */
|
|
29
|
+
export declare function columnLabelId(table: string, column: string): string;
|
|
30
|
+
/** `key:<table>` — the displayColumn + naturalKey bundle. */
|
|
31
|
+
export declare function keyId(table: string): string;
|
|
32
|
+
/** `enum:<table>.<column>` — enum semantics for one column. */
|
|
33
|
+
export declare function enumId(table: string, column: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* `relation:<fromTable>.<fromCols>-><toTable>.<toCols>` — one inferred/confirmed
|
|
36
|
+
* relation. Composite endpoints join their columns with `,` so multi-column FKs
|
|
37
|
+
* stay distinct and stable.
|
|
38
|
+
*/
|
|
39
|
+
export declare function relationId(fromTable: string, fromColumns: readonly string[], toTable: string, toColumns: readonly string[]): string;
|
|
40
|
+
/** `pii:<table>.<column>` — a column's PII flag + masking suggestion. */
|
|
41
|
+
export declare function piiId(table: string, column: string): string;
|
|
42
|
+
/** `template:<table>:<template>` — one page-template recommendation for a table. */
|
|
43
|
+
export declare function templateId(table: string, template: string): string;
|
|
44
|
+
/** `group:<slug>` — a navigation group. */
|
|
45
|
+
export declare function groupId(group: string): string;
|
|
46
|
+
/** `dashboard:<slug>` — a dashboard. */
|
|
47
|
+
export declare function dashboardId(dashboard: string): string;
|
|
48
|
+
/** `widget:<dashboard>:<widget>:<rank>` — one widget within a dashboard. */
|
|
49
|
+
export declare function widgetId(dashboard: string, widget: string, rank: number): string;
|
|
50
|
+
/** `copy:<table>` — the micro-copy bundle (empty state + subtitle) for a table. */
|
|
51
|
+
export declare function copyId(table: string): string;
|
|
52
|
+
/**
|
|
53
|
+
* A reference to any atomic suggestion. `suggestionId(ref)` turns it into the
|
|
54
|
+
* stable §8.1 id — the single entry point diff.ts / apply.ts use so the id
|
|
55
|
+
* scheme lives in exactly one place.
|
|
56
|
+
*/
|
|
57
|
+
export type SuggestionRef = {
|
|
58
|
+
readonly kind: 'table-label';
|
|
59
|
+
readonly table: string;
|
|
60
|
+
} | {
|
|
61
|
+
readonly kind: 'column-label';
|
|
62
|
+
readonly table: string;
|
|
63
|
+
readonly column: string;
|
|
64
|
+
} | {
|
|
65
|
+
readonly kind: 'key';
|
|
66
|
+
readonly table: string;
|
|
67
|
+
} | {
|
|
68
|
+
readonly kind: 'enum';
|
|
69
|
+
readonly table: string;
|
|
70
|
+
readonly column: string;
|
|
71
|
+
} | {
|
|
72
|
+
readonly kind: 'relation';
|
|
73
|
+
readonly fromTable: string;
|
|
74
|
+
readonly fromColumns: readonly string[];
|
|
75
|
+
readonly toTable: string;
|
|
76
|
+
readonly toColumns: readonly string[];
|
|
77
|
+
} | {
|
|
78
|
+
readonly kind: 'pii';
|
|
79
|
+
readonly table: string;
|
|
80
|
+
readonly column: string;
|
|
81
|
+
} | {
|
|
82
|
+
readonly kind: 'template';
|
|
83
|
+
readonly table: string;
|
|
84
|
+
readonly template: string;
|
|
85
|
+
} | {
|
|
86
|
+
readonly kind: 'group';
|
|
87
|
+
readonly group: string;
|
|
88
|
+
} | {
|
|
89
|
+
readonly kind: 'dashboard';
|
|
90
|
+
readonly dashboard: string;
|
|
91
|
+
} | {
|
|
92
|
+
readonly kind: 'widget';
|
|
93
|
+
readonly dashboard: string;
|
|
94
|
+
readonly widget: string;
|
|
95
|
+
readonly rank: number;
|
|
96
|
+
} | {
|
|
97
|
+
readonly kind: 'copy';
|
|
98
|
+
readonly table: string;
|
|
99
|
+
};
|
|
100
|
+
export declare function suggestionId(ref: SuggestionRef): string;
|
|
101
|
+
/** Extract the leading `<prefix>:` token of a suggestion id, if it is a known prefix. */
|
|
102
|
+
export declare function suggestionIdPrefix(id: string): SuggestionIdPrefix | null;
|
|
103
|
+
//# sourceMappingURL=suggestion-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggestion-id.d.ts","sourceRoot":"","sources":["../../src/apply/suggestion-id.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable suggestion identity (06-llm-assist.md §8.1).
|
|
3
|
+
*
|
|
4
|
+
* Every atomic suggestion gets a deterministic id so accept/reject state
|
|
5
|
+
* survives a reload and re-application is idempotent. Ids are pure functions of
|
|
6
|
+
* the suggestion's coordinates — no timestamps, no counters, no ordering — so
|
|
7
|
+
* the same suggestion always maps to the same id regardless of when or in what
|
|
8
|
+
* order it is produced.
|
|
9
|
+
*
|
|
10
|
+
* Scheme (§8.1):
|
|
11
|
+
* label:public.orders table label+description+icon bundle
|
|
12
|
+
* label:public.orders.total_cents column label+description bundle
|
|
13
|
+
* key:public.orders displayColumn + naturalKey
|
|
14
|
+
* enum:public.orders.status
|
|
15
|
+
* relation:public.orders.product_id->public.products.id
|
|
16
|
+
* pii:public.customers.email
|
|
17
|
+
* template:public.orders:page-queue-inbox
|
|
18
|
+
* group:sales
|
|
19
|
+
* dashboard:revenue
|
|
20
|
+
* widget:revenue:chart-line-area:3 dashboardId:widgetId:rank
|
|
21
|
+
* copy:public.orders microcopy bundle
|
|
22
|
+
*/
|
|
23
|
+
/** The id-prefix vocabulary. `label` is shared by table- and column-label ids. */
|
|
24
|
+
export const SUGGESTION_ID_PREFIXES = [
|
|
25
|
+
'label',
|
|
26
|
+
'key',
|
|
27
|
+
'enum',
|
|
28
|
+
'relation',
|
|
29
|
+
'pii',
|
|
30
|
+
'template',
|
|
31
|
+
'group',
|
|
32
|
+
'dashboard',
|
|
33
|
+
'widget',
|
|
34
|
+
'copy',
|
|
35
|
+
];
|
|
36
|
+
// ─── Constructors ────────────────────────────────────────────────────────────
|
|
37
|
+
/** `label:<table>` — the table's label + description + icon bundle. */
|
|
38
|
+
export function tableLabelId(table) {
|
|
39
|
+
return `label:${table}`;
|
|
40
|
+
}
|
|
41
|
+
/** `label:<table>.<column>` — a column's label + description bundle. */
|
|
42
|
+
export function columnLabelId(table, column) {
|
|
43
|
+
return `label:${table}.${column}`;
|
|
44
|
+
}
|
|
45
|
+
/** `key:<table>` — the displayColumn + naturalKey bundle. */
|
|
46
|
+
export function keyId(table) {
|
|
47
|
+
return `key:${table}`;
|
|
48
|
+
}
|
|
49
|
+
/** `enum:<table>.<column>` — enum semantics for one column. */
|
|
50
|
+
export function enumId(table, column) {
|
|
51
|
+
return `enum:${table}.${column}`;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* `relation:<fromTable>.<fromCols>-><toTable>.<toCols>` — one inferred/confirmed
|
|
55
|
+
* relation. Composite endpoints join their columns with `,` so multi-column FKs
|
|
56
|
+
* stay distinct and stable.
|
|
57
|
+
*/
|
|
58
|
+
export function relationId(fromTable, fromColumns, toTable, toColumns) {
|
|
59
|
+
return `relation:${fromTable}.${fromColumns.join(',')}->${toTable}.${toColumns.join(',')}`;
|
|
60
|
+
}
|
|
61
|
+
/** `pii:<table>.<column>` — a column's PII flag + masking suggestion. */
|
|
62
|
+
export function piiId(table, column) {
|
|
63
|
+
return `pii:${table}.${column}`;
|
|
64
|
+
}
|
|
65
|
+
/** `template:<table>:<template>` — one page-template recommendation for a table. */
|
|
66
|
+
export function templateId(table, template) {
|
|
67
|
+
return `template:${table}:${template}`;
|
|
68
|
+
}
|
|
69
|
+
/** `group:<slug>` — a navigation group. */
|
|
70
|
+
export function groupId(group) {
|
|
71
|
+
return `group:${group}`;
|
|
72
|
+
}
|
|
73
|
+
/** `dashboard:<slug>` — a dashboard. */
|
|
74
|
+
export function dashboardId(dashboard) {
|
|
75
|
+
return `dashboard:${dashboard}`;
|
|
76
|
+
}
|
|
77
|
+
/** `widget:<dashboard>:<widget>:<rank>` — one widget within a dashboard. */
|
|
78
|
+
export function widgetId(dashboard, widget, rank) {
|
|
79
|
+
return `widget:${dashboard}:${widget}:${rank}`;
|
|
80
|
+
}
|
|
81
|
+
/** `copy:<table>` — the micro-copy bundle (empty state + subtitle) for a table. */
|
|
82
|
+
export function copyId(table) {
|
|
83
|
+
return `copy:${table}`;
|
|
84
|
+
}
|
|
85
|
+
export function suggestionId(ref) {
|
|
86
|
+
switch (ref.kind) {
|
|
87
|
+
case 'table-label':
|
|
88
|
+
return tableLabelId(ref.table);
|
|
89
|
+
case 'column-label':
|
|
90
|
+
return columnLabelId(ref.table, ref.column);
|
|
91
|
+
case 'key':
|
|
92
|
+
return keyId(ref.table);
|
|
93
|
+
case 'enum':
|
|
94
|
+
return enumId(ref.table, ref.column);
|
|
95
|
+
case 'relation':
|
|
96
|
+
return relationId(ref.fromTable, ref.fromColumns, ref.toTable, ref.toColumns);
|
|
97
|
+
case 'pii':
|
|
98
|
+
return piiId(ref.table, ref.column);
|
|
99
|
+
case 'template':
|
|
100
|
+
return templateId(ref.table, ref.template);
|
|
101
|
+
case 'group':
|
|
102
|
+
return groupId(ref.group);
|
|
103
|
+
case 'dashboard':
|
|
104
|
+
return dashboardId(ref.dashboard);
|
|
105
|
+
case 'widget':
|
|
106
|
+
return widgetId(ref.dashboard, ref.widget, ref.rank);
|
|
107
|
+
case 'copy':
|
|
108
|
+
return copyId(ref.table);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/** Extract the leading `<prefix>:` token of a suggestion id, if it is a known prefix. */
|
|
112
|
+
export function suggestionIdPrefix(id) {
|
|
113
|
+
const colon = id.indexOf(':');
|
|
114
|
+
if (colon <= 0)
|
|
115
|
+
return null;
|
|
116
|
+
const prefix = id.slice(0, colon);
|
|
117
|
+
return SUGGESTION_ID_PREFIXES.includes(prefix)
|
|
118
|
+
? prefix
|
|
119
|
+
: null;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=suggestion-id.js.map
|