@hagicode/hagiscript 0.1.0 → 0.1.3

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
@@ -94,16 +94,20 @@ Reason: missing executable
94
94
 
95
95
  ### npm Global Package Synchronization
96
96
 
97
- `npm-sync` aligns npm global packages inside an explicit Node.js runtime with a JSON manifest. It always uses the `npm` executable resolved from `--runtime`; it does not use or mutate npm from the ambient shell `PATH`.
97
+ `npm-sync` aligns npm global packages inside a HagiScript-managed Node.js runtime with a JSON manifest. By default, it verifies or installs the managed runtime at `~/.hagiscript/node-runtime` and uses that runtime's `npm`; it does not use or mutate npm from the ambient shell `PATH`. Existing automation can keep passing `--runtime` to use an explicit runtime directory.
98
98
 
99
99
  ```bash
100
+ hagiscript npm-sync --manifest ./manifest.json
100
101
  hagiscript npm-sync --runtime /opt/hagiscript/node --manifest ./manifest.json
102
+ hagiscript npm-sync --manifest ./manifest.json --registry-mirror https://registry.npmmirror.com/
103
+ hagiscript npm-sync --manifest ./manifest.json --registry-mirror https://registry.npmmirror.com/ --mirror-only
101
104
  ```
102
105
 
103
- Manifest schema:
106
+ Compatibility manifest schema:
104
107
 
105
108
  ```json
106
109
  {
110
+ "registryMirror": "https://registry.npmmirror.com/",
107
111
  "packages": {
108
112
  "<npm-package-name>": {
109
113
  "version": "<semver range>",
@@ -115,6 +119,39 @@ Manifest schema:
115
119
 
116
120
  The required `version` field accepts package.json-style semver ranges such as `^1.2.0`, `>=1.0.0 <2.0.0`, or `1.0.0 || 2.0.0`. The optional `target` field controls the selector used for `npm install -g`; when omitted, Hagiscript installs `<package>@<version>`.
117
121
 
122
+ The optional top-level `registryMirror` field configures the npm registry used for both inventory and install commands. It must be a non-empty absolute `http:` or `https:` URL. When present, HagiScript first appends `--registry <registryMirror>` to `npm list -g --depth=0 --json` and `npm install -g <package>@<selector>` without changing package selection. If that mirror-backed npm command fails, HagiScript automatically retries the same inventory or install command once against the official npm registry `https://registry.npmjs.org/`. This mirror-first retry scope is intentionally limited to npm inventory and package mutation commands; runtime validation, manifest validation, and package planning do not retry. This is useful for public mirrors such as `https://registry.npmmirror.com/` or enterprise registries such as `https://npm.company.example/repository/npm/`.
123
+
124
+ Product-managed tool sync can use the expanded `tools` manifest shape. Mandatory tools are always included using internally pinned versions from `src/runtime/tool-sync-catalog.config.json`: OpenSpec skills (`skills@1.5.1`), OmniRoute (`omniroute@3.6.9`), and code-server (`code-server@4.117.0`). Optional agent CLI sync is enabled explicitly; selected built-in CLIs or custom npm packages are added when provided.
125
+
126
+ ```json
127
+ {
128
+ "registryMirror": "https://npm.company.example/repository/npm/",
129
+ "tools": {
130
+ "optionalAgentCliSyncEnabled": true,
131
+ "selectedOptionalAgentCliIds": ["codex", "claude-code", "fission-openspec", "opencode"],
132
+ "customAgentClis": [
133
+ {
134
+ "packageName": "@scope/agent-cli",
135
+ "version": "^1.0.0"
136
+ }
137
+ ]
138
+ }
139
+ }
140
+ ```
141
+
142
+ The first built-in optional agent CLI IDs are `codex` (`@openai/codex@0.125.0`), `claude-code` (`@anthropic-ai/claude-code@2.1.119`), `fission-openspec` (`@fission-ai/openspec@1.3.1`), `qoder` (`@qoder-ai/qodercli@0.1.48`), and `opencode` (`opencode-ai@1.14.24`). These built-in package versions are pinned in `src/runtime/tool-sync-catalog.config.json`. HagiScript validates unknown tool IDs, npm package names, and version selectors before `npm list` or `npm install` runs.
143
+
144
+ Use `--registry-mirror <url>` when automation needs to override the manifest registry for a single run. Precedence is CLI override first, manifest `registryMirror` second, and npm's default registry behavior third. If neither the CLI nor manifest provides a mirror, HagiScript does not add `--registry` and existing npm defaults, `.npmrc`, or environment configuration continue to apply.
145
+
146
+ Use `--mirror-only` when a run must stay on the configured mirror and must not retry against `https://registry.npmjs.org/`. When omitted, automatic official-registry fallback remains enabled by default for mirror-backed npm inventory and install commands.
147
+
148
+ For simple product-managed requests, optional CLI selections can be provided directly without writing a manifest:
149
+
150
+ ```bash
151
+ hagiscript npm-sync --selected-agent-cli codex
152
+ hagiscript npm-sync --selected-agent-cli codex --custom-agent-cli @scope/agent-cli@^1.0.0
153
+ ```
154
+
118
155
  Example manifest for openspec and skills tooling:
119
156
 
120
157
  ```json
@@ -136,7 +173,9 @@ During execution, Hagiscript validates the manifest and runtime before any npm i
136
173
  Example output:
137
174
 
138
175
  ```text
