ts-reviewer 1.2.0 → 2.0.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.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  An AI skill for deep code review and auto-fix of pure TypeScript codebases. Finds bugs, type safety holes, security vulnerabilities, async anti-patterns, outdated practices, and code smells — then fixes them with regression tests and verification.
4
4
 
5
- Built for **TypeScript 5.9+** without any framework-specific checks (no React, Vue, Angular, etc.).
5
+ Built for one fixed stack — **TypeScript 5.9.x, ES2024, Node 24** — without any framework-specific checks (no React, Vue, Angular, etc.). Anything below the stack is a finding, anything above it is never recommended.
6
6
 
7
7
  ## What It Does
8
8
 
@@ -14,17 +14,20 @@ Three modes, one skill:
14
14
  | **fix** | Reads the report and applies fixes file-by-file with tsc/lint/test verification |
15
15
  | **auto** | Runs scan, asks you to confirm, fixes everything, deletes the report if clean |
16
16
 
17
- The review covers six domains by default, each with its own detailed checklist. Add `--arch` or `--full` to include architecture analysis:
17
+ The review covers nine domains by default, each with its own detailed checklist. Add `--arch` or `--full` to include architecture analysis:
18
18
 
19
19
  | Domain | Examples | Default |
20
20
  |---|---|---|
21
- | **Type Safety** | `any` abuse, unsafe casts, non-null assertions, missing exhaustive checks | ✓ |
22
- | **Security** | Injection, prototype pollution, ReDoS, path traversal, hardcoded secrets | ✓ |
23
- | **Async Patterns** | Floating promises, race conditions, missing error propagation, `forEach(async...)` | ✓ |
24
- | **Modernization** | `enum` → `as const`, missing `satisfies`, `using` keyword, `import type` | ✓ |
25
- | **Code Quality** | Dead code, complexity, duplication, hacky patterns, error handling | ✓ |
26
- | **Config** | tsconfig.json strict flags, module resolution, deprecated options | ✓ |
27
- | **Architecture** | Shallow modules, scattered concepts, tight coupling, dependency seams, testability | `--arch` / `--full` |
21
+ | **Type Safety** | `any` abuse, unsafe casts, non-null assertions, `unknown` discipline, missing exhaustive checks | ✓ |
22
+ | **Security** | Injection, SSRF, prototype pollution, ReDoS, path traversal, hardcoded secrets | ✓ |
23
+ | **Async Patterns** | Floating promises, race conditions, missing timeouts, unbounded concurrency, `forEach(async...)` | ✓ |
24
+ | **Modernization** | Numeric enums, `\|\|` vs `??`, mutating array methods, `satisfies`, `using` keyword | ✓ |
25
+ | **Code Quality** | Dead code, complexity, duplication, debug artifacts, import-time side effects, testability | ✓ |
26
+ | **Config** | tsconfig.json strict flags, target/lib, module resolution, deprecated options | ✓ |
27
+ | **Boundary Validation** | `as T` on `JSON.parse`/`fetch`/env, DTO vs domain model separation, contract drift | ✓ |
28
+ | **Error Handling** | Silent failures, throw hygiene, `cause` chaining, failure design at API seams | ✓ |
29
+ | **Dependency Hygiene** | Lockfiles, wildcard versions, `npm audit`, duplicate-purpose and trivial deps | ✓ |
30
+ | **Architecture** | Shallow modules, scattered concepts, tight coupling, dependency direction, layering | `--arch` / `--full` |
28
31
 
29
32
  ## Installation
30
33
 
@@ -40,8 +43,8 @@ The installer prints a short summary before installation:
40
43
 
41
44
  ```text
42
45
  TypeScript Code Reviewer
43
- Checks: type safety, async patterns, security, tsconfig, modernization, code quality
44
- Target TypeScript: 5.9+
46
+ Checks: type safety, security, async patterns, boundary validation, error handling, modernization, code quality, tsconfig, dependency hygiene
47
+ Target stack: TypeScript 5.9.x, ES2024, Node 24
45
48
  ```
46
49
 
47
50
  Then it asks which AI agents to install for. Use Up/Down arrows to move, Space to toggle, and Enter to confirm.
@@ -51,9 +54,11 @@ Supported targets:
51
54
  | AI agent | Install path |
52
55
  |---|---|
53
56
  | Claude Code | `.claude/skills/ts-reviewer/` |
54
- | Codex | `.codex/skills/ts-reviewer/` |
57
+ | Codex | `.agents/skills/ts-reviewer/` |
55
58
  | Antigravity | `.agent/skills/ts-reviewer/` |
56
59
 
60
+ > **Note on Codex:** project-local skills belong in `.agents/` per the Codex docs; `~/.codex/` is the *global* per-user directory. Codex also reads a project-local `.codex/` implicitly, so installs from older versions of this installer keep working — but `.agents/` is the correct location going forward.
61
+
57
62
  In non-interactive terminals, the installer selects all supported targets.
58
63
 
