@wrongstack/plugins 0.308.6 → 0.308.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accessibility-auditor.js +26 -82
- package/dist/agent-handoff.js +16 -26
- package/dist/auto-i18n-extractor.js +19 -23
- package/dist/branch-guard.js +19 -111
- package/dist/changelog-writer.js +20 -133
- package/dist/code-metrics.js +26 -71
- package/dist/commit-validator.js +16 -14
- package/dist/config-validator.js +18 -22
- package/dist/cost-tracker.js +15 -96
- package/dist/dead-code-detector.js +27 -31
- package/dist/dependency-vulnerability-gate.js +18 -15
- package/dist/diff-summary.js +19 -128
- package/dist/doc-sync-guard.js +24 -39
- package/dist/duplicate-code-detector.js +30 -169
- package/dist/feature-flag-tracker.js +26 -71
- package/dist/file-watcher.js +19 -23
- package/dist/format-on-save.js +25 -214
- package/dist/import-organizer.js +31 -106
- package/dist/index.js +452 -1236
- package/dist/interface-contract-guard.js +26 -71
- package/dist/lint-gate.js +19 -111
- package/dist/migration-planner.js +28 -120
- package/dist/notify-hub.js +18 -28
- package/dist/path-guard.js +27 -102
- package/dist/pr-drafter.js +18 -16
- package/dist/prompt-firewall.js +8 -205
- package/dist/refactor-suggester.js +27 -166
- package/dist/release-notes-generator.js +6 -35
- package/dist/runtime/bounded-map.d.ts +2 -85
- package/dist/runtime/credential-patterns.d.ts +2 -41
- package/dist/runtime/h1-state.d.ts +2 -61
- package/dist/runtime/handles.d.ts +2 -45
- package/dist/runtime/index.d.ts +8 -180
- package/dist/runtime/llm.d.ts +2 -43
- package/dist/runtime/local-bin.d.ts +2 -119
- package/dist/runtime/redos-guard.d.ts +2 -68
- package/dist/runtime/safe-json.d.ts +2 -24
- package/dist/runtime/sandbox.d.ts +2 -58
- package/dist/runtime.js +1 -868
- package/dist/schema-evolution-guard.js +20 -24
- package/dist/secret-scanner.js +22 -146
- package/dist/security-hotspot-scanner.js +24 -154
- package/dist/session-recap.js +16 -14
- package/dist/spec-linker.js +19 -17
- package/dist/template-engine.js +22 -37
- package/dist/test-coverage-gate.js +19 -34
- package/dist/test-generator.js +6 -35
- package/dist/test-runner-gate.js +34 -143
- package/dist/todo-listener.js +17 -38
- package/dist/type-gate.js +23 -311
- package/package.json +4 -3
|
@@ -1,29 +1,25 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __copyProps = (to, from, except, desc) => {
|
|
6
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
+
for (let key of __getOwnPropNames(from))
|
|
8
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
10
|
+
}
|
|
11
|
+
return to;
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
14
|
+
|
|
1
15
|
// src/schema-evolution-guard/index.ts
|
|
2
16
|
import { readFileSync } from "node:fs";
|
|
3
|
-
import { basename
|
|
17
|
+
import { basename } from "node:path";
|
|
4
18
|
|
|
5
19
|
// src/runtime/index.ts
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
|
|
10
|
-
|
|
11
|
-
// src/runtime/index.ts
|
|
12
|
-
var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
|
|
13
|
-
function hasLeadingDash(arg) {
|
|
14
|
-
return arg.length > 0 && arg.startsWith("-");
|
|
15
|
-
}
|
|
16
|
-
function withinProjectPath(projectRoot, candidate) {
|
|
17
|
-
if (candidate.length === 0 || candidate.length > 4096) return false;
|
|
18
|
-
if (hasLeadingDash(candidate)) return false;
|
|
19
|
-
const resolved = isAbsolute(candidate) ? resolve(candidate) : resolve(projectRoot, candidate);
|
|
20
|
-
const rel = relative(projectRoot, resolved);
|
|
21
|
-
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
22
|
-
}
|
|
23
|
-
function withinProject(p) {
|
|
24
|
-
const cwd = process.cwd();
|
|
25
|
-
return withinProjectPath(cwd, p) || relative(cwd, p) === ".";
|
|
26
|
-
}
|
|
20
|
+
var runtime_exports = {};
|
|
21
|
+
__reExport(runtime_exports, runtime_star);
|
|
22
|
+
import * as runtime_star from "@wrongstack/plugin-sdk/runtime";
|
|
27
23
|
|
|
28
24
|
// src/schema-evolution-guard/index.ts
|
|
29
25
|
var API_VERSION = "^0.1.10";
|
|
@@ -212,7 +208,7 @@ var plugin = {
|
|
|
212
208
|
const filePath = typeof toolInput["path"] === "string" ? toolInput["path"] : void 0;
|
|
213
209
|
if (!filePath) return;
|
|
214
210
|
state.invocationCount += 1;
|
|
215
|
-
const fileName =
|
|
211
|
+
const fileName = basename(filePath);
|
|
216
212
|
if (!matchesAnyPattern(fileName, cfg.filePatterns)) {
|
|
217
213
|
state.skippedCount += 1;
|
|
218
214
|
return;
|
|
@@ -225,7 +221,7 @@ var plugin = {
|
|
|
225
221
|
let content;
|
|
226
222
|
if (typeof toolInput["content"] === "string") {
|
|
227
223
|
content = toolInput["content"];
|
|
228
|
-
} else if (withinProject(filePath)) {
|
|
224
|
+
} else if ((0, runtime_exports.withinProject)(filePath)) {
|
|
229
225
|
try {
|
|
230
226
|
content = readFileSync(filePath, "utf-8");
|
|
231
227
|
} catch {
|
package/dist/secret-scanner.js
CHANGED
|
@@ -1,151 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
// (`gho_`), user-to-server (`ghu_`), server-to-server (`ghs_`) and
|
|
11
|
-
// refresh (`ghr_`) tokens grant the same or broader access and were
|
|
12
|
-
// previously not detected at all.
|
|
13
|
-
{ type: "github_pat", regex: /(?<![A-Za-z0-9])ghp_[A-Za-z0-9]{36,}(?![A-Za-z0-9])/g },
|
|
14
|
-
{
|
|
15
|
-
type: "github_oauth_token",
|
|
16
|
-
regex: /(?<![A-Za-z0-9])gh[ousr]_[A-Za-z0-9]{36,}(?![A-Za-z0-9])/g
|
|
17
|
-
},
|
|
18
|
-
{ type: "github_pat_v2", regex: /(?<![A-Za-z0-9])github_pat_[A-Za-z0-9_]{50,}(?![A-Za-z0-9])/g },
|
|
19
|
-
// GitLab
|
|
20
|
-
{ type: "gitlab_pat", regex: /(?<![A-Za-z0-9])glpat-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g },
|
|
21
|
-
{
|
|
22
|
-
type: "gitlab_runner_token",
|
|
23
|
-
regex: /(?<![A-Za-z0-9])glrt-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g
|
|
24
|
-
},
|
|
25
|
-
// npm — a leaked publish token is a supply-chain compromise.
|
|
26
|
-
{ type: "npm_token", regex: /(?<![A-Za-z0-9])npm_[A-Za-z0-9]{36}(?![A-Za-z0-9])/g },
|
|
27
|
-
// AWS
|
|
28
|
-
{ type: "aws_access_key", regex: /(?<![A-Za-z0-9])AKIA[0-9A-Z]{16}(?![A-Za-z0-9])/g },
|
|
29
|
-
// GCP
|
|
30
|
-
{ type: "gcp_key", regex: /(?<![A-Za-z0-9])AIza[0-9A-Za-z_-]{35}(?![A-Za-z0-9])/g },
|
|
31
|
-
// Slack. `xoxe` (token-rotation) and `xapp` (app-level) were missing;
|
|
32
|
-
// both are as sensitive as the bot/user tokens already covered.
|
|
33
|
-
{
|
|
34
|
-
type: "slack_token",
|
|
35
|
-
regex: /(?<![A-Za-z0-9-])xox[abposer]-[A-Za-z0-9-]{10,}(?![A-Za-z0-9-])/g
|
|
36
|
-
},
|
|
37
|
-
{ type: "slack_app_token", regex: /(?<![A-Za-z0-9-])xapp-\d-[A-Za-z0-9-]{10,}(?![A-Za-z0-9-])/g },
|
|
38
|
-
{
|
|
39
|
-
type: "slack_webhook",
|
|
40
|
-
regex: /https:\/\/hooks\.slack\.com\/services\/T[A-Za-z0-9_-]+\/B[A-Za-z0-9_-]+\/[A-Za-z0-9]{16,}/g
|
|
41
|
-
},
|
|
42
|
-
// Stripe
|
|
43
|
-
{
|
|
44
|
-
type: "stripe_key",
|
|
45
|
-
regex: /(?<![A-Za-z0-9])sk_(?:live|test)_[A-Za-z0-9]{24,}(?![A-Za-z0-9])/g
|
|
46
|
-
},
|
|
47
|
-
// Twilio
|
|
48
|
-
{ type: "twilio_sid", regex: /(?<![A-Za-z0-9])AC[a-f0-9]{32}(?![A-Za-z0-9])/g },
|
|
49
|
-
// Telegram
|
|
50
|
-
{
|
|
51
|
-
type: "telegram_bot_token",
|
|
52
|
-
regex: /(?:(?<![A-Za-z0-9_])|(?<=(?:^|[^A-Za-z0-9_])bot))\d+:[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g
|
|
53
|
-
},
|
|
54
|
-
// JWT
|
|
55
|
-
{
|
|
56
|
-
type: "jwt",
|
|
57
|
-
regex: /(?<![A-Za-z0-9/+=])eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}(?![A-Za-z0-9/+=])/g
|
|
58
|
-
},
|
|
59
|
-
// Private keys
|
|
60
|
-
{
|
|
61
|
-
type: "private_key",
|
|
62
|
-
regex: /(?:^|\n)(?:-----BEGIN (?:RSA|EC|OPENSSH|DSA)? ?PRIVATE KEY-----[\s\S]*?-----END (?:RSA|EC|OPENSSH|DSA)? ?PRIVATE KEY-----|-----BEGIN PGP PRIVATE KEY BLOCK-----[\s\S]*?-----END PGP PRIVATE KEY BLOCK-----)(?!\S)/g
|
|
63
|
-
},
|
|
64
|
-
// AI/ML provider tokens
|
|
65
|
-
{ type: "huggingface_token", regex: /(?<![A-Za-z0-9])hf_[A-Za-z0-9]{34}(?![A-Za-z0-9])/g },
|
|
66
|
-
{ type: "replicate_token", regex: /(?<![A-Za-z0-9])r8_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g },
|
|
67
|
-
{ type: "perplexity_key", regex: /(?<![A-Za-z0-9])pplx-[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g },
|
|
68
|
-
{ type: "groq_key", regex: /(?<![A-Za-z0-9])gsk_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g },
|
|
69
|
-
// SaaS / infrastructure tokens — each grants API access on the user's
|
|
70
|
-
// account, and each was previously invisible to this gate.
|
|
71
|
-
{ type: "sendgrid_key", regex: /(?<![A-Za-z0-9])SG\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g },
|
|
72
|
-
{ type: "digitalocean_token", regex: /(?<![A-Za-z0-9])dop_v1_[a-f0-9]{64}(?![A-Za-z0-9])/g },
|
|
73
|
-
{ type: "doppler_token", regex: /(?<![A-Za-z0-9])dp\.(?:pt|st|sa|scim|audit)\.[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g },
|
|
74
|
-
{ type: "shopify_token", regex: /(?<![A-Za-z0-9])shp(?:at|ca|pa|ss)_[a-fA-F0-9]{32}(?![A-Za-z0-9])/g },
|
|
75
|
-
{ type: "docker_pat", regex: /(?<![A-Za-z0-9])dckr_pat_[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g },
|
|
76
|
-
{ type: "linear_key", regex: /(?<![A-Za-z0-9])lin_api_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g },
|
|
77
|
-
{ type: "atlassian_token", regex: /(?<![A-Za-z0-9])ATATT3[A-Za-z0-9_\-=]{40,}(?![A-Za-z0-9_\-=])/g },
|
|
78
|
-
{ type: "square_token", regex: /(?<![A-Za-z0-9])(?:sq0(?:atp|csp)-|EAAA)[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g },
|
|
79
|
-
{
|
|
80
|
-
type: "azure_storage_key",
|
|
81
|
-
regex: /AccountKey=[A-Za-z0-9+/]{80,}={0,2}/g
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
type: "google_oauth_client_secret",
|
|
85
|
-
regex: /(?<![A-Za-z0-9_-])GOCSPX-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g
|
|
86
|
-
},
|
|
87
|
-
// Bearer tokens
|
|
88
|
-
{
|
|
89
|
-
type: "bearer_token",
|
|
90
|
-
regex: /(?<![A-Za-z0-9_.~+/-])Bearer\s+[A-Za-z0-9._~+/-]{12,512}=*(?![A-Za-z0-9._~+/-])/g
|
|
91
|
-
},
|
|
92
|
-
// Database URIs. Require password-bearing user-info; credential-free values stay scannable.
|
|
93
|
-
{ type: "mongodb_uri", regex: /mongodb(?:\+srv)?:\/\/[^\s:/@"'`]*:[^\s/@"'`]+@[^\s"'`]+/g },
|
|
94
|
-
{
|
|
95
|
-
type: "postgres_uri",
|
|
96
|
-
// Query parsers decode percent-encoded parameter names. Recognize each
|
|
97
|
-
// encoded character in `password` so mixed forms such as `pass%77ord`
|
|
98
|
-
// cannot bypass detection while keeping the scan strictly bounded.
|
|
99
|
-
regex: /postgres(?:ql)?:\/\/(?:[^\s:/@"'`]*:[^\s/@"'`]+@[^\s"'`]+|[^&\s?"'`#]{1,2048}\?(?:(?!(?:p|%70)(?:a|%61)(?:s|%73)(?:s|%73)(?:w|%77)(?:o|%6[fF])(?:r|%72)(?:d|%64)=)[^&\s#"'`]{1,256}&){0,32}(?:p|%70)(?:a|%61)(?:s|%73)(?:s|%73)(?:w|%77)(?:o|%6[fF])(?:r|%72)(?:d|%64)=[^&\s#"'`]{1,4096})/g
|
|
100
|
-
},
|
|
101
|
-
{ type: "mysql_uri", regex: /mysql:\/\/[^\s:/@"'`]*:[^\s/@"'`]+@[^\s"'`]+/g },
|
|
102
|
-
{ type: "redis_uri", regex: /redis:\/\/[^\s:/@"'`]*:[^\s/@"'`]+@[^\s"'`]+/g },
|
|
103
|
-
{
|
|
104
|
-
// Credentials serialised as JSON, keyed rather than prefixed. Every other
|
|
105
|
-
// entry in this table recognises a credential by its SHAPE (`ghp_`, `sk-`,
|
|
106
|
-
// `eyJ`), which means a key with no distinctive prefix — Azure, a
|
|
107
|
-
// self-hosted gateway, an Anthropic/Codex OAuth token — was invisible to
|
|
108
|
-
// both surfaces. `prompt-firewall` guards the outgoing provider request, so
|
|
109
|
-
// this is what stops a JSON-shaped tool result carrying such a value to a
|
|
110
|
-
// third party.
|
|
111
|
-
//
|
|
112
|
-
// The key is matched in a LOOKBEHIND, so the reported match is the secret
|
|
113
|
-
// itself and the pattern keeps zero capturing groups — `secret-scanner`
|
|
114
|
-
// maps a combined-regex group index back to the pattern that fired, and an
|
|
115
|
-
// inner group would shift that mapping (see the style note above, enforced
|
|
116
|
-
// by credential-pattern-parity.test.ts).
|
|
117
|
-
//
|
|
118
|
-
// Mirrors `json_credential_key` in
|
|
119
|
-
// `@wrongstack/core` → `src/security/secret-scrubber.ts`. Keep the two key
|
|
120
|
-
// lists in step; the core side additionally preserves the key name when it
|
|
121
|
-
// rewrites, which is why it is written with capture groups instead.
|
|
122
|
-
type: "json_credential_key",
|
|
123
|
-
regex: /(?<="[A-Za-z0-9_]{0,64}(?:apiKey|api_key|token|secret|password|authorization|bearer|private_key|access_token|refresh_token|client_secret)"\s{0,8}:\s{0,8}")[^"\\]{8,512}(?=")/gi
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __copyProps = (to, from, except, desc) => {
|
|
6
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
+
for (let key of __getOwnPropNames(from))
|
|
8
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
124
10
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
type: p.type,
|
|
129
|
-
regex: new RegExp(p.regex.source, p.regex.flags)
|
|
130
|
-
}));
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// src/runtime/local-bin.ts
|
|
134
|
-
import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
|
|
11
|
+
return to;
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
135
14
|
|
|
136
|
-
// src/runtime/
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
} catch {
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
15
|
+
// src/runtime/credential-patterns.ts
|
|
16
|
+
import {
|
|
17
|
+
cloneCredentialPatterns,
|
|
18
|
+
CREDENTIAL_PATTERNS
|
|
19
|
+
} from "@wrongstack/plugin-sdk/runtime";
|
|
146
20
|
|
|
147
21
|
// src/runtime/index.ts
|
|
148
|
-
var
|
|
22
|
+
var runtime_exports = {};
|
|
23
|
+
__reExport(runtime_exports, runtime_star);
|
|
24
|
+
import * as runtime_star from "@wrongstack/plugin-sdk/runtime";
|
|
149
25
|
|
|
150
26
|
// src/secret-scanner/index.ts
|
|
151
27
|
var BASE_PATTERNS = cloneCredentialPatterns();
|
|
@@ -490,8 +366,8 @@ var plugin = {
|
|
|
490
366
|
setup(api) {
|
|
491
367
|
const previous = runtimes.get(api);
|
|
492
368
|
if (previous) {
|
|
493
|
-
previous.state.hookUnregister = releaseHandle(previous.state.hookUnregister);
|
|
494
|
-
previous.state.postHookUnregister = releaseHandle(previous.state.postHookUnregister);
|
|
369
|
+
previous.state.hookUnregister = (0, runtime_exports.releaseHandle)(previous.state.hookUnregister);
|
|
370
|
+
previous.state.postHookUnregister = (0, runtime_exports.releaseHandle)(previous.state.postHookUnregister);
|
|
495
371
|
}
|
|
496
372
|
const cfg = readConfig(api.config.extensions?.["secret-scanner"]);
|
|
497
373
|
PATTERNS = [...BASE_PATTERNS];
|
|
@@ -1,155 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// src/runtime/bounded-map.ts
|
|
12
|
-
var BoundedMap = class {
|
|
13
|
-
map = /* @__PURE__ */ new Map();
|
|
14
|
-
max;
|
|
15
|
-
ttlMs;
|
|
16
|
-
now;
|
|
17
|
-
/** Entries dropped to stay under `max`. Surfaced by plugin health(). */
|
|
18
|
-
evictions = 0;
|
|
19
|
-
constructor(options) {
|
|
20
|
-
const normalizedMax = Math.floor(options.max);
|
|
21
|
-
this.max = Number.isSafeInteger(normalizedMax) ? Math.max(1, normalizedMax) : 1;
|
|
22
|
-
this.ttlMs = options.ttlMs;
|
|
23
|
-
this.now = options.now ?? Date.now;
|
|
24
|
-
}
|
|
25
|
-
expired(entry) {
|
|
26
|
-
return this.ttlMs !== void 0 && this.now() - entry.storedAt > this.ttlMs;
|
|
27
|
-
}
|
|
28
|
-
get(key) {
|
|
29
|
-
const entry = this.map.get(key);
|
|
30
|
-
if (entry === void 0) return void 0;
|
|
31
|
-
if (this.expired(entry)) {
|
|
32
|
-
this.map.delete(key);
|
|
33
|
-
return void 0;
|
|
34
|
-
}
|
|
35
|
-
this.map.delete(key);
|
|
36
|
-
this.map.set(key, entry);
|
|
37
|
-
return entry.value;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Read without promoting the key to most-recently-used. Use for
|
|
41
|
-
* diagnostics that must not perturb the eviction order.
|
|
42
|
-
*/
|
|
43
|
-
peek(key) {
|
|
44
|
-
const entry = this.map.get(key);
|
|
45
|
-
if (entry === void 0 || this.expired(entry)) return void 0;
|
|
46
|
-
return entry.value;
|
|
47
|
-
}
|
|
48
|
-
has(key) {
|
|
49
|
-
const entry = this.map.get(key);
|
|
50
|
-
if (entry === void 0) return false;
|
|
51
|
-
if (this.expired(entry)) {
|
|
52
|
-
this.map.delete(key);
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
|
-
set(key, value) {
|
|
58
|
-
this.map.delete(key);
|
|
59
|
-
this.map.set(key, { value, storedAt: this.now() });
|
|
60
|
-
while (this.map.size > this.max) {
|
|
61
|
-
const coldest = this.map.keys().next().value;
|
|
62
|
-
if (coldest === void 0) break;
|
|
63
|
-
this.map.delete(coldest);
|
|
64
|
-
this.evictions += 1;
|
|
65
|
-
}
|
|
66
|
-
return this;
|
|
67
|
-
}
|
|
68
|
-
delete(key) {
|
|
69
|
-
return this.map.delete(key);
|
|
70
|
-
}
|
|
71
|
-
clear() {
|
|
72
|
-
this.map.clear();
|
|
73
|
-
this.evictions = 0;
|
|
74
|
-
}
|
|
75
|
-
get size() {
|
|
76
|
-
return this.map.size;
|
|
77
|
-
}
|
|
78
|
-
/** How many entries have been dropped to respect `max`, since the last clear. */
|
|
79
|
-
get evictionCount() {
|
|
80
|
-
return this.evictions;
|
|
81
|
-
}
|
|
82
|
-
/** Drop every expired entry. Cheap enough to call from a status tool. */
|
|
83
|
-
prune() {
|
|
84
|
-
if (this.ttlMs === void 0) return 0;
|
|
85
|
-
let removed = 0;
|
|
86
|
-
for (const [key, entry] of this.map) {
|
|
87
|
-
if (this.expired(entry)) {
|
|
88
|
-
this.map.delete(key);
|
|
89
|
-
removed += 1;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return removed;
|
|
93
|
-
}
|
|
94
|
-
/** Live (non-expired) entries, coldest first. */
|
|
95
|
-
*entries() {
|
|
96
|
-
for (const [key, entry] of this.map) {
|
|
97
|
-
if (!this.expired(entry)) yield [key, entry.value];
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
[Symbol.iterator]() {
|
|
101
|
-
return this.entries();
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
var BoundedSet = class {
|
|
105
|
-
inner;
|
|
106
|
-
constructor(options) {
|
|
107
|
-
this.inner = new BoundedMap(options);
|
|
108
|
-
}
|
|
109
|
-
has(value) {
|
|
110
|
-
return this.inner.has(value);
|
|
111
|
-
}
|
|
112
|
-
add(value) {
|
|
113
|
-
this.inner.set(value, true);
|
|
114
|
-
return this;
|
|
115
|
-
}
|
|
116
|
-
delete(value) {
|
|
117
|
-
return this.inner.delete(value);
|
|
118
|
-
}
|
|
119
|
-
clear() {
|
|
120
|
-
this.inner.clear();
|
|
121
|
-
}
|
|
122
|
-
get size() {
|
|
123
|
-
return this.inner.size;
|
|
124
|
-
}
|
|
125
|
-
/** How many entries have been dropped to respect `max`, since the last clear. */
|
|
126
|
-
get evictionCount() {
|
|
127
|
-
return this.inner.evictionCount;
|
|
128
|
-
}
|
|
129
|
-
*values() {
|
|
130
|
-
for (const [key] of this.inner) yield key;
|
|
131
|
-
}
|
|
132
|
-
[Symbol.iterator]() {
|
|
133
|
-
return this.values();
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __copyProps = (to, from, except, desc) => {
|
|
6
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
+
for (let key of __getOwnPropNames(from))
|
|
8
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
134
10
|
}
|
|
11
|
+
return to;
|
|
135
12
|
};
|
|
13
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
14
|
+
|
|
15
|
+
// src/security-hotspot-scanner/index.ts
|
|
16
|
+
import { readdir, readFile, stat } from "node:fs/promises";
|
|
17
|
+
import { isAbsolute, relative, resolve } from "node:path";
|
|
136
18
|
|
|
137
19
|
// src/runtime/index.ts
|
|
138
|
-
var
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
function withinProjectPath(projectRoot, candidate) {
|
|
143
|
-
if (candidate.length === 0 || candidate.length > 4096) return false;
|
|
144
|
-
if (hasLeadingDash(candidate)) return false;
|
|
145
|
-
const resolved = isAbsolute(candidate) ? resolve(candidate) : resolve(projectRoot, candidate);
|
|
146
|
-
const rel = relative(projectRoot, resolved);
|
|
147
|
-
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
148
|
-
}
|
|
149
|
-
function withinProject(p) {
|
|
150
|
-
const cwd = process.cwd();
|
|
151
|
-
return withinProjectPath(cwd, p) || relative(cwd, p) === ".";
|
|
152
|
-
}
|
|
20
|
+
var runtime_exports = {};
|
|
21
|
+
__reExport(runtime_exports, runtime_star);
|
|
22
|
+
import * as runtime_star from "@wrongstack/plugin-sdk/runtime";
|
|
153
23
|
|
|
154
24
|
// src/security-hotspot-scanner/index.ts
|
|
155
25
|
var API_VERSION = "^0.1.10";
|
|
@@ -161,7 +31,7 @@ var state = {
|
|
|
161
31
|
skippedCount: 0,
|
|
162
32
|
blockedCount: 0,
|
|
163
33
|
lastResult: null,
|
|
164
|
-
knownHotspots: new BoundedSet({ max: 5e3 }),
|
|
34
|
+
knownHotspots: new runtime_exports.BoundedSet({ max: 5e3 }),
|
|
165
35
|
hookUnregister: null
|
|
166
36
|
};
|
|
167
37
|
var DEFAULTS = {
|
|
@@ -242,8 +112,8 @@ function isSourceFile(filePath, extensions) {
|
|
|
242
112
|
async function scanPath(inputPath, cfg) {
|
|
243
113
|
const start = Date.now();
|
|
244
114
|
const root = process.cwd();
|
|
245
|
-
const resolved =
|
|
246
|
-
if (!withinProject(inputPath)) {
|
|
115
|
+
const resolved = isAbsolute(inputPath) ? resolve(inputPath) : resolve(root, inputPath);
|
|
116
|
+
if (!(0, runtime_exports.withinProject)(inputPath)) {
|
|
247
117
|
return {
|
|
248
118
|
path: inputPath,
|
|
249
119
|
scanned: false,
|
|
@@ -263,7 +133,7 @@ async function scanPath(inputPath, cfg) {
|
|
|
263
133
|
filesScanned += 1;
|
|
264
134
|
const findings = scanSource(content, maxPerFile);
|
|
265
135
|
for (const f of findings) {
|
|
266
|
-
allFindings.push({ ...f, snippet: `${
|
|
136
|
+
allFindings.push({ ...f, snippet: `${relative(root, filePath)}:${f.line}: ${f.snippet}` });
|
|
267
137
|
if (allFindings.length >= cfg.maxFindings) return;
|
|
268
138
|
}
|
|
269
139
|
} catch {
|
|
@@ -278,7 +148,7 @@ async function scanPath(inputPath, cfg) {
|
|
|
278
148
|
}
|
|
279
149
|
for (const entry of entries) {
|
|
280
150
|
if (allFindings.length >= cfg.maxFindings) return;
|
|
281
|
-
const full =
|
|
151
|
+
const full = resolve(dir, entry);
|
|
282
152
|
try {
|
|
283
153
|
const st = await stat(full);
|
|
284
154
|
if (st.isDirectory()) {
|
|
@@ -382,7 +252,7 @@ var plugin = {
|
|
|
382
252
|
const inp = input.toolInput ?? {};
|
|
383
253
|
const sourcePath = inp["path"];
|
|
384
254
|
if (!sourcePath || typeof sourcePath !== "string") return;
|
|
385
|
-
if (!withinProject(sourcePath)) return;
|
|
255
|
+
if (!(0, runtime_exports.withinProject)(sourcePath)) return;
|
|
386
256
|
const ext = sourcePath.includes(".") ? sourcePath.slice(sourcePath.lastIndexOf(".")).toLowerCase() : "";
|
|
387
257
|
if (!scanOnChangeSet.has(ext)) {
|
|
388
258
|
state.skippedCount += 1;
|
package/dist/session-recap.js
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __copyProps = (to, from, except, desc) => {
|
|
6
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
+
for (let key of __getOwnPropNames(from))
|
|
8
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
10
|
}
|
|
12
|
-
return
|
|
13
|
-
}
|
|
11
|
+
return to;
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
14
14
|
|
|
15
15
|
// src/runtime/index.ts
|
|
16
|
-
var
|
|
16
|
+
var runtime_exports = {};
|
|
17
|
+
__reExport(runtime_exports, runtime_star);
|
|
18
|
+
import * as runtime_star from "@wrongstack/plugin-sdk/runtime";
|
|
17
19
|
|
|
18
20
|
// src/session-recap/index.ts
|
|
19
21
|
var state = {
|
|
@@ -206,7 +208,7 @@ var plugin = {
|
|
|
206
208
|
state.commitCount = 0;
|
|
207
209
|
state.startedAt = null;
|
|
208
210
|
state.lastActivityAt = null;
|
|
209
|
-
state.stopHookUnregister = releaseHandle(state.stopHookUnregister);
|
|
211
|
+
state.stopHookUnregister = (0, runtime_exports.releaseHandle)(state.stopHookUnregister);
|
|
210
212
|
for (const off of state.eventUnsubscribers) {
|
|
211
213
|
try {
|
|
212
214
|
off();
|
package/dist/spec-linker.js
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __copyProps = (to, from, except, desc) => {
|
|
6
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
+
for (let key of __getOwnPropNames(from))
|
|
8
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
10
|
+
}
|
|
11
|
+
return to;
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
14
|
+
|
|
1
15
|
// src/spec-linker/index.ts
|
|
2
16
|
import * as fs from "node:fs/promises";
|
|
3
17
|
|
|
4
|
-
// src/runtime/local-bin.ts
|
|
5
|
-
import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
|
|
6
|
-
|
|
7
|
-
// src/runtime/handles.ts
|
|
8
|
-
function releaseHandle(off) {
|
|
9
|
-
if (off) {
|
|
10
|
-
try {
|
|
11
|
-
off();
|
|
12
|
-
} catch {
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
18
|
// src/runtime/index.ts
|
|
19
|
-
var
|
|
19
|
+
var runtime_exports = {};
|
|
20
|
+
__reExport(runtime_exports, runtime_star);
|
|
21
|
+
import * as runtime_star from "@wrongstack/plugin-sdk/runtime";
|
|
20
22
|
|
|
21
23
|
// src/manifest/index.ts
|
|
22
24
|
var OFFICIAL_PLUGIN_NAMES = [
|
|
@@ -348,8 +350,8 @@ var plugin = {
|
|
|
348
350
|
state.skippedNonMd = 0;
|
|
349
351
|
state.readErrorCount = 0;
|
|
350
352
|
state.autoFixApplied = 0;
|
|
351
|
-
state.postHookUnregister = releaseHandle(state.postHookUnregister);
|
|
352
|
-
state.preHookUnregister = releaseHandle(state.preHookUnregister);
|
|
353
|
+
state.postHookUnregister = (0, runtime_exports.releaseHandle)(state.postHookUnregister);
|
|
354
|
+
state.preHookUnregister = (0, runtime_exports.releaseHandle)(state.preHookUnregister);
|
|
353
355
|
const cfg = readConfig(api.config.extensions?.["spec-linker"]);
|
|
354
356
|
const postHook = async (input) => {
|
|
355
357
|
if (!cfg.enabled) return;
|
package/dist/template-engine.js
CHANGED
|
@@ -1,40 +1,25 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __copyProps = (to, from, except, desc) => {
|
|
6
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
+
for (let key of __getOwnPropNames(from))
|
|
8
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
10
|
+
}
|
|
11
|
+
return to;
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
14
|
+
|
|
1
15
|
// src/template-engine/index.ts
|
|
2
16
|
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
-
import { isAbsolute
|
|
4
|
-
|
|
5
|
-
// src/runtime/index.ts
|
|
6
|
-
import { basename, extname, isAbsolute, relative, resolve } from "node:path";
|
|
7
|
-
|
|
8
|
-
// src/runtime/local-bin.ts
|
|
9
|
-
import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
|
|
10
|
-
|
|
11
|
-
// src/runtime/handles.ts
|
|
12
|
-
function releaseHandle(off) {
|
|
13
|
-
if (off) {
|
|
14
|
-
try {
|
|
15
|
-
off();
|
|
16
|
-
} catch {
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
17
|
+
import { isAbsolute } from "node:path";
|
|
21
18
|
|
|
22
19
|
// src/runtime/index.ts
|
|
23
|
-
var
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
function withinProjectPath(projectRoot, candidate) {
|
|
28
|
-
if (candidate.length === 0 || candidate.length > 4096) return false;
|
|
29
|
-
if (hasLeadingDash(candidate)) return false;
|
|
30
|
-
const resolved = isAbsolute(candidate) ? resolve(candidate) : resolve(projectRoot, candidate);
|
|
31
|
-
const rel = relative(projectRoot, resolved);
|
|
32
|
-
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
33
|
-
}
|
|
34
|
-
function withinProject(p) {
|
|
35
|
-
const cwd = process.cwd();
|
|
36
|
-
return withinProjectPath(cwd, p) || relative(cwd, p) === ".";
|
|
37
|
-
}
|
|
20
|
+
var runtime_exports = {};
|
|
21
|
+
__reExport(runtime_exports, runtime_star);
|
|
22
|
+
import * as runtime_star from "@wrongstack/plugin-sdk/runtime";
|
|
38
23
|
|
|
39
24
|
// src/template-engine/index.ts
|
|
40
25
|
var API_VERSION = "^0.1.10";
|
|
@@ -92,10 +77,10 @@ function renderTemplateRaw(template, variables) {
|
|
|
92
77
|
return result;
|
|
93
78
|
}
|
|
94
79
|
function validateRelativeTemplatePath(field, value) {
|
|
95
|
-
if (
|
|
80
|
+
if (isAbsolute(value) || value.split(/[\\/]+/).includes("..")) {
|
|
96
81
|
return `${field} must be a relative path without ".." components`;
|
|
97
82
|
}
|
|
98
|
-
if (!withinProject(value)) {
|
|
83
|
+
if (!(0, runtime_exports.withinProject)(value)) {
|
|
99
84
|
return `${field} must resolve inside the project directory`;
|
|
100
85
|
}
|
|
101
86
|
return null;
|
|
@@ -398,7 +383,7 @@ var plugin = {
|
|
|
398
383
|
};
|
|
399
384
|
}
|
|
400
385
|
});
|
|
401
|
-
contributorUnregister = releaseHandle(contributorUnregister);
|
|
386
|
+
contributorUnregister = (0, runtime_exports.releaseHandle)(contributorUnregister);
|
|
402
387
|
contributorUnregister = api.registerSystemPromptContributor(async () => [
|
|
403
388
|
{
|
|
404
389
|
type: "text",
|
|
@@ -414,7 +399,7 @@ var plugin = {
|
|
|
414
399
|
teardown(api) {
|
|
415
400
|
const count = templates.size;
|
|
416
401
|
templates.clear();
|
|
417
|
-
contributorUnregister = releaseHandle(contributorUnregister);
|
|
402
|
+
contributorUnregister = (0, runtime_exports.releaseHandle)(contributorUnregister);
|
|
418
403
|
api.log.info("template-engine: teardown complete", { cleared: count });
|
|
419
404
|
},
|
|
420
405
|
async health() {
|