139
- Manifest validated: ./manifest.json (2 packages)
176
+ Manifest validated: ./manifest.json (2 packages, mode=packages)
177
+ Registry mirror: https://registry.npmmirror.com/
178
+ Fallback policy: auto
140
179
  Runtime validated: /opt/hagiscript/node
141
180
  node: /opt/hagiscript/node/bin/node (v22.12.0)
142
181
  npm: /opt/hagiscript/node/bin/npm (10.9.0)
@@ -149,11 +188,17 @@ Synced: @hagicode/skills (upgrade)
149
188
  npm-sync complete.
150
189
  Runtime: /opt/hagiscript/node
151
190
  Manifest: ./manifest.json
191
+ Mode: packages
192
+ Registry mirror: https://registry.npmmirror.com/
193
+ Fallback policy: auto
194
+ Fallback used: no
152
195
  Packages: 2
153
196
  No-op: 1
154
197
  Changed: 1
155
198
  ```
156
199
 
200
+ When fallback is triggered, HagiScript logs `Fallback used: ...` during execution and records `Fallback detail: ...` in the final summary so CI or desktop automation can see which mirror failed, which official registry retry was used, and whether that retry succeeded.
201
+
157
202
  Use the library API from ESM consumers:
158
203
 
159
204
  ```ts
@@ -207,9 +252,17 @@ The package `exports` field points consumers to `dist/index.js` and `dist/index.
207
252
 
208
253
  GitHub Actions provide three automation paths:
209
254
 
210
- - `ci.yml` installs dependencies with `npm ci`, then runs lint, format check, tests, build, and package verification.
211
- - `npm-publish.yml` publishes a unique prerelease version to the `dev` dist-tag from `main`.
212
- - `npm-publish.yml` also publishes stable GitHub releases tagged as `vX.Y.Z` to the `latest` dist-tag after validating the tag against `package.json`.
255
+ - `ci.yml` installs dependencies with `npm ci`, then runs tests, build, and package verification.
256
+ - `npm-publish.yml` resolves a unique prerelease version from `main`, stamps both `package.json` and `package-lock.json` with `npm version --no-git-tag-version`, then publishes to the `dev` dist-tag.
257
+ - `npm-publish.yml` also publishes stable GitHub releases tagged as `vX.Y.Z` to the `latest` dist-tag after validating the tag format, rejecting tags older than the repository base version, and stamping the stable version the same way.
213
258
  - `release-drafter.yml` keeps a categorized release draft using `.github/release-drafter.yml`.
214
259
 
215
- Before the first publish, make sure the npm organization `hagicode` exists and grant publish access for `@hagicode/hagiscript`. For GitHub Actions releases, configure npm trusted publishing. For local manual releases, run plain `npm publish`.
260
+ Before the first publish, make sure the npm organization or user scope `hagicode` exists on npm and grant publish access for `@hagicode/hagiscript`. For GitHub Actions releases, configure npm trusted publishing with package `@hagicode/hagiscript`, owner `HagiCode-org`, repository `hagiscript`, and workflow filename `npm-publish.yml`. Do not enter the full workflow path as the filename; leave the npm environment field empty unless the workflow job explicitly declares an environment. If the scope is missing or the workflow identity cannot create packages under it, npm returns `E404 Not Found` during the final `PUT https://registry.npmjs.org/@hagicode%2fhagiscript` publish request.
261
+
262
+ Run the publish prerequisite check before retrying a failed release:
263
+
264
+ ```bash
265
+ npm run publish:check-prereqs
266
+ ```
267
+
268
+ For local manual releases, run plain `npm publish` after logging in with an npm account that can publish under `@hagicode`.
package/README_cn.md CHANGED
@@ -94,13 +94,16 @@ Reason: missing executable
94
94
 
95
95
  ### npm 全局包同步
96
96
 
97
- `npm-sync` 会根据 JSON manifest,把指定 Node.js 运行时中的 npm 全局包版本同步到约束范围内。它始终使用 `--runtime` 解析出的 `npm` 可执行文件,不会使用或修改当前 shell `PATH` 中的 npm
97
+ `npm-sync` 会根据 JSON manifest,把 HagiScript 托管 Node.js 运行时中的 npm 全局包版本同步到约束范围内。默认情况下,它会验证或安装 `~/.hagiscript/node-runtime`,并使用该运行时内的 `npm`;它不会使用或修改当前 shell `PATH` 中的 npm。已有自动化仍可继续传入 `--runtime` 使用显式运行时目录。
98
98
 
99
99
  ```bash
100
+ hagiscript npm-sync --manifest ./manifest.json
100
101
  hagiscript npm-sync --runtime /opt/hagiscript/node --manifest ./manifest.json
102
+ hagiscript npm-sync --manifest ./manifest.json --registry-mirror https://registry.npmmirror.com/
103
+ hagiscript npm-sync --manifest ./manifest.json --registry-mirror https://registry.npmmirror.com/ --mirror-only
101
104
  ```
102
105
 
103
- Manifest 结构:
106
+ 兼容模式 manifest 结构:
104
107
 