59
64
  ### Manual Install
@@ -80,13 +85,14 @@ Claude will analyze the project and write a report to `code-smells.md` in the pr
80
85
 
81
86
  #### Domain flags
82
87
 
83
- By default, only the six core domains run. Use flags to control which domains are active:
88
+ By default, only the nine core domains run. Use flags to control which domains are active:
84
89
 
85
90
  | Flag | What runs |
86
91
  |---|---|
87
- | *(none)* | Type Safety, Security, Async, Modernization, Code Quality, Config |
88
- | `--arch` | Architecture only (shallow modules, coupling, dependency seams) |
89
- | `--full` | All seven domains |
92
+ | *(none)* | Type Safety, Security, Async, Modernization, Code Quality, Config, Boundary Validation, Error Handling, Dependency Hygiene |
93
+ | `--arch` | Architecture only (shallow modules, coupling, dependency direction, seams) |
94
+ | `--full` | All ten domains |
95
+ | `--no-arch` | The nine core domains — overrides `--arch`, `--full`, and any phrase that would enable architecture |
90
96
 
91
97
  Examples:
92
98
 
@@ -140,7 +146,7 @@ By default the entire codebase is reviewed. You can narrow the scope:
140
146
  | What you say | What gets reviewed |
141
147
  |---|---|
142
148
  | *"review my code"* | Full codebase |
143
- | *"review my changes"*, *"check uncommitted"* | Staged + unstaged + untracked `.ts` files |
149
+ | *"review my changes"*, *"check uncommitted"* | Staged + unstaged + untracked `.ts`/`.mts`/`.cts` files |
144
150
  | *"review my PR"*, *"diff against main"* | All changes on current branch vs base |
145
151
  | *"review last commit"*, *"check last 3 commits"* | Last N commits |
146
152
 
@@ -170,21 +176,37 @@ Architecture findings use the same scale. Each candidate also carries a **Fixabi
170
176
  ## Project Structure
171
177
 
172
178
  ```
179
+ AGENTS.md # How to edit the review rules — read before changing anything below
180
+ CLAUDE.md # Pointer to AGENTS.md, picked up automatically by Claude Code
181
+
173
182
  src/ # npm/npx installer source
174
183
  ├── cli.ts # CLI entrypoint and provider prompt
175
184
  ├── prompt.ts # raw-mode keyboard multi-select
176
185
  └── paths.ts # target directories and skill asset loading
177
186
 
187
+ cnlp/ # the CNL-P format the skill files are written in
188
+ ├── cnlp-format.md # the standard: forms, line rules, lexicon
189
+ ├── cnlp.js # the checker — Node builtins only, no dependencies
190
+ ├── skill-format.test.js # the conformance test, run by `npm test`
191
+ └── profiles/ # what each kind of document may contain
192
+ ├── skill.md # → ts-reviewer/SKILL.md
193
+ ├── reference.md # → ts-reviewer/references/*.md
194
+ ├── guide.md # → AGENTS.md
195
+ └── profile.md # → the profiles themselves
196
+
178
197
  ts-reviewer/
179
198
  ├── SKILL.md # Main skill file — mode routing, workflow orchestration
180
199
  └── references/
181
- ├── type-safety.md # Checklist: any, casts, !, exhaustiveness, generics
182
- ├── security.md # Checklist: injection, pollution, ReDoS, traversal
183
- ├── async-patterns.md # Checklist: floating promises, races, cancellation
184
- ├── modernization.md # Checklist: TS 5.9+ idioms, satisfies, using, as const
185
- ├── code-quality.md # Checklist: complexity, dead code, naming, duplication
186
- ├── tsconfig.md # Checklist: strict flags, module resolution, deprecated
187
- ├── architecture.md # Checklist: shallow modules, coupling, seams, deepening
200
+ ├── type-safety.md # Checklist: any, unknown, casts, !, exhaustiveness, branded types
201
+ ├── security.md # Checklist: trust boundaries, injection, SSRF, pollution, ReDoS
202
+ ├── async-patterns.md # Checklist: floating promises, races, timeouts, retries, cancellation
203
+ ├── boundary-validation.md # Checklist: runtime validation at edges, DTO/domain separation
204
+ ├── error-handling.md # Checklist: silent failures, throw hygiene, failure design
205
+ ├── modernization.md # Checklist: patterns below the stack, ??/?. , satisfies, using, toSorted
206
+ ├── code-quality.md # Checklist: complexity, dead code, debug artifacts, testability
207
+ ├── tsconfig.md # Checklist: strict flags, target/lib, module resolution, deprecated
208
+ ├── dependency-hygiene.md # Checklist: lockfiles, versions, npm audit, dependency choice
209
+ ├── architecture.md # Checklist: shallow modules, coupling, dependency direction, seams
188
210
  └── fix-workflow.md # Complete fix protocol: tests, verification, rollback
189
211
  ```
190
212
 
@@ -192,14 +214,34 @@ ts-reviewer/
192
214
 
