govon 0.1.0 → 1.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 CHANGED
@@ -2,44 +2,44 @@
2
2
 
3
3
  npm wrapper for the [GovOn](https://github.com/umyunsang/GovOn) CLI.
4
4
 
5
- GovOn 행정 지원 민원 처리 워크플로우를 위한 퍼스트 로컬 에이전트 런타임입니다.
5
+ GovOn is a shell-first local agent runtime for administrative support and civil complaint processing workflows.
6
6
 
7
- ## 요구 사항
7
+ ## Requirements
8
8
 
9
- - **Node.js** 18 이상
10
- - **Python** 3.10 이상
11
- - **pip** (Python 패키지 관리자)
9
+ - **Node.js** 18 or later
10
+ - **Python** 3.10 or later
11
+ - **pip** (Python package manager)
12
12
 
13
- ## 설치
13
+ ## Installation
14
14
 
15
15
  ```bash
16
16
  npm install -g govon
17
17
  ```
18
18
 
19
- 설치 Python 환경이 자동으로 확인됩니다.
20
- `govon` Python 패키지가 설치되어 있지 않다면 아래 명령어로 설치하세요.
19
+ After installation the Python environment is automatically verified.
20
+ If the `govon` Python package is not installed, install it with:
21
21
 
22
22
  ```bash
23
23
  pip install govon
24
24
  ```
25
25
 
26
- ## 사용법
26
+ ## Usage
27
27
 
28
28
  ```bash
29
29
  govon --help
30
30
  ```
31
31
 
32
- ## 동작 방식
32
+ ## How It Works
33
33
 
34
- 패키지는 Python CLI(`govon`)를 감싸는 thin wrapper입니다.
34
+ This package is a thin wrapper around the Python CLI (`govon`).
35
35
 
36
- 1. `govon` 명령어 실행 Python 3.10+ 설치 여부를 확인합니다.
37
- 2. `govon` CLI(`pip install govon`) 설치되어 있는지 확인합니다.
38
- 3. 조건이 충족되면 `child_process.spawn`을 통해 Python CLI 실행을 위임합니다.
39
- 4. 미충족 명확한 설치 안내 메시지를 출력하고 종료합니다.
36
+ 1. When the `govon` command is run, it checks whether Python 3.10+ is installed.
37
+ 2. It verifies that the `govon` CLI (`pip install govon`) is installed.
38
+ 3. If all conditions are met, execution is delegated to the Python CLI via `child_process.spawn`.
39
+ 4. If conditions are not met, a clear installation guide message is printed and the process exits.
40
40
 
41
- > Python 자동 설치는 보안 권한 이슈로 지원하지 않습니다.
41
+ > Automatic Python installation is not supported due to security and permission concerns.
42
42
 
43
- ## 라이선스
43
+ ## License
44
44
 
45
45
  MIT
package/bin/govon.js CHANGED
@@ -6,18 +6,18 @@ const { printEnvironmentStatus, isGovonInstalled } = require('../lib/python-chec
6
6
 
7
7
  const args = process.argv.slice(2);
8
8
 
9
- // postinstall 또는 직접 호출 환경 점검만 수행하고 종료
9
+ // On postinstall or direct invocation with --check-install, only run environment check and exit
10
10
  if (args[0] === '--check-install') {
11
11
  const ok = printEnvironmentStatus();
12
12
  process.exit(ok ? 0 : 1);
13
13
  }
14
14
 
15
- // 실제 CLI 실행 경로: 환경이 올바르지 않으면 안내 메시지를 출력하고 종료
15
+ // Actual CLI execution path: if environment is not valid, print guidance and exit
16
16
  if (!printEnvironmentStatus()) {
17
17
  process.exit(1);
18
18
  }
19
19
 
20
- // govon CLI를 실제로 실행
20
+ // Launch the govon CLI
21
21
  const child = spawn('govon', args, {
22
22
  stdio: 'inherit',
23
23
  shell: false,
@@ -28,13 +28,13 @@ child.on('error', (err) => {
28
28
  console.error(
29
29
  [
30
30
  '',
31
- ' [govon] govon 명령어를 실행할 없습니다.',
32
- ' pip install govon 으로 설치되었는지 확인하세요.',
31
+ ' [govon] Unable to execute the govon command.',
32
+ ' Please verify it is installed via: pip install govon',
33
33
  '',
34
34
  ].join('\n')
35
35
  );
36
36
  } else {
37
- console.error(`[govon] 실행 오류: ${err.message}`);
37
+ console.error(`[govon] Execution error: ${err.message}`);
38
38
  }
39
39
  process.exit(1);
40
40
  });
@@ -1,19 +1,21 @@
1
1
  'use strict';
2
2
 
3
3
  const { execSync, spawnSync } = require('child_process');
4
+ const { realpathSync } = require('fs');
5
+ const path = require('path');
4
6
 
5
7
  const MIN_PYTHON_MAJOR = 3;
6
8
  const MIN_PYTHON_MINOR = 10;
7
9
 
8
10
  /**
9
- * Python 실행 파일 후보 목록 (우선순위 순)
11
+ * List of Python executable candidates in priority order
10
12
  */
11
13
  const PYTHON_CANDIDATES = ['python3', 'python'];
12
14
 
13
15
  /**
14
- * 주어진 python 실행 파일의 버전을 반환합니다.
15
- * 실행 불가능하거나 파싱 실패 null을 반환합니다.
16
- * @param {string} cmd - 실행할 python 명령어
16
+ * Returns the version of the given Python executable.
17
+ * Returns null if the executable cannot be run or version parsing fails.
18
+ * @param {string} cmd - Python command to execute
17
19
  * @returns {{ major: number, minor: number } | null}
18
20
  */
19
21
  function getPythonVersion(cmd) {
@@ -21,7 +23,7 @@ function getPythonVersion(cmd) {
21
23
  const result = spawnSync(cmd, ['--version'], { encoding: 'utf8', timeout: 5000 });
22
24
  if (result.status !== 0 || result.error) return null;
23
25
 
24
- // "Python 3.11.4" 또는 stderr 출력될 수 있음 (Python 2)
26
+ // Output may appear as "Python 3.11.4" or on stderr (Python 2)
25
27
  const output = (result.stdout || result.stderr || '').trim();
26
28
  const match = output.match(/Python\s+(\d+)\.(\d+)/i);
27
29
  if (!match) return null;
@@ -33,7 +35,7 @@ function getPythonVersion(cmd) {
33
35
  }
34
36
 
35
37
  /**
36
- * 시스템에서 사용 가능한 Python 3.10+ 실행 파일을 찾습니다.
38
+ * Finds a Python 3.10+ executable available on the system.
37
39
  * @returns {{ cmd: string, major: number, minor: number } | null}
38
40
  */
39
41
  function findPython() {
@@ -51,22 +53,29 @@ function findPython() {
51
53
  }
52
54
 
53
55
  /**
54
- * `govon` CLI PATH에 설치되어 있는지 확인합니다.
55
- * npm의 govon.js wrapper가 아닌 Python govon binary 찾습니다.
56
+ * Checks whether the `govon` CLI is installed in PATH.
57
+ * Looks for the Python govon binary, not the npm govon.js wrapper.
56
58
  * @returns {boolean}
57
59
  */
58
60
  function isGovonInstalled() {
59
61
  try {
60
- // which/where govon 경로를 확인하여 Python binary인지 검증
62
+ // Verify govon path via which/where to confirm it is a Python binary
61
63
  const whichCmd = process.platform === 'win32' ? 'where' : 'which';
62
64
  const which = spawnSync(whichCmd, ['govon'], { encoding: 'utf8', timeout: 5000 });
63
65
  if (which.error || which.status !== 0) return false;
64
66
 
65
67
  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
+ // Resolve symlinks to detect npm wrapper even behind /usr/local/bin symlinks
69
+ let resolvedPath;
70
+ try {
71
+ resolvedPath = realpathSync(govonPath);
72
+ } catch {
73
+ resolvedPath = govonPath;
74
+ }
75
+ // If the resolved path is under node_modules/.bin it is the npm wrapper — ignore it
76
+ if (resolvedPath.includes('node_modules')) return false;
68
77
 
69
- // Python module로 직접 확인
78
+ // Confirm directly via Python module
70
79
  const python = findPython();
71
80
  if (!python) return false;
72
81
 
@@ -81,7 +90,21 @@ function isGovonInstalled() {
81
90
  }
82
91
 
83
92
  /**
84
- * Python 환경 전체를 검사하고 결과를 반환합니다.
93
+ * Reads the npm package version from package.json for version pinning.
94
+ * @returns {string} - version string (e.g. "1.0.6"), or empty string on failure
95
+ */
96
+ function getNpmPackageVersion() {
97
+ try {
98
+ const pkgPath = path.join(__dirname, '..', 'package.json');
99
+ const pkg = require(pkgPath);
100
+ return pkg.version || '';
101
+ } catch {
102
+ return '';
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Inspects the entire Python environment and returns the result.
85
108
  * @returns {{
86
109
  * pythonFound: boolean,
87
110
  * pythonCmd: string | null,
@@ -102,55 +125,99 @@ function checkEnvironment() {
102
125
  }
103
126
 
104
127
  /**
105
- * 환경 검사 결과를 stdout에 출력하고 문제가 있으면 안내 메시지를 표시합니다.
106
- * @returns {boolean} - 모든 조건이 충족되면 true
128
+ * Automatically installs the Python govon package via pip.
129
+ * Pins to the same version as the npm package to prevent version drift.
130
+ * @param {string} pythonCmd - path to the python executable
131
+ * @returns {boolean} - true if installation succeeded
107
132
  */
108
- function printEnvironmentStatus() {
109
- const { pythonFound, pythonCmd, pythonVersion, govonInstalled } = checkEnvironment();
133
+ function autoInstallGovon(pythonCmd) {
134
+ const version = getNpmPackageVersion();
135
+ const spec = version ? `govon==${version}` : 'govon';
110
136
 
111
- if (!pythonFound) {
137
+ console.log('\n [govon] Auto-installing the Python govon package…');
138
+ console.log(` → ${pythonCmd} -m pip install ${spec}\n`);
139
+
140
+ const result = spawnSync(pythonCmd, ['-m', 'pip', 'install', spec], {
141
+ stdio: 'inherit',
142
+ timeout: 120000,
143
+ });
144
+
145
+ if (result.error || result.status !== 0) {
112
146
  console.error(
113
147
  [
114
148
  '',
115
- ' [govon] Python 3.10 이상이 필요합니다.',
149
+ ' [govon] Auto-installation failed.',
116
150
  '',
117
- ' Python을 설치한 다시 시도해 주세요:',
118
- ' https://www.python.org/downloads/',
151
+ ' Please install manually with:',
152
+ ` ${pythonCmd} -m pip install ${spec}`,
119
153
  '',
120
- ' 또는 패키지 관리자를 이용하세요:',
121
- ' macOS: brew install python@3.12',
122
- ' Ubuntu: sudo apt install python3.12',
123
- ' Windows: winget install Python.Python.3.12',
154
+ ' If you encounter a permission error:',
155
+ ` ${pythonCmd} -m pip install --user ${spec}`,
124
156
  '',
125
157
  ].join('\n')
126
158
  );
127
159
  return false;
128
160
  }
129
161
 
130
- if (!govonInstalled) {
162
+ console.log('\n [govon] ✓ Python govon package installed successfully.\n');
163
+ return true;
164
+ }
165
+
166
+ /**
167
+ * Prints the environment check result to stdout and displays guidance if issues are found.
168
+ * Attempts auto-installation if Python govon is not found.
169
+ * @returns {boolean} - true if all conditions are met
170
+ */
171
+ function printEnvironmentStatus() {
172
+ const { pythonFound, pythonCmd, pythonVersion, govonInstalled } = checkEnvironment();
173
+
174
+ if (!pythonFound) {
131
175
  console.error(
132
176
  [
133
177
  '',
134
- ` [govon] govon CLI가 설치되어 있지 않습니다. (Python ${pythonVersion} 감지됨)`,
178
+ ' [govon] Python 3.10 or later is required.',
135
179
  '',
136
- ' 아래 명령어로 설치해 주세요:',
137
- ` ${pythonCmd} -m pip install govon`,
180
+ ' Please install Python and try again:',
181
+ ' https://www.python.org/downloads/',
138
182
  '',
139
- ' 가상환경을 사용하는 경우:',
140
- ' python -m venv .venv && source .venv/bin/activate',
141
- ` pip install govon`,
183
+ ' Or install via a package manager:',
184
+ ' macOS: brew install python@3.12',
185
+ ' Ubuntu: sudo apt install python3.12',
186
+ ' Windows: winget install Python.Python.3.12',
142
187
  '',
143
188
  ].join('\n')
144
189
  );
145
190
  return false;
146
191
  }
147
192
 
193
+ if (!govonInstalled) {
194
+ // Attempt auto-installation
195
+ if (!autoInstallGovon(pythonCmd)) {
196
+ return false;
197
+ }
198
+ // Re-verify after installation (resolve symlinks for accurate detection)
199
+ if (!isGovonInstalled()) {
200
+ console.error(
201
+ [
202
+ '',
203
+ ' [govon] govon CLI could not be found even after installation.',
204
+ '',
205
+ ' Please ensure the pip install path is included in your PATH.',
206
+ ` Or run directly: ${pythonCmd} -m govon`,
207
+ '',
208
+ ].join('\n')
209
+ );
210
+ return false;
211
+ }
212
+ }
213
+
148
214
  return true;
149
215
  }
150
216
 
151
217
  module.exports = {
152
218
  findPython,
153
219
  isGovonInstalled,
220
+ autoInstallGovon,
154
221
  checkEnvironment,
155
222
  printEnvironmentStatus,
156
223
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "govon",
3
- "version": "0.1.0",
3
+ "version": "1.1.0",
4
4
  "description": "npm wrapper for the GovOn CLI — Shell-first local agentic runtime for administrative assistance and civil complaint workflows",
5
5
  "keywords": [
6
6
  "govon",