@moewolf/moe-icons-cli 0.0.1 → 0.0.3
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 +249 -10
- package/bin/check-node.cjs +36 -0
- package/bin/moeicons.js +12 -1
- package/dist/api/client.d.ts +13 -2
- package/dist/api/client.js +145 -21
- package/dist/auth/device-login.d.ts +10 -7
- package/dist/auth/device-login.js +60 -37
- package/dist/auth/login-schemas.d.ts +24 -0
- package/dist/auth/login-schemas.js +67 -0
- package/dist/catalog/catalog.d.ts +11 -0
- package/dist/catalog/catalog.js +43 -0
- package/dist/catalog/catalog.json +12768 -3965
- package/dist/cli.d.ts +11 -2
- package/dist/cli.js +773 -147
- package/dist/commands/parser.d.ts +13 -2
- package/dist/commands/parser.js +138 -50
- package/dist/config-package/generated/SOURCE.json +25 -0
- package/dist/config-package/generated/moeicons-config.schema.json +191 -0
- package/dist/config-package/generated/moeicons.config.jsonc +42 -0
- package/dist/config-package/generated/render-config.cjs +145 -0
- package/dist/config-package/generated/validate-config.cjs +293 -0
- package/dist/config-package/generated-config.d.ts +32 -0
- package/dist/config-package/generated-config.js +19 -0
- package/dist/core/auth.d.ts +24 -0
- package/dist/core/auth.js +127 -8
- package/dist/core/bitmap-assets.d.ts +19 -5
- package/dist/core/bitmap-assets.js +40 -31
- package/dist/core/bitmap-shard-budget.d.ts +43 -0
- package/dist/core/bitmap-shard-budget.js +16 -0
- package/dist/core/bitmap-shard-cache.d.ts +68 -0
- package/dist/core/bitmap-shard-cache.js +115 -0
- package/dist/core/bitmap-shard-download.d.ts +130 -0
- package/dist/core/bitmap-shard-download.js +359 -0
- package/dist/core/bitmap-shard-resolver.d.ts +129 -0
- package/dist/core/bitmap-shard-resolver.js +262 -0
- package/dist/core/bitmap-shards.d.ts +70 -0
- package/dist/core/bitmap-shards.js +249 -0
- package/dist/core/bootstrap.d.ts +37 -0
- package/dist/core/bootstrap.js +54 -0
- package/dist/core/cache.d.ts +34 -0
- package/dist/core/cache.js +96 -0
- package/dist/core/context.d.ts +26 -0
- package/dist/core/doctor.d.ts +48 -0
- package/dist/core/doctor.js +190 -0
- package/dist/core/free-download.d.ts +64 -6
- package/dist/core/free-download.js +402 -30
- package/dist/core/generate.d.ts +29 -0
- package/dist/core/generate.js +341 -65
- package/dist/core/icon-selection.d.ts +8 -0
- package/dist/core/icon-selection.js +19 -0
- package/dist/core/install.d.ts +14 -0
- package/dist/core/install.js +132 -13
- package/dist/core/library-update.d.ts +5 -1
- package/dist/core/library-update.js +176 -17
- package/dist/core/local-test-env.d.ts +24 -0
- package/dist/core/local-test-env.js +43 -0
- package/dist/core/metadata-sync.d.ts +30 -0
- package/dist/core/metadata-sync.js +97 -0
- package/dist/core/pro-download.d.ts +63 -0
- package/dist/core/pro-download.js +247 -27
- package/dist/core/pro-install.d.ts +11 -3
- package/dist/core/pro-install.js +181 -19
- package/dist/core/pro-resources.d.ts +79 -0
- package/dist/core/pro-resources.js +204 -0
- package/dist/core/pro-selected-download.d.ts +18 -0
- package/dist/core/pro-selected-download.js +269 -0
- package/dist/core/release-descriptor.d.ts +42 -1
- package/dist/core/release-descriptor.js +117 -9
- package/dist/core/resource-variant.d.ts +27 -10
- package/dist/core/resource-variant.js +75 -34
- package/dist/core/selected-resources.d.ts +59 -0
- package/dist/core/selected-resources.js +350 -0
- package/dist/core/signed-artifact.d.ts +8 -1
- package/dist/core/signed-artifact.js +35 -11
- package/dist/core/target-subtree.d.ts +8 -0
- package/dist/core/target-subtree.js +54 -3
- package/dist/core/version-service.d.ts +11 -0
- package/dist/core/version-service.js +129 -24
- package/dist/core/wizard.d.ts +20 -17
- package/dist/core/wizard.js +66 -28
- package/dist/errors/errors.d.ts +2 -1
- package/dist/errors/errors.js +1 -0
- package/dist/generator/generate.d.ts +1 -1
- package/dist/generator/generate.js +420 -213
- package/dist/generator/shared/SOURCE.json +7 -0
- package/dist/generator/shared/svg-model.cjs +156 -0
- package/dist/generator/svg-model.d.ts +16 -0
- package/dist/generator/svg-model.js +4 -0
- package/dist/generator/theme-resolve.d.ts +2 -0
- package/dist/generator/theme-resolve.js +57 -26
- package/dist/mcp/server.d.ts +23 -36
- package/dist/mcp/server.js +74 -152
- package/dist/mcp/services.d.ts +4 -0
- package/dist/mcp/services.js +230 -0
- package/dist/metadata/archive.d.ts +38 -0
- package/dist/metadata/archive.js +94 -0
- package/dist/metadata/manifest.d.ts +33 -0
- package/dist/metadata/manifest.js +136 -0
- package/dist/metadata/version.d.ts +22 -0
- package/dist/metadata/version.js +53 -0
- package/dist/project/anchors/application.d.ts +13 -0
- package/dist/project/anchors/application.js +377 -0
- package/dist/project/anchors/apply.d.ts +28 -0
- package/dist/project/anchors/apply.js +65 -0
- package/dist/project/anchors/diagnose.d.ts +26 -0
- package/dist/project/anchors/diagnose.js +90 -0
- package/dist/project/anchors/helpers.d.ts +20 -0
- package/dist/project/anchors/helpers.js +55 -0
- package/dist/project/anchors/moeicons-config.d.ts +21 -0
- package/dist/project/anchors/moeicons-config.js +83 -0
- package/dist/project/anchors/parse.d.ts +14 -0
- package/dist/project/anchors/parse.js +36 -0
- package/dist/project/anchors/project-manifest.d.ts +19 -0
- package/dist/project/anchors/project-manifest.js +109 -0
- package/dist/project/anchors/style.d.ts +12 -0
- package/dist/project/anchors/style.js +87 -0
- package/dist/project/anchors/types.d.ts +32 -0
- package/dist/project/anchors/types.js +9 -0
- package/dist/project/config.d.ts +59 -5
- package/dist/project/config.js +234 -102
- package/dist/project/install-metadata.d.ts +23 -2
- package/dist/project/install-metadata.js +58 -7
- package/dist/project/install.d.ts +24 -4
- package/dist/project/install.js +402 -190
- package/dist/project/project-lock.d.ts +2 -2
- package/dist/project/project-lock.js +4 -4
- package/dist/project/tailwind.d.ts +2 -2
- package/dist/project/tailwind.js +3 -4
- package/dist/project/tar-gz.d.ts +18 -1
- package/dist/project/tar-gz.js +40 -3
- package/dist/tui/components.d.ts +62 -0
- package/dist/tui/components.js +100 -0
- package/dist/tui/primitives.d.ts +1 -0
- package/dist/tui/primitives.js +8 -1
- package/dist/ui/banner.d.ts +31 -3
- package/dist/ui/banner.js +120 -25
- package/dist/ui/branded-prompts.d.ts +41 -0
- package/dist/ui/branded-prompts.js +80 -0
- package/dist/ui/clack.d.ts +6 -3
- package/dist/ui/clack.js +56 -5
- package/dist/ui/create-ui.d.ts +1 -0
- package/dist/ui/create-ui.js +5 -1
- package/dist/ui/generated/wordmark-large.d.ts +17 -0
- package/dist/ui/generated/wordmark-large.js +28 -0
- package/dist/ui/generated/wordmark.d.ts +2 -0
- package/dist/ui/generated/wordmark.js +2 -0
- package/dist/ui/non-interactive.js +8 -0
- package/dist/ui/stream.js +30 -0
- package/dist/ui/theme.d.ts +42 -0
- package/dist/ui/theme.js +59 -0
- package/package.json +14 -6
|
@@ -12,10 +12,20 @@ export type Command = {
|
|
|
12
12
|
readonly name: "groups";
|
|
13
13
|
} | {
|
|
14
14
|
readonly name: "generate";
|
|
15
|
+
} | {
|
|
16
|
+
readonly name: "recover";
|
|
15
17
|
} | {
|
|
16
18
|
readonly name: "init";
|
|
19
|
+
readonly dryRun?: boolean;
|
|
20
|
+
} | {
|
|
21
|
+
readonly name: "doctor";
|
|
22
|
+
readonly check?: boolean;
|
|
23
|
+
readonly dryRun?: boolean;
|
|
17
24
|
} | {
|
|
18
25
|
readonly name: "mcp";
|
|
26
|
+
} | {
|
|
27
|
+
readonly name: "update";
|
|
28
|
+
readonly metadata?: boolean;
|
|
19
29
|
} | {
|
|
20
30
|
readonly name: "help";
|
|
21
31
|
} | {
|
|
@@ -34,8 +44,9 @@ export interface ParseResult {
|
|
|
34
44
|
}
|
|
35
45
|
export type Target = "react" | "vue" | "vanilla" | "assets";
|
|
36
46
|
/**
|
|
37
|
-
* Parse argv into a Command
|
|
47
|
+
* Parse argv into a Command. Never calls `process.exit()`.
|
|
38
48
|
* `moeicons --pro` / `--ent` legacy aliases map to install for the compatibility window.
|
|
49
|
+
* Unknown commands and unknown options map to a stable VALIDATION_ERROR.
|
|
39
50
|
*/
|
|
40
51
|
export declare function parseArgs(argv: readonly string[]): ParseResult;
|
|
41
|
-
export declare const HELP_TEXT = "moeicons \u2014 Moeicons icon library CLI\n\nUsage:\n moeicons interactive guided flow (free / pro / login)\n moeicons install [group] install an icon group\n moeicons login browser login (PKCE)\n moeicons logout clear local session\n moeicons account show account/tier info\n moeicons groups list available icon groups\n moeicons generate generate React/Vue proxy components\n moeicons init create moeicons.config.json\n moeicons mcp start the MCP stdio server\n moeicons --version show version\n moeicons --help show help\n\nOptions:\n --json machine-readable JSON output\n --yes skip confirmations in noninteractive mode\n --target output target: react, vue, vanilla, or assets\n --no-tailwind skip Tailwind config auto-integration\n";
|
|
52
|
+
export declare const HELP_TEXT = "moeicons \u2014 Moeicons icon library CLI\n\nUsage:\n moeicons interactive guided flow (free / pro / login)\n moeicons install [group] install an icon group\n moeicons login browser login (PKCE)\n moeicons logout clear local session\n moeicons account show account/tier info\n moeicons groups list available icon groups\n moeicons generate generate React/Vue proxy components\n moeicons init create moeicons.config.jsonc\n moeicons init --dry-run print the full config/entry/style plan without writing\n moeicons doctor diagnose project anchors (read-only)\n moeicons recover recover interrupted writes (run at project root)\n moeicons doctor --check exit non-zero when any required anchor is not OK\n moeicons update metadata sync MANUAL.md/catalog.json/manifest.json only\n moeicons update full code + metadata update\n moeicons mcp start the MCP stdio server\n moeicons --version show version\n moeicons --help show help\n\nOptions:\n --json machine-readable JSON output\n --yes skip confirmations in noninteractive mode\n --target output target: react, vue, vanilla, or assets\n --no-tailwind skip Tailwind config auto-integration\n --dry-run (init/doctor) plan only, never write\n --check (doctor) exit 1 when required anchors are not OK\n";
|
package/dist/commands/parser.js
CHANGED
|
@@ -6,10 +6,59 @@ const SIMPLE_COMMANDS = [
|
|
|
6
6
|
"account",
|
|
7
7
|
"groups",
|
|
8
8
|
"generate",
|
|
9
|
-
"
|
|
9
|
+
"recover",
|
|
10
10
|
"mcp",
|
|
11
11
|
"help",
|
|
12
12
|
];
|
|
13
|
+
/**
|
|
14
|
+
* Options accepted on every command. `--dry-run`/`--check` are additionally
|
|
15
|
+
* accepted on `init` / `doctor` (validated in parseArgs). Unknown options never
|
|
16
|
+
* pass silently; they produce a stable VALIDATION_ERROR.
|
|
17
|
+
*/
|
|
18
|
+
const GLOBAL_OPTIONS = new Set([
|
|
19
|
+
"--json",
|
|
20
|
+
"--yes",
|
|
21
|
+
"--no-tailwind",
|
|
22
|
+
"--pro",
|
|
23
|
+
"--ent",
|
|
24
|
+
"--help",
|
|
25
|
+
"-h",
|
|
26
|
+
"--version",
|
|
27
|
+
"-v",
|
|
28
|
+
"--showVersion",
|
|
29
|
+
]);
|
|
30
|
+
function commandName(argv) {
|
|
31
|
+
for (const arg of argv) {
|
|
32
|
+
if (!arg.startsWith("-"))
|
|
33
|
+
return arg;
|
|
34
|
+
}
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
/** Validate that no option is unknown for the given command. */
|
|
38
|
+
function rejectUnknownOptions(argv, command) {
|
|
39
|
+
const allowLocal = command === "init" || command === "doctor";
|
|
40
|
+
const local = new Set(["--dry-run", "--check"]);
|
|
41
|
+
for (const arg of argv) {
|
|
42
|
+
if (!arg.startsWith("-"))
|
|
43
|
+
continue;
|
|
44
|
+
const name = arg.split("=")[0] ?? arg;
|
|
45
|
+
if (arg.startsWith("--target"))
|
|
46
|
+
continue; // value validated separately
|
|
47
|
+
if (GLOBAL_OPTIONS.has(name))
|
|
48
|
+
continue;
|
|
49
|
+
if (allowLocal && local.has(name))
|
|
50
|
+
continue;
|
|
51
|
+
throw new CliError("VALIDATION_ERROR", `unknown option: ${name}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function parseTarget(argv) {
|
|
55
|
+
const targetIndex = argv.indexOf("--target");
|
|
56
|
+
const targetValue = targetIndex >= 0 ? argv[targetIndex + 1] : undefined;
|
|
57
|
+
if (targetIndex >= 0 && !["react", "vue", "vanilla", "assets"].includes(targetValue ?? "")) {
|
|
58
|
+
throw new CliError("VALIDATION_ERROR", `unknown target: ${targetValue ?? ""}`);
|
|
59
|
+
}
|
|
60
|
+
return targetValue;
|
|
61
|
+
}
|
|
13
62
|
function addSharedOptions(command) {
|
|
14
63
|
return command
|
|
15
64
|
.allowUnknownOption(true)
|
|
@@ -24,46 +73,11 @@ function addSharedOptions(command) {
|
|
|
24
73
|
.option("--pro")
|
|
25
74
|
.option("--ent");
|
|
26
75
|
}
|
|
27
|
-
|
|
28
|
-
const program = addSharedOptions(new Commander());
|
|
29
|
-
program
|
|
30
|
-
.name("moeicons")
|
|
31
|
-
.exitOverride()
|
|
32
|
-
.addHelpCommand(false)
|
|
33
|
-
.showHelpAfterError(false)
|
|
34
|
-
.enablePositionalOptions()
|
|
35
|
-
.configureOutput({
|
|
36
|
-
writeOut: () => undefined,
|
|
37
|
-
writeErr: () => undefined,
|
|
38
|
-
})
|
|
39
|
-
.action(() => {
|
|
40
|
-
onSelect({ name: "wizard" });
|
|
41
|
-
});
|
|
42
|
-
addSharedOptions(program.command("install").argument("[group]")).action((group) => {
|
|
43
|
-
onSelect(group ? { name: "install", group } : { name: "install" });
|
|
44
|
-
});
|
|
45
|
-
for (const name of SIMPLE_COMMANDS) {
|
|
46
|
-
addSharedOptions(program.command(name)).action(() => {
|
|
47
|
-
onSelect({ name });
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
return program;
|
|
51
|
-
}
|
|
52
|
-
function toCliError(error) {
|
|
53
|
-
if (error instanceof CommanderError && error.code === "commander.unknownCommand") {
|
|
54
|
-
const match = /unknown command ['`]?([^'`\s]+)/.exec(error.message);
|
|
55
|
-
throw new CliError("VALIDATION_ERROR", `unknown command: ${match?.[1] ?? "unknown"}`);
|
|
56
|
-
}
|
|
57
|
-
if (error instanceof CommanderError &&
|
|
58
|
-
(error.code === "commander.help" || error.code === "commander.helpDisplayed")) {
|
|
59
|
-
throw new CliError("VALIDATION_ERROR", error.message);
|
|
60
|
-
}
|
|
61
|
-
throw error;
|
|
62
|
-
}
|
|
63
|
-
const KNOWN_COMMANDS = new Set(["install", ...SIMPLE_COMMANDS]);
|
|
76
|
+
const KNOWN_COMMANDS = new Set(["install", "update", "init", "doctor", ...SIMPLE_COMMANDS]);
|
|
64
77
|
/**
|
|
65
|
-
* Parse argv into a Command
|
|
78
|
+
* Parse argv into a Command. Never calls `process.exit()`.
|
|
66
79
|
* `moeicons --pro` / `--ent` legacy aliases map to install for the compatibility window.
|
|
80
|
+
* Unknown commands and unknown options map to a stable VALIDATION_ERROR.
|
|
67
81
|
*/
|
|
68
82
|
export function parseArgs(argv) {
|
|
69
83
|
const json = argv.includes("--json");
|
|
@@ -73,12 +87,18 @@ export function parseArgs(argv) {
|
|
|
73
87
|
const help = argv.includes("--help") || argv.includes("-h");
|
|
74
88
|
const pro = argv.includes("--pro");
|
|
75
89
|
const ent = argv.includes("--ent");
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
if (
|
|
79
|
-
|
|
90
|
+
const target = parseTarget(argv);
|
|
91
|
+
const first = commandName(argv);
|
|
92
|
+
if (first !== undefined && !KNOWN_COMMANDS.has(first)) {
|
|
93
|
+
rejectUnknownOptions(argv, first);
|
|
94
|
+
throw new CliError("VALIDATION_ERROR", `unknown command: ${first}`);
|
|
95
|
+
}
|
|
96
|
+
if (first === "init" || first === "doctor") {
|
|
97
|
+
rejectUnknownOptions(argv, first);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
rejectUnknownOptions(argv);
|
|
80
101
|
}
|
|
81
|
-
const target = targetValue;
|
|
82
102
|
const withTarget = (command) => target ? { ...command, target } : command;
|
|
83
103
|
// Preserve previous flag precedence: version/help/legacy aliases beat subcommands.
|
|
84
104
|
if (version)
|
|
@@ -101,16 +121,33 @@ export function parseArgs(argv) {
|
|
|
101
121
|
noTailwind,
|
|
102
122
|
...(target ? { target } : {}),
|
|
103
123
|
};
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
124
|
+
if (first === "init") {
|
|
125
|
+
return {
|
|
126
|
+
command: withTarget({ name: "init", ...(argv.includes("--dry-run") ? { dryRun: true } : {}) }),
|
|
127
|
+
json,
|
|
128
|
+
yes,
|
|
129
|
+
noTailwind,
|
|
130
|
+
...(target ? { target } : {}),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
if (first === "doctor") {
|
|
134
|
+
return {
|
|
135
|
+
command: {
|
|
136
|
+
name: "doctor",
|
|
137
|
+
...(argv.includes("--check") ? { check: true } : {}),
|
|
138
|
+
...(argv.includes("--dry-run") ? { dryRun: true } : {}),
|
|
139
|
+
},
|
|
140
|
+
json,
|
|
141
|
+
yes,
|
|
142
|
+
noTailwind,
|
|
143
|
+
...(target ? { target } : {}),
|
|
144
|
+
};
|
|
108
145
|
}
|
|
109
146
|
let selected;
|
|
110
147
|
try {
|
|
111
148
|
createProgram((command) => {
|
|
112
149
|
selected = withTarget(command);
|
|
113
|
-
}).parse(
|
|
150
|
+
}).parse(argv, { from: "user" });
|
|
114
151
|
}
|
|
115
152
|
catch (error) {
|
|
116
153
|
toCliError(error);
|
|
@@ -123,6 +160,49 @@ export function parseArgs(argv) {
|
|
|
123
160
|
...(target ? { target } : {}),
|
|
124
161
|
};
|
|
125
162
|
}
|
|
163
|
+
function createProgram(onSelect) {
|
|
164
|
+
const program = addSharedOptions(new Commander());
|
|
165
|
+
program
|
|
166
|
+
.name("moeicons")
|
|
167
|
+
.exitOverride()
|
|
168
|
+
.addHelpCommand(false)
|
|
169
|
+
.showHelpAfterError(false)
|
|
170
|
+
.enablePositionalOptions()
|
|
171
|
+
.configureOutput({
|
|
172
|
+
writeOut: () => undefined,
|
|
173
|
+
writeErr: () => undefined,
|
|
174
|
+
})
|
|
175
|
+
.action(() => {
|
|
176
|
+
onSelect({ name: "wizard" });
|
|
177
|
+
});
|
|
178
|
+
addSharedOptions(program.command("install").argument("[group]")).action((group) => {
|
|
179
|
+
onSelect(group ? { name: "install", group } : { name: "install" });
|
|
180
|
+
});
|
|
181
|
+
addSharedOptions(program.command("update").argument("[sub]")).action((sub) => {
|
|
182
|
+
onSelect({ name: "update", metadata: sub === "metadata" });
|
|
183
|
+
});
|
|
184
|
+
for (const name of SIMPLE_COMMANDS) {
|
|
185
|
+
addSharedOptions(program.command(name)).action(() => {
|
|
186
|
+
onSelect({ name });
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
return program;
|
|
190
|
+
}
|
|
191
|
+
function toCliError(error) {
|
|
192
|
+
if (error instanceof CommanderError && error.code === "commander.unknownCommand") {
|
|
193
|
+
const match = /unknown command ['`]?([^'`\s]+)/.exec(error.message);
|
|
194
|
+
throw new CliError("VALIDATION_ERROR", `unknown command: ${match?.[1] ?? "unknown"}`);
|
|
195
|
+
}
|
|
196
|
+
if (error instanceof CommanderError && error.code === "commander.unknownOption") {
|
|
197
|
+
const match = /unknown option ['`]?([^'`\s]+)/.exec(error.message);
|
|
198
|
+
throw new CliError("VALIDATION_ERROR", `unknown option: ${match?.[1] ?? "unknown"}`);
|
|
199
|
+
}
|
|
200
|
+
if (error instanceof CommanderError &&
|
|
201
|
+
(error.code === "commander.help" || error.code === "commander.helpDisplayed")) {
|
|
202
|
+
throw new CliError("VALIDATION_ERROR", error.message);
|
|
203
|
+
}
|
|
204
|
+
throw error;
|
|
205
|
+
}
|
|
126
206
|
export const HELP_TEXT = `moeicons — Moeicons icon library CLI
|
|
127
207
|
|
|
128
208
|
Usage:
|
|
@@ -133,7 +213,13 @@ Usage:
|
|
|
133
213
|
moeicons account show account/tier info
|
|
134
214
|
moeicons groups list available icon groups
|
|
135
215
|
moeicons generate generate React/Vue proxy components
|
|
136
|
-
moeicons init create moeicons.config.
|
|
216
|
+
moeicons init create moeicons.config.jsonc
|
|
217
|
+
moeicons init --dry-run print the full config/entry/style plan without writing
|
|
218
|
+
moeicons doctor diagnose project anchors (read-only)
|
|
219
|
+
moeicons recover recover interrupted writes (run at project root)
|
|
220
|
+
moeicons doctor --check exit non-zero when any required anchor is not OK
|
|
221
|
+
moeicons update metadata sync MANUAL.md/catalog.json/manifest.json only
|
|
222
|
+
moeicons update full code + metadata update
|
|
137
223
|
moeicons mcp start the MCP stdio server
|
|
138
224
|
moeicons --version show version
|
|
139
225
|
moeicons --help show help
|
|
@@ -143,4 +229,6 @@ Options:
|
|
|
143
229
|
--yes skip confirmations in noninteractive mode
|
|
144
230
|
--target output target: react, vue, vanilla, or assets
|
|
145
231
|
--no-tailwind skip Tailwind config auto-integration
|
|
232
|
+
--dry-run (init/doctor) plan only, never write
|
|
233
|
+
--check (doctor) exit 1 when required anchors are not OK
|
|
146
234
|
`;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"sourceRepo": "moewolf-dev/moe-icons-code-library",
|
|
4
|
+
"sourceDir": "config-package",
|
|
5
|
+
"sourceCommit": "76d9924b2114afc317d0a630cde536fb035a908c",
|
|
6
|
+
"sourceCommitExact": true,
|
|
7
|
+
"files": {
|
|
8
|
+
"render-config.cjs": {
|
|
9
|
+
"size": 6002,
|
|
10
|
+
"sha256": "690418924769912a2e5b572ceed96b30cfe77e19ca3eb40189dc183bc32056c3"
|
|
11
|
+
},
|
|
12
|
+
"validate-config.cjs": {
|
|
13
|
+
"size": 11112,
|
|
14
|
+
"sha256": "36c35b686335eab4e7db002afb631aa631c80f66656f137b1e2437317b126b0f"
|
|
15
|
+
},
|
|
16
|
+
"moeicons-config.schema.json": {
|
|
17
|
+
"size": 4769,
|
|
18
|
+
"sha256": "0e15c0cf7c282abad7d7399e4a52b7804dc8211b427490fca5efc6c53d9319df"
|
|
19
|
+
},
|
|
20
|
+
"moeicons.config.jsonc": {
|
|
21
|
+
"size": 1207,
|
|
22
|
+
"sha256": "260496b4dee0796e03b37dffd442dafeb406b3fdf15eb43c2927e75b497cb6ef"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://moeicons.dev/schema/moeicons-config-v3.json",
|
|
4
|
+
"title": "Moeicons user-project configuration (schema v3)",
|
|
5
|
+
"description": "Canonical user-project configuration. Version 3 adds the optional `integration` object (application/style anchors confirmed by the CLI) on top of the schema v2 fields. The pixel-ladder field remains `imageSize` and is never called `size`.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"schemaVersion",
|
|
10
|
+
"tier",
|
|
11
|
+
"target",
|
|
12
|
+
"outputDir",
|
|
13
|
+
"defaultTheme",
|
|
14
|
+
"themes",
|
|
15
|
+
"icons"
|
|
16
|
+
],
|
|
17
|
+
"properties": {
|
|
18
|
+
"schemaVersion": {
|
|
19
|
+
"const": 3
|
|
20
|
+
},
|
|
21
|
+
"tier": {
|
|
22
|
+
"enum": [
|
|
23
|
+
"free",
|
|
24
|
+
"pro"
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"target": {
|
|
28
|
+
"enum": [
|
|
29
|
+
"react",
|
|
30
|
+
"vue",
|
|
31
|
+
"vanilla",
|
|
32
|
+
"assets"
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"outputDir": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"minLength": 1,
|
|
38
|
+
"pattern": "^(?!/)(?![A-Za-z]:)(?!.*(?:/|^)\\.{1,2}(?:/|$))(?!(?:\\.git|\\.moeicons|node_modules)(?:/|$))[A-Za-z0-9_-]+(?:/[A-Za-z0-9_.-]+)*$"
|
|
39
|
+
},
|
|
40
|
+
"defaultTheme": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"minLength": 1
|
|
43
|
+
},
|
|
44
|
+
"missingIconPolicy": {
|
|
45
|
+
"enum": [
|
|
46
|
+
"fallback",
|
|
47
|
+
"error"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
"themes": {
|
|
51
|
+
"type": "object",
|
|
52
|
+
"propertyNames": {
|
|
53
|
+
"pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$"
|
|
54
|
+
},
|
|
55
|
+
"additionalProperties": {
|
|
56
|
+
"type": "object",
|
|
57
|
+
"additionalProperties": false,
|
|
58
|
+
"required": [
|
|
59
|
+
"styleGroup"
|
|
60
|
+
],
|
|
61
|
+
"properties": {
|
|
62
|
+
"icons": {
|
|
63
|
+
"description": "Optional subset of project icons selected for this theme. Omit to select all registered icons; an empty array selects none. Missing variants follow missingIconPolicy.",
|
|
64
|
+
"type": "array",
|
|
65
|
+
"uniqueItems": true,
|
|
66
|
+
"items": {
|
|
67
|
+
"type": "string"
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"styleGroup": {
|
|
71
|
+
"type": "string",
|
|
72
|
+
"pattern": "^moe-[a-z0-9]+(?:-[a-z0-9]+)*$"
|
|
73
|
+
},
|
|
74
|
+
"styles": {
|
|
75
|
+
"type": "array",
|
|
76
|
+
"items": {
|
|
77
|
+
"type": "string"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"format": {
|
|
81
|
+
"enum": [
|
|
82
|
+
"svg",
|
|
83
|
+
"webp",
|
|
84
|
+
"png"
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
"imageSize": {
|
|
88
|
+
"enum": [
|
|
89
|
+
64,
|
|
90
|
+
128,
|
|
91
|
+
256,
|
|
92
|
+
512
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
"defaultSize": {
|
|
96
|
+
"type": "number",
|
|
97
|
+
"exclusiveMinimum": 0
|
|
98
|
+
},
|
|
99
|
+
"strokeWidth": {
|
|
100
|
+
"type": "number",
|
|
101
|
+
"minimum": 0
|
|
102
|
+
},
|
|
103
|
+
"className": {
|
|
104
|
+
"type": "string"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"icons": {
|
|
110
|
+
"description": "Either a flat string array or a prefix-grouped object. Grouped form is canonical; each key is a prefix and each value an array of icon IDs.",
|
|
111
|
+
"oneOf": [
|
|
112
|
+
{
|
|
113
|
+
"type": "array",
|
|
114
|
+
"items": {
|
|
115
|
+
"type": "string"
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"type": "object",
|
|
120
|
+
"additionalProperties": {
|
|
121
|
+
"type": "array",
|
|
122
|
+
"items": {
|
|
123
|
+
"type": "string"
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
"integration": {
|
|
130
|
+
"type": "object",
|
|
131
|
+
"additionalProperties": false,
|
|
132
|
+
"required": [
|
|
133
|
+
"adapter"
|
|
134
|
+
],
|
|
135
|
+
"properties": {
|
|
136
|
+
"adapter": {
|
|
137
|
+
"enum": [
|
|
138
|
+
"vite-react",
|
|
139
|
+
"next-app",
|
|
140
|
+
"next-pages",
|
|
141
|
+
"vite-vue",
|
|
142
|
+
"nuxt",
|
|
143
|
+
"vanilla",
|
|
144
|
+
"assets-only"
|
|
145
|
+
]
|
|
146
|
+
},
|
|
147
|
+
"entry": {
|
|
148
|
+
"type": "string",
|
|
149
|
+
"minLength": 1,
|
|
150
|
+
"pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*\\u0000)(?!.*(?:^|/)\\.{1,2}(?:/|$))[^/]+(?:/[^/]+)*$"
|
|
151
|
+
},
|
|
152
|
+
"style": {
|
|
153
|
+
"type": "string",
|
|
154
|
+
"minLength": 1,
|
|
155
|
+
"pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*\\u0000)(?!.*(?:^|/)\\.{1,2}(?:/|$))[^/]+(?:/[^/]+)*$"
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
"allOf": [
|
|
159
|
+
{
|
|
160
|
+
"if": {
|
|
161
|
+
"not": {
|
|
162
|
+
"properties": {
|
|
163
|
+
"adapter": {
|
|
164
|
+
"const": "assets-only"
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"required": [
|
|
168
|
+
"adapter"
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
"then": {
|
|
173
|
+
"required": [
|
|
174
|
+
"entry"
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
]
|
|
179
|
+
},
|
|
180
|
+
"downloadMode": {
|
|
181
|
+
"type": "string",
|
|
182
|
+
"enum": [
|
|
183
|
+
"auto",
|
|
184
|
+
"icons",
|
|
185
|
+
"full"
|
|
186
|
+
],
|
|
187
|
+
"default": "auto",
|
|
188
|
+
"description": "Prefer configuration-selected resources (auto), require them (icons), or download the full archive (full)."
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 3,
|
|
3
|
+
"tier": "free",
|
|
4
|
+
"target": "react",
|
|
5
|
+
"outputDir": "src/moeicons",
|
|
6
|
+
// auto: indexed resources when available; icons: require them; full: whole archive.
|
|
7
|
+
"downloadMode": "auto",
|
|
8
|
+
// Global icons registers IDs; per-theme icons selects a subset (empty means none).
|
|
9
|
+
"defaultTheme": "outline",
|
|
10
|
+
"themes": {
|
|
11
|
+
"outline": {
|
|
12
|
+
"styleGroup": "moe-outline"
|
|
13
|
+
},
|
|
14
|
+
// "solid": { "styleGroup": "moe-solid" },
|
|
15
|
+
// Bitmap style groups are commented out and selected with format/imageSize:
|
|
16
|
+
// cute — bitmap style (moe-cute-3d)
|
|
17
|
+
// format options: webp, png
|
|
18
|
+
// imageSize options: 64, 128, 256, 512
|
|
19
|
+
// "cute": {
|
|
20
|
+
// "styleGroup": "moe-cute-3d",
|
|
21
|
+
// "format": "webp",
|
|
22
|
+
// "imageSize": 256
|
|
23
|
+
// },
|
|
24
|
+
// Set defaultTheme above to any enabled theme key.
|
|
25
|
+
},
|
|
26
|
+
// Add icon ids from .moeicons/catalog.json as needed.
|
|
27
|
+
"icons": {
|
|
28
|
+
"arrow": [
|
|
29
|
+
"arrow-bold-right"
|
|
30
|
+
],
|
|
31
|
+
"ui": [
|
|
32
|
+
"ui-search"
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"missingIconPolicy": "fallback",
|
|
36
|
+
// integration is written only after the user confirms anchors:
|
|
37
|
+
// "integration": {
|
|
38
|
+
// "adapter": "vite-react",
|
|
39
|
+
// "entry": "src/main.tsx",
|
|
40
|
+
// "style": "src/index.css"
|
|
41
|
+
// }
|
|
42
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Canonical renderer for the user-project `moeicons.config.jsonc`.
|
|
4
|
+
//
|
|
5
|
+
// Ownership: this module (moe-icons-code-library/config-package) is the single
|
|
6
|
+
// source of truth for the editable config skeleton. The CLI bundles a generated
|
|
7
|
+
// copy of this module plus a source digest and must never maintain a second
|
|
8
|
+
// full renderer.
|
|
9
|
+
//
|
|
10
|
+
// Behaviour contract:
|
|
11
|
+
// - `fullCatalog: true` retains the historical exhaustive renderer for users
|
|
12
|
+
// who explicitly request it. The default is a small, valid first-run config.
|
|
13
|
+
// - When `integration` is supplied (adapter/entry/style confirmed by the user),
|
|
14
|
+
// the renderer emits schemaVersion 3 and adds the `integration` block. It
|
|
15
|
+
// never invents integration paths on its own.
|
|
16
|
+
// - Deterministic output for identical inputs.
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {object} options
|
|
20
|
+
* @param {"react"|"vue"|"vanilla"|"assets"} options.target
|
|
21
|
+
* @param {"react"|"vue"} [options.framework] legacy alias; resolves to target
|
|
22
|
+
* @param {"free"|"pro"} [options.tier]
|
|
23
|
+
* @param {object} [options.integration] optional {adapter, entry, style}
|
|
24
|
+
* @returns {string} JSONC skeleton text
|
|
25
|
+
*/
|
|
26
|
+
function renderMoeiconsConfigJsonc(options) {
|
|
27
|
+
const ALLOWED = new Set(['target', 'framework', 'tier', 'catalog', 'integration', 'fullCatalog']);
|
|
28
|
+
for (const key of Object.keys(options)) {
|
|
29
|
+
if (!ALLOWED.has(key)) {
|
|
30
|
+
throw new Error(`unknown render option "${key}"`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const tier = options.tier ?? 'free';
|
|
34
|
+
if (!options.catalog) {
|
|
35
|
+
throw new Error('catalog is required');
|
|
36
|
+
}
|
|
37
|
+
const target = options.target ?? options.framework ?? 'react';
|
|
38
|
+
|
|
39
|
+
const availableGroups = (options.catalog ? options.catalog.styleGroups : [])
|
|
40
|
+
.filter((g) => Array.isArray(g.tiers) && g.tiers.includes(tier))
|
|
41
|
+
.sort((a, b) => a.id.localeCompare(b.id));
|
|
42
|
+
|
|
43
|
+
const fullCatalog = options.fullCatalog === true;
|
|
44
|
+
const defaultGroup = availableGroups.find((group) => group.id === 'moe-outline') ?? availableGroups.find((group) => group.type !== 'bitmap');
|
|
45
|
+
if (!defaultGroup) throw new Error(`no SVG style group is available in ${tier} tier`);
|
|
46
|
+
const defaultThemeName = fullCatalog ? 'outline' : defaultGroup.id.replace(/^moe-/, '');
|
|
47
|
+
|
|
48
|
+
const themeLines = [];
|
|
49
|
+
for (const group of availableGroups) {
|
|
50
|
+
const themeName = group.id.replace(/^moe-/, '');
|
|
51
|
+
if (group.type === 'bitmap') {
|
|
52
|
+
const formatsComment = `// format options: ${group.formats.join(', ')}`;
|
|
53
|
+
const sizesComment = `// imageSize options: ${group.imageSizes.join(', ')}`;
|
|
54
|
+
themeLines.push(
|
|
55
|
+
` // ${themeName} — bitmap style (${group.id})`,
|
|
56
|
+
` // ${formatsComment}`,
|
|
57
|
+
` // ${sizesComment}`,
|
|
58
|
+
` // ${JSON.stringify(themeName)}: {`,
|
|
59
|
+
` // "styleGroup": ${JSON.stringify(group.id)},`,
|
|
60
|
+
` // "format": "webp",`,
|
|
61
|
+
` // "imageSize": 256`,
|
|
62
|
+
` // },`,
|
|
63
|
+
);
|
|
64
|
+
} else if (fullCatalog || group.id === defaultGroup.id) {
|
|
65
|
+
themeLines.push(
|
|
66
|
+
` ${JSON.stringify(themeName)}: {`,
|
|
67
|
+
` "styleGroup": ${JSON.stringify(group.id)}`,
|
|
68
|
+
` },`,
|
|
69
|
+
);
|
|
70
|
+
} else {
|
|
71
|
+
themeLines.push(` // ${JSON.stringify(themeName)}: { "styleGroup": ${JSON.stringify(group.id)} },`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const tierGroupIds = new Set((fullCatalog ? availableGroups : [defaultGroup]).map((g) => g.id));
|
|
76
|
+
const groups = new Map();
|
|
77
|
+
const eligible = (options.catalog ? options.catalog.icons : [])
|
|
78
|
+
.filter((icon) => icon.availableIn.some((sg) => tierGroupIds.has(sg)));
|
|
79
|
+
const examples = fullCatalog ? eligible : [
|
|
80
|
+
...['arrow-bold-right', 'ui-search'].map((id) => eligible.find((icon) => icon.id === id)).filter(Boolean),
|
|
81
|
+
...eligible,
|
|
82
|
+
].filter((icon, index, values) => values.findIndex((item) => item.id === icon.id) === index).slice(0, 2);
|
|
83
|
+
for (const icon of examples) {
|
|
84
|
+
const ids = groups.get(icon.prefix) ?? [];
|
|
85
|
+
ids.push(icon.id);
|
|
86
|
+
groups.set(icon.prefix, ids);
|
|
87
|
+
}
|
|
88
|
+
const iconLines = [...groups.entries()]
|
|
89
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
90
|
+
.flatMap(([prefix, ids]) => [
|
|
91
|
+
` // ${prefix} icons`,
|
|
92
|
+
` ${JSON.stringify(prefix)}: [`,
|
|
93
|
+
...ids.map((id) => ` ${JSON.stringify(id)},`),
|
|
94
|
+
' ],',
|
|
95
|
+
]);
|
|
96
|
+
|
|
97
|
+
const schemaVersion = options.integration || !fullCatalog ? 3 : 2;
|
|
98
|
+
const integrationBlock = options.integration
|
|
99
|
+
? [
|
|
100
|
+
'',
|
|
101
|
+
' // User-confirmed application/style anchors (written only after',
|
|
102
|
+
' // confirmation; never auto-guessed).',
|
|
103
|
+
` "integration": {`,
|
|
104
|
+
` "adapter": ${JSON.stringify(options.integration.adapter)},`,
|
|
105
|
+
...(options.integration.entry !== undefined
|
|
106
|
+
? [` "entry": ${JSON.stringify(options.integration.entry)},`]
|
|
107
|
+
: []),
|
|
108
|
+
...(options.integration.style !== undefined
|
|
109
|
+
? [` "style": ${JSON.stringify(options.integration.style)},`]
|
|
110
|
+
: []),
|
|
111
|
+
' }',
|
|
112
|
+
]
|
|
113
|
+
: [];
|
|
114
|
+
|
|
115
|
+
return [
|
|
116
|
+
'{',
|
|
117
|
+
` "schemaVersion": ${schemaVersion},`,
|
|
118
|
+
` "tier": ${JSON.stringify(tier)},`,
|
|
119
|
+
` "target": ${JSON.stringify(target)},`,
|
|
120
|
+
` "outputDir": "src/moeicons",`,
|
|
121
|
+
...(!fullCatalog ? [
|
|
122
|
+
' // auto: indexed resources when available; icons: require them; full: whole archive.',
|
|
123
|
+
' "downloadMode": "auto",',
|
|
124
|
+
' // Global icons registers IDs; per-theme icons selects a subset (empty means none).',
|
|
125
|
+
] : []),
|
|
126
|
+
` "defaultTheme": ${JSON.stringify(defaultThemeName)},`,
|
|
127
|
+
' "themes": {',
|
|
128
|
+
...themeLines,
|
|
129
|
+
` // Set defaultTheme above to one of: ${availableGroups
|
|
130
|
+
.filter((g) => g.type !== 'bitmap')
|
|
131
|
+
.map((g) => JSON.stringify(g.id.replace(/^moe-/, '')))
|
|
132
|
+
.join(', ')}`,
|
|
133
|
+
' },',
|
|
134
|
+
fullCatalog ? ' // Comment out individual IDs or a complete prefix group to exclude it.' : ' // Add more icon ids from .moeicons/catalog.json when needed.',
|
|
135
|
+
' "icons": {',
|
|
136
|
+
...iconLines,
|
|
137
|
+
' },',
|
|
138
|
+
` "missingIconPolicy": "fallback"${options.integration ? ',' : ''}`,
|
|
139
|
+
...integrationBlock,
|
|
140
|
+
'}',
|
|
141
|
+
'',
|
|
142
|
+
].join('\n');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
module.exports = { renderMoeiconsConfigJsonc };
|