@longzai-intelligence-issues/cli 0.0.1 → 0.0.2
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/.turbo/turbo-build.log +7 -0
- package/.turbo/turbo-lint.log +7 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/CHANGELOG.md +21 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/main.d.ts +4 -0
- package/dist/main.js +2 -0
- package/lzi-builder.config.ts +6 -2
- package/package.json +14 -17
- package/src/__tests__/commands.known-flags.test.ts +243 -0
- package/src/commands/close.commands.ts +175 -32
- package/src/commands/context.utils.ts +13 -3
- package/src/commands/gate.commands.ts +257 -44
- package/src/commands/index.ts +3 -0
- package/src/commands/issue.commands.ts +102 -38
- package/src/commands/migrate.commands.ts +113 -0
- package/src/commands/scaffold.commands.ts +57 -17
- package/src/main.ts +19 -0
- package/tsconfig/.cache/build.tsbuildinfo +1 -1
- package/tsconfig/.cache/node.tsbuildinfo +1 -1
- package/tsconfig/.cache/test.tsbuildinfo +1 -1
|
@@ -18,11 +18,11 @@ import * as z from 'zod';
|
|
|
18
18
|
import { fail, info, loadConfigOrExit, ok, repoRoot, violation } from './context.utils.js';
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
21
|
+
* 注册表 lint 门禁命令(12 核心规则 + 棘轮基线三态)
|
|
22
22
|
*
|
|
23
|
-
*
|
|
23
|
+
* @param program - CLI 程序实例
|
|
24
24
|
*/
|
|
25
|
-
|
|
25
|
+
function registerLintCommand(program: Command): void {
|
|
26
26
|
defineCommand(program, {
|
|
27
27
|
name: 'lint',
|
|
28
28
|
description: '注册表 lint(12 核心规则 + 棘轮基线三态)',
|
|
@@ -31,33 +31,51 @@ export function registerGateCommands(program: Command): void {
|
|
|
31
31
|
{ flags: '--strict-legacy', description: '旧格式状态行一并计违规' },
|
|
32
32
|
{ flags: '--write-baseline', description: '再生棘轮基线(须配 --issue)' },
|
|
33
33
|
{ flags: '--issue <issue>', description: '收编指针(write-baseline 必填)' },
|
|
34
|
+
{ flags: '--format <format>', description: 'text | json(json 为机器可读违规清单)' },
|
|
34
35
|
{ flags: '--config <path>', description: '显式配置路径' },
|
|
35
36
|
],
|
|
36
|
-
schema: z
|
|
37
|
-
.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
.passthrough(),
|
|
37
|
+
schema: z.looseObject({
|
|
38
|
+
dir: z.union([z.string(), z.array(z.string())]).optional(),
|
|
39
|
+
strictLegacy: z.boolean().optional(),
|
|
40
|
+
writeBaseline: z.boolean().optional(),
|
|
41
|
+
issue: z.string().optional(),
|
|
42
|
+
format: z.enum(['text', 'json']).optional(),
|
|
43
|
+
config: z.string().optional(),
|
|
44
|
+
}),
|
|
45
45
|
action: async (opts) => {
|
|
46
|
+
/**
|
|
47
|
+
* 仓库根
|
|
48
|
+
*/
|
|
46
49
|
const root = repoRoot();
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 解析后配置与命中路径
|
|
53
|
+
*/
|
|
47
54
|
const { config, configFilePath } = await loadConfigOrExit(opts.config);
|
|
48
55
|
|
|
49
56
|
/**
|
|
50
57
|
* 限定目录归一
|
|
51
58
|
*/
|
|
52
|
-
const dirRels =
|
|
59
|
+
const dirRels =
|
|
60
|
+
opts.dir === undefined ? undefined : Array.isArray(opts.dir) ? opts.dir : [opts.dir];
|
|
53
61
|
|
|
54
62
|
/**
|
|
55
63
|
* strictLegacy 覆盖(命令级旗标优先)
|
|
56
64
|
*/
|
|
57
|
-
const effective =
|
|
65
|
+
const effective =
|
|
66
|
+
opts.strictLegacy === true
|
|
67
|
+
? { ...config, lint: { ...config.lint, strictLegacy: true } }
|
|
68
|
+
: config;
|
|
58
69
|
|
|
59
70
|
if (opts.writeBaseline === true) {
|
|
60
|
-
|
|
71
|
+
/**
|
|
72
|
+
* 棘轮基线再生结果
|
|
73
|
+
*/
|
|
74
|
+
const regen = runWriteLintBaseline({
|
|
75
|
+
root,
|
|
76
|
+
config: effective,
|
|
77
|
+
issuePointer: opts.issue ?? '',
|
|
78
|
+
});
|
|
61
79
|
|
|
62
80
|
if (!regen.ok) {
|
|
63
81
|
fail(regen.error);
|
|
@@ -68,36 +86,73 @@ export function registerGateCommands(program: Command): void {
|
|
|
68
86
|
return;
|
|
69
87
|
}
|
|
70
88
|
|
|
89
|
+
/**
|
|
90
|
+
* lint 判定结果(active + stale 违规与基线计数)
|
|
91
|
+
*/
|
|
71
92
|
const result = runLint({ root, config: effective, dirRels });
|
|
72
93
|
|
|
73
|
-
|
|
74
|
-
|
|
94
|
+
if (opts.format === 'json') {
|
|
95
|
+
process.stdout.write(
|
|
96
|
+
`${JSON.stringify(
|
|
97
|
+
{
|
|
98
|
+
command: 'issues:lint',
|
|
99
|
+
ok: result.violations.length === 0,
|
|
100
|
+
violationCount: result.violations.length,
|
|
101
|
+
suppressed: result.suppressed,
|
|
102
|
+
baselineCount: result.baselineCount,
|
|
103
|
+
violations: result.violations,
|
|
104
|
+
},
|
|
105
|
+
null,
|
|
106
|
+
2,
|
|
107
|
+
)}\n`,
|
|
108
|
+
);
|
|
109
|
+
} else {
|
|
110
|
+
for (const v of result.violations) {
|
|
111
|
+
violation(`${v.file}:${v.line} [${v.rule}] ${v.message}`);
|
|
112
|
+
}
|
|
75
113
|
}
|
|
76
114
|
|
|
77
115
|
if (result.violations.length > 0) {
|
|
78
|
-
|
|
116
|
+
if (opts.format !== 'json') {
|
|
117
|
+
process.stderr.write(
|
|
118
|
+
`错误: issues:lint ${result.violations.length} 项违规|存量豁免 ${result.suppressed}|基线 ${result.baselineCount} 条\n`,
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
79
122
|
process.exit(1);
|
|
80
123
|
}
|
|
81
124
|
|
|
82
|
-
|
|
125
|
+
if (opts.format !== 'json') {
|
|
126
|
+
ok(
|
|
127
|
+
`issues:lint 通过(0 新增违规|存量豁免 ${result.suppressed}|基线 ${result.baselineCount} 条)`,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
83
130
|
},
|
|
84
131
|
});
|
|
132
|
+
}
|
|
85
133
|
|
|
134
|
+
/**
|
|
135
|
+
* 编号门禁命令组(父命令 numbering + next / check / audit 三子命令)
|
|
136
|
+
*
|
|
137
|
+
* @param program - CLI 程序实例
|
|
138
|
+
*/
|
|
139
|
+
function registerNumberingCommands(program: Command): void {
|
|
86
140
|
/**
|
|
87
|
-
* numbering
|
|
141
|
+
* numbering 三子命令共用 schema
|
|
88
142
|
*/
|
|
89
|
-
const numberingSchema = z
|
|
90
|
-
.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
.passthrough();
|
|
143
|
+
const numberingSchema = z.looseObject({
|
|
144
|
+
scope: z.string().optional(),
|
|
145
|
+
dir: z.string().optional(),
|
|
146
|
+
format: z.enum(['text', 'json']).optional(),
|
|
147
|
+
config: z.string().optional(),
|
|
148
|
+
});
|
|
96
149
|
|
|
97
150
|
/**
|
|
98
151
|
* numbering 父命令(子命令 next/check/audit)
|
|
99
152
|
*/
|
|
100
|
-
const numbering = program
|
|
153
|
+
const numbering = program
|
|
154
|
+
.command('numbering')
|
|
155
|
+
.description('编号门禁(next 取号 / check 判定 / audit 覆盖面审计)');
|
|
101
156
|
|
|
102
157
|
defineCommand(numbering, {
|
|
103
158
|
name: 'next',
|
|
@@ -105,19 +160,37 @@ export function registerGateCommands(program: Command): void {
|
|
|
105
160
|
options: [
|
|
106
161
|
{ flags: '--scope <scope>', description: '目标 scope key' },
|
|
107
162
|
{ flags: '--dir <dir>', description: '目标注册表目录' },
|
|
163
|
+
{ flags: '--format <format>', description: 'text | json(json 为机器可读取号结果)' },
|
|
108
164
|
{ flags: '--config <path>', description: '显式配置路径' },
|
|
109
165
|
],
|
|
110
166
|
schema: numberingSchema,
|
|
111
167
|
action: async (opts) => {
|
|
168
|
+
/**
|
|
169
|
+
* 仓库根
|
|
170
|
+
*/
|
|
112
171
|
const root = repoRoot();
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* 解析后配置
|
|
175
|
+
*/
|
|
113
176
|
const { config } = await loadConfigOrExit(opts.config);
|
|
114
177
|
|
|
178
|
+
/**
|
|
179
|
+
* 取号结果(下一可用编号)
|
|
180
|
+
*/
|
|
115
181
|
const result = runNumberingNext({ root, config, scopeKey: opts.scope, dirRel: opts.dir });
|
|
116
182
|
|
|
117
183
|
if (!result.ok) {
|
|
118
184
|
fail(result.error);
|
|
119
185
|
}
|
|
120
186
|
|
|
187
|
+
if (opts.format === 'json') {
|
|
188
|
+
process.stdout.write(
|
|
189
|
+
`${JSON.stringify({ command: 'numbering:next', ok: true, target: result.target, number: result.number }, null, 2)}\n`,
|
|
190
|
+
);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
121
194
|
info(`${result.target} 下一可用编号:${result.number}(已跳过保留号与已占用号)`);
|
|
122
195
|
},
|
|
123
196
|
});
|
|
@@ -127,55 +200,130 @@ export function registerGateCommands(program: Command): void {
|
|
|
127
200
|
description: '编号门禁判定(缺省全量;--dir 目录增量)',
|
|
128
201
|
options: [
|
|
129
202
|
{ flags: '--dir <dir>', description: '目录增量档' },
|
|
203
|
+
{ flags: '--format <format>', description: 'text | json(json 为机器可读违例清单)' },
|
|
130
204
|
{ flags: '--config <path>', description: '显式配置路径' },
|
|
131
205
|
],
|
|
132
206
|
schema: numberingSchema,
|
|
133
207
|
action: async (opts) => {
|
|
208
|
+
/**
|
|
209
|
+
* 仓库根
|
|
210
|
+
*/
|
|
134
211
|
const root = repoRoot();
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* 解析后配置
|
|
215
|
+
*/
|
|
135
216
|
const { config } = await loadConfigOrExit(opts.config);
|
|
136
217
|
|
|
218
|
+
/**
|
|
219
|
+
* 编号门禁判定结果
|
|
220
|
+
*/
|
|
137
221
|
const result = runNumberingCheck({ root, config, dirRel: opts.dir });
|
|
138
222
|
|
|
139
|
-
|
|
140
|
-
|
|
223
|
+
if (opts.format === 'json') {
|
|
224
|
+
process.stdout.write(
|
|
225
|
+
`${JSON.stringify(
|
|
226
|
+
{
|
|
227
|
+
command: 'numbering:check',
|
|
228
|
+
ok: result.findings.length === 0,
|
|
229
|
+
scopeCount: result.scopeCount,
|
|
230
|
+
scannedFiles: result.scannedFiles,
|
|
231
|
+
findings: result.findings,
|
|
232
|
+
},
|
|
233
|
+
null,
|
|
234
|
+
2,
|
|
235
|
+
)}\n`,
|
|
236
|
+
);
|
|
237
|
+
} else {
|
|
238
|
+
for (const f of result.findings) {
|
|
239
|
+
violation(`[${f.kind}] ${f.message}`);
|
|
240
|
+
}
|
|
141
241
|
}
|
|
142
242
|
|
|
143
243
|
if (result.findings.length > 0) {
|
|
144
|
-
|
|
244
|
+
if (opts.format !== 'json') {
|
|
245
|
+
process.stderr.write(
|
|
246
|
+
`错误: numbering:check ${result.findings.length} 项违规(scope ${result.scopeCount} 个 / 扫描面 ${result.scannedFiles} 文件)\n`,
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
145
250
|
process.exit(1);
|
|
146
251
|
}
|
|
147
252
|
|
|
148
|
-
|
|
253
|
+
if (opts.format !== 'json') {
|
|
254
|
+
ok(
|
|
255
|
+
`numbering:check 通过(scope ${result.scopeCount} 个 / 扫描面 ${result.scannedFiles} 文件 / 零违规)`,
|
|
256
|
+
);
|
|
257
|
+
}
|
|
149
258
|
},
|
|
150
259
|
});
|
|
151
260
|
|
|
152
261
|
defineCommand(numbering, {
|
|
153
262
|
name: 'audit',
|
|
154
263
|
description: '覆盖面审计(未登记编号区 / pending 失效)',
|
|
155
|
-
options: [
|
|
264
|
+
options: [
|
|
265
|
+
{ flags: '--format <format>', description: 'text | json(json 为机器可读发现清单)' },
|
|
266
|
+
{ flags: '--config <path>', description: '显式配置路径' },
|
|
267
|
+
],
|
|
156
268
|
schema: numberingSchema,
|
|
157
269
|
action: async (opts) => {
|
|
270
|
+
/**
|
|
271
|
+
* 仓库根
|
|
272
|
+
*/
|
|
158
273
|
const root = repoRoot();
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* 解析后配置
|
|
277
|
+
*/
|
|
159
278
|
const { config } = await loadConfigOrExit(opts.config);
|
|
160
279
|
|
|
280
|
+
/**
|
|
281
|
+
* 覆盖面审计结果(未登记编号区 / pending 失效)
|
|
282
|
+
*/
|
|
161
283
|
const result = runNumberingAudit({ root, config });
|
|
162
284
|
|
|
163
|
-
|
|
164
|
-
|
|
285
|
+
if (opts.format === 'json') {
|
|
286
|
+
process.stdout.write(
|
|
287
|
+
`${JSON.stringify(
|
|
288
|
+
{
|
|
289
|
+
command: 'numbering:audit',
|
|
290
|
+
ok: result.findings.length === 0,
|
|
291
|
+
scannedFiles: result.scannedFiles,
|
|
292
|
+
findings: result.findings,
|
|
293
|
+
},
|
|
294
|
+
null,
|
|
295
|
+
2,
|
|
296
|
+
)}\n`,
|
|
297
|
+
);
|
|
298
|
+
} else {
|
|
299
|
+
for (const f of result.findings) {
|
|
300
|
+
violation(`[${f.kind}] ${f.message}`);
|
|
301
|
+
}
|
|
165
302
|
}
|
|
166
303
|
|
|
167
304
|
if (result.findings.length > 0) {
|
|
168
|
-
|
|
305
|
+
if (opts.format !== 'json') {
|
|
306
|
+
process.stderr.write(
|
|
307
|
+
`错误: numbering:audit ${result.findings.length} 项违规(扫描面 ${result.scannedFiles} 文件)\n`,
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
|
|
169
311
|
process.exit(1);
|
|
170
312
|
}
|
|
171
313
|
|
|
172
|
-
|
|
314
|
+
if (opts.format !== 'json') {
|
|
315
|
+
ok(`numbering:audit 通过(扫描面 ${result.scannedFiles} 文件 / 零未登记编号区)`);
|
|
316
|
+
}
|
|
173
317
|
},
|
|
174
318
|
});
|
|
319
|
+
}
|
|
175
320
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
321
|
+
/**
|
|
322
|
+
* 文档 issue 引用检查命令(父命令 docs + 子命令 check)
|
|
323
|
+
*
|
|
324
|
+
* @param program - CLI 程序实例
|
|
325
|
+
*/
|
|
326
|
+
function registerDocsCommand(program: Command): void {
|
|
179
327
|
/**
|
|
180
328
|
* docs 父命令(子命令 check / fix)
|
|
181
329
|
*/
|
|
@@ -189,13 +337,27 @@ export function registerGateCommands(program: Command): void {
|
|
|
189
337
|
{ flags: '--issue <issue>', description: '收编指针' },
|
|
190
338
|
{ flags: '--config <path>', description: '显式配置路径' },
|
|
191
339
|
],
|
|
192
|
-
schema: z.
|
|
340
|
+
schema: z.looseObject({
|
|
341
|
+
writeBaseline: z.boolean().optional(),
|
|
342
|
+
issue: z.string().optional(),
|
|
343
|
+
config: z.string().optional(),
|
|
344
|
+
}),
|
|
193
345
|
action: async (opts) => {
|
|
346
|
+
/**
|
|
347
|
+
* 仓库根
|
|
348
|
+
*/
|
|
194
349
|
const root = repoRoot();
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* 解析后配置与命中路径
|
|
353
|
+
*/
|
|
195
354
|
const { config, configFilePath } = await loadConfigOrExit(opts.config);
|
|
196
355
|
|
|
197
356
|
if (opts.writeBaseline === true) {
|
|
198
357
|
try {
|
|
358
|
+
/**
|
|
359
|
+
* docs 基线再生结果
|
|
360
|
+
*/
|
|
199
361
|
const regen = runWriteDocsBaseline({ root, config, issuePointer: opts.issue ?? '' });
|
|
200
362
|
|
|
201
363
|
if (!regen.ok) {
|
|
@@ -211,6 +373,9 @@ export function registerGateCommands(program: Command): void {
|
|
|
211
373
|
}
|
|
212
374
|
|
|
213
375
|
try {
|
|
376
|
+
/**
|
|
377
|
+
* docs 引用检查结果
|
|
378
|
+
*/
|
|
214
379
|
const result = runDocsCheck({ root, config });
|
|
215
380
|
|
|
216
381
|
for (const v of result.violations) {
|
|
@@ -218,7 +383,9 @@ export function registerGateCommands(program: Command): void {
|
|
|
218
383
|
}
|
|
219
384
|
|
|
220
385
|
if (result.violations.length > 0) {
|
|
221
|
-
process.stderr.write(
|
|
386
|
+
process.stderr.write(
|
|
387
|
+
`错误: docs:check ${result.violations.length} 项违规(扫描面 ${result.scannedFiles} 文件 / 豁免 ${result.suppressed})\n`,
|
|
388
|
+
);
|
|
222
389
|
process.exit(1);
|
|
223
390
|
}
|
|
224
391
|
|
|
@@ -228,32 +395,78 @@ export function registerGateCommands(program: Command): void {
|
|
|
228
395
|
}
|
|
229
396
|
},
|
|
230
397
|
});
|
|
398
|
+
}
|
|
231
399
|
|
|
400
|
+
/**
|
|
401
|
+
* 黄灯巡检命令(状态分布 / 最老账龄 / A-B-C 分类,JSON)
|
|
402
|
+
*
|
|
403
|
+
* @param program - CLI 程序实例
|
|
404
|
+
*/
|
|
405
|
+
function registerHealthCommand(program: Command): void {
|
|
232
406
|
defineCommand(program, {
|
|
233
407
|
name: 'health',
|
|
234
408
|
description: '黄灯巡检(状态分布 / 最老账龄 / A-B-C 分类,JSON)',
|
|
235
409
|
options: [{ flags: '--config <path>', description: '显式配置路径' }],
|
|
236
|
-
schema: z.
|
|
410
|
+
schema: z.looseObject({ config: z.string().optional() }),
|
|
237
411
|
action: async (opts) => {
|
|
412
|
+
/**
|
|
413
|
+
* 仓库根
|
|
414
|
+
*/
|
|
238
415
|
const root = repoRoot();
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* 解析后配置
|
|
419
|
+
*/
|
|
239
420
|
const { config } = await loadConfigOrExit(opts.config);
|
|
240
421
|
|
|
241
422
|
process.stdout.write(`${JSON.stringify(runHealth({ root, config }), null, 2)}\n`);
|
|
242
423
|
},
|
|
243
424
|
});
|
|
425
|
+
}
|
|
244
426
|
|
|
427
|
+
/**
|
|
428
|
+
* 黄灯分诊台账命令(append-only 落 .lzi/issues/runs/ledger/)
|
|
429
|
+
*
|
|
430
|
+
* @param program - CLI 程序实例
|
|
431
|
+
*/
|
|
432
|
+
function registerTriageCommand(program: Command): void {
|
|
245
433
|
defineCommand(program, {
|
|
246
434
|
name: 'triage',
|
|
247
435
|
description: '黄灯分诊台账(append-only 落 .lzi/issues/runs/ledger/)',
|
|
248
436
|
options: [{ flags: '--config <path>', description: '显式配置路径' }],
|
|
249
|
-
schema: z.
|
|
437
|
+
schema: z.looseObject({ config: z.string().optional() }),
|
|
250
438
|
action: async (opts) => {
|
|
439
|
+
/**
|
|
440
|
+
* 仓库根
|
|
441
|
+
*/
|
|
251
442
|
const root = repoRoot();
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* 解析后配置
|
|
446
|
+
*/
|
|
252
447
|
const { config } = await loadConfigOrExit(opts.config);
|
|
253
448
|
|
|
449
|
+
/**
|
|
450
|
+
* 分诊台账落盘结果(台账文件路径与黄灯条目集)
|
|
451
|
+
*/
|
|
254
452
|
const { ledgerPath, ledger } = runTriage({ root, config });
|
|
255
453
|
|
|
256
454
|
ok(`issues:triage 台账已落盘: ${ledgerPath}(黄灯 ${ledger.items.length} 项)`);
|
|
257
455
|
},
|
|
258
456
|
});
|
|
259
457
|
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* 门禁与观测命令组:lint / numbering / docs / health / triage
|
|
461
|
+
*
|
|
462
|
+
* 判据口径:exit 0 过 / exit 1 违规(报文逐条输出后退出)。
|
|
463
|
+
*
|
|
464
|
+
* @param program - CLI 程序实例
|
|
465
|
+
*/
|
|
466
|
+
export function registerGateCommands(program: Command): void {
|
|
467
|
+
registerLintCommand(program);
|
|
468
|
+
registerNumberingCommands(program);
|
|
469
|
+
registerDocsCommand(program);
|
|
470
|
+
registerHealthCommand(program);
|
|
471
|
+
registerTriageCommand(program);
|
|
472
|
+
}
|
package/src/commands/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { Command } from '@longzai-intelligence-cli/core';
|
|
|
11
11
|
import { registerCloseCommands } from './close.commands.js';
|
|
12
12
|
import { registerGateCommands } from './gate.commands.js';
|
|
13
13
|
import { registerIssueCommands } from './issue.commands.js';
|
|
14
|
+
import { registerMigrateCommands } from './migrate.commands.js';
|
|
14
15
|
import { registerScaffoldCommands } from './scaffold.commands.js';
|
|
15
16
|
|
|
16
17
|
/**
|
|
@@ -26,4 +27,6 @@ export function registerCommands(program: Command): void {
|
|
|
26
27
|
registerGateCommands(program);
|
|
27
28
|
|
|
28
29
|
registerCloseCommands(program);
|
|
30
|
+
|
|
31
|
+
registerMigrateCommands(program);
|
|
29
32
|
}
|