@notedge/panduck 0.0.0 → 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/bin/{panduck.mjs → panduck} +11 -11
- package/locales/en-US/cli.json +46 -46
- package/locales/locales.json +7 -7
- package/locales/zh-CN/cli.json +46 -46
- package/package.json +30 -34
- package/readme.md +89 -5
- package/src/cli/cli.ts +28 -28
- package/src/cli/commands/check-cmd.ts +174 -174
- package/src/cli/commands/convert-cmd.ts +300 -300
- package/src/cli/commands/doctor-cmd.ts +84 -84
- package/src/cli/commands/formats-cmd.ts +50 -50
- package/src/cli/commands/inspect-cmd.ts +231 -231
- package/src/cli/commands/plan-cmd.ts +188 -188
- package/src/cli/console-backend.ts +16 -16
- package/src/cli/context.ts +98 -98
- package/src/cli/diagnostics.ts +24 -24
- package/src/cli/exit-codes.ts +14 -14
- package/src/cli/format-registry.ts +170 -170
- package/src/cli/index.ts +7 -7
- package/src/cli/main.ts +10 -10
- package/src/cli/options.ts +127 -127
- package/src/cli/paths.ts +57 -56
- package/src/cli/pipeline.ts +225 -225
- package/src/cli/report.ts +110 -110
- package/src/index.ts +8 -8
- package/src/node/index.ts +14 -14
- package/src/node/load.ts +120 -120
- package/src/types.ts +49 -49
- package/src/wasm/index.ts +14 -2
- package/src/wasm/load.ts +25 -23
- package/src/wasm/panduck_wasm.d.ts +0 -6
|
@@ -1,174 +1,174 @@
|
|
|
1
|
-
import type { Cli, ParsedOptions } from "@vmz/commander";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
assertReadableInput,
|
|
5
|
-
buildBlockedReport,
|
|
6
|
-
createContext,
|
|
7
|
-
resolveFormats,
|
|
8
|
-
} from "../context.js";
|
|
9
|
-
import { emitReport } from "../diagnostics.js";
|
|
10
|
-
import { ExitCode } from "../exit-codes.js";
|
|
11
|
-
import { findFormat } from "../format-registry.js";
|
|
12
|
-
import { CliOptionError, readSharedOptions, readString } from "../options.js";
|
|
13
|
-
import { createReport } from "../report.js";
|
|
14
|
-
import { configureConsoleBackend } from "../console-backend.js";
|
|
15
|
-
import {
|
|
16
|
-
emitPipelineResult,
|
|
17
|
-
hasPipeline,
|
|
18
|
-
inferCheckTarget,
|
|
19
|
-
runCheckPipeline,
|
|
20
|
-
} from "../pipeline.js";
|
|
21
|
-
|
|
22
|
-
export function registerCheckCommand(cli: Cli): void {
|
|
23
|
-
cli.command("check", "cli.cmd.check")
|
|
24
|
-
.option("--from <format>", "cli.opt.from")
|
|
25
|
-
.option("--format <format>", "cli.opt.to")
|
|
26
|
-
.option("--strict", "cli.opt.strict")
|
|
27
|
-
.option("--loss <policy>", "cli.opt.loss")
|
|
28
|
-
.option("--diagnostics <mode>", "cli.opt.diagnostics")
|
|
29
|
-
.option("--budget <limit>", "cli.opt.budget")
|
|
30
|
-
.option("--json", "cli.opt.json")
|
|
31
|
-
.action((options: ParsedOptions) => runCheck(options));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async function runCheck(options: ParsedOptions): Promise<number> {
|
|
35
|
-
try {
|
|
36
|
-
const shared = readSharedOptions(options);
|
|
37
|
-
const inputPath = options._[0] ?? readString(options, "input");
|
|
38
|
-
const outputFormat = readString(options, "format");
|
|
39
|
-
if (!inputPath) {
|
|
40
|
-
return ExitCode.InvalidArgs;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const ctx = createContext();
|
|
44
|
-
configureConsoleBackend(ctx.bindings, shared.logFile);
|
|
45
|
-
const resolved = resolveFormats(inputPath, undefined, {
|
|
46
|
-
...shared,
|
|
47
|
-
to: outputFormat ?? shared.to,
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
if (resolved.ambiguous) {
|
|
51
|
-
const report = buildBlockedReport(
|
|
52
|
-
ctx,
|
|
53
|
-
"check",
|
|
54
|
-
inputPath,
|
|
55
|
-
resolved,
|
|
56
|
-
"ambiguous input format",
|
|
57
|
-
ExitCode.InputUnsupported,
|
|
58
|
-
shared,
|
|
59
|
-
);
|
|
60
|
-
emitReport(report, shared.diagnostics, shared.json);
|
|
61
|
-
return ExitCode.InputUnsupported;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
try {
|
|
65
|
-
await assertReadableInput(inputPath);
|
|
66
|
-
} catch {
|
|
67
|
-
const report = buildBlockedReport(
|
|
68
|
-
ctx,
|
|
69
|
-
"check",
|
|
70
|
-
inputPath,
|
|
71
|
-
resolved,
|
|
72
|
-
"input is not readable",
|
|
73
|
-
ExitCode.InputUnsupported,
|
|
74
|
-
shared,
|
|
75
|
-
);
|
|
76
|
-
emitReport(report, shared.diagnostics, shared.json);
|
|
77
|
-
return ExitCode.InputUnsupported;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const source = resolved.from ? findFormat(ctx.registry, resolved.from) : undefined;
|
|
81
|
-
let targetFormat = resolved.to;
|
|
82
|
-
if (!targetFormat && resolved.from && ctx.bindings) {
|
|
83
|
-
targetFormat = inferCheckTarget(ctx.bindings, resolved.from);
|
|
84
|
-
}
|
|
85
|
-
const target = targetFormat ? findFormat(ctx.registry, targetFormat) : undefined;
|
|
86
|
-
const checkResolved = { ...resolved, to: targetFormat };
|
|
87
|
-
|
|
88
|
-
if (!targetFormat) {
|
|
89
|
-
const report = buildBlockedReport(
|
|
90
|
-
ctx,
|
|
91
|
-
"check",
|
|
92
|
-
inputPath,
|
|
93
|
-
checkResolved,
|
|
94
|
-
"target format is required for check",
|
|
95
|
-
ExitCode.InvalidArgs,
|
|
96
|
-
shared,
|
|
97
|
-
);
|
|
98
|
-
emitReport(report, shared.diagnostics, shared.json);
|
|
99
|
-
return ExitCode.InvalidArgs;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const routeReady = hasPipeline(ctx.bindings, resolved.from, targetFormat);
|
|
103
|
-
|
|
104
|
-
if (routeReady && ctx.bindings) {
|
|
105
|
-
try {
|
|
106
|
-
const result = await runCheckPipeline({
|
|
107
|
-
ctx,
|
|
108
|
-
bindings: ctx.bindings,
|
|
109
|
-
inputPath,
|
|
110
|
-
resolved: checkResolved,
|
|
111
|
-
shared,
|
|
112
|
-
});
|
|
113
|
-
return emitPipelineResult(result, shared);
|
|
114
|
-
} catch (error) {
|
|
115
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
116
|
-
const report = buildBlockedReport(
|
|
117
|
-
ctx,
|
|
118
|
-
"check",
|
|
119
|
-
inputPath,
|
|
120
|
-
checkResolved,
|
|
121
|
-
message,
|
|
122
|
-
ExitCode.IrOrWriterFailure,
|
|
123
|
-
shared,
|
|
124
|
-
);
|
|
125
|
-
emitReport(report, shared.diagnostics, shared.json);
|
|
126
|
-
return ExitCode.IrOrWriterFailure;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const report = createReport({
|
|
131
|
-
operation: "check",
|
|
132
|
-
toolVersion: ctx.toolVersion,
|
|
133
|
-
status: "partial",
|
|
134
|
-
inputs: [{ path: inputPath, format: resolved.from }],
|
|
135
|
-
detection: { format: resolved.from, confidence: resolved.from ? "hint" : undefined, hints: resolved.hints },
|
|
136
|
-
pipeline: {
|
|
137
|
-
reader: source?.format,
|
|
138
|
-
writer: target?.format,
|
|
139
|
-
stages: ["validate"],
|
|
140
|
-
blocked_reason: routeReady
|
|
141
|
-
? "native bindings are unavailable"
|
|
142
|
-
: "conversion route is not wired yet",
|
|
143
|
-
},
|
|
144
|
-
coverage: source?.coverage ?? target?.coverage,
|
|
145
|
-
diagnostics: [
|
|
146
|
-
{
|
|
147
|
-
owner: "panduck",
|
|
148
|
-
severity: "warning",
|
|
149
|
-
message: routeReady
|
|
150
|
-
? "check requires native bindings for wired routes"
|
|
151
|
-
: "check currently validates readability and registry presence only",
|
|
152
|
-
code: "panduck.check.partial",
|
|
153
|
-
},
|
|
154
|
-
],
|
|
155
|
-
budgets: shared.budgets,
|
|
156
|
-
determinism: { profile: shared.profile ?? "default", config: shared.config ?? null },
|
|
157
|
-
statusPolicy: {
|
|
158
|
-
loss: shared.loss,
|
|
159
|
-
strict: shared.strict,
|
|
160
|
-
exit_code: shared.strict ? ExitCode.LossPolicyViolation : ExitCode.Success,
|
|
161
|
-
},
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
emitReport(report, shared.diagnostics, shared.json);
|
|
165
|
-
return shared.strict ? ExitCode.LossPolicyViolation : ExitCode.Success;
|
|
166
|
-
} catch (error) {
|
|
167
|
-
if (error instanceof CliOptionError) {
|
|
168
|
-
console.error(error.message);
|
|
169
|
-
return error.exitCode;
|
|
170
|
-
}
|
|
171
|
-
console.error(error instanceof Error ? error.message : String(error));
|
|
172
|
-
return ExitCode.InvalidArgs;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
1
|
+
import type { Cli, ParsedOptions } from "@vmz/commander";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
assertReadableInput,
|
|
5
|
+
buildBlockedReport,
|
|
6
|
+
createContext,
|
|
7
|
+
resolveFormats,
|
|
8
|
+
} from "../context.js";
|
|
9
|
+
import { emitReport } from "../diagnostics.js";
|
|
10
|
+
import { ExitCode } from "../exit-codes.js";
|
|
11
|
+
import { findFormat } from "../format-registry.js";
|
|
12
|
+
import { CliOptionError, readSharedOptions, readString } from "../options.js";
|
|
13
|
+
import { createReport } from "../report.js";
|
|
14
|
+
import { configureConsoleBackend } from "../console-backend.js";
|
|
15
|
+
import {
|
|
16
|
+
emitPipelineResult,
|
|
17
|
+
hasPipeline,
|
|
18
|
+
inferCheckTarget,
|
|
19
|
+
runCheckPipeline,
|
|
20
|
+
} from "../pipeline.js";
|
|
21
|
+
|
|
22
|
+
export function registerCheckCommand(cli: Cli): void {
|
|
23
|
+
cli.command("check", "cli.cmd.check")
|
|
24
|
+
.option("--from <format>", "cli.opt.from")
|
|
25
|
+
.option("--format <format>", "cli.opt.to")
|
|
26
|
+
.option("--strict", "cli.opt.strict")
|
|
27
|
+
.option("--loss <policy>", "cli.opt.loss")
|
|
28
|
+
.option("--diagnostics <mode>", "cli.opt.diagnostics")
|
|
29
|
+
.option("--budget <limit>", "cli.opt.budget")
|
|
30
|
+
.option("--json", "cli.opt.json")
|
|
31
|
+
.action((options: ParsedOptions) => runCheck(options));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function runCheck(options: ParsedOptions): Promise<number> {
|
|
35
|
+
try {
|
|
36
|
+
const shared = readSharedOptions(options);
|
|
37
|
+
const inputPath = options._[0] ?? readString(options, "input");
|
|
38
|
+
const outputFormat = readString(options, "format");
|
|
39
|
+
if (!inputPath) {
|
|
40
|
+
return ExitCode.InvalidArgs;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const ctx = createContext();
|
|
44
|
+
configureConsoleBackend(ctx.bindings, shared.logFile);
|
|
45
|
+
const resolved = resolveFormats(inputPath, undefined, {
|
|
46
|
+
...shared,
|
|
47
|
+
to: outputFormat ?? shared.to,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
if (resolved.ambiguous) {
|
|
51
|
+
const report = buildBlockedReport(
|
|
52
|
+
ctx,
|
|
53
|
+
"check",
|
|
54
|
+
inputPath,
|
|
55
|
+
resolved,
|
|
56
|
+
"ambiguous input format",
|
|
57
|
+
ExitCode.InputUnsupported,
|
|
58
|
+
shared,
|
|
59
|
+
);
|
|
60
|
+
emitReport(report, shared.diagnostics, shared.json);
|
|
61
|
+
return ExitCode.InputUnsupported;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
await assertReadableInput(inputPath);
|
|
66
|
+
} catch {
|
|
67
|
+
const report = buildBlockedReport(
|
|
68
|
+
ctx,
|
|
69
|
+
"check",
|
|
70
|
+
inputPath,
|
|
71
|
+
resolved,
|
|
72
|
+
"input is not readable",
|
|
73
|
+
ExitCode.InputUnsupported,
|
|
74
|
+
shared,
|
|
75
|
+
);
|
|
76
|
+
emitReport(report, shared.diagnostics, shared.json);
|
|
77
|
+
return ExitCode.InputUnsupported;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const source = resolved.from ? findFormat(ctx.registry, resolved.from) : undefined;
|
|
81
|
+
let targetFormat = resolved.to;
|
|
82
|
+
if (!targetFormat && resolved.from && ctx.bindings) {
|
|
83
|
+
targetFormat = inferCheckTarget(ctx.bindings, resolved.from);
|
|
84
|
+
}
|
|
85
|
+
const target = targetFormat ? findFormat(ctx.registry, targetFormat) : undefined;
|
|
86
|
+
const checkResolved = { ...resolved, to: targetFormat };
|
|
87
|
+
|
|
88
|
+
if (!targetFormat) {
|
|
89
|
+
const report = buildBlockedReport(
|
|
90
|
+
ctx,
|
|
91
|
+
"check",
|
|
92
|
+
inputPath,
|
|
93
|
+
checkResolved,
|
|
94
|
+
"target format is required for check",
|
|
95
|
+
ExitCode.InvalidArgs,
|
|
96
|
+
shared,
|
|
97
|
+
);
|
|
98
|
+
emitReport(report, shared.diagnostics, shared.json);
|
|
99
|
+
return ExitCode.InvalidArgs;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const routeReady = hasPipeline(ctx.bindings, resolved.from, targetFormat);
|
|
103
|
+
|
|
104
|
+
if (routeReady && ctx.bindings) {
|
|
105
|
+
try {
|
|
106
|
+
const result = await runCheckPipeline({
|
|
107
|
+
ctx,
|
|
108
|
+
bindings: ctx.bindings,
|
|
109
|
+
inputPath,
|
|
110
|
+
resolved: checkResolved,
|
|
111
|
+
shared,
|
|
112
|
+
});
|
|
113
|
+
return emitPipelineResult(result, shared);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
116
|
+
const report = buildBlockedReport(
|
|
117
|
+
ctx,
|
|
118
|
+
"check",
|
|
119
|
+
inputPath,
|
|
120
|
+
checkResolved,
|
|
121
|
+
message,
|
|
122
|
+
ExitCode.IrOrWriterFailure,
|
|
123
|
+
shared,
|
|
124
|
+
);
|
|
125
|
+
emitReport(report, shared.diagnostics, shared.json);
|
|
126
|
+
return ExitCode.IrOrWriterFailure;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const report = createReport({
|
|
131
|
+
operation: "check",
|
|
132
|
+
toolVersion: ctx.toolVersion,
|
|
133
|
+
status: "partial",
|
|
134
|
+
inputs: [{ path: inputPath, format: resolved.from }],
|
|
135
|
+
detection: { format: resolved.from, confidence: resolved.from ? "hint" : undefined, hints: resolved.hints },
|
|
136
|
+
pipeline: {
|
|
137
|
+
reader: source?.format,
|
|
138
|
+
writer: target?.format,
|
|
139
|
+
stages: ["validate"],
|
|
140
|
+
blocked_reason: routeReady
|
|
141
|
+
? "native bindings are unavailable"
|
|
142
|
+
: "conversion route is not wired yet",
|
|
143
|
+
},
|
|
144
|
+
coverage: source?.coverage ?? target?.coverage,
|
|
145
|
+
diagnostics: [
|
|
146
|
+
{
|
|
147
|
+
owner: "panduck",
|
|
148
|
+
severity: "warning",
|
|
149
|
+
message: routeReady
|
|
150
|
+
? "check requires native bindings for wired routes"
|
|
151
|
+
: "check currently validates readability and registry presence only",
|
|
152
|
+
code: "panduck.check.partial",
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
budgets: shared.budgets,
|
|
156
|
+
determinism: { profile: shared.profile ?? "default", config: shared.config ?? null },
|
|
157
|
+
statusPolicy: {
|
|
158
|
+
loss: shared.loss,
|
|
159
|
+
strict: shared.strict,
|
|
160
|
+
exit_code: shared.strict ? ExitCode.LossPolicyViolation : ExitCode.Success,
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
emitReport(report, shared.diagnostics, shared.json);
|
|
165
|
+
return shared.strict ? ExitCode.LossPolicyViolation : ExitCode.Success;
|
|
166
|
+
} catch (error) {
|
|
167
|
+
if (error instanceof CliOptionError) {
|
|
168
|
+
console.error(error.message);
|
|
169
|
+
return error.exitCode;
|
|
170
|
+
}
|
|
171
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
172
|
+
return ExitCode.InvalidArgs;
|
|
173
|
+
}
|
|
174
|
+
}
|