@agentteams/runner 0.0.117 → 0.0.118

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.
@@ -1,17 +1,39 @@
1
1
  const PERMISSION_DENIED_MESSAGE = 'Global npm install requires elevated permissions. Configure a user-level npm prefix or rerun the update with appropriate permissions.';
2
+ const BIN_CONFLICT_MESSAGE = 'Global npm install failed because a command name is already taken by a file from another source. ' +
3
+ 'npm prints the conflicting path after "File exists:" — remove or rename that file, then retry the update.';
4
+ const toMessage = (error) => (error instanceof Error ? error.message : String(error));
5
+ const isPermissionFailure = (message) => message.includes('EACCES') || message.includes('EPERM') || message.toLowerCase().includes('permission denied');
6
+ /**
7
+ * 전역 bin 이름 충돌. 패키지가 링크하려는 bin 이름을 다른 출처의 파일이 이미 점유하고 있으면
8
+ * npm은 `EEXIST` / `File exists:`로 설치 전체를 실패시킨다. 사용자가 그 파일을 치우기 전에는 풀리지 않는다.
9
+ */
10
+ const isBinConflictFailure = (message) => message.includes('EEXIST') || message.includes('File exists:');
2
11
  export const classifyInstallError = (error) => {
3
- const message = error instanceof Error ? error.message : String(error);
4
- if (message.includes('EACCES') || message.includes('EPERM') || message.toLowerCase().includes('permission denied')) {
12
+ if (isPermissionFailure(toMessage(error))) {
5
13
  return 'PERMISSION_DENIED';
6
14
  }
7
15
  return 'UNKNOWN';
8
16
  };
9
- /** 사용자에게 보여줄 설치 실패 메시지. 권한 실패는 조치 방법을 담은 고정 문구를 쓴다. */
17
+ /**
18
+ * 재시도만으로는 절대 풀리지 않고 사용자가 직접 손대야 하는 실패인지 판정한다.
19
+ *
20
+ * 서버로 보내는 `reason` 코드 계약(`PERMISSION_DENIED` | `UNKNOWN`)은 그대로 두고, 자동 업데이트의
21
+ * 재시도 백오프만 이 판정으로 넓힌다. bin 이름 충돌은 `UNKNOWN`으로 보고되지만 1시간마다 재시도할
22
+ * 이유가 없는 실패라 여기에 포함된다.
23
+ */
24
+ export const requiresManualFix = (error) => {
25
+ const message = toMessage(error);
26
+ return isPermissionFailure(message) || isBinConflictFailure(message);
27
+ };
28
+ /** 사용자에게 보여줄 설치 실패 메시지. 조치 방법이 정해진 실패는 고정 문구를 쓴다. */
10
29
  export const describeInstallError = (error) => {
11
- const message = error instanceof Error ? error.message : String(error);
12
- if (classifyInstallError(error) === 'PERMISSION_DENIED') {
30
+ const message = toMessage(error);
31
+ if (isPermissionFailure(message)) {
13
32
  return PERMISSION_DENIED_MESSAGE;
14
33
  }
34
+ if (isBinConflictFailure(message)) {
35
+ return BIN_CONFLICT_MESSAGE;
36
+ }
15
37
  return `Failed to install the latest AgentRunner package: ${message}`;
16
38
  };
17
39
  /** 설치 실패를 사용자용 문구로 정규화한 Error로 바꾼다. */
@@ -1 +1 @@
1
- {"version":3,"file":"npm-install-error.js","sourceRoot":"","sources":["../../src/utils/npm-install-error.ts"],"names":[],"mappings":"AAQA,MAAM,yBAAyB,GAC7B,uIAAuI,CAAC;AAE1I,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAc,EAAwB,EAAE;IAC3E,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEvE,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACnH,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,uDAAuD;AACvD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAc,EAAU,EAAE;IAC7D,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEvE,IAAI,oBAAoB,CAAC,KAAK,CAAC,KAAK,mBAAmB,EAAE,CAAC;QACxD,OAAO,yBAAyB,CAAC;IACnC,CAAC;IAED,OAAO,qDAAqD,OAAO,EAAE,CAAC;AACxE,CAAC,CAAC;AAEF,uCAAuC;AACvC,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,KAAc,EAAS,EAAE,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"npm-install-error.js","sourceRoot":"","sources":["../../src/utils/npm-install-error.ts"],"names":[],"mappings":"AAQA,MAAM,yBAAyB,GAC7B,uIAAuI,CAAC;AAE1I,MAAM,oBAAoB,GACxB,mGAAmG;IACnG,2GAA2G,CAAC;AAE9G,MAAM,SAAS,GAAG,CAAC,KAAc,EAAU,EAAE,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAEvG,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAW,EAAE,CACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC;AAEjH;;;GAGG;AACH,MAAM,oBAAoB,GAAG,CAAC,OAAe,EAAW,EAAE,CACxD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;AAEjE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAc,EAAwB,EAAE;IAC3E,IAAI,mBAAmB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QAC1C,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAc,EAAW,EAAE;IAC3D,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO,mBAAmB,CAAC,OAAO,CAAC,IAAI,oBAAoB,CAAC,OAAO,CAAC,CAAC;AACvE,CAAC,CAAC;AAEF,qDAAqD;AACrD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAc,EAAU,EAAE;IAC7D,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAEjC,IAAI,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAAC;QACjC,OAAO,yBAAyB,CAAC;IACnC,CAAC;IAED,IAAI,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IAED,OAAO,qDAAqD,OAAO,EAAE,CAAC;AACxE,CAAC,CAAC;AAEF,uCAAuC;AACvC,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,KAAc,EAAS,EAAE,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import assert from 'node:assert/strict';
2
2
  import test from 'node:test';
3
- import { classifyInstallError, describeInstallError, normalizeInstallError } from './npm-install-error.js';
3
+ import { classifyInstallError, describeInstallError, normalizeInstallError, requiresManualFix, } from './npm-install-error.js';
4
4
  test('classifyInstallError detects permission failures from real npm output', () => {
5
5
  const eacces = new Error([
6
6
  'Command failed: /usr/bin/npm install -g @agentteams/runner@0.0.114',
@@ -25,4 +25,26 @@ test('normalizeInstallError returns an Error carrying the described message', ()
25
25
  assert.ok(normalized instanceof Error);
26
26
  assert.equal(normalized.message, describeInstallError(new Error('npm ERR! code EACCES')));
27
27
  });
28
+ const EEXIST_INSTALL_ERROR_MESSAGE = [
29
+ 'Command failed: /usr/bin/npm install -g @agentteams/cli@0.0.114',
30
+ 'npm ERR! code EEXIST',
31
+ 'npm ERR! path /usr/local/bin/agt',
32
+ 'npm ERR! EEXIST: file already exists',
33
+ 'npm ERR! File exists: /usr/local/bin/agt',
34
+ ].join('\n');
35
+ test('describeInstallError guides the user to clear a conflicting global bin file', () => {
36
+ // `agt`/`agr` bin이 늘어난 뒤 새로 열린 실패 경로다. 원시 npm 출력만 보여주면 조치를 알 수 없다.
37
+ const described = describeInstallError(new Error(EEXIST_INSTALL_ERROR_MESSAGE));
38
+ assert.match(described, /already taken by a file from another source/u);
39
+ assert.match(described, /remove or rename that file/u);
40
+ });
41
+ test('requiresManualFix covers both permission blocks and global bin conflicts', () => {
42
+ assert.equal(requiresManualFix(new Error('npm ERR! code EACCES')), true);
43
+ assert.equal(requiresManualFix(new Error(EEXIST_INSTALL_ERROR_MESSAGE)), true);
44
+ assert.equal(requiresManualFix(new Error('npm ERR! File exists: /usr/local/bin/agr')), true);
45
+ assert.equal(requiresManualFix(new Error('network unavailable')), false);
46
+ });
47
+ test('a bin conflict keeps reporting UNKNOWN so the server reason contract stays unchanged', () => {
48
+ assert.equal(classifyInstallError(new Error(EEXIST_INSTALL_ERROR_MESSAGE)), 'UNKNOWN');
49
+ });
28
50
  //# sourceMappingURL=npm-install-error.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"npm-install-error.test.js","sourceRoot":"","sources":["../../src/utils/npm-install-error.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE3G,IAAI,CAAC,uEAAuE,EAAE,GAAG,EAAE;IACjF,MAAM,MAAM,GAAG,IAAI,KAAK,CACtB;QACE,oEAAoE;QACpE,sBAAsB;QACtB,yBAAyB;QACzB,oBAAoB;KACrB,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAChE,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAC1F,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;AAC9F,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+DAA+D,EAAE,GAAG,EAAE;IACzE,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAChF,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,6BAA6B,CAAC,EAAE,SAAS,CAAC,CAAC;AAC/E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,4EAA4E,EAAE,GAAG,EAAE;IACtF,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC,EAAE,sBAAsB,CAAC,CAAC;IAC9F,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,EAAE,0CAA0C,CAAC,CAAC;AACnH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uEAAuE,EAAE,GAAG,EAAE;IACjF,MAAM,UAAU,GAAG,qBAAqB,CAAC,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAC5E,MAAM,CAAC,EAAE,CAAC,UAAU,YAAY,KAAK,CAAC,CAAC;IACvC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,oBAAoB,CAAC,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;AAC5F,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"npm-install-error.test.js","sourceRoot":"","sources":["../../src/utils/npm-install-error.test.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "0.0.117",
3
+ "version": "0.0.118",
4
4
  "platform": "win32",
5
5
  "arch": "x64",
6
6
  "fileName": "agentrunner-launcher.exe",
7
- "sha256": "43d2b6bb1a1aa370c04f7482a8acf8ba10c3f10c5074f54db55363763c35d998"
7
+ "sha256": "7401e89ce20c10a249e042e894a022f2c4e5fb5bea0230477026f00803c55a12"
8
8
  }
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@agentteams/runner",
3
- "version": "0.0.117",
3
+ "version": "0.0.118",
4
4
  "description": "AgentRunner - Background runner that polls and executes AI agent tasks",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
8
- "agentrunner": "dist/index.js"
8
+ "agentrunner": "dist/index.js",
9
+ "agr": "dist/index.js"
9
10
  },
10
11
  "files": [
11
12
  "dist/**/*",
package/readme.md CHANGED
@@ -23,6 +23,18 @@ Verify the installation:
23
23
  agentrunner --help
24
24
  ```
25
25
 
26
+ ### Short alias (`agr`)
27
+
28
+ `agentrunner` is also installed as `agr`. The canonical name keeps working — the alias is an addition, not a replacement.
29
+
30
+ ```bash
31
+ agr --help # same as: agentrunner --help
32
+ ```
33
+
34
+ - The alias symlink is created at install time. If you installed an earlier version, rerun `npm install -g @agentteams/runner` to get it.
35
+ - Use the alias only when you type commands yourself. Autostart entries, scripts, and agent guides should keep using `agentrunner`, which exists in every environment.
36
+ - Usage text echoes the alias only where npm installs bins as symlinks (POSIX). Windows `.cmd`/`.ps1` shims and pnpm global installs are shell wrappers, so `agr --help` still prints `Usage: agentrunner ...` there. Running the alias itself works everywhere.
37
+
26
38
  ## Quick Start
27
39
 
28
40
  ### 1. Initialize
@@ -213,9 +225,9 @@ For a release smoke test on a disposable Windows test machine:
213
225
 
214
226
  ## Troubleshooting
215
227
 
216
- ### `Missing token. Usage: agentrunner init --token <token> ...`
228
+ ### `Missing token. Usage: ... init --token <token> ...`
217
229
 
218
- The `--token` flag was not provided to `init`.
230
+ The `--token` flag was not provided to `init`. The usage line names whichever executable you ran, so it reads `agentrunner init ...` or `agr init ...`.
219
231
 
220
232
  ### `Daemon token is missing. Run 'agentrunner init --token <token>' first.`
221
233