@singbox-iac/cli 0.1.0

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 (133) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +265 -0
  3. package/dist/cli/command-helpers.d.ts +6 -0
  4. package/dist/cli/command-helpers.js +34 -0
  5. package/dist/cli/command-helpers.js.map +1 -0
  6. package/dist/cli/commands/apply.d.ts +2 -0
  7. package/dist/cli/commands/apply.js +32 -0
  8. package/dist/cli/commands/apply.js.map +1 -0
  9. package/dist/cli/commands/author.d.ts +2 -0
  10. package/dist/cli/commands/author.js +194 -0
  11. package/dist/cli/commands/author.js.map +1 -0
  12. package/dist/cli/commands/build.d.ts +2 -0
  13. package/dist/cli/commands/build.js +198 -0
  14. package/dist/cli/commands/build.js.map +1 -0
  15. package/dist/cli/commands/check.d.ts +2 -0
  16. package/dist/cli/commands/check.js +23 -0
  17. package/dist/cli/commands/check.js.map +1 -0
  18. package/dist/cli/commands/doctor.d.ts +2 -0
  19. package/dist/cli/commands/doctor.js +35 -0
  20. package/dist/cli/commands/doctor.js.map +1 -0
  21. package/dist/cli/commands/init.d.ts +2 -0
  22. package/dist/cli/commands/init.js +23 -0
  23. package/dist/cli/commands/init.js.map +1 -0
  24. package/dist/cli/commands/reload.d.ts +2 -0
  25. package/dist/cli/commands/reload.js +21 -0
  26. package/dist/cli/commands/reload.js.map +1 -0
  27. package/dist/cli/commands/run.d.ts +2 -0
  28. package/dist/cli/commands/run.js +25 -0
  29. package/dist/cli/commands/run.js.map +1 -0
  30. package/dist/cli/commands/schedule.d.ts +2 -0
  31. package/dist/cli/commands/schedule.js +77 -0
  32. package/dist/cli/commands/schedule.js.map +1 -0
  33. package/dist/cli/commands/templates.d.ts +2 -0
  34. package/dist/cli/commands/templates.js +34 -0
  35. package/dist/cli/commands/templates.js.map +1 -0
  36. package/dist/cli/commands/update.d.ts +2 -0
  37. package/dist/cli/commands/update.js +52 -0
  38. package/dist/cli/commands/update.js.map +1 -0
  39. package/dist/cli/commands/verify.d.ts +2 -0
  40. package/dist/cli/commands/verify.js +49 -0
  41. package/dist/cli/commands/verify.js.map +1 -0
  42. package/dist/cli/index.d.ts +5 -0
  43. package/dist/cli/index.js +55 -0
  44. package/dist/cli/index.js.map +1 -0
  45. package/dist/config/load-config.d.ts +2 -0
  46. package/dist/config/load-config.js +29 -0
  47. package/dist/config/load-config.js.map +1 -0
  48. package/dist/config/schema.d.ts +548 -0
  49. package/dist/config/schema.js +92 -0
  50. package/dist/config/schema.js.map +1 -0
  51. package/dist/domain/config.d.ts +8 -0
  52. package/dist/domain/config.js +2 -0
  53. package/dist/domain/config.js.map +1 -0
  54. package/dist/domain/node.d.ts +11 -0
  55. package/dist/domain/node.js +2 -0
  56. package/dist/domain/node.js.map +1 -0
  57. package/dist/domain/outbound.d.ts +15 -0
  58. package/dist/domain/outbound.js +2 -0
  59. package/dist/domain/outbound.js.map +1 -0
  60. package/dist/domain/subscription.d.ts +6 -0
  61. package/dist/domain/subscription.js +2 -0
  62. package/dist/domain/subscription.js.map +1 -0
  63. package/dist/index.d.ts +1 -0
  64. package/dist/index.js +2 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/modules/authoring/index.d.ts +41 -0
  67. package/dist/modules/authoring/index.js +596 -0
  68. package/dist/modules/authoring/index.js.map +1 -0
  69. package/dist/modules/build/index.d.ts +13 -0
  70. package/dist/modules/build/index.js +39 -0
  71. package/dist/modules/build/index.js.map +1 -0
  72. package/dist/modules/compiler/index.d.ts +10 -0
  73. package/dist/modules/compiler/index.js +305 -0
  74. package/dist/modules/compiler/index.js.map +1 -0
  75. package/dist/modules/doctor/index.d.ts +17 -0
  76. package/dist/modules/doctor/index.js +89 -0
  77. package/dist/modules/doctor/index.js.map +1 -0
  78. package/dist/modules/fetcher/index.d.ts +4 -0
  79. package/dist/modules/fetcher/index.js +42 -0
  80. package/dist/modules/fetcher/index.js.map +1 -0
  81. package/dist/modules/init/index.d.ts +12 -0
  82. package/dist/modules/init/index.js +41 -0
  83. package/dist/modules/init/index.js.map +1 -0
  84. package/dist/modules/manager/index.d.ts +29 -0
  85. package/dist/modules/manager/index.js +133 -0
  86. package/dist/modules/manager/index.js.map +1 -0
  87. package/dist/modules/natural-language/index.d.ts +54 -0
  88. package/dist/modules/natural-language/index.js +458 -0
  89. package/dist/modules/natural-language/index.js.map +1 -0
  90. package/dist/modules/parser/index.d.ts +10 -0
  91. package/dist/modules/parser/index.js +113 -0
  92. package/dist/modules/parser/index.js.map +1 -0
  93. package/dist/modules/preview/index.d.ts +22 -0
  94. package/dist/modules/preview/index.js +141 -0
  95. package/dist/modules/preview/index.js.map +1 -0
  96. package/dist/modules/rule-templates/index.d.ts +15 -0
  97. package/dist/modules/rule-templates/index.js +200 -0
  98. package/dist/modules/rule-templates/index.js.map +1 -0
  99. package/dist/modules/schedule/index.d.ts +32 -0
  100. package/dist/modules/schedule/index.js +155 -0
  101. package/dist/modules/schedule/index.js.map +1 -0
  102. package/dist/modules/update/index.d.ts +22 -0
  103. package/dist/modules/update/index.js +38 -0
  104. package/dist/modules/update/index.js.map +1 -0
  105. package/dist/modules/user-rules/index.d.ts +18 -0
  106. package/dist/modules/user-rules/index.js +98 -0
  107. package/dist/modules/user-rules/index.js.map +1 -0
  108. package/dist/modules/verification/index.d.ts +49 -0
  109. package/dist/modules/verification/index.js +432 -0
  110. package/dist/modules/verification/index.js.map +1 -0
  111. package/dist/shared/errors.d.ts +3 -0
  112. package/dist/shared/errors.js +7 -0
  113. package/dist/shared/errors.js.map +1 -0
  114. package/dist/shared/logger.d.ts +2 -0
  115. package/dist/shared/logger.js +5 -0
  116. package/dist/shared/logger.js.map +1 -0
  117. package/dist/shared/result.d.ts +11 -0
  118. package/dist/shared/result.js +7 -0
  119. package/dist/shared/result.js.map +1 -0
  120. package/docs/antigravity-endpoints.md +77 -0
  121. package/docs/competitive-landscape.md +45 -0
  122. package/docs/development-workflow.md +80 -0
  123. package/docs/natural-language-authoring.md +376 -0
  124. package/docs/positioning.md +42 -0
  125. package/docs/releasing.md +72 -0
  126. package/docs/rule-templates.md +122 -0
  127. package/docs/rules-dsl.md +107 -0
  128. package/docs/runtime-on-macos.md +42 -0
  129. package/docs/sing-box-config-primer.md +39 -0
  130. package/docs/subscription-format.md +38 -0
  131. package/examples/builder.config.yaml +220 -0
  132. package/examples/custom.rules.yaml +18 -0
  133. package/package.json +51 -0
