govon 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/README.md +45 -0
- package/bin/govon.js +44 -0
- package/lib/python-check.js +156 -0
- package/package.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# govon (npm)
|
|
2
|
+
|
|
3
|
+
npm wrapper for the [GovOn](https://github.com/umyunsang/GovOn) CLI.
|
|
4
|
+
|
|
5
|
+
GovOn은 행정 지원 및 민원 처리 워크플로우를 위한 셸 퍼스트 로컬 에이전트 런타임입니다.
|
|
6
|
+
|
|
7
|
+
## 요구 사항
|
|
8
|
+
|
|
9
|
+
- **Node.js** 18 이상
|
|
10
|
+
- **Python** 3.10 이상
|
|
11
|
+
- **pip** (Python 패키지 관리자)
|
|
12
|
+
|
|
13
|
+
## 설치
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g govon
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
설치 후 Python 환경이 자동으로 확인됩니다.
|
|
20
|
+
`govon` Python 패키지가 설치되어 있지 않다면 아래 명령어로 설치하세요.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install govon
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 사용법
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
govon --help
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 동작 방식
|
|
33
|
+
|
|
34
|
+
이 패키지는 Python CLI(`govon`)를 감싸는 thin wrapper입니다.
|
|
35
|
+
|
|
36
|
+
1. `govon` 명령어 실행 시 Python 3.10+ 설치 여부를 확인합니다.
|
|
37
|
+
2. `govon` CLI(`pip install govon`)가 설치되어 있는지 확인합니다.
|
|
38
|
+
3. 조건이 충족되면 `child_process.spawn`을 통해 Python CLI에 실행을 위임합니다.
|
|
39
|
+
4. 미충족 시 명확한 설치 안내 메시지를 출력하고 종료합니다.
|
|
40
|
+
|
|
41
|
+
> Python 자동 설치는 보안 및 권한 이슈로 지원하지 않습니다.
|
|
42
|
+
|
|
43
|
+
## 라이선스
|
|
44
|
+
|
|
45
|
+
MIT
|
package/bin/govon.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { spawn } = require('child_process');
|
|
5
|
+
const { printEnvironmentStatus, isGovonInstalled } = require('../lib/python-check');
|
|
6
|
+
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
|
|
9
|
+
// postinstall 또는 직접 호출 시 환경 점검만 수행하고 종료
|
|
10
|
+
if (args[0] === '--check-install') {
|
|
11
|
+
const ok = printEnvironmentStatus();
|
|
12
|
+
process.exit(ok ? 0 : 1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// 실제 CLI 실행 경로: 환경이 올바르지 않으면 안내 메시지를 출력하고 종료
|
|
16
|
+
if (!printEnvironmentStatus()) {
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// govon CLI를 실제로 실행
|
|
21
|
+
const child = spawn('govon', args, {
|
|
22
|
+
stdio: 'inherit',
|
|
23
|
+
shell: false,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
child.on('error', (err) => {
|
|
27
|
+
if (err.code === 'ENOENT') {
|
|
28
|
+
console.error(
|
|
29
|
+
[
|
|
30
|
+
'',
|
|
31
|
+
' [govon] govon 명령어를 실행할 수 없습니다.',
|
|
32
|
+
' pip install govon 으로 설치되었는지 확인하세요.',
|
|
33
|
+
'',
|
|
34
|
+
].join('\n')
|
|
35
|
+
);
|
|
36
|
+
} else {
|
|
37
|
+
console.error(`[govon] 실행 오류: ${err.message}`);
|
|
38
|
+
}
|
|
39
|
+
process.exit(1);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
child.on('close', (code) => {
|
|
43
|
+
process.exit(code ?? 0);
|
|
44
|
+
});
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { execSync, spawnSync } = require('child_process');
|
|
4
|
+
|
|
5
|
+
const MIN_PYTHON_MAJOR = 3;
|
|
6
|
+
const MIN_PYTHON_MINOR = 10;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Python 실행 파일 후보 목록 (우선순위 순)
|
|
10
|
+
*/
|
|
11
|
+
const PYTHON_CANDIDATES = ['python3', 'python'];
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 주어진 python 실행 파일의 버전을 반환합니다.
|
|
15
|
+
* 실행 불가능하거나 파싱 실패 시 null을 반환합니다.
|
|
16
|
+
* @param {string} cmd - 실행할 python 명령어
|
|
17
|
+
* @returns {{ major: number, minor: number } | null}
|
|
18
|
+
*/
|
|
19
|
+
function getPythonVersion(cmd) {
|
|
20
|
+
try {
|
|
21
|
+
const result = spawnSync(cmd, ['--version'], { encoding: 'utf8', timeout: 5000 });
|
|
22
|
+
if (result.status !== 0 || result.error) return null;
|
|
23
|
+
|
|
24
|
+
// "Python 3.11.4" 또는 stderr에 출력될 수 있음 (Python 2)
|
|
25
|
+
const output = (result.stdout || result.stderr || '').trim();
|
|
26
|
+
const match = output.match(/Python\s+(\d+)\.(\d+)/i);
|
|
27
|
+
if (!match) return null;
|
|
28
|
+
|
|
29
|
+
return { major: parseInt(match[1], 10), minor: parseInt(match[2], 10) };
|
|
30
|
+
} catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 시스템에서 사용 가능한 Python 3.10+ 실행 파일을 찾습니다.
|
|
37
|
+
* @returns {{ cmd: string, major: number, minor: number } | null}
|
|
38
|
+
*/
|
|
39
|
+
function findPython() {
|
|
40
|
+
for (const candidate of PYTHON_CANDIDATES) {
|
|
41
|
+
const version = getPythonVersion(candidate);
|
|
42
|
+
if (
|
|
43
|
+
version &&
|
|
44
|
+
(version.major > MIN_PYTHON_MAJOR ||
|
|
45
|
+
(version.major === MIN_PYTHON_MAJOR && version.minor >= MIN_PYTHON_MINOR))
|
|
46
|
+
) {
|
|
47
|
+
return { cmd: candidate, ...version };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* `govon` CLI가 PATH에 설치되어 있는지 확인합니다.
|
|
55
|
+
* npm의 govon.js wrapper가 아닌 Python의 govon binary를 찾습니다.
|
|
56
|
+
* @returns {boolean}
|
|
57
|
+
*/
|
|
58
|
+
function isGovonInstalled() {
|
|
59
|
+
try {
|
|
60
|
+
// which/where로 govon 경로를 확인하여 Python binary인지 검증
|
|
61
|
+
const whichCmd = process.platform === 'win32' ? 'where' : 'which';
|
|
62
|
+
const which = spawnSync(whichCmd, ['govon'], { encoding: 'utf8', timeout: 5000 });
|
|
63
|
+
if (which.error || which.status !== 0) return false;
|
|
64
|
+
|
|
65
|
+
const govonPath = (which.stdout || '').trim().split('\n')[0];
|
|
66
|
+
// npm bin 경로(node_modules/.bin)에 있으면 npm wrapper이므로 무시
|
|
67
|
+
if (govonPath.includes('node_modules')) return false;
|
|
68
|
+
|
|
69
|
+
// Python module로 직접 확인
|
|
70
|
+
const python = findPython();
|
|
71
|
+
if (!python) return false;
|
|
72
|
+
|
|
73
|
+
const result = spawnSync(python.cmd, ['-m', 'govon', '--version'], {
|
|
74
|
+
encoding: 'utf8',
|
|
75
|
+
timeout: 5000,
|
|
76
|
+
});
|
|
77
|
+
return !result.error && result.status === 0;
|
|
78
|
+
} catch {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Python 환경 전체를 검사하고 결과를 반환합니다.
|
|
85
|
+
* @returns {{
|
|
86
|
+
* pythonFound: boolean,
|
|
87
|
+
* pythonCmd: string | null,
|
|
88
|
+
* pythonVersion: string | null,
|
|
89
|
+
* govonInstalled: boolean
|
|
90
|
+
* }}
|
|
91
|
+
*/
|
|
92
|
+
function checkEnvironment() {
|
|
93
|
+
const python = findPython();
|
|
94
|
+
const govonInstalled = python ? isGovonInstalled() : false;
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
pythonFound: python !== null,
|
|
98
|
+
pythonCmd: python ? python.cmd : null,
|
|
99
|
+
pythonVersion: python ? `${python.major}.${python.minor}` : null,
|
|
100
|
+
govonInstalled,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* 환경 검사 결과를 stdout에 출력하고 문제가 있으면 안내 메시지를 표시합니다.
|
|
106
|
+
* @returns {boolean} - 모든 조건이 충족되면 true
|
|
107
|
+
*/
|
|
108
|
+
function printEnvironmentStatus() {
|
|
109
|
+
const { pythonFound, pythonCmd, pythonVersion, govonInstalled } = checkEnvironment();
|
|
110
|
+
|
|
111
|
+
if (!pythonFound) {
|
|
112
|
+
console.error(
|
|
113
|
+
[
|
|
114
|
+
'',
|
|
115
|
+
' [govon] Python 3.10 이상이 필요합니다.',
|
|
116
|
+
'',
|
|
117
|
+
' Python을 설치한 뒤 다시 시도해 주세요:',
|
|
118
|
+
' https://www.python.org/downloads/',
|
|
119
|
+
'',
|
|
120
|
+
' 또는 패키지 관리자를 이용하세요:',
|
|
121
|
+
' macOS: brew install python@3.12',
|
|
122
|
+
' Ubuntu: sudo apt install python3.12',
|
|
123
|
+
' Windows: winget install Python.Python.3.12',
|
|
124
|
+
'',
|
|
125
|
+
].join('\n')
|
|
126
|
+
);
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (!govonInstalled) {
|
|
131
|
+
console.error(
|
|
132
|
+
[
|
|
133
|
+
'',
|
|
134
|
+
` [govon] govon CLI가 설치되어 있지 않습니다. (Python ${pythonVersion} 감지됨)`,
|
|
135
|
+
'',
|
|
136
|
+
' 아래 명령어로 설치해 주세요:',
|
|
137
|
+
` ${pythonCmd} -m pip install govon`,
|
|
138
|
+
'',
|
|
139
|
+
' 가상환경을 사용하는 경우:',
|
|
140
|
+
' python -m venv .venv && source .venv/bin/activate',
|
|
141
|
+
` pip install govon`,
|
|
142
|
+
'',
|
|
143
|
+
].join('\n')
|
|
144
|
+
);
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
module.exports = {
|
|
152
|
+
findPython,
|
|
153
|
+
isGovonInstalled,
|
|
154
|
+
checkEnvironment,
|
|
155
|
+
printEnvironmentStatus,
|
|
156
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "govon",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "npm wrapper for the GovOn CLI — Shell-first local agentic runtime for administrative assistance and civil complaint workflows",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"govon",
|
|
7
|
+
"agentic-shell",
|
|
8
|
+
"local-runtime",
|
|
9
|
+
"civil-complaint",
|
|
10
|
+
"korean-nlp",
|
|
11
|
+
"cli"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/GovOn-Org/GovOn#readme",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/GovOn-Org/GovOn/issues"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/GovOn-Org/GovOn.git",
|
|
20
|
+
"directory": "packages/npm"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"bin": {
|
|
24
|
+
"govon": "./bin/govon.js"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"postinstall": "node ./bin/govon.js --check-install || true"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"bin/",
|
|
34
|
+
"lib/",
|
|
35
|
+
"README.md"
|
|
36
|
+
]
|
|
37
|
+
}
|