@singbox-iac/cli 0.1.15 → 0.1.17

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 (80) hide show
  1. package/README.md +70 -24
  2. package/dist/cli/commands/author.d.ts +2 -0
  3. package/dist/cli/commands/author.js +49 -19
  4. package/dist/cli/commands/author.js.map +1 -1
  5. package/dist/cli/commands/build.js +25 -13
  6. package/dist/cli/commands/build.js.map +1 -1
  7. package/dist/cli/commands/diagnose.d.ts +2 -0
  8. package/dist/cli/commands/diagnose.js +120 -0
  9. package/dist/cli/commands/diagnose.js.map +1 -0
  10. package/dist/cli/commands/doctor.js +21 -1
  11. package/dist/cli/commands/doctor.js.map +1 -1
  12. package/dist/cli/commands/restart.js +42 -2
  13. package/dist/cli/commands/restart.js.map +1 -1
  14. package/dist/cli/commands/rulesets.d.ts +2 -0
  15. package/dist/cli/commands/rulesets.js +125 -0
  16. package/dist/cli/commands/rulesets.js.map +1 -0
  17. package/dist/cli/commands/runtime-watchdog.d.ts +2 -0
  18. package/dist/cli/commands/runtime-watchdog.js +45 -0
  19. package/dist/cli/commands/runtime-watchdog.js.map +1 -0
  20. package/dist/cli/commands/setup.js +190 -20
  21. package/dist/cli/commands/setup.js.map +1 -1
  22. package/dist/cli/commands/start.js +29 -1
  23. package/dist/cli/commands/start.js.map +1 -1
  24. package/dist/cli/commands/status.js +135 -28
  25. package/dist/cli/commands/status.js.map +1 -1
  26. package/dist/cli/commands/stop.js +19 -1
  27. package/dist/cli/commands/stop.js.map +1 -1
  28. package/dist/cli/commands/use.js +3 -1
  29. package/dist/cli/commands/use.js.map +1 -1
  30. package/dist/cli/index.js +12 -4
  31. package/dist/cli/index.js.map +1 -1
  32. package/dist/config/schema.d.ts +49 -6
  33. package/dist/config/schema.js +17 -0
  34. package/dist/config/schema.js.map +1 -1
  35. package/dist/modules/authoring/index.js +25 -8
  36. package/dist/modules/authoring/index.js.map +1 -1
  37. package/dist/modules/build/index.d.ts +4 -1
  38. package/dist/modules/build/index.js +17 -4
  39. package/dist/modules/build/index.js.map +1 -1
  40. package/dist/modules/bundle-registry/index.d.ts +46 -0
  41. package/dist/modules/bundle-registry/index.js +650 -0
  42. package/dist/modules/bundle-registry/index.js.map +1 -0
  43. package/dist/modules/desktop-runtime/index.d.ts +11 -0
  44. package/dist/modules/desktop-runtime/index.js +41 -0
  45. package/dist/modules/desktop-runtime/index.js.map +1 -1
  46. package/dist/modules/diagnostics/index.d.ts +28 -0
  47. package/dist/modules/diagnostics/index.js +288 -0
  48. package/dist/modules/diagnostics/index.js.map +1 -0
  49. package/dist/modules/layered-authoring/index.d.ts +45 -0
  50. package/dist/modules/layered-authoring/index.js +549 -0
  51. package/dist/modules/layered-authoring/index.js.map +1 -0
  52. package/dist/modules/natural-language/index.d.ts +6 -3
  53. package/dist/modules/natural-language/index.js +74 -69
  54. package/dist/modules/natural-language/index.js.map +1 -1
  55. package/dist/modules/proxifier/index.d.ts +1 -14
  56. package/dist/modules/proxifier/index.js +10 -139
  57. package/dist/modules/proxifier/index.js.map +1 -1
  58. package/dist/modules/rule-set-catalog/index.d.ts +25 -0
  59. package/dist/modules/rule-set-catalog/index.js +135 -0
  60. package/dist/modules/rule-set-catalog/index.js.map +1 -0
  61. package/dist/modules/runtime-watchdog/index.d.ts +73 -0
  62. package/dist/modules/runtime-watchdog/index.js +532 -0
  63. package/dist/modules/runtime-watchdog/index.js.map +1 -0
  64. package/dist/modules/status/index.d.ts +48 -0
  65. package/dist/modules/status/index.js +254 -23
  66. package/dist/modules/status/index.js.map +1 -1
  67. package/dist/modules/system-proxy/index.d.ts +31 -0
  68. package/dist/modules/system-proxy/index.js +164 -0
  69. package/dist/modules/system-proxy/index.js.map +1 -0
  70. package/docs/agent-context.md +131 -0
  71. package/docs/natural-language-authoring.md +106 -1
  72. package/docs/proxifier-onboarding.md +15 -4
  73. package/docs/rule-templates.md +2 -0
  74. package/docs/runtime-modes.md +84 -0
  75. package/docs/runtime-on-macos.md +53 -4
  76. package/examples/builder.config.yaml +60 -0
  77. package/package.json +3 -2
  78. package/dist/cli/commands/quickstart.d.ts +0 -2
  79. package/dist/cli/commands/quickstart.js +0 -54
  80. package/dist/cli/commands/quickstart.js.map +0 -1