@@ -0,0 +1,198 @@
1
+ import { homedir } from "node:os";
2
+ import path from "node:path";
3
+ import { buildConfigArtifact } from "../../modules/build/index.js";
4
+ import { resolveBuilderConfig } from "../command-helpers.js";
5
+ export function registerBuildCommand(program) {
6
+ program
7
+ .command("build")
8
+ .description("Fetch, parse, and compile a staging sing-box config.")
9
+ .option("-c, --config <path>", "path to builder config YAML")
10
+ .option("--subscription-url <url>", "override subscription URL")
11
+ .option("--subscription-file <path>", "use a local subscription file instead of fetching")
12
+ .option("-o, --output <path>", "override output path")
13
+ .action(async (options) => {
14
+ const config = await resolveBuildConfig(options);
15
+ const result = await buildConfigArtifact({
16
+ config,
17
+ ...(options.output ? { outputPath: options.output } : {}),
18
+ ...(options.subscriptionFile ? { subscriptionFile: options.subscriptionFile } : {}),
19
+ ...(options.subscriptionUrl ? { subscriptionUrl: options.subscriptionUrl } : {}),
20
+ });
21
+ const warnings = [...result.warnings];
22
+ process.stdout.write(`${[
23
+ `Generated ${result.nodeCount} nodes.`,
24
+ `Output: ${result.outputPath}`,
25
+ warnings.length > 0 ? `Warnings: ${warnings.length}` : "Warnings: 0",
26
+ ].join("\n")}\n`);
27
+ if (warnings.length > 0) {
28
+ process.stdout.write(`${warnings.map((warning) => `- ${warning}`).join("\n")}\n`);
29
+ }
30
+ });
31
+ }
32
+ async function resolveBuildConfig(options) {
33
+ const builderConfig = await resolveBuilderConfig(options);
34
+ if (builderConfig) {
35
+ return builderConfig;
36
+ }
37
+ return {
38
+ version: 1,
39
+ subscription: {
40
+ url: options.subscriptionUrl ?? "",
41
+ format: "base64-lines",
42
+ protocols: ["trojan"],
43
+ },
44
+ output: {
45
+ stagingPath: options.output ?? path.resolve(process.cwd(), "config.json"),
46
+ livePath: options.output ?? path.resolve(process.cwd(), "config.json"),
47
+ backupPath: path.resolve(process.cwd(), "config.last-known-good.json"),
48
+ },
49
+ runtime: {
50
+ checkCommand: "sing-box check -c {{stagingPath}}",
51
+ reload: {
52
+ kind: "signal",
53
+ processName: "sing-box",
54
+ signal: "HUP",
55
+ },
56
+ },
57
+ listeners: {
58
+ mixed: {
59
+ enabled: true,
60
+ listen: "127.0.0.1",
61
+ port: 39097,
62
+ },
63
+ proxifier: {
64
+ enabled: true,
65
+ listen: "127.0.0.1",
66
+ port: 39091,
67
+ },
68
+ },
69
+ ruleSets: [
70
+ localRuleSet("geosite-cn"),
71
+ localRuleSet("geoip-cn"),
72
+ localRuleSet("geosite-google"),
73
+ localRuleSet("geosite-google-gemini"),
74
+ localRuleSet("geosite-google-deepmind"),
75
+ localRuleSet("geosite-anthropic"),
76
+ localRuleSet("geosite-github"),
77
+ localRuleSet("geosite-github-copilot"),
78
+ localRuleSet("geosite-cursor"),
79
+ localRuleSet("geosite-figma"),
80
+ ],
81
+ groups: {
82
+ processProxy: {
83
+ type: "selector",
84
+ includes: ["US", "SG", "JP", "HK"],
85
+ defaultNodePattern: "OnlyAI",
86
+ },
87
+ aiOut: { type: "selector", includes: ["HK", "SG", "US", "JP"], defaultTarget: "HK" },
88
+ devCommonOut: {
89
+ type: "selector",
90
+ includes: ["HK", "SG", "US", "JP"],
91
+ defaultTarget: "HK",
92
+ },
93
+ stitchOut: { type: "selector", includes: ["US", "SG", "JP"], defaultTarget: "US" },
94
+ global: { type: "urltest", includes: ["HK", "SG", "JP", "US"] },
95
+ },
96
+ rules: {
97
+ userRulesFile: path.resolve(process.cwd(), "custom.rules.yaml"),
98
+ },
99
+ verification: {
100
+ scenarios: [
101
+ {
102
+ id: "antigravity-auth",
103
+ name: "Antigravity auth via proxifier stays on the OnlyAI US node",
104
+ url: "https://accounts.google.com/favicon.ico",
105
+ inbound: "in-proxifier",
106
+ expectedOutbound: "Process-Proxy",
107
+ },
108
+ {
109
+ id: "antigravity-oauth",
110
+ name: "Antigravity OAuth metadata via proxifier stays on the OnlyAI US node",
111
+ url: "https://oauth2.googleapis.com/.well-known/openid-configuration",
112
+ inbound: "in-proxifier",
113
+ expectedOutbound: "Process-Proxy",
114
+ },
115
+ {
116
+ id: "antigravity-docs",
117
+ name: "Antigravity docs via proxifier stay on the OnlyAI US node",
118
+ url: "https://antigravity.google/docs",
119
+ inbound: "in-proxifier",
120
+ expectedOutbound: "Process-Proxy",
121
+ },
122
+ {
123
+ id: "antigravity-rules-docs",
124
+ name: "Antigravity rules docs via proxifier stay on the OnlyAI US node",
125
+ url: "https://antigravity.google/docs/rules",
126
+ inbound: "in-proxifier",
127
+ expectedOutbound: "Process-Proxy",
128
+ },
129
+ {
130
+ id: "antigravity-mcp-docs",
131
+ name: "Antigravity MCP docs via proxifier stay on the OnlyAI US node",
132
+ url: "https://antigravity.google/docs/mcp",
133
+ inbound: "in-proxifier",
134
+ expectedOutbound: "Process-Proxy",
135
+ },
136
+ {
137
+ id: "antigravity-google-apis",
138
+ name: "Antigravity Google API discovery traffic via proxifier stays on the OnlyAI US node",
139
+ url: "https://www.googleapis.com/discovery/v1/apis",
140
+ inbound: "in-proxifier",
141
+ expectedOutbound: "Process-Proxy",
142
+ },
143
+ {
144
+ id: "stitch-us",
145
+ name: "Google Stitch always uses the dedicated US exit",
146
+ url: "https://stitch.withgoogle.com/favicon.ico",
147
+ inbound: "in-mixed",
148
+ expectedOutbound: "Stitch-Out",
149
+ },
150
+ {
151
+ id: "cn-direct",
152
+ name: "China traffic stays direct",
153
+ url: "https://www.baidu.com/favicon.ico",
154
+ inbound: "in-mixed",
155
+ expectedOutbound: "direct",
156
+ },
157
+ {
158
+ id: "chatgpt-hk",
159
+ name: "ChatGPT uses the HK default AI path",
160
+ url: "https://chatgpt.com/favicon.ico",
161
+ inbound: "in-mixed",
162
+ expectedOutbound: "AI-Out",
163
+ },
164
+ {
165
+ id: "openrouter-hk",
166
+ name: "OpenRouter custom DSL rules send traffic to the HK AI path",
167
+ url: "https://openrouter.ai/favicon.ico",
168
+ inbound: "in-mixed",
169
+ expectedOutbound: "AI-Out",
170
+ },
171
+ {
172
+ id: "github-hk",
173
+ name: "GitHub uses the HK default developer path",
174
+ url: "https://github.com/favicon.ico",
175
+ inbound: "in-mixed",
176
+ expectedOutbound: "Dev-Common-Out",
177
+ },
178
+ ],
179
+ },
180
+ schedule: {
181
+ enabled: false,
182
+ intervalMinutes: 30,
183
+ },
184
+ authoring: {
185
+ provider: "deterministic",
186
+ timeoutMs: 4000,
187
+ },
188
+ };
189
+ }
190
+ function localRuleSet(tag) {
191
+ return {
192
+ tag,
193
+ format: "binary",
194
+ type: "local",
195
+ path: path.join(homedir(), ".config", "sing-box", "rule-set", `${tag}.srs`),
196
+ };
197
+ }
198
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/cli/commands/build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerCheckCommand(program: Command): void;
@@ -0,0 +1,23 @@
1
+ import { checkConfig } from "../../modules/manager/index.js";
2
+ import { resolveBuilderConfig } from "../command-helpers.js";
3
+ export function registerCheckCommand(program) {
4
+ program
5
+ .command("check")
6
+ .description("Validate a generated sing-box config.")
7
+ .option("-c, --config <path>", "path to builder config YAML")
8
+ .option("-i, --input <path>", "path to config JSON to validate")
9
+ .option("--sing-box-bin <path>", "path to sing-box binary")
10
+ .action(async (options) => {
11
+ const builderConfig = await resolveBuilderConfig(options);
12
+ const configPath = options.input ?? builderConfig?.output.stagingPath;
13
+ if (!configPath) {
14
+ throw new Error("No config path resolved. Pass --input or provide a builder config.");
15
+ }
16
+ const result = await checkConfig({
17
+ configPath,
18
+ ...(options.singBoxBin ? { singBoxBinary: options.singBoxBin } : {}),
19
+ });
20
+ process.stdout.write(`OK: ${configPath}\nBinary: ${result.binaryPath}\n`);
21
+ });
22
+ }
23
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/cli/commands/check.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,uCAAuC,CAAC;SACpD,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;SAC5D,MAAM,CAAC,oBAAoB,EAAE,iCAAiC,CAAC;SAC/D,MAAM,CAAC,uBAAuB,EAAE,yBAAyB,CAAC;SAC1D,MAAM,CAAC,KAAK,EAAE,OAA4B,EAAE,EAAE;QAC7C,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAC1D,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,IAAI,aAAa,EAAE,MAAM,CAAC,WAAW,CAAC;QACtE,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;QACxF,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC;YAC/B,UAAU;YACV,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE,CAAC,CAAC;QAEH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,UAAU,aAAa,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerDoctorCommand(program: Command): void;
@@ -0,0 +1,35 @@
1
+ import path from "node:path";
2
+ import { runDoctor } from "../../modules/doctor/index.js";
3
+ import { findDefaultConfigPath, resolveBuilderConfig } from "../command-helpers.js";
4
+ export function registerDoctorCommand(program) {
5
+ program
6
+ .command("doctor")
7
+ .description("Inspect environment readiness for singbox-iac.")
8
+ .option("-c, --config <path>", "path to builder config YAML")
9
+ .option("--sing-box-bin <path>", "path to sing-box binary")
10
+ .option("--chrome-bin <path>", "path to Chrome binary")
11
+ .option("--launch-agents-dir <path>", "override launch agents directory for checks")
12
+ .action(async (options) => {
13
+ const [config, configPath] = await Promise.all([
14
+ resolveBuilderConfig(options),
15
+ options.config ? Promise.resolve(pathResolve(options.config)) : findDefaultConfigPath(),
16
+ ]);
17
+ const report = await runDoctor({
18
+ ...(config ? { config } : {}),
19
+ ...(configPath ? { configPath } : {}),
20
+ ...(options.singBoxBin ? { singBoxBinary: options.singBoxBin } : {}),
21
+ ...(options.chromeBin ? { chromeBinary: options.chromeBin } : {}),
22
+ ...(options.launchAgentsDir
23
+ ? { launchAgentsDir: pathResolve(options.launchAgentsDir) }
24
+ : {}),
25
+ });
26
+ process.stdout.write(`${report.checks.map((check) => `[${check.status}] ${check.name}: ${check.details}`).join("\n")}\n`);
27
+ if (report.checks.some((check) => check.status === "FAIL")) {
28
+ throw new Error("Doctor found blocking failures.");
29
+ }
30
+ });
31
+ }
32
+ function pathResolve(filePath) {
33
+ return filePath.startsWith("/") ? filePath : path.resolve(process.cwd(), filePath);
34
+ }
35
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAEpF,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,gDAAgD,CAAC;SAC7D,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;SAC5D,MAAM,CAAC,uBAAuB,EAAE,yBAAyB,CAAC;SAC1D,MAAM,CAAC,qBAAqB,EAAE,uBAAuB,CAAC;SACtD,MAAM,CAAC,4BAA4B,EAAE,6CAA6C,CAAC;SACnF,MAAM,CAAC,KAAK,EAAE,OAA6B,EAAE,EAAE;QAC9C,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC7C,oBAAoB,CAAC,OAAO,CAAC;YAC7B,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,EAAE;SACxF,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC;YAC7B,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7B,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,GAAG,CAAC,OAAO,CAAC,eAAe;gBACzB,CAAC,CAAC,EAAE,eAAe,EAAE,WAAW,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE;gBAC3D,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAC;QAEH,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CACpG,CAAC;QAEF,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,CAAC;YAC3D,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AASD,SAAS,WAAW,CAAC,QAAgB;IACnC,OAAO,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;AACrF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerInitCommand(program: Command): void;
@@ -0,0 +1,23 @@
1
+ import { homedir } from "node:os";
2
+ import path from "node:path";
3
+ import { initWorkspace } from "../../modules/init/index.js";
4
+ export function registerInitCommand(program) {
5
+ program
6
+ .command("init")
7
+ .description("Create example singbox-iac configuration assets.")
8
+ .option("-c, --config-out <path>", "path to write builder config", "builder.config.local.yaml")
9
+ .option("--rules-out <path>", "path to write the custom rules YAML", path.join(homedir(), ".config", "singbox-iac", "rules", "custom.rules.yaml"))
10
+ .option("--subscription-url <url>", "seed the generated config with a real subscription URL")
11
+ .option("-f, --force", "overwrite existing generated assets")
12
+ .action(async (options) => {
13
+ const result = await initWorkspace({
14
+ configOutPath: path.resolve(options.configOut),
15
+ rulesOutPath: path.resolve(options.rulesOut),
16
+ examplesDir: path.resolve(process.cwd(), "examples"),
17
+ ...(options.subscriptionUrl ? { subscriptionUrl: options.subscriptionUrl } : {}),
18
+ force: options.force === true,
19
+ });
20
+ process.stdout.write(`${[`Config: ${result.configPath}`, `Rules: ${result.rulesPath}`].join("\n")}\n`);
21
+ });
22
+ }
23
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,kDAAkD,CAAC;SAC/D,MAAM,CAAC,yBAAyB,EAAE,8BAA8B,EAAE,2BAA2B,CAAC;SAC9F,MAAM,CACL,oBAAoB,EACpB,qCAAqC,EACrC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAC7E;SACA,MAAM,CAAC,0BAA0B,EAAE,wDAAwD,CAAC;SAC5F,MAAM,CAAC,aAAa,EAAE,qCAAqC,CAAC;SAC5D,MAAM,CAAC,KAAK,EAAE,OAA2B,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC;YACjC,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;YAC9C,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC5C,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC;YACpD,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChF,KAAK,EAAE,OAAO,CAAC,KAAK,KAAK,IAAI;SAC9B,CAAC,CAAC;QAEH,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,CAAC,WAAW,MAAM,CAAC,UAAU,EAAE,EAAE,UAAU,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CACjF,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerReloadCommand(program: Command): void;
@@ -0,0 +1,21 @@
1
+ import { reloadRuntime } from "../../modules/manager/index.js";
2
+ import { resolveBuilderConfig } from "../command-helpers.js";
3
+ export function registerReloadCommand(program) {
4
+ program
5
+ .command("reload")
6
+ .description("Reload the running sing-box process.")
7
+ .option("-c, --config <path>", "path to builder config YAML")
8
+ .option("--sing-box-bin <path>", "path to sing-box binary")
9
+ .action(async (options) => {
10
+ const builderConfig = await resolveBuilderConfig(options);
11
+ if (!builderConfig) {
12
+ throw new Error("A builder config is required for reload.");
13
+ }
14
+ await reloadRuntime({
15
+ ...(options.singBoxBin ? { singBoxBinary: options.singBoxBin } : {}),
16
+ runtime: builderConfig.runtime.reload,
17
+ });
18
+ process.stdout.write("Reloaded sing-box runtime.\n");
19
+ });
20
+ }
21
+ //# sourceMappingURL=reload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reload.js","sourceRoot":"","sources":["../../../src/cli/commands/reload.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,sCAAsC,CAAC;SACnD,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;SAC5D,MAAM,CAAC,uBAAuB,EAAE,yBAAyB,CAAC;SAC1D,MAAM,CAAC,KAAK,EAAE,OAA6B,EAAE,EAAE;QAC9C,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAC1D,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,aAAa,CAAC;YAClB,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,MAAM;SACtC,CAAC,CAAC;QAEH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerRunCommand(program: Command): void;
@@ -0,0 +1,25 @@
1
+ import { runConfig } from "../../modules/manager/index.js";
2
+ import { resolveBuilderConfig } from "../command-helpers.js";
3
+ export function registerRunCommand(program) {
4
+ program
5
+ .command("run")
6
+ .description("Run sing-box in the foreground with a generated config.")
7
+ .option("-c, --config <path>", "path to builder config YAML")
8
+ .option("-i, --input <path>", "path to config JSON to run")
9
+ .option("--sing-box-bin <path>", "path to sing-box binary")
10
+ .option("--no-check", "skip sing-box check before run")
11
+ .action(async (options) => {
12
+ const builderConfig = await resolveBuilderConfig(options);
13
+ const configPath = options.input ?? builderConfig?.output.livePath ?? builderConfig?.output.stagingPath;
14
+ if (!configPath) {
15
+ throw new Error("No config path resolved. Pass --input or provide a builder config.");
16
+ }
17
+ const exitCode = await runConfig({
18
+ configPath,
19
+ ...(options.singBoxBin ? { singBoxBinary: options.singBoxBin } : {}),
20
+ validateFirst: options.check,
21
+ });
22
+ process.exitCode = exitCode;
23
+ });
24
+ }
25
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/cli/commands/run.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,yDAAyD,CAAC;SACtE,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;SAC5D,MAAM,CAAC,oBAAoB,EAAE,4BAA4B,CAAC;SAC1D,MAAM,CAAC,uBAAuB,EAAE,yBAAyB,CAAC;SAC1D,MAAM,CAAC,YAAY,EAAE,gCAAgC,CAAC;SACtD,MAAM,CAAC,KAAK,EAAE,OAA0B,EAAE,EAAE;QAC3C,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAC1D,MAAM,UAAU,GACd,OAAO,CAAC,KAAK,IAAI,aAAa,EAAE,MAAM,CAAC,QAAQ,IAAI,aAAa,EAAE,MAAM,CAAC,WAAW,CAAC;QACvF,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;QACxF,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC;YAC/B,UAAU;YACV,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,aAAa,EAAE,OAAO,CAAC,KAAK;SAC7B,CAAC,CAAC;QAEH,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC9B,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerScheduleCommand(program: Command): void;
@@ -0,0 +1,77 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import { installLaunchdSchedule, removeLaunchdSchedule } from "../../modules/schedule/index.js";
4
+ import { findDefaultConfigPath, resolveBuilderConfig } from "../command-helpers.js";
5
+ export function registerScheduleCommand(program) {
6
+ const schedule = program.command("schedule").description("Manage macOS launchd scheduling.");
7
+ schedule
8
+ .command("install")
9
+ .description("Install a launchd job.")
10
+ .option("-c, --config <path>", "path to builder config YAML")
11
+ .option("--label <label>", "LaunchAgent label", "org.singbox-iac.update")
12
+ .option("--interval-minutes <minutes>", "override update interval in minutes")
13
+ .option("--launch-agents-dir <path>", "override LaunchAgents directory")
14
+ .option("--logs-dir <path>", "override log directory")
15
+ .option("--cwd <path>", "working directory for launchd execution")
16
+ .option("-f, --force", "replace an existing LaunchAgent file")
17
+ .option("--no-load", "write the plist without calling launchctl bootstrap")
18
+ .action(async (options) => {
19
+ const builderConfig = await resolveBuilderConfig(options);
20
+ const configPath = options.config
21
+ ? resolvePath(options.config)
22
+ : await findDefaultConfigPath();
23
+ if (!builderConfig || !configPath) {
24
+ throw new Error("schedule install requires a builder config. Pass --config or run init.");
25
+ }
26
+ const intervalMinutes = options.intervalMinutes
27
+ ? Number.parseInt(options.intervalMinutes, 10)
28
+ : builderConfig.schedule.intervalMinutes;
29
+ if (!Number.isInteger(intervalMinutes) || intervalMinutes <= 0) {
30
+ throw new Error("interval-minutes must be a positive integer.");
31
+ }
32
+ const result = await installLaunchdSchedule({
33
+ configPath,
34
+ intervalMinutes,
35
+ cliEntrypoint: resolveCliEntrypoint(import.meta.url),
36
+ label: options.label,
37
+ ...(options.launchAgentsDir
38
+ ? { launchAgentsDir: resolvePath(options.launchAgentsDir) }
39
+ : {}),
40
+ ...(options.logsDir ? { logsDir: resolvePath(options.logsDir) } : {}),
41
+ ...(options.cwd ? { workingDirectory: resolvePath(options.cwd) } : {}),
42
+ force: options.force === true,
43
+ load: options.load !== false,
44
+ });
45
+ process.stdout.write(`${[
46
+ `Label: ${result.label}`,
47
+ `Plist: ${result.plistPath}`,
48
+ `Stdout: ${result.stdoutPath}`,
49
+ `Stderr: ${result.stderrPath}`,
50
+ ].join("\n")}\n`);
51
+ });
52
+ schedule
53
+ .command("remove")
54
+ .description("Remove a launchd job.")
55
+ .option("--label <label>", "LaunchAgent label", "org.singbox-iac.update")
56
+ .option("--launch-agents-dir <path>", "override LaunchAgents directory")
57
+ .option("--no-unload", "remove the plist without calling launchctl bootout")
58
+ .action(async (options) => {
59
+ const plistPath = await removeLaunchdSchedule({
60
+ label: options.label,
61
+ ...(options.launchAgentsDir
62
+ ? { launchAgentsDir: resolvePath(options.launchAgentsDir) }
63
+ : {}),
64
+ unload: options.unload !== false,
65
+ });
66
+ process.stdout.write(`Removed: ${plistPath}\n`);
67
+ });
68
+ }
69
+ function resolvePath(filePath) {
70
+ return filePath.startsWith("/") ? filePath : path.resolve(process.cwd(), filePath);
71
+ }
72
+ function resolveCliEntrypoint(moduleUrl) {
73
+ const commandModulePath = fileURLToPath(moduleUrl);
74
+ const extension = path.extname(commandModulePath);
75
+ return path.resolve(path.dirname(commandModulePath), "..", `index${extension}`);
76
+ }
77
+ //# sourceMappingURL=schedule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule.js","sourceRoot":"","sources":["../../../src/cli/commands/schedule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerTemplatesCommand(program: Command): void;
@@ -0,0 +1,34 @@
1
+ import { getRuleTemplate, listRuleTemplates } from "../../modules/rule-templates/index.js";
2
+ export function registerTemplatesCommand(program) {
3
+ const templates = program.command("templates").description("Browse built-in rule templates.");
4
+ templates
5
+ .command("list")
6
+ .description("List available templates.")
7
+ .action(() => {
8
+ process.stdout.write(`${listRuleTemplates()
9
+ .map((template) => `${template.id}: ${template.summary}`)
10
+ .join("\n")}\n`);
11
+ });
12
+ templates
13
+ .command("show")
14
+ .description("Show one template in YAML-like form.")
15
+ .argument("<id>", "template identifier")
16
+ .action((id) => {
17
+ const template = getRuleTemplate(id);
18
+ if (!template) {
19
+ throw new Error(`Unknown template "${id}".`);
20
+ }
21
+ const lines = [
22
+ `id: ${template.id}`,
23
+ `title: ${template.title}`,
24
+ `summary: ${template.summary}`,
25
+ `tags: ${template.tags.join(", ")}`,
26
+ "beforeBuiltins:",
27
+ ...template.beforeBuiltins.map((rule) => ` - ${JSON.stringify(rule)}`),
28
+ "afterBuiltins:",
29
+ ...template.afterBuiltins.map((rule) => ` - ${JSON.stringify(rule)}`),
30
+ ];
31
+ process.stdout.write(`${lines.join("\n")}\n`);
32
+ });
33
+ }
34
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/cli/commands/templates.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAE3F,MAAM,UAAU,wBAAwB,CAAC,OAAgB;IACvD,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,iCAAiC,CAAC,CAAC;IAE9F,SAAS;SACN,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,2BAA2B,CAAC;SACxC,MAAM,CAAC,GAAG,EAAE;QACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,iBAAiB,EAAE;aACnB,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAC,EAAE,KAAK,QAAQ,CAAC,OAAO,EAAE,CAAC;aACxD,IAAI,CAAC,IAAI,CAAC,IAAI,CAClB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEL,SAAS;SACN,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,sCAAsC,CAAC;SACnD,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;SACvC,MAAM,CAAC,CAAC,EAAU,EAAE,EAAE;QACrB,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,KAAK,GAAG;YACZ,OAAO,QAAQ,CAAC,EAAE,EAAE;YACpB,UAAU,QAAQ,CAAC,KAAK,EAAE;YAC1B,YAAY,QAAQ,CAAC,OAAO,EAAE;YAC9B,SAAS,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACnC,iBAAiB;YACjB,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YACvE,gBAAgB;YAChB,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;SACvE,CAAC;QACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerUpdateCommand(program: Command): void;
@@ -0,0 +1,52 @@
1
+ import { runUpdate } from "../../modules/update/index.js";
2
+ import { resolveBuilderConfig } from "../command-helpers.js";
3
+ export function registerUpdateCommand(program) {
4
+ program
5
+ .command("update")
6
+ .description("Run build, verify, publish, and optional reload as one closed loop.")
7
+ .option("-c, --config <path>", "path to builder config YAML")
8
+ .option("--subscription-url <url>", "override subscription URL when rebuilding")
9
+ .option("--subscription-file <path>", "use a local subscription file instead of fetching")
10
+ .option("-o, --output <path>", "override staging output path")
11
+ .option("--live-path <path>", "override live config path")
12
+ .option("--backup-path <path>", "override backup config path")
13
+ .option("--sing-box-bin <path>", "path to sing-box binary")
14
+ .option("--chrome-bin <path>", "path to Chrome binary")
15
+ .option("--skip-verify", "skip the runtime verification harness before publish")
16
+ .option("--reload", "reload sing-box after publish")
17
+ .action(async (options) => {
18
+ const builderConfig = await resolveBuilderConfig(options);
19
+ if (!builderConfig) {
20
+ throw new Error("Update requires a builder config. Pass --config or create builder.config.local.yaml.");
21
+ }
22
+ const result = await runUpdate({
23
+ config: builderConfig,
24
+ ...(options.output ? { outputPath: options.output } : {}),
25
+ ...(options.livePath ? { livePath: options.livePath } : {}),
26
+ ...(options.backupPath ? { backupPath: options.backupPath } : {}),
27
+ ...(options.subscriptionFile ? { subscriptionFile: options.subscriptionFile } : {}),
28
+ ...(options.subscriptionUrl ? { subscriptionUrl: options.subscriptionUrl } : {}),
29
+ ...(options.singBoxBin ? { singBoxBinary: options.singBoxBin } : {}),
30
+ ...(options.chromeBin ? { chromeBinary: options.chromeBin } : {}),
31
+ verify: !options.skipVerify,
32
+ ...(options.reload ? { reload: true } : {}),
33
+ });
34
+ const verificationSummary = result.verification
35
+ ? `Verified scenarios: ${result.verification.scenarios.filter((scenario) => scenario.passed).length}/${result.verification.scenarios.length}`
36
+ : "Verified scenarios: skipped";
37
+ process.stdout.write(`${[
38
+ `Generated ${result.build.nodeCount} nodes.`,
39
+ `Staging: ${result.build.outputPath}`,
40
+ verificationSummary,
41
+ `Live: ${result.livePath}`,
42
+ result.backupPath ? `Backup: ${result.backupPath}` : undefined,
43
+ `Warnings: ${result.build.warnings.length}`,
44
+ ]
45
+ .filter((line) => typeof line === "string")
46
+ .join("\n")}\n`);
47
+ if (result.build.warnings.length > 0) {
48
+ process.stdout.write(`${result.build.warnings.map((warning) => `- ${warning}`).join("\n")}\n`);
49
+ }
50
+ });
51
+ }
52
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/cli/commands/update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerVerifyCommand(program: Command): void;