105
108
  ```json
106
109
  {
@@ -115,6 +118,38 @@ Manifest 结构:
115
118
 
116
119
  必填的 `version` 字段使用 package.json 风格的 semver 范围,例如 `^1.2.0`、`>=1.0.0 <2.0.0` 或 `1.0.0 || 2.0.0`。可选的 `target` 字段用于指定实际执行 `npm install -g` 时使用的选择器;如果省略,Hagiscript 会安装 `<package>@<version>`。
117
120
 
121
+ 可选的顶层 `registryMirror` 字段用于指定 npm 检测与安装命令所使用的镜像地址,必须是非空的绝对 `http:` 或 `https:` URL。配置后,Hagiscript 会先对 `npm list -g --depth=0 --json` 和 `npm install -g <package>@<selector>` 追加 `--registry <registryMirror>` 并优先走镜像;如果镜像对应的 npm 命令失败,则会把同一条 inventory 或 install 命令自动重试一次到官方源 `https://registry.npmjs.org/`。这个自动降级只作用于 npm inventory 与包变更命令,不会重试运行时校验、manifest 校验或同步计划计算。
122
+
123
+ 产品托管的工具同步可使用扩展后的 `tools` manifest。必选工具始终会按 `src/runtime/tool-sync-catalog.config.json` 中的内部固定版本纳入同步:OpenSpec skills(`skills@1.5.1`)、OmniRoute(`omniroute@3.6.9`)和 code-server(`code-server@4.117.0`)。可选 agent CLI 同步需要显式启用;如果传入内置 CLI 或自定义 npm 包选择,它们会被加入同步。
124
+
125
+ ```json
126
+ {
127
+ "tools": {
128
+ "optionalAgentCliSyncEnabled": true,
129
+ "selectedOptionalAgentCliIds": ["codex", "claude-code", "fission-openspec", "opencode"],
130
+ "customAgentClis": [
131
+ {
132
+ "packageName": "@scope/agent-cli",
133
+ "version": "^1.0.0"
134
+ }
135
+ ]
136
+ }
137
+ }
138
+ ```
139
+
140
+ 首批内置可选 agent CLI ID 为 `codex`(`@openai/codex@0.125.0`)、`claude-code`(`@anthropic-ai/claude-code@2.1.119`)、`fission-openspec`(`@fission-ai/openspec@1.3.1`)、`qoder`(`@qoder-ai/qodercli@0.1.48`)和 `opencode`(`opencode-ai@1.14.24`)。这些内置包版本固定在 `src/runtime/tool-sync-catalog.config.json` 中。HagiScript 会在执行 `npm list` 或 `npm install` 前校验未知工具 ID、npm 包名和版本选择器。
141
+
142
+ 使用 `--registry-mirror <url>` 可以在单次运行中覆盖 manifest 中的镜像地址,优先级依次为 CLI 覆盖、manifest 的 `registryMirror`、以及 npm 默认注册表行为。如果 CLI 与 manifest 都没有提供镜像,Hagiscript 就不会附加 `--registry`,现有的 npm 默认设置、`.npmrc` 或环境变量行为会保持不变。
143
+
144
+ 如果某次同步必须严格停留在镜像源且不能自动切回官方源,请添加 `--mirror-only`。省略该选项时,只要配置了镜像,Hagiscript 默认就会在镜像失败后自动回退到 `https://registry.npmjs.org/` 一次。
145
+
146
+ 简单的产品托管请求也可以直接通过 CLI 选项传入可选 CLI,而不必先写 manifest:
147
+
148
+ ```bash
149
+ hagiscript npm-sync --selected-agent-cli codex
150
+ hagiscript npm-sync --selected-agent-cli codex --custom-agent-cli @scope/agent-cli@^1.0.0
151
+ ```
152
+
118
153
  openspec 和 skills 工具同步示例:
119
154
 
120
155
  ```json
@@ -136,7 +171,9 @@ openspec 和 skills 工具同步示例:
136
171
  输出示例:
137
172
 
138
173
  ```text
139
- Manifest validated: ./manifest.json (2 packages)
174
+ Manifest validated: ./manifest.json (2 packages, mode=packages)
175
+ Registry mirror: https://registry.npmmirror.com/
176
+ Fallback policy: auto
140
177
  Runtime validated: /opt/hagiscript/node
141
178
  node: /opt/hagiscript/node/bin/node (v22.12.0)
142
179
  npm: /opt/hagiscript/node/bin/npm (10.9.0)
@@ -149,11 +186,17 @@ Synced: @hagicode/skills (upgrade)
149
186
  npm-sync complete.
150
187
  Runtime: /opt/hagiscript/node
151
188
  Manifest: ./manifest.json
189
+ Mode: packages
190
+ Registry mirror: https://registry.npmmirror.com/
191
+ Fallback policy: auto
192
+ Fallback used: no
152
193
  Packages: 2
153
194
  No-op: 1
154
195
  Changed: 1
155
196
  ```
156
197
 
198
+ 如果触发了回退,Hagiscript 会在执行期间输出 `Fallback used: ...`,并在最终摘要中记录 `Fallback detail: ...`,这样 CI 或桌面端自动化就能明确知道哪个镜像失败了、是否切到了官方源,以及官方源重试是否成功。
199
+
157
200
  在 ESM 项目中使用库 API:
158
201
 
159
202
  ```ts
@@ -207,9 +250,17 @@ npm run publish:verify-release -- v0.1.0
207
250
 
208
251
  GitHub Actions 提供三类自动化流程:
209
252
 