193
215
  **Reference files** contain the detailed checklists and protocols. Each analysis agent reads only the reference file relevant to its domain, keeping context focused. Architecture analysis is opt-in and loaded only when the domain is active.
194
216
 
217
+ ## Editing the Rules
218
+
219
+ As of 2.0.0, `SKILL.md` and every reference file are written in **CNL-P** — a block-structured format an agent reads as instructions rather than prose. One rule per line, one term per concept, no headings, a hard 250-character line limit.
220
+
221
+ A check line looks like this:
222
+
223
+ ```
224
+ - injection — `eval()` and `new Function()` executing a dynamic string: Highest, use a lookup table, a strategy, or a safe parser
225
+ ```
226
+
227
+ The format is enforced, not merely recommended:
228
+
229
+ ```bash
230
+ npm test # typecheck + 5 conformance tests
231
+ ```
232
+
233
+ The test catches a check line that lost its severity, a block the profile does not declare, blocks out of order, a banned vague word, and a line over the limit — each reported with its file and line number.
234
+
235
+ **Before adding or changing a rule, read [`AGENTS.md`](AGENTS.md).** It states which file owns which domain, the shape of a check line, the severity scale, which block takes what, and the line rules. Claude Code picks this up on its own through `CLAUDE.md`; for another agent, point it at `AGENTS.md` explicitly.
236
+
195
237
  ## How It Works Under the Hood
196
238
 
197
239
  ### Scan mode
198
240
 
199
241
  1. **Discovery** — detects domain flags, maps the project, reads tsconfig.json, detects linter and test runner. If architecture is active, also maps module relationships and checks for `docs/adr/`.
200
242
  2. **Diagnostics** — runs `tsc --noEmit`, linter, and LSP diagnostics (if available)
201
- 3. **Analysis** — specialized passes for each active domain (sub-agents in Claude Code, sequential in Claude.ai), each with its own checklist
202
- 4. **Report** — deduplicates, applies severity boost (scoped modes), consolidates recurring patterns, writes `code-smells.md`. Architecture findings appear in a separate `## Architecture Opportunities` section at the end.
243
+ 3. **Analysis** — specialized passes for each active domain (sub-agents in Claude Code, sequential in Claude.ai), each with its own checklist. Every finding passes an Evidence Protocol: verified against the actual file content, confidence-gated, version-gated against the project's TS/runtime.
244
+ 4. **Report** — deduplicates, applies severity boost (scoped modes), consolidates recurring patterns, enforces a noise budget, writes `code-smells.md`. Architecture findings appear in a separate `## Architecture Opportunities` section at the end.
203
245
 
204
246
  ### Fix mode
205
247
 
@@ -224,9 +266,9 @@ ts-reviewer/
224
266
 
225
267
  ## Requirements
226
268
 
227
- - TypeScript 5.9+ project
269
+ - TypeScript 5.9.x project targeting ES2024 on Node 24
228
270
  - Git repository (for scoped modes and safe revert during fix)
229
- - Node.js with `npx` available (for tsc, linter)
271
+ - Node 24 with `npx` available (for tsc, linter)
230
272
  - Claude Code (recommended) or any Claude interface with skill support
231
273
 
232
274
  ## License
package/dist/cli.js CHANGED
@@ -1,11 +1,9 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- const index_1 = require("./index");
5
- const prompt_1 = require("./prompt");
6
- const paths_1 = require("./paths");
2
+ import { scaffoldTsReviewerSkill } from "./index.js";
3
+ import { multiSelect } from "./prompt.js";
4
+ import { AI_PROVIDERS, skillTargetDir } from "./paths.js";
7
5
  const SKILL_NAME = "ts-reviewer";
