@safets-org/cli 1.0.0 → 1.0.2

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/README.md CHANGED
@@ -16,6 +16,18 @@ Cannot read properties of undefined (reading 'name')
16
16
  npm install --save-dev @safets-org/cli typescript
17
17
  ```
18
18
 
19
+ With Bun:
20
+
21
+ ```bash
22
+ bun add -D @safets-org/cli typescript
23
+ ```
24
+
25
+ With pnpm:
26
+
27
+ ```bash
28
+ pnpm add -D @safets-org/cli typescript
29
+ ```
30
+
19
31
  No runtime TypeScript loader is required. SafeTS uses the TypeScript compiler already in your project.
20
32
 
21
33
  The npm package is scoped as `@safets-org/cli`, but the installed command is still `safets`.
@@ -24,6 +36,16 @@ The npm package is scoped as `@safets-org/cli`, but the installed command is sti
24
36
 
25
37
  ## Usage
26
38
 
39
+ Run the installed `safets` binary with your package manager:
40
+
41
+ ```bash
42
+ npx safets doctor
43
+ pnpm exec safets doctor
44
+ bunx safets doctor
45
+ ```
46
+
47
+ Or add package scripts and run `safets` directly inside those scripts:
48
+
27
49
  ```bash
28
50
  safets doctor
29
51
  safets doctor --include-tests
@@ -94,6 +116,13 @@ No target fell back to AST-only mode. See [docs/real-world-validation.md](./docs
94
116
 
95
117
  ---
96
118
 
119
+ ## End-To-End Guides
120
+
121
+ - [SafeTS documentation website](./docs-site/README.md)
122
+ - [TanStack Start, shadcn/ui, Tailwind CSS, and dark mode](./docs/tanstack-start-shadcn-tailwind.md)
123
+
124
+ ---
125
+
97
126
  ## The 9 Patterns
98
127
 
99
128
  | Pattern | Confidence | Example |
@@ -133,7 +162,7 @@ The baseline stores scan options such as `includeTests`. If you run `doctor --fa
133
162
  SafeTS can run directly in GitHub Actions:
134
163
 
135
164
  ```yaml
136
- - uses: Dioman-Keita/safets@v1.0.0
165
+ - uses: Dioman-Keita/safets@v1.0.2
137
166
  with:
138
167
  fail-on-new: "true"
139
168
  ```
@@ -167,6 +196,22 @@ SafeTS releases follow the documented workflow in [docs/release.md](./docs/relea
167
196
 
168
197
  Detector architecture and contribution expectations are documented in [docs/detectors.md](./docs/detectors.md).
169
198
 
199
+ ## AI Agent Skill
200
+
201
+ SafeTS includes an installable skill for agents that support the `skills` CLI:
202
+
203
+ ```bash
204
+ npx skills add Dioman-Keita/safets
205
+ ```
206
+
207
+ For a non-interactive install, pass the target agent explicitly. For Codex:
208
+
209
+ ```bash
210
+ npx skills add Dioman-Keita/safets --skill safets-agent -a codex -g -y
211
+ ```
212
+
213
+ The skill is not coupled to Codex; Codex is only one supported target. After installation, restart the agent and invoke `$safets-agent` when an agent should run or interpret SafeTS on a TypeScript project.
214
+
170
215
  ## Roadmap
171
216
 
172
217
  The launch plan is tracked in [ROADMAP.md](./ROADMAP.md).
@@ -282,9 +282,35 @@ export function detectUnsafeEnvAccess(sf, checker) {
282
282
  return false;
283
283
  }
284
284
  }
285
+ function isOptionalChainReceiver(node) {
286
+ let current = node;
287
+ while (ts.isParenthesizedExpression(current.parent)) {
288
+ current = current.parent;
289
+ }
290
+ const parent = current.parent;
291
+ const isOptionalReceiver = ((ts.isPropertyAccessExpression(parent) || ts.isElementAccessExpression(parent)) &&
292
+ parent.expression === current &&
293
+ parent.questionDotToken !== undefined) ||
294
+ (ts.isCallExpression(parent) &&
295
+ parent.expression === current &&
296
+ parent.questionDotToken !== undefined);
297
+ if (!isOptionalReceiver) {
298
+ return false;
299
+ }
300
+ let optionalAccess = parent;
301
+ let sawParentheses = false;
302
+ while (ts.isParenthesizedExpression(optionalAccess.parent)) {
303
+ sawParentheses = true;
304
+ optionalAccess = optionalAccess.parent;
305
+ }
306
+ return (!sawParentheses ||
307
+ !(ts.isCallExpression(optionalAccess.parent) &&
308
+ optionalAccess.parent.expression === optionalAccess));
309
+ }
285
310
  function visit(node) {
286
311
  if (isEnvAccess(node) &&
287
312
  !isSafelyDefaulted(node) &&
313
+ !isOptionalChainReceiver(node) &&
288
314
  !ts.isNonNullExpression(node.parent)) {
289
315
  try {
290
316
  const envVar = node.name.getText();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@safets-org/cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Finds common runtime crashes TypeScript can't detect",
5
5
  "type": "module",
6
6
  "bin": {