@mobileaidev/ai-app-bridge 0.2.15 → 0.3.0-rc.2
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/LICENSE +201 -0
- package/NOTICE +7 -0
- package/README.md +306 -53
- package/bin/ai-app-bridge.js +51 -4504
- package/bin/android-permissions.js +152 -0
- package/bin/android-uia-xml.js +74 -0
- package/bin/artifact-paths.js +127 -1
- package/bin/bridge-forward.js +56 -0
- package/bin/command-discovery.js +86 -0
- package/bin/command-errors.js +60 -0
- package/bin/command-registry.js +504 -0
- package/bin/command-request.js +14 -0
- package/bin/command-router.js +80 -0
- package/bin/connection-cache.js +119 -0
- package/bin/device-provider.js +2934 -0
- package/bin/execution-host.js +596 -0
- package/bin/execution-runtime.js +101 -0
- package/bin/fact-codec.js +321 -0
- package/bin/fact-recorder.js +691 -0
- package/bin/fact-store.js +226 -0
- package/bin/feedback-probe.js +285 -0
- package/bin/intent/install-intent.js +267 -0
- package/bin/intent/intent-action-executor.js +129 -0
- package/bin/intent/intent-autonomous-adapter.js +46 -0
- package/bin/intent/intent-capture-port.js +64 -0
- package/bin/intent/intent-entry.js +226 -0
- package/bin/intent/intent-errors.js +28 -0
- package/bin/intent/intent-evidence-store.js +121 -0
- package/bin/intent/intent-lifetime.js +62 -0
- package/bin/intent/intent-observation-target.js +33 -0
- package/bin/intent/intent-observer.js +194 -0
- package/bin/intent/intent-production-adapter.js +334 -0
- package/bin/intent/intent-provider.js +27 -0
- package/bin/intent/intent-runtime.js +63 -0
- package/bin/intent/intent-worker.js +432 -0
- package/bin/intent/ios-intent-adapter.js +90 -0
- package/bin/intent/permission-intent.js +239 -0
- package/bin/intent/web-intent-adapter.js +31 -0
- package/bin/ios-device-outcome.js +47 -0
- package/bin/ios-execution.js +108 -0
- package/bin/ios-provider.js +497 -583
- package/bin/ios-runtime-binding.js +54 -0
- package/bin/ios-wda-execution.js +70 -0
- package/bin/ios-wda-port.js +98 -0
- package/bin/ios-wda-project.js +79 -0
- package/bin/mcp-server.js +83 -1040
- package/bin/mmap-scan-index.js +329 -0
- package/bin/observation-collector.js +862 -0
- package/bin/runtime-client.js +154 -0
- package/bin/runtime-directory.js +107 -0
- package/bin/runtime-protocol.js +36 -0
- package/bin/script/bounded-script-registry.js +103 -0
- package/bin/script/node-runtime-adapter.js +233 -0
- package/bin/script/progress-projector.js +63 -0
- package/bin/script/python-runtime-adapter.js +111 -0
- package/bin/script/rolling-summary.js +134 -0
- package/bin/script/script-agent-port.js +40 -0
- package/bin/script/script-assert.js +95 -0
- package/bin/script/script-capture-port.js +76 -0
- package/bin/script/script-catalog.js +85 -0
- package/bin/script/script-durable-restore.js +195 -0
- package/bin/script/script-entry-code.js +26 -0
- package/bin/script/script-entry-route.js +38 -0
- package/bin/script/script-entry.js +3 -0
- package/bin/script/script-errors.js +29 -0
- package/bin/script/script-evidence-store.js +22 -0
- package/bin/script/script-format-removed.js +26 -0
- package/bin/script/script-host-port.js +397 -0
- package/bin/script/script-ledger.js +64 -0
- package/bin/script/script-result.js +57 -0
- package/bin/script/script-sdk.js +152 -0
- package/bin/script/script-sdk.py +153 -0
- package/bin/script/script-session-channel.js +127 -0
- package/bin/script/script-spec.js +86 -0
- package/bin/script/script-supervisor.js +919 -0
- package/bin/script/templates/checkpoint-reentry.js +13 -0
- package/bin/segment-index.js +481 -0
- package/bin/segmented-fact-store.js +1571 -0
- package/bin/shared-kernel/android-h5-target.js +10 -0
- package/bin/shared-kernel/android-install-execution.js +176 -0
- package/bin/shared-kernel/android-sdk-endpoint.js +42 -0
- package/bin/shared-kernel/android-shell-execution.js +195 -0
- package/bin/shared-kernel/argument-schema.js +117 -0
- package/bin/shared-kernel/canonical-path.js +17 -0
- package/bin/shared-kernel/device-acknowledgements.js +53 -0
- package/bin/shared-kernel/device-completion-history.js +52 -0
- package/bin/shared-kernel/device-mutation-lease.js +219 -0
- package/bin/shared-kernel/device-ownership-recovery.js +95 -0
- package/bin/shared-kernel/device-ownership-store.js +94 -0
- package/bin/shared-kernel/evidence-adapters.js +251 -0
- package/bin/shared-kernel/evidence-archive.js +329 -0
- package/bin/shared-kernel/evidence-recording.js +131 -0
- package/bin/shared-kernel/evidence-schema.js +194 -0
- package/bin/shared-kernel/evidence-store.js +190 -0
- package/bin/shared-kernel/execution-admission.js +22 -0
- package/bin/shared-kernel/execution-contracts.js +171 -0
- package/bin/shared-kernel/execution-io.js +106 -0
- package/bin/shared-kernel/execution-ledger.js +125 -0
- package/bin/shared-kernel/execution-scope.js +87 -0
- package/bin/shared-kernel/execution-target.js +115 -0
- package/bin/shared-kernel/flutter-execution.js +13 -0
- package/bin/shared-kernel/flutter-h5-port.js +60 -0
- package/bin/shared-kernel/flutter-h5-target.js +9 -0
- package/bin/shared-kernel/flutter-target.js +75 -0
- package/bin/shared-kernel/h5-execution.js +11 -0
- package/bin/shared-kernel/h5-target.js +31 -0
- package/bin/shared-kernel/host-fact-store.js +49 -0
- package/bin/shared-kernel/ios-h5-target.js +9 -0
- package/bin/shared-kernel/ios-native-target.js +71 -0
- package/bin/shared-kernel/live-capture-query.js +115 -0
- package/bin/shared-kernel/managed-sdk-execution.js +78 -0
- package/bin/shared-kernel/native-execution.js +13 -0
- package/bin/shared-kernel/native-target.js +156 -0
- package/bin/shared-kernel/provider-command-contracts.js +55 -0
- package/bin/shared-kernel/recorded-payload-archive.js +195 -0
- package/bin/shared-kernel/request-context.js +35 -0
- package/bin/shared-kernel/semantic-node.js +55 -0
- package/bin/shared-kernel/summary-transformer.js +352 -0
- package/bin/shared-kernel/target-lease-protocol.js +47 -0
- package/bin/shared-kernel/text-wait.js +111 -0
- package/bin/shared-kernel/uia-execution.js +96 -0
- package/bin/shared-kernel/uia-protocol.js +214 -0
- package/bin/shared-kernel/uia-runtime-port.js +377 -0
- package/bin/shared-kernel/uia-target.js +39 -0
- package/bin/shared-kernel/web-dom-target.js +44 -0
- package/bin/shared-kernel/xml-attributes.js +25 -0
- package/bin/target-execution.js +275 -0
- package/bin/web/command-schema.js +60 -0
- package/bin/web/session-store.js +157 -0
- package/bin/web-provider.js +334 -553
- package/docs/COMMAND_CONTRACT.md +1563 -0
- package/docs/EVIDENCE_ARCHIVE.md +214 -0
- package/docs/INTENT_FOREGROUND.md +71 -0
- package/docs/INTENT_NATIVE_EDITING.md +79 -0
- package/docs/RELEASE.md +59 -0
- package/docs/SCRIPT_AUTHORING.md +489 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/LICENSE +201 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/NOTICE +7 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/binding.gyp +36 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/bindings/node/sfs_node.c +597 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/include/sfs.h +178 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/index.js +5 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/package.json +24 -0
- package/node_modules/@mobileaidev/segmented-fact-store-native/src/sfs.c +2349 -0
- package/package.json +60 -5
- package/runtime/ios-wda/AABWDABinding.h +19 -0
- package/runtime/ios-wda/AABWDABinding.m +97 -0
- package/runtime/ios-wda/AABWDAExecution.h +26 -0
- package/runtime/ios-wda/AABWDAExecution.m +172 -0
- package/runtime/ios-wda/AABWDAIntegration.h +71 -0
- package/runtime/ios-wda/AABWDAManagedRoutes.h +392 -0
- package/runtime/ios-wda/AABWDAReceiptStore.h +10 -0
- package/runtime/ios-wda/AABWDAReceiptStore.m +116 -0
- package/runtime/uia/ai-app-bridge-uia.jar +0 -0
- package/runtime/uia/manifest.json +22 -0
- package/skills/ai-app-bridge-use/SKILL.md +23 -360
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { isolatedCommandDefinitions } = require('./command-registry');
|
|
4
|
+
const { commandFailure } = require('./command-errors');
|
|
5
|
+
|
|
6
|
+
function createCommandRouter({ loadScript, loadIntent, loadEvidence, dispatchCommon } = {}) {
|
|
7
|
+
if (typeof dispatchCommon !== 'function') {
|
|
8
|
+
throw new TypeError('dispatchCommon is required');
|
|
9
|
+
}
|
|
10
|
+
const loads = { script: 0, intent: 0, evidence: 0 };
|
|
11
|
+
return {
|
|
12
|
+
isolatedCommandDefinitions,
|
|
13
|
+
loads,
|
|
14
|
+
async route(command, args = {}, dependencies) {
|
|
15
|
+
if (command === 'script') {
|
|
16
|
+
return invokeIsolated('script', loadScript, args, loads);
|
|
17
|
+
}
|
|
18
|
+
if (command === 'intent') {
|
|
19
|
+
return invokeIsolated('intent', loadIntent, args, loads);
|
|
20
|
+
}
|
|
21
|
+
if (command === 'install-apk') {
|
|
22
|
+
return invokeIsolated('intent', loadIntent, { install: args, recordingDir: args.recordingDir }, loads);
|
|
23
|
+
}
|
|
24
|
+
if (command === 'permission-dialog') {
|
|
25
|
+
return invokeIsolated('intent', loadIntent, { permissionDialog: args, recordingDir: args.recordingDir }, loads);
|
|
26
|
+
}
|
|
27
|
+
if (command === 'evidence') {
|
|
28
|
+
return invokeIsolated('evidence', loadEvidence, args, loads);
|
|
29
|
+
}
|
|
30
|
+
return dispatchCommon(command, args, dependencies);
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function invokeIsolated(name, loader, args, loads) {
|
|
36
|
+
if (typeof loader !== 'function') {
|
|
37
|
+
return isolatedError(name, 'not_implemented');
|
|
38
|
+
}
|
|
39
|
+
loads[name] += 1;
|
|
40
|
+
let entry;
|
|
41
|
+
try {
|
|
42
|
+
entry = loader();
|
|
43
|
+
} catch (error) {
|
|
44
|
+
return isolatedError(name, 'isolated_module_unavailable', error.message || String(error));
|
|
45
|
+
}
|
|
46
|
+
if (!entry || typeof entry.handle !== 'function') {
|
|
47
|
+
return isolatedError(name, 'isolated_module_unavailable', 'entry handle is missing');
|
|
48
|
+
}
|
|
49
|
+
let handlePromise;
|
|
50
|
+
try {
|
|
51
|
+
handlePromise = Promise.resolve(entry.handle(args));
|
|
52
|
+
} catch (error) {
|
|
53
|
+
return { value: isolatedHandleError(name, error) };
|
|
54
|
+
}
|
|
55
|
+
// Stateful runtimes own cancellation and draining. An outer timer must not
|
|
56
|
+
// report a timeout while their work continues without supervision.
|
|
57
|
+
const result = await handlePromise.catch(error => isolatedHandleError(name, error));
|
|
58
|
+
return { value: result };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function isolatedHandleError(name, error) {
|
|
62
|
+
if (error?.code === 'sfs_busy') return { ok: false, error: 'fact_store_writer_busy', command: name, detail: error.message };
|
|
63
|
+
return commandFailure(error, name);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function isolatedError(command, error, detail) {
|
|
67
|
+
return {
|
|
68
|
+
value: {
|
|
69
|
+
ok: false,
|
|
70
|
+
error,
|
|
71
|
+
command,
|
|
72
|
+
...(detail ? { detail } : {}),
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = {
|
|
78
|
+
createCommandRouter,
|
|
79
|
+
isolatedCommandDefinitions,
|
|
80
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
class ConnectionCache {
|
|
4
|
+
constructor({ ttlMs = 15_000, maxEntries = 256, now = Date.now } = {}) {
|
|
5
|
+
if (!Number.isFinite(ttlMs) || ttlMs < 0) {
|
|
6
|
+
throw new TypeError('ttlMs must be a non-negative number');
|
|
7
|
+
}
|
|
8
|
+
if (typeof now !== 'function') {
|
|
9
|
+
throw new TypeError('now must be a function');
|
|
10
|
+
}
|
|
11
|
+
if (!Number.isInteger(maxEntries) || maxEntries < 1) {
|
|
12
|
+
throw new TypeError('maxEntries must be a positive integer');
|
|
13
|
+
}
|
|
14
|
+
this.ttlMs = ttlMs;
|
|
15
|
+
this.maxEntries = maxEntries;
|
|
16
|
+
this.now = now;
|
|
17
|
+
this.entries = new Map();
|
|
18
|
+
this.inflight = new Map();
|
|
19
|
+
this.generations = new Map();
|
|
20
|
+
this.nextGeneration = 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async getOrCreate(key, create, { force = false } = {}) {
|
|
24
|
+
if (typeof key !== 'string' || key.length === 0) {
|
|
25
|
+
throw new TypeError('key is required');
|
|
26
|
+
}
|
|
27
|
+
if (typeof create !== 'function') {
|
|
28
|
+
throw new TypeError('create must be a function');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
this.pruneEntries();
|
|
32
|
+
if (!force) {
|
|
33
|
+
const cached = this.entries.get(key);
|
|
34
|
+
if (cached && cached.expiresAtMs >= this.now()) {
|
|
35
|
+
this.entries.delete(key);
|
|
36
|
+
this.entries.set(key, cached);
|
|
37
|
+
return cached.value;
|
|
38
|
+
}
|
|
39
|
+
if (cached) this.entries.delete(key);
|
|
40
|
+
if (this.inflight.has(key)) return this.inflight.get(key);
|
|
41
|
+
} else {
|
|
42
|
+
this.entries.delete(key);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const generation = ++this.nextGeneration;
|
|
46
|
+
this.generations.set(key, generation);
|
|
47
|
+
const pending = Promise.resolve()
|
|
48
|
+
.then(create)
|
|
49
|
+
.then((value) => {
|
|
50
|
+
if (this.generations.get(key) === generation) {
|
|
51
|
+
this.entries.set(key, {
|
|
52
|
+
value,
|
|
53
|
+
expiresAtMs: this.now() + this.ttlMs,
|
|
54
|
+
});
|
|
55
|
+
this.pruneEntries();
|
|
56
|
+
}
|
|
57
|
+
return value;
|
|
58
|
+
})
|
|
59
|
+
.finally(() => {
|
|
60
|
+
if (this.inflight.get(key) === pending) {
|
|
61
|
+
this.inflight.delete(key);
|
|
62
|
+
}
|
|
63
|
+
if (
|
|
64
|
+
this.generations.get(key) === generation
|
|
65
|
+
&& !this.inflight.has(key)
|
|
66
|
+
&& !this.entries.has(key)
|
|
67
|
+
) {
|
|
68
|
+
this.generations.delete(key);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
this.inflight.set(key, pending);
|
|
72
|
+
return pending;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
has(key) {
|
|
76
|
+
this.pruneEntries();
|
|
77
|
+
const cached = this.entries.get(key);
|
|
78
|
+
if (!cached) return false;
|
|
79
|
+
if (cached.expiresAtMs < this.now()) {
|
|
80
|
+
this.entries.delete(key);
|
|
81
|
+
if (!this.inflight.has(key)) this.generations.delete(key);
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
pruneEntries() {
|
|
88
|
+
const now = this.now();
|
|
89
|
+
for (const [key, entry] of this.entries) {
|
|
90
|
+
if (entry.expiresAtMs < now) {
|
|
91
|
+
this.entries.delete(key);
|
|
92
|
+
if (!this.inflight.has(key)) this.generations.delete(key);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
while (this.entries.size > this.maxEntries) {
|
|
96
|
+
const oldestKey = this.entries.keys().next().value;
|
|
97
|
+
this.entries.delete(oldestKey);
|
|
98
|
+
if (!this.inflight.has(oldestKey)) this.generations.delete(oldestKey);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
invalidate(key) {
|
|
103
|
+
this.generations.set(key, ++this.nextGeneration);
|
|
104
|
+
this.inflight.delete(key);
|
|
105
|
+
const deleted = this.entries.delete(key);
|
|
106
|
+
this.generations.delete(key);
|
|
107
|
+
return deleted;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
clear() {
|
|
111
|
+
this.entries.clear();
|
|
112
|
+
this.inflight.clear();
|
|
113
|
+
this.generations.clear();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module.exports = {
|
|
118
|
+
ConnectionCache,
|
|
119
|
+
};
|