@jonathanleelx/meddle 0.5.0-beta.22 → 0.5.0-beta.24

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 (114) hide show
  1. package/CONFIG_STRUCTURE.md +1 -0
  2. package/README.md +16 -0
  3. package/bin/commands/route/active.js +14 -1
  4. package/bin/commands/route/add.js +27 -30
  5. package/bin/commands/route/delete.js +31 -30
  6. package/bin/commands/route/index.js +4 -0
  7. package/bin/commands/route/list.js +2 -2
  8. package/bin/commands/route/show.js +10 -1
  9. package/bin/commands/route/update.js +32 -30
  10. package/bin/lib/api-client.js +14 -2
  11. package/bin/lib/file-access.js +39 -1
  12. package/bin/lib/rule-file-edit.js +263 -0
  13. package/bin/lib/ruleset-readonly.js +61 -0
  14. package/dist/core/mock-handler.d.ts +0 -6
  15. package/dist/core/mock-handler.d.ts.map +1 -1
  16. package/dist/core/mock-handler.js +101 -11
  17. package/dist/core/mock-handler.js.map +1 -1
  18. package/dist/core/rule-file-edit.d.ts +81 -0
  19. package/dist/core/rule-file-edit.d.ts.map +1 -0
  20. package/dist/core/rule-file-edit.js +243 -0
  21. package/dist/core/rule-file-edit.js.map +1 -0
  22. package/dist/core/static-server.d.ts.map +1 -1
  23. package/dist/core/static-server.js +15 -13
  24. package/dist/core/static-server.js.map +1 -1
  25. package/dist/server/agent/tools.d.ts.map +1 -1
  26. package/dist/server/agent/tools.js +18 -17
  27. package/dist/server/agent/tools.js.map +1 -1
  28. package/dist/server/app-info.d.ts +14 -0
  29. package/dist/server/app-info.d.ts.map +1 -1
  30. package/dist/server/app-info.js +33 -1
  31. package/dist/server/app-info.js.map +1 -1
  32. package/dist/server/config.d.ts.map +1 -1
  33. package/dist/server/config.js +51 -9
  34. package/dist/server/config.js.map +1 -1
  35. package/dist/server/index.d.ts.map +1 -1
  36. package/dist/server/index.js +1 -0
  37. package/dist/server/index.js.map +1 -1
  38. package/dist/server/rule-files.d.ts +23 -0
  39. package/dist/server/rule-files.d.ts.map +1 -1
  40. package/dist/server/rule-files.js +169 -81
  41. package/dist/server/rule-files.js.map +1 -1
  42. package/dist/server/ruleset-lock.d.ts +62 -0
  43. package/dist/server/ruleset-lock.d.ts.map +1 -0
  44. package/dist/server/ruleset-lock.js +234 -0
  45. package/dist/server/ruleset-lock.js.map +1 -0
  46. package/mcp-server.js +87 -88
  47. package/package.json +1 -1
  48. package/web/dist/assets/{checkbox-v2kzp7K8.js → checkbox-CQyFsZzS.js} +1 -1
  49. package/web/dist/assets/detail-panel-D56nCma2.js +4 -0
  50. package/web/dist/assets/dist-BQN0rzUS.js +1 -0
  51. package/web/dist/assets/dist-DLQKRjuW.js +5 -0
  52. package/web/dist/assets/es2015-DPJTBYa9.js +41 -0
  53. package/web/dist/assets/{global-panel-shell-D32I98dR.js → global-panel-shell-SKPshqTf.js} +2 -2
  54. package/web/dist/assets/health-panel-CvI-VsvG.js +1 -0
  55. package/web/dist/assets/index-C6dPxxT3.css +2 -0
  56. package/web/dist/assets/index-Dcm171u1.js +21 -0
  57. package/web/dist/assets/mobile-proxy-panel-cpkvsdBT.js +8 -0
  58. package/web/dist/assets/mock-config-CtZ866iI.js +1 -0
  59. package/web/dist/assets/mock-editor-panel-CweYBdeM.js +20 -0
  60. package/web/dist/assets/{mocks-file-missing-note-DmrrCBYY.js → mocks-file-missing-note-C-QJ8Bpm.js} +1 -1
  61. package/web/dist/assets/{monaco-editor-6oLiu4W6.js → monaco-editor-Cge8h-Ca.js} +2 -2
  62. package/web/dist/assets/pane-bar-Dvi-MHuB.js +1 -0
  63. package/web/dist/assets/{pane-split-DYB05onX.js → pane-split-ChCHxR7K.js} +1 -1
  64. package/web/dist/assets/panel-heading-Crmy9fo0.js +1 -0
  65. package/web/dist/assets/plugin-code-editor-VaL2lVyD.js +2 -0
  66. package/web/dist/assets/plugin-config-DSiOk77l.js +2 -0
  67. package/web/dist/assets/{plugin-generator-Ba4hP5rg.js → plugin-generator-iAksMY2Q.js} +2 -2
  68. package/web/dist/assets/plugin-test-dialog-Cx6ifDnm.js +7 -0
  69. package/web/dist/assets/route-preview-T0s6si4V.js +1 -0
  70. package/web/dist/assets/{rule-ai-assistant-panel-CQTsZMJu.js → rule-ai-assistant-panel-DzfobTWM.js} +2 -2
  71. package/web/dist/assets/rule-config-ESpfkJg6.js +15 -0
  72. package/web/dist/assets/{rule-overview-panel-CmWdMs4I.js → rule-overview-panel-BswSByar.js} +1 -1
  73. package/web/dist/assets/settings-panel-Cj-1Z8Ow.js +1 -0
  74. package/web/dist/assets/{switch-DpLnRvOJ.js → switch-94vgsMHm.js} +1 -1
  75. package/web/dist/assets/toast-9yeTf7d9.js +1 -0
  76. package/web/dist/assets/use-mocks-file-status-BUIUJ4oQ.js +1 -0
  77. package/web/dist/index.html +11 -10
  78. package/web/dist/assets/detail-panel-DK7pM43g.js +0 -4
  79. package/web/dist/assets/dist-BNcjMpca.js +0 -1
  80. package/web/dist/assets/dist-DD7AvbXP.js +0 -1
  81. package/web/dist/assets/dist-UcOFuoN0.js +0 -5
  82. package/web/dist/assets/es2015-CRmLuA2o.js +0 -41
  83. package/web/dist/assets/health-panel-Dw7qdFVS.js +0 -1
  84. package/web/dist/assets/index-CYUNdxqh.css +0 -2
  85. package/web/dist/assets/index-CkoYwomI.js +0 -18
  86. package/web/dist/assets/mobile-proxy-panel-DtiDkpAa.js +0 -8
  87. package/web/dist/assets/mock-config-C3jSpNNu.js +0 -1
  88. package/web/dist/assets/mock-editor-panel-ByCYWJjO.js +0 -20
  89. package/web/dist/assets/panel-heading-BS8loc49.js +0 -1
  90. package/web/dist/assets/plugin-code-editor-DGzCBEpg.js +0 -2
  91. package/web/dist/assets/plugin-config-NVw234EF.js +0 -2
  92. package/web/dist/assets/plugin-test-dialog-B4ojc2_9.js +0 -7
  93. package/web/dist/assets/route-preview-BspvfNdW.js +0 -1
  94. package/web/dist/assets/rule-config-DDOeMRXa.js +0 -15
  95. package/web/dist/assets/settings-panel-aB0ojA9D.js +0 -1
  96. /package/web/dist/assets/{ai-config-store-B_VpGvwx.js → ai-config-store-C8D_PUGV.js} +0 -0
  97. /package/web/dist/assets/{alert-BmsRCcSL.js → alert-B514Frte.js} +0 -0
  98. /package/web/dist/assets/{babel-D1quDdNt.js → babel-bwZm0qi3.js} +0 -0
  99. /package/web/dist/assets/{body-diff-view-ByCHr9bv.js → body-diff-view-SfLCLzs9.js} +0 -0
  100. /package/web/dist/assets/{clipboard-DUgC_tNv.js → clipboard-Bt1qY01V.js} +0 -0
  101. /package/web/dist/assets/{dist-Bq2klZ3g.js → dist-Bsv9ad5F.js} +0 -0
  102. /package/web/dist/assets/{dist-BCvvYbmI.js → dist-fzPL-8F9.js} +0 -0
  103. /package/web/dist/assets/{dist-YM3jbhT-.js → dist-wv9ebJK_.js} +0 -0
  104. /package/web/dist/assets/{editor-pane-actions-DN-pxFsl.js → editor-pane-actions-_ckwcCII.js} +0 -0
  105. /package/web/dist/assets/{estree--Vq99DGn.js → estree-MatbZDwq.js} +0 -0
  106. /package/web/dist/assets/{html-D2PZBPnP.js → html-CCrsbFYX.js} +0 -0
  107. /package/web/dist/assets/{postcss-DfIslWug.js → postcss-BxN7Gr8n.js} +0 -0
  108. /package/web/dist/assets/{standalone-D-fjaAIs.js → standalone-DsnFnsqM.js} +0 -0
  109. /package/web/dist/assets/{syntax-highlight-EJCxGikd.js → syntax-highlight-BFgN_C0Y.js} +0 -0
  110. /package/web/dist/assets/{table-C3mgEjkP.js → table-DaXD6jJv.js} +0 -0
  111. /package/web/dist/assets/{textarea-BjWF0pk4.js → textarea-9wB8Hsz-.js} +0 -0
  112. /package/web/dist/assets/{wand-sparkles-DDGjzjnX.js → wand-sparkles-Bmt4dDOf.js} +0 -0
  113. /package/web/dist/assets/{wifi-QkTcTrED.js → wifi-Cjj_Br1u.js} +0 -0
  114. /package/web/dist/assets/{zap-CEVoVkAg.js → zap-BuOtogAv.js} +0 -0
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Line-preserving edits of route rule files (issue #145).
3
+ *
4
+ * The old write path parsed a rule file into a ruleMap and rebuilt the whole
5
+ * text, which dropped comments, blank lines and disabled (`//`) rules. These
6
+ * helpers edit only the lines that hold the target pattern; every other line
7
+ * keeps its exact bytes (including its line ending).
8
+ *
9
+ * Kept in sync with bin/lib/rule-file-edit.js (same convention as
10
+ * core/meddle-home.ts ↔ bin/lib/meddle-home.js). The JS copy exists so the CLI
11
+ * and the MCP server do not depend on the compiled dist/ output.
12
+ */
13
+ export declare const SPLIT_UNSAFE_MESSAGE = "\u8BE5\u884C\u5269\u4F59\u7684 pattern \u4EE5 // \u6216 # \u5F00\u5934\uFF0C\u62C6\u5F00\u540E\u4F1A\u88AB\u5F53\u6210\u6CE8\u91CA\uFF0C\u8BF7\u7528\u6587\u672C\u7F16\u8F91\u5668\u624B\u52A8\u4FEE\u6539";
14
+ /**
15
+ * Thrown when splitting a line or removing a pattern would put a pattern that
16
+ * starts with `//` or `#` at the start of a line, turning it into a disabled
17
+ * rule or a comment. The rule file is left untouched.
18
+ */
19
+ export declare class RuleLineSplitError extends Error {
20
+ readonly code = "RULE_LINE_SPLIT_UNSAFE";
21
+ constructor();
22
+ }
23
+ export declare const NEW_RULE_COMMENT_MESSAGE = "\u89C4\u5219\u4E0D\u80FD\u4EE5 // \u6216 # \u5F00\u5934\uFF0C\u5426\u5219\u4F1A\u88AB\u5F53\u6210\u7981\u7528\u884C\u6216\u6CE8\u91CA\u3002\u8981\u5199\u6CE8\u91CA\u6216\u7981\u7528\u89C4\u5219\uFF0C\u8BF7\u7528\u6587\u672C\u7F16\u8F91\u5668\u3002";
24
+ /**
25
+ * Thrown when a NEW rule's pattern starts with `//` or `#`: appended as a line it
26
+ * would read back as a disabled rule or a comment. Same code as RuleLineSplitError.
27
+ */
28
+ export declare class RuleNewRuleCommentError extends Error {
29
+ readonly code = "RULE_LINE_SPLIT_UNSAFE";
30
+ constructor();
31
+ }
32
+ export interface RouteRuleEdit {
33
+ pattern: string;
34
+ target?: string;
35
+ /** `undefined` keeps each edited line's own exclusions. */
36
+ exclusions?: string[];
37
+ }
38
+ interface ParsedRuleLine {
39
+ leading: string;
40
+ patterns: string[];
41
+ target: string;
42
+ exclusions: string[];
43
+ }
44
+ /** Internal key of a pattern token: `[marker]` brackets removed (same as the parser). */
45
+ export declare function patternKey(token: string): string;
46
+ /**
47
+ * Parse one line the way parseEprcWithExclusions does. Returns null for blank
48
+ * lines, `#` comments, `//` disabled rules and lines that are not rules.
49
+ */
50
+ export declare function parseRuleLine(line: string): ParsedRuleLine | null;
51
+ /**
52
+ * Point every enabled occurrence of `pattern` at `target` (if given) and/or set
53
+ * its exclusions (if given; `undefined` keeps each line's own exclusions).
54
+ * Lines that do not contain the pattern are left untouched.
55
+ */
56
+ export declare function updateRouteRule(content: string, edit: RouteRuleEdit): {
57
+ content: string;
58
+ found: boolean;
59
+ };
60
+ /**
61
+ * Add a rule. An existing pattern is updated in place (its exclusions are kept
62
+ * unless `exclusions` is given); otherwise a new line is appended at the end.
63
+ */
64
+ export declare function addRouteRule(content: string, edit: RouteRuleEdit & {
65
+ target: string;
66
+ }): {
67
+ content: string;
68
+ existed: boolean;
69
+ };
70
+ /**
71
+ * Remove every enabled occurrence of `pattern`. Other patterns on the same line
72
+ * stay; a line left without patterns is removed with its line ending.
73
+ */
74
+ export declare function deleteRouteRule(content: string, edit: {
75
+ pattern: string;
76
+ }): {
77
+ content: string;
78
+ found: boolean;
79
+ };
80
+ export {};
81
+ //# sourceMappingURL=rule-file-edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule-file-edit.d.ts","sourceRoot":"","sources":["../../core/rule-file-edit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,eAAO,MAAM,oBAAoB,+MAAoD,CAAA;AAErF;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,4BAA2B;;CAM3C;AAED,eAAO,MAAM,wBAAwB,4PAAoD,CAAA;AAEzF;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,4BAA2B;;CAM3C;AAiBD,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACxB;AAED,UAAU,cAAc;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,yFAAyF;AACzF,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGhD;AAOD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAajE;AA2CD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAEzG;AA+CD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAU7H;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAE/G"}
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ /**
3
+ * Line-preserving edits of route rule files (issue #145).
4
+ *
5
+ * The old write path parsed a rule file into a ruleMap and rebuilt the whole
6
+ * text, which dropped comments, blank lines and disabled (`//`) rules. These
7
+ * helpers edit only the lines that hold the target pattern; every other line
8
+ * keeps its exact bytes (including its line ending).
9
+ *
10
+ * Kept in sync with bin/lib/rule-file-edit.js (same convention as
11
+ * core/meddle-home.ts ↔ bin/lib/meddle-home.js). The JS copy exists so the CLI
12
+ * and the MCP server do not depend on the compiled dist/ output.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.RuleNewRuleCommentError = exports.NEW_RULE_COMMENT_MESSAGE = exports.RuleLineSplitError = exports.SPLIT_UNSAFE_MESSAGE = void 0;
16
+ exports.patternKey = patternKey;
17
+ exports.parseRuleLine = parseRuleLine;
18
+ exports.updateRouteRule = updateRouteRule;
19
+ exports.addRouteRule = addRouteRule;
20
+ exports.deleteRouteRule = deleteRouteRule;
21
+ const MARKER = /\[([^\]]+)\]/;
22
+ const BOM = '\uFEFF';
23
+ exports.SPLIT_UNSAFE_MESSAGE = '该行剩余的 pattern 以 // 或 # 开头,拆开后会被当成注释,请用文本编辑器手动修改';
24
+ /**
25
+ * Thrown when splitting a line or removing a pattern would put a pattern that
26
+ * starts with `//` or `#` at the start of a line, turning it into a disabled
27
+ * rule or a comment. The rule file is left untouched.
28
+ */
29
+ class RuleLineSplitError extends Error {
30
+ constructor() {
31
+ super(exports.SPLIT_UNSAFE_MESSAGE);
32
+ this.code = 'RULE_LINE_SPLIT_UNSAFE';
33
+ this.name = 'RuleLineSplitError';
34
+ }
35
+ }
36
+ exports.RuleLineSplitError = RuleLineSplitError;
37
+ exports.NEW_RULE_COMMENT_MESSAGE = '规则不能以 // 或 # 开头,否则会被当成禁用行或注释。要写注释或禁用规则,请用文本编辑器。';
38
+ /**
39
+ * Thrown when a NEW rule's pattern starts with `//` or `#`: appended as a line it
40
+ * would read back as a disabled rule or a comment. Same code as RuleLineSplitError.
41
+ */
42
+ class RuleNewRuleCommentError extends Error {
43
+ constructor() {
44
+ super(exports.NEW_RULE_COMMENT_MESSAGE);
45
+ this.code = 'RULE_LINE_SPLIT_UNSAFE';
46
+ this.name = 'RuleNewRuleCommentError';
47
+ }
48
+ }
49
+ exports.RuleNewRuleCommentError = RuleNewRuleCommentError;
50
+ function startsAsComment(pattern) {
51
+ return pattern.startsWith('//') || pattern.startsWith('#');
52
+ }
53
+ /**
54
+ * A leading UTF-8 BOM is not part of the first line: strip it before editing
55
+ * and put it back afterwards, so it stays byte-identical even when the first
56
+ * line is split or deleted (JS `trim()` / `\s` treat U+FEFF as whitespace).
57
+ */
58
+ function withBom(content, edit) {
59
+ if (!content.startsWith(BOM))
60
+ return edit(content);
61
+ const result = edit(content.slice(BOM.length));
62
+ return { ...result, content: BOM + result.content };
63
+ }
64
+ /** Internal key of a pattern token: `[marker]` brackets removed (same as the parser). */
65
+ function patternKey(token) {
66
+ const bm = token.match(MARKER);
67
+ return bm ? token.replace(bm[0], bm[1]) : token;
68
+ }
69
+ /** Split into [line, eol, line, eol, ..., line]; the parser splits on /\r?\n/ too. */
70
+ function splitLines(content) {
71
+ return content.split(/(\r?\n)/);
72
+ }
73
+ /**
74
+ * Parse one line the way parseEprcWithExclusions does. Returns null for blank
75
+ * lines, `#` comments, `//` disabled rules and lines that are not rules.
76
+ */
77
+ function parseRuleLine(line) {
78
+ const trimmed = line.trim();
79
+ if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('//'))
80
+ return null;
81
+ const parts = trimmed.split(/\s+/).filter(Boolean);
82
+ const exclusionTokens = parts.filter((p) => p.startsWith('!'));
83
+ const regular = parts.filter((p) => !p.startsWith('!'));
84
+ if (regular.length < 2)
85
+ return null;
86
+ return {
87
+ leading: (line.match(/^\s*/) || [''])[0],
88
+ patterns: regular.slice(0, -1),
89
+ target: regular[regular.length - 1],
90
+ exclusions: exclusionTokens.map((t) => t.slice(1)),
91
+ };
92
+ }
93
+ function formatLine(leading, patterns, exclusions, target) {
94
+ const parts = patterns.slice();
95
+ for (const e of exclusions)
96
+ parts.push(`!${e}`);
97
+ parts.push(target);
98
+ return `${leading}${parts.join(' ')}`;
99
+ }
100
+ function sameList(a, b) {
101
+ return a.length === b.length && a.every((v, i) => v === b[i]);
102
+ }
103
+ /** Replace the last regular (target) token in place, keeping all spacing. */
104
+ function replaceTargetInPlace(line, target) {
105
+ const tokens = line.match(/\s+|\S+/g) || [];
106
+ for (let i = tokens.length - 1; i >= 0; i--) {
107
+ if (/\S/.test(tokens[i]) && !tokens[i].startsWith('!')) {
108
+ tokens[i] = target;
109
+ return tokens.join('');
110
+ }
111
+ }
112
+ return line;
113
+ }
114
+ /** Remove the pattern tokens whose key is in `keys` (and one adjacent separator each). */
115
+ function removePatternTokens(line, keys) {
116
+ const tokens = line.match(/\s+|\S+/g) || [];
117
+ const nonSpace = [];
118
+ tokens.forEach((t, i) => { if (/\S/.test(t))
119
+ nonSpace.push(i); });
120
+ const regularIdx = nonSpace.filter((i) => !tokens[i].startsWith('!'));
121
+ const patternIdx = regularIdx.slice(0, -1);
122
+ const drop = new Set();
123
+ for (const i of patternIdx) {
124
+ if (!keys.has(patternKey(tokens[i])))
125
+ continue;
126
+ drop.add(i);
127
+ // Prefer the separator after the token (a pattern is never the last token).
128
+ if (i + 1 < tokens.length && !/\S/.test(tokens[i + 1]) && !drop.has(i + 1))
129
+ drop.add(i + 1);
130
+ else if (i - 1 > 0 && !/\S/.test(tokens[i - 1]))
131
+ drop.add(i - 1);
132
+ }
133
+ return tokens.filter((_, i) => !drop.has(i)).join('');
134
+ }
135
+ /**
136
+ * Point every enabled occurrence of `pattern` at `target` (if given) and/or set
137
+ * its exclusions (if given; `undefined` keeps each line's own exclusions).
138
+ * Lines that do not contain the pattern are left untouched.
139
+ */
140
+ function updateRouteRule(content, edit) {
141
+ return withBom(content, (text) => updateLines(text, edit));
142
+ }
143
+ function updateLines(content, edit) {
144
+ const { pattern, target, exclusions } = edit;
145
+ const key = patternKey(pattern);
146
+ const userHasMarker = MARKER.test(pattern);
147
+ const segments = splitLines(content);
148
+ let found = false;
149
+ for (let s = 0; s < segments.length; s += 2) {
150
+ const line = segments[s];
151
+ const parsed = parseRuleLine(line);
152
+ if (!parsed || !parsed.patterns.some((p) => patternKey(p) === key))
153
+ continue;
154
+ found = true;
155
+ const nextTarget = target !== undefined ? target : parsed.target;
156
+ const nextExclusions = exclusions !== undefined ? exclusions : parsed.exclusions;
157
+ const exclusionsChanged = !sameList(nextExclusions, parsed.exclusions);
158
+ const markerChanged = userHasMarker && parsed.patterns.some((p) => patternKey(p) === key && p !== pattern);
159
+ if (nextTarget === parsed.target && !exclusionsChanged && !markerChanged)
160
+ continue;
161
+ const allMatch = parsed.patterns.every((p) => patternKey(p) === key);
162
+ if (allMatch && !exclusionsChanged && !markerChanged) {
163
+ segments[s] = replaceTargetInPlace(line, nextTarget);
164
+ continue;
165
+ }
166
+ // Split the line into consecutive groups so other patterns on the same line
167
+ // keep their target / exclusions and the original order is preserved.
168
+ const groups = [];
169
+ for (const p of parsed.patterns) {
170
+ const match = patternKey(p) === key;
171
+ const last = groups[groups.length - 1];
172
+ if (last && last.match === match)
173
+ last.patterns.push(p);
174
+ else
175
+ groups.push({ match, patterns: [p] });
176
+ }
177
+ if (groups.some((g) => startsAsComment(g.match && userHasMarker ? pattern : g.patterns[0])))
178
+ throw new RuleLineSplitError();
179
+ const lines = groups.map((g) => g.match
180
+ ? formatLine(parsed.leading, g.patterns.map((p) => (userHasMarker ? pattern : p)), nextExclusions, nextTarget)
181
+ : formatLine(parsed.leading, g.patterns, parsed.exclusions, parsed.target));
182
+ const eol = segments[s + 1] !== undefined ? segments[s + 1] : (content.includes('\r\n') ? '\r\n' : '\n');
183
+ segments[s] = lines.join(eol);
184
+ }
185
+ return { content: segments.join(''), found };
186
+ }
187
+ /**
188
+ * Add a rule. An existing pattern is updated in place (its exclusions are kept
189
+ * unless `exclusions` is given); otherwise a new line is appended at the end.
190
+ */
191
+ function addRouteRule(content, edit) {
192
+ const updated = updateRouteRule(content, edit);
193
+ if (updated.found)
194
+ return { content: updated.content, existed: true };
195
+ if (startsAsComment(edit.pattern))
196
+ throw new RuleNewRuleCommentError();
197
+ const line = formatLine('', [edit.pattern], edit.exclusions || [], edit.target);
198
+ if (content === '' || content === BOM)
199
+ return { content: content + line, existed: false };
200
+ const eol = content.includes('\r\n') ? '\r\n' : '\n';
201
+ if (/\r?\n$/.test(content))
202
+ return { content: `${content}${line}${eol}`, existed: false };
203
+ return { content: `${content}${eol}${line}`, existed: false };
204
+ }
205
+ /**
206
+ * Remove every enabled occurrence of `pattern`. Other patterns on the same line
207
+ * stay; a line left without patterns is removed with its line ending.
208
+ */
209
+ function deleteRouteRule(content, edit) {
210
+ return withBom(content, (text) => deleteLines(text, edit));
211
+ }
212
+ function deleteLines(content, edit) {
213
+ const key = patternKey(edit.pattern);
214
+ const segments = splitLines(content);
215
+ const out = [];
216
+ let found = false;
217
+ for (let s = 0; s < segments.length; s += 2) {
218
+ const line = segments[s];
219
+ const eol = segments[s + 1];
220
+ const parsed = parseRuleLine(line);
221
+ if (!parsed || !parsed.patterns.some((p) => patternKey(p) === key)) {
222
+ out.push(line);
223
+ if (eol !== undefined)
224
+ out.push(eol);
225
+ continue;
226
+ }
227
+ found = true;
228
+ if (parsed.patterns.every((p) => patternKey(p) === key)) {
229
+ // Drop the whole line. For a last line without a line ending, drop the
230
+ // previous line's ending instead so no dangling empty line is left behind.
231
+ if (eol === undefined && out.length > 0)
232
+ out.pop();
233
+ continue;
234
+ }
235
+ if (startsAsComment(parsed.patterns.find((p) => patternKey(p) !== key)))
236
+ throw new RuleLineSplitError();
237
+ out.push(removePatternTokens(line, new Set([key])));
238
+ if (eol !== undefined)
239
+ out.push(eol);
240
+ }
241
+ return { content: out.join(''), found };
242
+ }
243
+ //# sourceMappingURL=rule-file-edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule-file-edit.js","sourceRoot":"","sources":["../../core/rule-file-edit.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"static-server.d.ts","sourceRoot":"","sources":["../../core/static-server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAS3C,UAAU,yBAAyB;IAC/B,UAAU,EAAE,GAAG,CAAC;IAChB,aAAa,EAAE,GAAG,CAAC;IACnB,GAAG,EAAE,YAAY,CAAC;CACrB;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,yBAAyB,GAAG,IAAI,CAsE5F"}
1
+ {"version":3,"file":"static-server.d.ts","sourceRoot":"","sources":["../../core/static-server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAU3C,UAAU,yBAAyB;IAC/B,UAAU,EAAE,GAAG,CAAC;IAChB,aAAa,EAAE,GAAG,CAAC;IACnB,GAAG,EAAE,YAAY,CAAC;CACrB;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,yBAAyB,GAAG,IAAI,CAyE5F"}
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.handleLocalRequest = handleLocalRequest;
37
37
  const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
+ const ruleset_lock_1 = require("../server/ruleset-lock");
39
40
  const STATIC_MIME = {
40
41
  '.html': 'text/html', '.js': 'application/javascript', '.css': 'text/css',
41
42
  '.json': 'application/json', '.png': 'image/png', '.jpg': 'image/jpeg',
@@ -52,6 +53,14 @@ function handleLocalRequest(req, res, opts) {
52
53
  res.setHeader('Pragma', 'no-cache');
53
54
  res.setHeader('Expires', '0');
54
55
  }
56
+ // Issue #137: the page carries a per-server token that only the web UI uses
57
+ // to lock / unlock rulesets (anti-accident guard, not a security boundary).
58
+ function sendHtml(fullPath) {
59
+ setNoCacheHeaders('text/html');
60
+ res.writeHead(200);
61
+ res.write((0, ruleset_lock_1.injectUiToken)(fs.readFileSync(fullPath, 'utf8'), (0, ruleset_lock_1.getUiToken)(serverContext)));
62
+ res.end();
63
+ }
55
64
  if (req.url && req.url.startsWith('/api')) {
56
65
  serverContext.currentMocksPath = ctx.currentMocksPath;
57
66
  serverContext.routeRules = ctx.routeRules;
@@ -87,12 +96,11 @@ function handleLocalRequest(req, res, opts) {
87
96
  const ext = path.extname(fullPath).toLowerCase();
88
97
  const contentType = STATIC_MIME[ext] || 'application/octet-stream';
89
98
  if (ext === '.html') {
90
- setNoCacheHeaders(contentType);
91
- }
92
- else {
93
- res.setHeader('Content-Type', contentType);
94
- res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
99
+ sendHtml(fullPath);
100
+ return;
95
101
  }
102
+ res.setHeader('Content-Type', contentType);
103
+ res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
96
104
  res.writeHead(200);
97
105
  const stream = fs.createReadStream(fullPath);
98
106
  stream.on('error', (err) => {
@@ -107,20 +115,14 @@ function handleLocalRequest(req, res, opts) {
107
115
  stream.pipe(res);
108
116
  }
109
117
  else {
110
- setNoCacheHeaders('text/html');
111
- res.writeHead(200);
112
- res.write(fs.readFileSync(path.resolve(webDistDir, 'index.html'), 'utf8'));
113
- res.end();
118
+ sendHtml(path.resolve(webDistDir, 'index.html'));
114
119
  }
115
120
  }
116
121
  else {
117
122
  if (req.url === '/' || !req.url.startsWith('/api')) {
118
123
  const legacyHtml = path.resolve(__dirname, '../../index.html');
119
124
  if (fs.existsSync(legacyHtml)) {
120
- setNoCacheHeaders('text/html');
121
- res.writeHead(200);
122
- res.write(fs.readFileSync(legacyHtml, 'utf8'));
123
- res.end();
125
+ sendHtml(legacyHtml);
124
126
  }
125
127
  else {
126
128
  res.writeHead(404);
@@ -1 +1 @@
1
- {"version":3,"file":"static-server.js","sourceRoot":"","sources":["../../core/static-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"static-server.js","sourceRoot":"","sources":["../../core/static-server.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../server/agent/tools.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAoB,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAE/E,KAAK,YAAY,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;AA8qC1C,wBAAgB,gBAAgB,IAAI,YAAY,CA2B/C;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,mBAAmB,EAAE,CAS5E;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY;;;;;;IAQrD"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../server/agent/tools.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAoB,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAE/E,KAAK,YAAY,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;AA8qC1C,wBAAgB,gBAAgB,IAAI,YAAY,CA2B/C;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,mBAAmB,EAAE,CAS5E;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY;;;;;;IAQrD"}
@@ -5,6 +5,7 @@ exports.toToolDefinitions = toToolDefinitions;
5
5
  exports.describeAgentTools = describeAgentTools;
6
6
  const route_preview_1 = require("../../core/route-preview");
7
7
  const helpers_1 = require("../../helpers");
8
+ const rule_file_edit_1 = require("../../core/rule-file-edit");
8
9
  const rule_files_1 = require("../rule-files");
9
10
  const config_1 = require("../config");
10
11
  const mocks_1 = require("../mocks");
@@ -73,7 +74,8 @@ function normalizeRouteRuleAddInput(input) {
73
74
  ruleFile: asString(input.ruleFile, 'ruleFile'),
74
75
  pattern: asString(input.pattern, 'pattern'),
75
76
  target: asString(input.target, 'target'),
76
- exclusions: asStringArray(input.exclusions),
77
+ // Issue #145: omitted exclusions keep an existing rule's own exclusions.
78
+ exclusions: input.exclusions === undefined ? undefined : asStringArray(input.exclusions),
77
79
  };
78
80
  }
79
81
  function normalizeRouteRuleUpdateInput(input) {
@@ -105,16 +107,17 @@ function buildRouteRuleAddContent(input, ctx) {
105
107
  const { ruleMap, excludeMap } = (0, helpers_1.parseEprcWithExclusions)(content);
106
108
  const { internalPattern, markerSuffix } = normalizeRoutePattern(input.pattern);
107
109
  const previousTarget = ruleMap[internalPattern];
108
- ruleMap[internalPattern] = `${input.target}${markerSuffix}`;
109
- excludeMap[internalPattern] = input.exclusions || [];
110
+ const previousExclusions = previousTarget ? excludeMap[internalPattern] || [] : [];
111
+ const exclusions = input.exclusions === undefined ? previousExclusions : input.exclusions;
110
112
  return {
111
113
  content,
112
- newContent: (0, helpers_1.ruleMapToEprcText)(ruleMap, excludeMap),
114
+ // Issue #145: edit only this rule's line(s); other lines keep their exact bytes.
115
+ newContent: (0, rule_file_edit_1.addRouteRule)(content, { pattern: input.pattern, target: input.target, exclusions: input.exclusions }).content,
113
116
  internalPattern,
114
117
  previousTarget,
115
- previousExclusions: previousTarget ? excludeMap[internalPattern] || [] : [],
116
- newTarget: ruleMap[internalPattern],
117
- exclusions: excludeMap[internalPattern] || [],
118
+ previousExclusions,
119
+ newTarget: `${input.target}${markerSuffix}`,
120
+ exclusions,
118
121
  };
119
122
  }
120
123
  function buildRouteRuleUpdateContent(input, ctx) {
@@ -128,11 +131,10 @@ function buildRouteRuleUpdateContent(input, ctx) {
128
131
  const previousExclusions = excludeMap[internalPattern] || [];
129
132
  const nextTarget = input.target ? `${input.target}${markerSuffix}` : previousTarget;
130
133
  const nextExclusions = input.exclusions === undefined ? previousExclusions : input.exclusions;
131
- ruleMap[internalPattern] = nextTarget;
132
- excludeMap[internalPattern] = nextExclusions;
133
134
  return {
134
135
  content,
135
- newContent: (0, helpers_1.ruleMapToEprcText)(ruleMap, excludeMap),
136
+ // Issue #145: edit only this rule's line(s); other lines keep their exact bytes.
137
+ newContent: (0, rule_file_edit_1.updateRouteRule)(content, { pattern: input.pattern, target: input.target || undefined, exclusions: input.exclusions }).content,
136
138
  internalPattern,
137
139
  previousTarget,
138
140
  previousExclusions,
@@ -149,11 +151,10 @@ function buildRouteRuleDeleteContent(input, ctx) {
149
151
  throw new Error(`未找到路由规则: ${input.pattern}`);
150
152
  }
151
153
  const previousExclusions = excludeMap[internalPattern] || [];
152
- delete ruleMap[internalPattern];
153
- delete excludeMap[internalPattern];
154
154
  return {
155
155
  content,
156
- newContent: (0, helpers_1.ruleMapToEprcText)(ruleMap, excludeMap),
156
+ // Issue #145: remove only this rule; other lines keep their exact bytes.
157
+ newContent: (0, rule_file_edit_1.deleteRouteRule)(content, { pattern: input.pattern }).content,
157
158
  internalPattern,
158
159
  previousTarget,
159
160
  previousExclusions,
@@ -449,7 +450,7 @@ function createRouteRuleAddTool() {
449
450
  exclusions: {
450
451
  type: 'array',
451
452
  items: { type: 'string' },
452
- description: '可选排除规则列表。',
453
+ description: '可选排除规则列表。不传时保留该规则原有的排除规则(新规则无排除规则);传 [] 清空。',
453
454
  },
454
455
  },
455
456
  required: ['ruleFile', 'pattern', 'target'],
@@ -466,7 +467,7 @@ function createRouteRuleAddTool() {
466
467
  ruleFile: normalized.ruleFile,
467
468
  pattern: normalized.pattern,
468
469
  target: normalized.target,
469
- exclusions: normalized.exclusions || [],
470
+ exclusions: next.exclusions,
470
471
  overwritesExistingRule: Boolean(next.previousTarget),
471
472
  },
472
473
  input: normalized,
@@ -482,7 +483,7 @@ function createRouteRuleAddTool() {
482
483
  ruleFile: normalized.ruleFile,
483
484
  pattern: normalized.pattern,
484
485
  target: normalized.target,
485
- exclusions: normalized.exclusions || [],
486
+ exclusions: next.exclusions,
486
487
  };
487
488
  },
488
489
  };
@@ -515,7 +516,7 @@ function createRouteRuleUpdateTool() {
515
516
  exclusions: {
516
517
  type: 'array',
517
518
  items: { type: 'string' },
518
- description: '新的排除规则列表;传空数组表示清空。',
519
+ description: '新的排除规则列表。不传时保留该规则原有的排除规则;传 [] 清空。',
519
520
  },
520
521
  },
521
522
  required: ['ruleFile', 'pattern'],