@cybedefend/vibedefend 1.4.7 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/README.md +77 -2
  2. package/dist/api/gateway-request.js +49 -0
  3. package/dist/api/gateway-request.js.map +1 -0
  4. package/dist/api/projects.js +67 -0
  5. package/dist/api/projects.js.map +1 -1
  6. package/dist/api/repository-link.js +157 -0
  7. package/dist/api/repository-link.js.map +1 -0
  8. package/dist/auth/auth-store.js +107 -25
  9. package/dist/auth/auth-store.js.map +1 -1
  10. package/dist/auth/auth.js +21 -0
  11. package/dist/auth/auth.js.map +1 -1
  12. package/dist/clients/cursor.js +5 -1
  13. package/dist/clients/cursor.js.map +1 -1
  14. package/dist/clients/vscode.js +38 -29
  15. package/dist/clients/vscode.js.map +1 -1
  16. package/dist/commands/mcp/allow.js +219 -0
  17. package/dist/commands/mcp/allow.js.map +1 -0
  18. package/dist/commands/mcp/connect.js +337 -0
  19. package/dist/commands/mcp/connect.js.map +1 -0
  20. package/dist/commands/mcp/index.js +170 -0
  21. package/dist/commands/mcp/index.js.map +1 -0
  22. package/dist/commands/mcp/proxy.js +264 -0
  23. package/dist/commands/mcp/proxy.js.map +1 -0
  24. package/dist/commands/mcp/scan.js +349 -0
  25. package/dist/commands/mcp/scan.js.map +1 -0
  26. package/dist/commands/mcp/sync.js +215 -0
  27. package/dist/commands/mcp/sync.js.map +1 -0
  28. package/dist/config.js +6 -0
  29. package/dist/config.js.map +1 -1
  30. package/dist/diagnostics.js +78 -12
  31. package/dist/diagnostics.js.map +1 -1
  32. package/dist/doctor.js +19 -0
  33. package/dist/doctor.js.map +1 -1
  34. package/dist/guards-evaluator/analysis-types.js +27 -0
  35. package/dist/guards-evaluator/analysis-types.js.map +1 -0
  36. package/dist/guards-evaluator/command-analysis.js +572 -0
  37. package/dist/guards-evaluator/command-analysis.js.map +1 -0
  38. package/dist/guards-evaluator/command-view.js +586 -0
  39. package/dist/guards-evaluator/command-view.js.map +1 -0
  40. package/dist/guards-evaluator/env.js +11 -0
  41. package/dist/guards-evaluator/env.js.map +1 -0
  42. package/dist/guards-evaluator/evaluate.js +91 -41
  43. package/dist/guards-evaluator/evaluate.js.map +1 -1
  44. package/dist/guards-evaluator/index.js +2 -1
  45. package/dist/guards-evaluator/index.js.map +1 -1
  46. package/dist/guards-evaluator/inline-code.js +259 -0
  47. package/dist/guards-evaluator/inline-code.js.map +1 -0
  48. package/dist/guards-evaluator/normalize.js +716 -0
  49. package/dist/guards-evaluator/normalize.js.map +1 -0
  50. package/dist/guards-evaluator/preprocess.js +13 -5
  51. package/dist/guards-evaluator/preprocess.js.map +1 -1
  52. package/dist/guards-evaluator/redact.js +19 -0
  53. package/dist/guards-evaluator/redact.js.map +1 -1
  54. package/dist/guards-evaluator/regex.js +25 -3
  55. package/dist/guards-evaluator/regex.js.map +1 -1
  56. package/dist/guards-evaluator/safe-commands.js +155 -0
  57. package/dist/guards-evaluator/safe-commands.js.map +1 -0
  58. package/dist/guards-evaluator/triage.js +315 -0
  59. package/dist/guards-evaluator/triage.js.map +1 -0
  60. package/dist/hook-runner.js +24873 -5068
  61. package/dist/hooks/install.js +38 -0
  62. package/dist/hooks/install.js.map +1 -1
  63. package/dist/hooks/runtime/config.js +38 -0
  64. package/dist/hooks/runtime/config.js.map +1 -1
  65. package/dist/hooks/runtime/emit.js +126 -53
  66. package/dist/hooks/runtime/emit.js.map +1 -1
  67. package/dist/hooks/runtime/fetch-rules.js +27 -7
  68. package/dist/hooks/runtime/fetch-rules.js.map +1 -1
  69. package/dist/hooks/runtime/gateway-http-error.js +34 -0
  70. package/dist/hooks/runtime/gateway-http-error.js.map +1 -0
  71. package/dist/hooks/runtime/guard-rules-cache.js +139 -17
  72. package/dist/hooks/runtime/guard-rules-cache.js.map +1 -1
  73. package/dist/hooks/runtime/guard-violations-buffer.js +321 -48
  74. package/dist/hooks/runtime/guard-violations-buffer.js.map +1 -1
  75. package/dist/hooks/runtime/judge-cache.js +6 -0
  76. package/dist/hooks/runtime/judge-cache.js.map +1 -1
  77. package/dist/hooks/runtime/judge-triage.js +193 -0
  78. package/dist/hooks/runtime/judge-triage.js.map +1 -0
  79. package/dist/hooks/runtime/judge.js +7 -1
  80. package/dist/hooks/runtime/judge.js.map +1 -1
  81. package/dist/hooks/runtime/pre-compact.js +21 -6
  82. package/dist/hooks/runtime/pre-compact.js.map +1 -1
  83. package/dist/hooks/runtime/resolve.js +108 -17
  84. package/dist/hooks/runtime/resolve.js.map +1 -1
  85. package/dist/hooks/runtime/retry-policy.js +57 -0
  86. package/dist/hooks/runtime/retry-policy.js.map +1 -0
  87. package/dist/hooks/runtime/review-sessions.js +74 -0
  88. package/dist/hooks/runtime/review-sessions.js.map +1 -0
  89. package/dist/hooks/runtime/script-resolve.js +695 -0
  90. package/dist/hooks/runtime/script-resolve.js.map +1 -0
  91. package/dist/hooks/runtime/session-activation.js +226 -0
  92. package/dist/hooks/runtime/session-activation.js.map +1 -0
  93. package/dist/hooks/runtime/session-review.js +174 -46
  94. package/dist/hooks/runtime/session-review.js.map +1 -1
  95. package/dist/hooks/runtime/session-start.js +35 -4
  96. package/dist/hooks/runtime/session-start.js.map +1 -1
  97. package/dist/hooks/runtime/session-writes.js +232 -0
  98. package/dist/hooks/runtime/session-writes.js.map +1 -0
  99. package/dist/hooks/runtime/sniff.js +26 -7
  100. package/dist/hooks/runtime/sniff.js.map +1 -1
  101. package/dist/hooks/runtime/target-resolve.js +336 -0
  102. package/dist/hooks/runtime/target-resolve.js.map +1 -0
  103. package/dist/hooks/runtime/unmapped-tools.js +93 -0
  104. package/dist/hooks/runtime/unmapped-tools.js.map +1 -0
  105. package/dist/hooks/runtime/usage-block.js +4 -0
  106. package/dist/hooks/runtime/usage-block.js.map +1 -1
  107. package/dist/hooks/runtime/user-prompt-submit.js +8 -2
  108. package/dist/hooks/runtime/user-prompt-submit.js.map +1 -1
  109. package/dist/hooks/runtime/wire-text.js +41 -0
  110. package/dist/hooks/runtime/wire-text.js.map +1 -0
  111. package/dist/hooks/runtime/work-dir.js +84 -0
  112. package/dist/hooks/runtime/work-dir.js.map +1 -0
  113. package/dist/index.js +45 -12
  114. package/dist/index.js.map +1 -1
  115. package/dist/install.js +174 -11
  116. package/dist/install.js.map +1 -1
  117. package/dist/link.js +74 -48
  118. package/dist/link.js.map +1 -1
  119. package/dist/login.js +99 -14
  120. package/dist/login.js.map +1 -1
  121. package/dist/mcp/auth/agent-sign-ins.js +174 -0
  122. package/dist/mcp/auth/agent-sign-ins.js.map +1 -0
  123. package/dist/mcp/auth/callback.js +200 -0
  124. package/dist/mcp/auth/callback.js.map +1 -0
  125. package/dist/mcp/auth/connect.js +392 -0
  126. package/dist/mcp/auth/connect.js.map +1 -0
  127. package/dist/mcp/auth/discovery.js +399 -0
  128. package/dist/mcp/auth/discovery.js.map +1 -0
  129. package/dist/mcp/auth/oauth.js +326 -0
  130. package/dist/mcp/auth/oauth.js.map +1 -0
  131. package/dist/mcp/auth/probe.js +128 -0
  132. package/dist/mcp/auth/probe.js.map +1 -0
  133. package/dist/mcp/auth/secrets.js +446 -0
  134. package/dist/mcp/auth/secrets.js.map +1 -0
  135. package/dist/mcp/auth/store.js +260 -0
  136. package/dist/mcp/auth/store.js.map +1 -0
  137. package/dist/mcp/auth/tokenSource.js +55 -0
  138. package/dist/mcp/auth/tokenSource.js.map +1 -0
  139. package/dist/mcp/config/atomicWrite.js +98 -0
  140. package/dist/mcp/config/atomicWrite.js.map +1 -0
  141. package/dist/mcp/config/clients.js +171 -0
  142. package/dist/mcp/config/clients.js.map +1 -0
  143. package/dist/mcp/config/cybedefend-servers.js +48 -0
  144. package/dist/mcp/config/cybedefend-servers.js.map +1 -0
  145. package/dist/mcp/config/discover.js +114 -0
  146. package/dist/mcp/config/discover.js.map +1 -0
  147. package/dist/mcp/config/hook.js +123 -0
  148. package/dist/mcp/config/hook.js.map +1 -0
  149. package/dist/mcp/config/index.js +11 -0
  150. package/dist/mcp/config/index.js.map +1 -0
  151. package/dist/mcp/config/install.js +132 -0
  152. package/dist/mcp/config/install.js.map +1 -0
  153. package/dist/mcp/config/installed.js +37 -0
  154. package/dist/mcp/config/installed.js.map +1 -0
  155. package/dist/mcp/config/jsonEdit.js +119 -0
  156. package/dist/mcp/config/jsonEdit.js.map +1 -0
  157. package/dist/mcp/config/lock.js +102 -0
  158. package/dist/mcp/config/lock.js.map +1 -0
  159. package/dist/mcp/config/proxyBinary.js +211 -0
  160. package/dist/mcp/config/proxyBinary.js.map +1 -0
  161. package/dist/mcp/config/rewrite.js +388 -0
  162. package/dist/mcp/config/rewrite.js.map +1 -0
  163. package/dist/mcp/config/types.js +34 -0
  164. package/dist/mcp/config/types.js.map +1 -0
  165. package/dist/mcp/proxy/audit.js +83 -0
  166. package/dist/mcp/proxy/audit.js.map +1 -0
  167. package/dist/mcp/proxy/authInterceptor.js +119 -0
  168. package/dist/mcp/proxy/authInterceptor.js.map +1 -0
  169. package/dist/mcp/proxy/expand.js +93 -0
  170. package/dist/mcp/proxy/expand.js.map +1 -0
  171. package/dist/mcp/proxy/inject.js +397 -0
  172. package/dist/mcp/proxy/inject.js.map +1 -0
  173. package/dist/mcp/proxy/intercept.js +37 -0
  174. package/dist/mcp/proxy/intercept.js.map +1 -0
  175. package/dist/mcp/proxy/jsonrpc.js +153 -0
  176. package/dist/mcp/proxy/jsonrpc.js.map +1 -0
  177. package/dist/mcp/proxy/log.js +109 -0
  178. package/dist/mcp/proxy/log.js.map +1 -0
  179. package/dist/mcp/proxy/paths.js +53 -0
  180. package/dist/mcp/proxy/paths.js.map +1 -0
  181. package/dist/mcp/proxy/proxy.js +510 -0
  182. package/dist/mcp/proxy/proxy.js.map +1 -0
  183. package/dist/mcp/proxy/spec.js +203 -0
  184. package/dist/mcp/proxy/spec.js.map +1 -0
  185. package/dist/mcp/proxy/sse.js +77 -0
  186. package/dist/mcp/proxy/sse.js.map +1 -0
  187. package/dist/mcp/proxy/upstream.js +2 -0
  188. package/dist/mcp/proxy/upstream.js.map +1 -0
  189. package/dist/mcp/proxy/upstreamHttp.js +499 -0
  190. package/dist/mcp/proxy/upstreamHttp.js.map +1 -0
  191. package/dist/mcp/proxy/upstreamStdio.js +188 -0
  192. package/dist/mcp/proxy/upstreamStdio.js.map +1 -0
  193. package/dist/mcp/proxy/upstreams.js +143 -0
  194. package/dist/mcp/proxy/upstreams.js.map +1 -0
  195. package/dist/mcp/proxy/verifyInterceptor.js +559 -0
  196. package/dist/mcp/proxy/verifyInterceptor.js.map +1 -0
  197. package/dist/mcp/proxy/windowsCommand.js +99 -0
  198. package/dist/mcp/proxy/windowsCommand.js.map +1 -0
  199. package/dist/mcp/scan/args.js +228 -0
  200. package/dist/mcp/scan/args.js.map +1 -0
  201. package/dist/mcp/scan/results.js +253 -0
  202. package/dist/mcp/scan/results.js.map +1 -0
  203. package/dist/mcp/scan/types.js +40 -0
  204. package/dist/mcp/scan/types.js.map +1 -0
  205. package/dist/mcp/verify/api.js +475 -0
  206. package/dist/mcp/verify/api.js.map +1 -0
  207. package/dist/mcp/verify/backend.js +143 -0
  208. package/dist/mcp/verify/backend.js.map +1 -0
  209. package/dist/mcp/verify/cache.js +182 -0
  210. package/dist/mcp/verify/cache.js.map +1 -0
  211. package/dist/mcp/verify/contract-errors.js +198 -0
  212. package/dist/mcp/verify/contract-errors.js.map +1 -0
  213. package/dist/mcp/verify/digest.js +91 -0
  214. package/dist/mcp/verify/digest.js.map +1 -0
  215. package/dist/mcp/verify/factory.js +56 -0
  216. package/dist/mcp/verify/factory.js.map +1 -0
  217. package/dist/mcp/verify/identity.js +173 -0
  218. package/dist/mcp/verify/identity.js.map +1 -0
  219. package/dist/mcp/verify/policy-store.js +63 -0
  220. package/dist/mcp/verify/policy-store.js.map +1 -0
  221. package/dist/mcp/verify/policy.js +158 -0
  222. package/dist/mcp/verify/policy.js.map +1 -0
  223. package/dist/mcp/verify/pool.js +27 -0
  224. package/dist/mcp/verify/pool.js.map +1 -0
  225. package/dist/mcp/verify/token-refresh.js +44 -0
  226. package/dist/mcp/verify/token-refresh.js.map +1 -0
  227. package/dist/mcp/verify/token.js +67 -0
  228. package/dist/mcp/verify/token.js.map +1 -0
  229. package/dist/mcp/verify/verifier.js +1009 -0
  230. package/dist/mcp/verify/verifier.js.map +1 -0
  231. package/dist/org-gate.js +1 -1
  232. package/dist/org-gate.js.map +1 -1
  233. package/dist/org.js +146 -0
  234. package/dist/org.js.map +1 -0
  235. package/dist/project-create.js +129 -0
  236. package/dist/project-create.js.map +1 -0
  237. package/dist/prompts.js +21 -0
  238. package/dist/prompts.js.map +1 -1
  239. package/dist/re2.wasm +0 -0
  240. package/dist/status.js +61 -0
  241. package/dist/status.js.map +1 -1
  242. package/dist/uninstall.js +49 -4
  243. package/dist/uninstall.js.map +1 -1
  244. package/dist/utils.js +62 -6
  245. package/dist/utils.js.map +1 -1
  246. package/package.json +10 -3
