@x-otto/install 0.0.1-alpha.5 → 0.0.1-alpha.7
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 +21 -15
- package/dist/index.d.ts +45 -35
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -8
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -13,39 +13,45 @@ pnpm add @x-otto/install
|
|
|
13
13
|
## Usage
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
const manager = new InstallManager()
|
|
16
|
+
import { install } from '@x-otto/install'
|
|
19
17
|
|
|
20
18
|
// Install a skill from a local .tgz archive
|
|
21
|
-
const result = await
|
|
19
|
+
const result = await install('./my-skill.tgz', {
|
|
22
20
|
workspaceDir: '/path/to/project',
|
|
23
21
|
onProgress: (p) => console.log(`[${p.phase}] ${p.message}`),
|
|
24
22
|
})
|
|
25
23
|
|
|
26
24
|
// Install a plugin from npm
|
|
27
|
-
const pluginResult = await
|
|
25
|
+
const pluginResult = await install('@scope/my-plugin', {
|
|
28
26
|
global: true,
|
|
29
27
|
})
|
|
30
28
|
|
|
31
|
-
// Install an MCP server from a git repo tag
|
|
32
|
-
const mcpResult = await
|
|
33
|
-
|
|
34
|
-
env: { API_KEY: 'xxx' },
|
|
35
|
-
|
|
29
|
+
// Install an MCP server from a git repo tag (MCP needs settings accessors)
|
|
30
|
+
const mcpResult = await install(
|
|
31
|
+
'https://github.com/user/mcp-server.git',
|
|
32
|
+
{ ref: 'v1.2.0', env: { API_KEY: 'xxx' } },
|
|
33
|
+
() => readMcpSettings(),
|
|
34
|
+
(servers) => persistMcpSettings(servers),
|
|
35
|
+
)
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
`install()` auto-detects the source type (file/url/git/npm) and content type (skill/plugin/mcp). Use `as` to override auto-detection:
|
|
39
39
|
|
|
40
40
|
```typescript
|
|
41
41
|
// Force treat content as plugin even if auto-detect might guess skill
|
|
42
|
-
await
|
|
42
|
+
await install('./dir', { as: 'plugin' })
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
> **Note (endgame review 2026-08-14):** `install` is a pure function — it replaced the
|
|
46
|
+
> stateless `InstallManager` class (which held no instance state, so `new InstallManager()`
|
|
47
|
+
> was an empty shell). MCP settings access is injected via the optional `getMcpSettings` /
|
|
48
|
+
> `persistMcpSettings` callbacks; single-install semantics stay in `options`.
|
|
49
|
+
|
|
45
50
|
## Key Exports
|
|
46
51
|
|
|
47
52
|
### Installation
|
|
48
|
-
- `
|
|
53
|
+
- `install()` — Top-level orchestrator (auto-detect source + content, dispatch to installer)
|
|
54
|
+
- `installSkill()` — Convenience wrapper forcing `as: 'skill'`
|
|
49
55
|
- `InstallOptions` — Workspace, scope, force, dry-run, sub-path, ref, progress callbacks
|
|
50
56
|
- `InstallResult` — Success status, target path, definition/manifest, warnings, pending capabilities
|
|
51
57
|
|
|
@@ -70,8 +76,8 @@ await manager.install('./dir', { as: 'plugin' })
|
|
|
70
76
|
|
|
71
77
|
## Dependencies
|
|
72
78
|
|
|
73
|
-
- **Internal**: `@x-otto/mcp`, `@x-otto/plugin`, `@x-otto/skill`, `@x-otto/shared`
|
|
74
|
-
- **External**: `zod`, Node.js built-ins (fs, path, os, child_process)
|
|
79
|
+
- **Internal**: `@x-otto/env`, `@x-otto/mcp`, `@x-otto/plugin`, `@x-otto/skill`, `@x-otto/shared`
|
|
80
|
+
- **External**: `semver`, `zod`, Node.js built-ins (fs, path, os, child_process)
|
|
75
81
|
|
|
76
82
|
## Related
|
|
77
83
|
|
package/dist/index.d.ts
CHANGED
|
@@ -154,30 +154,30 @@ interface InstallOptions {
|
|
|
154
154
|
//#endregion
|
|
155
155
|
//#region src/installer.d.ts
|
|
156
156
|
/**
|
|
157
|
-
*
|
|
157
|
+
* install — 安装编排入口(自动检测来源类型和内容类型)。
|
|
158
158
|
*
|
|
159
159
|
* 支持四种来源 × 三种内容类型。
|
|
160
160
|
* 来源:file(本地归档)、url(HTTP 下载)、git(浅克隆)、npm(npm pack)
|
|
161
161
|
* 内容:skill、plugin、mcp
|
|
162
162
|
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
163
|
+
* **形态(终局 review 2026-08-14 P1-1)**:此前是 `class InstallManager`,但该类零实例状态
|
|
164
|
+
* (无 logger/fetchImpl/配置持有),CLI 侧每次 `new InstallManager()` 都是空壳——类壳只是形式
|
|
165
|
+
* 化封装,无语义价值。降级为纯函数:单次安装语义走 `options`,MCP settings 访问经 `getMcpSettings`
|
|
166
|
+
* /`persistMcpSettings` 回调注入(本就是参数)。未引入 logger/fetchImpl/timeout 的 deps bag——
|
|
167
|
+
* 那三者当前无任何消费方(logger 在 url-resolver 硬编码、fetchImpl 仅 RegistryClient 用、timeout
|
|
168
|
+
* 已由 env var 覆盖),凭空造 bag 即为抽象而抽象。真需要时再随消费方一起引入。
|
|
169
|
+
*
|
|
170
|
+
* **阶段归属(RFC-286 D4)**:只负责 resolve / detect / write 三段,只 fire
|
|
171
|
+
* `resolving` / `detecting` / `installing`。**不 fire `refreshing`**——该阶段语义是「能力热重载」,
|
|
172
|
+
* 真实动作 `App.reloadCapabilities()` 由 CLI 侧持有,install 包无 App 句柄。谁执行谁上报:
|
|
173
|
+
* `refreshing` 由 `handlers/install.ts` 在调用真实 reload 前 fire。`ProgressPhase` 类型保留
|
|
174
|
+
* `'refreshing'` 取值供 CLI 使用。
|
|
170
175
|
*/
|
|
171
|
-
declare
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* 安装 skill 包(兼容旧 API)。
|
|
178
|
-
*/
|
|
179
|
-
installSkill(source: string, options: InstallOptions): Promise<InstallResult>;
|
|
180
|
-
}
|
|
176
|
+
declare function install(source: string, options: InstallOptions, getMcpSettings?: () => Record<string, unknown> | undefined, persistMcpSettings?: (servers: Record<string, unknown>) => Promise<void>): Promise<InstallResult>;
|
|
177
|
+
/**
|
|
178
|
+
* 安装 skill 包(便捷入口:强制 `as: 'skill'`)。
|
|
179
|
+
*/
|
|
180
|
+
declare function installSkill(source: string, options: InstallOptions): Promise<InstallResult>;
|
|
181
181
|
//#endregion
|
|
182
182
|
//#region src/uninstaller.d.ts
|
|
183
183
|
type UninstallTarget = 'skill' | 'plugin' | 'mcp';
|
|
@@ -192,6 +192,13 @@ interface UninstallResult {
|
|
|
192
192
|
error?: string;
|
|
193
193
|
/** dry-run 预览 */
|
|
194
194
|
plan?: string[];
|
|
195
|
+
/**
|
|
196
|
+
* 非阻断告警(RFC-354 安全修复):卸载成功但存在需用户知晓的残留风险。
|
|
197
|
+
* 典型:信任记录撤销失败——目录已删但信任白名单/能力授权可能残留,
|
|
198
|
+
* 重装同 id 插件到同一路径时旧授权会复活(fail-open)。撤销失败不阻断目录删除
|
|
199
|
+
* (删除是用户明确意图),但必须可见而非静默吞掉。
|
|
200
|
+
*/
|
|
201
|
+
warnings?: string[];
|
|
195
202
|
}
|
|
196
203
|
interface InstalledItem {
|
|
197
204
|
name: string;
|
|
@@ -233,7 +240,7 @@ declare function listInstalledItems(options: ListInstalledOptions, mcpServers?:
|
|
|
233
240
|
* @param name 扩展名称
|
|
234
241
|
* @param type 扩展类型(由 detectUninstallTarget 提供)
|
|
235
242
|
* @param options 卸载选项
|
|
236
|
-
* @param
|
|
243
|
+
* @param getMcpServers 读取当前 mcp_servers 配置(仅 mcp 类型需要)
|
|
237
244
|
* @param persistSettings 持久化 settings(仅 mcp 类型需要)
|
|
238
245
|
*/
|
|
239
246
|
declare function uninstall(name: string, type: UninstallTarget, options: UninstallOptions, getMcpServers?: () => Record<string, unknown> | undefined, persistSettings?: (servers: Record<string, unknown>) => Promise<void>): Promise<UninstallResult>;
|
|
@@ -295,8 +302,12 @@ interface GitUpgradeCheckResult {
|
|
|
295
302
|
/**
|
|
296
303
|
* 检查 git 来源 skill/plugin 是否有更新。
|
|
297
304
|
* 扫描 baseDir 下所有子目录的 .otto-install.json → git ls-remote → 比较 hash。
|
|
305
|
+
*
|
|
306
|
+
* 异步化(终局 review 2026-08-14 P1-3):此前用 `spawnSync` 同步阻塞事件循环做
|
|
307
|
+
* 网络 `git ls-remote`——N 个 git 来源项串行最长阻塞 N×10s,TUI 环境冻结整个界面。
|
|
308
|
+
* 改为经包内共享 `spawnAsync`(与 git-resolver 同源),签名 `sync → async`。
|
|
298
309
|
*/
|
|
299
|
-
declare function checkGitUpgrades(baseDir: string, type: 'skill' | 'plugin'): GitUpgradeCheckResult[]
|
|
310
|
+
declare function checkGitUpgrades(baseDir: string, type: 'skill' | 'plugin'): Promise<GitUpgradeCheckResult[]>;
|
|
300
311
|
//#endregion
|
|
301
312
|
//#region src/archive-utils.d.ts
|
|
302
313
|
/**
|
|
@@ -2392,6 +2403,12 @@ interface LoadedRegistry extends ParsedRegistry {
|
|
|
2392
2403
|
}
|
|
2393
2404
|
/** 官方源缺省条目(url 由调用方装配注入——发布形态未定期间指向仓内文件)。 */
|
|
2394
2405
|
declare function builtinOfficialSource(url: string): RegistrySourceConfig;
|
|
2406
|
+
/**
|
|
2407
|
+
* 2026-08-14 修订(用户指令):删除内网官方源(`otto-official-internal`)自动加载——
|
|
2408
|
+
* 原 RFC-341 G2 的 `OTTO_INTERNAL_REGISTRY_URL` + 内网可达探测机制整体退役,registry
|
|
2409
|
+
* 单一走官方源(GitHub Pages)+ 用户自添源。内网插件发现不再依赖 registry 分发,
|
|
2410
|
+
* 由插件自身的 install/装载链路负责(详见 RFC-341 修订记录)。
|
|
2411
|
+
*/
|
|
2395
2412
|
declare class RegistryClient {
|
|
2396
2413
|
private readonly options;
|
|
2397
2414
|
constructor(options: {
|
|
@@ -2402,20 +2419,13 @@ declare class RegistryClient {
|
|
|
2402
2419
|
});
|
|
2403
2420
|
private get registriesPath();
|
|
2404
2421
|
private get cacheDir();
|
|
2405
|
-
/** 读源清单(官方源恒在首位;用户文件坏/缺时退化为仅官方源)。不含内网源——同步场景
|
|
2406
|
-
* (如 `/registry remove` 参数补全)不该为一次可能的网络探测阻塞输入响应,见 `listSourcesAsync`。 */
|
|
2407
|
-
listSources(): RegistrySourceConfig[];
|
|
2408
2422
|
/**
|
|
2409
|
-
*
|
|
2410
|
-
* 首位,`otto-official-internal`(内网)紧随其后(仅内网可达 + `OTTO_INTERNAL_REGISTRY_URL`
|
|
2411
|
-
* 已配置时才出现),随后是用户自定义源。
|
|
2423
|
+
* 读源清单(官方源恒在首位;用户文件坏/缺时退化为仅官方源)。
|
|
2412
2424
|
*
|
|
2413
|
-
*
|
|
2414
|
-
*
|
|
2415
|
-
* 异步流程的场景改用它;纯同步场景(如参数补全建议器)继续用 `listSources()`,
|
|
2416
|
-
* 不因偶发探测延迟阻塞按键响应。
|
|
2425
|
+
* 2026-08-14 修订:原 RFC-341 G2 的内网官方源自动追加(`listSourcesAsync`)已随
|
|
2426
|
+
* 该特性整体退役删除——清单就是清单,不再含网络探测。
|
|
2417
2427
|
*/
|
|
2418
|
-
|
|
2428
|
+
listSources(): RegistrySourceConfig[];
|
|
2419
2429
|
addSource(name: string, url: string): void;
|
|
2420
2430
|
removeSource(name: string): void;
|
|
2421
2431
|
/**
|
|
@@ -2424,19 +2434,19 @@ declare class RegistryClient {
|
|
|
2424
2434
|
* - 第三方源:改写用户配置中该条目的 disabled 字段;条目不存在则抛错。
|
|
2425
2435
|
*/
|
|
2426
2436
|
setSourceEnabled(name: string, enabled: boolean): void;
|
|
2427
|
-
/** 拉取全部启用源(缓存优先 → fetch → 陈旧缓存降级)。坏源跳过并记 warning。
|
|
2428
|
-
* RFC-341 G2:内网可达时自动含内网官方源(`listSourcesAsync`),公网用户/公网环境
|
|
2429
|
-
* 不受影响(探测目标未配置时零网络请求、零延迟,见 `isIntranetReachable` doc)。 */
|
|
2437
|
+
/** 拉取全部启用源(缓存优先 → fetch → 陈旧缓存降级)。坏源跳过并记 warning。 */
|
|
2430
2438
|
loadAll(): Promise<{
|
|
2431
2439
|
registries: LoadedRegistry[];
|
|
2432
2440
|
warnings: string[];
|
|
2433
2441
|
}>;
|
|
2434
2442
|
private loadOne;
|
|
2443
|
+
/** 缓存优先 → fetch → 陈旧缓存降级(URL 源与 npm 包源共用)。 */
|
|
2444
|
+
private loadWithCache;
|
|
2435
2445
|
private readUserSources;
|
|
2436
2446
|
private writeUserSources;
|
|
2437
2447
|
private readCache;
|
|
2438
2448
|
private writeCache;
|
|
2439
2449
|
}
|
|
2440
2450
|
//#endregion
|
|
2441
|
-
export { type ContentType, type GitUpgradeCheckResult,
|
|
2451
|
+
export { type ContentType, type GitUpgradeCheckResult, type InstallOptions, type InstallProgress, type InstallResult, type InstallScope, type InstallSourceMetadata, type InstalledItem, type ListInstalledOptions, type LoadedRegistry, type ParsedRegistry, type PostInstallContext, type PostInstallResult, type ProgressPhase, type RegistriesFile, RegistryClient, type RegistryEntry, type RegistryEntryType, type RegistrySourceConfig, type ResolvedSource, type SourceType, type UninstallOptions, type UninstallResult, type UninstallTarget, type UpgradeCheckOptions, type UpgradeCheckResult, type VersionInfo, builtinOfficialSource, checkArchiveBomb, checkGitUpgrades, checkUpgrades, cleanTempDir, createArchive, createTempDir, detectUninstallTarget, extractArchive, install, installSkill, listInstalledItems, parseRegistry, registryEntrySchema, registryEntryTypeSchema, registrySchema, sanitizeSourceUrl, scanInstalledVersions, uninstall, validateExtractedPaths };
|
|
2442
2452
|
//# sourceMappingURL=index.d.ts.map
|