@mobileaidev/ai-app-bridge 0.3.3 → 0.3.4
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 +2 -2
- package/bin/runtime-client.js +5 -1
- package/bin/runtime-directory.js +3 -1
- package/bin/shared-kernel/executable-path.js +26 -0
- package/docs/COMMAND_CONTRACT.md +5 -0
- package/docs/RELEASE.md +16 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ discovery. Every request checks the mapping before dispatch. Mutating requests
|
|
|
7
7
|
are never replayed after a missing route or uncertain result. For manual cleanup,
|
|
8
8
|
pass the exact serial and returned Host port to `remove-forward`.
|
|
9
9
|
|
|
10
|
-
This release is `0.3.
|
|
10
|
+
This release is `0.3.4`, distributed through the npm `latest` dist-tag.
|
|
11
11
|
The default installation includes the Script/Intent and capture contracts below.
|
|
12
12
|
The `next` dist-tag also points to this release until a newer candidate is published.
|
|
13
13
|
The supported Node range is `>=26.3.0 <27`; this release was checked on 26.3.0.
|
|
@@ -56,7 +56,7 @@ domains, commands, and options, then call `run` with the selected command.
|
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
58
|
# Install the current stable release; see docs/RELEASE.md for packaging.
|
|
59
|
-
npm install -g @mobileaidev/ai-app-bridge@0.3.
|
|
59
|
+
npm install -g @mobileaidev/ai-app-bridge@0.3.4
|
|
60
60
|
|
|
61
61
|
ai-app-bridge status --package-name io.github.mobileaidev.aiappbridge.sample
|
|
62
62
|
ai-app-bridge tree --package-name io.github.mobileaidev.aiappbridge.sample
|
package/bin/runtime-client.js
CHANGED
|
@@ -8,6 +8,7 @@ const { CommandError, commandFailure } = require('./command-errors');
|
|
|
8
8
|
const { validateRunRequest } = require('./command-request');
|
|
9
9
|
const { protocol, maxMessageBytes, readJson, decodeReply } = require('./runtime-protocol');
|
|
10
10
|
const { runtimeLocation, runtimeIdentity, acquireRuntimeLock, readEndpoint, prepareDirectory } = require('./runtime-directory');
|
|
11
|
+
const { executablePath } = require('./shared-kernel/executable-path');
|
|
11
12
|
const starting = new Map();
|
|
12
13
|
|
|
13
14
|
// Transport failures do not retry execution or cancel its owner. Once the
|
|
@@ -75,9 +76,12 @@ function launch(location) {
|
|
|
75
76
|
const log = fs.openSync(location.logFile, 'a', 0o600);
|
|
76
77
|
let child;
|
|
77
78
|
try {
|
|
79
|
+
// Pin the provider chosen by this client before requests change cwd. Other
|
|
80
|
+
// clients may reach the same executable through a different PATH or alias.
|
|
81
|
+
const adb = executablePath(process.env.ADB || 'adb');
|
|
78
82
|
child = fork(path.join(__dirname, 'execution-runtime.js'), [], {
|
|
79
83
|
detached: true, execArgv: [], stdio: ['ignore', log, log, 'ipc'],
|
|
80
|
-
env: { ...process.env, AI_APP_BRIDGE_FACT_STORE_DIR: location.facts },
|
|
84
|
+
env: { ...process.env, ...(adb ? { ADB: adb } : {}), AI_APP_BRIDGE_FACT_STORE_DIR: location.facts },
|
|
81
85
|
});
|
|
82
86
|
} finally { fs.closeSync(log); }
|
|
83
87
|
return new Promise((resolve, reject) => {
|
package/bin/runtime-directory.js
CHANGED
|
@@ -9,6 +9,7 @@ const { hostFactStoreTarget } = require('./shared-kernel/host-fact-store');
|
|
|
9
9
|
const { defaultDirectory: ownershipDirectory } = require('./shared-kernel/device-ownership-store');
|
|
10
10
|
const { protocol } = require('./runtime-protocol');
|
|
11
11
|
const { canonicalPath } = require('./shared-kernel/canonical-path');
|
|
12
|
+
const { executablePath } = require('./shared-kernel/executable-path');
|
|
12
13
|
|
|
13
14
|
let fingerprint;
|
|
14
15
|
function codeFingerprint() {
|
|
@@ -49,9 +50,10 @@ function runtimeLocation() {
|
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
function runtimeIdentity(location = runtimeLocation()) {
|
|
52
|
-
const names = ['
|
|
53
|
+
const names = ['AI_APP_BRIDGE_ADB_TIMEOUT_MS', 'AI_APP_BRIDGE_DEVICECTL', 'AI_APP_BRIDGE_FACT_CACHE',
|
|
53
54
|
'AI_APP_BRIDGE_IOS_TEAM_ID', 'AI_APP_BRIDGE_PYTHON', 'ANDROID_HOME', 'ANDROID_SDK_ROOT', 'DEVELOPMENT_TEAM', 'DEVELOPER_DIR', 'XCODEBUILD'];
|
|
54
55
|
const config = { facts: location.facts, profile: location.profile, ownership: canonicalPath(ownershipDirectory()),
|
|
56
|
+
adb: executablePath(process.env.ADB || 'adb') ?? { unavailable: process.env.ADB || 'adb' },
|
|
55
57
|
environment: Object.fromEntries(names.map(name => [name, process.env[name] ?? null])) };
|
|
56
58
|
return { protocol, code: codeFingerprint(), config: createHash('sha256').update(JSON.stringify(config)).digest('hex') };
|
|
57
59
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
|
|
6
|
+
// Match direct executable lookup, without invoking a shell or running the tool.
|
|
7
|
+
// An unavailable optional provider must not prevent Web or iOS runtime startup.
|
|
8
|
+
function executablePath(command, { env = process.env, cwd = process.cwd() } = {}) {
|
|
9
|
+
const explicit = command.includes('/') || (process.platform === 'win32' && command.includes('\\'));
|
|
10
|
+
const directories = explicit ? [''] : (env.PATH ?? '/usr/bin:/bin').split(path.delimiter);
|
|
11
|
+
const extensions = process.platform === 'win32' ? ['', '.exe', '.com'] : [''];
|
|
12
|
+
for (const directory of directories) {
|
|
13
|
+
for (const extension of extensions) {
|
|
14
|
+
const candidate = path.resolve(cwd, directory, command + extension);
|
|
15
|
+
try {
|
|
16
|
+
fs.accessSync(candidate, fs.constants.X_OK);
|
|
17
|
+
if (fs.statSync(candidate).isFile()) return fs.realpathSync(candidate);
|
|
18
|
+
} catch (error) {
|
|
19
|
+
if (!['ENOENT', 'ENOTDIR', 'EACCES'].includes(error.code)) throw error;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = { executablePath };
|
package/docs/COMMAND_CONTRACT.md
CHANGED
|
@@ -73,6 +73,11 @@ only after proving the lock is free and before dispatching any command.
|
|
|
73
73
|
Code, bundled runtime artifacts, native-store binary, Node version, FactStore
|
|
74
74
|
profile and provider configuration must match the owner. Mismatch rejects
|
|
75
75
|
execution with `runtime_code_mismatch` or `runtime_configuration_mismatch`.
|
|
76
|
+
ADB is compared by its resolved executable path: automatic PATH lookup, an
|
|
77
|
+
explicit path and symlinks to the same executable share the same configuration.
|
|
78
|
+
Startup pins that executable for subsequent requests; selecting a different ADB
|
|
79
|
+
still requires an explicit runtime stop. Missing ADB does not block capabilities
|
|
80
|
+
that do not use it.
|
|
76
81
|
`runtime status` reports the owner and compatibility; explicit `runtime stop`
|
|
77
82
|
remains available from a different build/configuration. An unresponsive owner
|
|
78
83
|
returns `runtime_unresponsive` without killing or replacing it. Lost execution
|
package/docs/RELEASE.md
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
# 0.3.
|
|
1
|
+
# 0.3.4 发行与接入交接
|
|
2
2
|
|
|
3
3
|
本文件记录正式版的依赖关系和出仓库交付入口。封版要求是同一提交的源码、发行包与公开接入合同一致;单个样本的测试进度不改变包版本或发布状态。推送 Git、创建远端标签及发布 npm/pub 包由维护者执行。
|
|
4
4
|
|
|
5
|
-
## 0.3.
|
|
5
|
+
## 0.3.4 变更
|
|
6
|
+
|
|
7
|
+
- CLI 和 MCP 按实际解析后的 ADB 可执行文件判断共享 Runtime 配置;PATH 查找、绝对路径和符号链接指向同一文件时可共享。启动时固定解析路径;不同可执行文件仍拒绝混用,缺少 ADB 不阻塞无设备依赖的能力。
|
|
8
|
+
- 同步全部发行渠道版本;SDK 的设备行为与 0.3.3 相同。
|
|
9
|
+
|
|
10
|
+
## 随本版包含的 0.3.3 修复
|
|
6
11
|
|
|
7
12
|
- Native 观察按当前 Activity 的窗口组选择节点,保留 Dialog/Popup;修复返回和前进时 Activity 与节点不一致。
|
|
8
13
|
- Android 安装与执行校验实际探测 standalone、toybox、busybox 的 SHA-256;保留完整性校验,不要求固定 PATH 命令。
|
|
@@ -15,12 +20,12 @@
|
|
|
15
20
|
|
|
16
21
|
| 交付物 | 发行版本 | 独立消费入口 | 发布依赖 |
|
|
17
22
|
| --- | --- | --- | --- |
|
|
18
|
-
| Android SDK | `0.3.
|
|
19
|
-
| Android Gradle 插件 | `0.3.
|
|
20
|
-
| 原生 iOS SDK | Git tag `0.3.
|
|
21
|
-
| Flutter 插件 | `0.3.
|
|
22
|
-
| Desktop CLI/MCP | `0.3.
|
|
23
|
-
| Web SDK | `0.3.
|
|
23
|
+
| Android SDK | `0.3.4` | JitPack `com.github.mobileAiDev.ai-app-bridge:ai-app-bridge-android:0.3.4` | 同名 Git tag,JitPack 对该提交成功构建 |
|
|
24
|
+
| Android Gradle 插件 | `0.3.4` | JitPack `ai-app-bridge-gradle-plugin` 模块及插件 ID `io.github.mobileaidev.aiappbridge.android` | 与 SDK 相同的 Git tag;不再使用旧默认 `0.2.8` |
|
|
25
|
+
| 原生 iOS SDK | Git tag `0.3.4` | Git URL 的仓库根 `Package.swift`,产品 `AiAppBridgeIOS` | 根清单包含 Swift runtime、C adapter 和 segmented C store,无外部 C 包路径 |
|
|
26
|
+
| Flutter 插件 | `0.3.4` | pub `ai_app_bridge_flutter` | Android 固定依赖上述 SDK;iOS Swift/C 源码随插件分发 |
|
|
27
|
+
| Desktop CLI/MCP | `0.3.4` | npm `@mobileaidev/ai-app-bridge` | 包含 UIA bundle、WDA 模板和 native store 源码;WDA 上游固定 `14.1.1` |
|
|
28
|
+
| Web SDK | `0.3.4` | npm `@mobileaidev/ai-app-bridge-web` | 独立浏览器源码包,无 npm 对 CLI 的安装依赖 |
|
|
24
29
|
| Native store | `0.1.0` | 随 CLI 的 bundled dependency 安装 | 不要求另行发布到 npm;`file:../../native/segmented-fact-store` 是工作区构建入口,最终 tarball 必须包含该依赖源码 |
|
|
25
30
|
|
|
26
31
|
Flutter 的 podspec 是随 pub 插件消费的本地 podspec,不是独立 CocoaPods trunk 发布包;原生 iOS 使用根 Swift package。Flutter SwiftPM 的 `../FlutterFramework` 由 Flutter 的集成生成,不能当作本仓库的外部私有依赖,也不应将本机 Flutter framework 打包进插件。
|
|
@@ -29,11 +34,11 @@ Host 支持范围声明为 Node `>=26.3.0 <27`,本轮实际验证基线是 **2
|
|
|
29
34
|
|
|
30
35
|
## 发布顺序
|
|
31
36
|
|
|
32
|
-
1. 完成源码审阅并冻结一个提交,核对以下命令的产物确实来自它;包含当前 untracked 的实际源码、测试和文档,排除本机生成目录。所有对外发行版本使用同一个 `0.3.
|
|
33
|
-
2. 维护者推送提交与 `0.3.
|
|
37
|
+
1. 完成源码审阅并冻结一个提交,核对以下命令的产物确实来自它;包含当前 untracked 的实际源码、测试和文档,排除本机生成目录。所有对外发行版本使用同一个 `0.3.4`,若需要改版本,先同时更新上表涉及的 manifest 与固定依赖。
|
|
38
|
+
2. 维护者推送提交与 `0.3.4` 标签,让 JitPack 构建 Android SDK/插件。确认两条公开坐标可解析后,再发布依赖它们的 Flutter 包。本地 Gradle project/path/AAR 替换不能证明 JitPack 坐标可消费。
|
|
34
39
|
3. 原生 iOS 消费相同 Git tag 的根 package;完成根 package 的 iOS 构建,不仅构建 `ios/ai-app-bridge-ios/Package.swift`。Flutter iOS 则检查实际 pub 包内 Swift/C 源码与声明相符。
|
|
35
40
|
4. CLI 与 Web SDK 可分别发布到 npm 的 `latest` dist-tag。CLI 的 native store 已打包随行,不等待一个不存在的单独 registry 依赖。Flutter 包发布以第 2 步完成为前提。
|
|
36
|
-
5. 同步 npm `next` 指向 `0.3.
|
|
41
|
+
5. 同步 npm `next` 指向 `0.3.4`,让已有候选入口也使用本次正式版。将 GitHub `main` 与发行提交同步,并创建非预发布的 GitHub Release。
|
|
37
42
|
6. 从 registry/tag 安装刚发布的确切版本,读取 `capabilities` 和版本,核对来源及支持范围,确认默认安装入口指向本次发行版本。正式发布不自动等于全平台生产验收完成。
|
|
38
43
|
|
|
39
44
|
正式发布命令需在对应目录由维护者执行,例如 npm 使用 `npm publish --tag latest`;pub 使用 `flutter pub publish`。这些命令属于发布动作,不能混入本地验证脚本。
|
package/package.json
CHANGED