@systemfsoftware/omp-typescript-discipline 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/CHANGELOG.md +13 -0
- package/package.json +10 -1
- package/rules/no-hand-rolled-std.md +30 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# @systemfsoftware/omp-typescript-discipline
|
|
2
|
+
|
|
3
|
+
## 1.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Peer Effect requirement advances to 4.0.0-rc.112. No API changes.
|
|
8
|
+
|
|
9
|
+
## 1.0.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- TypeScript discipline now guides the agent toward standard libraries instead of hand-rolled helpers — `jsr:@std/encoding`, `jsr:@std/async`, `jsr:@std/bytes`, `jsr:@std/path`, and, when you already import from `effect`, the Effect-native `Effect.sleep` and `Schedule` primitives. The guidance appears as an inline hint while the agent writes code.
|
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@systemfsoftware/omp-typescript-discipline",
|
|
3
3
|
"license": "Apache-2.0",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.2",
|
|
5
5
|
"author": "Ryan Lee <drdgvhbh@gmail.com>",
|
|
6
6
|
"description": "OMP TypeScript discipline plugin: enforces project references for tooling files and pure tsconfig boundaries",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"files": [
|
|
9
9
|
"rules"
|
|
10
10
|
],
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"provenance": true
|
|
13
|
+
},
|
|
11
14
|
"devDependencies": {
|
|
12
15
|
"oxlint": "^1.77.0",
|
|
13
16
|
"@systemfsoftware/oxlint-config": "^0.1.0"
|
|
@@ -16,5 +19,11 @@
|
|
|
16
19
|
"type": "git",
|
|
17
20
|
"url": "git+https://github.com/systemfsoftware/systemfsoftware.git",
|
|
18
21
|
"directory": "omp/plugins/omp-typescript-discipline"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"check": "deno task --cwd scripts check"
|
|
25
|
+
},
|
|
26
|
+
"exports": {
|
|
27
|
+
"./package.json": "./package.json"
|
|
19
28
|
}
|
|
20
29
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Prefer Effect / JSR @std/* over hand-rolled encoding, async, bytes, path, dates, uuid, and crypto primitives
|
|
3
|
+
condition: '(btoa\s*\(|atob\s*\(|Buffer\.from\([^)]*base64|\.toString\([^)]*base64|charCodeAt[^\n]*toString\(16\)|new\s+Date\s*\(|Date\.now\(\)|toISOString\(\)|getTimezoneOffset|randomUUID|createHash|crypto\.subtle|new\s+Promise\s*\(\s*\w+\s*=>\s*setTimeout|clearTimeout\s*\(|for\s*\([^)]*\)\s*\{[^\}]*setTimeout|Uint8Array[\s\S]*?for\s*\(|\.split\(|\+[\x22\x27]\/[\x22\x27])'
|
|
4
|
+
scope:
|
|
5
|
+
- "tool:edit(**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs})"
|
|
6
|
+
- "tool:write(**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs})"
|
|
7
|
+
interruptMode: 'tool-only'
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
> **Precedence: Effect-native > `@std/*` > hand-rolled.** If the edited file already imports from `"effect"` (portable signal `from "effect"`), prefer Effect for async; otherwise use `@std/*`. Encoding/bytes/path have no Effect overlap — always `@std/*`.
|
|
11
|
+
|
|
12
|
+
Hand-rolled primitives reinvent tested correctness, lose typed errors/interruption, and inflate bundle and review cost. Use the stdlib.
|
|
13
|
+
|
|
14
|
+
| Hand-rolled signal | Effect-native (if `from "effect"` in file) | `@std/*` fallback | Import example |
|
|
15
|
+
| -------------------------------------------------------------------------------------- | -------------------------------------------------------------- | --------------------------------------- | ---------------------------------------------------------------------------- |
|
|
16
|
+
| `btoa`/`atob`, `Buffer.from(x,'base64')`, `.toString('base64')` | — | `jsr:@std/encoding` | `import {encodeBase64, decodeBase64} from "jsr:@std/encoding"` |
|
|
17
|
+
| hex loop `charCodeAt`→`toString(16)` table | — | `jsr:@std/encoding` | `import {encodeHex, decodeHex} from "jsr:@std/encoding"` |
|
|
18
|
+
| `new Promise(r=>setTimeout(r,ms))` | `Effect.sleep(Duration.millis(ms))` | `jsr:@std/async` `delay` | `import {delay} from "jsr:@std/async"` / `yield* Effect.sleep("100 millis")` |
|
|
19
|
+
| `clearTimeout`/`setTimeout` debounce/throttle closure | `Schedule` / `Effect` composition | `jsr:@std/async` `debounce` | `import {debounce} from "jsr:@std/async"` |
|
|
20
|
+
| retry loop `for/while`+`try/catch`+`setTimeout` | `Effect.retry({schedule: Schedule.exponential("100 millis")})` | `jsr:@std/async` `retry` | `import {retry} from "jsr:@std/async"` |
|
|
21
|
+
| concurrency pool `for`+`await` | `Effect.forEach(arr, fn, {concurrency:4})` / `Stream` | `jsr:@std/async` `pooledMap` | `import {pooledMap} from "jsr:@std/async"` |
|
|
22
|
+
| `Uint8Array` manual concat/copy `for` loop | — | `jsr:@std/bytes` | `import {concat} from "jsr:@std/bytes"` |
|
|
23
|
+
| `dir + "/" + name`, `split("/")` path surgery | — | `jsr:@std/path` | `import {join} from "jsr:@std/path"` |
|
|
24
|
+
| `new Date()`, `Date.now()`, `toISOString()`, `getTimezoneOffset` hand-rolled date math | — | `jsr:@std/datetime` / `Temporal` | `import {format} from "jsr:@std/datetime"` |
|
|
25
|
+
| `randomUUID`, `uuid()` hand-rolled ids | — | `jsr:@std/uuid` / `crypto.randomUUID()` | `import {v4} from "jsr:@std/uuid"` / `crypto.randomUUID()` |
|
|
26
|
+
| `createHash`, `crypto.subtle` hand-rolled hashing | — | `jsr:@std/crypto` | `import {crypto} from "jsr:@std/crypto"` |
|
|
27
|
+
|
|
28
|
+
Resolver: `jsr:@std/*` in Deno, or `jsr:` catalog / `npm:@jsr/std__*` in Node/pnpm (one illustrative `catalog:` pin `"@std/encoding": "jsr:^1.0.11"`).
|
|
29
|
+
|
|
30
|
+
**When not to apply:** already using `Effect-native` or `jsr:@std/*`; genuine polyfill for legacy runtime with comment; trivial one-off helper justified in review.
|