@gurulu/cli 0.4.7 → 1.0.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.
Files changed (190) hide show
  1. package/LICENSE +92 -0
  2. package/README.md +35 -106
  3. package/dist/bin.d.ts +3 -0
  4. package/dist/bin.d.ts.map +1 -0
  5. package/dist/bin.js +25751 -0
  6. package/dist/commands/auth.d.ts +23 -20
  7. package/dist/commands/auth.d.ts.map +1 -0
  8. package/dist/commands/doctor.d.ts +20 -6
  9. package/dist/commands/doctor.d.ts.map +1 -0
  10. package/dist/commands/init.d.ts +33 -11
  11. package/dist/commands/init.d.ts.map +1 -0
  12. package/dist/commands/pull.d.ts +13 -0
  13. package/dist/commands/pull.d.ts.map +1 -0
  14. package/dist/commands/push.d.ts +40 -0
  15. package/dist/commands/push.d.ts.map +1 -0
  16. package/dist/commands/validate.d.ts +36 -0
  17. package/dist/commands/validate.d.ts.map +1 -0
  18. package/dist/index.d.ts +4 -1
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +25326 -876
  21. package/dist/lib/api.d.ts +139 -0
  22. package/dist/lib/api.d.ts.map +1 -0
  23. package/dist/lib/codegen.d.ts +4 -0
  24. package/dist/lib/codegen.d.ts.map +1 -0
  25. package/dist/lib/config.d.ts +43 -0
  26. package/dist/lib/config.d.ts.map +1 -0
  27. package/dist/lib/detect.d.ts +27 -0
  28. package/dist/lib/detect.d.ts.map +1 -0
  29. package/dist/lib/detect.js +106 -0
  30. package/dist/lib/exec-install.d.ts +21 -0
  31. package/dist/lib/exec-install.d.ts.map +1 -0
  32. package/dist/lib/install-plan.d.ts +25 -0
  33. package/dist/lib/install-plan.d.ts.map +1 -0
  34. package/dist/lib/install-plan.js +161 -0
  35. package/package.json +51 -20
  36. package/bin/gurulu.js +0 -2
  37. package/dist/api-client.d.ts +0 -33
  38. package/dist/api-client.js +0 -175
  39. package/dist/commands/add-server.d.ts +0 -9
  40. package/dist/commands/add-server.js +0 -162
  41. package/dist/commands/alerts.d.ts +0 -27
  42. package/dist/commands/alerts.js +0 -309
  43. package/dist/commands/api-keys.d.ts +0 -20
  44. package/dist/commands/api-keys.js +0 -130
  45. package/dist/commands/attribution.d.ts +0 -22
  46. package/dist/commands/attribution.js +0 -111
  47. package/dist/commands/audiences.d.ts +0 -23
  48. package/dist/commands/audiences.js +0 -243
  49. package/dist/commands/audit.d.ts +0 -20
  50. package/dist/commands/audit.js +0 -130
  51. package/dist/commands/auth.js +0 -249
  52. package/dist/commands/chat.d.ts +0 -19
  53. package/dist/commands/chat.js +0 -118
  54. package/dist/commands/config.d.ts +0 -10
  55. package/dist/commands/config.js +0 -92
  56. package/dist/commands/consent.d.ts +0 -27
  57. package/dist/commands/consent.js +0 -233
  58. package/dist/commands/conversion-paths.d.ts +0 -19
  59. package/dist/commands/conversion-paths.js +0 -55
  60. package/dist/commands/db.d.ts +0 -25
  61. package/dist/commands/db.js +0 -330
  62. package/dist/commands/destinations.d.ts +0 -20
  63. package/dist/commands/destinations.js +0 -191
  64. package/dist/commands/doctor.js +0 -360
  65. package/dist/commands/errors.d.ts +0 -27
  66. package/dist/commands/errors.js +0 -121
  67. package/dist/commands/events.d.ts +0 -33
  68. package/dist/commands/events.js +0 -371
  69. package/dist/commands/experiments.d.ts +0 -22
  70. package/dist/commands/experiments.js +0 -264
  71. package/dist/commands/funnels.d.ts +0 -17
  72. package/dist/commands/funnels.js +0 -203
  73. package/dist/commands/goals.d.ts +0 -18
  74. package/dist/commands/goals.js +0 -214
  75. package/dist/commands/heatmap.d.ts +0 -27
  76. package/dist/commands/heatmap.js +0 -112
  77. package/dist/commands/identity.d.ts +0 -29
  78. package/dist/commands/identity.js +0 -328
  79. package/dist/commands/init.js +0 -215
  80. package/dist/commands/insights.d.ts +0 -10
  81. package/dist/commands/insights.js +0 -77
  82. package/dist/commands/install.d.ts +0 -259
  83. package/dist/commands/install.js +0 -1590
  84. package/dist/commands/login.d.ts +0 -20
  85. package/dist/commands/login.js +0 -170
  86. package/dist/commands/logout.d.ts +0 -10
  87. package/dist/commands/logout.js +0 -41
  88. package/dist/commands/playground.d.ts +0 -11
  89. package/dist/commands/playground.js +0 -47
  90. package/dist/commands/releases.d.ts +0 -17
  91. package/dist/commands/releases.js +0 -54
  92. package/dist/commands/replay.d.ts +0 -18
  93. package/dist/commands/replay.js +0 -64
  94. package/dist/commands/secrets.d.ts +0 -19
  95. package/dist/commands/secrets.js +0 -145
  96. package/dist/commands/setup.d.ts +0 -21
  97. package/dist/commands/setup.js +0 -67
  98. package/dist/commands/sites.d.ts +0 -18
  99. package/dist/commands/sites.js +0 -139
  100. package/dist/commands/skad.d.ts +0 -18
  101. package/dist/commands/skad.js +0 -53
  102. package/dist/commands/sourcemap.d.ts +0 -33
  103. package/dist/commands/sourcemap.js +0 -204
  104. package/dist/commands/status.d.ts +0 -7
  105. package/dist/commands/status.js +0 -136
  106. package/dist/commands/upgrade.d.ts +0 -21
  107. package/dist/commands/upgrade.js +0 -183
  108. package/dist/commands/warehouse.d.ts +0 -20
  109. package/dist/commands/warehouse.js +0 -65
  110. package/dist/commands/warehouses.d.ts +0 -17
  111. package/dist/commands/warehouses.js +0 -182
  112. package/dist/commands/watch.d.ts +0 -45
  113. package/dist/commands/watch.js +0 -258
  114. package/dist/commands/whoami.d.ts +0 -9
  115. package/dist/commands/whoami.js +0 -50
  116. package/dist/config.d.ts +0 -75
  117. package/dist/config.js +0 -329
  118. package/dist/frameworks/detect.d.ts +0 -8
  119. package/dist/frameworks/detect.js +0 -458
  120. package/dist/install-intent-proposal.d.ts +0 -99
  121. package/dist/install-intent-proposal.js +0 -202
  122. package/dist/utils/api.d.ts +0 -20
  123. package/dist/utils/api.js +0 -47
  124. package/dist/utils/config.d.ts +0 -13
  125. package/dist/utils/config.js +0 -30
  126. package/dist/utils/confirm.d.ts +0 -17
  127. package/dist/utils/confirm.js +0 -40
  128. package/dist/utils/dry-run.d.ts +0 -20
  129. package/dist/utils/dry-run.js +0 -67
  130. package/dist/utils/from-file.d.ts +0 -9
  131. package/dist/utils/from-file.js +0 -72
  132. package/dist/utils/redact.d.ts +0 -14
  133. package/dist/utils/redact.js +0 -48
  134. package/dist/utils/ui.d.ts +0 -14
  135. package/dist/utils/ui.js +0 -59
  136. package/scripts/.gitkeep +0 -0
  137. package/scripts/README-gurulu-agentic-install.md +0 -114
  138. package/scripts/README-gurulu-scan.md +0 -98
  139. package/scripts/audit-cli-scopes.mjs +0 -204
  140. package/scripts/backfill-tenant-id.mjs +0 -172
  141. package/scripts/backfill-tenant-links.ts +0 -252
  142. package/scripts/backup-clickhouse.sh +0 -27
  143. package/scripts/backup-postgres.sh +0 -19
  144. package/scripts/bootstrap-runtime-schema.mjs +0 -87
  145. package/scripts/bootstrap-stripe.mjs +0 -158
  146. package/scripts/gurulu-agentic-install.lib.cjs +0 -762
  147. package/scripts/gurulu-agentic-install.mjs +0 -623
  148. package/scripts/gurulu-scan.lib.cjs +0 -1509
  149. package/scripts/gurulu-scan.mjs +0 -91
  150. package/scripts/gurulu-verify-install.lib.cjs +0 -334
  151. package/scripts/gurulu-verify-install.mjs +0 -59
  152. package/scripts/init-ssl.sh +0 -26
  153. package/scripts/migrate-flow-graph-enums.sh +0 -86
  154. package/scripts/monitor-disk.sh +0 -24
  155. package/scripts/patches/astro.patch.cjs +0 -74
  156. package/scripts/patches/auto-instrument/ast-helper.cjs +0 -480
  157. package/scripts/patches/auto-instrument/astro.cjs +0 -273
  158. package/scripts/patches/auto-instrument/express.cjs +0 -383
  159. package/scripts/patches/auto-instrument/fastify.cjs +0 -262
  160. package/scripts/patches/auto-instrument/hono.cjs +0 -392
  161. package/scripts/patches/auto-instrument/index.cjs +0 -80
  162. package/scripts/patches/auto-instrument/nestjs.cjs +0 -286
  163. package/scripts/patches/auto-instrument/nextjs-app-router.cjs +0 -345
  164. package/scripts/patches/auto-instrument/nextjs-pages.cjs +0 -361
  165. package/scripts/patches/auto-instrument/remix.cjs +0 -168
  166. package/scripts/patches/auto-instrument/sdk-helper-map.cjs +0 -241
  167. package/scripts/patches/auto-instrument/singleton-helper.cjs +0 -193
  168. package/scripts/patches/auto-instrument/sveltekit.cjs +0 -161
  169. package/scripts/patches/auto-instrument/vite-react.cjs +0 -37
  170. package/scripts/patches/auto-instrument/vue.cjs +0 -196
  171. package/scripts/patches/express.patch.cjs +0 -99
  172. package/scripts/patches/fastify.patch.cjs +0 -108
  173. package/scripts/patches/index.cjs +0 -300
  174. package/scripts/patches/nestjs.patch.cjs +0 -112
  175. package/scripts/patches/nextjs-app-router.patch.cjs +0 -97
  176. package/scripts/patches/nextjs-pages.patch.cjs +0 -97
  177. package/scripts/patches/remix.patch.cjs +0 -75
  178. package/scripts/patches/sveltekit.patch.cjs +0 -72
  179. package/scripts/patches/vite-react.patch.cjs +0 -73
  180. package/scripts/patches/vue.patch.cjs +0 -82
  181. package/scripts/renew-ssl.sh +0 -14
  182. package/scripts/resolve-migration.sh +0 -23
  183. package/scripts/seed-cli-dev-keys.mjs +0 -130
  184. package/scripts/seed-test-data.mjs +0 -391
  185. package/scripts/spike-browserless.ts +0 -65
  186. package/scripts/tenant-pivot-consistency-check.mjs +0 -205
  187. package/scripts/tenant-pivot-phase-3-cleanup.lib.cjs +0 -258
  188. package/scripts/tenant-pivot-phase-3-cleanup.mjs +0 -98
  189. package/scripts/test-identity-resolution.ts +0 -804
  190. package/scripts/validate-gurulu-schemas.mjs +0 -79
