pi-opa-net 0.1.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/CHANGELOG.md +37 -0
- package/LICENSE +21 -0
- package/README.md +203 -0
- package/bin/pi-opa-net.js +65 -0
- package/package.json +71 -0
- package/policy/safety.rego +374 -0
- package/schemas/decision-output.v1.json +298 -0
- package/skills/pi-opa-net/SKILL.md +63 -0
- package/src/cli/run.ts +76 -0
- package/src/config/Config.ts +78 -0
- package/src/engine/OpaCliEngine.ts +166 -0
- package/src/engine/index.ts +2 -0
- package/src/engine/types.ts +35 -0
- package/src/index.ts +32 -0
- package/src/output/DecisionBuilder.ts +163 -0
- package/src/output/OutputFormatter.ts +43 -0
- package/src/output/index.ts +9 -0
- package/src/parser/CommandParser.ts +32 -0
- package/src/parser/RegexFallbackParser.ts +31 -0
- package/src/parser/ShellQuoteParser.ts +72 -0
- package/src/parser/index.ts +4 -0
- package/src/parser/types.ts +27 -0
- package/src/rules/RuleRegistry.ts +65 -0
- package/src/rules/catalog.ts +221 -0
- package/src/rules/index.ts +3 -0
- package/src/util/digest.ts +18 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] - 2026-07-01
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **decision-output.v1 schema** — JSON Schema draft 2020-12, strict (`additionalProperties: false`). Symmetric allow + deny output with rule provenance, fail-mode observability, and parse-confidence surfacing. 4 canonical examples, all validated by a hard test gate.
|
|
15
|
+
- **OPA decision engine** (`OpaCliEngine`) — subprocess `opa eval` with temp-file input, fail-open/fail-closed branching, SHA-256 rulebook digest for drift detection.
|
|
16
|
+
- **Hybrid command parser** — `ShellQuoteParser` (AST primary) + `RegexFallbackParser` (fallback), coordinated via `CommandParserCoordinator`. Program-aware subcommand classification (git/docker/gh/glab subcommand-style; rm/bd/gcloud/bq args-only).
|
|
17
|
+
- **Rule registry + 37-rule catalog** mirroring `policy/safety.rego` message-for-message. A bidirectional parity test enforces zero drift between rego and the TS catalog.
|
|
18
|
+
- **CLI** (`pi-opa-net eval`) — claude-code mode (suppress allow stdout) and `--json` mode (always emit schema). Exit codes `0 = allow`, `2 = deny` (Claude Code hook protocol compatible). Reads from args or stdin.
|
|
19
|
+
- **Rego policy** (`policy/safety.rego`) — covers git, docker, docker-compose carve-outs, rm, gh, glab, gcloud, bq, bd families. Native bare-default handling (`git stash` ≡ push).
|
|
20
|
+
- **Env-driven config** — `PI_OPA_FAIL_MODE`, `PI_OPA_TIMEOUT_MS`, `PI_OPA_BINARY` (mise-aware discovery), `PI_OPA_HOSTNAME`, `PI_OPA_SESSION_ID`.
|
|
21
|
+
- **Decision-design docs** — `docs/locked-decisions.yaml` (LD1–LD5), `docs/open-threads.yaml` (OT1–OT5, all resolved with rationale).
|
|
22
|
+
- **CI** — GitHub Actions workflow (typecheck + lint + test + coverage on ubuntu/macos).
|
|
23
|
+
- **Skill doc** — `skills/pi-opa-net/SKILL.md` for pi agent discovery.
|
|
24
|
+
|
|
25
|
+
### Resolved design threads
|
|
26
|
+
|
|
27
|
+
- **OT1 (parser)** — hybrid: AST primary, regex fallback; `parse_confidence` surfaces path per-decision.
|
|
28
|
+
- **OT2 (fail-mode)** — fail-open default (matches pi-safety-net fork), configurable to fail-closed.
|
|
29
|
+
- **OT3 (bare git stash)** — handled natively in rego (`subcommand == "stash" && count(args) == 0`).
|
|
30
|
+
- **OT4 (fork disposition)** — pi-safety-net kept as Path A (non-pi agents); pi-opa-net is Path B (OPA-backed).
|
|
31
|
+
- **OT5 (pi extension wiring)** — deferred to a separate `pi-opa-net-ext` repo; this package exposes the engine + library + CLI.
|
|
32
|
+
|
|
33
|
+
### Tests
|
|
34
|
+
|
|
35
|
+
- 106 tests across 10 files (unit + e2e + schema gate).
|
|
36
|
+
- Line coverage 98.89%, function coverage 88.98%.
|
|
37
|
+
- E2E runs the live CLI against real OPA 1.18.1 — 20 distinct deny rules fire (≥40% of the 37-rule catalog) plus 5 allow carve-outs and fail-open/fail-closed paths.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 buihongduc132
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# pi-opa-net
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/pi-opa-net)
|
|
4
|
+
[](https://github.com/buihongduc132/pi-opa-net/actions/workflows/ci.yml)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
|
|
7
|
+
> OPA-backed bash command guard for the [Pi](https://pi.dev) ecosystem. Structured `--json` output (decision-output.v1 schema), fail-open default, exit-code compatible with the Claude Code hook protocol.
|
|
8
|
+
|
|
9
|
+
An **agent-agnostic** engine + CLI that evaluates shell commands against an [OPA](https://www.openpolicyagent.org/)/Rego policy and emits a strict, auditable decision record. Designed as the decision backend for pi extensions, Claude Code hooks, scripts, and any agent that needs a uniform bash-guard contract.
|
|
10
|
+
|
|
11
|
+
## Why
|
|
12
|
+
|
|
13
|
+
Three limitations of today's asymmetric, agent-specific guard output that this fixes:
|
|
14
|
+
|
|
15
|
+
| # | Limitation | Fix |
|
|
16
|
+
|---|------------|-----|
|
|
17
|
+
| 1 | **Asymmetric** — allow is silent, deny emits a string | Both allow AND deny emit the full schema |
|
|
18
|
+
| 2 | **No provenance** — only a human message | `reasons[].rule_id` traces decision → rule → source line |
|
|
19
|
+
| 3 | **Agent-specific** — tied to one hook protocol | Agent-agnostic wrapper; adapters become thin views |
|
|
20
|
+
|
|
21
|
+
## Status
|
|
22
|
+
|
|
23
|
+
- **Stable:** v0.1.0 — schema v1.0, 37-rule catalog, full TDD coverage
|
|
24
|
+
- **Engine:** OPA 1.x (lazy-loaded on every dev box)
|
|
25
|
+
- **Scope:** bash command guarding only (see [`docs/locked-decisions.yaml`](docs/locked-decisions.yaml) LD3)
|
|
26
|
+
- **Pi extension:** the thin tool_call adapter lives in a separate future repo (`pi-opa-net-ext`, per OT5) — this package is the engine + library
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
### Prerequisites
|
|
31
|
+
|
|
32
|
+
OPA 1.x on `PATH` (recommended via [mise](https://mise.jdx.dev)):
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
mise install opa@latest
|
|
36
|
+
mise use -g opa@latest
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Install
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# as a library (pi extension / script consumer)
|
|
43
|
+
npm install pi-opa-net
|
|
44
|
+
# or
|
|
45
|
+
bun add pi-opa-net
|
|
46
|
+
|
|
47
|
+
# run the CLI directly via bun
|
|
48
|
+
bunx pi-opa-net eval "git stash pop"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Usage
|
|
52
|
+
|
|
53
|
+
### CLI
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# claude-code mode (default): suppress stdout on allow, JSON on deny
|
|
57
|
+
pi-opa-net eval "git stash pop" # exit 2 + JSON on stdout
|
|
58
|
+
pi-opa-net eval "git stash list" # exit 0, empty stdout
|
|
59
|
+
|
|
60
|
+
# --json: always emit the full decision-output.v1 schema
|
|
61
|
+
pi-opa-net eval "git stash pop" --json
|
|
62
|
+
|
|
63
|
+
# stdin
|
|
64
|
+
echo "docker stop foo" | pi-opa-net eval
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Exit codes:** `0 = allow`, `2 = deny` (Claude Code hook protocol compatible).
|
|
68
|
+
|
|
69
|
+
### Programmatic API
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { configFromEnv, CommandParserCoordinator, OpaCliEngine, DecisionBuilder, OutputFormatter, RULES, RuleRegistry } from 'pi-opa-net';
|
|
73
|
+
|
|
74
|
+
const config = configFromEnv('/path/to/safety.rego');
|
|
75
|
+
const parser = new CommandParserCoordinator();
|
|
76
|
+
const engine = new OpaCliEngine(config);
|
|
77
|
+
const builder = new DecisionBuilder({
|
|
78
|
+
config,
|
|
79
|
+
registry: new RuleRegistry(RULES),
|
|
80
|
+
digest: engine.rulebookDigest(),
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const parsed = parser.parse('git stash pop');
|
|
84
|
+
const engineDecision = await engine.evaluate(parsed);
|
|
85
|
+
const output = builder.build(parsed, engineDecision);
|
|
86
|
+
|
|
87
|
+
console.log(output.decision); // 'deny'
|
|
88
|
+
console.log(output.reasons[0].rule_id); // 'block-git-stash-mutations'
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Output schema
|
|
92
|
+
|
|
93
|
+
See [`schemas/decision-output.v1.json`](schemas/decision-output.v1.json) — JSON Schema draft 2020-12, strict (`additionalProperties: false` throughout). Every emitted record is validated against it before leaving the process.
|
|
94
|
+
|
|
95
|
+
```jsonc
|
|
96
|
+
{
|
|
97
|
+
"schema_version": "1.0",
|
|
98
|
+
"decision": "deny", // allow | deny
|
|
99
|
+
"action": "block", // allow | block | prompt_user(v2) | log_only(v2)
|
|
100
|
+
"source": "opa", // opa | fail-open | fail-closed | cached
|
|
101
|
+
"reasons": [ // every fired deny rule → one entry
|
|
102
|
+
{ "rule_id": "block-git-stash-mutations",
|
|
103
|
+
"message": "Do not mutate stashes in shared work...",
|
|
104
|
+
"family": "git", "severity": "block" }
|
|
105
|
+
],
|
|
106
|
+
"input": { "raw": "git stash pop", "program": "git",
|
|
107
|
+
"subcommand": "stash", "args": ["pop"],
|
|
108
|
+
"parse_confidence": "full" }, // full | partial | regex-only | failed
|
|
109
|
+
"summary": "BLOCKED: git stash pop (rule: block-git-stash-mutations)",
|
|
110
|
+
"suggestions": ["git stash list", "git stash show"],
|
|
111
|
+
"metadata": { "engine": "opa", "opa_version": "1.18.1",
|
|
112
|
+
"rulebook_digest": "dee3746bf7b5", "policy_path": "...",
|
|
113
|
+
"hostname": "box", "session_id": "" },
|
|
114
|
+
"evaluated_at": "2026-07-01T14:23:45.123Z",
|
|
115
|
+
"decision_id": "7f3a9c2e-1b4d-4e8f-9a2c-5d6e7f8a9b01",
|
|
116
|
+
"duration_ms": 4.2
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Architecture
|
|
121
|
+
|
|
122
|
+
Two halves (per the design findings):
|
|
123
|
+
|
|
124
|
+
| Half | Responsibility | Module |
|
|
125
|
+
|------|----------------|--------|
|
|
126
|
+
| **Parse** | raw `"git stash list"` → `{program, subcommand, args, parse_confidence}` | `src/parser/` |
|
|
127
|
+
| **Decide** | structured input → allow/deny + reasons | `policy/safety.rego` + `src/engine/` |
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
src/
|
|
131
|
+
├── parser/ CommandParserCoordinator (hybrid: ShellQuote AST primary, regex fallback)
|
|
132
|
+
├── engine/ OpaCliEngine (subprocess `opa eval` + fail-mode)
|
|
133
|
+
├── rules/ RuleRegistry + catalog (message → rule_id + family provenance)
|
|
134
|
+
├── output/ DecisionBuilder (schema assembly) + OutputFormatter (stdout/exit-code)
|
|
135
|
+
├── config/ EngineConfig (fail-mode, OPA binary discovery)
|
|
136
|
+
├── cli/ run.ts (wires the pipeline)
|
|
137
|
+
└── util/ sha256Prefix (rulebook drift detection)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Design principles
|
|
141
|
+
|
|
142
|
+
- **OOP** — `DecisionEngine` and `CommandParser` interfaces; fakes injectable for tests.
|
|
143
|
+
- **DRY** — `RuleRegistry` is the single source of truth for rule provenance; the catalog mirrors `policy/safety.rego` message-for-message (a parity test fails on drift).
|
|
144
|
+
- **Observable** — the `source` field makes fail-mode (open/closed) auditable per-decision; `parse_confidence` surfaces parser fidelity.
|
|
145
|
+
|
|
146
|
+
## Fail-mode
|
|
147
|
+
|
|
148
|
+
When OPA is unreachable (cold-start, binary missing, timeout):
|
|
149
|
+
|
|
150
|
+
| Mode | Behavior | `source` field |
|
|
151
|
+
|------|----------|----------------|
|
|
152
|
+
| `open` (default) | allow the command through | `fail-open` |
|
|
153
|
+
| `closed` | block the command | `fail-closed` |
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
PI_OPA_FAIL_MODE=closed pi-opa-net eval "git stash pop"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The default `open` matches the [`pi-safety-net`](https://www.npmjs.com/package/pi-safety-net) fork's "never brick the shell" guarantee.
|
|
160
|
+
|
|
161
|
+
## Configuration (env)
|
|
162
|
+
|
|
163
|
+
| Var | Default | Purpose |
|
|
164
|
+
|-----|---------|---------|
|
|
165
|
+
| `PI_OPA_BINARY` | auto (PATH → mise) | OPA binary path |
|
|
166
|
+
| `PI_OPA_FAIL_MODE` | `open` | fail-mode |
|
|
167
|
+
| `PI_OPA_TIMEOUT_MS` | `250` | OPA eval timeout |
|
|
168
|
+
| `PI_OPA_HOSTNAME` | `os.hostname()` | metadata.hostname |
|
|
169
|
+
| `PI_OPA_SESSION_ID` | `""` | metadata.session_id |
|
|
170
|
+
|
|
171
|
+
## Develop
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
bun install
|
|
175
|
+
bun test # all tests (106)
|
|
176
|
+
bun test --coverage # coverage (line > 98%)
|
|
177
|
+
bun run typecheck # tsc --noEmit
|
|
178
|
+
bun run lint # biome
|
|
179
|
+
bun run smoke # one-shot CLI check
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
E2E tests run the live CLI against real OPA + the real policy, covering ≥40% of the 37-rule catalog.
|
|
183
|
+
|
|
184
|
+
## Decisions & open threads
|
|
185
|
+
|
|
186
|
+
- [`docs/locked-decisions.yaml`](docs/locked-decisions.yaml) — LD1–LD5 (immutable inputs).
|
|
187
|
+
- [`docs/open-threads.yaml`](docs/open-threads.yaml) — OT1–OT5 resolved at implementation time.
|
|
188
|
+
|
|
189
|
+
## Project health
|
|
190
|
+
|
|
191
|
+
- **Security policy:** [`SECURITY.md`](SECURITY.md)
|
|
192
|
+
- **Contributing:** [`CONTRIBUTING.md`](CONTRIBUTING.md)
|
|
193
|
+
- **Support:** [`SUPPORT.md`](SUPPORT.md)
|
|
194
|
+
- **Changelog:** [`CHANGELOG.md`](CHANGELOG.md)
|
|
195
|
+
|
|
196
|
+
## Related
|
|
197
|
+
|
|
198
|
+
- [`pi-safety-net`](https://www.npmjs.com/package/pi-safety-net) — the fail-open fork of cc-safety-net (Path A: non-pi agents). pi-opa-net is Path B (OPA-backed, structured output).
|
|
199
|
+
- [`cc-safety-net`](https://www.npmjs.com/package/cc-safety-net) — upstream Claude Code safety net.
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
MIT © [buihongduc132](https://github.com/buihongduc132)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* pi-opa-net — OPA-backed bash command guard with structured --json output.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* pi-opa-net eval "<command>" # claude-code mode (default)
|
|
7
|
+
* pi-opa-net eval "<command>" --json # full schema on stdout always
|
|
8
|
+
* echo "<command>" | pi-opa-net eval # read from stdin
|
|
9
|
+
*
|
|
10
|
+
* Exit codes: 0=allow, 2=deny (Claude Code hook protocol compatible).
|
|
11
|
+
*/
|
|
12
|
+
import { defaultPolicyPath, runCli } from '../src/cli/run.ts';
|
|
13
|
+
|
|
14
|
+
function parseArgs(argv) {
|
|
15
|
+
const args = argv.slice(2); // drop node + script
|
|
16
|
+
let mode = 'claude-code';
|
|
17
|
+
let command;
|
|
18
|
+
let policyPath = defaultPolicyPath();
|
|
19
|
+
let sawAction = false;
|
|
20
|
+
|
|
21
|
+
for (let i = 0; i < args.length; i++) {
|
|
22
|
+
const a = args[i];
|
|
23
|
+
if (a === '--json') {
|
|
24
|
+
mode = 'json';
|
|
25
|
+
} else if (a === '--policy' || a === '-p') {
|
|
26
|
+
policyPath = args[++i];
|
|
27
|
+
} else if (a === '--help' || a === '-h') {
|
|
28
|
+
printHelp();
|
|
29
|
+
process.exit(0);
|
|
30
|
+
} else if (!a.startsWith('-')) {
|
|
31
|
+
// First positional is the action verb ('eval'); subsequent ones form the command.
|
|
32
|
+
if (!sawAction && a === 'eval') {
|
|
33
|
+
sawAction = true;
|
|
34
|
+
} else {
|
|
35
|
+
command = command === undefined ? a : `${command} ${a}`;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return { command, mode, policyPath };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function printHelp() {
|
|
43
|
+
console.error(`pi-opa-net — OPA-backed bash command guard
|
|
44
|
+
|
|
45
|
+
Usage:
|
|
46
|
+
pi-opa-net eval "<command>" [--json] [--policy <path>]
|
|
47
|
+
echo "<command>" | pi-opa-net eval
|
|
48
|
+
|
|
49
|
+
Modes:
|
|
50
|
+
(default) claude-code: suppress stdout on allow, JSON on deny
|
|
51
|
+
--json always emit full decision-output.v1 schema on stdout
|
|
52
|
+
|
|
53
|
+
Exit codes: 0=allow, 2=deny`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function main() {
|
|
57
|
+
const { command, mode, policyPath } = parseArgs(process.argv);
|
|
58
|
+
const { stdout, exitCode } = await runCli({ command, mode, policyPath });
|
|
59
|
+
if (stdout) {
|
|
60
|
+
console.log(stdout);
|
|
61
|
+
}
|
|
62
|
+
process.exit(exitCode);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
void main();
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pi-opa-net",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "OPA-backed bash command guard for the pi ecosystem — structured decision-output.v1 JSON, fail-open default, Claude Code hook protocol compatible. Agent-agnostic engine + CLI.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"types": "src/index.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"pi-opa-net": "bin/pi-opa-net.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"src",
|
|
13
|
+
"bin",
|
|
14
|
+
"schemas",
|
|
15
|
+
"policy",
|
|
16
|
+
"skills",
|
|
17
|
+
"README.md",
|
|
18
|
+
"CHANGELOG.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"lint": "biome check --write src tests bin",
|
|
24
|
+
"lint:ci": "biome ci src tests bin",
|
|
25
|
+
"test": "bun test",
|
|
26
|
+
"test:coverage": "bun test --coverage",
|
|
27
|
+
"check": "bun run typecheck && bun run lint:ci && bun test --coverage",
|
|
28
|
+
"smoke": "bun run bin/pi-opa-net.js eval \"git stash pop\" --json",
|
|
29
|
+
"prepublishOnly": "bun run check"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"pi-package",
|
|
33
|
+
"pi",
|
|
34
|
+
"pi-coding-agent",
|
|
35
|
+
"pi-library",
|
|
36
|
+
"opa",
|
|
37
|
+
"rego",
|
|
38
|
+
"bash-guard",
|
|
39
|
+
"safety-net",
|
|
40
|
+
"claude-code",
|
|
41
|
+
"policy",
|
|
42
|
+
"decision-output"
|
|
43
|
+
],
|
|
44
|
+
"pi": {
|
|
45
|
+
"skills": ["./skills"]
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"ajv": "^8.17.1",
|
|
49
|
+
"ajv-formats": "^3.0.1",
|
|
50
|
+
"shell-quote": "^1.8.2"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@biomejs/biome": "^1.9.4",
|
|
54
|
+
"@types/bun": "latest",
|
|
55
|
+
"@types/shell-quote": "^1.7.5",
|
|
56
|
+
"typescript": "^5.6.0"
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"bun": ">=1.1.0"
|
|
60
|
+
},
|
|
61
|
+
"license": "MIT",
|
|
62
|
+
"author": "buihongduc132",
|
|
63
|
+
"homepage": "https://github.com/buihongduc132/pi-opa-net#readme",
|
|
64
|
+
"repository": {
|
|
65
|
+
"type": "git",
|
|
66
|
+
"url": "git+https://github.com/buihongduc132/pi-opa-net.git"
|
|
67
|
+
},
|
|
68
|
+
"bugs": {
|
|
69
|
+
"url": "https://github.com/buihongduc132/pi-opa-net/issues"
|
|
70
|
+
}
|
|
71
|
+
}
|