210
- - `ci.yml` 使用 `npm ci` 安装依赖,并执行 lint、格式检查、测试、构建和包内容校验。
211
- - `npm-publish.yml` 在 `main` 分支发布唯一预发布版本到 `dev` dist-tag。
212
- - `npm-publish.yml` 也会在非草稿、非 prerelease 的 GitHub Release 发布时,校验 `vX.Y.Z` 标签并发布到 `latest` dist-tag。
253
+ - `ci.yml` 使用 `npm ci` 安装依赖,并执行测试、构建和包内容校验。
254
+ - `npm-publish.yml` 在 `main` 分支解析唯一预发布版本,用 `npm version --no-git-tag-version` 同步 `package.json` 和 `package-lock.json`,再发布到 `dev` dist-tag。
255
+ - `npm-publish.yml` 也会在非草稿、非 prerelease 的 GitHub Release 发布时,校验 `vX.Y.Z` 标签格式,拒绝早于仓库基础版本的标签,并用同样方式写入稳定版本再发布到 `latest` dist-tag。
213
256
  - `release-drafter.yml` 通过 `.github/release-drafter.yml` 维护分类清晰的发布草稿。
214
257
 
215
- 首次发布前,需要先确保 npm 组织 `hagicode` 已存在,并且 `@hagicode/hagiscript` 已授权当前发布主体。GitHub Actions 发布时再配置 trusted publishing;本地手动发布时直接执行普通 `npm publish` 即可。
258
+ 首次发布前,需要先确保 npm 上已经存在组织或用户 scope `hagicode`,并且 `@hagicode/hagiscript` 已授权当前发布主体。GitHub Actions 发布时,需要在 npm trusted publishing 中配置:package `@hagicode/hagiscript`、owner `HagiCode-org`、repository `hagiscript`、workflow filename `npm-publish.yml`。不要把 workflow filename 填成完整路径;如果 npm 表单有 environment 字段,除非 workflow job 显式声明了 environment,否则保持为空。如果 scope 不存在,或 workflow 身份无权在该 scope 下创建包,npm 会在最后的 `PUT https://registry.npmjs.org/@hagicode%2fhagiscript` 发布请求中返回 `E404 Not Found`。
259
+
260
+ 重试失败的发布前,先运行发布前置检查:
261
+
262
+ ```bash
263
+ npm run publish:check-prereqs
264
+ ```
265
+
266
+ 本地手动发布时,先登录一个有权发布到 `@hagicode` scope 的 npm 账号,再直接执行普通 `npm publish`。
package/dist/cli.d.ts CHANGED
@@ -2,3 +2,4 @@
2
2
  import { Command } from "commander";
3
3
  export declare function createCli(): Command;
4
4
  export declare function runCli(argv?: string[]): Promise<void>;