@@ -35,7 +35,7 @@ export function registerDoctorCommand(program) {
35
35
  : {}),
36
36
  });
37
37
  }
38
- process.stdout.write(`${report.checks.map((check) => `[${check.status}] ${check.name}: ${check.details}`).join("\n")}\n`);
38
+ process.stdout.write(renderDoctorOutput(report, configPath));
39
39
  if (report.checks.some((check) => check.status === "FAIL")) {
40
40
  throw new Error("Doctor found blocking failures.");
41
41
  }
@@ -44,4 +44,24 @@ export function registerDoctorCommand(program) {
44
44
  function pathResolve(filePath) {
45
45
  return filePath.startsWith("/") ? filePath : path.resolve(process.cwd(), filePath);
46
46
  }
47
+ function renderDoctorOutput(report, configPath) {
48
+ const lines = [
49
+ "Readiness check: environment and config prerequisites for singbox-iac.",
50
+ "",
51
+ ...renderSection("Context", [`config: ${configPath ?? "(missing)"}`]),
52
+ "",
53
+ ...renderSection("Checks", report.checks.map((check) => `[${check.status}] ${check.name}: ${check.details}`)),
54
+ "",
55
+ ...renderSection("Result", [formatDoctorResult(report.checks)]),
56
+ ];
57
+ return `${lines.join("\n")}\n`;
58
+ }
59
+ function formatDoctorResult(checks) {
60
+ return checks.some((check) => check.status === "FAIL")
61
+ ? "blocking-failures: yes"
62
+ : "blocking-failures: no";
63
+ }
64
+ function renderSection(title, items) {
65
+ return [`${title}:`, ...items.map((item) => `- ${item}`)];
66
+ }
47
67
  //# sourceMappingURL=doctor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  import path from "node:path";
2
2
  import { installDesktopRuntimeAgent, removeDesktopRuntimeAgent, restartDesktopRuntimeAgent, } from "../../modules/desktop-runtime/index.js";
3
3
  import { checkConfig, resolveSingBoxBinary } from "../../modules/manager/index.js";
4
- import { resolveBuilderConfig } from "../command-helpers.js";
4
+ import { installRuntimeWatchdogAgent, removeRuntimeWatchdogAgent, } from "../../modules/runtime-watchdog/index.js";
5
+ import { findDefaultConfigPath, resolveBuilderConfig, resolveCliEntrypoint, } from "../command-helpers.js";
5
6
  export function registerRestartCommand(program) {
6
7
  program
7
8
  .command("restart")
@@ -14,13 +15,20 @@ export function registerRestartCommand(program) {
14
15
  .option("--no-load", "write the runtime LaunchAgent without calling launchctl bootstrap")
15
16
  .action(async (options) => {
16
17
  const builderConfig = await resolveBuilderConfig(options);
18
+ const configPath = options.config
19
+ ? resolvePath(options.config)
20
+ : await findDefaultConfigPath();
17
21
  if (!builderConfig) {
18
22
  throw new Error("Restart requires a builder config. Run `singbox-iac go` first.");
19
23
  }
24
+ if (!configPath) {
25
+ throw new Error("Restart requires a builder config path.");
26
+ }
20
27
  if (builderConfig.runtime.desktop.profile === "none") {
21
28
  throw new Error("Desktop runtime profile is disabled in this config. Re-run onboarding or set runtime.desktop.profile first.");
22
29
  }
23
30
  const label = options.label ?? builderConfig.runtime.desktop.launchAgentLabel;
31
+ const watchdogLabel = builderConfig.runtime.desktop.watchdog.launchAgentLabel;
24
32
  const singBoxBinary = await resolveSingBoxBinary(options.singBoxBin ? resolvePath(options.singBoxBin) : undefined, builderConfig.runtime.dependencies.singBoxBinary);
25
33
  await checkConfig({
26
34
  configPath: builderConfig.output.livePath,
@@ -29,7 +37,9 @@ export function registerRestartCommand(program) {
29
37
  const hasOverrides = options.singBoxBin !== undefined ||
30
38
  options.launchAgentsDir !== undefined ||
31
39
  options.logsDir !== undefined;
32
- if (options.load !== false && !hasOverrides) {
40
+ const needsWatchdogLifecycle = builderConfig.runtime.desktop.profile === "system-proxy" &&
41
+ builderConfig.runtime.desktop.watchdog.enabled;
42
+ if (options.load !== false && !hasOverrides && !needsWatchdogLifecycle) {
33
43
  try {
34
44
  await restartDesktopRuntimeAgent({ label });
35
45
  process.stdout.write(`${[
@@ -50,6 +60,15 @@ export function registerRestartCommand(program) {
50
60
  ? { launchAgentsDir: resolvePath(options.launchAgentsDir) }
51
61
  : {}),
52
62
  });
63
+ if (builderConfig.runtime.desktop.profile === "system-proxy" &&
64
+ builderConfig.runtime.desktop.watchdog.enabled) {
65
+ await removeRuntimeWatchdogAgent({
66
+ label: watchdogLabel,
67
+ ...(options.launchAgentsDir
68
+ ? { launchAgentsDir: resolvePath(options.launchAgentsDir) }
69
+ : {}),
70
+ });
71
+ }
53
72
  const result = await installDesktopRuntimeAgent({
54
73
  liveConfigPath: builderConfig.output.livePath,
55
74
  singBoxBinary,
@@ -61,11 +80,32 @@ export function registerRestartCommand(program) {
61
80
  force: true,
62
81
  load: options.load !== false,
63
82
  });
83
+ const watchdogResult = builderConfig.runtime.desktop.profile === "system-proxy" &&
84
+ builderConfig.runtime.desktop.watchdog.enabled
85
+ ? await installRuntimeWatchdogAgent({
86
+ configPath,
87
+ cliEntrypoint: resolveCliEntrypoint(import.meta.url),
88
+ intervalSeconds: builderConfig.runtime.desktop.watchdog.intervalSeconds,
89
+ label: watchdogLabel,
90
+ ...(options.launchAgentsDir
91
+ ? { launchAgentsDir: resolvePath(options.launchAgentsDir) }
92
+ : {}),
93
+ ...(options.logsDir ? { logsDir: resolvePath(options.logsDir) } : {}),
94
+ force: true,
95
+ load: options.load !== false,
96
+ })
97
+ : undefined;
64
98
  process.stdout.write(`${[
65
99
  `Restarted desktop runtime profile: ${builderConfig.runtime.desktop.profile}`,
66
100
  `Label: ${result.label}`,
67
101
  `Live config: ${builderConfig.output.livePath}`,
68
102
  `LaunchAgent: ${result.plistPath}`,
103
+ ...(watchdogResult
104
+ ? [
105
+ `Watchdog: ${watchdogResult.label}`,
106
+ `Watchdog LaunchAgent: ${watchdogResult.plistPath}`,
107
+ ]
108
+ : []),
69
109
  ].join("\n")}\n`);
70
110
  });
71
111
  }
@@ -1 +1 @@
1
- {"version":3,"file":"restart.js","sourceRoot":"","sources":["../../../src/cli/commands/restart.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"restart.js","sourceRoot":"","sources":["../../../src/cli/commands/restart.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerRuleSetsCommand(program: Command): void;
@@ -0,0 +1,125 @@
1
+ import { listBuiltInPreferredSiteRuleSetTags, listSiteBundles, } from "../../modules/bundle-registry/index.js";
2
+ import { defaultOfficialRuleSetCatalogCachePath, loadOfficialRuleSetCatalog, } from "../../modules/rule-set-catalog/index.js";
3
+ import { findDefaultConfigPath, resolveBuilderConfig } from "../command-helpers.js";
4
+ export function registerRuleSetsCommand(program) {
5
+ const root = program
6
+ .command("rulesets")
7
+ .description("Inspect configured and official sing-box rule-set tags.");
8
+ root
9
+ .command("list")
10
+ .description("Show configured rule sets and refreshable official upstream tags.")
11
+ .option("-c, --config <path>", "path to builder config YAML")
12
+ .option("--refresh", "refresh the official upstream catalog before printing")
13
+ .option("--filter <text>", "only show official tags containing this text")
14
+ .option("--kind <kind>", "filter official tags by kind: geosite, geoip, or all", "all")
15
+ .option("--all", "print all matching official tags in human-readable output")
16
+ .option("--json", "print the full machine-readable report")
17
+ .action(async (options) => {
18
+ const configPath = options.config ?? (await findDefaultConfigPath());
19
+ const config = configPath ? await resolveBuilderConfig({ config: configPath }) : undefined;
20
+ const catalog = await loadOfficialRuleSetCatalog({
21
+ refresh: options.refresh === true,
22
+ cachePath: defaultOfficialRuleSetCatalogCachePath(),
23
+ });
24
+ const configuredTags = [...(config?.ruleSets.map((ruleSet) => ruleSet.tag) ?? [])].sort();
25
+ const configuredTagSet = new Set(configuredTags);
26
+ const filter = options.filter?.toLowerCase().trim();
27
+ const selectedKinds = normalizeKinds(options.kind);
28
+ const geositeTags = filterOfficialTags(catalog.geositeTags, selectedKinds.has("geosite"), filter);
29
+ const geoipTags = filterOfficialTags(catalog.geoipTags, selectedKinds.has("geoip"), filter);
30
+ const builtInBundleCoverage = listSiteBundles()
31
+ .map((bundle) => {
32
+ const preferredRuleSetTags = [...(bundle.preferredRuleSetTags ?? [])];
33
+ return {
34
+ id: bundle.id,
35
+ name: bundle.name,
36
+ preferredRuleSetTags,
37
+ activeRuleSetTags: preferredRuleSetTags.filter((tag) => configuredTagSet.has(tag)),
38
+ usingFallback: preferredRuleSetTags.every((tag) => !configuredTagSet.has(tag)),
39
+ };
40
+ })
41
+ .filter((bundle) => bundle.preferredRuleSetTags.length > 0 ||
42
+ (filter
43
+ ? bundle.id.includes(filter) || bundle.name.toLowerCase().includes(filter)
44
+ : true));
45
+ if (options.json === true) {
46
+ process.stdout.write(`${JSON.stringify({
47
+ configPath: configPath ?? null,
48
+ configuredTags,
49
+ officialCatalog: {
50
+ cachePath: catalog.cachePath,
51
+ source: catalog.source,
52
+ refreshedAt: catalog.refreshedAt,
53
+ geositeRef: catalog.geositeRef,
54
+ geoipRef: catalog.geoipRef,
55
+ geositeTags,
56
+ geoipTags,
57
+ },
58
+ builtInSiteBundleCoverage: builtInBundleCoverage,
59
+ builtInPreferredRuleSetTags: listBuiltInPreferredSiteRuleSetTags(),
60
+ }, null, 2)}\n`);
61
+ return;
62
+ }
63
+ const lines = [
64
+ "Rule-set inventory: configured tags plus official upstream geosite/geoip catalog.",
65
+ "",
66
+ "Context",
67
+ `- builder-config: ${configPath ?? "(none)"}`,
68
+ `- cache: ${catalog.cachePath}`,
69
+ `- catalog-source: ${catalog.source}`,
70
+ `- refreshed-at: ${catalog.refreshedAt}`,
71
+ `- upstream-geosite-ref: ${catalog.geositeRef}`,
72
+ `- upstream-geoip-ref: ${catalog.geoipRef}`,
73
+ "",
74
+ "Configured",
75
+ `- count: ${configuredTags.length}`,
76
+ `- tags: ${configuredTags.length > 0 ? configuredTags.join(", ") : "(none)"}`,
77
+ "",
78
+ "Built-In Site Bundle Coverage",
79
+ ];
80
+ if (builtInBundleCoverage.length === 0) {
81
+ lines.push("- bundles: (none)");
82
+ }
83
+ else {
84
+ for (const bundle of builtInBundleCoverage) {
85
+ lines.push(`- ${bundle.name}: preferred=${bundle.preferredRuleSetTags.join(", ")}; active=${bundle.activeRuleSetTags.length > 0 ? bundle.activeRuleSetTags.join(", ") : "(none)"}; mode=${bundle.usingFallback ? "fallback" : "rule-set"}`);
86
+ }
87
+ }
88
+ lines.push("", "Official Catalog", `- geosite-count: ${geositeTags.length}`, `- geoip-count: ${geoipTags.length}`);
89
+ if (filter) {
90
+ lines.push(`- filter: ${filter}`);
91
+ }
92
+ if (options.all === true || filter) {
93
+ if (geositeTags.length > 0) {
94
+ lines.push(`- geosite-tags: ${geositeTags.join(", ")}`);
95
+ }
96
+ if (geoipTags.length > 0) {
97
+ lines.push(`- geoip-tags: ${geoipTags.join(", ")}`);
98
+ }
99
+ }
100
+ else {
101
+ lines.push("- official-tags: use --all or --filter <text> to inspect individual upstream tags");
102
+ }
103
+ process.stdout.write(`${lines.join("\n")}\n`);
104
+ });
105
+ }
106
+ function normalizeKinds(kind) {
107
+ const normalized = kind.toLowerCase();
108
+ if (normalized === "geosite") {
109
+ return new Set(["geosite"]);
110
+ }
111
+ if (normalized === "geoip") {
112
+ return new Set(["geoip"]);
113
+ }
114
+ return new Set(["geosite", "geoip"]);
115
+ }
116
+ function filterOfficialTags(tags, enabled, filter) {
117
+ if (!enabled) {
118
+ return [];
119
+ }
120
+ if (!filter) {
121
+ return tags;
122
+ }
123
+ return tags.filter((tag) => tag.toLowerCase().includes(filter));
124
+ }
125
+ //# sourceMappingURL=rulesets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rulesets.js","sourceRoot":"","sources":["../../../src/cli/commands/rulesets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerRuntimeWatchdogCommand(program: Command): void;
@@ -0,0 +1,45 @@
1
+ import path from "node:path";
2
+ import { loadConfig } from "../../config/load-config.js";
3
+ import { runRuntimeWatchdogTick } from "../../modules/runtime-watchdog/index.js";
4
+ import { findDefaultConfigPath } from "../command-helpers.js";
5
+ export function registerRuntimeWatchdogCommand(program) {
6
+ program
7
+ .command("runtime-watchdog")
8
+ .description("Internal command used by the desktop runtime watchdog LaunchAgent.")
9
+ .option("-c, --config <path>", "path to builder config YAML")
10
+ .option("--json", "print machine-readable JSON")
11
+ .action(async (options) => {
12
+ const configPath = options.config
13
+ ? resolvePath(options.config)
14
+ : await findDefaultConfigPath();
15
+ if (!configPath) {
16
+ throw new Error("runtime-watchdog requires a builder config path.");
17
+ }
18
+ const config = await loadConfig(configPath);
19
+ const result = await runRuntimeWatchdogTick({
20
+ config,
21
+ configPath,
22
+ });
23
+ if (options.json) {
24
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
25
+ return;
26
+ }
27
+ process.stdout.write(`${[
28
+ `Watchdog label: ${config.runtime.desktop.watchdog.launchAgentLabel}`,
29
+ `Result: ${result.state.lastResult}`,
30
+ ...(result.state.lastRecoveryAction
31
+ ? [`Recovery action: ${result.state.lastRecoveryAction}`]
32
+ : []),
33
+ ...(result.state.lastTrigger ? [`Trigger: ${result.state.lastTrigger}`] : []),
34
+ `Recorded: ${result.state.lastCheckedAt}`,
35
+ `Message: ${result.state.lastMessage}`,
36
+ ...(result.state.lastReassertAt ? [`Last reassert: ${result.state.lastReassertAt}`] : []),
37
+ ...(result.state.lastRestartAt ? [`Last restart: ${result.state.lastRestartAt}`] : []),
38
+ ...(result.state.lastError ? [`Error: ${result.state.lastError}`] : []),
39
+ ].join("\n")}\n`);
40
+ });
41
+ }
42
+ function resolvePath(filePath) {
43
+ return filePath.startsWith("/") ? filePath : path.resolve(process.cwd(), filePath);
44
+ }
45
+ //# sourceMappingURL=runtime-watchdog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-watchdog.js","sourceRoot":"","sources":["../../../src/cli/commands/runtime-watchdog.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,MAAM,UAAU,8BAA8B,CAAC,OAAgB;IAC7D,OAAO;SACJ,OAAO,CAAC,kBAAkB,CAAC;SAC3B,WAAW,CAAC,oEAAoE,CAAC;SACjF,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;SAC5D,MAAM,CAAC,QAAQ,EAAE,6BAA6B,CAAC;SAC/C,MAAM,CAAC,KAAK,EAAE,OAAsC,EAAE,EAAE;QACvD,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM;YAC/B,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;YAC7B,CAAC,CAAC,MAAM,qBAAqB,EAAE,CAAC;QAClC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACtE,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC;YAC1C,MAAM;YACN,UAAU;SACX,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YAC7D,OAAO;QACT,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG;YACD,mBAAmB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,EAAE;YACrE,WAAW,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE;YACpC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB;gBACjC,CAAC,CAAC,CAAC,oBAAoB,MAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC;gBACzD,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7E,aAAa,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE;YACzC,YAAY,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE;YACtC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,kBAAkB,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACzF,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,iBAAiB,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtF,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SACxE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CACjB,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC;AAOD,SAAS,WAAW,CAAC,QAAgB;IACnC,OAAO,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;AACrF,CAAC"}
@@ -9,6 +9,7 @@ import { buildConfigArtifact, resolveEffectiveIntent } from "../../modules/build
9
9
  import { updateBuilderDesktopRuntime } from "../../modules/desktop-runtime/index.js";
10
10
  import { runDoctor } from "../../modules/doctor/index.js";
11
11
  import { initWorkspace } from "../../modules/init/index.js";
12
+ import { applyLayeredAuthoringUpdate, materializeLayeredAuthoringState, resolveLayeredAuthoringPath, resolveLayeredAuthoringState, writeLayeredAuthoringState, } from "../../modules/layered-authoring/index.js";
12
13
  import { applyConfig, checkConfig, resolveSingBoxBinary } from "../../modules/manager/index.js";
13
14
  import { applyPlanToBuilderConfig, selectVerificationScenariosForPrompt, updateBuilderAuthoring, writeGeneratedRules, } from "../../modules/natural-language/index.js";
14
15
  import { selectProxifierBundlesFromPrompt, writeProxifierScaffold, } from "../../modules/proxifier/index.js";
@@ -92,23 +93,44 @@ export async function runSetupFlow(options) {
92
93
  ...(options.execCommand ? { execCommand: options.execCommand } : {}),
93
94
  ...(options.execArg.length > 0 ? { execArgs: options.execArg } : {}),
94
95
  });
96
+ const currentLayeredState = await resolveLayeredAuthoringState({
97
+ config: builderConfig,
98
+ });
99
+ const nextLayeredState = applyLayeredAuthoringUpdate({
100
+ current: currentLayeredState.state,
101
+ prompt: options.prompt,
102
+ plan: planResult.plan,
103
+ mode: "replace",
104
+ appliedAt: new Date().toISOString(),
105
+ });
106
+ const nextResolvedLayeredState = materializeLayeredAuthoringState({
107
+ filePath: resolveLayeredAuthoringPath(builderConfig.rules.userRulesFile),
108
+ exists: true,
109
+ state: nextLayeredState,
110
+ });
95
111
  effectiveConfig = applyPlanToBuilderConfig(builderConfig, {
96
112
  rulesPath: builderConfig.rules.userRulesFile,
97
- plan: planResult.plan,
113
+ plan: nextResolvedLayeredState.mergedPlan,
98
114
  });
99
115
  await writeGeneratedRules({
100
116
  filePath: effectiveConfig.rules.userRulesFile,
101
- plan: planResult.plan,
117
+ plan: nextResolvedLayeredState.mergedPlan,
118
+ });
119
+ await writeLayeredAuthoringState({
120
+ rulesPath: effectiveConfig.rules.userRulesFile,
121
+ state: nextLayeredState,
102
122
  });
103
123
  await updateBuilderAuthoring({
104
124
  configPath,
105
125
  rulesPath: effectiveConfig.rules.userRulesFile,
106
- ...(planResult.plan.scheduleIntervalMinutes
107
- ? { intervalMinutes: planResult.plan.scheduleIntervalMinutes }
126
+ ...(nextResolvedLayeredState.mergedPlan.scheduleIntervalMinutes
127
+ ? { intervalMinutes: nextResolvedLayeredState.mergedPlan.scheduleIntervalMinutes }
108
128
  : {}),
109
- ...(planResult.plan.groupDefaults ? { groupDefaults: planResult.plan.groupDefaults } : {}),
110
- ...(planResult.plan.verificationOverrides
111
- ? { verificationOverrides: planResult.plan.verificationOverrides }
129
+ ...(nextResolvedLayeredState.mergedPlan.groupDefaults
130
+ ? { groupDefaults: nextResolvedLayeredState.mergedPlan.groupDefaults }
131
+ : {}),
132
+ ...(nextResolvedLayeredState.mergedPlan.verificationOverrides
133
+ ? { verificationOverrides: nextResolvedLayeredState.mergedPlan.verificationOverrides }
112
134
  : {}),
113
135
  });
114
136
  builderConfig = await loadConfig(configPath);
@@ -116,9 +138,13 @@ export async function runSetupFlow(options) {
116
138
  planSummary = {
117
139
  providerRequested: planResult.providerRequested,
118
140
  providerUsed: planResult.providerUsed,
119
- templates: planResult.plan.templateIds,
120
- generatedRules: planResult.plan.beforeBuiltins.length + planResult.plan.afterBuiltins.length,
121
- notes: planResult.plan.notes,
141
+ templates: nextResolvedLayeredState.mergedPlan.templateIds,
142
+ generatedRules: nextResolvedLayeredState.mergedPlan.beforeBuiltins.length +
143
+ nextResolvedLayeredState.mergedPlan.afterBuiltins.length,
144
+ notes: nextResolvedLayeredState.mergedPlan.notes,
145
+ intent: nextResolvedLayeredState.mergedIntent,
146
+ ambiguities: planResult.ambiguities,
147
+ groupDefaults: nextResolvedLayeredState.mergedPlan.groupDefaults ?? {},
122
148
  };
123
149
  }
124
150
  const lines = [`Config: ${configPath}`, `Rules: ${effectiveConfig.rules.userRulesFile}`];
@@ -190,13 +216,7 @@ export async function runSetupFlow(options) {
190
216
  lines.push(...formatDoctorSummary(doctorReport));
191
217
  }
192
218
  if (planSummary) {
193
- lines.push(`Provider requested: ${planSummary.providerRequested}`);
194
- lines.push(`Provider used: ${planSummary.providerUsed}`);
195
- lines.push(`Templates: ${planSummary.templates.length > 0 ? planSummary.templates.join(", ") : "(none)"}`);
196
- lines.push(`Generated rules: ${planSummary.generatedRules}`);
197
- if (planSummary.notes.length > 0) {
198
- lines.push(...planSummary.notes.map((note) => `- ${note}`));
199
- }
219
+ lines.push(...formatIntentSummary(planSummary));
200
220
  }
201
221
  const selectedProxifierBundles = options.prompt
202
222
  ? selectProxifierBundlesFromPrompt(options.prompt)
@@ -290,7 +310,7 @@ export async function runSetupFlow(options) {
290
310
  configuredScenarios: effectiveConfig.verification.scenarios,
291
311
  });
292
312
  assertVerificationReportPassed(verification);
293
- lines.push(`Verified scenarios: ${verification.scenarios.filter((scenario) => scenario.passed).length}/${verification.scenarios.length}`);
313
+ lines.push(...formatVerificationSummary(verification));
294
314
  }
295
315
  if (shouldApply) {
296
316
  await applyConfig({
@@ -345,6 +365,9 @@ export async function runSetupFlow(options) {
345
365
  lines.push(`LaunchAgent: ${schedule.plistPath}`);
346
366
  }
347
367
  lines.push(`Proxy ports: mixed ${effectiveConfig.listeners.mixed.listen}:${effectiveConfig.listeners.mixed.port}, proxifier ${effectiveConfig.listeners.proxifier.listen}:${effectiveConfig.listeners.proxifier.port}`);
368
+ if (!shouldRun) {
369
+ lines.push("Runtime: not started (--no-run).");
370
+ }
348
371
  if (shouldApply) {
349
372
  lines.push(desktopRuntimeProfile === "none"
350
373
  ? "Next: sing-box run -c ~/.config/sing-box/config.json"
@@ -360,7 +383,7 @@ export async function runSetupFlow(options) {
360
383
  lines.push("Next: singbox-iac run");
361
384
  lines.push("Next: singbox-iac update --reload");
362
385
  }
363
- process.stdout.write(`${lines.join("\n")}\n`);
386
+ process.stdout.write(`${renderCliSummary(lines)}\n`);
364
387
  if (!shouldRun || !buildSummary) {
365
388
  return;
366
389
  }
@@ -387,7 +410,9 @@ export async function runSetupFlow(options) {
387
410
  if (shouldOpenBrowser) {
388
411
  const runtimeScenarios = selectVerificationScenariosForRuntimeMode(runtimeMode, effectiveConfig.verification.scenarios);
389
412
  const selectedScenarios = options.prompt
390
- ? selectVerificationScenariosForPrompt(options.prompt, runtimeScenarios)
413
+ ? selectVerificationScenariosForPrompt(options.prompt, runtimeScenarios, {
414
+ activeRuleSetTags: effectiveConfig.ruleSets.map((ruleSet) => ruleSet.tag),
415
+ })
391
416
  : runtimeScenarios.slice(0, Math.min(runtimeModeDefaults.visibleBrowserScenarioLimit, runtimeScenarios.length));
392
417
  const visibleScenarios = selectedScenarios.map((scenario) => ({
393
418
  id: scenario.id,
@@ -441,6 +466,151 @@ function formatDoctorSummary(report) {
441
466
  }
442
467
  return lines;
443
468
  }
469
+ function formatIntentSummary(planSummary) {
470
+ const lines = [
471
+ `Intent: provider ${planSummary.providerUsed}${planSummary.providerUsed !== planSummary.providerRequested ? ` (requested ${planSummary.providerRequested})` : ""}`,
472
+ ];
473
+ if (planSummary.templates.length > 0) {
474
+ lines.push(`Intent templates: ${planSummary.templates.join(", ")}`);
475
+ }
476
+ const strategyLines = [
477
+ ...formatProcessPolicies(planSummary.intent),
478
+ ...formatSitePolicies(planSummary.intent.sitePolicies),
479
+ ...formatGroupDefaults(planSummary.groupDefaults),
480
+ ];
481
+ if (strategyLines.length > 0) {
482
+ lines.push(`Intent strategies (${strategyLines.length}):`);
483
+ lines.push(...strategyLines.map((line) => `- ${line}`));
484
+ }
485
+ lines.push(`Generated rules: ${planSummary.generatedRules}`);
486
+ if (planSummary.notes.length > 0) {
487
+ lines.push(...planSummary.notes.map((note) => `- ${note}`));
488
+ }
489
+ return lines;
490
+ }
491
+ function formatProcessPolicies(intent) {
492
+ return intent.processPolicies.map((policy) => {
493
+ const target = formatProcessMatchers(policy.match);
494
+ return `${target} -> ${policy.outboundGroup} via ${policy.inbound}`;
495
+ });
496
+ }
497
+ function formatProcessMatchers(match) {
498
+ const values = [...(match.processName ?? []), ...(match.bundleId ?? [])];
499
+ if (values.length === 0) {
500
+ return "process flow";
501
+ }
502
+ return values.join(", ");
503
+ }
504
+ function formatSitePolicies(sitePolicies) {
505
+ return sitePolicies.slice(0, 8).map((policy) => {
506
+ const matcher = describeSiteMatch(policy);
507
+ if (policy.action.type === "reject") {
508
+ return `${matcher} -> reject`;
509
+ }
510
+ return `${matcher} -> ${policy.action.outboundGroup}`;
511
+ });
512
+ }
513
+ function describeSiteMatch(policy) {
514
+ if (policy.match.domainSuffix?.length) {
515
+ return policy.match.domainSuffix.join(", ");
516
+ }
517
+ if (policy.match.domain?.length) {
518
+ return policy.match.domain.join(", ");
519
+ }
520
+ if (policy.match.ruleSet?.length) {
521
+ return `rule-set ${policy.match.ruleSet.join(", ")}`;
522
+ }
523
+ if (policy.match.inbound?.length) {
524
+ return `inbound ${policy.match.inbound.join(", ")}`;
525
+ }
526
+ if (policy.match.protocol) {
527
+ return `protocol ${policy.match.protocol}`;
528
+ }
529
+ return policy.name ?? "generated policy";
530
+ }
531
+ function formatGroupDefaults(groupDefaults) {
532
+ const knownGroups = [
533
+ ["processProxy", "default Process-Proxy"],
534
+ ["aiOut", "default AI-Out"],
535
+ ["devCommonOut", "default Dev-Common-Out"],
536
+ ["stitchOut", "default Stitch-Out"],
537
+ ];
538
+ const lines = [];
539
+ for (const [key, label] of knownGroups) {
540
+ const override = groupDefaults[key];
541
+ if (!override || typeof override !== "object" || Array.isArray(override)) {
542
+ continue;
543
+ }
544
+ const record = override;
545
+ if (!record.defaultTarget && !record.defaultNodePattern) {
546
+ continue;
547
+ }
548
+ lines.push(`${label} -> ${record.defaultTarget ?? "(unchanged)"}${record.defaultNodePattern ? ` (pattern ${record.defaultNodePattern})` : ""}`);
549
+ }
550
+ return lines;
551
+ }
552
+ function formatVerificationSummary(report) {
553
+ const passed = report.scenarios.filter((scenario) => scenario.passed).length;
554
+ const lines = [`Verified scenarios: ${passed}/${report.scenarios.length}`];
555
+ lines.push(...report.scenarios.map((scenario) => formatVerificationScenario(scenario)));
556
+ return lines;
557
+ }
558
+ function formatVerificationScenario(scenario) {
559
+ const status = scenario.passed ? "PASS" : "FAIL";
560
+ return `- [${status}] ${scenario.name} -> ${scenario.expectedOutboundTag} via ${scenario.inboundTag}`;
561
+ }
562
+ function renderCliSummary(lines) {
563
+ const ansi = createAnsiStyler();
564
+ return lines
565
+ .map((line) => {
566
+ if (line.startsWith("Config:") || line.startsWith("Rules:")) {
567
+ return ansi.header(line);
568
+ }
569
+ if (line.startsWith("Doctor:")) {
570
+ return ansi.section(line);
571
+ }
572
+ if (line.startsWith("Intent:") || line.startsWith("Intent templates:")) {
573
+ return ansi.section(line);
574
+ }
575
+ if (line.startsWith("Intent strategies") || line.startsWith("Verified scenarios:")) {
576
+ return ansi.section(line);
577
+ }
578
+ if (line.startsWith("- [PASS]")) {
579
+ return ansi.success(line);
580
+ }
581
+ if (line.startsWith("- [WARN]") || line.startsWith("Warnings:")) {
582
+ return ansi.warn(line);
583
+ }
584
+ if (line.startsWith("- [FAIL]")) {
585
+ return ansi.fail(line);
586
+ }
587
+ if (line.startsWith("Live:") ||
588
+ line.startsWith("Backup:") ||
589
+ line.startsWith("LaunchAgent:")) {
590
+ return ansi.success(line);
591
+ }
592
+ if (line.startsWith("Runtime: not started")) {
593
+ return ansi.warn(line);
594
+ }
595
+ if (line.startsWith("Next:")) {
596
+ return ansi.info(line);
597
+ }
598
+ return line;
599
+ })
600
+ .join("\n");
601
+ }
602
+ function createAnsiStyler() {
603
+ const enabled = process.stdout.isTTY === true && process.env.NO_COLOR === undefined;
604
+ const wrap = (code, value) => enabled ? `\u001B[${code}m${value}\u001B[0m` : value;
605
+ return {
606
+ header: (value) => wrap("1;36", value),
607
+ section: (value) => wrap("1;34", value),
608
+ success: (value) => wrap("32", value),
609
+ warn: (value) => wrap("33", value),
610
+ fail: (value) => wrap("31", value),
611
+ info: (value) => wrap("36", value),
612
+ };
613
+ }
444
614
  async function pathExists(filePath) {
445
615
  try {
446
616
  await access(filePath, constants.F_OK);