@nerdvana/parism 0.1.6 → 0.3.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.en.md +46 -8
- package/README.md +56 -9
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +19 -3
- package/dist/config/loader.js.map +1 -1
- package/dist/engine/guard.d.ts.map +1 -1
- package/dist/engine/guard.js +4 -2
- package/dist/engine/guard.js.map +1 -1
- package/dist/parsers/compact.d.ts +6 -0
- package/dist/parsers/compact.d.ts.map +1 -0
- package/dist/parsers/compact.js +42 -0
- package/dist/parsers/compact.js.map +1 -0
- package/dist/parsers/devops/docker.d.ts +28 -0
- package/dist/parsers/devops/docker.d.ts.map +1 -0
- package/dist/parsers/devops/docker.js +63 -0
- package/dist/parsers/devops/docker.js.map +1 -0
- package/dist/parsers/devops/gh.d.ts +18 -0
- package/dist/parsers/devops/gh.d.ts.map +1 -0
- package/dist/parsers/devops/gh.js +62 -0
- package/dist/parsers/devops/gh.js.map +1 -0
- package/dist/parsers/devops/helm.d.ts +27 -0
- package/dist/parsers/devops/helm.d.ts.map +1 -0
- package/dist/parsers/devops/helm.js +41 -0
- package/dist/parsers/devops/helm.js.map +1 -0
- package/dist/parsers/devops/index.d.ts +6 -0
- package/dist/parsers/devops/index.d.ts.map +1 -0
- package/dist/parsers/devops/index.js +6 -0
- package/dist/parsers/devops/index.js.map +1 -0
- package/dist/parsers/devops/kubectl.d.ts +27 -0
- package/dist/parsers/devops/kubectl.d.ts.map +1 -0
- package/dist/parsers/devops/kubectl.js +68 -0
- package/dist/parsers/devops/kubectl.js.map +1 -0
- package/dist/parsers/devops/terraform.d.ts +22 -0
- package/dist/parsers/devops/terraform.d.ts.map +1 -0
- package/dist/parsers/devops/terraform.js +30 -0
- package/dist/parsers/devops/terraform.js.map +1 -0
- package/dist/parsers/fs/ls.js +1 -1
- package/dist/parsers/fs/ls.js.map +1 -1
- package/dist/parsers/fs/stat.d.ts.map +1 -1
- package/dist/parsers/fs/stat.js +33 -0
- package/dist/parsers/fs/stat.js.map +1 -1
- package/dist/parsers/git/diff.d.ts +23 -2
- package/dist/parsers/git/diff.d.ts.map +1 -1
- package/dist/parsers/git/diff.js +57 -2
- package/dist/parsers/git/diff.js.map +1 -1
- package/dist/parsers/index.d.ts.map +1 -1
- package/dist/parsers/index.js +16 -1
- package/dist/parsers/index.js.map +1 -1
- package/dist/parsers/json-passthrough.d.ts +6 -0
- package/dist/parsers/json-passthrough.d.ts.map +1 -0
- package/dist/parsers/json-passthrough.js +19 -0
- package/dist/parsers/json-passthrough.js.map +1 -0
- package/dist/parsers/network/netstat.d.ts.map +1 -1
- package/dist/parsers/network/netstat.js +7 -2
- package/dist/parsers/network/netstat.js.map +1 -1
- package/dist/parsers/packages/cargo.d.ts +23 -0
- package/dist/parsers/packages/cargo.d.ts.map +1 -0
- package/dist/parsers/packages/cargo.js +41 -0
- package/dist/parsers/packages/cargo.js.map +1 -0
- package/dist/parsers/packages/index.d.ts +3 -0
- package/dist/parsers/packages/index.d.ts.map +1 -0
- package/dist/parsers/packages/index.js +3 -0
- package/dist/parsers/packages/index.js.map +1 -0
- package/dist/parsers/packages/npm.d.ts +23 -0
- package/dist/parsers/packages/npm.d.ts.map +1 -0
- package/dist/parsers/packages/npm.js +38 -0
- package/dist/parsers/packages/npm.js.map +1 -0
- package/dist/parsers/registry.d.ts +8 -0
- package/dist/parsers/registry.d.ts.map +1 -1
- package/dist/parsers/registry.js.map +1 -1
- package/dist/parsers/system/apt.d.ts +24 -0
- package/dist/parsers/system/apt.d.ts.map +1 -0
- package/dist/parsers/system/apt.js +38 -0
- package/dist/parsers/system/apt.js.map +1 -0
- package/dist/parsers/system/brew.d.ts +22 -0
- package/dist/parsers/system/brew.d.ts.map +1 -0
- package/dist/parsers/system/brew.js +31 -0
- package/dist/parsers/system/brew.js.map +1 -0
- package/dist/parsers/system/index.d.ts +4 -0
- package/dist/parsers/system/index.d.ts.map +1 -1
- package/dist/parsers/system/index.js +4 -0
- package/dist/parsers/system/index.js.map +1 -1
- package/dist/parsers/system/journalctl.d.ts +27 -0
- package/dist/parsers/system/journalctl.d.ts.map +1 -0
- package/dist/parsers/system/journalctl.js +57 -0
- package/dist/parsers/system/journalctl.js.map +1 -0
- package/dist/parsers/system/systemctl.d.ts +27 -0
- package/dist/parsers/system/systemctl.d.ts.map +1 -0
- package/dist/parsers/system/systemctl.js +50 -0
- package/dist/parsers/system/systemctl.js.map +1 -0
- package/dist/parsers/windows/tasklist.d.ts.map +1 -1
- package/dist/parsers/windows/tasklist.js +0 -2
- package/dist/parsers/windows/tasklist.js.map +1 -1
- package/dist/server.d.ts +3 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +66 -42
- package/dist/server.js.map +1 -1
- package/package.json +14 -2
- package/prism.config.json +5 -2
package/README.en.md
CHANGED
|
@@ -99,11 +99,11 @@ There are four layers of defense.
|
|
|
99
99
|
|
|
100
100
|
**Command Whitelist**: Commands not in `allowed_commands` are never executed. No process is created. Rejected silently.
|
|
101
101
|
|
|
102
|
-
**Path Restriction**: When `allowed_paths` is set,
|
|
102
|
+
**Path Restriction**: When `allowed_paths` is set, Guard validates both `cwd` and path-like args (starting with `/`, `./`, `../`). Anything outside allowed paths is blocked.
|
|
103
103
|
|
|
104
|
-
**Injection Pattern Blocking**: If `;`, `$(`, `` ` ``, `&&`, `||`, or
|
|
104
|
+
**Injection Pattern Blocking**: If `;`, `$(`, `` ` ``, `&&`, `||`, `|`, `>`, `>>`, or `<` appear in any argument, the command is not executed.
|
|
105
105
|
|
|
106
|
-
**Per-Command Argument Restrictions
|
|
106
|
+
**Per-Command Argument Restrictions**: Specific flags can be blocked per command. `node -e`, `node --eval`, and `node --input-type` are blocked by default. `npx --yes` is also blocked.
|
|
107
107
|
|
|
108
108
|
A blocked command returns this:
|
|
109
109
|
|
|
@@ -121,7 +121,7 @@ The agent receives the block reason in the same envelope structure as any other
|
|
|
121
121
|
|
|
122
122
|
---
|
|
123
123
|
|
|
124
|
-
## Supported Commands —
|
|
124
|
+
## Supported Commands — 34 Built-in Parsers
|
|
125
125
|
|
|
126
126
|
| Category | Command | Parsed Output |
|
|
127
127
|
|---|---|---|
|
|
@@ -146,6 +146,9 @@ The agent receives the block reason in the same envelope structure as any other
|
|
|
146
146
|
| Git | `git log --oneline` | `commits[]` — hash, message |
|
|
147
147
|
| Git | `git diff` | `files_changed[]` |
|
|
148
148
|
| Git | `git branch -vv` | `branches[]` — name, current, upstream, ahead/behind |
|
|
149
|
+
| DevOps | `kubectl get pods`, `kubectl get events` | `pods[]` / `events[]` — status, restarts, reasons, messages |
|
|
150
|
+
| DevOps | `docker ps`, `docker stats --no-stream` | `containers[]` / `stats[]` — image, status, CPU/MEM/IO |
|
|
151
|
+
| DevOps | `gh pr list` | `pull_requests[]` — number, title, state, author, labels |
|
|
149
152
|
| Env | `env` | `vars{}` — key-value map (secrets filtered) |
|
|
150
153
|
| Env | `pwd` | `path` |
|
|
151
154
|
| Env | `which` | `paths[]` |
|
|
@@ -210,7 +213,37 @@ Claude Code (Linux):
|
|
|
210
213
|
}
|
|
211
214
|
```
|
|
212
215
|
|
|
213
|
-
Once connected,
|
|
216
|
+
Once connected, two tools are exposed: `run` and `run_paged`.
|
|
217
|
+
|
|
218
|
+
`run` is the default command runner with structured parsing when available.
|
|
219
|
+
`run_paged` returns paginated stdout for large output and includes `page_info`.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Tools
|
|
224
|
+
|
|
225
|
+
### run
|
|
226
|
+
|
|
227
|
+
Default tool for most commands. Use when output is small or structured parsing is needed.
|
|
228
|
+
|
|
229
|
+
Parameters:
|
|
230
|
+
- `cmd` — command name (e.g. `ls`, `git`)
|
|
231
|
+
- `args` — argument array (default: `[]`)
|
|
232
|
+
- `cwd` — working directory (default: current directory)
|
|
233
|
+
|
|
234
|
+
### run_paged
|
|
235
|
+
|
|
236
|
+
Use for large stdout (`ps aux`, `find`, `grep -r`).
|
|
237
|
+
|
|
238
|
+
Parameters:
|
|
239
|
+
- `cmd`, `args`, `cwd` — same as `run`
|
|
240
|
+
- `page` — 0-indexed page number (default: `0`)
|
|
241
|
+
- `page_size` — lines per page (default: `default_page_size`, 100 by default)
|
|
242
|
+
|
|
243
|
+
Extra fields:
|
|
244
|
+
- `page_info.total_lines` — total line count
|
|
245
|
+
- `page_info.has_next` — whether next page exists
|
|
246
|
+
- `stdout.parsed` — always `null` (partial output cannot be safely parsed)
|
|
214
247
|
|
|
215
248
|
---
|
|
216
249
|
|
|
@@ -224,12 +257,15 @@ Place `prism.config.json` in the project root to control Guard behavior.
|
|
|
224
257
|
"allowed_commands": ["ls", "git", "find", "grep", "env", "ps"],
|
|
225
258
|
"allowed_paths": ["/home/user/projects"],
|
|
226
259
|
"timeout_ms": 10000,
|
|
227
|
-
"
|
|
260
|
+
"max_output_bytes": 102400,
|
|
261
|
+
"max_items": 500,
|
|
262
|
+
"default_page_size": 100,
|
|
263
|
+
"block_patterns": [";", "$(", "`", "&&", "||", ">", ">>", "<", "|"],
|
|
228
264
|
"command_arg_restrictions": {
|
|
229
|
-
"node": { "blocked_flags": ["-e", "--eval", "-r", "--require", "-p", "--print"] },
|
|
265
|
+
"node": { "blocked_flags": ["-e", "--eval", "-r", "--require", "-p", "--print", "--input-type"] },
|
|
230
266
|
"npx": { "blocked_flags": ["--yes", "-y"] }
|
|
231
267
|
},
|
|
232
|
-
"env_secret_patterns": ["TOKEN", "SECRET", "AUTHZ", "PASSWORD", "CREDENTIAL"]
|
|
268
|
+
"env_secret_patterns": ["TOKEN", "SECRET", "AUTHZ", "PASSWORD", "PASSWD", "CREDENTIAL"]
|
|
233
269
|
}
|
|
234
270
|
}
|
|
235
271
|
```
|
|
@@ -238,6 +274,8 @@ Place `prism.config.json` in the project root to control Guard behavior.
|
|
|
238
274
|
|
|
239
275
|
`env_secret_patterns` strips matching environment variables from child processes before execution. The `env` command will not expose them.
|
|
240
276
|
|
|
277
|
+
`command_arg_restrictions` is deep-merged with defaults. Overriding one command does not remove restrictions for others.
|
|
278
|
+
|
|
241
279
|
---
|
|
242
280
|
|
|
243
281
|
## What Parism Is Not
|
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Parism
|
|
2
2
|
|
|
3
3
|
> Refract the Shell. Every command, structured.
|
|
4
|
+
>
|
|
5
|
+
> AI 에이전트를 위한 안전하고 예측 가능한 OS 실행 게이트웨이.
|
|
4
6
|
|
|
5
7
|
<p align="right"><a href="README.md">한국어</a> | <a href="README.en.md">English</a></p>
|
|
6
8
|
|
|
@@ -34,6 +36,18 @@ Parism이 개입하는 것은 두 번째와 세 번째 사이다. 한 번 버려
|
|
|
34
36
|
|
|
35
37
|
---
|
|
36
38
|
|
|
39
|
+
## 솔직한 이야기 — 토큰은 더 든다
|
|
40
|
+
|
|
41
|
+
Parism을 만들 때 기대한 것은 토큰 절약이었다. 구조화된 데이터가 raw 텍스트보다 효율적일 것이라고.
|
|
42
|
+
|
|
43
|
+
17개 시나리오를 벤치마크한 결과는 그 기대를 정면으로 배반했다. JSON 출력은 raw 텍스트보다 평균 205% 더 무겁다. `ls -la` 200개 파일 기준으로 raw 5,807 토큰, Parism 15,531 토큰. 거의 세 배다. 키 이름이 매 항목마다 반복되기 때문이다. 인간의 눈에 테이블 헤더 한 줄이면 되는 정보를 N번 써야 한다.
|
|
44
|
+
|
|
45
|
+
하지만 같은 벤치마크가 다른 사실 하나를 드러냈다. 에이전트가 raw 텍스트를 직접 파싱할 때 오독률이 평균 4.18%, 공백이 섞인 파일명에서는 28.6%에 달했다. 열 번 중 세 번은 틀린다. 틀린 결과로 에이전트가 다음 작업을 수행하고, 그 작업이 또 틀리고, 결국 사람이 개입해서 되돌린다. 재시도 토큰, 디버깅 시간, 롤백 비용. 보이지 않는 곳에서 비용이 불어난다.
|
|
46
|
+
|
|
47
|
+
Parism의 경제성은 토큰 청구서 위에 있지 않다. 실수와 재작업이 사라지는 자리에 있다. 한 번 더 읽는 비용보다, 한 번 잘못 읽어서 치르는 비용이 더 크다.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
37
51
|
## Parism이 하는 일
|
|
38
52
|
|
|
39
53
|
프리즘은 빛을 파괴하지 않는다. 분해할 뿐이다.
|
|
@@ -62,7 +76,11 @@ Parism이 개입하는 것은 두 번째와 세 번째 사이다. 한 번 버려
|
|
|
62
76
|
|
|
63
77
|
### 파싱 오류가 없어진다
|
|
64
78
|
|
|
65
|
-
텍스트 파싱은 깨지기 쉽다. `ps aux`는 리눅스와 macOS에서 컬럼 순서가 다르다. `df -h`의 `1K-blocks` 헤더는 환경에 따라 다르게 나온다. 파일명에 공백이 있으면 `ls` 파싱은 거의 반드시 틀린다.
|
|
79
|
+
텍스트 파싱은 깨지기 쉽다. `ps aux`는 리눅스와 macOS에서 컬럼 순서가 다르다. `df -h`의 `1K-blocks` 헤더는 환경에 따라 다르게 나온다. 파일명에 공백이 있으면 `ls` 파싱은 거의 반드시 틀린다.
|
|
80
|
+
|
|
81
|
+
수치로 말하면: raw 텍스트를 에이전트가 직접 파싱할 때 평균 CFR(Critical Failure Rate)은 4.18%다. 공백이 포함된 파일명이 섞이면 28.6%까지 치솟는다. 1000회 호출 시 286회는 잘못된 파일 목록을 기반으로 에이전트가 다음 작업을 수행한다는 뜻이다. 잘못된 파일을 읽고, 존재하지 않는 경로에 쓰고, 엉뚱한 파일을 삭제한다.
|
|
82
|
+
|
|
83
|
+
Parism의 CFR은 0%다. 파서는 deterministic code이기 때문이다. 정규표현식 추론이 아니라 구조적 분해다. 에이전트는 구조화된 데이터만 받는다.
|
|
66
84
|
|
|
67
85
|
### 재시도가 줄어든다
|
|
68
86
|
|
|
@@ -99,11 +117,11 @@ Parism이 개입하는 것은 두 번째와 세 번째 사이다. 한 번 버려
|
|
|
99
117
|
|
|
100
118
|
**화이트리스트**: `allowed_commands`에 없는 명령어는 실행되지 않는다. 프로세스를 만들지도 않는다. 설명 없이 거절한다.
|
|
101
119
|
|
|
102
|
-
**경로 제한**: `allowed_paths`를
|
|
120
|
+
**경로 제한**: `allowed_paths`를 설정하면 `cwd`뿐 아니라 경로형 인자(`/`, `./`, `../` 시작)도 검사한다. 허용 경로 밖을 참조하면 차단된다.
|
|
103
121
|
|
|
104
|
-
**인젝션 패턴 차단**: `;`, `$(`, `` ` ``, `&&`, `||`,
|
|
122
|
+
**인젝션 패턴 차단**: `;`, `$(`, `` ` ``, `&&`, `||`, `|`, `>`, `>>`, `<`가 인자에 포함되면 실행하지 않는다.
|
|
105
123
|
|
|
106
|
-
**명령별 인자
|
|
124
|
+
**명령별 인자 제한**: 명령마다 차단할 플래그를 지정할 수 있다. `node -e`, `node --eval`, `node --input-type`은 기본 차단된다. `npx --yes`도 기본 차단된다.
|
|
107
125
|
|
|
108
126
|
차단된 명령은 이런 응답을 반환한다.
|
|
109
127
|
|
|
@@ -121,7 +139,7 @@ Parism이 개입하는 것은 두 번째와 세 번째 사이다. 한 번 버려
|
|
|
121
139
|
|
|
122
140
|
---
|
|
123
141
|
|
|
124
|
-
## 지원 명령어 —
|
|
142
|
+
## 지원 명령어 — 44종 내장 파서
|
|
125
143
|
|
|
126
144
|
| 카테고리 | 명령어 | 파싱 결과 |
|
|
127
145
|
|---|---|---|
|
|
@@ -146,12 +164,23 @@ Parism이 개입하는 것은 두 번째와 세 번째 사이다. 한 번 버려
|
|
|
146
164
|
| Git | `git log --oneline` | `commits[]` — hash, message |
|
|
147
165
|
| Git | `git diff` | `files_changed[]` |
|
|
148
166
|
| Git | `git branch -vv` | `branches[]` — 이름, current, upstream, ahead/behind |
|
|
167
|
+
| DevOps | `kubectl get pods`, `kubectl get events` | `pods[]`/`events[]` — 상태, 재시도, 이벤트 사유/메시지 |
|
|
168
|
+
| DevOps | `docker ps`, `docker stats --no-stream` | `containers[]`/`stats[]` — 이미지, 상태, CPU/MEM/IO |
|
|
169
|
+
| DevOps | `gh pr list` | `pull_requests[]` — 번호, 제목, 상태, 작성자, 라벨 |
|
|
170
|
+
| DevOps | `helm list` | `releases[]` — name, namespace, status, chart, app_version |
|
|
171
|
+
| DevOps | `terraform plan` | `summary` — to_add, to_change, to_destroy |
|
|
149
172
|
| 환경 | `env` | `vars{}` — 키-값 맵 |
|
|
150
173
|
| 환경 | `pwd` | `path` |
|
|
151
174
|
| 환경 | `which` | `paths[]` |
|
|
152
175
|
| 시스템 | `free` | `rows{}` — mem/swap별 total, used, free, available (bytes) |
|
|
153
176
|
| 시스템 | `uname` | `kernel`, `hostname`, `release`, `version`, `arch`, `os` |
|
|
154
177
|
| 시스템 | `id` | `uid`, `gid`, `username`, `groups[]` — id, name |
|
|
178
|
+
| 시스템 | `systemctl list-units` | `units[]` — name, load, active, sub, description (Linux) |
|
|
179
|
+
| 시스템 | `journalctl -o short-iso` | `entries[]` — timestamp, hostname, unit, pid, message (Linux) |
|
|
180
|
+
| 시스템 | `apt list --installed` | `packages[]` — name, version, arch, status |
|
|
181
|
+
| 시스템 | `brew list --versions` | `packages[]` — name, version |
|
|
182
|
+
| 패키지 | `npm list`, `pnpm list`, `yarn list` | `dependencies[]` — name, version, depth |
|
|
183
|
+
| 패키지 | `cargo tree` | `crates[]` — name, version, path |
|
|
155
184
|
| Windows | `dir` | `directory`, `entries[]` — 이름, 타입, 크기, 수정 시각, `free_bytes` |
|
|
156
185
|
| Windows | `tasklist` | `processes[]` — 이름, PID, 세션, 메모리. CSV 형식 지원 |
|
|
157
186
|
| Windows | `ipconfig` | `hostname`, `adapters[]` — IPv4/6, 서브넷, 게이트웨이, DNS, MAC |
|
|
@@ -159,6 +188,10 @@ Parism이 개입하는 것은 두 번째와 세 번째 사이다. 한 번 버려
|
|
|
159
188
|
|
|
160
189
|
파서가 없는 명령어는 `parsed: null`로 반환된다. `raw`는 그대로 있다.
|
|
161
190
|
|
|
191
|
+
### 네이티브 JSON 패스스루
|
|
192
|
+
|
|
193
|
+
파서가 없는 명령이라도 출력 자체가 JSON이면(예: `kubectl get pods -o json`, `docker inspect`) Parism이 이를 자동으로 감지하여 `parsed`에 넣는다. Guard 검사와 봉투 래핑은 동일하게 적용된다. 별도 설정은 필요 없다.
|
|
194
|
+
|
|
162
195
|
---
|
|
163
196
|
|
|
164
197
|
## 설치
|
|
@@ -246,6 +279,16 @@ Claude Code (Linux):
|
|
|
246
279
|
- `cmd` — 명령어 이름 (예: `ls`, `git`)
|
|
247
280
|
- `args` — 인자 배열 (기본값: `[]`)
|
|
248
281
|
- `cwd` — 작업 디렉토리 (기본값: 현재 디렉토리)
|
|
282
|
+
- `format` — 출력 형식 (`"json"` 기본값, `"compact"` 가능). compact는 리스트형 출력을 schema+rows 컬럼 기반으로 압축하여 토큰 비용을 절감한다.
|
|
283
|
+
|
|
284
|
+
compact 예시:
|
|
285
|
+
|
|
286
|
+
```json
|
|
287
|
+
{
|
|
288
|
+
"schema": ["name", "type", "size_bytes"],
|
|
289
|
+
"rows": [["src", "directory", 4096], ["main.ts", "file", 1200]]
|
|
290
|
+
}
|
|
291
|
+
```
|
|
249
292
|
|
|
250
293
|
### run_paged
|
|
251
294
|
|
|
@@ -282,13 +325,15 @@ Claude Code (Linux):
|
|
|
282
325
|
"allowed_commands": ["ls", "git", "find", "grep", "env", "ps"],
|
|
283
326
|
"allowed_paths": ["/home/user/projects"],
|
|
284
327
|
"timeout_ms": 10000,
|
|
285
|
-
"
|
|
328
|
+
"max_output_bytes": 102400,
|
|
329
|
+
"max_items": 500,
|
|
330
|
+
"default_page_size": 100,
|
|
331
|
+
"block_patterns": [";", "$(", "`", "&&", "||", ">", ">>", "<", "|"],
|
|
286
332
|
"command_arg_restrictions": {
|
|
287
|
-
"node": { "blocked_flags": ["-e", "--eval", "-r", "--require", "-p", "--print"] },
|
|
333
|
+
"node": { "blocked_flags": ["-e", "--eval", "-r", "--require", "-p", "--print", "--input-type"] },
|
|
288
334
|
"npx": { "blocked_flags": ["--yes", "-y"] }
|
|
289
335
|
},
|
|
290
|
-
"env_secret_patterns": ["TOKEN", "SECRET", "AUTHZ", "PASSWORD", "CREDENTIAL"]
|
|
291
|
-
"default_page_size": 100
|
|
336
|
+
"env_secret_patterns": ["TOKEN", "SECRET", "AUTHZ", "PASSWORD", "PASSWD", "CREDENTIAL"]
|
|
292
337
|
}
|
|
293
338
|
}
|
|
294
339
|
```
|
|
@@ -297,6 +342,8 @@ Claude Code (Linux):
|
|
|
297
342
|
|
|
298
343
|
`env_secret_patterns`에 일치하는 환경 변수는 실행 전 자식 프로세스에서 제거된다. `env` 명령 실행 시 해당 변수가 노출되지 않는다.
|
|
299
344
|
|
|
345
|
+
`command_arg_restrictions`는 기본값과 병합된다. 일부 명령만 override해도 나머지 기본 제한은 유지된다.
|
|
346
|
+
|
|
300
347
|
---
|
|
301
348
|
|
|
302
349
|
## Parism이 아닌 것
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,EAAU,MAAM,EAAE,CAAC;IACnC,aAAa,EAAa,MAAM,EAAE,CAAC;IACnC,UAAU,EAAgB,MAAM,CAAC;IACjC,gBAAgB,EAAU,MAAM,CAAC;IACjC,SAAS,EAAiB,MAAM,CAAC;IACjC,iBAAiB,EAAS,MAAM,CAAC;IACjC,cAAc,EAAY,MAAM,EAAE,CAAC;IACnC,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAChE,mBAAmB,EAAO,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAID,eAAO,MAAM,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,EAAU,MAAM,EAAE,CAAC;IACnC,aAAa,EAAa,MAAM,EAAE,CAAC;IACnC,UAAU,EAAgB,MAAM,CAAC;IACjC,gBAAgB,EAAU,MAAM,CAAC;IACjC,SAAS,EAAiB,MAAM,CAAC;IACjC,iBAAiB,EAAS,MAAM,CAAC;IACjC,cAAc,EAAY,MAAM,EAAE,CAAC;IACnC,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAChE,mBAAmB,EAAO,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAID,eAAO,MAAM,cAAc,EAAE,WAmC5B,CAAC;AAmBF;;;GAGG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAqBzE"}
|
package/dist/config/loader.js
CHANGED
|
@@ -3,14 +3,18 @@ export const DEFAULT_CONFIG = {
|
|
|
3
3
|
guard: {
|
|
4
4
|
allowed_commands: [
|
|
5
5
|
"ls", "find", "stat", "du", "df", "tree",
|
|
6
|
-
"ps",
|
|
6
|
+
"ps",
|
|
7
7
|
"ping", "curl", "netstat",
|
|
8
8
|
"grep", "wc", "head", "tail", "cat",
|
|
9
9
|
"git",
|
|
10
10
|
"env", "pwd", "which",
|
|
11
11
|
"echo", "date", "uname", "hostname",
|
|
12
|
+
"kubectl", "docker", "gh",
|
|
13
|
+
"systemctl", "journalctl",
|
|
14
|
+
"helm", "terraform", "apt", "brew",
|
|
15
|
+
"npm", "pnpm", "yarn", "cargo",
|
|
12
16
|
],
|
|
13
|
-
allowed_paths: [],
|
|
17
|
+
allowed_paths: [process.cwd()],
|
|
14
18
|
timeout_ms: 10000,
|
|
15
19
|
max_output_bytes: 102400, // 100 KB
|
|
16
20
|
max_items: 500,
|
|
@@ -19,6 +23,12 @@ export const DEFAULT_CONFIG = {
|
|
|
19
23
|
command_arg_restrictions: {
|
|
20
24
|
node: { blocked_flags: ["-e", "--eval", "-r", "--require", "-p", "--print", "--input-type"] },
|
|
21
25
|
npx: { blocked_flags: ["--yes", "-y"] },
|
|
26
|
+
curl: {
|
|
27
|
+
blocked_flags: [
|
|
28
|
+
"-d", "--data", "-F", "--upload-file", "-T",
|
|
29
|
+
"-K", "--config", "-o", "--output", "-O",
|
|
30
|
+
],
|
|
31
|
+
},
|
|
22
32
|
},
|
|
23
33
|
env_secret_patterns: [
|
|
24
34
|
"TOKEN", "SECRET", "AUTHZ", "PASSWORD", "PASSWD", "CREDENTIAL",
|
|
@@ -48,9 +58,15 @@ export async function loadConfig(configPath) {
|
|
|
48
58
|
try {
|
|
49
59
|
const raw = await readFile(configPath, "utf-8");
|
|
50
60
|
const json = JSON.parse(raw);
|
|
51
|
-
|
|
61
|
+
const config = {
|
|
52
62
|
guard: mergeGuardConfig(json.guard ?? {}),
|
|
53
63
|
};
|
|
64
|
+
if (config.guard.allowed_paths.length === 0) {
|
|
65
|
+
console.warn("[parism] WARNING: allowed_paths is empty. " +
|
|
66
|
+
"All filesystem paths are accessible. " +
|
|
67
|
+
"Add paths to guard.allowed_paths in prism.config.json, or set [] to disable restriction.");
|
|
68
|
+
}
|
|
69
|
+
return config;
|
|
54
70
|
}
|
|
55
71
|
catch {
|
|
56
72
|
return DEFAULT_CONFIG;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAwB5C,MAAM,CAAC,MAAM,cAAc,GAAgB;IACzC,KAAK,EAAE;QACL,gBAAgB,EAAE;YAChB,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM;YACxC,IAAI
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAwB5C,MAAM,CAAC,MAAM,cAAc,GAAgB;IACzC,KAAK,EAAE;QACL,gBAAgB,EAAE;YAChB,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM;YACxC,IAAI;YACJ,MAAM,EAAE,MAAM,EAAE,SAAS;YACzB,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK;YACnC,KAAK;YACL,KAAK,EAAE,KAAK,EAAE,OAAO;YACrB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU;YACnC,SAAS,EAAE,QAAQ,EAAE,IAAI;YACzB,WAAW,EAAE,YAAY;YACzB,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM;YAClC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;SAC/B;QACD,aAAa,EAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACjC,UAAU,EAAQ,KAAK;QACvB,gBAAgB,EAAG,MAAM,EAAI,SAAS;QACtC,SAAS,EAAU,GAAG;QACtB,iBAAiB,EAAE,GAAG;QACtB,cAAc,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;QACjE,wBAAwB,EAAE;YACxB,IAAI,EAAE,EAAE,aAAa,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,CAAC,EAAE;YAC7F,GAAG,EAAG,EAAE,aAAa,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE;YACxC,IAAI,EAAE;gBACJ,aAAa,EAAE;oBACb,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI;oBAC3C,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI;iBACzC;aACF;SACF;QACD,mBAAmB,EAAE;YACnB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY;SAC/D;KACF;CACF,CAAC;AAEF;;;GAGG;AACH,SAAS,gBAAgB,CAAC,SAAkC;IAC1D,MAAM,4BAA4B,GAAG;QACnC,GAAG,cAAc,CAAC,KAAK,CAAC,wBAAwB;QAChD,GAAG,CAAC,SAAS,CAAC,wBAAwB,IAAI,EAAE,CAAC;KAC9C,CAAC;IAEF,OAAO;QACL,GAAG,cAAc,CAAC,KAAK;QACvB,GAAG,SAAS;QACZ,wBAAwB,EAAE,4BAA4B;KACvD,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAkB;IACjD,IAAI,CAAC;QACH,MAAM,GAAG,GAAI,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAyB,CAAC;QAErD,MAAM,MAAM,GAAgB;YAC1B,KAAK,EAAE,gBAAgB,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;SAC1C,CAAC;QAEF,IAAI,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5C,OAAO,CAAC,IAAI,CACV,4CAA4C;gBAC5C,uCAAuC;gBACvC,0FAA0F,CAC3F,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,cAAc,CAAC;IACxB,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/engine/guard.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;GAEG;AACH,qBAAa,UAAW,SAAQ,KAAK;aAGjB,MAAM,EAClB,qBAAqB,GACrB,kBAAkB,GAClB,mBAAmB,GACnB,iBAAiB;gBALrB,OAAO,EAAE,MAAM,EACC,MAAM,EAClB,qBAAqB,GACrB,kBAAkB,GAClB,mBAAmB,GACnB,iBAAiB;CAKxB;AAgCD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAK,MAAM,EACd,IAAI,EAAI,MAAM,EAAE,EAChB,GAAG,EAAK,MAAM,EACd,MAAM,EAAE,WAAW,GAClB,IAAI,
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/engine/guard.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;GAEG;AACH,qBAAa,UAAW,SAAQ,KAAK;aAGjB,MAAM,EAClB,qBAAqB,GACrB,kBAAkB,GAClB,mBAAmB,GACnB,iBAAiB;gBALrB,OAAO,EAAE,MAAM,EACC,MAAM,EAClB,qBAAqB,GACrB,kBAAkB,GAClB,mBAAmB,GACnB,iBAAiB;CAKxB;AAgCD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAK,MAAM,EACd,IAAI,EAAI,MAAM,EAAE,EAChB,GAAG,EAAK,MAAM,EACd,MAAM,EAAE,WAAW,GAClB,IAAI,CAyDN"}
|
package/dist/engine/guard.js
CHANGED
|
@@ -68,13 +68,15 @@ export function checkGuard(cmd, args, cwd, config) {
|
|
|
68
68
|
if (guard.allowed_paths.length > 0) {
|
|
69
69
|
const resolvedCwd = path.resolve(cwd);
|
|
70
70
|
if (!isAllowedPath(resolvedCwd, guard.allowed_paths)) {
|
|
71
|
-
throw new GuardError(`Working directory '${cwd}' is outside allowed paths
|
|
71
|
+
throw new GuardError(`Working directory '${cwd}' is outside allowed paths. ` +
|
|
72
|
+
"Add guard.allowed_paths in prism.config.json or set [] to disable.", "path_not_allowed");
|
|
72
73
|
}
|
|
73
74
|
const pathLikeArgs = getPathLikeArgs(args);
|
|
74
75
|
for (const arg of pathLikeArgs) {
|
|
75
76
|
const resolvedArgPath = path.resolve(cwd, arg);
|
|
76
77
|
if (!isAllowedPath(resolvedArgPath, guard.allowed_paths)) {
|
|
77
|
-
throw new GuardError(`Path argument '${arg}' resolves outside allowed paths
|
|
78
|
+
throw new GuardError(`Path argument '${arg}' resolves outside allowed paths. ` +
|
|
79
|
+
"Add guard.allowed_paths in prism.config.json or set [] to disable.", "path_not_allowed");
|
|
78
80
|
}
|
|
79
81
|
}
|
|
80
82
|
}
|
package/dist/engine/guard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../../src/engine/guard.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../../src/engine/guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compact.d.ts","sourceRoot":"","sources":["../../src/parsers/compact.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAI,OAAO,EAAE,EAAE,CAAC;CACrB;AAYD,wBAAgB,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CA+BlD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 중첩 배열/객체를 compact 표 형식에 맞게 평탄화.
|
|
3
|
+
* 배열 → "a|b" 문자열, 객체 → JSON 문자열.
|
|
4
|
+
*/
|
|
5
|
+
function flattenCell(v) {
|
|
6
|
+
if (Array.isArray(v))
|
|
7
|
+
return v.map((x) => String(x)).join("|");
|
|
8
|
+
if (typeof v === "object" && v !== null)
|
|
9
|
+
return JSON.stringify(v);
|
|
10
|
+
return v;
|
|
11
|
+
}
|
|
12
|
+
export function toCompact(parsed) {
|
|
13
|
+
if (parsed == null)
|
|
14
|
+
return null;
|
|
15
|
+
if (typeof parsed !== "object" || Array.isArray(parsed))
|
|
16
|
+
return parsed;
|
|
17
|
+
const obj = parsed;
|
|
18
|
+
const result = {};
|
|
19
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
20
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
21
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
22
|
+
result[key] = { schema: [], rows: [] };
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
result[key] = value;
|
|
26
|
+
}
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (typeof value[0] !== "object" || value[0] === null) {
|
|
30
|
+
result[key] = value;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const schema = Object.keys(value[0]);
|
|
34
|
+
const rows = value.map((item) => {
|
|
35
|
+
const rec = item;
|
|
36
|
+
return schema.map((k) => flattenCell(rec[k]));
|
|
37
|
+
});
|
|
38
|
+
result[key] = { schema, rows };
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=compact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compact.js","sourceRoot":"","sources":["../../src/parsers/compact.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,SAAS,WAAW,CAAC,CAAU;IAC7B,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/D,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAe;IACvC,IAAI,MAAM,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAEvE,MAAM,GAAG,GAAM,MAAiC,CAAC;IACjD,MAAM,MAAM,GAA4B,EAAE,CAAC;IAE3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/C,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;YACzC,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACtB,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACtD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACpB,SAAS;QACX,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAA4B,CAAC,CAAC;QAChE,MAAM,IAAI,GAAK,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YAChC,MAAM,GAAG,GAAG,IAA+B,CAAC;YAC5C,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACjC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface DockerPsEntry {
|
|
2
|
+
container_id: string;
|
|
3
|
+
image: string;
|
|
4
|
+
command: string;
|
|
5
|
+
created: string;
|
|
6
|
+
status: string;
|
|
7
|
+
ports: string;
|
|
8
|
+
names: string;
|
|
9
|
+
}
|
|
10
|
+
export interface DockerStatsEntry {
|
|
11
|
+
container_id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
cpu_perc: string;
|
|
14
|
+
mem_usage: string;
|
|
15
|
+
mem_limit: string;
|
|
16
|
+
mem_perc: string;
|
|
17
|
+
net_io: string;
|
|
18
|
+
block_io: string;
|
|
19
|
+
pids: number | null;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* docker 서브커맨드별 출력 파싱.
|
|
23
|
+
* 현재 지원:
|
|
24
|
+
* - docker ps
|
|
25
|
+
* - docker stats --no-stream
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseDocker(_cmd: string, args: string[], raw: string): unknown | null;
|
|
28
|
+
//# sourceMappingURL=docker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../../src/parsers/devops/docker.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAS,MAAM,CAAC;IACrB,OAAO,EAAO,MAAM,CAAC;IACrB,OAAO,EAAO,MAAM,CAAC;IACrB,MAAM,EAAQ,MAAM,CAAC;IACrB,KAAK,EAAS,MAAM,CAAC;IACrB,KAAK,EAAS,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAU,MAAM,CAAC;IACrB,QAAQ,EAAM,MAAM,CAAC;IACrB,SAAS,EAAK,MAAM,CAAC;IACrB,SAAS,EAAK,MAAM,CAAC;IACrB,QAAQ,EAAM,MAAM,CAAC;IACrB,MAAM,EAAQ,MAAM,CAAC;IACrB,QAAQ,EAAM,MAAM,CAAC;IACrB,IAAI,EAAU,MAAM,GAAG,IAAI,CAAC;CAC7B;AA0DD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAOrF"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
function splitColumns(line) {
|
|
2
|
+
return line.trim().split(/\s{2,}/).map((v) => v.trim());
|
|
3
|
+
}
|
|
4
|
+
function parseDockerPs(raw) {
|
|
5
|
+
const lines = raw.split("\n").filter(Boolean);
|
|
6
|
+
if (lines.length <= 1)
|
|
7
|
+
return { resource: "ps", containers: [] };
|
|
8
|
+
const containers = [];
|
|
9
|
+
for (const line of lines.slice(1)) {
|
|
10
|
+
const cols = splitColumns(line);
|
|
11
|
+
if (cols.length < 6)
|
|
12
|
+
continue;
|
|
13
|
+
containers.push({
|
|
14
|
+
container_id: cols[0] ?? "",
|
|
15
|
+
image: cols[1] ?? "",
|
|
16
|
+
command: cols[2] ?? "",
|
|
17
|
+
created: cols[3] ?? "",
|
|
18
|
+
status: cols[4] ?? "",
|
|
19
|
+
ports: cols.length === 6 ? "" : (cols[5] ?? ""),
|
|
20
|
+
names: cols.length === 6 ? (cols[5] ?? "") : (cols[6] ?? ""),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return { resource: "ps", containers };
|
|
24
|
+
}
|
|
25
|
+
function parseDockerStats(raw) {
|
|
26
|
+
const lines = raw.split("\n").filter(Boolean);
|
|
27
|
+
if (lines.length <= 1)
|
|
28
|
+
return { resource: "stats", stats: [] };
|
|
29
|
+
const stats = [];
|
|
30
|
+
for (const line of lines.slice(1)) {
|
|
31
|
+
const cols = splitColumns(line);
|
|
32
|
+
if (cols.length < 7)
|
|
33
|
+
continue;
|
|
34
|
+
const memUsageParts = (cols[3] ?? "").split("/").map((v) => v.trim());
|
|
35
|
+
stats.push({
|
|
36
|
+
container_id: cols[0] ?? "",
|
|
37
|
+
name: cols[1] ?? "",
|
|
38
|
+
cpu_perc: cols[2] ?? "",
|
|
39
|
+
mem_usage: memUsageParts[0] ?? "",
|
|
40
|
+
mem_limit: memUsageParts[1] ?? "",
|
|
41
|
+
mem_perc: cols[4] ?? "",
|
|
42
|
+
net_io: cols[5] ?? "",
|
|
43
|
+
block_io: cols[6] ?? "",
|
|
44
|
+
pids: cols[7] ? (parseInt(cols[7], 10) || null) : null,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return { resource: "stats", stats };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* docker 서브커맨드별 출력 파싱.
|
|
51
|
+
* 현재 지원:
|
|
52
|
+
* - docker ps
|
|
53
|
+
* - docker stats --no-stream
|
|
54
|
+
*/
|
|
55
|
+
export function parseDocker(_cmd, args, raw) {
|
|
56
|
+
const sub = args[0];
|
|
57
|
+
if (sub === "ps")
|
|
58
|
+
return parseDockerPs(raw);
|
|
59
|
+
if (sub === "stats")
|
|
60
|
+
return parseDockerStats(raw);
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=docker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../../../src/parsers/devops/docker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface GhPullRequest {
|
|
2
|
+
number: number | null;
|
|
3
|
+
title: string;
|
|
4
|
+
branch: string | null;
|
|
5
|
+
state: string | null;
|
|
6
|
+
age: string | null;
|
|
7
|
+
author: string | null;
|
|
8
|
+
labels: string[];
|
|
9
|
+
updated_at: string | null;
|
|
10
|
+
draft: boolean | null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* gh 서브커맨드별 출력 파싱.
|
|
14
|
+
* 현재 지원:
|
|
15
|
+
* - gh pr list (table/json)
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseGh(_cmd: string, args: string[], raw: string): unknown | null;
|
|
18
|
+
//# sourceMappingURL=gh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gh.d.ts","sourceRoot":"","sources":["../../../src/parsers/devops/gh.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAM,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAO,MAAM,CAAC;IACnB,MAAM,EAAM,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAO,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,EAAS,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAM,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAM,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAO,OAAO,GAAG,IAAI,CAAC;CAC5B;AAyDD;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAOjF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
function parseGhPrListFromJson(raw) {
|
|
2
|
+
try {
|
|
3
|
+
const parsed = JSON.parse(raw);
|
|
4
|
+
if (!Array.isArray(parsed))
|
|
5
|
+
return null;
|
|
6
|
+
const pullRequests = parsed.map((pr) => {
|
|
7
|
+
const author = pr.author;
|
|
8
|
+
const labels = Array.isArray(pr.labels) ? pr.labels : [];
|
|
9
|
+
return {
|
|
10
|
+
number: typeof pr.number === "number" ? pr.number : null,
|
|
11
|
+
title: typeof pr.title === "string" ? pr.title : "",
|
|
12
|
+
branch: typeof pr.headRefName === "string" ? pr.headRefName : null,
|
|
13
|
+
state: typeof pr.state === "string" ? pr.state : null,
|
|
14
|
+
age: null,
|
|
15
|
+
author: typeof author?.login === "string" ? author.login : null,
|
|
16
|
+
labels: labels.map((label) => String(label.name ?? "")).filter(Boolean),
|
|
17
|
+
updated_at: typeof pr.updatedAt === "string" ? pr.updatedAt : null,
|
|
18
|
+
draft: typeof pr.isDraft === "boolean" ? pr.isDraft : null,
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
return { resource: "pr_list", pull_requests: pullRequests };
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function parseGhPrListFromTable(raw) {
|
|
28
|
+
const lines = raw.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
29
|
+
const pullRequests = [];
|
|
30
|
+
for (const line of lines) {
|
|
31
|
+
const cols = line.includes("\t")
|
|
32
|
+
? line.split(/\t+/).map((v) => v.trim())
|
|
33
|
+
: line.split(/\s{2,}/).map((v) => v.trim());
|
|
34
|
+
if (cols.length < 2)
|
|
35
|
+
continue;
|
|
36
|
+
pullRequests.push({
|
|
37
|
+
number: parseInt(cols[0] ?? "", 10) || null,
|
|
38
|
+
title: cols[1] ?? "",
|
|
39
|
+
branch: cols[2] ?? null,
|
|
40
|
+
state: cols[3] ?? null,
|
|
41
|
+
age: cols[4] ?? null,
|
|
42
|
+
author: null,
|
|
43
|
+
labels: [],
|
|
44
|
+
updated_at: null,
|
|
45
|
+
draft: null,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return { resource: "pr_list", pull_requests: pullRequests };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* gh 서브커맨드별 출력 파싱.
|
|
52
|
+
* 현재 지원:
|
|
53
|
+
* - gh pr list (table/json)
|
|
54
|
+
*/
|
|
55
|
+
export function parseGh(_cmd, args, raw) {
|
|
56
|
+
const sub1 = args[0];
|
|
57
|
+
const sub2 = args[1];
|
|
58
|
+
if (!(sub1 === "pr" && sub2 === "list"))
|
|
59
|
+
return null;
|
|
60
|
+
return parseGhPrListFromJson(raw) ?? parseGhPrListFromTable(raw);
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=gh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gh.js","sourceRoot":"","sources":["../../../src/parsers/devops/gh.ts"],"names":[],"mappings":"AAYA,SAAS,qBAAqB,CAAC,GAAW;IACxC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmC,CAAC;QACjE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QAExC,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG,EAAE,CAAC,MAA6C,CAAC;YAChE,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAwC,CAAC,CAAC,CAAC,EAAE,CAAC;YAE3F,OAAO;gBACL,MAAM,EAAM,OAAO,EAAE,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI;gBAC5D,KAAK,EAAO,OAAO,EAAE,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;gBACxD,MAAM,EAAM,OAAO,EAAE,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;gBACtE,KAAK,EAAO,OAAO,EAAE,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;gBAC1D,GAAG,EAAS,IAAI;gBAChB,MAAM,EAAM,OAAO,MAAM,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;gBACnE,MAAM,EAAM,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;gBAC3E,UAAU,EAAE,OAAO,EAAE,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;gBAClE,KAAK,EAAO,OAAO,EAAE,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;aACxC,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB,CAAC,GAAW;IACzC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACzE,MAAM,YAAY,GAAoB,EAAE,CAAC;IAEzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAC9B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACxC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAE9C,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAE9B,YAAY,CAAC,IAAI,CAAC;YAChB,MAAM,EAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,IAAI;YAC/C,KAAK,EAAO,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;YACzB,MAAM,EAAM,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI;YAC3B,KAAK,EAAO,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI;YAC3B,GAAG,EAAS,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI;YAC3B,MAAM,EAAM,IAAI;YAChB,MAAM,EAAM,EAAE;YACd,UAAU,EAAE,IAAI;YAChB,KAAK,EAAO,IAAI;SACjB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,IAAc,EAAE,GAAW;IAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACrB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAErB,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAErD,OAAO,qBAAqB,CAAC,GAAG,CAAC,IAAI,sBAAsB,CAAC,GAAG,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* helm list 출력 파싱.
|
|
3
|
+
*
|
|
4
|
+
* @author 최진호
|
|
5
|
+
* @date 2026-03-07
|
|
6
|
+
*/
|
|
7
|
+
import type { ParseContext } from "../registry.js";
|
|
8
|
+
export interface HelmRelease {
|
|
9
|
+
name: string;
|
|
10
|
+
namespace: string;
|
|
11
|
+
revision: number;
|
|
12
|
+
updated: string;
|
|
13
|
+
status: string;
|
|
14
|
+
chart: string;
|
|
15
|
+
app_version: string;
|
|
16
|
+
}
|
|
17
|
+
export interface HelmResult {
|
|
18
|
+
releases: HelmRelease[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* helm list 출력을 파싱한다.
|
|
22
|
+
* 탭 또는 2+ 공백으로 구분된 컬럼.
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseHelm(_cmd: string, _args: string[], raw: string, ctx?: ParseContext): HelmResult | {
|
|
25
|
+
lines: string[];
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=helm.d.ts.map
|