@@ -0,0 +1,336 @@
1
+ /**
2
+ * Level 0 — disk resolution of ONE raw target path into the set of REAL
3
+ * candidate paths it may resolve to.
4
+ *
5
+ * Why this exists (hardening SPEC, "Measured gaps"): the Action Guards
6
+ * evaluator matches a file path as a LITERAL STRING. That is blind to two
7
+ * trivially evasive shapes:
8
+ *
9
+ * - a shell glob — `cat .en?`, `cat config/*.json` — never literally equals
10
+ * `.env`, so the sensitive-file rule does not fire;
11
+ * - a symlink — `app.py -> /proc/self/environ`, or a link whose name is
12
+ * innocuous but whose target is `.env` — reads the secret while the rule
13
+ * only ever sees `app.py`.
14
+ *
15
+ * The PreToolUse hook runs LOCALLY on the developer machine, so disk access is
16
+ * allowed here. This module turns a raw path (as written in a tool envelope or
17
+ * a command argument) into every real path it may touch, so the integrator can
18
+ * run the file rules against each one:
19
+ *
20
+ * - a leading `~` / `~/` is expanded to `homeDir`;
21
+ * - glob metacharacters (`*`, `?`, `[…]`) are expanded against the REAL
22
+ * filesystem relative to `cwd`, BOUNDED (at most `maxMatches` results and a
23
+ * capped number of directory reads); on the cap it stops and returns what
24
+ * it found plus the original (lexically-normalized) pattern;
25
+ * - every existing result is `realpath()`-ed to follow symlinks; BOTH the
26
+ * lexical path and its realpath target are returned when they differ, so a
27
+ * symlink to `.env` yields the `.env` realpath too;
28
+ * - a path that does NOT exist still contributes its lexically-resolved form
29
+ * (absolute, cwd-joined, `~`-expanded, `.`/`..` collapsed) so rules still
30
+ * fire on a not-yet-existing target;
31
+ * - the lexically-normalized input itself is ALWAYS included (deduped), so
32
+ * the caller never loses the original.
33
+ *
34
+ * Design rules (match the rest of the hardening work):
35
+ * - NEVER THROWS. A symlink loop, a permission error, an ENOENT — all are
36
+ * swallowed and the function returns best-effort. Blindness must fail
37
+ * toward "return more candidates", never toward a silent allow.
38
+ * - BOUNDED TIME. No unbounded recursion: the directory walk is an explicit
39
+ * queue with a readdir budget, a depth cap, and a visited-realpath set that
40
+ * breaks symlink cycles.
41
+ * - INJECTABLE FS. All disk access goes through a minimal `FsLike` passed via
42
+ * `opts.fs` (defaulting to `node:fs`), so tests drive a fake in-memory FS
43
+ * and never touch the real disk.
44
+ */
45
+ import { existsSync as nodeExistsSync, readdirSync as nodeReaddirSync, realpathSync as nodeRealpathSync, statSync as nodeStatSync, lstatSync as nodeLstatSync, } from 'node:fs';
46
+ import { matchGlob } from '../../guards-evaluator/glob.js';
47
+ /** Default: bind `node:fs` into the narrow `FsLike` shape. */
48
+ const DEFAULT_FS = {
49
+ existsSync: (p) => nodeExistsSync(p),
50
+ readdirSync: (p) => nodeReaddirSync(p),
51
+ realpathSync: (p) => nodeRealpathSync(p),
52
+ statSync: (p) => nodeStatSync(p),
53
+ lstatSync: (p) => nodeLstatSync(p),
54
+ };
55
+ const DEFAULT_MAX_MATCHES = 64;
56
+ /** Max directories descended through for a `**` segment. */
57
+ const MAX_DIR_DEPTH = 16;
58
+ // ---------------------------------------------------------------------------
59
+ // Pure path helpers (no I/O)
60
+ // ---------------------------------------------------------------------------
61
+ /** Windows backslashes → forward slashes, consistent with glob.ts. */
62
+ function normSep(s) {
63
+ return s.replace(/\\/g, '/');
64
+ }
65
+ /** Expand a leading `~` / `~/` only; a `~` elsewhere is left untouched. */
66
+ function expandTilde(p, homeDir) {
67
+ if (p === '~')
68
+ return homeDir;
69
+ if (p.startsWith('~/'))
70
+ return homeDir + p.slice(1);
71
+ return p;
72
+ }
73
+ function isAbsolute(p) {
74
+ return p.startsWith('/');
75
+ }
76
+ /**
77
+ * Collapse `.`, `..`, empty and duplicate segments WITHOUT touching glob
78
+ * metacharacters (they live inside a segment, never equal `.`/`..`/'').
79
+ * Assumes `/`-separated input.
80
+ */
81
+ function collapse(p) {
82
+ const abs = isAbsolute(p);
83
+ const out = [];
84
+ for (const part of p.split('/')) {
85
+ if (part === '' || part === '.')
86
+ continue;
87
+ if (part === '..') {
88
+ if (out.length > 0 && out[out.length - 1] !== '..')
89
+ out.pop();
90
+ else if (!abs)
91
+ out.push('..');
92
+ // For an absolute path, a leading `..` is dropped (cannot go above root).
93
+ continue;
94
+ }
95
+ out.push(part);
96
+ }
97
+ const joined = out.join('/');
98
+ if (abs)
99
+ return '/' + joined;
100
+ return joined === '' ? '.' : joined;
101
+ }
102
+ /**
103
+ * Absolute, `~`-expanded, cwd-joined, `.`/`..`-collapsed form of `raw`. Glob
104
+ * metacharacters survive untouched (so it doubles as the absolute pattern for
105
+ * glob expansion).
106
+ */
107
+ function lexicalResolve(raw, cwd, homeDir) {
108
+ let p = expandTilde(normSep(raw), homeDir);
109
+ if (!isAbsolute(p)) {
110
+ const base = cwd === '' ? '/' : cwd;
111
+ p = base + '/' + p;
112
+ }
113
+ return collapse(p);
114
+ }
115
+ function joinPath(dir, name) {
116
+ return dir === '/' ? '/' + name : dir + '/' + name;
117
+ }
118
+ /**
119
+ * A pattern is a glob only for `*` / `?`, or a BALANCED `[…]` character class.
120
+ * A lone `[` with no closing `]` (and no `*`/`?`) is a literal path.
121
+ */
122
+ function hasGlobMeta(p) {
123
+ return /[*?]/.test(p) || /\[[^/\]]*\]/.test(p);
124
+ }
125
+ function dedupe(xs) {
126
+ return [...new Set(xs.filter((x) => x.length > 0))];
127
+ }
128
+ // ---------------------------------------------------------------------------
129
+ // Safe FS wrappers — every one swallows errors (never throw on the hot path)
130
+ // ---------------------------------------------------------------------------
131
+ function safeExists(fs, p) {
132
+ try {
133
+ return fs.existsSync(p);
134
+ }
135
+ catch {
136
+ return false;
137
+ }
138
+ }
139
+ function safeReaddir(fs, p) {
140
+ try {
141
+ const r = fs.readdirSync(p);
142
+ return Array.isArray(r) ? r : [];
143
+ }
144
+ catch {
145
+ return [];
146
+ }
147
+ }
148
+ function safeIsDir(fs, p) {
149
+ try {
150
+ return fs.statSync(p).isDirectory();
151
+ }
152
+ catch {
153
+ return false;
154
+ }
155
+ }
156
+ function safeIsSymlink(fs, p) {
157
+ try {
158
+ return fs.lstatSync(p).isSymbolicLink();
159
+ }
160
+ catch {
161
+ return false;
162
+ }
163
+ }
164
+ /** Realpath, normalized; on any failure returns the input unchanged. */
165
+ function safeRealpath(fs, p) {
166
+ try {
167
+ const r = fs.realpathSync(p);
168
+ return typeof r === 'string' && r.length > 0 ? normSep(r) : p;
169
+ }
170
+ catch {
171
+ return p;
172
+ }
173
+ }
174
+ /**
175
+ * Push `lexPath` and, when it exists (or is a symlink) and its realpath
176
+ * differs, the realpath target too.
177
+ */
178
+ function pushWithReal(out, fs, lexPath) {
179
+ out.push(lexPath);
180
+ if (safeExists(fs, lexPath) || safeIsSymlink(fs, lexPath)) {
181
+ const real = safeRealpath(fs, lexPath);
182
+ if (real !== lexPath)
183
+ out.push(real);
184
+ }
185
+ }
186
+ /**
187
+ * All directories reachable from `starts` (inclusive of `starts` themselves),
188
+ * for a `**` segment. Explicit BFS — bounded by the readdir budget, a depth
189
+ * cap, and a visited-realpath set that breaks symlink cycles.
190
+ */
191
+ function collectDescendants(fs, starts, state) {
192
+ const result = [];
193
+ const visited = new Set();
194
+ const queue = starts.map((d) => ({
195
+ dir: d,
196
+ depth: 0,
197
+ }));
198
+ while (queue.length > 0) {
199
+ if (state.readdirBudget <= 0) {
200
+ state.capped = true;
201
+ break;
202
+ }
203
+ const { dir, depth } = queue.shift();
204
+ const canonical = safeRealpath(fs, dir);
205
+ if (visited.has(canonical))
206
+ continue; // cycle / already seen
207
+ visited.add(canonical);
208
+ result.push(dir);
209
+ if (depth >= MAX_DIR_DEPTH)
210
+ continue;
211
+ state.readdirBudget--;
212
+ for (const name of safeReaddir(fs, dir)) {
213
+ const child = joinPath(dir, name);
214
+ if (safeIsDir(fs, child))
215
+ queue.push({ dir: child, depth: depth + 1 });
216
+ }
217
+ }
218
+ return result;
219
+ }
220
+ /**
221
+ * Expand an absolute `/`-separated glob pattern into existing matches, walking
222
+ * one path segment at a time. Bounded: stops at `maxMatches` matches or once
223
+ * the readdir budget is spent, flagging `capped`.
224
+ */
225
+ function expandGlob(fs, absPattern, homeDir, maxMatches) {
226
+ const matches = [];
227
+ // Budget scales with the match cap but stays bounded for tiny caps.
228
+ const state = {
229
+ readdirBudget: Math.max(256, maxMatches * 8),
230
+ capped: false,
231
+ };
232
+ const addMatch = (p) => {
233
+ if (matches.length >= maxMatches) {
234
+ state.capped = true;
235
+ return;
236
+ }
237
+ matches.push(p);
238
+ };
239
+ const segs = absPattern.split('/').filter((s) => s.length > 0);
240
+ let frontier = ['/'];
241
+ for (let s = 0; s < segs.length; s++) {
242
+ if (state.capped || state.readdirBudget <= 0) {
243
+ state.capped = true;
244
+ break;
245
+ }
246
+ const seg = segs[s];
247
+ const isLast = s === segs.length - 1;
248
+ if (seg === '**') {
249
+ const dirs = collectDescendants(fs, frontier, state);
250
+ if (isLast)
251
+ for (const d of dirs)
252
+ addMatch(d);
253
+ frontier = dirs;
254
+ continue;
255
+ }
256
+ const next = [];
257
+ const glob = hasGlobMeta(seg);
258
+ for (const dir of frontier) {
259
+ if (state.capped || state.readdirBudget <= 0) {
260
+ state.capped = true;
261
+ break;
262
+ }
263
+ if (glob) {
264
+ state.readdirBudget--;
265
+ for (const name of safeReaddir(fs, dir)) {
266
+ if (!matchGlob(seg, name, { homeDir }))
267
+ continue;
268
+ const child = joinPath(dir, name);
269
+ if (isLast) {
270
+ addMatch(child);
271
+ if (state.capped)
272
+ break;
273
+ }
274
+ else if (safeIsDir(fs, child)) {
275
+ next.push(child);
276
+ }
277
+ }
278
+ }
279
+ else {
280
+ // A literal segment: no readdir needed, just probe the one path.
281
+ const child = joinPath(dir, seg);
282
+ if (isLast) {
283
+ if (safeExists(fs, child) || safeIsSymlink(fs, child))
284
+ addMatch(child);
285
+ }
286
+ else if (safeIsDir(fs, child)) {
287
+ next.push(child);
288
+ }
289
+ }
290
+ }
291
+ frontier = next;
292
+ }
293
+ return { matches, capped: state.capped };
294
+ }
295
+ // ---------------------------------------------------------------------------
296
+ // Public entry point
297
+ // ---------------------------------------------------------------------------
298
+ /**
299
+ * Resolve ONE raw path into every real candidate path it may touch. Pure of
300
+ * exceptions; bounded in time. The first element is always the
301
+ * lexically-normalized input; it is followed by glob matches and symlink
302
+ * realpath targets, deduped in first-seen order.
303
+ */
304
+ export function resolveCandidatePaths(rawPath, opts) {
305
+ const out = [];
306
+ try {
307
+ if (typeof rawPath !== 'string' || rawPath.length === 0)
308
+ return [];
309
+ const fs = opts.fs ?? DEFAULT_FS;
310
+ const homeDir = normSep(opts.homeDir ?? '');
311
+ const cwd = normSep(opts.cwd ?? '');
312
+ const maxMatches = typeof opts.maxMatches === 'number' && opts.maxMatches > 0
313
+ ? Math.floor(opts.maxMatches)
314
+ : DEFAULT_MAX_MATCHES;
315
+ // Always include the lexically-normalized input (also the glob pattern
316
+ // itself when the raw path globs). This is the "plus the original pattern"
317
+ // the SPEC requires on a cap, and the caller's guaranteed fallback.
318
+ const lexInput = lexicalResolve(rawPath, cwd, homeDir);
319
+ out.push(lexInput);
320
+ if (hasGlobMeta(rawPath)) {
321
+ const { matches } = expandGlob(fs, lexInput, homeDir, maxMatches);
322
+ for (const m of matches)
323
+ pushWithReal(out, fs, m);
324
+ }
325
+ else {
326
+ // Non-glob: add the realpath target when the lexical path is a symlink
327
+ // (or exists and its canonical form differs).
328
+ pushWithReal(out, fs, lexInput);
329
+ }
330
+ }
331
+ catch {
332
+ // Never throw: return whatever was gathered (at least the lexical input).
333
+ }
334
+ return dedupe(out);
335
+ }
336
+ //# sourceMappingURL=target-resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"target-resolve.js","sourceRoot":"","sources":["../../../src/hooks/runtime/target-resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * BACK-174 — explicit policy + telemetry for tool envelopes the guard cannot
3
+ * map to a file / command / URL target.
4
+ *
5
+ * Before: `unrecognized tool envelope, no guard applied` went to stderr on
6
+ * EVERY such call (five times per session on Claude Code: `ToolSearch` and
7
+ * the `mcp__cybedefend__*` tools), and the action ran unevaluated. A tool
8
+ * type the guard has never seen is a tool type the guard does not guard —
9
+ * that has to be a decision, not an accident, and it has to be visible.
10
+ *
11
+ * Policy:
12
+ * 1. TARGET-LESS tools ({@link isTargetlessTool}) carry nothing to gate by
13
+ * construction (todo lists, sub-agents, skill loading, our own MCP
14
+ * tools). They pass silently; a debug-log line only.
15
+ * 2. Every OTHER unmapped envelope FAILS OPEN (the action runs) but is
16
+ * counted here, in `~/.cybedefend/guards-unmapped-tools.json`, and
17
+ * announced on stderr once per session per tool. `vibedefend status`
18
+ * lists the file so the unguarded surface is reviewable.
19
+ * 3. `CYBEDEFEND_GUARDS_STRICT=1` flips class 2 to fail-CLOSED (exit 2).
20
+ * Class 1 is never blocked — blocking `ToolSearch` would brick the agent.
21
+ */
22
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
23
+ import { dirname, join } from 'node:path';
24
+ import { homedir } from 'node:os';
25
+ import { envFlag } from '../../guards-evaluator/env.js';
26
+ /** Tool names (any agent) that never carry a file, command or URL. */
27
+ const TARGETLESS_TOOL_RE = /^(?:ToolSearch|TodoRead|TodoWrite|Task|Agent|AskUserQuestion|Skill|SlashCommand|EnterPlanMode|ExitPlanMode|EnterWorktree|ExitWorktree|BashOutput|KillShell|KillBash|Monitor|ListMcpResourcesTool|ReadMcpResourceTool|ReadMcpResourceDirTool|ScheduleWakeup|PushNotification|CronCreate|CronDelete|CronList|SendMessage|ListAgents|TaskOutput|TaskStop|ReportFindings|Workflow)$/;
28
+ /** Our own MCP server, under any region alias (`cybedefend`, `cybedefend-us`, …). */
29
+ const OWN_MCP_TOOL_RE = /^mcp__cybedefend(?:-[A-Za-z0-9_-]+)?__/;
30
+ export function isTargetlessTool(tool) {
31
+ if (!tool)
32
+ return false;
33
+ return TARGETLESS_TOOL_RE.test(tool) || OWN_MCP_TOOL_RE.test(tool);
34
+ }
35
+ /** Strict mode: genuinely unmapped envelopes are denied instead of allowed. */
36
+ export function strictUnmappedPolicy() {
37
+ return envFlag('CYBEDEFEND_GUARDS_STRICT');
38
+ }
39
+ /** Distinct tool names kept; the least recently seen are dropped beyond it. */
40
+ const MAX_TOOLS = 200;
41
+ export function defaultUnmappedToolsFile() {
42
+ const dir = process.env.CYBEDEFEND_BASELINE_DIR ?? join(homedir(), '.cybedefend');
43
+ return join(dir, 'guards-unmapped-tools.json');
44
+ }
45
+ function load(file) {
46
+ try {
47
+ if (!existsSync(file))
48
+ return { tools: {} };
49
+ const parsed = JSON.parse(readFileSync(file, 'utf8'));
50
+ if (!parsed || typeof parsed !== 'object' || typeof parsed.tools !== 'object' || !parsed.tools) {
51
+ return { tools: {} };
52
+ }
53
+ return { tools: parsed.tools };
54
+ }
55
+ catch {
56
+ return { tools: {} };
57
+ }
58
+ }
59
+ export function makeUnmappedToolTelemetry(file = defaultUnmappedToolsFile()) {
60
+ return {
61
+ record(tool, client) {
62
+ try {
63
+ const data = load(file);
64
+ const prev = data.tools[tool];
65
+ data.tools[tool] = {
66
+ count: (prev?.count ?? 0) + 1,
67
+ lastSeen: new Date().toISOString(),
68
+ client,
69
+ };
70
+ const names = Object.keys(data.tools);
71
+ if (names.length > MAX_TOOLS) {
72
+ names
73
+ .sort((a, b) => data.tools[a].lastSeen.localeCompare(data.tools[b].lastSeen))
74
+ .slice(0, names.length - MAX_TOOLS)
75
+ .forEach((n) => delete data.tools[n]);
76
+ }
77
+ mkdirSync(dirname(file), { recursive: true });
78
+ writeFileSync(file, JSON.stringify(data, null, 2) + '\n', 'utf8');
79
+ }
80
+ catch {
81
+ // Telemetry must never interfere with the tool call.
82
+ }
83
+ },
84
+ };
85
+ }
86
+ /** Most frequent first. Empty when the file is absent or unreadable. */
87
+ export function readUnmappedTools(file = defaultUnmappedToolsFile()) {
88
+ const data = load(file);
89
+ return Object.entries(data.tools)
90
+ .map(([tool, v]) => ({ tool, count: v.count, lastClient: v.client }))
91
+ .sort((a, b) => b.count - a.count || a.tool.localeCompare(b.tool));
92
+ }
93
+ //# sourceMappingURL=unmapped-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unmapped-tools.js","sourceRoot":"","sources":["../../../src/hooks/runtime/unmapped-tools.ts"],"names":[],"mappings":"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"}
@@ -25,6 +25,7 @@ const REASONS = [
25
25
  'cap_reached',
26
26
  'unpaid',
27
27
  'product_inactive',
28
+ 'contract_limit',
28
29
  ];
