@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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sing-box IaC Builder contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,265 @@
1
+ # Sing-box IaC Builder
2
+
3
+ Policy-first subscription compiler for `sing-box` on macOS.
4
+
5
+ `Sing-box IaC Builder` turns fragile proxy subscriptions into deterministic, verifiable `sing-box` infrastructure. It fetches provider subscriptions, parses share links into a normalized intermediate model, compiles them with a controlled routing policy, validates the generated configuration, and applies updates safely in a headless macOS environment.
6
+
7
+ This project is built for users who have outgrown GUI clients and template patch scripts:
8
+
9
+ - Subscriptions should provide nodes, not define your whole routing architecture.
10
+ - Route priority should be explicit and testable.
11
+ - Runtime updates should be validated before they touch the live config.
12
+ - `Proxifier`, multiple listeners, AI application routing, and custom rule sets should be first-class use cases.
13
+
14
+ ## Why This Exists
15
+
16
+ Most GUI-centric workflows solve "import subscription", not "manage proxy infrastructure".
17
+
18
+ Typical pain points:
19
+
20
+ - Large provider groups with poor or unstable region segmentation
21
+ - Template- or JavaScript-based patching that breaks whenever the upstream subscription changes
22
+ - Opaque config merge behavior and hard-to-debug rule precedence issues
23
+ - High resource usage from GUI shells that should not be involved in a headless proxy runtime
24
+ - Weak support for process-aware routing, `Proxifier`, and application-specific AI egress policies
25
+
26
+ `Sing-box IaC Builder` treats `sing-box` as infrastructure:
27
+
28
+ - `subscription -> parser -> compiler -> check -> publish -> reload`
29
+ - Deterministic route ordering
30
+ - Human-friendly rule authoring
31
+ - Safe rollout with staging and validation
32
+ - macOS-first headless operation via `launchd`
33
+
34
+ ## Positioning
35
+
36
+ This is not:
37
+
38
+ - another GUI client
39
+ - an online converter
40
+ - a one-off template filler
41
+ - a generic multi-client subscription merger
42
+
43
+ This is:
44
+
45
+ - a `sing-box` configuration compiler
46
+ - a runtime-safe CLI for headless macOS setups
47
+ - a policy-first abstraction over fragile provider subscriptions
48
+ - a foundation for future natural-language rule authoring
49
+
50
+ ## How It Differs
51
+
52
+ | Dimension | Subscription Converters | GUI Clients / Launchers | Sing-box IaC Builder |
53
+ | --- | --- | --- | --- |
54
+ | Core goal | Convert one config format into another | Provide visual client UX | Compile subscriptions into managed `sing-box` infrastructure |
55
+ | Policy control | Often template-driven | Often merged inside the client | Explicit compiler-controlled route policy |
56
+ | Rule priority | Easy to drift with upstream changes | Often opaque | Fixed ordering and testable behavior |
57
+ | Runtime safety | Usually writes output only | Apply path is often hidden | `build -> check -> publish -> reload` |
58
+ | macOS headless | Usually not a focus | Usually not a focus | First-class |
59
+ | `Proxifier` / multi-listener | Rarely central | Awkward to maintain | Core scenario |
60
+ | AI app routing | Usually manual | Possible but brittle | Policy-level capability |
61
+ | User customization | Template edits / scripts | GUI clicks / raw config edits | Declarative DSL, later NL-to-DSL |
62
+
63
+ ## Implemented Today
64
+
65
+ The current repository is already beyond Phase 0. It includes:
66
+
67
+ - Base64 Trojan subscription fetching and parsing
68
+ - `sing-box` config compilation with fixed route ordering
69
+ - runtime-safe commands: `build`, `check`, `apply`, `run`, `verify`, `update`
70
+ - config-driven route verification with real `sing-box` and headless Chrome
71
+ - simple YAML user-rules DSL with protected insertion points
72
+ - built-in rule templates for common developer and video-site patterns
73
+ - natural-language authoring that generates DSL, builds config, can install `launchd`, and can optionally probe local AI CLIs
74
+ - macOS helper commands: `init`, `doctor`, `schedule install`, `schedule remove`
75
+
76
+ ## Install
77
+
78
+ For local dogfooding today, the CLI can already be installed from a packed tarball:
79
+
80
+ ```bash
81
+ npm pack
82
+ npm install -g ./singbox-iac-cli-0.1.0.tgz
83
+ singbox-iac --help
84
+ ```
85
+
86
+ For repository-based installs during development:
87
+
88
+ ```bash
89
+ npm install
90
+ npm run build
91
+ npx singbox-iac --help
92
+ ```
93
+
94
+ The package name is now aligned to the intended public scope, but the repository still stays `"private": true` until the first real publish. The distribution shape is already prepared for npm publishing:
95
+
96
+ - Node shebang on the compiled CLI entrypoint
97
+ - `dist`-only package contents plus docs/examples
98
+ - `prepare` and `prepack` build hooks
99
+ - `bin` and `exports` metadata
100
+
101
+ For a full repeatable distribution smoke, run:
102
+
103
+ ```bash
104
+ npm run release:check
105
+ ```
106
+
107
+ That command executes:
108
+
109
+ - `npm run typecheck`
110
+ - `npm run lint`
111
+ - `npm test`
112
+ - `npm run build`
113
+ - `npm pack`
114
+ - clean-directory install smoke with `singbox-iac --help`
115
+
116
+ On success it cleans up the tarball and temp install directory. On failure it keeps them for debugging.
117
+
118
+ For a publish-level dry run without changing the repository's `"private": true` setting:
119
+
120
+ ```bash
121
+ npm run release:dry-run
122
+ ```
123
+
124
+ That command stages a temporary publishable package copy and runs `npm publish --dry-run`. You can also test a future public package name without editing `package.json`:
125
+
126
+ ```bash
127
+ SINGBOX_IAC_PACKAGE_NAME=@singbox-iac/experimental-cli npm run release:dry-run
128
+ ```
129
+
130
+ Detailed publish notes are in [Releasing](/Users/lvyuanfang/Code/SingBoxConfig/docs/releasing.md).
131
+
132
+ ## Planned CLI
133
+
134
+ ```bash
135
+ singbox-iac init
136
+ singbox-iac author
137
+ singbox-iac build
138
+ singbox-iac apply
139
+ singbox-iac update
140
+ singbox-iac doctor
141
+ singbox-iac schedule install
142
+ singbox-iac schedule remove
143
+ singbox-iac templates list
144
+ ```
145
+
146
+ ## Project Status
147
+
148
+ The project is currently at a usable MVP-plus stage:
149
+
150
+ - real subscription ingestion works
151
+ - real route verification works
152
+ - real publish flow works
153
+ - simple rule DSL works
154
+ - macOS launchd integration is available
155
+
156
+ The highest-value remaining areas are:
157
+
158
+ - more protocol support beyond Trojan
159
+ - first real npm publish and release automation
160
+
161
+ ## Authoring Shortcuts
162
+
163
+ For day-to-day usage, the practical authoring stack is:
164
+
165
+ - built-in policy for protected routes
166
+ - Proxifier for process-aware IDE and app routing
167
+ - built-in templates for common developer and video-site rules
168
+ - natural-language prompts for fast generation
169
+ - YAML DSL only for small exceptions
170
+
171
+ Docs:
172
+
173
+ - [Rules DSL](/Users/lvyuanfang/Code/SingBoxConfig/docs/rules-dsl.md)
174
+ - [Rule Templates](/Users/lvyuanfang/Code/SingBoxConfig/docs/rule-templates.md)
175
+ - [Natural-Language Authoring](/Users/lvyuanfang/Code/SingBoxConfig/docs/natural-language-authoring.md)
176
+
177
+ ## Local AI CLI Support
178
+
179
+ This project does not require API keys for authoring.
180
+
181
+ The recommended flow is:
182
+
183
+ - default to deterministic local authoring
184
+ - optionally probe a local AI CLI with `provider=auto`
185
+ - optionally integrate any other CLI through `provider=exec`
186
+ - use `author --preview` before writing when changing prompts or providers
187
+ - always validate and compile through the same DSL and `sing-box` pipeline
188
+
189
+ Current support model:
190
+
191
+ - built-in provider:
192
+ - `claude`
193
+ - generic `exec` integrations:
194
+ - `gemini`
195
+ - `codebuddy`
196
+ - `codex`
197
+ - `opencode`
198
+ - `qodercli` / `qoder`
199
+ - tooling-only detection:
200
+ - `trae`
201
+
202
+ The project should not hard-code every AI CLI vendor. Instead:
203
+
204
+ - keep one or two verified built-ins
205
+ - support broad developer tooling through `provider=exec`
206
+ - allow wrapper scripts for CLIs with noisy or event-stream output
207
+
208
+ The `exec` adapter already supports:
209
+
210
+ - `{{prompt}}`
211
+ - `{{schema}}`
212
+ - `{{context_json}}`
213
+ - `{{full_prompt}}`
214
+ - `{{schema_file}}`
215
+ - `{{output_file}}`
216
+
217
+ and will accept:
218
+
219
+ - exact JSON stdout
220
+ - fenced JSON blocks
221
+ - a balanced JSON object extracted from longer text
222
+ - output written to `{{output_file}}`
223
+
224
+ This is the compatibility layer that makes “support most AI CLIs” practical without turning the project into a vendor-specific adapter zoo.
225
+
226
+ Natural-language authoring is now intent-first for common developer use cases. The user does not need to know the DSL or internal selector names for routine requests such as:
227
+
228
+ - `GitHub 这类开发类都走香港出口`
229
+ - `Antigravity 进程级都走独立入口并路由到美国节点`
230
+ - `Gemini 都出口到新加坡`
231
+
232
+ The authoring layer can compile those sentences into:
233
+
234
+ - explicit site rules
235
+ - selector default changes
236
+ - verification expectation updates
237
+
238
+ so the normal `author -> build -> verify` pipeline still stays consistent.
239
+
240
+ It also understands more mainstream subscription vocabulary, for example:
241
+
242
+ - `Google 服务和 GitHub 这类开发类都走香港`
243
+ - `Apple 服务走香港`
244
+ - `Amazon Prime 和 Apple TV 走新加坡`
245
+ - `视频网站走美国`
246
+
247
+ And it can now go all the way to publish from one sentence:
248
+
249
+ ```bash
250
+ ./node_modules/.bin/tsx src/cli/index.ts author \
251
+ --config ./builder.config.local.yaml \
252
+ --provider deterministic \
253
+ --prompt "Google 服务和 GitHub 这类开发类都走香港,Gemini 走新加坡,Antigravity 进程级走美国,每30分钟自动更新" \
254
+ --update
255
+ ```
256
+
257
+ See:
258
+
259
+ - [Natural-Language Authoring](/Users/lvyuanfang/Code/SingBoxConfig/docs/natural-language-authoring.md)
260
+
261
+ ## References
262
+
263
+ - [OpenSpec](https://openspec.pro/)
264
+ - [sing-box documentation](https://sing-box.sagernet.org/configuration/)
265
+ - [sing-box migration guide](https://sing-box.sagernet.org/migration/)
@@ -0,0 +1,6 @@
1
+ import type { BuilderConfig } from "../config/schema.js";
2
+ export interface SharedCommandOptions {
3
+ readonly config?: string;
4
+ }
5
+ export declare function resolveBuilderConfig(options: SharedCommandOptions): Promise<BuilderConfig | undefined>;
6
+ export declare function findDefaultConfigPath(): Promise<string | undefined>;
@@ -0,0 +1,34 @@
1
+ import { constants } from "node:fs";
2
+ import { access } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { loadConfig } from "../config/load-config.js";
5
+ const defaultConfigCandidates = ["builder.config.local.yaml", "builder.config.yaml"];
6
+ export async function resolveBuilderConfig(options) {
7
+ if (options.config) {
8
+ return loadConfig(options.config);
9
+ }
10
+ const configPath = await findDefaultConfigPath();
11
+ if (!configPath) {
12
+ return undefined;
13
+ }
14
+ return loadConfig(configPath);
15
+ }
16
+ export async function findDefaultConfigPath() {
17
+ for (const candidate of defaultConfigCandidates) {
18
+ const filePath = path.resolve(process.cwd(), candidate);
19
+ if (await fileExists(filePath)) {
20
+ return filePath;
21
+ }
22
+ }
23
+ return undefined;
24
+ }
25
+ async function fileExists(filePath) {
26
+ try {
27
+ await access(filePath, constants.F_OK);
28
+ return true;
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ //# sourceMappingURL=command-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-helpers.js","sourceRoot":"","sources":["../../src/cli/command-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAGtD,MAAM,uBAAuB,GAAG,CAAC,2BAA2B,EAAE,qBAAqB,CAAC,CAAC;AAMrF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAA6B;IAE7B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,qBAAqB,EAAE,CAAC;IACjD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,UAAU,CAAC,UAAU,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,KAAK,MAAM,SAAS,IAAI,uBAAuB,EAAE,CAAC;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;QACxD,IAAI,MAAM,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerApplyCommand(program: Command): void;
@@ -0,0 +1,32 @@
1
+ import { applyConfig } from "../../modules/manager/index.js";
2
+ import { resolveBuilderConfig } from "../command-helpers.js";
3
+ export function registerApplyCommand(program) {
4
+ program
5
+ .command("apply")
6
+ .description("Validate and publish the latest generated config.")
7
+ .option("-c, --config <path>", "path to builder config YAML")
8
+ .option("-i, --input <path>", "path to staging config JSON")
9
+ .option("--live-path <path>", "override live config path")
10
+ .option("--backup-path <path>", "override backup config path")
11
+ .option("--sing-box-bin <path>", "path to sing-box binary")
12
+ .option("--reload", "reload sing-box after publish")
13
+ .action(async (options) => {
14
+ const builderConfig = await resolveBuilderConfig(options);
15
+ const stagingPath = options.input ?? builderConfig?.output.stagingPath;
16
+ const livePath = options.livePath ?? builderConfig?.output.livePath;
17
+ const backupPath = options.backupPath ?? builderConfig?.output.backupPath;
18
+ if (!stagingPath || !livePath) {
19
+ throw new Error("Unable to resolve staging/live paths. Pass --input/--live-path or provide a builder config.");
20
+ }
21
+ await applyConfig({
22
+ stagingPath,
23
+ livePath,
24
+ ...(backupPath ? { backupPath } : {}),
25
+ ...(options.singBoxBin ? { singBoxBinary: options.singBoxBin } : {}),
26
+ ...(options.reload !== undefined ? { reload: options.reload } : {}),
27
+ ...(builderConfig?.runtime.reload ? { runtime: builderConfig.runtime.reload } : {}),
28
+ });
29
+ process.stdout.write(`Applied config.\nSource: ${stagingPath}\nLive: ${livePath}\n${backupPath ? `Backup: ${backupPath}\n` : ""}`);
30
+ });
31
+ }
32
+ //# sourceMappingURL=apply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/cli/commands/apply.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,mDAAmD,CAAC;SAChE,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;SAC5D,MAAM,CAAC,oBAAoB,EAAE,6BAA6B,CAAC;SAC3D,MAAM,CAAC,oBAAoB,EAAE,2BAA2B,CAAC;SACzD,MAAM,CAAC,sBAAsB,EAAE,6BAA6B,CAAC;SAC7D,MAAM,CAAC,uBAAuB,EAAE,yBAAyB,CAAC;SAC1D,MAAM,CAAC,UAAU,EAAE,+BAA+B,CAAC;SACnD,MAAM,CAAC,KAAK,EAAE,OAA4B,EAAE,EAAE;QAC7C,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAC1D,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,IAAI,aAAa,EAAE,MAAM,CAAC,WAAW,CAAC;QACvE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC;QACpE,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC;QAE1E,IAAI,CAAC,WAAW,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CACb,6FAA6F,CAC9F,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,CAAC;YAChB,WAAW;YACX,QAAQ;YACR,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,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnE,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpF,CAAC,CAAC;QAEH,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,4BAA4B,WAAW,WAAW,QAAQ,KACxD,UAAU,CAAC,CAAC,CAAC,WAAW,UAAU,IAAI,CAAC,CAAC,CAAC,EAC3C,EAAE,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerAuthorCommand(program: Command): void;
@@ -0,0 +1,194 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import { generateAuthoringPlan } from "../../modules/authoring/index.js";
4
+ import { buildConfigArtifact } from "../../modules/build/index.js";
5
+ import { applyPlanToBuilderConfig, updateBuilderAuthoring, writeGeneratedRules, } from "../../modules/natural-language/index.js";
6
+ import { generateAuthoringPreview } from "../../modules/preview/index.js";
7
+ import { installLaunchdSchedule } from "../../modules/schedule/index.js";
8
+ import { runUpdate } from "../../modules/update/index.js";
9
+ import { findDefaultConfigPath, resolveBuilderConfig } from "../command-helpers.js";
10
+ export function registerAuthorCommand(program) {
11
+ program
12
+ .command("author")
13
+ .description("Generate custom rules from a natural-language prompt, then optionally build and schedule.")
14
+ .requiredOption("-p, --prompt <text>", "natural-language routing prompt")
15
+ .option("-c, --config <path>", "path to builder config YAML")
16
+ .option("--provider <provider>", "authoring provider: deterministic, auto, claude, exec")
17
+ .option("--author-timeout-ms <ms>", "timeout for local AI CLI authoring")
18
+ .option("--exec-command <command>", "command for the exec authoring provider")
19
+ .option("--exec-arg <arg>", "append one argument for the exec authoring provider", collectOption, [])
20
+ .option("--rules-out <path>", "override the target custom-rules file")
21
+ .option("--subscription-url <url>", "override subscription URL when building")
22
+ .option("--subscription-file <path>", "use a local subscription file instead of fetching")
23
+ .option("--preview", "print rules/config/staging diffs without writing any files")
24
+ .option("--skip-build", "write rules only and skip config generation")
25
+ .option("--update", "after writing rules, run build + verify + publish")
26
+ .option("--skip-verify", "when used with --update, skip runtime verification before publish")
27
+ .option("--reload", "when used with --update, reload sing-box after publish")
28
+ .option("--live-path <path>", "override live config path when using --update")
29
+ .option("--backup-path <path>", "override backup config path when using --update")
30
+ .option("--sing-box-bin <path>", "path to sing-box binary")
31
+ .option("--chrome-bin <path>", "path to Chrome binary for runtime verification")
32
+ .option("--install-schedule", "install a launchd job after writing rules and building")
33
+ .option("--label <label>", "LaunchAgent label", "org.singbox-iac.update")
34
+ .option("--launch-agents-dir <path>", "override LaunchAgents directory")
35
+ .option("--logs-dir <path>", "override launchd log directory")
36
+ .option("-f, --force-schedule", "replace an existing LaunchAgent file when installing")
37
+ .option("--no-load", "write the LaunchAgent without calling launchctl bootstrap")
38
+ .action(async (options) => {
39
+ const [builderConfig, configPath] = await Promise.all([
40
+ resolveBuilderConfig(options),
41
+ options.config ? Promise.resolve(resolvePath(options.config)) : findDefaultConfigPath(),
42
+ ]);
43
+ if (!builderConfig || !configPath) {
44
+ throw new Error("author requires a builder config. Pass --config or run init first.");
45
+ }
46
+ if (options.update && options.skipBuild) {
47
+ throw new Error("author cannot use --update together with --skip-build.");
48
+ }
49
+ const planResult = await generateAuthoringPlan({
50
+ prompt: options.prompt,
51
+ config: builderConfig,
52
+ ...(options.provider ? { provider: options.provider } : {}),
53
+ ...(options.authorTimeoutMs
54
+ ? { timeoutMs: Number.parseInt(options.authorTimeoutMs, 10) }
55
+ : {}),
56
+ ...(options.execCommand ? { execCommand: options.execCommand } : {}),
57
+ ...(options.execArg.length > 0 ? { execArgs: options.execArg } : {}),
58
+ });
59
+ const plan = planResult.plan;
60
+ const rulesPath = options.rulesOut
61
+ ? resolvePath(options.rulesOut)
62
+ : builderConfig.rules.userRulesFile;
63
+ const effectiveConfig = applyPlanToBuilderConfig(builderConfig, {
64
+ rulesPath,
65
+ plan,
66
+ });
67
+ if (options.preview) {
68
+ const preview = await generateAuthoringPreview({
69
+ configPath,
70
+ config: builderConfig,
71
+ plan,
72
+ rulesPath,
73
+ ...(options.subscriptionFile ? { subscriptionFile: options.subscriptionFile } : {}),
74
+ ...(options.subscriptionUrl ? { subscriptionUrl: options.subscriptionUrl } : {}),
75
+ buildStaging: !options.skipBuild,
76
+ });
77
+ const lines = [
78
+ `Config: ${configPath}`,
79
+ `Rules: ${rulesPath}`,
80
+ `Provider requested: ${planResult.providerRequested}`,
81
+ `Provider used: ${planResult.providerUsed}`,
82
+ `Templates: ${plan.templateIds.length > 0 ? plan.templateIds.join(", ") : "(none)"}`,
83
+ `Generated rules: ${plan.beforeBuiltins.length + plan.afterBuiltins.length}`,
84
+ "Preview mode: no files were written.",
85
+ ];
86
+ if (plan.notes.length > 0) {
87
+ lines.push(`Notes: ${plan.notes.length}`);
88
+ lines.push(...plan.notes.map((note) => `- ${note}`));
89
+ }
90
+ if (options.installSchedule) {
91
+ lines.push("Schedule install: requested, but skipped in preview mode.");
92
+ }
93
+ if (options.update) {
94
+ lines.push("Live update: requested, but skipped in preview mode.");
95
+ }
96
+ lines.push("");
97
+ lines.push("Rules diff:");
98
+ lines.push(preview.rulesDiff.diff);
99
+ lines.push("");
100
+ lines.push("Builder config diff:");
101
+ lines.push(preview.configDiff.diff);
102
+ if (preview.stagingDiff) {
103
+ lines.push("");
104
+ lines.push("Staging config diff:");
105
+ lines.push(preview.stagingDiff.diff);
106
+ }
107
+ process.stdout.write(`${lines.join("\n")}\n`);
108
+ return;
109
+ }
110
+ await writeGeneratedRules({
111
+ filePath: rulesPath,
112
+ plan,
113
+ });
114
+ await updateBuilderAuthoring({
115
+ configPath,
116
+ rulesPath,
117
+ ...(plan.scheduleIntervalMinutes ? { intervalMinutes: plan.scheduleIntervalMinutes } : {}),
118
+ ...(plan.groupDefaults ? { groupDefaults: plan.groupDefaults } : {}),
119
+ ...(plan.verificationOverrides
120
+ ? { verificationOverrides: plan.verificationOverrides }
121
+ : {}),
122
+ });
123
+ const lines = [
124
+ `Config: ${configPath}`,
125
+ `Rules: ${rulesPath}`,
126
+ `Provider requested: ${planResult.providerRequested}`,
127
+ `Provider used: ${planResult.providerUsed}`,
128
+ `Templates: ${plan.templateIds.length > 0 ? plan.templateIds.join(", ") : "(none)"}`,
129
+ `Generated rules: ${plan.beforeBuiltins.length + plan.afterBuiltins.length}`,
130
+ ];
131
+ if (plan.notes.length > 0) {
132
+ lines.push(`Notes: ${plan.notes.length}`);
133
+ lines.push(...plan.notes.map((note) => `- ${note}`));
134
+ }
135
+ if (options.installSchedule) {
136
+ const intervalMinutes = plan.scheduleIntervalMinutes ?? effectiveConfig.schedule.intervalMinutes;
137
+ const schedule = await installLaunchdSchedule({
138
+ configPath,
139
+ intervalMinutes,
140
+ cliEntrypoint: resolveCliEntrypoint(import.meta.url),
141
+ label: options.label,
142
+ ...(options.launchAgentsDir
143
+ ? { launchAgentsDir: resolvePath(options.launchAgentsDir) }
144
+ : {}),
145
+ ...(options.logsDir ? { logsDir: resolvePath(options.logsDir) } : {}),
146
+ force: options.forceSchedule === true,
147
+ load: options.load !== false,
148
+ });
149
+ lines.push(`LaunchAgent: ${schedule.plistPath}`);
150
+ }
151
+ if (options.update) {
152
+ const updateResult = await runUpdate({
153
+ config: effectiveConfig,
154
+ ...(options.subscriptionFile ? { subscriptionFile: options.subscriptionFile } : {}),
155
+ ...(options.subscriptionUrl ? { subscriptionUrl: options.subscriptionUrl } : {}),
156
+ ...(options.livePath ? { livePath: resolvePath(options.livePath) } : {}),
157
+ ...(options.backupPath ? { backupPath: resolvePath(options.backupPath) } : {}),
158
+ ...(options.singBoxBin ? { singBoxBinary: resolvePath(options.singBoxBin) } : {}),
159
+ ...(options.chromeBin ? { chromeBinary: resolvePath(options.chromeBin) } : {}),
160
+ verify: !options.skipVerify,
161
+ ...(options.reload ? { reload: true } : {}),
162
+ });
163
+ lines.push(`Staging: ${updateResult.build.outputPath}`);
164
+ lines.push(updateResult.verification
165
+ ? `Verified scenarios: ${updateResult.verification.scenarios.filter((scenario) => scenario.passed).length}/${updateResult.verification.scenarios.length}`
166
+ : "Verified scenarios: skipped");
167
+ lines.push(`Live: ${updateResult.livePath}`);
168
+ if (updateResult.backupPath) {
169
+ lines.push(`Backup: ${updateResult.backupPath}`);
170
+ }
171
+ }
172
+ else if (!options.skipBuild) {
173
+ const build = await buildConfigArtifact({
174
+ config: effectiveConfig,
175
+ ...(options.subscriptionFile ? { subscriptionFile: options.subscriptionFile } : {}),
176
+ ...(options.subscriptionUrl ? { subscriptionUrl: options.subscriptionUrl } : {}),
177
+ });
178
+ lines.push(`Staging: ${build.outputPath}`);
179
+ }
180
+ process.stdout.write(`${lines.join("\n")}\n`);
181
+ });
182
+ }
183
+ function resolvePath(filePath) {
184
+ return filePath.startsWith("/") ? filePath : path.resolve(process.cwd(), filePath);
185
+ }
186
+ function resolveCliEntrypoint(moduleUrl) {
187
+ const commandModulePath = fileURLToPath(moduleUrl);
188
+ const extension = path.extname(commandModulePath);
189
+ return path.resolve(path.dirname(commandModulePath), "..", `index${extension}`);
190
+ }
191
+ function collectOption(value, previous) {
192
+ return [...previous, value];
193
+ }
194
+ //# sourceMappingURL=author.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"author.js","sourceRoot":"","sources":["../../../src/cli/commands/author.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerBuildCommand(program: Command): void;