@contentful/experience-design-system-cli 2.2.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/README.md +532 -0
- package/bin/cli.js +58 -0
- package/dist/package.json +56 -0
- package/dist/src/analyze/command.d.ts +3 -0
- package/dist/src/analyze/command.js +175 -0
- package/dist/src/analyze/extract/astro.d.ts +5 -0
- package/dist/src/analyze/extract/astro.js +280 -0
- package/dist/src/analyze/extract/pipeline.d.ts +6 -0
- package/dist/src/analyze/extract/pipeline.js +298 -0
- package/dist/src/analyze/extract/react.d.ts +2 -0
- package/dist/src/analyze/extract/react.js +1949 -0
- package/dist/src/analyze/extract/slot-detection.d.ts +35 -0
- package/dist/src/analyze/extract/slot-detection.js +101 -0
- package/dist/src/analyze/extract/stencil.d.ts +2 -0
- package/dist/src/analyze/extract/stencil.js +293 -0
- package/dist/src/analyze/extract/tsx-shared.d.ts +8 -0
- package/dist/src/analyze/extract/tsx-shared.js +263 -0
- package/dist/src/analyze/extract/vue-tsx.d.ts +2 -0
- package/dist/src/analyze/extract/vue-tsx.js +498 -0
- package/dist/src/analyze/extract/vue.d.ts +5 -0
- package/dist/src/analyze/extract/vue.js +647 -0
- package/dist/src/analyze/extract/web-components.d.ts +2 -0
- package/dist/src/analyze/extract/web-components.js +866 -0
- package/dist/src/analyze/pre-classify.d.ts +17 -0
- package/dist/src/analyze/pre-classify.js +144 -0
- package/dist/src/analyze/select/command.d.ts +2 -0
- package/dist/src/analyze/select/command.js +256 -0
- package/dist/src/analyze/select/index.d.ts +6 -0
- package/dist/src/analyze/select/index.js +5 -0
- package/dist/src/analyze/select/parser.d.ts +6 -0
- package/dist/src/analyze/select/parser.js +53 -0
- package/dist/src/analyze/select/persistence.d.ts +9 -0
- package/dist/src/analyze/select/persistence.js +42 -0
- package/dist/src/analyze/select/stdout.d.ts +7 -0
- package/dist/src/analyze/select/stdout.js +3 -0
- package/dist/src/analyze/select/tui/App.d.ts +8 -0
- package/dist/src/analyze/select/tui/App.js +491 -0
- package/dist/src/analyze/select/tui/components/ComponentDetail.d.ts +20 -0
- package/dist/src/analyze/select/tui/components/ComponentDetail.js +43 -0
- package/dist/src/analyze/select/tui/components/FieldEditor.d.ts +11 -0
- package/dist/src/analyze/select/tui/components/FieldEditor.js +531 -0
- package/dist/src/analyze/select/tui/components/FinalizeDialog.d.ts +10 -0
- package/dist/src/analyze/select/tui/components/FinalizeDialog.js +15 -0
- package/dist/src/analyze/select/tui/components/HelpOverlay.d.ts +7 -0
- package/dist/src/analyze/select/tui/components/HelpOverlay.js +11 -0
- package/dist/src/analyze/select/tui/components/JsonEditor.d.ts +11 -0
- package/dist/src/analyze/select/tui/components/JsonEditor.js +154 -0
- package/dist/src/analyze/select/tui/components/JsonPanel.d.ts +11 -0
- package/dist/src/analyze/select/tui/components/JsonPanel.js +62 -0
- package/dist/src/analyze/select/tui/components/PreviewSummaryBar.d.ts +8 -0
- package/dist/src/analyze/select/tui/components/PreviewSummaryBar.js +29 -0
- package/dist/src/analyze/select/tui/components/QuitDialog.d.ts +8 -0
- package/dist/src/analyze/select/tui/components/QuitDialog.js +14 -0
- package/dist/src/analyze/select/tui/components/Sidebar.d.ts +15 -0
- package/dist/src/analyze/select/tui/components/Sidebar.js +48 -0
- package/dist/src/analyze/select/tui/components/SourcePanel.d.ts +11 -0
- package/dist/src/analyze/select/tui/components/SourcePanel.js +52 -0
- package/dist/src/analyze/select/tui/components/StatusBar.d.ts +11 -0
- package/dist/src/analyze/select/tui/components/StatusBar.js +6 -0
- package/dist/src/analyze/select/tui/components/TopBar.d.ts +10 -0
- package/dist/src/analyze/select/tui/components/TopBar.js +5 -0
- package/dist/src/analyze/select/tui/hooks/useImmediateInput.d.ts +24 -0
- package/dist/src/analyze/select/tui/hooks/useImmediateInput.js +68 -0
- package/dist/src/analyze/select/tui/hooks/useKeymap.d.ts +24 -0
- package/dist/src/analyze/select/tui/hooks/useKeymap.js +67 -0
- package/dist/src/analyze/select/tui/hooks/useSession.d.ts +19 -0
- package/dist/src/analyze/select/tui/hooks/useSession.js +52 -0
- package/dist/src/analyze/select/tui/hooks/useUndo.d.ts +8 -0
- package/dist/src/analyze/select/tui/hooks/useUndo.js +26 -0
- package/dist/src/analyze/select/types.d.ts +46 -0
- package/dist/src/analyze/select/types.js +20 -0
- package/dist/src/analyze/select-agent/command.d.ts +2 -0
- package/dist/src/analyze/select-agent/command.js +208 -0
- package/dist/src/analyze/tui/AnalyzeView.d.ts +24 -0
- package/dist/src/analyze/tui/AnalyzeView.js +38 -0
- package/dist/src/apply/api-client.d.ts +35 -0
- package/dist/src/apply/api-client.js +143 -0
- package/dist/src/apply/command.d.ts +6 -0
- package/dist/src/apply/command.js +787 -0
- package/dist/src/apply/manifest.d.ts +1 -0
- package/dist/src/apply/manifest.js +1 -0
- package/dist/src/apply/tui/SelectView.d.ts +18 -0
- package/dist/src/apply/tui/SelectView.js +34 -0
- package/dist/src/apply/tui/ServerApplyView.d.ts +32 -0
- package/dist/src/apply/tui/ServerApplyView.js +42 -0
- package/dist/src/apply/tui/ServerPreviewView.d.ts +9 -0
- package/dist/src/apply/tui/ServerPreviewView.js +21 -0
- package/dist/src/credentials-store.d.ts +8 -0
- package/dist/src/credentials-store.js +30 -0
- package/dist/src/generate/agent-runner.d.ts +86 -0
- package/dist/src/generate/agent-runner.js +314 -0
- package/dist/src/generate/command.d.ts +2 -0
- package/dist/src/generate/command.js +545 -0
- package/dist/src/generate/edit/command.d.ts +2 -0
- package/dist/src/generate/edit/command.js +126 -0
- package/dist/src/generate/prompt-builder.d.ts +18 -0
- package/dist/src/generate/prompt-builder.js +202 -0
- package/dist/src/generate/tui/GenerateView.d.ts +12 -0
- package/dist/src/generate/tui/GenerateView.js +10 -0
- package/dist/src/import/command.d.ts +2 -0
- package/dist/src/import/command.js +96 -0
- package/dist/src/import/orchestrator.d.ts +37 -0
- package/dist/src/import/orchestrator.js +374 -0
- package/dist/src/import/path-utils.d.ts +15 -0
- package/dist/src/import/path-utils.js +30 -0
- package/dist/src/import/tui/WizardApp.d.ts +10 -0
- package/dist/src/import/tui/WizardApp.js +906 -0
- package/dist/src/import/tui/steps/CredentialsStep.d.ts +15 -0
- package/dist/src/import/tui/steps/CredentialsStep.js +79 -0
- package/dist/src/import/tui/steps/DoneStep.d.ts +20 -0
- package/dist/src/import/tui/steps/DoneStep.js +17 -0
- package/dist/src/import/tui/steps/ErrorStep.d.ts +8 -0
- package/dist/src/import/tui/steps/ErrorStep.js +11 -0
- package/dist/src/import/tui/steps/GateStep.d.ts +14 -0
- package/dist/src/import/tui/steps/GateStep.js +20 -0
- package/dist/src/import/tui/steps/GenerateReviewStep.d.ts +8 -0
- package/dist/src/import/tui/steps/GenerateReviewStep.js +208 -0
- package/dist/src/import/tui/steps/PathValidationStep.d.ts +10 -0
- package/dist/src/import/tui/steps/PathValidationStep.js +151 -0
- package/dist/src/import/tui/steps/PreviewStep.d.ts +21 -0
- package/dist/src/import/tui/steps/PreviewStep.js +36 -0
- package/dist/src/import/tui/steps/RunningStep.d.ts +10 -0
- package/dist/src/import/tui/steps/RunningStep.js +20 -0
- package/dist/src/import/tui/steps/TokenInputStep.d.ts +8 -0
- package/dist/src/import/tui/steps/TokenInputStep.js +70 -0
- package/dist/src/import/tui/steps/WelcomeStep.d.ts +7 -0
- package/dist/src/import/tui/steps/WelcomeStep.js +33 -0
- package/dist/src/import/tui/steps/WizardPreviewStep.d.ts +15 -0
- package/dist/src/import/tui/steps/WizardPreviewStep.js +121 -0
- package/dist/src/import/tui/steps/preview-diff.d.ts +10 -0
- package/dist/src/import/tui/steps/preview-diff.js +132 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +2 -0
- package/dist/src/output/format.d.ts +23 -0
- package/dist/src/output/format.js +110 -0
- package/dist/src/print/command.d.ts +2 -0
- package/dist/src/print/command.js +199 -0
- package/dist/src/print/validate/tui/ValidateView.d.ts +15 -0
- package/dist/src/print/validate/tui/ValidateView.js +37 -0
- package/dist/src/print/validate/validators/cdf-validator.d.ts +2 -0
- package/dist/src/print/validate/validators/cdf-validator.js +104 -0
- package/dist/src/print/validate/validators/dtcg-validator.d.ts +2 -0
- package/dist/src/print/validate/validators/dtcg-validator.js +110 -0
- package/dist/src/print/validate/validators/format-errors.d.ts +12 -0
- package/dist/src/print/validate/validators/format-errors.js +18 -0
- package/dist/src/program.d.ts +2 -0
- package/dist/src/program.js +25 -0
- package/dist/src/session/command.d.ts +2 -0
- package/dist/src/session/command.js +261 -0
- package/dist/src/session/db.d.ts +111 -0
- package/dist/src/session/db.js +1114 -0
- package/dist/src/session/migration.d.ts +4 -0
- package/dist/src/session/migration.js +117 -0
- package/dist/src/session/session-id.d.ts +1 -0
- package/dist/src/session/session-id.js +212 -0
- package/dist/src/session/stats.d.ts +27 -0
- package/dist/src/session/stats.js +89 -0
- package/dist/src/setup/command.d.ts +2 -0
- package/dist/src/setup/command.js +765 -0
- package/dist/src/types.d.ts +48 -0
- package/dist/src/types.js +1 -0
- package/package.json +55 -0
- package/skills/generate-components.md +361 -0
- package/skills/generate-tokens.md +194 -0
- package/skills/select-components.md +180 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { openPipelineDb, getPipelineDbPath } from './db.js';
|
|
2
|
+
import { getStats, formatStatsText } from './stats.js';
|
|
3
|
+
import { runMigrationIfNeeded } from './migration.js';
|
|
4
|
+
function parseDuration(str) {
|
|
5
|
+
const m = /^(\d+)([dwmy])$/.exec(str);
|
|
6
|
+
if (!m)
|
|
7
|
+
return null;
|
|
8
|
+
const n = parseInt(m[1], 10);
|
|
9
|
+
const unit = m[2];
|
|
10
|
+
const days = unit === 'd' ? n : unit === 'w' ? n * 7 : unit === 'm' ? n * 30 : n * 365;
|
|
11
|
+
return days * 24 * 60 * 60 * 1000;
|
|
12
|
+
}
|
|
13
|
+
function formatDate(iso) {
|
|
14
|
+
return iso.replace('T', ' ').slice(0, 16);
|
|
15
|
+
}
|
|
16
|
+
export function registerSessionCommand(program) {
|
|
17
|
+
const session = program.command('session').description('Manage pipeline sessions');
|
|
18
|
+
// session list
|
|
19
|
+
session
|
|
20
|
+
.command('list')
|
|
21
|
+
.description('List all pipeline sessions')
|
|
22
|
+
.option('--status <status>', 'Filter by status: in-progress, complete, failed, interrupted')
|
|
23
|
+
.option('--all', 'Include interrupted sessions (hidden by default)')
|
|
24
|
+
.option('--limit <n>', 'Max rows to return', '20')
|
|
25
|
+
.option('--json', 'Force JSON output')
|
|
26
|
+
.action((opts) => {
|
|
27
|
+
const dbPath = getPipelineDbPath();
|
|
28
|
+
const db = openPipelineDb(dbPath);
|
|
29
|
+
runMigrationIfNeeded(db);
|
|
30
|
+
const limit = parseInt(opts.limit, 10) || 20;
|
|
31
|
+
const rows = db
|
|
32
|
+
.prepare(`SELECT s.id, s.name, s.updated_at,
|
|
33
|
+
COUNT(st.id) AS step_count,
|
|
34
|
+
(SELECT command FROM steps WHERE session_id = s.id ORDER BY started_at DESC, id DESC LIMIT 1) AS last_step,
|
|
35
|
+
(SELECT status FROM steps WHERE session_id = s.id ORDER BY started_at DESC, id DESC LIMIT 1) AS last_status
|
|
36
|
+
FROM sessions s
|
|
37
|
+
LEFT JOIN steps st ON st.session_id = s.id
|
|
38
|
+
GROUP BY s.id
|
|
39
|
+
ORDER BY s.updated_at DESC
|
|
40
|
+
LIMIT ?`)
|
|
41
|
+
.all(limit);
|
|
42
|
+
let filtered = rows;
|
|
43
|
+
if (opts.status) {
|
|
44
|
+
const filterStatus = opts.status === 'in-progress' ? 'pending' : opts.status;
|
|
45
|
+
filtered = rows.filter((r) => r.last_status === filterStatus || (!r.last_status && opts.status === 'in-progress'));
|
|
46
|
+
}
|
|
47
|
+
else if (!opts.all) {
|
|
48
|
+
// Hide interrupted sessions by default — they're typically migration artifacts
|
|
49
|
+
filtered = rows.filter((r) => r.last_status !== 'interrupted');
|
|
50
|
+
}
|
|
51
|
+
db.close();
|
|
52
|
+
if (opts.json) {
|
|
53
|
+
process.stdout.write(JSON.stringify(filtered.map((r) => ({
|
|
54
|
+
id: r.id,
|
|
55
|
+
name: r.name,
|
|
56
|
+
status: r.last_status ?? null,
|
|
57
|
+
stepCount: r.step_count,
|
|
58
|
+
lastStep: r.last_step,
|
|
59
|
+
updatedAt: r.updated_at,
|
|
60
|
+
})), null, 2) + '\n');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (filtered.length === 0) {
|
|
64
|
+
process.stdout.write('No sessions found.\n');
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const header = 'ID Name Steps Status Last Step Updated';
|
|
68
|
+
process.stdout.write(header + '\n');
|
|
69
|
+
process.stdout.write('─'.repeat(header.length) + '\n');
|
|
70
|
+
for (const r of filtered) {
|
|
71
|
+
const id = r.id.padEnd(22);
|
|
72
|
+
const name = (r.name ?? '(none)').slice(0, 18).padEnd(20);
|
|
73
|
+
const steps = String(r.step_count).padStart(5);
|
|
74
|
+
const status = (r.last_status ?? '—').padEnd(13);
|
|
75
|
+
const lastStep = (r.last_step ?? '—').padEnd(22);
|
|
76
|
+
const updated = formatDate(r.updated_at);
|
|
77
|
+
process.stdout.write(`${id}${name}${steps} ${status}${lastStep}${updated}\n`);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
// session show
|
|
81
|
+
session
|
|
82
|
+
.command('show <id>')
|
|
83
|
+
.description('Show all steps for a session')
|
|
84
|
+
.option('--json', 'Force JSON output')
|
|
85
|
+
.action((id, opts) => {
|
|
86
|
+
const dbPath = getPipelineDbPath();
|
|
87
|
+
const db = openPipelineDb(dbPath);
|
|
88
|
+
runMigrationIfNeeded(db);
|
|
89
|
+
const sess = db.prepare('SELECT id, name, created_at, updated_at FROM sessions WHERE id = ?').get(id);
|
|
90
|
+
if (!sess) {
|
|
91
|
+
db.close();
|
|
92
|
+
process.stderr.write(`Error: session '${id}' not found.\n`);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
const steps = db
|
|
96
|
+
.prepare(`SELECT id, command, status, started_at, completed_at, inputs, outputs, error
|
|
97
|
+
FROM steps WHERE session_id = ? ORDER BY started_at ASC, id ASC`)
|
|
98
|
+
.all(id);
|
|
99
|
+
db.close();
|
|
100
|
+
if (opts.json) {
|
|
101
|
+
process.stdout.write(JSON.stringify({
|
|
102
|
+
id: sess.id,
|
|
103
|
+
name: sess.name,
|
|
104
|
+
createdAt: sess.created_at,
|
|
105
|
+
updatedAt: sess.updated_at,
|
|
106
|
+
steps: steps.map((s, i) => ({
|
|
107
|
+
number: i + 1,
|
|
108
|
+
command: s.command,
|
|
109
|
+
status: s.status,
|
|
110
|
+
startedAt: s.started_at,
|
|
111
|
+
completedAt: s.completed_at,
|
|
112
|
+
inputs: JSON.parse(s.inputs),
|
|
113
|
+
outputs: JSON.parse(s.outputs),
|
|
114
|
+
error: s.error,
|
|
115
|
+
})),
|
|
116
|
+
}, null, 2) + '\n');
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
process.stdout.write(`Session: ${sess.id}\n`);
|
|
120
|
+
process.stdout.write(`Name: ${sess.name ?? '(none)'}\n`);
|
|
121
|
+
process.stdout.write(`Created: ${formatDate(sess.created_at)}\n`);
|
|
122
|
+
process.stdout.write(`Updated: ${formatDate(sess.updated_at)}\n`);
|
|
123
|
+
process.stdout.write(`\nSteps\n${'─'.repeat(60)}\n`);
|
|
124
|
+
for (const [i, s] of steps.entries()) {
|
|
125
|
+
const num = String(i + 1).padStart(3);
|
|
126
|
+
const cmd = s.command.padEnd(20);
|
|
127
|
+
const stat = s.status.padEnd(12);
|
|
128
|
+
const timing = s.completed_at
|
|
129
|
+
? `${s.started_at.slice(11, 16)} → ${s.completed_at.slice(11, 16)}`
|
|
130
|
+
: `${s.started_at.slice(11, 16)} → …`;
|
|
131
|
+
let inputs = {};
|
|
132
|
+
let outputs = {};
|
|
133
|
+
try {
|
|
134
|
+
inputs = JSON.parse(s.inputs);
|
|
135
|
+
outputs = JSON.parse(s.outputs);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// ignore
|
|
139
|
+
}
|
|
140
|
+
const inputStr = Object.values(inputs).join(', ');
|
|
141
|
+
const outputStr = Object.values(outputs).join(', ');
|
|
142
|
+
const paths = [inputStr, outputStr].filter(Boolean).join(' → ');
|
|
143
|
+
process.stdout.write(`${num} ${cmd}${stat}${timing} ${paths}\n`);
|
|
144
|
+
if (s.error) {
|
|
145
|
+
process.stdout.write(` Error: ${s.error}\n`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
// session stats
|
|
150
|
+
session
|
|
151
|
+
.command('stats')
|
|
152
|
+
.description('Show aggregate storage and record counts')
|
|
153
|
+
.option('--json', 'Force JSON output')
|
|
154
|
+
.action((opts) => {
|
|
155
|
+
const dbPath = getPipelineDbPath();
|
|
156
|
+
const db = openPipelineDb(dbPath);
|
|
157
|
+
runMigrationIfNeeded(db);
|
|
158
|
+
const stats = getStats(db, dbPath);
|
|
159
|
+
db.close();
|
|
160
|
+
if (opts.json) {
|
|
161
|
+
process.stdout.write(JSON.stringify(stats, null, 2) + '\n');
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
process.stdout.write(formatStatsText(stats) + '\n');
|
|
165
|
+
});
|
|
166
|
+
// session prune
|
|
167
|
+
session
|
|
168
|
+
.command('prune')
|
|
169
|
+
.description('Delete sessions matching criteria')
|
|
170
|
+
.option('--id <id>', 'Delete a specific session by ID')
|
|
171
|
+
.option('--older-than <duration>', 'Delete sessions older than this age (e.g. 30d, 2w, 1y)')
|
|
172
|
+
.option('--status <status>', 'Delete sessions by last step status: complete, failed, interrupted')
|
|
173
|
+
.option('--yes', 'Skip confirmation prompt')
|
|
174
|
+
.option('--dry-run', 'Print what would be deleted without deleting')
|
|
175
|
+
.action(async (opts) => {
|
|
176
|
+
if (!opts.id && !opts.olderThan && !opts.status) {
|
|
177
|
+
process.stderr.write('Error: at least one of --id, --older-than, or --status is required\n');
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|
|
180
|
+
const dbPath = getPipelineDbPath();
|
|
181
|
+
const db = openPipelineDb(dbPath);
|
|
182
|
+
runMigrationIfNeeded(db);
|
|
183
|
+
// Build the list of sessions to delete
|
|
184
|
+
let candidates;
|
|
185
|
+
if (opts.id) {
|
|
186
|
+
const sess = db.prepare('SELECT id, updated_at FROM sessions WHERE id = ?').get(opts.id);
|
|
187
|
+
if (!sess) {
|
|
188
|
+
db.close();
|
|
189
|
+
process.stderr.write(`Error: session '${opts.id}' not found.\n`);
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
candidates = [sess];
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
candidates = db.prepare('SELECT id, updated_at FROM sessions ORDER BY updated_at DESC').all();
|
|
196
|
+
}
|
|
197
|
+
if (opts.olderThan) {
|
|
198
|
+
const ms = parseDuration(opts.olderThan);
|
|
199
|
+
if (!ms) {
|
|
200
|
+
db.close();
|
|
201
|
+
process.stderr.write(`Error: invalid duration '${opts.olderThan}'. Use e.g. 30d, 2w, 1y.\n`);
|
|
202
|
+
process.exit(1);
|
|
203
|
+
}
|
|
204
|
+
const cutoff = new Date(Date.now() - ms).toISOString();
|
|
205
|
+
candidates = candidates.filter((c) => c.updated_at < cutoff);
|
|
206
|
+
}
|
|
207
|
+
if (opts.status) {
|
|
208
|
+
const filterStatus = opts.status === 'in-progress' ? 'pending' : opts.status;
|
|
209
|
+
candidates = candidates.filter((c) => {
|
|
210
|
+
const lastStep = db
|
|
211
|
+
.prepare('SELECT status FROM steps WHERE session_id = ? ORDER BY started_at DESC, id DESC LIMIT 1')
|
|
212
|
+
.get(c.id);
|
|
213
|
+
return lastStep?.status === filterStatus;
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
if (candidates.length === 0) {
|
|
217
|
+
db.close();
|
|
218
|
+
process.stdout.write('No sessions match the specified criteria.\n');
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (opts.dryRun) {
|
|
222
|
+
db.close();
|
|
223
|
+
process.stdout.write(`Would delete ${candidates.length} session(s):\n\n`);
|
|
224
|
+
for (const c of candidates) {
|
|
225
|
+
process.stdout.write(` ${c.id.padEnd(22)}last updated ${c.updated_at.slice(0, 10)}\n`);
|
|
226
|
+
}
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (!opts.yes && process.stdout.isTTY) {
|
|
230
|
+
process.stdout.write(`This will delete ${candidates.length} session(s) matching your criteria.\n\n`);
|
|
231
|
+
for (const c of candidates) {
|
|
232
|
+
process.stdout.write(` ${c.id.padEnd(22)}last updated ${c.updated_at.slice(0, 10)}\n`);
|
|
233
|
+
}
|
|
234
|
+
process.stdout.write('\nDelete these sessions? (y/N) ');
|
|
235
|
+
const answer = await new Promise((resolve) => {
|
|
236
|
+
process.stdin.setEncoding('utf8');
|
|
237
|
+
process.stdin.once('data', (chunk) => resolve(String(chunk).trim().toLowerCase()));
|
|
238
|
+
});
|
|
239
|
+
if (answer !== 'y') {
|
|
240
|
+
db.close();
|
|
241
|
+
process.stdout.write('Cancelled.\n');
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
db.exec('BEGIN');
|
|
246
|
+
try {
|
|
247
|
+
for (const c of candidates) {
|
|
248
|
+
db.prepare('DELETE FROM sessions WHERE id = ?').run(c.id);
|
|
249
|
+
}
|
|
250
|
+
db.exec('COMMIT');
|
|
251
|
+
}
|
|
252
|
+
catch (e) {
|
|
253
|
+
db.exec('ROLLBACK');
|
|
254
|
+
db.close();
|
|
255
|
+
process.stderr.write(`Error: failed to delete sessions: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
256
|
+
process.exit(1);
|
|
257
|
+
}
|
|
258
|
+
db.close();
|
|
259
|
+
process.stdout.write(`Deleted ${candidates.length} session(s).\n`);
|
|
260
|
+
});
|
|
261
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
2
|
+
import type { RawComponentDefinition } from '../types.js';
|
|
3
|
+
import type { CDFComponentEntry, DTCGTokenEntry, DTCGTokenGroup } from '@contentful/experience-design-system-types';
|
|
4
|
+
import type { ToolCall, TokenToolCall } from '../generate/agent-runner.js';
|
|
5
|
+
import type { ComponentTypeSummary } from '@contentful/experience-design-system-types';
|
|
6
|
+
export type StepStatus = 'pending' | 'complete' | 'failed' | 'interrupted';
|
|
7
|
+
export type CommandName = 'analyze extract' | 'analyze select' | 'generate components' | 'generate tokens' | 'generate edit' | 'apply preview' | 'apply select' | 'apply push' | 'print components' | 'print tokens' | 'import';
|
|
8
|
+
export interface SessionRow {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string | null;
|
|
11
|
+
created_at: string;
|
|
12
|
+
updated_at: string;
|
|
13
|
+
}
|
|
14
|
+
export interface StepRow {
|
|
15
|
+
id: number;
|
|
16
|
+
session_id: string;
|
|
17
|
+
command: string;
|
|
18
|
+
status: StepStatus;
|
|
19
|
+
started_at: string;
|
|
20
|
+
completed_at: string | null;
|
|
21
|
+
inputs: string;
|
|
22
|
+
outputs: string;
|
|
23
|
+
error: string | null;
|
|
24
|
+
updated_at: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function getPipelineDbPath(): string;
|
|
27
|
+
export declare function openPipelineDb(dbPath?: string): DatabaseSync;
|
|
28
|
+
export interface ApplyToolCallsResult {
|
|
29
|
+
classified: number;
|
|
30
|
+
excluded: number;
|
|
31
|
+
slots: number;
|
|
32
|
+
warnings: string[];
|
|
33
|
+
}
|
|
34
|
+
export declare function applyToolCalls(db: DatabaseSync, sessionId: string, componentId: string, componentName: string, calls: ToolCall[], incomingWarnings: string[]): ApplyToolCallsResult;
|
|
35
|
+
export interface MatchHints {
|
|
36
|
+
command: CommandName;
|
|
37
|
+
inputPath?: string;
|
|
38
|
+
outDir?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface SessionResolution {
|
|
41
|
+
sessionId: string;
|
|
42
|
+
isNew: boolean;
|
|
43
|
+
isResumed: boolean;
|
|
44
|
+
}
|
|
45
|
+
export declare function getOrCreateSession(db: DatabaseSync, sessionFlag: string | undefined, sessionName: string | undefined, hints: MatchHints): SessionResolution;
|
|
46
|
+
export declare function createStep(db: DatabaseSync, sessionId: string, command: CommandName, inputs: Record<string, string>): number;
|
|
47
|
+
export declare function updateStep(db: DatabaseSync, stepId: number, status: 'complete' | 'failed', outputs: Record<string, string>, error?: string): void;
|
|
48
|
+
export declare function storeRawComponents(db: DatabaseSync, sessionId: string, components: RawComponentDefinition[], options?: {
|
|
49
|
+
status?: string;
|
|
50
|
+
preserveCDF?: boolean;
|
|
51
|
+
}): void;
|
|
52
|
+
export type RawComponentWithId = RawComponentDefinition & {
|
|
53
|
+
component_id: string;
|
|
54
|
+
};
|
|
55
|
+
export declare function loadRawComponents(db: DatabaseSync, sessionId: string, allowedNames?: Set<string>): RawComponentWithId[];
|
|
56
|
+
export declare function storeCDFComponents(db: DatabaseSync, sessionId: string, components: Array<{
|
|
57
|
+
key: string;
|
|
58
|
+
entry: CDFComponentEntry;
|
|
59
|
+
}>): void;
|
|
60
|
+
export declare function loadCDFComponents(db: DatabaseSync, sessionId: string): Array<{
|
|
61
|
+
key: string;
|
|
62
|
+
entry: CDFComponentEntry;
|
|
63
|
+
}>;
|
|
64
|
+
export declare function storeDTCGTokens(db: DatabaseSync, sessionId: string, groups: DTCGTokenGroup[], tokens: DTCGTokenEntry[]): void;
|
|
65
|
+
export interface ApplyTokenToolCallsResult {
|
|
66
|
+
tokens: number;
|
|
67
|
+
groups: number;
|
|
68
|
+
warnings: string[];
|
|
69
|
+
}
|
|
70
|
+
export declare function applyTokenToolCalls(db: DatabaseSync, sessionId: string, calls: TokenToolCall[], incomingWarnings: string[]): ApplyTokenToolCallsResult;
|
|
71
|
+
export declare function loadDTCGTokens(db: DatabaseSync, sessionId: string): {
|
|
72
|
+
groups: DTCGTokenGroup[];
|
|
73
|
+
tokens: DTCGTokenEntry[];
|
|
74
|
+
};
|
|
75
|
+
export declare function findLatestSessionForCommand(db: DatabaseSync, command: CommandName): string | null;
|
|
76
|
+
export declare function seedCDFFromPriorSession(db: DatabaseSync, targetSessionId: string): number;
|
|
77
|
+
export declare function seedCDFFromPreviewResponse(db: DatabaseSync, sessionId: string, removedItems: ComponentTypeSummary[]): number;
|
|
78
|
+
/**
|
|
79
|
+
* Seeds server-side metadata for changed components:
|
|
80
|
+
* 1. Fills in defaults the server has but we don't (prevents accidental removal)
|
|
81
|
+
* 2. Seeds cdf_type/cdf_category for props that exist on server but lack CDF locally
|
|
82
|
+
* (e.g. props with non-standard source types the generation step couldn't classify)
|
|
83
|
+
*/
|
|
84
|
+
export declare function seedDefaultsFromChangedItems(db: DatabaseSync, sessionId: string, changedItems: Array<{
|
|
85
|
+
current: ComponentTypeSummary;
|
|
86
|
+
proposed: Record<string, unknown>;
|
|
87
|
+
}>): number;
|
|
88
|
+
/**
|
|
89
|
+
* Ensures all props on generated components have a cdf_type.
|
|
90
|
+
* Uses the pre-classification `category` column when available.
|
|
91
|
+
* Falls back to cdf_type: 'string', cdf_category: 'content' for props
|
|
92
|
+
* with no pre-classification (safe default — content is the most common category).
|
|
93
|
+
*/
|
|
94
|
+
export declare function backfillUnclassifiedProps(db: DatabaseSync, sessionId: string): number;
|
|
95
|
+
export interface CacheEntry {
|
|
96
|
+
inputHash: string;
|
|
97
|
+
entityType: 'component' | 'token_set';
|
|
98
|
+
entityId: string;
|
|
99
|
+
sourceSessionId: string;
|
|
100
|
+
humanEdited: boolean;
|
|
101
|
+
createdAt: string;
|
|
102
|
+
updatedAt: string;
|
|
103
|
+
}
|
|
104
|
+
export declare function computeComponentInputHash(component: RawComponentWithId): string;
|
|
105
|
+
export declare function computeTokenInputHash(rawTokenContent: string): string;
|
|
106
|
+
export declare function lookupCache(db: DatabaseSync, inputHash: string, entityType: 'component' | 'token_set', entityId: string): CacheEntry | null;
|
|
107
|
+
export declare function lookupCacheByEntity(db: DatabaseSync, entityType: 'component' | 'token_set', entityId: string): CacheEntry | null;
|
|
108
|
+
export declare function storeCache(db: DatabaseSync, inputHash: string, entityType: 'component' | 'token_set', entityId: string, sourceSessionId: string, humanEdited: boolean): void;
|
|
109
|
+
export declare function markCacheHumanEdited(db: DatabaseSync, entityType: 'component' | 'token_set', entityId: string): void;
|
|
110
|
+
export declare function copyComponentFromCache(db: DatabaseSync, sourceSessionId: string, targetSessionId: string, componentId: string): void;
|
|
111
|
+
export declare function copyTokensFromCache(db: DatabaseSync, sourceSessionId: string, targetSessionId: string): void;
|