29
30
  const WARNINGS = [
30
31
  'approaching_limit',
@@ -114,6 +115,9 @@ export function blockSentence(block) {
114
115
  case 'product_inactive':
115
116
  return ('VibeDefend is not active for your organisation, so rules, Action Guards and diff scans are off. ' +
116
117
  'An administrator can activate it in the CybeDefend dashboard.');
118
+ case 'contract_limit':
119
+ return (`VibeDefend paused: ${label} reached the usage limit of your organisation's VibeDefend contract, so ${effect}. ` +
120
+ 'An administrator can contact CybeDefend.');
117
121
  default:
118
122
  return (`VibeDefend paused: ${label} is blocked for your organisation, so ${effect}. ` +
119
123
  'An administrator can check the VibeDefend usage page.');
@@ -1 +1 @@
1
- {"version":3,"file":"usage-block.js","sourceRoot":"","sources":["../../../src/hooks/runtime/usage-block.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAoB1C,MAAM,CAAC,MAAM,YAAY,GAAG,oBAAoB,CAAC;AACjD,MAAM,CAAC,MAAM,oBAAoB,GAAG,4BAA4B,CAAC;AAEjE,MAAM,KAAK,GAA8B,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;AAChF,MAAM,OAAO,GAAqC;IAChD,qBAAqB;IACrB,aAAa;IACb,QAAQ;IACR,kBAAkB;CACnB,CAAC;AACF,MAAM,QAAQ,GAA0C;IACtD,mBAAmB;IACnB,eAAe;CAChB,CAAC;AAEF,SAAS,IAAI,CACX,OAAqB,EACrB,KAAc;IAEd,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAa;IAEb,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,IAAI,GAAG,IAA+B,CAAC;IAC7C,MAAM,IAAI,GACR,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QACxC,CAAC,CAAE,IAAI,CAAC,IAAgC;QACxC,CAAC,CAAC,IAAI,CAAC;IACX,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACxD,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IAC9C,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,SAAS;QACjD,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS;KAC5C,CAAC;AACJ,CAAC;AAED,6GAA6G;AAC7G,MAAM,UAAU,gBAAgB,CAAC,GAAa;IAC5C,IAAI,GAA8B,CAAC;IACnC,IAAI,CAAC;QACH,GAAG,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,oBAAoB,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,GAA+C;IAC7D,SAAS,EAAE,0BAA0B;IACrC,QAAQ,EAAE,yBAAyB;IACnC,SAAS,EAAE,YAAY;IACvB,OAAO,EAAE,oBAAoB;CAC9B,CAAC;AAEF,2CAA2C;AAC3C,MAAM,WAAW,GAA+C;IAC9D,SAAS,EAAE,uDAAuD;IAClE,QAAQ,EAAE,wCAAwC;IAClD,SAAS,EAAE,6BAA6B;IACxC,OAAO,EAAE,8BAA8B;CACxC,CAAC;AAEF,6EAA6E;AAC7E,MAAM,UAAU,aAAa,CAAC,KAAsB;IAClD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC;QACrB,KAAK,qBAAqB;YACxB,OAAO,CACL,sBAAsB,KAAK,uCAAuC,MAAM,IAAI;gBAC5E,gGAAgG,CACjG,CAAC;QACJ,KAAK,aAAa;YAChB,OAAO,CACL,sBAAsB,KAAK,8DAA8D,MAAM,IAAI;gBACnG,kEAAkE,CACnE,CAAC;QACJ,KAAK,QAAQ;YACX,OAAO,CACL,4HAA4H;gBAC5H,oEAAoE,CACrE,CAAC;QACJ,KAAK,kBAAkB;YACrB,OAAO,CACL,kGAAkG;gBAClG,+DAA+D,CAChE,CAAC;QACJ;YACE,OAAO,CACL,sBAAsB,KAAK,yCAAyC,MAAM,IAAI;gBAC9E,uDAAuD,CACxD,CAAC;IACN,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,CAAyB;IACvD,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,CAAC,OAAO,KAAK,mBAAmB,EAAE,CAAC;QACtC,OAAO,CACL,eAAe,KAAK,iEAAiE;YACrF,8DAA8D,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,CACL,eAAe,KAAK,2FAA2F;QAC/G,gFAAgF,CACjF,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAA4B;IAC1D,QAAQ;IACR,kBAAkB;CACnB,CAAC,CAAC;AAEH,SAAS,QAAQ,CAAC,KAAsB;IACtC,OAAO,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;QACvC,CAAC,CAAC,SAAS,KAAK,CAAC,MAAM,EAAE;QACzB,CAAC,CAAC,SAAS,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;AAC5C,CAAC;AAED,gEAAgE;AAChE,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB,MAAM,UAAU,uBAAuB;IACrC,MAAM,GAAG,GACP,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;IACxE,OAAO,IAAI,CAAC,GAAG,EAAE,6BAA6B,CAAC,CAAC;AAClD,CAAC;AAYD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAA0D,EAAE;IAE5D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,uBAAuB,EAAE,CAAC;IACpD,MAAM,KAAK,GACT,IAAI,CAAC,KAAK;QACV,CAAC,CAAC,IAAY,EAAE,EAAE;YAChB,IAAI,CAAC;gBACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;YAAC,MAAM,CAAC;gBACP,cAAc;YAChB,CAAC;QACH,CAAC,CAAC,CAAC;IAEL,SAAS,IAAI;QACX,IAAI,CAAC;YACH,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBAAE,OAAO,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAuB,CAAC;YAC1E,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC7B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;gBAC7D,CAAC,CAAC,EAAE,CAAC;QACT,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,SAAS,IAAI,CAAC,SAA6B,EAAE,GAAW,EAAE,QAAgB;QACxE,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,MAAM,GAAG,GAAG,SAAS,IAAI,GAAG,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,IAAI,EAAE,CAAC;YACpB,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,OAAO,IAAI,CAAC;YACvC,IAAI,CAAC;gBACH,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC9C,aAAa,CACX,IAAI,EACJ,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,EAC/D,MAAM,CACP,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY;YACd,CAAC;QACH,CAAC;QACD,KAAK,CAAC,gBAAgB,QAAQ,IAAI,CAAC,CAAC;QACpC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO;QACL,WAAW,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,CAChC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;QACxD,aAAa,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,CAC9B,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;KACxE,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"usage-block.js","sourceRoot":"","sources":["../../../src/hooks/runtime/usage-block.ts"],"names":[],"mappings":"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"}
@@ -41,6 +41,7 @@ import { fetchProposalsCount } from './api.js';
41
41
  import { emit } from './emit.js';
42
42
  import { loadRuntimeConfig, readStdinJson } from './config.js';
43
43
  import { isNonBlockingMode, NON_BLOCKING_INBOX_DIRECTIVE, } from './proposal-mode.js';
44
+ import { isSessionInactive, sessionFolderOf, } from './session-activation.js';
44
45
  /** Cap on persisted entries — drops oldest when exceeded. */
45
46
  const SESSIONS_CAP = 100;
46
47
  /** Default filename for the disk-backed tracker. */
@@ -110,9 +111,14 @@ export async function userPromptSubmitHook(deps = {}) {
110
111
  const config = loadConfig();
111
112
  if (!config)
112
113
  return;
114
+ // SessionStart found no CybeDefend project for this session: stay off.
115
+ const folder = sessionFolderOf(stdin, event.client);
116
+ if (isSessionInactive(stdin, { store: deps.sessionStore, cwd: folder }))
117
+ return;
113
118
  // Async: falls back to git-origin auto-discovery (cache + bounded 4s
114
- // gateway call) when no env var / config.json projectId exists.
115
- const { projectId, apiBase: configApiBase } = await resolveProject();
119
+ // gateway call) when no env var / config.json projectId exists. Resolved
120
+ // where the agent works, not where the hook runs (Cursor: ~/.cursor/).
121
+ const { projectId, apiBase: configApiBase } = await resolveProject(folder);
116
122
  if (!projectId)
117
123
  return; // silent no-op — see file header
118
124
  const apiBase = process.env.CYBEDEFEND_API_BASE ?? configApiBase ?? config.region.apiBase;
@@ -1 +1 @@
1
- {"version":3,"file":"user-prompt-submit.js","sourceRoot":"","sources":["../../../src/hooks/runtime/user-prompt-submit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"user-prompt-submit.js","sourceRoot":"","sources":["../../../src/hooks/runtime/user-prompt-submit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Strings the hook sends to the gateway (BACK-240 L2).
3
+ *
4
+ * A JS string's length counts UTF-16 units. A character outside the BMP (an
5
+ * emoji, many CJK ideographs) takes two of them, a surrogate pair, so a
6
+ * `slice(0, n)` can keep its first half alone. The server counts characters
7
+ * (Python `str`, i.e. code points) and rejects a lone surrogate (Pydantic
8
+ * `string_unicode`), failing the whole request: one emoji astride the cut of
9
+ * a violation summary was a 500 on the whole batch, again on every flush.
10
+ */
11
+ /** A lone surrogate (half a pair), high or low. */
12
+ const LONE_SURROGATE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g;
13
+ function isHighSurrogate(unit) {
14
+ return unit >= 0xd800 && unit <= 0xdbff;
15
+ }
16
+ /**
17
+ * `text` cut to at most `maxUnits` UTF-16 units, never inside a surrogate
18
+ * pair: when the last unit kept is the high half of a pair, it goes too (the
19
+ * cut moves back one unit). The result is at most `maxUnits` units, hence at
20
+ * most `maxUnits` code points, so it fits a bound counted either way: the
21
+ * bounds the server enforces (`max_length`) count code points, and the bound
22
+ * we cut to stays the one the server sets.
23
+ */
24
+ export function truncateCodePoints(text, maxUnits) {
25
+ if (text.length <= maxUnits)
26
+ return text;
27
+ const end = isHighSurrogate(text.charCodeAt(maxUnits - 1))
28
+ ? maxUnits - 1
29
+ : maxUnits;
30
+ return text.slice(0, end);
31
+ }
32
+ /**
33
+ * `text` with every lone surrogate replaced by U+FFFD, as the server's
34
+ * validator does since the #3172 hotfix. One unit for one unit, so a bounded
35
+ * string stays within its bound. Repairs what an older version buffered,
36
+ * already cut in half a pair.
37
+ */
38
+ export function replaceLoneSurrogates(text) {
39
+ return text.replace(LONE_SURROGATE, '�');
40
+ }
41
+ //# sourceMappingURL=wire-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire-text.js","sourceRoot":"","sources":["../../../src/hooks/runtime/wire-text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,mDAAmD;AACnD,MAAM,cAAc,GAClB,yEAAyE,CAAC;AAE5E,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;AAC1C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,QAAgB;IAC/D,IAAI,IAAI,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QACxD,CAAC,CAAC,QAAQ,GAAG,CAAC;QACd,CAAC,CAAC,QAAQ,CAAC;IACb,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;AAC3C,CAAC"}