@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,122 @@
1
+ # Rule Templates
2
+
3
+ Built-in rule templates are intended to cover the repetitive cases that most developer-oriented setups run into:
4
+
5
+ - third-party AI sites
6
+ - common third-party developer tooling sites
7
+ - international video sites that should exit through a specific region
8
+ - mainland video sites that should stay direct
9
+
10
+ Templates are not a replacement for the compiler's built-in policy. They sit on top of it and are meant for fast customization.
11
+
12
+ ## Current Templates
13
+
14
+ ### Developer
15
+
16
+ - `developer-ai-sites`
17
+ Routes common third-party AI sites to `AI-Out`.
18
+ Includes:
19
+ - `openrouter.ai`
20
+ - `perplexity.ai`
21
+
22
+ - `developer-common-sites`
23
+ Routes common third-party developer sites to `Dev-Common-Out`.
24
+ Includes:
25
+ - `gitlab.com`
26
+ - `npmjs.com`
27
+ - `registry.npmjs.org`
28
+ - `vercel.com`
29
+ - `cloudflare.com`
30
+ - `docker.com`
31
+ - `hub.docker.com`
32
+ - `stackoverflow.com`
33
+ - `huggingface.co`
34
+
35
+ ### Video
36
+
37
+ - `video-us`
38
+ Routes international streaming sites to `US`.
39
+
40
+ - `video-hk`
41
+ Routes international streaming sites to `HK`.
42
+
43
+ - `video-sg`
44
+ Routes international streaming sites to `SG`.
45
+
46
+ - `video-jp`
47
+ Routes Japan-oriented video sites to `JP`.
48
+
49
+ - `cn-video-direct`
50
+ Keeps common mainland video sites on `direct`.
51
+
52
+ The international streaming templates currently cover:
53
+
54
+ - `youtube.com`
55
+ - `youtu.be`
56
+ - `netflix.com`
57
+ - `nflxvideo.net`
58
+ - `disneyplus.com`
59
+ - `disney-plus.net`
60
+ - `hulu.com`
61
+ - `max.com`
62
+ - `twitch.tv`
63
+
64
+ The JP template currently covers:
65
+
66
+ - `abema.tv`
67
+ - `niconico.jp`
68
+ - `dmm.com`
69
+ - `lemino.docomo.ne.jp`
70
+
71
+ The CN direct template currently covers:
72
+
73
+ - `bilibili.com`
74
+ - `bilibili.tv`
75
+ - `iqiyi.com`
76
+ - `iq.com`
77
+ - `youku.com`
78
+ - `mgtv.com`
79
+
80
+ ## CLI Usage
81
+
82
+ List templates:
83
+
84
+ ```bash
85
+ ./node_modules/.bin/tsx src/cli/index.ts templates list
86
+ ```
87
+
88
+ Show one template:
89
+
90
+ ```bash
91
+ ./node_modules/.bin/tsx src/cli/index.ts templates show video-sg
92
+ ```
93
+
94
+ ## Natural-Language Mapping
95
+
96
+ The `author` command can infer templates from short prompts.
97
+
98
+ Examples:
99
+
100
+ - `开发者网站走香港,视频网站走新加坡`
101
+ - `AI 工具走香港,视频网站走美国,每45分钟自动更新`
102
+ - `国内视频网站直连,YouTube Netflix 走美国`
103
+
104
+ Typical mapping behavior:
105
+
106
+ - `开发者网站` -> `developer-common-sites`
107
+ - `AI 工具` -> `developer-ai-sites`
108
+ - `视频网站走美国` -> `video-us`
109
+ - `视频网站走香港` -> `video-hk`
110
+ - `视频网站走新加坡` -> `video-sg`
111
+ - `日本视频网站` -> `video-jp`
112
+ - `国内视频网站直连` -> `cn-video-direct`
113
+
114
+ ## Design Boundary
115
+
116
+ Templates are intentionally coarse-grained. They are best for:
117
+
118
+ - "a whole class of sites should go to one region"
119
+ - "these common developer sites should use the developer selector"
120
+ - "these common AI sites should use the AI selector"
121
+
122
+ If a user needs one-off exceptions, prefer the DSL instead of adding more template complexity.
@@ -0,0 +1,107 @@
1
+ # Rules DSL
2
+
3
+ ## Design Goal
4
+
5
+ Users should customize routing intent without editing raw `sing-box` JSON.
6
+
7
+ ## Layers
8
+
9
+ ### Layer 1: Built-in system rules
10
+
11
+ These are protected invariants controlled by the compiler, such as:
12
+
13
+ - QUIC kill-switch for `udp:443`
14
+ - DNS handling
15
+ - `in-proxifier` high-priority routing
16
+
17
+ These rules always stay ahead of user rules.
18
+
19
+ ### Layer 2: Declarative user rules
20
+
21
+ Users write a small YAML DSL with only two insertion points:
22
+
23
+ - `beforeBuiltins`
24
+ Inserted after protected system rules and before built-in service rules such as Stitch, OpenAI, AI rule sets, and developer rule sets.
25
+ - `afterBuiltins`
26
+ Inserted after built-in service rules and before China direct rules.
27
+
28
+ ## File Shape
29
+
30
+ ```yaml
31
+ version: 1
32
+
33
+ beforeBuiltins:
34
+ - name: "OpenRouter uses AI"
35
+ domainSuffix:
36
+ - "openrouter.ai"
37
+ route: "AI-Out"
38
+
39
+ afterBuiltins:
40
+ - name: "Example mainland domain stays direct"
41
+ domainSuffix:
42
+ - "intranet.example.cn"
43
+ route: "direct"
44
+ ```
45
+
46
+ ## Supported Matchers
47
+
48
+ Each rule may use one or more of these fields:
49
+
50
+ - `inbound`
51
+ - `protocol`
52
+ - `network`
53
+ - `port`
54
+ - `domain`
55
+ - `domainSuffix`
56
+ - `ruleSet`
57
+
58
+ Scalar values are allowed for convenience. These are normalized to arrays where needed.
59
+
60
+ ## Supported Actions
61
+
62
+ - `route: "<outbound-or-group-tag>"`
63
+ - `action: "reject"`
64
+
65
+ Examples:
66
+
67
+ ```yaml
68
+ version: 1
69
+
70
+ beforeBuiltins:
71
+ - name: "OpenRouter uses the AI selector"
72
+ domainSuffix: "openrouter.ai"
73
+ route: "AI-Out"
74
+
75
+ - name: "Block a specific UDP port"
76
+ inbound: "in-mixed"
77
+ network: "udp"
78
+ port: 443
79
+ action: "reject"
80
+ ```
81
+
82
+ ## Guardrails
83
+
84
+ - Every rule must define at least one matcher.
85
+ - Every rule must define exactly one action.
86
+ - Route targets must refer to an existing outbound or selector such as `AI-Out`, `HK`, `US`, `direct`, or `Global`.
87
+ - `ruleSet` matchers must refer to configured and active rule-set tags.
88
+ - User rules cannot be inserted ahead of protected system rules.
89
+
90
+ ## Layer 3: Natural language to DSL
91
+
92
+ Natural-language authoring is now implemented as a separate front door. It still follows the same safety model:
93
+
94
+ - prompt -> generated DSL
95
+ - generated DSL -> validated user rules
96
+ - validated user rules -> compiled `sing-box` config
97
+ - optional schedule install only when explicitly requested
98
+
99
+ See:
100
+
101
+ - `/Users/lvyuanfang/Code/SingBoxConfig/docs/natural-language-authoring.md`
102
+ - `/Users/lvyuanfang/Code/SingBoxConfig/docs/rule-templates.md`
103
+
104
+ ## Non-Goals for v1
105
+
106
+ - direct natural-language writes to live config
107
+ - arbitrary raw JSON mutation
@@ -0,0 +1,42 @@
1
+ # Runtime on macOS
2
+
3
+ ## Runtime Goal
4
+
5
+ The target runtime is a headless macOS deployment:
6
+
7
+ - `sing-box` installed separately
8
+ - this CLI generates and validates config
9
+ - `launchd` handles periodic updates
10
+
11
+ ## Planned Flow
12
+
13
+ 1. Generate a staging config
14
+ 2. Run `sing-box check -c <staging>`
15
+ 3. If valid, publish to the live path
16
+ 4. Reload `sing-box`
17
+ 5. Keep the last-known-good config for recovery
18
+
19
+ ## Current CLI Flow
20
+
21
+ ```bash
22
+ singbox-iac init
23
+ singbox-iac doctor
24
+ singbox-iac build
25
+ singbox-iac verify
26
+ singbox-iac update
27
+ singbox-iac schedule install
28
+ ```
29
+
30
+ ## Launchd Notes
31
+
32
+ - In source-tree development, `schedule install` emits a LaunchAgent that runs `node_modules/.bin/tsx src/cli/index.ts update --config <path>`.
33
+ - In built distributions, the same logic emits a LaunchAgent that runs the compiled CLI entrypoint with `node`.
34
+ - Use `--no-load` during testing to validate the generated plist without calling `launchctl bootstrap`.
35
+
36
+ ## Why `launchd`
37
+
38
+ For macOS, `launchd` is the correct scheduler primitive. It integrates better with user sessions than `cron` and matches the product's OS target.
39
+
40
+ ## Runtime Safety
41
+
42
+ The tool must never overwrite the live config with an unchecked file.
@@ -0,0 +1,39 @@
1
+ # sing-box Config Primer
2
+
3
+ ## Top-Level Areas
4
+
5
+ The generated config will primarily work with:
6
+
7
+ - `dns`
8
+ - `inbounds`
9
+ - `outbounds`
10
+ - `route`
11
+
12
+ ## Product Model
13
+
14
+ This project will generate:
15
+
16
+ - fixed inbound listeners
17
+ - dynamic proxy outbounds derived from subscriptions
18
+ - dynamic selector and `urltest` groups
19
+ - rule sets and route rules assembled with stable precedence
20
+
21
+ ## Compatibility Direction
22
+
23
+ Target `sing-box` version:
24
+
25
+ - `1.8.x` or newer, with preference for current rule set and rule action formats
26
+
27
+ The implementation should prefer:
28
+
29
+ - external `rule_set` references
30
+ - current route actions
31
+ - avoiding deprecated legacy structures where newer forms exist
32
+
33
+ ## Key Invariants
34
+
35
+ - `udp:443` rejection must stay near the top of route processing
36
+ - DNS handling must happen before ordinary traffic policy
37
+ - `in-proxifier` traffic must have absolute precedence over later domain-based rules
38
+ - China direct-routing rules must remain after higher-priority process and AI rules
39
+
@@ -0,0 +1,38 @@
1
+ # Subscription Format Primer
2
+
3
+ ## Reality of Provider Subscriptions
4
+
5
+ Provider subscriptions are not a `sing-box` native format. In practice they are ecosystem-specific feeds that commonly look like:
6
+
7
+ 1. an HTTP endpoint
8
+ 2. returning a Base64-encoded payload
9
+ 3. which decodes into plain text
10
+ 4. where each line is a share-link URI
11
+
12
+ Example:
13
+
14
+ ```text
15
+ trojan://password@host:443?sni=example.com#HK-01
16
+ ```
17
+
18
+ ## Implication for This Project
19
+
20
+ This project should not treat provider subscriptions as a final configuration format. It should treat them as a source of nodes to parse into an intermediate representation.
21
+
22
+ Pipeline:
23
+
24
+ `fetch -> decode -> parse -> normalize -> compile`
25
+
26
+ ## Phase 1 Scope
27
+
28
+ Phase 1 supports:
29
+
30
+ - Base64 line-based subscriptions
31
+ - `trojan://` share links
32
+
33
+ Later phases may support:
34
+
35
+ - `vless://`
36
+ - `vmess://`
37
+ - `hysteria2://`
38
+
@@ -0,0 +1,220 @@
1
+ version: 1
2
+
3
+ subscription:
4
+ url: "https://example.com/subscription"
5
+ format: "base64-lines"
6
+ protocols:
7
+ - trojan
8
+
9
+ output:
10
+ stagingPath: "~/.config/singbox-iac/generated/config.staging.json"
11
+ livePath: "~/.config/sing-box/config.json"
12
+ backupPath: "~/.config/singbox-iac/generated/config.last-known-good.json"
13
+
14
+ runtime:
15
+ checkCommand: "sing-box check -c {{stagingPath}}"
16
+ reload:
17
+ kind: "signal"
18
+ processName: "sing-box"
19
+ signal: "HUP"
20
+
21
+ listeners:
22
+ mixed:
23
+ enabled: true
24
+ listen: "127.0.0.1"
25
+ port: 39097
26
+ proxifier:
27
+ enabled: true
28
+ listen: "127.0.0.1"
29
+ port: 39091
30
+
31
+ ruleSets:
32
+ - tag: "geosite-cn"
33
+ format: "binary"
34
+ type: "local"
35
+ path: "~/.config/sing-box/rule-set/geosite-cn.srs"
36
+ - tag: "geoip-cn"
37
+ format: "binary"
38
+ type: "local"
39
+ path: "~/.config/sing-box/rule-set/geoip-cn.srs"
40
+ - tag: "geosite-google"
41
+ format: "binary"
42
+ type: "local"
43
+ path: "~/.config/sing-box/rule-set/geosite-google.srs"
44
+ - tag: "geosite-google-gemini"
45
+ format: "binary"
46
+ type: "local"
47
+ path: "~/.config/sing-box/rule-set/geosite-google-gemini.srs"
48
+ - tag: "geosite-google-deepmind"
49
+ format: "binary"
50
+ type: "local"
51
+ path: "~/.config/sing-box/rule-set/geosite-google-deepmind.srs"
52
+ - tag: "geosite-anthropic"
53
+ format: "binary"
54
+ type: "local"
55
+ path: "~/.config/sing-box/rule-set/geosite-anthropic.srs"
56
+ - tag: "geosite-github"
57
+ format: "binary"
58
+ type: "local"
59
+ path: "~/.config/sing-box/rule-set/geosite-github.srs"
60
+ - tag: "geosite-github-copilot"
61
+ format: "binary"
62
+ type: "local"
63
+ path: "~/.config/sing-box/rule-set/geosite-github-copilot.srs"
64
+ - tag: "geosite-cursor"
65
+ format: "binary"
66
+ type: "local"
67
+ path: "~/.config/sing-box/rule-set/geosite-cursor.srs"
68
+ - tag: "geosite-figma"
69
+ format: "binary"
70
+ type: "local"
71
+ path: "~/.config/sing-box/rule-set/geosite-figma.srs"
72
+
73
+ groups:
74
+ processProxy:
75
+ type: "selector"
76
+ includes:
77
+ - "US"
78
+ - "SG"
79
+ - "JP"
80
+ - "HK"
81
+ defaultNodePattern: "OnlyAI"
82
+ aiOut:
83
+ type: "selector"
84
+ includes:
85
+ - "HK"
86
+ - "SG"
87
+ - "US"
88
+ - "JP"
89
+ defaultTarget: "HK"
90
+ devCommonOut:
91
+ type: "selector"
92
+ includes:
93
+ - "HK"
94
+ - "SG"
95
+ - "US"
96
+ - "JP"
97
+ defaultTarget: "HK"
98
+ stitchOut:
99
+ type: "selector"
100
+ includes:
101
+ - "US"
102
+ - "SG"
103
+ - "JP"
104
+ defaultTarget: "US"
105
+ global:
106
+ type: "urltest"
107
+ includes:
108
+ - "HK"
109
+ - "SG"
110
+ - "JP"
111
+ - "US"
112
+
113
+ rules:
114
+ userRulesFile: "~/.config/singbox-iac/rules/custom.rules.yaml"
115
+
116
+ verification:
117
+ scenarios:
118
+ - id: "antigravity-auth"
119
+ name: "Antigravity auth via proxifier stays on the OnlyAI US node"
120
+ url: "https://accounts.google.com/favicon.ico"
121
+ inbound: "in-proxifier"
122
+ expectedOutbound: "Process-Proxy"
123
+ - id: "antigravity-oauth"
124
+ name: "Antigravity OAuth metadata via proxifier stays on the OnlyAI US node"
125
+ url: "https://oauth2.googleapis.com/.well-known/openid-configuration"
126
+ inbound: "in-proxifier"
127
+ expectedOutbound: "Process-Proxy"
128
+ - id: "antigravity-docs"
129
+ name: "Antigravity docs via proxifier stay on the OnlyAI US node"
130
+ url: "https://antigravity.google/docs"
131
+ inbound: "in-proxifier"
132
+ expectedOutbound: "Process-Proxy"
133
+ - id: "antigravity-rules-docs"
134
+ name: "Antigravity rules docs via proxifier stay on the OnlyAI US node"
135
+ url: "https://antigravity.google/docs/rules"
136
+ inbound: "in-proxifier"
137
+ expectedOutbound: "Process-Proxy"
138
+ - id: "antigravity-mcp-docs"
139
+ name: "Antigravity MCP docs via proxifier stay on the OnlyAI US node"
140
+ url: "https://antigravity.google/docs/mcp"
141
+ inbound: "in-proxifier"
142
+ expectedOutbound: "Process-Proxy"
143
+ - id: "antigravity-google-apis"
144
+ name: "Antigravity Google API discovery traffic via proxifier stays on the OnlyAI US node"
145
+ url: "https://www.googleapis.com/discovery/v1/apis"
146
+ inbound: "in-proxifier"
147
+ expectedOutbound: "Process-Proxy"
148
+ - id: "stitch-us"
149
+ name: "Google Stitch always uses the dedicated US exit"
150
+ url: "https://stitch.withgoogle.com/favicon.ico"
151
+ inbound: "in-mixed"
152
+ expectedOutbound: "Stitch-Out"
153
+ - id: "cn-direct"
154
+ name: "China traffic stays direct"
155
+ url: "https://www.baidu.com/favicon.ico"
156
+ inbound: "in-mixed"
157
+ expectedOutbound: "direct"
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
+ - id: "openrouter-hk"
164
+ name: "OpenRouter custom DSL rules send traffic to the HK AI path"
165
+ url: "https://openrouter.ai/favicon.ico"
166
+ inbound: "in-mixed"
167
+ expectedOutbound: "AI-Out"
168
+ - id: "github-hk"
169
+ name: "GitHub uses the HK default developer path"
170
+ url: "https://github.com/favicon.ico"
171
+ inbound: "in-mixed"
172
+ expectedOutbound: "Dev-Common-Out"
173
+
174
+ schedule:
175
+ enabled: true
176
+ intervalMinutes: 30
177
+
178
+ authoring:
179
+ provider: "deterministic"
180
+ timeoutMs: 4000
181
+ # To try a local AI CLI safely, switch provider to "auto" or "exec".
182
+ # provider: "auto"
183
+ # provider: "exec"
184
+ # exec:
185
+ # command: "gemini"
186
+ # args:
187
+ # - "-p"
188
+ # - "{{full_prompt}}"
189
+ #
190
+ # provider: "exec"
191
+ # exec:
192
+ # command: "codebuddy"
193
+ # args:
194
+ # - "--print"
195
+ # - "--output-format"
196
+ # - "json"
197
+ # - "{{full_prompt}}"
198
+ #
199
+ # provider: "exec"
200
+ # exec:
201
+ # command: "codex"
202
+ # args:
203
+ # - "exec"
204
+ # - "--skip-git-repo-check"
205
+ # - "--output-schema"
206
+ # - "{{schema_file}}"
207
+ # - "--output-last-message"
208
+ # - "{{output_file}}"
209
+ # - "{{full_prompt}}"
210
+ #
211
+ # provider: "exec"
212
+ # exec:
213
+ # command: "claude"
214
+ # args:
215
+ # - "-p"
216
+ # - "--output-format"
217
+ # - "json"
218
+ # - "--json-schema"
219
+ # - "{{schema}}"
220
+ # - "{{prompt}}"
@@ -0,0 +1,18 @@
1
+ version: 1
2
+
3
+ beforeBuiltins:
4
+ - name: "OpenRouter uses the AI selector"
5
+ domainSuffix:
6
+ - "openrouter.ai"
7
+ route: "AI-Out"
8
+
9
+ - name: "Perplexity uses the AI selector"
10
+ domainSuffix:
11
+ - "perplexity.ai"
12
+ route: "AI-Out"
13
+
14
+ afterBuiltins:
15
+ - name: "Example mainland-only host stays direct"
16
+ domainSuffix:
17
+ - "intranet.example.cn"
18
+ route: "direct"
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@singbox-iac/cli",
3
+ "version": "0.1.0",
4
+ "description": "Policy-first subscription compiler for sing-box on macOS.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "files": ["dist", "README.md", "docs", "examples"],
8
+ "bin": {
9
+ "singbox-iac": "dist/cli/index.js"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js"
18
+ }
19
+ },
20
+ "types": "./dist/index.d.ts",
21
+ "engines": {
22
+ "node": ">=20.19.0"
23
+ },
24
+ "keywords": ["sing-box", "proxy", "subscription", "macos", "cli", "proxifier"],
25
+ "scripts": {
26
+ "build": "tsc -p tsconfig.json",
27
+ "dev": "tsx src/cli/index.ts",
28
+ "prepare": "npm run build",
29
+ "prepack": "npm run build",
30
+ "release:check": "node ./scripts/release-check.mjs",
31
+ "release:dry-run": "node ./scripts/release-dry-run.mjs",
32
+ "test": "vitest run",
33
+ "test:watch": "vitest",
34
+ "lint": "biome check .",
35
+ "format": "biome format --write .",
36
+ "typecheck": "tsc -p tsconfig.json --noEmit"
37
+ },
38
+ "dependencies": {
39
+ "commander": "^13.1.0",
40
+ "pino": "^9.7.0",
41
+ "yaml": "^2.8.0",
42
+ "zod": "^3.24.3"
43
+ },
44
+ "devDependencies": {
45
+ "@biomejs/biome": "^1.9.4",
46
+ "@types/node": "^22.15.3",
47
+ "tsx": "^4.19.3",
48
+ "typescript": "^5.8.3",
49
+ "vitest": "^3.1.2"
50
+ }
51
+ }