5
+ export declare function isCliEntrypoint(moduleUrl?: string, argvPath?: string): boolean;
package/dist/cli.js CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env node
2
+ import { realpathSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
2
4
  import { Command } from "commander";
3
5
  import { createRuntimeInfo, packageVersion } from "./index.js";
4
6
  import { registerNpmSyncCommand } from "./commands/npm-sync-commands.js";
@@ -27,7 +29,18 @@ export async function runCli(argv = process.argv) {
27
29
  const program = createCli();
28
30
  await program.parseAsync(argv);
29
31
  }
30
- if (import.meta.url === `file://${process.argv[1]}`) {
32
+ export function isCliEntrypoint(moduleUrl = import.meta.url, argvPath = process.argv[1]) {
33
+ if (!argvPath) {
34
+ return false;
35
+ }
36
+ try {
37
+ return realpathSync(fileURLToPath(moduleUrl)) === realpathSync(argvPath);
38
+ }
39
+ catch {
40
+ return false;
41
+ }
42
+ }
43
+ if (isCliEntrypoint()) {
31
44
  runCli().catch((error) => {
32
45
  const message = error instanceof Error ? error.message : String(error);
33
46
  process.stderr.write(`${message}\n`);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAElF,MAAM,UAAU,SAAS;IACvB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,YAAY,CAAC;SAClB,WAAW,CAAC,6CAA6C,CAAC;SAC1D,OAAO,CAAC,cAAc,EAAE,eAAe,EAAE,8BAA8B,CAAC,CAAC;IAE5E,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,mCAAmC,CAAC;SAChD,MAAM,CAAC,GAAG,EAAE;QACX,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;QACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEL,2BAA2B,CAAC,OAAO,CAAC,CAAC;IACrC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAEhC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE;QAClB,OAAO,CAAC,UAAU,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI;IAC9C,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;IAC5B,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpD,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QAChC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACrC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAElF,MAAM,UAAU,SAAS;IACvB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,YAAY,CAAC;SAClB,WAAW,CAAC,6CAA6C,CAAC;SAC1D,OAAO,CAAC,cAAc,EAAE,eAAe,EAAE,8BAA8B,CAAC,CAAC;IAE5E,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,mCAAmC,CAAC;SAChD,MAAM,CAAC,GAAG,EAAE;QACX,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;QACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEL,2BAA2B,CAAC,OAAO,CAAC,CAAC;IACrC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAEhC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE;QAClB,OAAO,CAAC,UAAU,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI;IAC9C,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;IAC5B,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAC3B,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAE1B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,KAAK,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,IAAI,eAAe,EAAE,EAAE,CAAC;IACtB,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QAChC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACrC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1,18 +1,49 @@
1
1
  import { InvalidArgumentError } from "commander";
2
- import { NpmManifestValidationError, NpmSyncCommandError, syncNpmGlobals } from "../runtime/npm-sync.js";
2
+ import { mkdtemp, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { getDefaultManagedNodeRuntimeDirectory, resolveManagedNodeRuntime } from "../runtime/node-installer.js";
6
+ import { NpmManifestValidationError, NpmSyncCommandError, syncNpmGlobals, validateRegistryMirror } from "../runtime/npm-sync.js";
3
7
  export function registerNpmSyncCommand(program) {
4
8
  program
5
9
  .command("npm-sync")
6
- .description("sync npm global packages in an explicit Node.js runtime")
7
- .requiredOption("--runtime <path>", "target Node.js runtime directory")
8
- .requiredOption("--manifest <path>", "npm-sync manifest JSON file")
10
+ .description("sync managed npm tools using HagiScript's Node.js runtime, or an explicit runtime for compatibility")
11
+ .option("--runtime <path>", "explicit Node.js runtime directory")
12
+ .option("--managed-runtime <path>", "HagiScript-managed runtime directory to verify or install before sync")
13
+ .option("--manifest <path>", "npm-sync manifest JSON file")
14
+ .option("--registry-mirror <url>", "npm registry mirror URL to use for this sync run")
15
+ .option("--mirror-only", "disable automatic retry against https://registry.npmjs.org/ when a registry mirror is configured")
16
+ .option("--selected-agent-cli <id>", "selected optional agent CLI ID for product-managed tool sync", collectValues, [])
17
+ .option("--custom-agent-cli <package[@version]>", "custom npm-installable agent CLI for product-managed tool sync", collectValues, [])
9
18
  .action(async (options, command) => {
10
- const runtimePath = validatePathOption(options.runtime, "--runtime");
11
- const manifestPath = validatePathOption(options.manifest, "--manifest");
19
+ const explicitRuntime = options.runtime
20
+ ? validatePathOption(options.runtime, "--runtime")
21
+ : undefined;
22
+ const registryMirror = validateRegistryMirror(options.registryMirror, "--registry-mirror");
23
+ const selectedAgentCliIds = options.selectedAgentCli ?? [];
24
+ const customAgentCliSelectors = options.customAgentCli ?? [];
25
+ const hasInlineToolSelection = selectedAgentCliIds.length > 0 || customAgentCliSelectors.length > 0;
26
+ const manifestPath = options.manifest
27
+ ? validatePathOption(options.manifest, "--manifest")
28
+ : hasInlineToolSelection
29
+ ? await writeInlineToolManifest(selectedAgentCliIds, customAgentCliSelectors)
30
+ : undefined;
31
+ if (!manifestPath) {
32
+ throw new InvalidArgumentError("--manifest is required unless --selected-agent-cli or --custom-agent-cli is provided.");
33
+ }
34
+ const managedRuntimePath = options.managedRuntime
35
+ ? validatePathOption(options.managedRuntime, "--managed-runtime")
36
+ : getDefaultManagedNodeRuntimeDirectory();
12
37
  try {
38
+ const runtimePath = explicitRuntime ?? (await resolveManagedNodeRuntime({
39
+ targetDirectory: managedRuntimePath
40
+ })).targetDirectory;
41
+ const fallbackPolicy = options.mirrorOnly ? "mirror-only" : "auto";
13
42
  await syncNpmGlobals({
14
43
  runtimePath,
15
44
  manifestPath,
45
+ registryMirror,
46
+ fallbackPolicy,
16
47
  onLog: printNpmSyncLog
17
48
  });
18
49
  }
@@ -21,6 +52,37 @@ export function registerNpmSyncCommand(program) {
21
52
  }
22
53
  });
23
54
  }
55
+ function collectValues(value, previous) {
56
+ return [...previous, value];
57
+ }
58
+ async function writeInlineToolManifest(selectedAgentCliIds, customAgentCliSelectors) {
59
+ const directory = await mkdtemp(join(tmpdir(), "hagiscript-tool-sync-"));
60
+ const manifestPath = join(directory, "manifest.json");
61
+ await writeFile(manifestPath, JSON.stringify({
62
+ tools: {
63
+ optionalAgentCliSyncEnabled: true,
64
+ selectedOptionalAgentCliIds: selectedAgentCliIds,
65
+ customAgentClis: customAgentCliSelectors.map(parseCustomAgentCli)
66
+ }
67
+ }, null, 2));
68
+ return manifestPath;
69
+ }
70
+ function parseCustomAgentCli(selector) {
71
+ const trimmed = selector.trim();
72
+ const versionSeparator = trimmed.startsWith("@")
73
+ ? trimmed.indexOf("@", 1)
74
+ : trimmed.indexOf("@");
75
+ if (versionSeparator <= 0) {
76
+ return { packageName: trimmed };
77
+ }
78
+ const packageName = trimmed.slice(0, versionSeparator);
79
+ const version = trimmed.slice(versionSeparator + 1);
80
+ return {
81
+ packageName,
82
+ version,
83
+ target: version
84
+ };
85
+ }
24
86
  function validatePathOption(value, optionName) {
25
87
  const normalized = value?.trim();
26
88
  if (!normalized) {
@@ -34,7 +96,19 @@ function validatePathOption(value, optionName) {
34
96
  function printNpmSyncLog(event) {
35
97
  switch (event.type) {
36
98
  case "manifest-loaded":
37
- process.stdout.write(`Manifest validated: ${event.manifestPath} (${event.packageCount} packages)\n`);
99
+ process.stdout.write(`Manifest validated: ${event.manifestPath} (${event.packageCount} packages, mode=${event.syncMode})\n`);
100
+ if (event.registryMirror) {
101
+ process.stdout.write(`Registry mirror: ${event.registryMirror}\n`);
102
+ }
103
+ break;
104
+ case "fallback-policy":
105
+ process.stdout.write(`Fallback policy: ${event.fallbackPolicy}\n`);
106
+ break;
107
+ case "fallback-used":
108
+ process.stdout.write(`Fallback used: ${formatFallbackEvent(event.fallback)}\n`);
109
+ break;
110
+ case "mirror-only":
111
+ process.stdout.write(`Mirror-only: official registry fallback disabled for ${event.registryMirror}\n`);
38
112
  break;
39
113
  case "runtime-valid":
40
114
  process.stdout.write(`Runtime validated: ${event.runtime.targetDirectory}\n`);
@@ -45,7 +119,7 @@ function printNpmSyncLog(event) {
45
119
  process.stdout.write(`Detected global packages: ${Object.keys(event.packages).sort().length}\n`);
46
120
  break;
47
121
  case "planned-action":
48
- process.stdout.write(`Plan: ${event.action.packageName} ${event.action.action} installed=${event.action.installedVersion ?? "missing"} required=${event.action.requiredRange} selector=${event.action.selectedInstallSelector}\n`);
122
+ process.stdout.write(`Plan: ${event.action.packageName} ${event.action.action} installed=${event.action.installedVersion ?? "missing"} required=${event.action.requiredRange} selector=${event.action.selectedInstallSelector}${formatToolMetadata(event.action)}\n`);
49
123
  break;
50
124
  case "skip":
51
125
  process.stdout.write(`Skip: ${event.action.packageName} already satisfies range\n`);
@@ -65,10 +139,31 @@ function printSummary(summary) {
65
139
  process.stdout.write(`npm-sync complete.\n`);
66
140
  process.stdout.write(`Runtime: ${summary.runtime.targetDirectory}\n`);
67
141
  process.stdout.write(`Manifest: ${summary.manifestPath}\n`);
142
+ process.stdout.write(`Mode: ${summary.syncMode}\n`);
143
+ if (summary.registryMirror) {
144
+ process.stdout.write(`Registry mirror: ${summary.registryMirror}\n`);
145
+ process.stdout.write(`Fallback policy: ${summary.fallbackPolicy}\n`);
146
+ process.stdout.write(`Fallback used: ${summary.fallbackUsed ? "yes" : "no"}\n`);
147
+ for (const fallback of summary.fallbackEvents) {
148
+ process.stdout.write(`Fallback detail: ${formatFallbackEvent(fallback)}\n`);
149
+ }
150
+ }
68
151
  process.stdout.write(`Packages: ${summary.packageCount}\n`);
69
152
  process.stdout.write(`No-op: ${summary.noopCount}\n`);
70
153
  process.stdout.write(`Changed: ${summary.changedCount}\n`);
71
154
  }
155
+ function formatFallbackEvent(fallback) {
156
+ const packageSegment = fallback.packageName
157
+ ? ` package=${fallback.packageName}`
158
+ : "";
159
+ return `${fallback.commandKind}${packageSegment} mirror=${fallback.mirrorRegistry} fallback=${fallback.fallbackRegistry} success=${fallback.retrySucceeded}`;
160
+ }
161
+ function formatToolMetadata(action) {
162
+ if (!action.toolId) {
163
+ return "";
164
+ }
165
+ return ` tool=${action.toolId} group=${action.toolGroup ?? "unknown"}`;
166
+ }
72
167
  function formatNpmSyncError(error) {
73
168
  if (error instanceof NpmManifestValidationError) {
74
169
  return error.message;
@@ -78,12 +173,42 @@ function formatNpmSyncError(error) {
78
173
  if (error.packageName) {
79
174
  lines.push(`Package: ${error.packageName}`);
80
175
  }
81
- lines.push(`Command: ${error.command} ${error.args.join(" ")}`);
82
- if (error.stderr.trim().length > 0) {
83
- lines.push(`stderr: ${error.stderr.trim()}`);
176
+ if (error.registryMirror) {
177
+ lines.push(`Registry mirror: ${error.registryMirror}`);
178
+ lines.push(`Fallback policy: ${error.fallbackPolicy}`);
179
+ if (error.fallbackPolicy === "mirror-only") {
180
+ lines.push("Mirror-only: official registry fallback disabled.");
181
+ }
182
+ }
183
+ if (error.fallbackAttempted && error.fallbackRegistry) {
184
+ lines.push(`Fallback registry: ${error.fallbackRegistry}`);
185
+ }
186
+ if (error.mirrorContext) {
187
+ lines.push(`Mirror command: ${error.mirrorContext.command} ${error.mirrorContext.args.join(" ")}`);
188
+ if (error.mirrorContext.stderr.trim().length > 0) {
189
+ lines.push(`mirror stderr: ${error.mirrorContext.stderr.trim()}`);
190
+ }
191
+ if (error.mirrorContext.stdout.trim().length > 0) {
192
+ lines.push(`mirror stdout: ${error.mirrorContext.stdout.trim()}`);
193
+ }
194
+ }
195
+ if (error.officialContext) {
196
+ lines.push(`Official retry command: ${error.officialContext.command} ${error.officialContext.args.join(" ")}`);
197
+ if (error.officialContext.stderr.trim().length > 0) {
198
+ lines.push(`official stderr: ${error.officialContext.stderr.trim()}`);
199
+ }
200
+ if (error.officialContext.stdout.trim().length > 0) {
201
+ lines.push(`official stdout: ${error.officialContext.stdout.trim()}`);
202
+ }
84
203
  }
85
- if (error.stdout.trim().length > 0) {
86
- lines.push(`stdout: ${error.stdout.trim()}`);
204
+ if (!error.mirrorContext && !error.officialContext) {
205
+ lines.push(`Command: ${error.command} ${error.args.join(" ")}`);
206
+ if (error.stderr.trim().length > 0) {
207
+ lines.push(`stderr: ${error.stderr.trim()}`);
208
+ }
209
+ if (error.stdout.trim().length > 0) {
210
+ lines.push(`stdout: ${error.stdout.trim()}`);
211
+ }
87
212
  }
88
213
  return lines.join("\n");
89
214
  }
@@ -1 +1 @@
1
- {"version":3,"file":"npm-sync-commands.js","sourceRoot":"","sources":["../../src/commands/npm-sync-commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"npm-sync-commands.js","sourceRoot":"","sources":["../../src/commands/npm-sync-commands.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export interface HagiscriptRuntimeInfo {
5
5
  status: "foundation";
6
6
  }
7
7
  export declare function createRuntimeInfo(): HagiscriptRuntimeInfo;
8
- export { installNodeRuntime, type InstallNodeRuntimeResult } from "./runtime/node-installer.js";
8
+ export { getDefaultManagedNodeRuntimeDirectory, installNodeRuntime, resolveManagedNodeRuntime, type InstallNodeRuntimeResult, type ResolveManagedNodeRuntimeResult } from "./runtime/node-installer.js";
9
9
  export { verifyNodeRuntime, type NodeRuntimeVerificationResult } from "./runtime/node-verify.js";
10
- export { createNpmSyncPlan, loadNpmSyncManifest, normalizeGlobalInventory, syncNpmGlobals, validateNpmSyncManifest, type InstalledGlobalPackages, type NpmSyncActionKind, type NpmSyncActionResult, type NpmSyncManifest, type NpmSyncManifestEntry, type NpmSyncPlannedAction, type NpmSyncRuntimeMetadata, type NpmSyncSummary } from "./runtime/npm-sync.js";
10
+ export { createNpmSyncPlan, loadNpmSyncManifest, normalizeGlobalInventory, syncNpmGlobals, validateNpmSyncManifest, type InstalledGlobalPackages, type NpmSyncActionKind, type NpmSyncActionResult, type NpmSyncCommandKind, type NpmSyncFallbackEvent, type NpmSyncFallbackPolicy, type NpmSyncManifest, type NpmSyncManifestEntry, type NpmSyncPlannedAction, type NpmSyncRuntimeMetadata, type NpmSyncSummary } from "./runtime/npm-sync.js";
11
+ export { buildToolSyncPackageSet, builtInToolSyncCatalog, normalizeToolSyncEntry, validateToolSyncCatalog, type CustomAgentCliToolInput, type ToolSyncCatalogEntry, type ToolSyncGroupId, type ToolSyncPackageConstraint, type ToolSyncRequirement, type ToolSyncSelection } from "./runtime/tool-sync-catalog.js";
package/dist/index.js CHANGED
@@ -7,7 +7,8 @@ export function createRuntimeInfo() {
7
7
  status: "foundation"
8
8
  };
9
9
  }
10
- export { installNodeRuntime } from "./runtime/node-installer.js";
10
+ export { getDefaultManagedNodeRuntimeDirectory, installNodeRuntime, resolveManagedNodeRuntime } from "./runtime/node-installer.js";
11
11
  export { verifyNodeRuntime } from "./runtime/node-verify.js";
12
12
  export { createNpmSyncPlan, loadNpmSyncManifest, normalizeGlobalInventory, syncNpmGlobals, validateNpmSyncManifest } from "./runtime/npm-sync.js";
13
+ export { buildToolSyncPackageSet, builtInToolSyncCatalog, normalizeToolSyncEntry, validateToolSyncCatalog } from "./runtime/tool-sync-catalog.js";
13
14
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,cAAc,EAEf,MAAM,cAAc,CAAC;AAQtB,MAAM,UAAU,iBAAiB;IAC/B,OAAO;QACL,WAAW;QACX,OAAO,EAAE,cAAc;QACvB,MAAM,EAAE,YAAY;KACrB,CAAC;AACJ,CAAC;AAED,OAAO,EACL,kBAAkB,EAEnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,iBAAiB,EAElB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,cAAc,EACd,uBAAuB,EASxB,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,cAAc,EAEf,MAAM,cAAc,CAAC;AAQtB,MAAM,UAAU,iBAAiB;IAC/B,OAAO;QACL,WAAW;QACX,OAAO,EAAE,cAAc;QACvB,MAAM,EAAE,YAAY;KACrB,CAAC;AACJ,CAAC;AAED,OAAO,EACL,qCAAqC,EACrC,kBAAkB,EAClB,yBAAyB,EAG1B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,iBAAiB,EAElB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,cAAc,EACd,uBAAuB,EAYxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EAOxB,MAAM,gCAAgC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { type DownloadProgress } from "./node-download.js";
2
+ import { verifyNodeRuntime } from "./node-verify.js";
2
3
  export interface InstallNodeRuntimeOptions {
3
4
  targetDirectory: string;
4
5
  versionSelector?: string;
@@ -7,6 +8,16 @@ export interface InstallNodeRuntimeOptions {
7
8
  verifyTimeoutMs?: number;
8
9
  onProgress?: (progress: DownloadProgress) => void;
9
10
  }
11
+ export interface ResolveManagedNodeRuntimeOptions {
12
+ targetDirectory?: string;
13
+ versionSelector?: string;
14
+ fetchImpl?: typeof fetch;
15
+ downloadTimeoutMs?: number;
16
+ verifyTimeoutMs?: number;
17
+ verifyRuntime?: typeof verifyNodeRuntime;
18
+ installRuntime?: typeof installNodeRuntime;
19
+ onProgress?: (progress: DownloadProgress) => void;
20
+ }
10
21
  export interface InstallNodeRuntimeResult {
11
22
  version: string;
12
23
  npmVersion: string;
@@ -15,4 +26,14 @@ export interface InstallNodeRuntimeResult {
15
26
  npmPath: string;
16
27
  archiveUrl: string;
17
28
  }
29
+ export interface ResolveManagedNodeRuntimeResult {
30
+ targetDirectory: string;
31
+ nodePath: string;
32
+ npmPath: string;
33
+ nodeVersion: string;
34
+ npmVersion: string;
35
+ installed: boolean;
36
+ }
37
+ export declare function getDefaultManagedNodeRuntimeDirectory(): string;
38
+ export declare function resolveManagedNodeRuntime(options?: ResolveManagedNodeRuntimeOptions): Promise<ResolveManagedNodeRuntimeResult>;
18
39
  export declare function installNodeRuntime(options: InstallNodeRuntimeOptions): Promise<InstallNodeRuntimeResult>;
@@ -1,10 +1,38 @@
1
1
  import { mkdtemp, rm } from "node:fs/promises";
2
2
  import { dirname, join, resolve } from "node:path";
3
+ import { homedir } from "node:os";
3
4
  import { assertTargetIsEmptyOrMissing, extractNodeArchive, moveExtractedRootToTarget } from "./node-extract.js";
4
5
  import { downloadNodeArchive } from "./node-download.js";
5
6
  import { fetchNodeReleaseMetadata, selectNodeArchive } from "./node-release.js";
6
7
  import { mapNodePlatform } from "./node-platform.js";
7
8
  import { getRuntimeExecutablePaths, verifyNodeRuntime } from "./node-verify.js";
9
+ export function getDefaultManagedNodeRuntimeDirectory() {
10
+ return join(homedir(), ".hagiscript", "node-runtime");
11
+ }
12
+ export async function resolveManagedNodeRuntime(options = {}) {
13
+ const targetDirectory = resolve(options.targetDirectory ?? getDefaultManagedNodeRuntimeDirectory());
14
+ const verifyRuntime = options.verifyRuntime ?? verifyNodeRuntime;
15
+ const initialVerification = await verifyRuntime(targetDirectory, {
16
+ timeoutMs: options.verifyTimeoutMs
17
+ });
18
+ if (initialVerification.valid) {
19
+ return toResolvedRuntime(initialVerification, false);
20
+ }
21
+ const installRuntime = options.installRuntime ?? installNodeRuntime;
22
+ await installRuntime({
23
+ targetDirectory,
24
+ versionSelector: options.versionSelector,
25
+ fetchImpl: options.fetchImpl,
26
+ downloadTimeoutMs: options.downloadTimeoutMs,
27
+ verifyTimeoutMs: options.verifyTimeoutMs,
28
+ onProgress: options.onProgress
29
+ });
30
+ const finalVerification = await verifyRuntime(targetDirectory, {
31
+ timeoutMs: options.verifyTimeoutMs
32
+ });
33
+ assertValidVerification(finalVerification);
34
+ return toResolvedRuntime(finalVerification, true);
35
+ }
8
36
  export async function installNodeRuntime(options) {
9
37
  const targetDirectory = resolve(options.targetDirectory);
10
38
  await assertTargetIsEmptyOrMissing(targetDirectory);
@@ -43,4 +71,15 @@ function assertValidVerification(verification) {
43
71
  throw new Error(`Installed Node.js runtime failed verification: ${verification.failureReason ?? "unknown failure"}`);
44
72
  }
45
73
  }
74
+ function toResolvedRuntime(verification, installed) {
75
+ assertValidVerification(verification);
76
+ return {
77
+ targetDirectory: verification.targetDirectory,
78
+ nodePath: verification.nodePath,
79
+ npmPath: verification.npmPath,
80
+ nodeVersion: verification.nodeVersion,
81
+ npmVersion: verification.npmVersion,
82
+ installed
83
+ };
84
+ }
46
85
  //# sourceMappingURL=node-installer.js.map