@0xcraft/powershot 1.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.
Files changed (87) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +306 -0
  3. package/dist/agents.js +82 -0
  4. package/dist/bench.js +179 -0
  5. package/dist/budget.js +59 -0
  6. package/dist/bundle.js +173 -0
  7. package/dist/cache.js +155 -0
  8. package/dist/cli/agent-command.js +27 -0
  9. package/dist/cli/app.js +31 -0
  10. package/dist/cli/args.js +76 -0
  11. package/dist/cli/bench-command.js +89 -0
  12. package/dist/cli/dismiss-command.js +42 -0
  13. package/dist/cli/environment.js +32 -0
  14. package/dist/cli/reports.js +64 -0
  15. package/dist/cli/review-command.js +268 -0
  16. package/dist/cli/session-command.js +62 -0
  17. package/dist/cli.js +7 -0
  18. package/dist/config.js +130 -0
  19. package/dist/delegate.js +84 -0
  20. package/dist/dismissed.js +130 -0
  21. package/dist/fspolicy.js +62 -0
  22. package/dist/git.js +238 -0
  23. package/dist/ground.js +286 -0
  24. package/dist/judges/judge.js +85 -0
  25. package/dist/judges/llm.js +234 -0
  26. package/dist/judges/prompts.js +86 -0
  27. package/dist/judges/tools.js +125 -0
  28. package/dist/lang/packs.js +557 -0
  29. package/dist/lang/pyright.js +108 -0
  30. package/dist/lang/python-deps.js +174 -0
  31. package/dist/lang/ruby-deps.js +77 -0
  32. package/dist/langtest.js +248 -0
  33. package/dist/manifest.js +209 -0
  34. package/dist/otel.js +75 -0
  35. package/dist/package-meta.js +13 -0
  36. package/dist/package-smoke.js +110 -0
  37. package/dist/plan.js +134 -0
  38. package/dist/position.js +94 -0
  39. package/dist/report/ansi.js +18 -0
  40. package/dist/report/codequality.js +19 -0
  41. package/dist/report/compact.js +15 -0
  42. package/dist/report/highlight.js +54 -0
  43. package/dist/report/markdown.js +113 -0
  44. package/dist/report/sarif.js +66 -0
  45. package/dist/report/terminal.js +170 -0
  46. package/dist/report/viewer.js +148 -0
  47. package/dist/review.js +355 -0
  48. package/dist/scan.js +67 -0
  49. package/dist/selftest.js +1928 -0
  50. package/dist/session.js +140 -0
  51. package/dist/snapshot.js +101 -0
  52. package/dist/text.js +50 -0
  53. package/dist/types.js +2 -0
  54. package/dist/verifiers/assertion-drift.js +137 -0
  55. package/dist/verifiers/contract-drift.js +140 -0
  56. package/dist/verifiers/copy-paste-drift.js +106 -0
  57. package/dist/verifiers/dead-on-arrival.js +92 -0
  58. package/dist/verifiers/dropped-guard.js +144 -0
  59. package/dist/verifiers/foreign-contract-drift.js +114 -0
  60. package/dist/verifiers/foreign-copy-paste-drift.js +83 -0
  61. package/dist/verifiers/foreign-dropped-guard.js +78 -0
  62. package/dist/verifiers/foreign-phantom-api.js +36 -0
  63. package/dist/verifiers/foreign-phantom-config.js +40 -0
  64. package/dist/verifiers/foreign-phantom-dep.js +82 -0
  65. package/dist/verifiers/foreign-reinvented.js +65 -0
  66. package/dist/verifiers/foreign-scope-creep.js +42 -0
  67. package/dist/verifiers/foreign-swallowed-error.js +36 -0
  68. package/dist/verifiers/foreign-tests.js +143 -0
  69. package/dist/verifiers/foreign-tokens.js +94 -0
  70. package/dist/verifiers/foreign.js +16 -0
  71. package/dist/verifiers/index.js +38 -0
  72. package/dist/verifiers/lying-comment.js +90 -0
  73. package/dist/verifiers/phantom-api.js +88 -0
  74. package/dist/verifiers/phantom-config.js +93 -0
  75. package/dist/verifiers/phantom-dep.js +110 -0
  76. package/dist/verifiers/reinvented.js +74 -0
  77. package/dist/verifiers/scope-creep.js +77 -0
  78. package/dist/verifiers/swallowed-error.js +110 -0
  79. package/dist/verifiers/vacuous-test.js +138 -0
  80. package/docs/architecture.md +191 -0
  81. package/docs/assets/cli-preview.svg +68 -0
  82. package/docs/assets/powershot-logo.png +0 -0
  83. package/docs/ci.md +151 -0
  84. package/examples/github-actions/action.yml +23 -0
  85. package/examples/github-actions/cli.yml +43 -0
  86. package/examples/gitlab/.gitlab-ci.yml +21 -0
  87. package/package.json +65 -0
