@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.
- package/LICENSE +21 -0
- package/README.md +265 -0
- package/dist/cli/command-helpers.d.ts +6 -0
- package/dist/cli/command-helpers.js +34 -0
- package/dist/cli/command-helpers.js.map +1 -0
- package/dist/cli/commands/apply.d.ts +2 -0
- package/dist/cli/commands/apply.js +32 -0
- package/dist/cli/commands/apply.js.map +1 -0
- package/dist/cli/commands/author.d.ts +2 -0
- package/dist/cli/commands/author.js +194 -0
- package/dist/cli/commands/author.js.map +1 -0
- package/dist/cli/commands/build.d.ts +2 -0
- package/dist/cli/commands/build.js +198 -0
- package/dist/cli/commands/build.js.map +1 -0
- package/dist/cli/commands/check.d.ts +2 -0
- package/dist/cli/commands/check.js +23 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.js +35 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.js +23 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/reload.d.ts +2 -0
- package/dist/cli/commands/reload.js +21 -0
- package/dist/cli/commands/reload.js.map +1 -0
- package/dist/cli/commands/run.d.ts +2 -0
- package/dist/cli/commands/run.js +25 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/schedule.d.ts +2 -0
- package/dist/cli/commands/schedule.js +77 -0
- package/dist/cli/commands/schedule.js.map +1 -0
- package/dist/cli/commands/templates.d.ts +2 -0
- package/dist/cli/commands/templates.js +34 -0
- package/dist/cli/commands/templates.js.map +1 -0
- package/dist/cli/commands/update.d.ts +2 -0
- package/dist/cli/commands/update.js +52 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/commands/verify.d.ts +2 -0
- package/dist/cli/commands/verify.js +49 -0
- package/dist/cli/commands/verify.js.map +1 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.js +55 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/load-config.d.ts +2 -0
- package/dist/config/load-config.js +29 -0
- package/dist/config/load-config.js.map +1 -0
- package/dist/config/schema.d.ts +548 -0
- package/dist/config/schema.js +92 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/domain/config.d.ts +8 -0
- package/dist/domain/config.js +2 -0
- package/dist/domain/config.js.map +1 -0
- package/dist/domain/node.d.ts +11 -0
- package/dist/domain/node.js +2 -0
- package/dist/domain/node.js.map +1 -0
- package/dist/domain/outbound.d.ts +15 -0
- package/dist/domain/outbound.js +2 -0
- package/dist/domain/outbound.js.map +1 -0
- package/dist/domain/subscription.d.ts +6 -0
- package/dist/domain/subscription.js +2 -0
- package/dist/domain/subscription.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/authoring/index.d.ts +41 -0
- package/dist/modules/authoring/index.js +596 -0
- package/dist/modules/authoring/index.js.map +1 -0
- package/dist/modules/build/index.d.ts +13 -0
- package/dist/modules/build/index.js +39 -0
- package/dist/modules/build/index.js.map +1 -0
- package/dist/modules/compiler/index.d.ts +10 -0
- package/dist/modules/compiler/index.js +305 -0
- package/dist/modules/compiler/index.js.map +1 -0
- package/dist/modules/doctor/index.d.ts +17 -0
- package/dist/modules/doctor/index.js +89 -0
- package/dist/modules/doctor/index.js.map +1 -0
- package/dist/modules/fetcher/index.d.ts +4 -0
- package/dist/modules/fetcher/index.js +42 -0
- package/dist/modules/fetcher/index.js.map +1 -0
- package/dist/modules/init/index.d.ts +12 -0
- package/dist/modules/init/index.js +41 -0
- package/dist/modules/init/index.js.map +1 -0
- package/dist/modules/manager/index.d.ts +29 -0
- package/dist/modules/manager/index.js +133 -0
- package/dist/modules/manager/index.js.map +1 -0
- package/dist/modules/natural-language/index.d.ts +54 -0
- package/dist/modules/natural-language/index.js +458 -0
- package/dist/modules/natural-language/index.js.map +1 -0
- package/dist/modules/parser/index.d.ts +10 -0
- package/dist/modules/parser/index.js +113 -0
- package/dist/modules/parser/index.js.map +1 -0
- package/dist/modules/preview/index.d.ts +22 -0
- package/dist/modules/preview/index.js +141 -0
- package/dist/modules/preview/index.js.map +1 -0
- package/dist/modules/rule-templates/index.d.ts +15 -0
- package/dist/modules/rule-templates/index.js +200 -0
- package/dist/modules/rule-templates/index.js.map +1 -0
- package/dist/modules/schedule/index.d.ts +32 -0
- package/dist/modules/schedule/index.js +155 -0
- package/dist/modules/schedule/index.js.map +1 -0
- package/dist/modules/update/index.d.ts +22 -0
- package/dist/modules/update/index.js +38 -0
- package/dist/modules/update/index.js.map +1 -0
- package/dist/modules/user-rules/index.d.ts +18 -0
- package/dist/modules/user-rules/index.js +98 -0
- package/dist/modules/user-rules/index.js.map +1 -0
- package/dist/modules/verification/index.d.ts +49 -0
- package/dist/modules/verification/index.js +432 -0
- package/dist/modules/verification/index.js.map +1 -0
- package/dist/shared/errors.d.ts +3 -0
- package/dist/shared/errors.js +7 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/shared/logger.d.ts +2 -0
- package/dist/shared/logger.js +5 -0
- package/dist/shared/logger.js.map +1 -0
- package/dist/shared/result.d.ts +11 -0
- package/dist/shared/result.js +7 -0
- package/dist/shared/result.js.map +1 -0
- package/docs/antigravity-endpoints.md +77 -0
- package/docs/competitive-landscape.md +45 -0
- package/docs/development-workflow.md +80 -0
- package/docs/natural-language-authoring.md +376 -0
- package/docs/positioning.md +42 -0
- package/docs/releasing.md +72 -0
- package/docs/rule-templates.md +122 -0
- package/docs/rules-dsl.md +107 -0
- package/docs/runtime-on-macos.md +42 -0
- package/docs/sing-box-config-primer.md +39 -0
- package/docs/subscription-format.md +38 -0
- package/examples/builder.config.yaml +220 -0
- package/examples/custom.rules.yaml +18 -0
- package/package.json +51 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.js","sourceRoot":"","sources":["../../src/shared/result.ts"],"names":[],"mappings":"AAYA,MAAM,UAAU,EAAE,CAAI,KAAQ;IAC5B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,GAAG,CAAI,KAAQ;IAC7B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Antigravity Endpoint Notes
|
|
2
|
+
|
|
3
|
+
These notes were derived from the installed macOS app bundle at `/Applications/Antigravity.app` and local logs under `/Users/lvyuanfang/Library/Application Support/Antigravity/logs`.
|
|
4
|
+
|
|
5
|
+
## App Identity
|
|
6
|
+
|
|
7
|
+
- Bundle identifier: `com.google.antigravity`
|
|
8
|
+
- Product links in `product.json`:
|
|
9
|
+
- `https://antigravity.google/docs`
|
|
10
|
+
- `https://antigravity.google/docs/rules`
|
|
11
|
+
- `https://antigravity.google/docs/mcp`
|
|
12
|
+
- `https://antigravity.google/support`
|
|
13
|
+
|
|
14
|
+
## Observed Or Referenced Google Endpoints
|
|
15
|
+
|
|
16
|
+
The installed app and local logs reference these Google-hosted domains that are relevant for routing verification:
|
|
17
|
+
|
|
18
|
+
- `antigravity.google`
|
|
19
|
+
- `accounts.google.com`
|
|
20
|
+
- `oauth2.googleapis.com`
|
|
21
|
+
- `clients2.google.com`
|
|
22
|
+
- `android.clients.google.com`
|
|
23
|
+
- `apis.google.com`
|
|
24
|
+
- `aiplatform.googleapis.com`
|
|
25
|
+
- `cloud.google.com`
|
|
26
|
+
- `daily-cloudcode-pa.googleapis.com`
|
|
27
|
+
- `firebase.googleapis.com`
|
|
28
|
+
- `fonts.googleapis.com`
|
|
29
|
+
- `fonts.gstatic.com`
|
|
30
|
+
- `lh3.googleusercontent.com`
|
|
31
|
+
- `play.googleapis.com`
|
|
32
|
+
- `antigravity-unleash.goog`
|
|
33
|
+
- `www.googleapis.com`
|
|
34
|
+
- `www.gstatic.com`
|
|
35
|
+
|
|
36
|
+
## Why These Matter
|
|
37
|
+
|
|
38
|
+
- `accounts.google.com` is a good auth-path verification target for `in-proxifier`.
|
|
39
|
+
- `oauth2.googleapis.com` is a good OAuth metadata verification target for `in-proxifier`.
|
|
40
|
+
- `antigravity.google` is a good product-surface verification target for `in-proxifier`.
|
|
41
|
+
- `www.googleapis.com` is a stable Google API surface that appeared in real runtime logs and is suitable for verification.
|
|
42
|
+
- `daily-cloudcode-pa.googleapis.com` appears during real model streaming, but it is less stable as a browser verification target and is better tracked as an observed runtime dependency.
|
|
43
|
+
- `play.googleapis.com`, `antigravity-unleash.goog`, `lh3.googleusercontent.com`, `clients2.google.com`, `android.clients.google.com`, `fonts.googleapis.com`, and `www.gstatic.com` regularly appear as supporting traffic during a real Antigravity session.
|
|
44
|
+
|
|
45
|
+
## User Journey Buckets
|
|
46
|
+
|
|
47
|
+
### Product Surfaces
|
|
48
|
+
|
|
49
|
+
- `https://antigravity.google/docs`
|
|
50
|
+
- `https://antigravity.google/docs/rules`
|
|
51
|
+
- `https://antigravity.google/docs/mcp`
|
|
52
|
+
|
|
53
|
+
### Auth And Session Bootstrap
|
|
54
|
+
|
|
55
|
+
- `https://accounts.google.com/favicon.ico`
|
|
56
|
+
- `https://oauth2.googleapis.com/.well-known/openid-configuration`
|
|
57
|
+
|
|
58
|
+
### Control And API Surfaces
|
|
59
|
+
|
|
60
|
+
- `https://www.googleapis.com/discovery/v1/apis`
|
|
61
|
+
- Observed at runtime, but not used as fixed browser probes:
|
|
62
|
+
- `daily-cloudcode-pa.googleapis.com`
|
|
63
|
+
- `play.googleapis.com`
|
|
64
|
+
- `antigravity-unleash.goog`
|
|
65
|
+
|
|
66
|
+
## Current Verification Usage
|
|
67
|
+
|
|
68
|
+
The current verification harness uses:
|
|
69
|
+
|
|
70
|
+
- `https://accounts.google.com/favicon.ico`
|
|
71
|
+
- `https://oauth2.googleapis.com/.well-known/openid-configuration`
|
|
72
|
+
- `https://antigravity.google/docs`
|
|
73
|
+
- `https://antigravity.google/docs/rules`
|
|
74
|
+
- `https://antigravity.google/docs/mcp`
|
|
75
|
+
- `https://www.googleapis.com/discovery/v1/apis`
|
|
76
|
+
|
|
77
|
+
All of these are routed through `in-proxifier` and must land on the fixed US `OnlyAI` node.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Competitive Landscape
|
|
2
|
+
|
|
3
|
+
## Existing Categories
|
|
4
|
+
|
|
5
|
+
### Generic subscription converters
|
|
6
|
+
|
|
7
|
+
These tools convert provider subscriptions into one or more target client formats. They are useful, but their center of gravity is format conversion, not runtime-safe policy compilation.
|
|
8
|
+
|
|
9
|
+
Typical limitations:
|
|
10
|
+
|
|
11
|
+
- route precedence is often inherited from templates
|
|
12
|
+
- process-aware routing is not a first-class use case
|
|
13
|
+
- runtime validation and staged publish are usually outside scope
|
|
14
|
+
|
|
15
|
+
### GUI clients and launchers
|
|
16
|
+
|
|
17
|
+
These tools optimize for usability and visual management. They are convenient but tend to hide merge order, effective config structure, and runtime rollout details.
|
|
18
|
+
|
|
19
|
+
Typical limitations:
|
|
20
|
+
|
|
21
|
+
- higher idle resource usage
|
|
22
|
+
- config merge logic is harder to audit
|
|
23
|
+
- process routing and custom listeners become brittle over time
|
|
24
|
+
|
|
25
|
+
### Library-style generators
|
|
26
|
+
|
|
27
|
+
These projects expose config generation as an SDK or library. They can be useful implementation references but are not the final product shape targeted here.
|
|
28
|
+
|
|
29
|
+
Typical limitations:
|
|
30
|
+
|
|
31
|
+
- not macOS workflow-oriented
|
|
32
|
+
- no opinionated CLI lifecycle
|
|
33
|
+
- no declarative policy authoring model
|
|
34
|
+
|
|
35
|
+
## Planned Differentiators
|
|
36
|
+
|
|
37
|
+
`Sing-box IaC Builder` should differentiate on:
|
|
38
|
+
|
|
39
|
+
- policy-first compilation
|
|
40
|
+
- macOS headless operation
|
|
41
|
+
- explicit staged rollout
|
|
42
|
+
- route ordering invariants
|
|
43
|
+
- user-facing rule DSL
|
|
44
|
+
- future natural-language rule authoring with DSL confirmation
|
|
45
|
+
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Development Workflow
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Use OpenSpec for specification control and Superpowers for execution discipline.
|
|
6
|
+
|
|
7
|
+
## Working Model
|
|
8
|
+
|
|
9
|
+
- OpenSpec answers: what behavior should exist.
|
|
10
|
+
- Superpowers answers: how this change will be executed safely.
|
|
11
|
+
|
|
12
|
+
## Standard Flow for Each Phase
|
|
13
|
+
|
|
14
|
+
1. Clarify scope and non-goals.
|
|
15
|
+
2. Create or update `openspec/changes/<change-id>/proposal.md`.
|
|
16
|
+
3. Write `design.md` only for the important decisions.
|
|
17
|
+
4. Write `tasks.md` with small, executable tasks.
|
|
18
|
+
5. Update the relevant capability specs under `openspec/specs/`.
|
|
19
|
+
6. Write fixtures or tests before implementation where behavior is concrete.
|
|
20
|
+
7. Implement in small batches.
|
|
21
|
+
8. Run validation.
|
|
22
|
+
9. Fold approved behavior back into the long-lived specs.
|
|
23
|
+
|
|
24
|
+
## MVP Path
|
|
25
|
+
|
|
26
|
+
For self-hosting and early dogfooding, prefer a vertical slice when the full roadmap would delay first use too much.
|
|
27
|
+
|
|
28
|
+
Recommended first slice:
|
|
29
|
+
|
|
30
|
+
1. parse Trojan subscriptions
|
|
31
|
+
2. compile a minimal usable `sing-box` config
|
|
32
|
+
3. expose a `build` command
|
|
33
|
+
4. test locally with manual `sing-box check`
|
|
34
|
+
|
|
35
|
+
This keeps OpenSpec lightweight:
|
|
36
|
+
|
|
37
|
+
- use one MVP-oriented change proposal
|
|
38
|
+
- keep specs focused on acceptance criteria and invariants
|
|
39
|
+
- avoid writing extra design documents unless a decision is genuinely hard to reverse
|
|
40
|
+
|
|
41
|
+
## Phase Guidance
|
|
42
|
+
|
|
43
|
+
### Phase 0
|
|
44
|
+
|
|
45
|
+
Use OpenSpec to define project constraints, architecture, and capability boundaries. Use Superpowers to enforce small setup tasks and avoid jumping into parser or compiler code too early.
|
|
46
|
+
|
|
47
|
+
### Phase 1
|
|
48
|
+
|
|
49
|
+
Use OpenSpec to lock parser input, output, and failure semantics. Use Superpowers to drive fixture-first implementation and edge-case coverage.
|
|
50
|
+
|
|
51
|
+
If the immediate goal is self-use, combine the parser with a minimal compiler and `build` command under a vertical MVP change before returning to the broader phase roadmap.
|
|
52
|
+
|
|
53
|
+
### Phase 2
|
|
54
|
+
|
|
55
|
+
Use OpenSpec to define compiler invariants and route priority. Use Superpowers to break the compiler into template assembly, grouping, and route generation tasks.
|
|
56
|
+
|
|
57
|
+
### Phase 3
|
|
58
|
+
|
|
59
|
+
Use OpenSpec to define CLI contracts and fetch behavior. Use Superpowers to implement command-by-command instead of building the whole pipeline as one opaque step.
|
|
60
|
+
|
|
61
|
+
### Phase 4
|
|
62
|
+
|
|
63
|
+
Use OpenSpec to define runtime state transitions and safety rules. Use Superpowers to implement validation, publish, reload, and rollback in explicit steps.
|
|
64
|
+
|
|
65
|
+
### Future Rule Authoring
|
|
66
|
+
|
|
67
|
+
Use OpenSpec to define the DSL grammar and compiler guarantees. Use Superpowers to keep natural-language support behind a preview-and-confirm flow.
|
|
68
|
+
|
|
69
|
+
## Review Focus
|
|
70
|
+
|
|
71
|
+
Before closing a change, verify:
|
|
72
|
+
|
|
73
|
+
- specs still match implementation
|
|
74
|
+
- error handling is defensive
|
|
75
|
+
- route ordering invariants are protected
|
|
76
|
+
- user-configurable layers cannot bypass system invariants silently
|
|
77
|
+
|
|
78
|
+
## Current Recommendation
|
|
79
|
+
|
|
80
|
+
The next implementation step for this repository is `parse-and-build-first-config`. It is the shortest path from specification baseline to a locally usable config generator.
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
# Natural-Language Authoring
|
|
2
|
+
|
|
3
|
+
The `author` command is the bridge between a short routing prompt and the full local workflow:
|
|
4
|
+
|
|
5
|
+
1. turn a prompt into the YAML rules DSL
|
|
6
|
+
2. write the generated rules file
|
|
7
|
+
3. update the builder config to point at that rules file
|
|
8
|
+
4. build a new `sing-box` config
|
|
9
|
+
5. optionally install a `launchd` schedule that runs `update`
|
|
10
|
+
6. optionally run `update` immediately from the same command
|
|
11
|
+
|
|
12
|
+
The output still goes through the normal compiler pipeline. Natural language does not mutate `sing-box` JSON directly.
|
|
13
|
+
|
|
14
|
+
## Provider Modes
|
|
15
|
+
|
|
16
|
+
The authoring layer supports four provider modes:
|
|
17
|
+
|
|
18
|
+
- `deterministic`
|
|
19
|
+
The built-in keyword/template parser. This is the default because it is fast, testable, and does not depend on any external model.
|
|
20
|
+
|
|
21
|
+
- `auto`
|
|
22
|
+
Try a supported local AI CLI first, then fall back to the deterministic parser if the local CLI is unavailable, times out, or returns invalid output.
|
|
23
|
+
|
|
24
|
+
- `claude`
|
|
25
|
+
Use the local `claude` CLI directly for structured JSON plan generation.
|
|
26
|
+
|
|
27
|
+
- `exec`
|
|
28
|
+
Use any local command that can print a JSON authoring plan to stdout or write one to a file.
|
|
29
|
+
|
|
30
|
+
Recommended default:
|
|
31
|
+
|
|
32
|
+
```yaml
|
|
33
|
+
authoring:
|
|
34
|
+
provider: "deterministic"
|
|
35
|
+
timeoutMs: 4000
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Opt in to local AI CLI probing:
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
authoring:
|
|
42
|
+
provider: "auto"
|
|
43
|
+
timeoutMs: 1000
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## One-Line Examples
|
|
47
|
+
|
|
48
|
+
Generate rules and build a staging config:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
./node_modules/.bin/tsx src/cli/index.ts author \
|
|
52
|
+
--config ./builder.config.local.yaml \
|
|
53
|
+
--prompt "开发者网站走香港,视频网站走新加坡"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Preview what would change without writing files:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
./node_modules/.bin/tsx src/cli/index.ts author \
|
|
60
|
+
--config ./builder.config.local.yaml \
|
|
61
|
+
--provider deterministic \
|
|
62
|
+
--prompt "OpenRouter 走香港,YouTube Netflix 走美国,每60分钟自动更新" \
|
|
63
|
+
--preview
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Generate rules, build a config, and install a schedule:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
./node_modules/.bin/tsx src/cli/index.ts author \
|
|
70
|
+
--config ./builder.config.local.yaml \
|
|
71
|
+
--prompt "OpenRouter 和 Perplexity 走香港,YouTube Netflix 走美国,每45分钟自动更新" \
|
|
72
|
+
--install-schedule
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Generate rules and immediately run `build -> verify -> publish`:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
./node_modules/.bin/tsx src/cli/index.ts author \
|
|
79
|
+
--config ./builder.config.local.yaml \
|
|
80
|
+
--provider deterministic \
|
|
81
|
+
--prompt "Google 服务和 GitHub 这类开发类都走香港,Gemini 走新加坡,Antigravity 进程级走美国,每30分钟自动更新" \
|
|
82
|
+
--update
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Force a local AI CLI attempt first, then fall back safely if needed:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
./node_modules/.bin/tsx src/cli/index.ts author \
|
|
89
|
+
--config ./builder.config.local.yaml \
|
|
90
|
+
--provider auto \
|
|
91
|
+
--author-timeout-ms 1000 \
|
|
92
|
+
--prompt "开发者网站走香港,AI 工具走香港,视频网站走新加坡,每45分钟自动更新"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Use a local subscription fixture instead of fetching remotely:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
./node_modules/.bin/tsx src/cli/index.ts author \
|
|
99
|
+
--config ./builder.config.local.yaml \
|
|
100
|
+
--prompt "国内视频网站直连,AI 工具走香港,每2小时自动更新" \
|
|
101
|
+
--subscription-file ./tests/fixtures/subscriptions/trojan-sample.b64 \
|
|
102
|
+
--install-schedule \
|
|
103
|
+
--no-load
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## What the Prompt Can Express
|
|
107
|
+
|
|
108
|
+
This layer intentionally aims at simple intent, not full policy programming.
|
|
109
|
+
|
|
110
|
+
It works best for:
|
|
111
|
+
|
|
112
|
+
- process-aware reminders like `IDE 走 proxifier`
|
|
113
|
+
- site classes like `视频网站走美国`
|
|
114
|
+
- named products like `Google Stitch 走美国`
|
|
115
|
+
- short regional intents like `OpenRouter 走香港`
|
|
116
|
+
- schedule phrases like `每45分钟自动更新`
|
|
117
|
+
- one-sentence developer routing like `GitHub 这类开发类走香港,Antigravity 进程级走美国,Gemini 走新加坡`
|
|
118
|
+
- mainstream subscription vocabulary like `Google 服务`, `Apple 服务`, `Amazon Prime`, `Apple TV`
|
|
119
|
+
|
|
120
|
+
## Intent-First Behavior
|
|
121
|
+
|
|
122
|
+
The `author` command does not require the user to think in DSL terms.
|
|
123
|
+
|
|
124
|
+
For common developer sentences, it now compiles intent across three layers:
|
|
125
|
+
|
|
126
|
+
1. specific site overrides
|
|
127
|
+
Example: `Gemini 走新加坡` becomes an explicit rule before built-ins.
|
|
128
|
+
2. selector default changes
|
|
129
|
+
Example: `开发类都走香港` updates `Dev-Common-Out` to default to `HK`.
|
|
130
|
+
3. verification expectation alignment
|
|
131
|
+
Example: if the configured verification URL for Gemini previously expected `AI-Out -> HK`, it will be updated so runtime verification now expects `SG`.
|
|
132
|
+
|
|
133
|
+
That keeps `author -> build -> verify` truthful even after intent-driven changes.
|
|
134
|
+
|
|
135
|
+
Example:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
./node_modules/.bin/tsx src/cli/index.ts author \
|
|
139
|
+
--config ./builder.config.local.yaml \
|
|
140
|
+
--provider deterministic \
|
|
141
|
+
--prompt "GitHub 这类开发类都走香港出口,Antigravity 进程级都走独立的入口并路由到美国节点,Gemini 都出口到新加坡,每30分钟自动更新"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Common category-style examples:
|
|
145
|
+
|
|
146
|
+
- `Google 服务和 GitHub 这类开发类都走香港`
|
|
147
|
+
- `Apple 服务走香港`
|
|
148
|
+
- `Amazon Prime 和 Apple TV 走新加坡`
|
|
149
|
+
- `视频网站走美国`
|
|
150
|
+
|
|
151
|
+
Supported schedule phrases include:
|
|
152
|
+
|
|
153
|
+
- `每30分钟`
|
|
154
|
+
- `每45分钟`
|
|
155
|
+
- `每2小时`
|
|
156
|
+
- `schedule`
|
|
157
|
+
- `launchd`
|
|
158
|
+
|
|
159
|
+
## Output Model
|
|
160
|
+
|
|
161
|
+
Natural language produces three things:
|
|
162
|
+
|
|
163
|
+
- generated user rules
|
|
164
|
+
- optional inferred templates
|
|
165
|
+
- optional schedule interval
|
|
166
|
+
- optional selector default changes
|
|
167
|
+
- optional verification expectation overrides
|
|
168
|
+
|
|
169
|
+
The command then updates:
|
|
170
|
+
|
|
171
|
+
- `rules.userRulesFile`
|
|
172
|
+
- `schedule.enabled`
|
|
173
|
+
- `schedule.intervalMinutes`
|
|
174
|
+
- selector defaults such as `AI-Out`, `Dev-Common-Out`, or `Process-Proxy`
|
|
175
|
+
- verification scenario expectations when an existing scenario’s target intent changed
|
|
176
|
+
|
|
177
|
+
and writes a new staging config.
|
|
178
|
+
|
|
179
|
+
With `--preview`, the command does not write anything. Instead it prints:
|
|
180
|
+
|
|
181
|
+
- rules diff
|
|
182
|
+
- builder config diff
|
|
183
|
+
- staging config diff
|
|
184
|
+
|
|
185
|
+
This is the safest way to inspect what a prompt or local AI CLI would change before touching your local files.
|
|
186
|
+
|
|
187
|
+
## Exec Provider
|
|
188
|
+
|
|
189
|
+
The `exec` provider is the escape hatch for developer machines that already have local AI tooling.
|
|
190
|
+
This is the recommended way to integrate most AI CLIs beyond the built-in `claude` adapter.
|
|
191
|
+
|
|
192
|
+
The command receives:
|
|
193
|
+
|
|
194
|
+
- `SINGBOX_IAC_AUTHOR_PROMPT`
|
|
195
|
+
- `SINGBOX_IAC_AUTHOR_SCHEMA`
|
|
196
|
+
- `SINGBOX_IAC_AUTHOR_CONTEXT`
|
|
197
|
+
|
|
198
|
+
Arguments may use placeholders:
|
|
199
|
+
|
|
200
|
+
- `{{prompt}}`
|
|
201
|
+
- `{{schema}}`
|
|
202
|
+
- `{{context_json}}`
|
|
203
|
+
- `{{full_prompt}}`
|
|
204
|
+
- `{{schema_file}}`
|
|
205
|
+
- `{{output_file}}`
|
|
206
|
+
|
|
207
|
+
Environment variables are also injected for wrapper scripts:
|
|
208
|
+
|
|
209
|
+
- `SINGBOX_IAC_AUTHOR_PROMPT`
|
|
210
|
+
- `SINGBOX_IAC_AUTHOR_SCHEMA`
|
|
211
|
+
- `SINGBOX_IAC_AUTHOR_CONTEXT`
|
|
212
|
+
- `SINGBOX_IAC_AUTHOR_FULL_PROMPT`
|
|
213
|
+
- `SINGBOX_IAC_AUTHOR_SCHEMA_FILE`
|
|
214
|
+
- `SINGBOX_IAC_AUTHOR_OUTPUT_FILE`
|
|
215
|
+
|
|
216
|
+
The command must print a JSON object that matches the internal plan schema:
|
|
217
|
+
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"templateIds": ["developer-ai-sites", "video-sg"],
|
|
221
|
+
"beforeBuiltins": [],
|
|
222
|
+
"afterBuiltins": [],
|
|
223
|
+
"notes": [],
|
|
224
|
+
"scheduleIntervalMinutes": 45
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
If the CLI is noisy, the provider will also accept:
|
|
229
|
+
|
|
230
|
+
- a fenced ````json` block that contains the plan
|
|
231
|
+
- a longer text response with one balanced JSON object inside it
|
|
232
|
+
- an output file path populated through `{{output_file}}`
|
|
233
|
+
|
|
234
|
+
## Common Local AI CLI Integrations
|
|
235
|
+
|
|
236
|
+
The goal is not to hard-code every AI CLI on the market. The goal is to make almost all of them usable through one bounded adapter.
|
|
237
|
+
|
|
238
|
+
Recommended support model:
|
|
239
|
+
|
|
240
|
+
- stable built-ins:
|
|
241
|
+
- `claude`
|
|
242
|
+
- generic `exec` integrations:
|
|
243
|
+
- `gemini`
|
|
244
|
+
- `codebuddy`
|
|
245
|
+
- `codex`
|
|
246
|
+
- `opencode`
|
|
247
|
+
- `qodercli` / `qoder`
|
|
248
|
+
- tooling-only or editor launchers:
|
|
249
|
+
- `trae`
|
|
250
|
+
|
|
251
|
+
### Gemini CLI
|
|
252
|
+
|
|
253
|
+
Best when Gemini is already logged in locally and you want a lightweight prompt-only integration.
|
|
254
|
+
|
|
255
|
+
```yaml
|
|
256
|
+
authoring:
|
|
257
|
+
provider: "exec"
|
|
258
|
+
timeoutMs: 4000
|
|
259
|
+
exec:
|
|
260
|
+
command: "gemini"
|
|
261
|
+
args:
|
|
262
|
+
- "-p"
|
|
263
|
+
- "{{full_prompt}}"
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### CodeBuddy CLI
|
|
267
|
+
|
|
268
|
+
`codebuddy` and `cbc` expose `--print` and `--output-format json`, which makes them strong `exec` candidates.
|
|
269
|
+
|
|
270
|
+
```yaml
|
|
271
|
+
authoring:
|
|
272
|
+
provider: "exec"
|
|
273
|
+
timeoutMs: 4000
|
|
274
|
+
exec:
|
|
275
|
+
command: "codebuddy"
|
|
276
|
+
args:
|
|
277
|
+
- "--print"
|
|
278
|
+
- "--output-format"
|
|
279
|
+
- "json"
|
|
280
|
+
- "{{full_prompt}}"
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Codex CLI
|
|
284
|
+
|
|
285
|
+
Codex already supports schema files and writing the final response to a file. That maps well onto `{{schema_file}}` and `{{output_file}}`.
|
|
286
|
+
|
|
287
|
+
```yaml
|
|
288
|
+
authoring:
|
|
289
|
+
provider: "exec"
|
|
290
|
+
timeoutMs: 8000
|
|
291
|
+
exec:
|
|
292
|
+
command: "codex"
|
|
293
|
+
args:
|
|
294
|
+
- "exec"
|
|
295
|
+
- "--skip-git-repo-check"
|
|
296
|
+
- "--output-schema"
|
|
297
|
+
- "{{schema_file}}"
|
|
298
|
+
- "--output-last-message"
|
|
299
|
+
- "{{output_file}}"
|
|
300
|
+
- "{{full_prompt}}"
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### OpenCode
|
|
304
|
+
|
|
305
|
+
`opencode run` supports a non-interactive message flow and a JSON event mode. Use a small wrapper if the raw JSON event stream is too noisy.
|
|
306
|
+
|
|
307
|
+
```yaml
|
|
308
|
+
authoring:
|
|
309
|
+
provider: "exec"
|
|
310
|
+
timeoutMs: 8000
|
|
311
|
+
exec:
|
|
312
|
+
command: "opencode"
|
|
313
|
+
args:
|
|
314
|
+
- "run"
|
|
315
|
+
- "--format"
|
|
316
|
+
- "json"
|
|
317
|
+
- "{{full_prompt}}"
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Qoder CLI
|
|
321
|
+
|
|
322
|
+
If Qoder is installed locally, prefer a wrapper script or a direct print/json mode if your local version exposes one.
|
|
323
|
+
|
|
324
|
+
```yaml
|
|
325
|
+
authoring:
|
|
326
|
+
provider: "exec"
|
|
327
|
+
timeoutMs: 8000
|
|
328
|
+
exec:
|
|
329
|
+
command: "qodercli"
|
|
330
|
+
args:
|
|
331
|
+
- "--print"
|
|
332
|
+
- "--output-format"
|
|
333
|
+
- "json"
|
|
334
|
+
- "{{full_prompt}}"
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Wrapper Pattern
|
|
338
|
+
|
|
339
|
+
Some CLIs will not print the exact JSON plan directly. In that case, use a tiny local wrapper script.
|
|
340
|
+
|
|
341
|
+
```yaml
|
|
342
|
+
authoring:
|
|
343
|
+
provider: "exec"
|
|
344
|
+
timeoutMs: 8000
|
|
345
|
+
exec:
|
|
346
|
+
command: "/Users/you/bin/singbox-author-wrapper"
|
|
347
|
+
args:
|
|
348
|
+
- "{{prompt}}"
|
|
349
|
+
- "{{output_file}}"
|
|
350
|
+
- "{{schema_file}}"
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
That wrapper can:
|
|
354
|
+
|
|
355
|
+
1. call the local AI CLI you prefer
|
|
356
|
+
2. instruct it to output only one JSON plan
|
|
357
|
+
3. write the final JSON object to `{{output_file}}`
|
|
358
|
+
|
|
359
|
+
This keeps the project neutral and avoids shipping hard-coded adapters for every vendor.
|
|
360
|
+
|
|
361
|
+
## Guardrails
|
|
362
|
+
|
|
363
|
+
- Built-in protected system rules still stay first.
|
|
364
|
+
- Generated rules still pass through the DSL validator.
|
|
365
|
+
- Schedule installation is explicit through `--install-schedule`.
|
|
366
|
+
- If a clause maps better to the built-in proxifier flow, the generator emits a note rather than trying to fake process matching inside the DSL.
|
|
367
|
+
- `auto` may fall back to deterministic if a local AI CLI is installed but not usable in the current environment.
|
|
368
|
+
|
|
369
|
+
## Recommended Usage
|
|
370
|
+
|
|
371
|
+
For developer-oriented setups, use this workflow:
|
|
372
|
+
|
|
373
|
+
1. keep `Process-Proxy` reserved for Proxifier-driven IDE and app traffic
|
|
374
|
+
2. use built-in service rules for Stitch, OpenAI, Gemini, Anthropic, GitHub, and Google
|
|
375
|
+
3. use templates or natural language for third-party AI sites and video sites
|
|
376
|
+
4. use the DSL only for small exceptions
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Positioning
|
|
2
|
+
|
|
3
|
+
## One-Line Summary
|
|
4
|
+
|
|
5
|
+
`Sing-box IaC Builder` is a policy-first CLI that compiles subscriptions into safe, headless `sing-box` infrastructure for macOS.
|
|
6
|
+
|
|
7
|
+
## Problem Statement
|
|
8
|
+
|
|
9
|
+
Existing workflows usually optimize for importing subscriptions into a GUI client. They do not optimize for:
|
|
10
|
+
|
|
11
|
+
- deterministic route priority
|
|
12
|
+
- process-aware routing via `Proxifier`
|
|
13
|
+
- multiple listeners with stable semantics
|
|
14
|
+
- headless runtime management
|
|
15
|
+
- low resource usage
|
|
16
|
+
- safe rollout and validation
|
|
17
|
+
|
|
18
|
+
## Strategic Difference
|
|
19
|
+
|
|
20
|
+
This project separates three concerns that are often mixed together:
|
|
21
|
+
|
|
22
|
+
1. provider input
|
|
23
|
+
2. local policy
|
|
24
|
+
3. runtime application
|
|
25
|
+
|
|
26
|
+
Provider subscriptions are treated as untrusted upstream data. Local policy is declared separately and compiled with stable precedence. Runtime application is validated before live deployment.
|
|
27
|
+
|
|
28
|
+
## Open Source Position
|
|
29
|
+
|
|
30
|
+
This project should be published as:
|
|
31
|
+
|
|
32
|
+
- a `sing-box` compiler, not a generic converter
|
|
33
|
+
- a macOS-first headless runtime tool, not a GUI replacement
|
|
34
|
+
- a policy authoring system, not only a template pack
|
|
35
|
+
|
|
36
|
+
## Target Users
|
|
37
|
+
|
|
38
|
+
- advanced macOS users who already run `sing-box`
|
|
39
|
+
- users migrating away from Clash Verge or similar GUI clients
|
|
40
|
+
- users relying on `Proxifier`, AI applications, or mixed app-specific routing
|
|
41
|
+
- users who want a low-overhead headless runtime
|
|
42
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Releasing
|
|
2
|
+
|
|
3
|
+
This repository is prepared for npm-style distribution. The default package name is now:
|
|
4
|
+
|
|
5
|
+
```json
|
|
6
|
+
"name": "@singbox-iac/cli"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
The repository still intentionally remains `"private": true` until the first real publish.
|
|
10
|
+
|
|
11
|
+
## Current Release Safety Commands
|
|
12
|
+
|
|
13
|
+
Use these two commands before any real publish:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm run release:check
|
|
17
|
+
npm run release:dry-run
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`release:check` verifies:
|
|
21
|
+
|
|
22
|
+
- typecheck
|
|
23
|
+
- lint
|
|
24
|
+
- tests
|
|
25
|
+
- build
|
|
26
|
+
- `npm pack`
|
|
27
|
+
- clean-directory install
|
|
28
|
+
- installed `singbox-iac --help`
|
|
29
|
+
|
|
30
|
+
`release:dry-run` first runs `release:check`, then stages a publishable package copy with:
|
|
31
|
+
|
|
32
|
+
- `private: false`
|
|
33
|
+
- a publish name
|
|
34
|
+
- compiled `dist`
|
|
35
|
+
- docs/examples/README/LICENSE
|
|
36
|
+
|
|
37
|
+
and finally runs:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm publish --dry-run
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Package Name
|
|
44
|
+
The chosen default publish target is:
|
|
45
|
+
|
|
46
|
+
- `@singbox-iac/cli`
|
|
47
|
+
|
|
48
|
+
The installed command remains:
|
|
49
|
+
|
|
50
|
+
- `singbox-iac`
|
|
51
|
+
|
|
52
|
+
## Dry-Run with a Candidate Name
|
|
53
|
+
|
|
54
|
+
You can still test an alternate future publish name without changing the repository package metadata:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
SINGBOX_IAC_PACKAGE_NAME=@singbox-iac/experimental-cli npm run release:dry-run
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Real Publish Checklist
|
|
61
|
+
|
|
62
|
+
1. confirm the license choice
|
|
63
|
+
2. remove `"private": true` in `package.json`
|
|
64
|
+
3. ensure you are logged into npm with access to the `singbox-iac` organization
|
|
65
|
+
4. run `npm run release:check`
|
|
66
|
+
5. run `npm run release:dry-run`
|
|
67
|
+
6. publish from a clean working tree with `npm publish --access public`
|
|
68
|
+
|
|
69
|
+
## Notes
|
|
70
|
+
|
|
71
|
+
- `release:dry-run` keeps its staging directory on failure for debugging.
|
|
72
|
+
- `release:check` and `release:dry-run` both avoid mutating the live repository package metadata.
|