@@ -1,258 +0,0 @@
1
- // tenant-pivot-phase-3-cleanup.lib.cjs — destructive-cleanup logic for the
2
- // Phase 18 A4 tenant pivot phase 3 migration (drop `site_id` column).
3
- //
4
- // CommonJS so it can be `require()`-d by both the ESM CLI wrapper
5
- // (`scripts/tenant-pivot-phase-3-cleanup.mjs`) and the ts-jest test
6
- // (`tests/scripts-tenant-pivot-phase-3-cleanup.test.ts`). See the README
7
- // header in the .mjs wrapper for the operator-facing contract.
8
- //
9
- // IMPORTANT: This module exposes pure helpers and a CLI orchestrator. None of
10
- // it self-executes. The `.mjs` wrapper is the only thing with a top-level
11
- // `runCli()` call, gated on `import.meta.url === process.argv[1]`.
12
-
13
- 'use strict';
14
-
15
- const fs = require('node:fs').promises;
16
- const path = require('node:path');
17
- const readline = require('node:readline');
18
-
19
- // ---------------------------------------------------------------------------
20
- // Constants
21
- // ---------------------------------------------------------------------------
22
-
23
- // Every analytics table that still carries `site_id` after Phase 18 A4. See
24
- // docker/clickhouse/init/01_schema.sql for the canonical column definitions.
25
- // ORDER MATTERS for the dry-run output but not for execution.
26
- const AFFECTED_TABLES = [
27
- 'events_raw',
28
- 'flow_session_events',
29
- 'journey_events',
30
- 'cross_property_journeys',
31
- 'inferred_events',
32
- ];
33
-
34
- const LOG_PATH_DEFAULT = path.resolve(process.cwd(), 'logs', 'tenant-pivot-phase-3.log');
35
-
36
- // ---------------------------------------------------------------------------
37
- // Pure helpers
38
- // ---------------------------------------------------------------------------
39
-
40
- function buildDropColumnSql(table) {
41
- if (!table || typeof table !== 'string') {
42
- throw new Error('buildDropColumnSql: table is required');
43
- }
44
- // ClickHouse ALTER TABLE DROP COLUMN is implemented as a mutation on the
45
- // affected parts. Destructive and irreversible without a backup.
46
- return `ALTER TABLE ${table} DROP COLUMN IF EXISTS site_id`;
47
- }
48
-
49
- function buildRowCountSql(table) {
50
- return `SELECT count() AS c FROM ${table}`;
51
- }
52
-
53
- function parseArgs(argv) {
54
- const args = { apply: false, help: false, noConfirm: false };
55
- for (let i = 2; i < argv.length; i++) {
56
- const a = argv[i];
57
- if (a === '--apply') args.apply = true;
58
- else if (a === '--no-confirm') args.noConfirm = true;
59
- else if (a === '--help' || a === '-h') args.help = true;
60
- }
61
- return args;
62
- }
63
-
64
- function printHelp(out) {
65
- const log = out || console.log;
66
- log(
67
- [
68
- '',
69
- 'Usage: node scripts/tenant-pivot-phase-3-cleanup.mjs [--apply] [--no-confirm]',
70
- '',
71
- ' (default) DRY-RUN. Prints SQL + row counts. Touches nothing.',
72
- ' --apply Actually execute ALTER TABLE DROP COLUMN. Requires',
73
- ' an interactive `yes` confirmation from a human operator.',
74
- ' --no-confirm Skip the readline prompt (still requires --apply). For',
75
- ' automated test harnesses only — do NOT use in prod.',
76
- '',
77
- '⚠ This is a DESTRUCTIVE migration. Take a ClickHouse backup first.',
78
- '',
79
- ].join('\n'),
80
- );
81
- }
82
-
83
- // Real ClickHouse HTTP client — unit tests inject a stub via the runCli
84
- // `queryFn` parameter so this is never actually invoked under jest.
85
- async function clickhouseQuery(query, params = {}) {
86
- const CLICKHOUSE_URL = process.env.CLICKHOUSE_URL || 'http://localhost:8123';
87
- const CLICKHOUSE_DB = process.env.CLICKHOUSE_DATABASE || 'gurulu';
88
- const url = new URL(CLICKHOUSE_URL);
89
- url.searchParams.set('database', CLICKHOUSE_DB);
90
- url.searchParams.set('default_format', 'JSON');
91
- for (const [k, v] of Object.entries(params)) {
92
- url.searchParams.set(`param_${k}`, String(v));
93
- }
94
- const res = await fetch(url.toString(), {
95
- method: 'POST',
96
- body: query,
97
- headers: { 'Content-Type': 'text/plain' },
98
- });
99
- if (!res.ok) {
100
- throw new Error(`ClickHouse error ${res.status}: ${await res.text()}`);
101
- }
102
- return res.json();
103
- }
104
-
105
- async function safeRowCount(table, queryFn) {
106
- const fn = queryFn || clickhouseQuery;
107
- try {
108
- const res = await fn(buildRowCountSql(table));
109
- const row = (res && res.data && res.data[0]) || {};
110
- return Number(row.c != null ? row.c : (row.count != null ? row.count : 0));
111
- } catch (_err) {
112
- return null;
113
- }
114
- }
115
-
116
- async function buildPlan(queryFn) {
117
- const plan = [];
118
- for (const table of AFFECTED_TABLES) {
119
- const rowCount = await safeRowCount(table, queryFn);
120
- plan.push({ table, rowCount, sql: buildDropColumnSql(table) });
121
- }
122
- return plan;
123
- }
124
-
125
- function renderPlan(plan, mode) {
126
- const lines = [];
127
- lines.push(`# tenant-pivot-phase-3-cleanup mode=${mode} ts=${new Date().toISOString()}`);
128
- lines.push('');
129
- lines.push('Affected tables:');
130
- for (const step of plan) {
131
- const rc =
132
- step.rowCount === null || step.rowCount === undefined
133
- ? '(unknown)'
134
- : Number(step.rowCount).toLocaleString();
135
- lines.push(` • ${step.table} rows=${rc}`);
136
- lines.push(` ${step.sql}`);
137
- }
138
- lines.push('');
139
- return lines.join('\n');
140
- }
141
-
142
- async function appendLog(block, logPath) {
143
- const target = logPath || LOG_PATH_DEFAULT;
144
- await fs.mkdir(path.dirname(target), { recursive: true });
145
- await fs.appendFile(target, block + '\n', 'utf8');
146
- }
147
-
148
- // Interactive confirmation prompt. Defaults to a real readline interface;
149
- // tests inject `promptFn` to avoid touching stdin.
150
- async function confirmDestructive(promptFn) {
151
- const ask =
152
- promptFn ||
153
- function defaultAsk(q) {
154
- return new Promise((resolve) => {
155
- const rl = readline.createInterface({
156
- input: process.stdin,
157
- output: process.stdout,
158
- });
159
- rl.question(q, (ans) => {
160
- rl.close();
161
- resolve(ans);
162
- });
163
- });
164
- };
165
- const answer = await ask(
166
- '\n⚠ About to DROP COLUMN site_id from production analytics tables. Type "yes" to proceed: ',
167
- );
168
- return String(answer || '').trim().toLowerCase() === 'yes';
169
- }
170
-
171
- // ---------------------------------------------------------------------------
172
- // CLI orchestrator
173
- // ---------------------------------------------------------------------------
174
-
175
- async function runCli(opts) {
176
- const o = opts || {};
177
- const argv = o.argv || process.argv;
178
- const queryFn = o.queryFn || clickhouseQuery;
179
- const promptFn = o.promptFn;
180
- const log = o.log || console.log;
181
- const errorLog = o.errorLog || console.error;
182
- const logPath = o.logPath || LOG_PATH_DEFAULT;
183
-
184
- const args = parseArgs(argv);
185
- if (args.help) {
186
- printHelp(log);
187
- return { ok: true, mode: 'help' };
188
- }
189
-
190
- const mode = args.apply ? 'APPLY' : 'DRY-RUN';
191
- log(`[phase-3-cleanup] mode=${mode}`);
192
- log('[phase-3-cleanup] ⚠ This script is destructive. See the README header.');
193
-
194
- const plan = await buildPlan(queryFn);
195
- const rendered = renderPlan(plan, mode);
196
- log(rendered);
197
- try {
198
- await appendLog(rendered, logPath);
199
- } catch (err) {
200
- errorLog('[phase-3-cleanup] WARNING: failed to write migration log:', err);
201
- }
202
-
203
- if (!args.apply) {
204
- log('[phase-3-cleanup] dry-run complete. Re-run with --apply to actually drop columns.');
205
- return { ok: true, mode: 'dry-run', plan };
206
- }
207
-
208
- // --apply path: require either an interactive `yes` or the explicit
209
- // --no-confirm test-only flag.
210
- if (!args.noConfirm) {
211
- const confirmed = await confirmDestructive(promptFn);
212
- if (!confirmed) {
213
- errorLog('[phase-3-cleanup] confirmation declined; nothing was changed.');
214
- return { ok: false, mode: 'apply', reason: 'declined' };
215
- }
216
- } else {
217
- log('[phase-3-cleanup] --no-confirm set: skipping interactive prompt (test mode).');
218
- }
219
-
220
- const executed = [];
221
- for (const step of plan) {
222
- log(`[phase-3-cleanup] APPLY ${step.table}`);
223
- log(` ${step.sql}`);
224
- try {
225
- await queryFn(step.sql);
226
- executed.push(Object.assign({}, step, { status: 'ok' }));
227
- } catch (err) {
228
- errorLog(`[phase-3-cleanup] FAILED on ${step.table}:`, err);
229
- executed.push(Object.assign({}, step, { status: 'error', error: String(err) }));
230
- break;
231
- }
232
- }
233
-
234
- await appendLog(
235
- `# applied ts=${new Date().toISOString()}\n` +
236
- executed.map((s) => ` ${s.status} ${s.table} :: ${s.sql}`).join('\n') +
237
- '\n',
238
- logPath,
239
- );
240
-
241
- return { ok: executed.every((s) => s.status === 'ok'), mode: 'apply', executed };
242
- }
243
-
244
- module.exports = {
245
- AFFECTED_TABLES,
246
- LOG_PATH_DEFAULT,
247
- buildDropColumnSql,
248
- buildRowCountSql,
249
- parseArgs,
250
- printHelp,
251
- clickhouseQuery,
252
- safeRowCount,
253
- buildPlan,
254
- renderPlan,
255
- appendLog,
256
- confirmDestructive,
257
- runCli,
258
- };
@@ -1,98 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * ============================================================================
4
- * README — DO NOT RUN AUTOMATICALLY. EVER.
5
- * ============================================================================
6
- *
7
- * Phase 18 A4 — Tenant pivot phase 3 cleanup script.
8
- *
9
- * This is a DESTRUCTIVE migration tool. It exists so an operator can, when
10
- * they are ready, drop the obsolete `site_id` column from the ClickHouse
11
- * analytics tables now that the tenant-first read path (Phase 18 A4) and
12
- * the tenant-first write path (Phase 17 B1) are both in production.
13
- *
14
- * ⚠ This script must NEVER be invoked by CI, pre-commit, deploy hooks,
15
- * ⚠ cron, AI agents, or anything other than a human operator who has
16
- * ⚠ taken a verified ClickHouse backup and read PHASE-18-ROADMAP.md §A4.
17
- *
18
- * Default behaviour (no flags) is a SAFE DRY-RUN: it prints exactly the
19
- * ALTER TABLE statements it would execute, fetches a current row count for
20
- * every affected table, and writes a markdown-friendly migration log to
21
- * `logs/tenant-pivot-phase-3.log`. It does NOT touch ClickHouse beyond the
22
- * read-only `SELECT count()` queries.
23
- *
24
- * Passing `--apply` is the only way to actually run the destructive ALTER
25
- * TABLE DROP COLUMN statements. The `--apply` path additionally requires an
26
- * interactive `yes` typed at a confirmation prompt so an operator cannot
27
- * fat-finger it from shell history.
28
- *
29
- * Affected tables (every analytics table that still carries `site_id` after
30
- * Phase 18 A4 — see docker/clickhouse/init/01_schema.sql for the canonical
31
- * list):
32
- *
33
- * • events_raw — primary fact table
34
- * • flow_session_events — per-session ordered event tape
35
- * • journey_events — cross-property event timeline (Phase 13)
36
- * • cross_property_journeys — aggregated journey rollup (Phase 13)
37
- * • inferred_events — server-derived event sink
38
- *
39
- * Usage:
40
- *
41
- * node scripts/tenant-pivot-phase-3-cleanup.mjs # dry-run (default)
42
- * node scripts/tenant-pivot-phase-3-cleanup.mjs --apply # interactive destructive run
43
- * node scripts/tenant-pivot-phase-3-cleanup.mjs --apply --no-confirm # test harness only
44
- *
45
- * Env:
46
- * CLICKHOUSE_URL (default http://localhost:8123)
47
- * CLICKHOUSE_DATABASE (default gurulu)
48
- *
49
- * The detection / orchestration logic lives in
50
- * `scripts/tenant-pivot-phase-3-cleanup.lib.cjs` so it can be reused by the
51
- * ts-jest test suite via `require()`. This wrapper exposes the same API as
52
- * an ESM module and, when invoked directly, runs the CLI.
53
- *
54
- * IMPORTANT: Do not modify this script to auto-run. Do not add it to any
55
- * workflow. The whole point of the human-in-the-loop confirmation is to
56
- * guarantee an operator chose to drop the column.
57
- * ============================================================================
58
- */
59
-
60
- import { createRequire } from 'node:module';
61
- import { fileURLToPath } from 'node:url';
62
-
63
- const require = createRequire(import.meta.url);
64
- const lib = require('./tenant-pivot-phase-3-cleanup.lib.cjs');
65
-
66
- export const AFFECTED_TABLES = lib.AFFECTED_TABLES;
67
- export const buildDropColumnSql = lib.buildDropColumnSql;
68
- export const buildRowCountSql = lib.buildRowCountSql;
69
- export const parseArgs = lib.parseArgs;
70
- export const printHelp = lib.printHelp;
71
- export const safeRowCount = lib.safeRowCount;
72
- export const buildPlan = lib.buildPlan;
73
- export const renderPlan = lib.renderPlan;
74
- export const appendLog = lib.appendLog;
75
- export const confirmDestructive = lib.confirmDestructive;
76
- export const runCli = lib.runCli;
77
-
78
- // CLI entry — only auto-runs when invoked directly via `node ...mjs`, not
79
- // when imported by another module.
80
- const isMain = (() => {
81
- try {
82
- return fileURLToPath(import.meta.url) === process.argv[1];
83
- } catch {
84
- return false;
85
- }
86
- })();
87
-
88
- if (isMain) {
89
- lib.runCli().then(
90
- (r) => {
91
- if (!r.ok) process.exitCode = 1;
92
- },
93
- (err) => {
94
- console.error('[phase-3-cleanup] fatal:', err);
95
- process.exitCode = 1;
96
- },
97
- );
98
- }