8
- const TYPESCRIPT_VERSION = "5.9+";
6
+ const TARGET_STACK = "TypeScript 5.9.x, ES2024, Node 24";
9
7
  function printHelp() {
10
8
  process.stdout.write([
11
9
  "ts-reviewer: install TypeScript review skill\n",
@@ -27,20 +25,20 @@ async function main() {
27
25
  const skillName = SKILL_NAME;
28
26
  process.stdout.write([
29
27
  "TypeScript Code Reviewer\n",
30
- `Checks: type safety, async patterns, security, tsconfig, modernization, code quality\n`,
31
- `Target TypeScript: ${TYPESCRIPT_VERSION}\n`,
28
+ `Checks: type safety, security, async patterns, boundary validation, error handling, modernization, code quality, tsconfig, dependency hygiene\n`,
29
+ `Target stack: ${TARGET_STACK}\n`,
32
30
  "\n",
33
31
  ].join(""));
34
- const selected = await (0, prompt_1.multiSelect)("Install for which AI agents? (Space = toggle, Enter = confirm)", paths_1.AI_PROVIDERS);
32
+ const selected = await multiSelect("Install for which AI agents? (Space = toggle, Enter = confirm)", AI_PROVIDERS);
35
33
  if (selected.length === 0) {
36
34
  process.stdout.write("No agents selected. Exiting.\n");
37
35
  return;
38
36
  }
39
37
  for (const provider of selected) {
40
- const targetDir = (0, paths_1.skillTargetDir)(cwd, provider, skillName);
41
- const providerLabel = paths_1.AI_PROVIDERS.find((p) => p.value === provider).label;
38
+ const targetDir = skillTargetDir(cwd, provider, skillName);
39
+ const providerLabel = AI_PROVIDERS.find((p) => p.value === provider).label;
42
40
  process.stdout.write(`\n[${providerLabel}]\n`);
43
- const result = await (0, index_1.scaffoldTsReviewerSkill)({ cwd, skillName, targetDir });
41
+ const result = await scaffoldTsReviewerSkill({ cwd, skillName, targetDir });
44
42
  for (const e of result.entries) {
45
43
  const suffix = e.detail ? ` (${e.detail})` : "";
46
44
  process.stdout.write(`${e.action}\t${e.relativePath}${suffix}\n`);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,mCAAkD;AAClD,qCAAuC;AACvC,mCAAwE;AAExE,MAAM,UAAU,GAAG,aAAa,CAAC;AACjC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,SAAS,SAAS;IAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB;QACE,gDAAgD;QAChD,IAAI;QACJ,UAAU;QACV,qBAAqB;QACrB,IAAI;QACJ,YAAY;QACZ,+BAA+B;KAChC,CAAC,IAAI,CAAC,EAAE,CAAC,CACX,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnD,SAAS,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,SAAS,GAAG,UAAU,CAAC;IAE7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB;QACE,4BAA4B;QAC5B,wFAAwF;QACxF,sBAAsB,kBAAkB,IAAI;QAC5C,IAAI;KACL,CAAC,IAAI,CAAC,EAAE,CAAC,CACX,CAAC;IAEF,MAAM,QAAQ,GAAG,MAAM,IAAA,oBAAW,EAChC,gEAAgE,EAChE,oBAAY,CACb,CAAC;IAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,KAAK,MAAM,QAAQ,IAAI,QAAwB,EAAE,CAAC;QAChD,MAAM,SAAS,GAAG,IAAA,sBAAc,EAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC3D,MAAM,aAAa,GAAG,oBAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAE,CAAC,KAAK,CAAC;QAE5E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,aAAa,KAAK,CAAC,CAAC;QAE/C,MAAM,MAAM,GAAG,MAAM,IAAA,+BAAuB,EAAC,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;QAE5E,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAChD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,YAAY,GAAG,MAAM,IAAI,CAAC,CAAC;QACpE,CAAC;QAED,IAAI,MAAM,CAAC,YAAY;YAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAE,GAAa,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAE,GAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACzF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,cAAc,EAAmB,MAAM,YAAY,CAAC;AAE3E,MAAM,UAAU,GAAG,aAAa,CAAC;AACjC,MAAM,YAAY,GAAG,mCAAmC,CAAC;AAEzD,SAAS,SAAS;IAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB;QACE,gDAAgD;QAChD,IAAI;QACJ,UAAU;QACV,qBAAqB;QACrB,IAAI;QACJ,YAAY;QACZ,+BAA+B;KAChC,CAAC,IAAI,CAAC,EAAE,CAAC,CACX,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnD,SAAS,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,SAAS,GAAG,UAAU,CAAC;IAE7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB;QACE,4BAA4B;QAC5B,iJAAiJ;QACjJ,iBAAiB,YAAY,IAAI;QACjC,IAAI;KACL,CAAC,IAAI,CAAC,EAAE,CAAC,CACX,CAAC;IAEF,MAAM,QAAQ,GAAG,MAAM,WAAW,CAChC,gEAAgE,EAChE,YAAY,CACb,CAAC;IAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,KAAK,MAAM,QAAQ,IAAI,QAAwB,EAAE,CAAC;QAChD,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC3D,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAE,CAAC,KAAK,CAAC;QAE5E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,aAAa,KAAK,CAAC,CAAC;QAE/C,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;QAE5E,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAChD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,YAAY,GAAG,MAAM,IAAI,CAAC,CAAC;QACpE,CAAC;QAED,IAAI,MAAM,CAAC,YAAY;YAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAE,GAAa,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAE,GAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACzF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
package/dist/hash.js CHANGED
@@ -1,11 +1,5 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.sha256Hex = sha256Hex;
7
- const node_crypto_1 = __importDefault(require("node:crypto"));
8
- function sha256Hex(input) {
9
- return node_crypto_1.default.createHash("sha256").update(input, "utf8").digest("hex");
1
+ import crypto from "node:crypto";
2
+ export function sha256Hex(input) {
3
+ return crypto.createHash("sha256").update(input, "utf8").digest("hex");
10
4
  }
11
5
  //# sourceMappingURL=hash.js.map
package/dist/hash.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hash.js","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":";;;;;AAEA,8BAEC;AAJD,8DAAiC;AAEjC,SAAgB,SAAS,CAAC,KAAa;IACrC,OAAO,qBAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzE,CAAC"}
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzE,CAAC"}
package/dist/incoming.js CHANGED
@@ -1,14 +1,8 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.findAvailableIncomingPath = findAvailableIncomingPath;
7
- const promises_1 = __importDefault(require("node:fs/promises"));
8
- const node_path_1 = __importDefault(require("node:path"));
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
9
3
  async function exists(p) {
10
4
  try {
11
- await promises_1.default.stat(p);
5
+ await fs.stat(p);
12
6
  return true;
13
7
  }
14
8
  catch (e) {
@@ -17,18 +11,18 @@ async function exists(p) {
17
11
  throw e;
18
12
  }
19
13
  }
20
- async function findAvailableIncomingPath(dstPath) {
21
- const dir = node_path_1.default.dirname(dstPath);
22
- const base = node_path_1.default.basename(dstPath);
23
- const first = node_path_1.default.join(dir, `${base}.incoming`);
14
+ export async function findAvailableIncomingPath(dstPath) {
15
+ const dir = path.dirname(dstPath);
16
+ const base = path.basename(dstPath);
17
+ const first = path.join(dir, `${base}.incoming`);
24
18
  if (!(await exists(first)))
25
19
  return first;
26
20
  for (let i = 2; i < 1000; i++) {
27
- const p = node_path_1.default.join(dir, `${base}.incoming${i}`);
21
+ const p = path.join(dir, `${base}.incoming${i}`);
28
22
  if (!(await exists(p)))
29
23
  return p;
30
24
  }
31
25
  // should never happen
32
- return node_path_1.default.join(dir, `${base}.incoming-${Date.now()}`);
26
+ return path.join(dir, `${base}.incoming-${Date.now()}`);
33
27
  }
34
28
  //# sourceMappingURL=incoming.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"incoming.js","sourceRoot":"","sources":["../src/incoming.ts"],"names":[],"mappings":";;;;;AAaA,8DAcC;AA3BD,gEAAkC;AAClC,0DAA6B;AAE7B,KAAK,UAAU,MAAM,CAAC,CAAS;IAC7B,IAAI,CAAC;QACH,MAAM,kBAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC3C,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,yBAAyB,CAAC,OAAe;IAC7D,MAAM,GAAG,GAAG,mBAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,mBAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAEpC,MAAM,KAAK,GAAG,mBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,WAAW,CAAC,CAAC;IACjD,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAEzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,mBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,YAAY,CAAC,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,sBAAsB;IACtB,OAAO,mBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,aAAa,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAC1D,CAAC"}
1
+ {"version":3,"file":"incoming.js","sourceRoot":"","sources":["../src/incoming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,KAAK,UAAU,MAAM,CAAC,CAAS;IAC7B,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC3C,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,OAAe;IAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAEpC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,WAAW,CAAC,CAAC;IACjD,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAEzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,YAAY,CAAC,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,sBAAsB;IACtB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,aAAa,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAC1D,CAAC"}
package/dist/index.js CHANGED
@@ -1,41 +1,35 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.scaffoldTsReviewerSkill = scaffoldTsReviewerSkill;
7
- const node_path_1 = __importDefault(require("node:path"));
8
- const paths_1 = require("./paths");
9
- const meta_1 = require("./meta");
10
- const hash_1 = require("./hash");
11
- const io_1 = require("./io");
12
- const updatePolicy_1 = require("./updatePolicy");
13
- const incoming_1 = require("./incoming");
14
- async function scaffoldTsReviewerSkill(opts) {
1
+ import path from "node:path";
2
+ import { listSkillAssetTemplates } from "./paths.js";
3
+ import { readMeta, writeMeta } from "./meta.js";
4
+ import { sha256Hex } from "./hash.js";
5
+ import { ensureDir, readFileIfExists, atomicWriteFile } from "./io.js";
6
+ import { decideUpdate } from "./updatePolicy.js";
7
+ import { findAvailableIncomingPath } from "./incoming.js";
8
+ export async function scaffoldTsReviewerSkill(opts) {
15
9
  const skillName = opts.skillName;
16
10
  const targetDir = opts.targetDir;
17
- await (0, io_1.ensureDir)(targetDir);
18
- const metaPath = node_path_1.default.join(targetDir, ".scaffold-meta.json");
19
- const meta = (await (0, meta_1.readMeta)(metaPath)) ?? { version: 1, files: {} };
11
+ await ensureDir(targetDir);
12
+ const metaPath = path.join(targetDir, ".scaffold-meta.json");
13
+ const meta = (await readMeta(metaPath)) ?? { version: 1, files: {} };
20
14
  const entries = [];
21
15
  let hadConflicts = false;
22
- for (const t of (0, paths_1.listSkillAssetTemplates)(skillName)) {
23
- const relativePath = node_path_1.default.relative(opts.cwd, node_path_1.default.join(targetDir, t.fileName)).replace(/\\/g, "/");
24
- const dstPath = node_path_1.default.join(targetDir, t.fileName);
16
+ for (const t of listSkillAssetTemplates(skillName)) {
17
+ const relativePath = path.relative(opts.cwd, path.join(targetDir, t.fileName)).replace(/\\/g, "/");
18
+ const dstPath = path.join(targetDir, t.fileName);
25
19
  const desired = t.content;
26
- const desiredHash = (0, hash_1.sha256Hex)(desired);
27
- const existing = await (0, io_1.readFileIfExists)(dstPath);
28
- const existingHash = existing === null ? null : (0, hash_1.sha256Hex)(existing);
20
+ const desiredHash = sha256Hex(desired);
21
+ const existing = await readFileIfExists(dstPath);
22
+ const existingHash = existing === null ? null : sha256Hex(existing);
29
23
  const lastWrittenHash = meta.files[t.fileName]?.lastWrittenHash ?? null;
30
- const decision = (0, updatePolicy_1.decideUpdate)({ existingHash, lastWrittenHash });
24
+ const decision = decideUpdate({ existingHash, lastWrittenHash });
31
25
  if (decision.kind === "write") {
32
- await (0, io_1.atomicWriteFile)(dstPath, desired);
26
+ await atomicWriteFile(dstPath, desired);
33
27
  meta.files[t.fileName] = { lastWrittenHash: desiredHash };
34
28
  entries.push({ action: "WROTE", relativePath });
35
29
  continue;
36
30
  }
37
31
  if (decision.kind === "overwrite") {
38
- await (0, io_1.atomicWriteFile)(dstPath, desired);
32
+ await atomicWriteFile(dstPath, desired);
39
33
  meta.files[t.fileName] = { lastWrittenHash: desiredHash };
40
34
  entries.push({ action: "UPDATED", relativePath });
41
35
  continue;
@@ -46,15 +40,15 @@ async function scaffoldTsReviewerSkill(opts) {
46
40
  }
47
41
  // conflict
48
42
  hadConflicts = true;
49
- const incomingPath = await (0, incoming_1.findAvailableIncomingPath)(dstPath);
50
- await (0, io_1.atomicWriteFile)(incomingPath, desired);
43
+ const incomingPath = await findAvailableIncomingPath(dstPath);
44
+ await atomicWriteFile(incomingPath, desired);
51
45
  entries.push({
52
46
  action: "CONFLICT",
53
47
  relativePath,
54
- detail: node_path_1.default.basename(incomingPath),
48
+ detail: path.basename(incomingPath),
55
49
  });
56
50
  }
57
- await (0, meta_1.writeMeta)(metaPath, meta);
51
+ await writeMeta(metaPath, meta);
58
52
  return { entries, hadConflicts };
59
53
  }
60
54
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/io.js CHANGED
@@ -1,19 +1,11 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ensureDir = ensureDir;
7
- exports.readFileIfExists = readFileIfExists;
8
- exports.atomicWriteFile = atomicWriteFile;
9
- const promises_1 = __importDefault(require("node:fs/promises"));
10
- const node_path_1 = __importDefault(require("node:path"));
11
- async function ensureDir(dirPath) {
12
- await promises_1.default.mkdir(dirPath, { recursive: true });
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ export async function ensureDir(dirPath) {
4
+ await fs.mkdir(dirPath, { recursive: true });
13
5
  }
14
- async function readFileIfExists(filePath) {
6
+ export async function readFileIfExists(filePath) {
15
7
  try {
16
- return await promises_1.default.readFile(filePath, "utf8");
8
+ return await fs.readFile(filePath, "utf8");
17
9
  }
18
10
  catch (e) {
19
11
  if (e && (e.code === "ENOENT" || e.code === "ENOTDIR"))
@@ -21,19 +13,19 @@ async function readFileIfExists(filePath) {
21
13
  throw e;
22
14
  }
23
15
  }
24
- async function atomicWriteFile(filePath, content) {
25
- const dir = node_path_1.default.dirname(filePath);
16
+ export async function atomicWriteFile(filePath, content) {
17
+ const dir = path.dirname(filePath);
26
18
  await ensureDir(dir);
27
- const tmp = node_path_1.default.join(dir, `.${node_path_1.default.basename(filePath)}.tmp-${process.pid}-${Date.now()}`);
28
- await promises_1.default.writeFile(tmp, content, "utf8");
19
+ const tmp = path.join(dir, `.${path.basename(filePath)}.tmp-${process.pid}-${Date.now()}`);
20
+ await fs.writeFile(tmp, content, "utf8");
29
21
  try {
30
22
  // Windows cannot atomically replace existing; remove first.
31
- await promises_1.default.unlink(filePath);
23
+ await fs.unlink(filePath);
32
24
  }
33
25
  catch (e) {
34
26
  if (!(e && e.code === "ENOENT"))
35
27
  throw e;
36
28
  }
37
- await promises_1.default.rename(tmp, filePath);
29
+ await fs.rename(tmp, filePath);
38
30
  }
39
31
  //# sourceMappingURL=io.js.map
package/dist/io.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"io.js","sourceRoot":"","sources":["../src/io.ts"],"names":[],"mappings":";;;;;AAGA,8BAEC;AAED,4CAOC;AAED,0CAeC;AA/BD,gEAAkC;AAClC,0DAA6B;AAEtB,KAAK,UAAU,SAAS,CAAC,OAAe;IAC7C,MAAM,kBAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/C,CAAC;AAEM,KAAK,UAAU,gBAAgB,CAAC,QAAgB;IACrD,IAAI,CAAC;QACH,OAAO,MAAM,kBAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC;QACpE,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,eAAe,CAAC,QAAgB,EAAE,OAAe;IACrE,MAAM,GAAG,GAAG,mBAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;IAErB,MAAM,GAAG,GAAG,mBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,mBAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC3F,MAAM,kBAAE,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAEzC,IAAI,CAAC;QACH,4DAA4D;QAC5D,MAAM,kBAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;YAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,kBAAE,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"io.js","sourceRoot":"","sources":["../src/io.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAe;IAC7C,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,QAAgB;IACrD,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC;QACpE,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAgB,EAAE,OAAe;IACrE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;IAErB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC3F,MAAM,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAEzC,IAAI,CAAC;QACH,4DAA4D;QAC5D,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;YAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AACjC,CAAC"}
package/dist/meta.js CHANGED
@@ -1,14 +1,7 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.readMeta = readMeta;
7
- exports.writeMeta = writeMeta;
8
- const promises_1 = __importDefault(require("node:fs/promises"));
9
- async function readMeta(metaPath) {
1
+ import fs from "node:fs/promises";
2
+ export async function readMeta(metaPath) {
10
3
  try {
11
- const raw = await promises_1.default.readFile(metaPath, "utf8");
4
+ const raw = await fs.readFile(metaPath, "utf8");
12
5
  const parsed = JSON.parse(raw);
13
6
  if (!parsed || parsed.version !== 1 || typeof parsed.files !== "object")
14
7
  return null;
@@ -20,8 +13,8 @@ async function readMeta(metaPath) {
20
13
  throw e;
21
14
  }
22
15
  }
23
- async function writeMeta(metaPath, meta) {
16
+ export async function writeMeta(metaPath, meta) {
24
17
  const body = JSON.stringify(meta, null, 2) + "\n";
25
- await promises_1.default.writeFile(metaPath, body, "utf8");
18
+ await fs.writeFile(metaPath, body, "utf8");
26
19
  }
27
20
  //# sourceMappingURL=meta.js.map
package/dist/meta.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"meta.js","sourceRoot":"","sources":["../src/meta.ts"],"names":[],"mappings":";;;;;AAOA,4BAUC;AAED,8BAGC;AAtBD,gEAAkC;AAO3B,KAAK,UAAU,QAAQ,CAAC,QAAgB;IAC7C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACrF,OAAO,MAAsB,CAAC;IAChC,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC1C,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,SAAS,CAAC,QAAgB,EAAE,IAAkB;IAClE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IAClD,MAAM,kBAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"meta.js","sourceRoot":"","sources":["../src/meta.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAOlC,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB;IAC7C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACrF,OAAO,MAAsB,CAAC;IAChC,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC1C,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAgB,EAAE,IAAkB;IAClE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IAClD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAC7C,CAAC"}
package/dist/paths.js CHANGED
@@ -1,54 +1,47 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.AI_PROVIDERS = void 0;
7
- exports.skillTargetDir = skillTargetDir;
8
- exports.skillAssetsDir = skillAssetsDir;
9
- exports.listSkillAssetTemplates = listSkillAssetTemplates;
10
- const node_fs_1 = __importDefault(require("node:fs"));
11
- const node_path_1 = __importDefault(require("node:path"));
12
- exports.AI_PROVIDERS = [
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ export const AI_PROVIDERS = [
13
4
  { label: "Claude Code", value: "claude-code" },
14
5
  { label: "Codex", value: "codex" },
15
6
  { label: "Antigravity", value: "antigravity" },
16
7
  ];
17
8
  const PROVIDER_BASE = {
18
9
  "claude-code": ".claude",
19
- "codex": ".codex",
10
+ // Project-local Codex skills belong in ".agents"; "~/.codex" is the global user dir.
11
+ // Codex also reads ".codex" implicitly, but ".agents" is the documented location.
12
+ "codex": ".agents",
20
13
  "antigravity": ".agent",
21
14
  };
22
- function skillTargetDir(projectRoot, provider, skillName) {
23
- return node_path_1.default.join(projectRoot, PROVIDER_BASE[provider], "skills", skillName);
15
+ export function skillTargetDir(projectRoot, provider, skillName) {
16
+ return path.join(projectRoot, PROVIDER_BASE[provider], "skills", skillName);
24
17
  }
25
18
  function packageRootDir() {
26
19
  // dist/* at runtime; src/* in dev. In both cases, package root is one level up.
27
- return node_path_1.default.resolve(__dirname, "..");
20
+ return path.resolve(import.meta.dirname, "..");
28
21
  }
29
- function skillAssetsDir(skillName) {
30
- return node_path_1.default.join(packageRootDir(), skillName);
22
+ export function skillAssetsDir(skillName) {
23
+ return path.join(packageRootDir(), skillName);
31
24
  }
32
25
  function readAsset(skillName, fileName) {
33
- const p = node_path_1.default.join(skillAssetsDir(skillName), fileName);
34
- return node_fs_1.default.readFileSync(p, "utf8");
26
+ const p = path.join(skillAssetsDir(skillName), fileName);
27
+ return fs.readFileSync(p, "utf8");
35
28
  }
36
29
  function walkAssetFiles(rootDir, currentDir = rootDir) {
37
- const entries = node_fs_1.default.readdirSync(currentDir, { withFileTypes: true });
30
+ const entries = fs.readdirSync(currentDir, { withFileTypes: true });
38
31
  const files = [];
39
32
  for (const entry of entries) {
40
- const absolutePath = node_path_1.default.join(currentDir, entry.name);
33
+ const absolutePath = path.join(currentDir, entry.name);
41
34
  if (entry.isDirectory()) {
42
35
  files.push(...walkAssetFiles(rootDir, absolutePath));
43
36
  continue;
44
37
  }
45
38
  if (entry.isFile()) {
46
- files.push(node_path_1.default.relative(rootDir, absolutePath).replace(/\\/g, "/"));
39
+ files.push(path.relative(rootDir, absolutePath).replace(/\\/g, "/"));
47
40
  }
48
41
  }
49
42
  return files.sort();
50
43
  }
51
- function listSkillAssetTemplates(skillName) {
44
+ export function listSkillAssetTemplates(skillName) {
52
45
  return walkAssetFiles(skillAssetsDir(skillName)).map((fileName) => ({
53
46
  fileName,
54
47
  content: readAsset(skillName, fileName),
package/dist/paths.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":";;;;;;AAiBA,wCAEC;AASD,wCAEC;AA0BD,0DAKC;AA7DD,sDAAyB;AACzB,0DAA6B;AAIhB,QAAA,YAAY,GAA2C;IAClE,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE;IAC9C,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;IAClC,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE;CAC/C,CAAC;AAEF,MAAM,aAAa,GAA+B;IAChD,aAAa,EAAE,SAAS;IACxB,OAAO,EAAE,QAAQ;IACjB,aAAa,EAAE,QAAQ;CACxB,CAAC;AAEF,SAAgB,cAAc,CAAC,WAAmB,EAAE,QAAoB,EAAE,SAAiB;IACzF,OAAO,mBAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AAC9E,CAAC;AAID,SAAS,cAAc;IACrB,gFAAgF;IAChF,OAAO,mBAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,SAAgB,cAAc,CAAC,SAAiB;IAC9C,OAAO,mBAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,SAAS,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,SAAS,CAAC,SAAiB,EAAE,QAAgB;IACpD,MAAM,CAAC,GAAG,mBAAI,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,CAAC;IACzD,OAAO,iBAAE,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,cAAc,CAAC,OAAe,EAAE,UAAU,GAAG,OAAO;IAC3D,MAAM,OAAO,GAAG,iBAAE,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,YAAY,GAAG,mBAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACvD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;YACrD,SAAS;QACX,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,mBAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,SAAgB,uBAAuB,CAAC,SAAiB;IACvD,OAAO,cAAc,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAClE,QAAQ;QACR,OAAO,EAAE,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC;KACxC,CAAC,CAAC,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,MAAM,CAAC,MAAM,YAAY,GAA2C;IAClE,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE;IAC9C,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;IAClC,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE;CAC/C,CAAC;AAEF,MAAM,aAAa,GAA+B;IAChD,aAAa,EAAE,SAAS;IACxB,qFAAqF;IACrF,kFAAkF;IAClF,OAAO,EAAE,SAAS;IAClB,aAAa,EAAE,QAAQ;CACxB,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,QAAoB,EAAE,SAAiB;IACzF,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AAC9E,CAAC;AAID,SAAS,cAAc;IACrB,gFAAgF;IAChF,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,SAAS,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,SAAS,CAAC,SAAiB,EAAE,QAAgB;IACpD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,CAAC;IACzD,OAAO,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,cAAc,CAAC,OAAe,EAAE,UAAU,GAAG,OAAO;IAC3D,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACvD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;YACrD,SAAS;QACX,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,SAAiB;IACvD,OAAO,cAAc,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAClE,QAAQ;QACR,OAAO,EAAE,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC;KACxC,CAAC,CAAC,CAAC;AACN,CAAC"}