@ps-neko/nekowork 0.2.0-alpha.3 → 0.2.0-alpha.5
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
|
@@ -10,23 +10,24 @@ pushes, or deploys on its own.
|
|
|
10
10
|
|
|
11
11
|
## Status
|
|
12
12
|
|
|
13
|
-
**Published alpha** (`@ps-neko/nekowork`, alpha dist-tag). This package is the
|
|
14
|
-
published slim verification gate.
|
|
13
|
+
**Published alpha** (`@ps-neko/nekowork`, `@alpha` dist-tag). This package is the
|
|
14
|
+
published slim verification gate. Always install with the **`@alpha`** tag —
|
|
15
|
+
`latest` is pinned to an old `0.2.0-alpha.0` and is not the alpha line:
|
|
15
16
|
|
|
16
17
|
```bash
|
|
17
|
-
npm i -g @ps-neko/nekowork
|
|
18
|
+
npm i -g @ps-neko/nekowork@alpha
|
|
18
19
|
```
|
|
19
20
|
|
|
20
21
|
The fuller legacy and power-user surface lives in the internal
|
|
21
22
|
`@ps-neko/nekowork-harness` package (not separately published). See
|
|
22
|
-
[HANDOFF-PACKAGE-SPLIT.md](
|
|
23
|
+
[HANDOFF-PACKAGE-SPLIT.md](https://github.com/Ps-Neko/NEKOWORK/blob/main/packages/nekowork/HANDOFF-PACKAGE-SPLIT.md) for the split history.
|
|
23
24
|
|
|
24
25
|
## Quickstart
|
|
25
26
|
|
|
26
27
|
```bash
|
|
27
28
|
# right after your AI tool changes some files:
|
|
28
|
-
npx -y @ps-neko/nekowork check # 30-sec environment check
|
|
29
|
-
npx -y @ps-neko/nekowork verify-pr # scan the diff → get a verdict
|
|
29
|
+
npx -y @ps-neko/nekowork@alpha check # 30-sec environment check
|
|
30
|
+
npx -y @ps-neko/nekowork@alpha verify-pr # scan the diff → get a verdict
|
|
30
31
|
```
|
|
31
32
|
|
|
32
33
|
`verify-pr` reads the diff, writes a plain-English `REPORT.md`, and tells you
|
|
@@ -39,7 +40,7 @@ whether the change is safe to merge.
|
|
|
39
40
|
| `check` | Probe environment readiness (Node version, git repo, etc.) |
|
|
40
41
|
| `verify-pr` | Scan working-tree diff. Produce REPORT.md + .nekowork/decision.json |
|
|
41
42
|
| `report` | Render an existing decision.json to a human-readable REPORT.md |
|
|
42
|
-
| `apply` | Session-based compatibility apply. Requires a completed work cycle (SHIP_READY marker + cleared Human Gate). NOT driven by verify-pr's decision.json. See [ADVANCED.md](
|
|
43
|
+
| `apply` | Session-based compatibility apply. Requires a completed work cycle (SHIP_READY marker + cleared Human Gate). NOT driven by verify-pr's decision.json. See [ADVANCED.md](https://github.com/Ps-Neko/NEKOWORK/blob/main/packages/nekowork-cli/docs/ADVANCED.md). |
|
|
43
44
|
|
|
44
45
|
Anything else (`ask`, `plan`, `team`, `work`, `ship`, `build`, `auto`,
|
|
45
46
|
`pr-prep`, `review`, ...) belongs to `@ps-neko/nekowork-harness` (legacy and
|
|
@@ -63,10 +64,10 @@ step — it is not triggered by `decision.json`.
|
|
|
63
64
|
|
|
64
65
|
## Docs
|
|
65
66
|
|
|
66
|
-
- [Quickstart](
|
|
67
|
-
- [How verification works](
|
|
68
|
-
- [Benchmark](
|
|
69
|
-
- [Integration](
|
|
67
|
+
- [Quickstart](https://github.com/Ps-Neko/NEKOWORK/blob/main/packages/nekowork-cli/docs/QUICKSTART.md)
|
|
68
|
+
- [How verification works](https://github.com/Ps-Neko/NEKOWORK/blob/main/packages/nekowork-cli/docs/SCOPE-1.0.md)
|
|
69
|
+
- [Benchmark](https://github.com/Ps-Neko/NEKOWORK/blob/main/packages/nekowork-cli/docs/BENCHMARK.md) — 85/86 (99%) recall, 0/47 FP, 30 real OSS positives (secret-fallback)
|
|
70
|
+
- [Integration](https://github.com/Ps-Neko/NEKOWORK/blob/main/packages/nekowork-cli/docs/INTEGRATION.md)
|
|
70
71
|
|
|
71
72
|
## License
|
|
72
73
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ps-neko/nekowork",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.5",
|
|
4
4
|
"description": "Local verification gate for AI-written code diffs. Deterministic rules decide the verdict, never the LLM. No auto-commit, push, or deploy — you decide at the Human Gate.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-code-review",
|
|
@@ -276,10 +276,15 @@ function synthesizeUntrackedDiff(cwd) {
|
|
|
276
276
|
* @returns {string} concatenated unified-diff chunks
|
|
277
277
|
*/
|
|
278
278
|
const SYNTH_FILE_SIZE_LIMIT = 2 * 1024 * 1024; // 2 MB per file
|
|
279
|
+
const SYNTH_TOTAL_SIZE_LIMIT = 64 * 1024 * 1024; // 64 MB aggregate (guards full-scan OOM)
|
|
279
280
|
|
|
280
281
|
function synthesizeFilesAsDiff(cwd, relPaths) {
|
|
281
282
|
let chunks = '';
|
|
283
|
+
let truncated = false;
|
|
282
284
|
for (const rel of relPaths) {
|
|
285
|
+
// Aggregate cap: stop accumulating once the synthesized diff is very large,
|
|
286
|
+
// so a huge full-scan / untracked tree cannot exhaust memory.
|
|
287
|
+
if (chunks.length >= SYNTH_TOTAL_SIZE_LIMIT) { truncated = true; break; }
|
|
283
288
|
const full = path.join(cwd, rel);
|
|
284
289
|
let content;
|
|
285
290
|
try {
|
|
@@ -300,6 +305,11 @@ function synthesizeFilesAsDiff(cwd, relPaths) {
|
|
|
300
305
|
chunks += `@@ -0,0 +1,${lines.length} @@\n`;
|
|
301
306
|
for (const line of lines) chunks += `+${line}\n`;
|
|
302
307
|
}
|
|
308
|
+
if (truncated) {
|
|
309
|
+
process.stderr.write(
|
|
310
|
+
`warning: diff synthesis truncated at ${Math.round(SYNTH_TOTAL_SIZE_LIMIT / (1024 * 1024))}MB; some files were not scanned. Narrow the scope (avoid --full-scan on very large trees).\n`,
|
|
311
|
+
);
|
|
312
|
+
}
|
|
303
313
|
return chunks;
|
|
304
314
|
}
|
|
305
315
|
|
|
@@ -28,8 +28,9 @@ const PATTERNS = [
|
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
30
|
id: 'rm-rf-variable',
|
|
31
|
-
// rm
|
|
32
|
-
|
|
31
|
+
// rm with recursive+force flags (combined `-rf`/`-fr` or separated `-r -f`/`-f -r`)
|
|
32
|
+
// and variable expansion in the path.
|
|
33
|
+
re: /\brm\s+(?=-[a-zA-Z]*(?:rf|fr)|-[a-zA-Z]*r[a-zA-Z]*\s+-[a-zA-Z]*f|-[a-zA-Z]*f[a-zA-Z]*\s+-[a-zA-Z]*r)-[a-zA-Z][^\n]*\$\{?\w/g,
|
|
33
34
|
severity: 'critical',
|
|
34
35
|
title: 'rm -rf with variable path',
|
|
35
36
|
description: 'Removing with a variable path is dangerous — if the variable is empty, the parent directory is wiped.',
|
|
@@ -39,7 +40,7 @@ const PATTERNS = [
|
|
|
39
40
|
id: 'rm-rf-system',
|
|
40
41
|
// rm -rf on a root-like path (not allowed: /tmp, /var/{log,cache,tmp},
|
|
41
42
|
// /home/<u>, /root/<x>, /node_modules — common safe targets)
|
|
42
|
-
re: /\brm\s
|
|
43
|
+
re: /\brm\s+(?=-[a-zA-Z]*(?:rf|fr)|-[a-zA-Z]*r[a-zA-Z]*\s+-[a-zA-Z]*f|-[a-zA-Z]*f[a-zA-Z]*\s+-[a-zA-Z]*r)-[a-zA-Z][^\n]*?\s+\/(?!tmp(?:\/|$|\s)|var\/(?:log|cache|tmp)\/|home\/\w|root\/\w|node_modules\/|opt\/render\/)\S*/g,
|
|
43
44
|
severity: 'critical',
|
|
44
45
|
title: 'rm -rf on system path',
|
|
45
46
|
description: 'Removing system paths is destructive and rarely intentional in a build/automation script.',
|
|
@@ -18,9 +18,10 @@ import { addedLines as collectAddedLines } from '../diff-parser.js';
|
|
|
18
18
|
const PATTERNS = [
|
|
19
19
|
{
|
|
20
20
|
id: 'env-or-literal',
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
// dot form process.env.X || "lit" and bracket form process.env['X'] || "lit"
|
|
22
|
+
re: /process\.env(?:\.(\w+)|\[(["'`])(\w+)\2\])\s*\|\|\s*(["'`])([^"'`\n]+)\4/g,
|
|
23
|
+
pickEnv: m => m[1] || m[3],
|
|
24
|
+
pickLiteral: m => m[5],
|
|
24
25
|
},
|
|
25
26
|
{
|
|
26
27
|
id: 'nullish-fallback',
|
|
@@ -42,9 +43,12 @@ const PATTERNS = [
|
|
|
42
43
|
},
|
|
43
44
|
{
|
|
44
45
|
id: 'config-or-literal',
|
|
45
|
-
|
|
46
|
+
// dot form obj.secretProp || "lit" and bracket form obj['SECRET_KEY'] || "lit".
|
|
47
|
+
// The bracket key is gated to secret-keyword names so generic config defaults
|
|
48
|
+
// (e.g. config['timeout'] || 5000) do not match.
|
|
49
|
+
re: /\b([A-Za-z_]\w*\.(?:apiKey|secret|secretKey|token|password|key|jwt|auth)|[A-Za-z_]\w*\[(["'`])[\w-]*(?:KEY|TOKEN|SECRET|PASSWORD|PASS|AUTH|JWT|API|CREDENTIAL|apiKey|secretKey)[\w-]*\2\])\s*\|\|\s*(["'`])([^"'`\n]+)\3/g,
|
|
46
50
|
pickEnv: m => m[1],
|
|
47
|
-
pickLiteral: m => m[
|
|
51
|
+
pickLiteral: m => m[4],
|
|
48
52
|
},
|
|
49
53
|
{
|
|
50
54
|
id: 'config-fallback-property',
|