@@ -0,0 +1,191 @@
1
+ # Architecture
2
+
3
+ PowerShot is a single-package review engine with a small CLI adapter. The package is
4
+ split by runtime responsibility, not by hypothetical deployment boundaries: no module
5
+ below is independently versioned or consumed.
6
+
7
+ ## System shape
8
+
9
+ ```mermaid
10
+ flowchart LR
11
+ subgraph adapters["Delivery adapters"]
12
+ CLI["CLI commands"]
13
+ CI["CI workflows"]
14
+ end
15
+
16
+ subgraph engine["Review engine"]
17
+ SNAP["Target snapshot"]
18
+ GROUND["Ground<br/>parsers · types · symbols"]
19
+ PLAN["Selection plan<br/>per-file capabilities"]
20
+ VERIFY["Deterministic verifiers"]
21
+ BUNDLE["Review bundles"]
22
+ JUDGE["Optional judges"]
23
+ MANIFEST["Run manifest"]
24
+ end
25
+
26
+ subgraph outputs["Output adapters"]
27
+ TERM["Terminal"]
28
+ MD["Markdown"]
29
+ SARIF["SARIF"]
30
+ JSON["JSON · manifest"]
31
+ CQ["GitLab Code Quality"]
32
+ end
33
+
34
+ CLI --> SNAP
35
+ CI --> CLI
36
+ SNAP --> GROUND --> PLAN
37
+ PLAN --> VERIFY --> MANIFEST
38
+ PLAN -. when enabled .-> BUNDLE --> JUDGE --> MANIFEST
39
+ MANIFEST --> TERM
40
+ MANIFEST --> MD
41
+ MANIFEST --> SARIF
42
+ MANIFEST --> JSON
43
+ MANIFEST --> CQ
44
+
45
+ classDef adapter fill:#172033,stroke:#57a6ff,color:#f0f6fc,stroke-width:2px
46
+ classDef core fill:#241b20,stroke:#ff675c,color:#f0f6fc,stroke-width:2px
47
+ classDef output fill:#17251f,stroke:#4ac58b,color:#f0f6fc,stroke-width:2px
48
+ class CLI,CI adapter
49
+ class SNAP,GROUND,PLAN,VERIFY,BUNDLE,JUDGE,MANIFEST core
50
+ class TERM,MD,SARIF,JSON,CQ output
51
+ ```
52
+
53
+ The dependency direction is inward. Delivery and report adapters depend on the review
54
+ engine. The engine does not depend on a workflow provider or terminal layout.
55
+
56
+ ## Module boundaries
57
+
58
+ | Module | Owns | Does not own |
59
+ |---|---|---|
60
+ | `src/cli/` | Argument parsing, command dispatch, report publication, exit mapping | Review algorithms |
61
+ | `src/review.ts` | One review run and its stage orchestration | CLI parsing or presentation |
62
+ | `src/ground.ts` | TypeScript project, parse trees, manifests, symbol index | Check selection |
63
+ | `src/plan.ts` | File selection and per-file capability accounting | Finding generation |
64
+ | `src/manifest.ts` | Completion state and the authoritative run record | Rendering |
65
+ | `src/verifiers/` | Deterministic check implementations | Model calls |
66
+ | `src/judges/` | Prompt data, bounded model loop, tool adapter | Git target selection |
67
+ | `src/lang/` | Language-pack data and optional language oracles | Cross-run policy |
68
+ | `src/report/` | Pure output adapters | Re-running or reinterpreting a review |
69
+ | `src/bench.ts` | Historical and labelled evaluation | Production command dispatch |
70
+ | `src/session.ts`, `src/cache.ts` | Reuse of completed judge work | Completion decisions |
71
+
72
+ `src/cli.ts` contains only the executable boundary. It delegates to `src/cli/app.ts`,
73
+ which routes a command to a deeper module. This keeps a new output format or maintenance
74
+ command from increasing the dependency fan-out of the executable.
75
+
76
+ ### Import discipline
77
+
78
+ Use `./` while the dependency is reachable without leaving the current directory. Use
79
+ `#app/*.js` instead of `../` traversal. The alias is a native Node.js package import
80
+ mapped to `dist`, so TypeScript, the built CLI, and the installed npm package share one
81
+ resolution rule. Keep `node:*` for the standard library and package names for external
82
+ dependencies. The self-test checks every TypeScript source recursively and rejects
83
+ static, side-effect, dynamic, and CommonJS parent imports.
84
+
85
+ ## Runtime sequence
86
+
87
+ ```mermaid
88
+ sequenceDiagram
89
+ autonumber
90
+ actor User as Developer / CI
91
+ participant CLI as CLI adapter
92
+ participant Git as Target snapshot
93
+ participant Ground as Ground
94
+ participant Plan as Selection plan
95
+ participant Verify as Verifiers
96
+ participant Judge as Judges
97
+ participant Manifest as Run manifest
98
+ participant Report as Report adapters
99
+
100
+ User->>CLI: psh review
101
+ CLI->>Git: resolve range and target tree
102
+ Git->>Ground: changed files + base content
103
+ Ground->>Plan: parsers, types, references, manifests
104
+ Plan->>Verify: eligible file/check pairs
105
+ Verify-->>Manifest: findings + coverage
106
+ opt model judges enabled
107
+ Plan->>Judge: bounded related-file bundles
108
+ Judge-->>Manifest: judged findings + usage
109
+ end
110
+ Manifest->>Manifest: compute complete / partial / failed
111
+ Manifest->>Report: one result, many formats
112
+ Report-->>User: terminal, Markdown, SARIF, JSON
113
+ ```
114
+
115
+ ## Load-bearing invariants
116
+
117
+ ### One target tree
118
+
119
+ A branch or commit review reads source from the target revision, not from whatever is
120
+ currently present in the working directory. Grounding, verification, bundling, and
121
+ positioning all receive the same tree.
122
+
123
+ ### Capabilities belong to files
124
+
125
+ A run can contain a typed TypeScript file beside a Python file or a TypeScript file
126
+ excluded from `tsconfig`. Capabilities therefore live on each selected file. A checker
127
+ available somewhere in the run is not evidence that it inspected every file.
128
+
129
+ ### The manifest owns completion
130
+
131
+ Findings alone cannot distinguish a clean review from an interrupted or unsupported
132
+ one. `RunManifest` accounts for selected files, executed checks, judge units, failures,
133
+ limits, and skips. Renderers and the CLI consume that state instead of deriving their
134
+ own verdict.
135
+
136
+ ```mermaid
137
+ stateDiagram-v2
138
+ [*] --> Selected
139
+ Selected --> Complete: every file and unit accounted for
140
+ Selected --> Partial: capability, budget, or cancellation gap
141
+ Selected --> Failed: required stage or file failed
142
+ Complete --> Exit0: no findings
143
+ Complete --> Exit1: findings
144
+ Partial --> Exit3
145
+ Failed --> Exit3
146
+ ```
147
+
148
+ ### One run, many reports
149
+
150
+ `--report` fans one review result into multiple adapters. CI should never execute the
151
+ review once for SARIF and again for Markdown: optional judges can answer differently,
152
+ and duplicated runs waste both time and tokens.
153
+
154
+ ## Extension paths
155
+
156
+ ### Add a deterministic verifier
157
+
158
+ 1. Implement the `Verifier` contract in `src/verifiers/`.
159
+ 2. Declare its domain and required capabilities.
160
+ 3. Export one unique id from `src/verifiers/index.ts`.
161
+ 4. Add positive and negative cases to the self-check suite.
162
+ 5. Document the check in the README only after the oracle is exercised by tests.
163
+
164
+ ### Add a language pack
165
+
166
+ Add grammar data and conventions in `src/lang/packs.ts`, then add a dedicated fixture
167
+ to `src/langtest.ts`. Language packs run in separate processes so all grammars remain
168
+ covered without sharing one unbounded WASM heap.
169
+
170
+ ### Add a report format
171
+
172
+ Implement a pure function in `src/report/`, register it in `src/cli/reports.ts`, and
173
+ test its consumer contract. A renderer receives findings and the manifest; it does not
174
+ call the review engine.
175
+
176
+ ### Add a CLI command
177
+
178
+ Place command behavior under `src/cli/` and add one dispatch line to `app.ts`. If the
179
+ command needs review results, use the existing review command interface rather than
180
+ importing individual verifiers into the executable.
181
+
182
+ ## Verification strategy
183
+
184
+ - `npm run build` checks module contracts with strict TypeScript.
185
+ - `npm test` runs core self-checks and every enabled language pack.
186
+ - `npm run smoke` packs, installs, and exercises the public binary in a clean project.
187
+ - `node dist/cli.js review --verify-only` reviews the working diff through PowerShot's
188
+ own deterministic pipeline.
189
+
190
+ See [CI integration](ci.md) for the delivery contract and
191
+ [CONTRIBUTING.md](../CONTRIBUTING.md) for the change workflow.
@@ -0,0 +1,68 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="680" viewBox="0 0 1200 680" role="img" aria-labelledby="title desc">
2
+ <title id="title">PowerShot CLI reporting a swallowed error</title>
3
+ <desc id="desc">A deterministic PowerShot scan reports one proven high-severity finding in an empty catch block.</desc>
4
+ <defs>
5
+ <linearGradient id="canvas" x1="0" y1="0" x2="1" y2="1">
6
+ <stop offset="0" stop-color="#080b12"/>
7
+ <stop offset="1" stop-color="#111827"/>
8
+ </linearGradient>
9
+ <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
10
+ <feDropShadow dx="0" dy="18" stdDeviation="24" flood-color="#000000" flood-opacity="0.42"/>
11
+ </filter>
12
+ <style>
13
+ .mono { font-family: "SFMono-Regular", "Cascadia Code", "Liberation Mono", Consolas, monospace; }
14
+ .muted { fill: #778196; }
15
+ .body { fill: #d9e0ea; }
16
+ .bright { fill: #f6f8fb; }
17
+ .red { fill: #ff5a62; }
18
+ .gold { fill: #ffc857; }
19
+ .steel { fill: #7dd3fc; }
20
+ .green { fill: #61d095; }
21
+ </style>
22
+ </defs>
23
+
24
+ <rect width="1200" height="680" rx="28" fill="url(#canvas)"/>
25
+ <rect x="44" y="38" width="1112" height="604" rx="18" fill="#0c111b" stroke="#242d3c" filter="url(#shadow)"/>
26
+ <path d="M44 94H1156" stroke="#242d3c"/>
27
+ <circle cx="78" cy="66" r="7" fill="#ff5f57"/>
28
+ <circle cx="102" cy="66" r="7" fill="#febc2e"/>
29
+ <circle cx="126" cy="66" r="7" fill="#28c840"/>
30
+ <text x="600" y="72" text-anchor="middle" class="mono muted" font-size="16">powershot — deterministic review</text>
31
+
32
+ <g class="mono" font-size="18">
33
+ <text x="78" y="132" class="green">$</text>
34
+ <text x="102" y="132" class="bright">psh scan src/example.ts --verify-only</text>
35
+
36
+ <text x="78" y="178" class="muted">◇ ground</text>
37
+ <text x="200" y="178" class="body">1 file · 1 symbol</text>
38
+ <text x="78" y="208" class="muted">◇ verify</text>
39
+ <text x="200" y="208" class="body">1 check × 1 file · 0 tokens</text>
40
+
41
+ <text x="78" y="256" class="bright" font-weight="700">PowerShot</text>
42
+ <text x="196" y="256" class="muted">· scan src/example.ts</text>
43
+ <path d="M78 278H1122" stroke="#2b3444"/>
44
+
45
+ <text x="78" y="318" class="steel">src/example.ts</text>
46
+ <text x="78" y="360" class="gold" font-weight="700">▣ HIGH</text>
47
+ <text x="174" y="360" class="body">swallowed-error ·</text>
48
+ <text x="388" y="360" class="red">proven</text>
49
+
50
+ <text x="106" y="397" class="bright">Empty catch block — the failure is discarded and the caller is</text>
51
+ <text x="106" y="425" class="bright">told it succeeded</text>
52
+
53
+ <text x="106" y="470" class="muted">3 │</text>
54
+ <text x="164" y="470" class="body">return JSON.parse(input)</text>
55
+ <text x="78" y="500" class="red">❯</text>
56
+ <text x="106" y="500" class="muted">4 │</text>
57
+ <text x="164" y="500" class="bright">} catch {</text>
58
+ <text x="252" y="527" class="red">^</text>
59
+ <text x="106" y="550" class="muted">5 │</text>
60
+ <text x="164" y="550" class="body">}</text>
61
+ <text x="164" y="583" class="muted">╰ AST: catch body contains no statements</text>
62
+
63
+ <path d="M78 605H1122" stroke="#2b3444"/>
64
+ <text x="78" y="630" class="bright">1 finding</text>
65
+ <text x="204" y="630" class="gold">1 high</text>
66
+ <text x="290" y="630" class="muted">· 1 verified · 0 judged</text>
67
+ </g>
68
+ </svg>
Binary file
package/docs/ci.md ADDED
@@ -0,0 +1,151 @@
1
+ # CI integration
2
+
3
+ PowerShot has two CI surfaces:
4
+
5
+ - the composite GitHub Action for the shortest GitHub setup;
6
+ - the `psh` CLI for GitHub, GitLab, and any runner that can execute Node.js 24.
7
+
8
+ Use the composite action for GitHub-native reporting or install the versioned npm
9
+ package when the CLI needs to fit into another CI system.
10
+
11
+ ## Choose a policy first
12
+
13
+ There are two independent decisions:
14
+
15
+ 1. Must the review complete? Usually yes. Exit `2` or `3` should always fail a gate.
16
+ 2. Do findings block the change? Set this per repository. Exit `1` is a complete
17
+ verdict with findings, not an engine failure.
18
+
19
+ | Exit | Meaning | Recommended CI handling |
20
+ |---:|---|---|
21
+ | `0` | Complete, no findings | Pass |
22
+ | `1` | Complete, findings reported | Pass or fail according to repository policy |
23
+ | `2` | Invalid command or Git input | Fail |
24
+ | `3` | Partial or failed review | Fail |
25
+ | `130` | Interrupted | Fail or retry |
26
+
27
+ ## GitHub Action
28
+
29
+ The action runs one review, adds a job summary, uploads SARIF, and can maintain one
30
+ pull-request comment.
31
+
32
+ ```yaml
33
+ name: PowerShot
34
+
35
+ on:
36
+ pull_request:
37
+
38
+ permissions:
39
+ contents: read
40
+ pull-requests: write
41
+ security-events: write
42
+
43
+ jobs:
44
+ review:
45
+ runs-on: ubuntu-latest
46
+ steps:
47
+ - uses: actions/checkout@v7
48
+ with:
49
+ fetch-depth: 0
50
+
51
+ - uses: xcrft/powershot@v1
52
+ with:
53
+ verify-only: 'true'
54
+ comment: 'true'
55
+ fail-on-findings: 'true'
56
+ ```
57
+
58
+ The major tag follows compatible `1.x` releases. Pin a full commit SHA in a protected
59
+ required workflow when immutable dependencies are required. The copy-paste version
60
+ lives at [`examples/github-actions/action.yml`](../examples/github-actions/action.yml).
61
+
62
+ ### Action inputs
63
+
64
+ | Input | Default | Purpose |
65
+ |---|---|---|
66
+ | `verify-only` | `true` | Run deterministic checks without a model |
67
+ | `anthropic-api-key` | empty | Enable configured model judges |
68
+ | `min-severity` | `low` | Filter findings below a severity |
69
+ | `checks` | empty | Select comma-separated check ids |
70
+ | `comment` | `true` | Maintain a pull-request comment |
71
+ | `fail-on-findings` | `false` | Turn a complete finding verdict into a failed job |
72
+ | `approve` | `false` | Approve only a complete, clean review |
73
+
74
+ The outputs are `findings` and `complete`. `complete` is the important one when a
75
+ later job decides whether to publish or deploy.
76
+
77
+ ## Direct CLI on GitHub Actions
78
+
79
+ Use the CLI when the workflow needs custom artifact handling or when PowerShot is one
80
+ step inside a larger quality job. The complete example is
81
+ [`examples/github-actions/cli.yml`](../examples/github-actions/cli.yml).
82
+
83
+ The core pattern is:
84
+
85
+ ```bash
86
+ npm install --global --ignore-scripts @0xcraft/powershot@1.0.0
87
+
88
+ STATUS=0
89
+ psh review --verify-only \
90
+ --from "$BASE" --to HEAD \
91
+ --report sarif=powershot.sarif \
92
+ --report markdown=powershot.md \
93
+ --format compact || STATUS=$?
94
+
95
+ case "$STATUS" in
96
+ 0) exit 0 ;;
97
+ 1) exit 1 ;; # change to 0 when findings are advisory
98
+ *) exit "$STATUS" ;;
99
+ esac
100
+ ```
101
+
102
+ Do not pipe the review directly into another command without preserving its exit code.
103
+ Do not run once per report: repeated `--report` flags create all artifacts from the
104
+ same verdict.
105
+
106
+ ## GitLab Code Quality
107
+
108
+ The CLI's `codequality` format is accepted by GitLab's Code Quality report. Use a full
109
+ clone or fetch both merge-request SHAs, then preserve the CLI status separately from
110
+ the redirected report:
111
+
112
+ ```bash
113
+ STATUS=0
114
+ node "$POWERSHOT/dist/cli.js" review --verify-only \
115
+ --from "$CI_MERGE_REQUEST_DIFF_BASE_SHA" \
116
+ --to "$CI_COMMIT_SHA" \
117
+ --format codequality > gl-code-quality-report.json || STATUS=$?
118
+
119
+ test "$STATUS" -le 1 || exit "$STATUS"
120
+ test "$STATUS" -eq 0
121
+ ```
122
+
123
+ See [`examples/gitlab/.gitlab-ci.yml`](../examples/gitlab/.gitlab-ci.yml) for the job
124
+ and artifact declaration.
125
+
126
+ ## CI checklist
127
+
128
+ - Use Node.js 24 or newer.
129
+ - Fetch enough Git history for both endpoints of the review range.
130
+ - Use immutable base and head SHAs where the CI provider exposes them.
131
+ - Run `--verify-only` as the fast required check; add model judges only where their
132
+ cost and latency are intentional.
133
+ - Treat exit `2`, `3`, and `130` as infrastructure or completeness failures.
134
+ - Generate every report from one invocation.
135
+ - Publish the Markdown report for humans and SARIF or Code Quality for annotations.
136
+ - Pin the PowerShot source version in protected workflows.
137
+ - Keep `powershot.config.json` in review so policy changes are visible.
138
+
139
+ ## Local parity
140
+
141
+ Run the same deterministic gate before pushing:
142
+
143
+ ```bash
144
+ node dist/cli.js review --verify-only --from main --to HEAD
145
+ ```
146
+
147
+ For an uncommitted workspace, omit the range:
148
+
149
+ ```bash
150
+ node dist/cli.js review --verify-only
151
+ ```
@@ -0,0 +1,23 @@
1
+ name: PowerShot
2
+
3
+ on:
4
+ pull_request:
5
+
6
+ permissions:
7
+ contents: read
8
+ pull-requests: write
9
+ security-events: write
10
+
11
+ jobs:
12
+ review:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v7
16
+ with:
17
+ fetch-depth: 0
18
+
19
+ - uses: xcrft/powershot@v1
20
+ with:
21
+ verify-only: 'true'
22
+ comment: 'true'
23
+ fail-on-findings: 'true'
@@ -0,0 +1,43 @@
1
+ name: PowerShot CLI
2
+
3
+ on:
4
+ pull_request:
5
+
6
+ permissions:
7
+ contents: read
8
+
9
+ jobs:
10
+ review:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v7
14
+ with:
15
+ fetch-depth: 0
16
+
17
+ - uses: actions/setup-node@v7
18
+ with:
19
+ node-version: '24'
20
+
21
+ - name: Install PowerShot
22
+ run: npm install --global --ignore-scripts @0xcraft/powershot@1.0.0
23
+
24
+ - name: Review pull request
25
+ env:
26
+ BASE: origin/${{ github.base_ref }}
27
+ run: |
28
+ STATUS=0
29
+ psh review --verify-only \
30
+ --from "$BASE" --to HEAD \
31
+ --report markdown=powershot.md \
32
+ --report sarif=powershot.sarif \
33
+ --format compact || STATUS=$?
34
+ if [ -f powershot.md ]; then
35
+ cat powershot.md >> "$GITHUB_STEP_SUMMARY"
36
+ else
37
+ echo "PowerShot produced no Markdown report. Exit: $STATUS." >> "$GITHUB_STEP_SUMMARY"
38
+ fi
39
+ case "$STATUS" in
40
+ 0) exit 0 ;;
41
+ 1) exit 1 ;;
42
+ *) exit "$STATUS" ;;
43
+ esac
@@ -0,0 +1,21 @@
1
+ powershot:
2
+ image: node:24
3
+ rules:
4
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
5
+ variables:
6
+ GIT_DEPTH: "0"
7
+ before_script:
8
+ - npm install --global --ignore-scripts @0xcraft/powershot@1.0.0
9
+ script:
10
+ - |
11
+ STATUS=0
12
+ psh review --verify-only \
13
+ --from "$CI_MERGE_REQUEST_DIFF_BASE_SHA" \
14
+ --to "$CI_COMMIT_SHA" \
15
+ --format codequality > gl-code-quality-report.json || STATUS=$?
16
+ test "$STATUS" -le 1 || exit "$STATUS"
17
+ test "$STATUS" -eq 0
18
+ artifacts:
19
+ when: always
20
+ reports:
21
+ codequality: gl-code-quality-report.json
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@0xcraft/powershot",
3
+ "version": "1.0.0",
4
+ "description": "Oracle-first code review for machine-written code, with deterministic verification and CI-ready reports.",
5
+ "license": "Apache-2.0",
6
+ "author": "aglumova <alina.glumova@gmail.com>",
7
+ "keywords": [
8
+ "ai",
9
+ "ci",
10
+ "cli",
11
+ "code-review",
12
+ "developer-tools",
13
+ "github-actions",
14
+ "static-analysis",
15
+ "typescript"
16
+ ],
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/xcrft/powershot.git"
20
+ },
21
+ "homepage": "https://github.com/xcrft/powershot#readme",
22
+ "bugs": {
23
+ "url": "https://github.com/xcrft/powershot/issues"
24
+ },
25
+ "type": "module",
26
+ "imports": {
27
+ "#app/*.js": "./dist/*.js"
28
+ },
29
+ "bin": {
30
+ "powershot": "dist/cli.js",
31
+ "psh": "dist/cli.js"
32
+ },
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "engines": {
37
+ "node": ">=24"
38
+ },
39
+ "files": [
40
+ "dist/**/*.js",
41
+ "docs/**/*.md",
42
+ "docs/assets/*",
43
+ "examples/**/*",
44
+ "README.md",
45
+ "LICENSE"
46
+ ],
47
+ "scripts": {
48
+ "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
49
+ "build": "tsc",
50
+ "dev": "tsc --watch",
51
+ "test": "npm run build && node dist/selftest.js && node dist/langtest.js",
52
+ "psh": "npm run build && node dist/cli.js",
53
+ "prepack": "npm run clean && npm run build && npm test",
54
+ "smoke": "node dist/package-smoke.js"
55
+ },
56
+ "dependencies": {
57
+ "ts-morph": "^23.0.0",
58
+ "web-tree-sitter": "0.22.6",
59
+ "tree-sitter-wasms": "0.1.13"
60
+ },
61
+ "devDependencies": {
62
+ "@types/node": "^20.14.0",
63
+ "typescript": "^5.5.0"
64
+ }
65
+ }