mobile-automator 0.23.8
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 +17 -0
- package/README.md +167 -0
- package/bin/mauto-session-daemon.js +101 -0
- package/bin/mauto.js +13 -0
- package/package.json +49 -0
- package/src/assertion/evaluator.js +285 -0
- package/src/cli.js +1722 -0
- package/src/config/coerce.js +97 -0
- package/src/config/manager.js +75 -0
- package/src/config/schema.js +124 -0
- package/src/device/action-catalog.js +99 -0
- package/src/device/bridge.js +139 -0
- package/src/device/connection.js +65 -0
- package/src/device/device-model.js +59 -0
- package/src/device/device-resolver.js +34 -0
- package/src/device/element-model.js +82 -0
- package/src/device/mobile-mcp-client.js +163 -0
- package/src/device/resolve-connection.js +156 -0
- package/src/device/selection.js +80 -0
- package/src/device/semantic-press/index.js +38 -0
- package/src/device/semantic-press/labels.js +39 -0
- package/src/device/semantic-press/resolver.js +100 -0
- package/src/device/session-client.js +173 -0
- package/src/device/session-daemon.js +526 -0
- package/src/device/session-paths.js +80 -0
- package/src/device/session-protocol.js +60 -0
- package/src/device/session-spawn.js +67 -0
- package/src/device/tool-args.js +14 -0
- package/src/guide/content/execute.agnostic.md +207 -0
- package/src/guide/content/execute.aware.md +281 -0
- package/src/guide/content/execute.invariants.md +4 -0
- package/src/guide/content/generate.agnostic.md +236 -0
- package/src/guide/content/generate.aware.md +327 -0
- package/src/guide/content/generate.invariants.md +5 -0
- package/src/guide/content/setup.agnostic.md +63 -0
- package/src/guide/content/setup.aware.md +91 -0
- package/src/guide/content/setup.invariants.md +3 -0
- package/src/guide/emitter.js +137 -0
- package/src/guide/placeholders.js +132 -0
- package/src/init/adapters.js +162 -0
- package/src/init/skill-meta.js +31 -0
- package/src/init/skill-renderer.js +60 -0
- package/src/mcp/prompts.js +55 -0
- package/src/mcp/server.js +55 -0
- package/src/memory/entries.js +61 -0
- package/src/memory/history.js +86 -0
- package/src/memory/lock.js +5 -0
- package/src/memory/paths.js +47 -0
- package/src/memory/store.js +230 -0
- package/src/output/envelope.js +106 -0
- package/src/result/capability-catalog.js +144 -0
- package/src/result/flags.js +52 -0
- package/src/result/store.js +273 -0
- package/src/scenario/validator.js +30 -0
- package/src/schemas/config_schema.json +68 -0
- package/src/schemas/format-error.js +19 -0
- package/src/schemas/result_schema.json +211 -0
- package/src/schemas/scenario_schema.json +587 -0
- package/src/setup/scaffold.js +53 -0
- package/src/util/atomic.js +41 -0
- package/src/util/lock.js +85 -0
package/src/util/lock.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
// Advisory lock for shared read-modify-write files. The memory files are
|
|
7
|
+
// appended across every run and verb, and the result files are written by
|
|
8
|
+
// one-shot CLI processes, so a naive read-modify-write races: two processes
|
|
9
|
+
// both read the old bytes and one write is silently lost. atomic-rename only
|
|
10
|
+
// protects readers from torn reads, NOT writers from lost updates — hence this
|
|
11
|
+
// explicit lock. We use O_CREAT|O_EXCL ('wx') as the mutex and break a lock
|
|
12
|
+
// whose holder crashed (mtime older than STALE_MS).
|
|
13
|
+
|
|
14
|
+
// STALE_MS bounds how long a held lock may sit before another acquirer treats
|
|
15
|
+
// it as abandoned. It is judged from the lockfile's creation mtime and is NOT
|
|
16
|
+
// refreshed while held — safe here because every memory/result write is a
|
|
17
|
+
// sub-second read-modify-write inside a one-shot verb, far below this window.
|
|
18
|
+
// Revisit if a future caller ever holds the lock across a long-running
|
|
19
|
+
// operation.
|
|
20
|
+
const STALE_MS = 10_000; // a held lock older than this is presumed abandoned
|
|
21
|
+
const RETRY_MS = 50; // wait between acquire attempts
|
|
22
|
+
const MAX_WAIT_MS = 5_000; // give up after this and throw
|
|
23
|
+
|
|
24
|
+
// Synchronous sleep with no busy-spin (Atomics.wait blocks the thread).
|
|
25
|
+
function sleepSync(ms) {
|
|
26
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function acquire(lockPath, { now = Date.now, sleep = sleepSync } = {}) {
|
|
30
|
+
fs.mkdirSync(path.dirname(lockPath), { recursive: true });
|
|
31
|
+
const deadline = now() + MAX_WAIT_MS;
|
|
32
|
+
const backoffOrThrow = () => {
|
|
33
|
+
if (now() >= deadline) {
|
|
34
|
+
throw new Error(`could not acquire lock at ${lockPath} within ${MAX_WAIT_MS}ms`);
|
|
35
|
+
}
|
|
36
|
+
sleep(RETRY_MS);
|
|
37
|
+
};
|
|
38
|
+
for (;;) {
|
|
39
|
+
try {
|
|
40
|
+
const fd = fs.openSync(lockPath, 'wx');
|
|
41
|
+
fs.writeSync(fd, String(process.pid));
|
|
42
|
+
fs.closeSync(fd);
|
|
43
|
+
return;
|
|
44
|
+
} catch (e) {
|
|
45
|
+
if (e.code !== 'EEXIST') throw e;
|
|
46
|
+
// Someone holds it. Break it if it looks abandoned.
|
|
47
|
+
try {
|
|
48
|
+
const st = fs.statSync(lockPath);
|
|
49
|
+
if (now() - st.mtimeMs > STALE_MS) {
|
|
50
|
+
fs.unlinkSync(lockPath);
|
|
51
|
+
continue; // retry immediately
|
|
52
|
+
}
|
|
53
|
+
} catch (statErr) {
|
|
54
|
+
if (statErr.code !== 'ENOENT') {
|
|
55
|
+
// Not the benign vanished-lock case — apply the bounded backoff so
|
|
56
|
+
// a persistent stat/unlink failure (EACCES/EPERM/EBUSY, ...) times
|
|
57
|
+
// out instead of busy-looping the CPU forever.
|
|
58
|
+
backoffOrThrow();
|
|
59
|
+
}
|
|
60
|
+
continue; // ENOENT: lock vanished between open and stat — retry now;
|
|
61
|
+
// any other error already backed off above before retrying.
|
|
62
|
+
}
|
|
63
|
+
backoffOrThrow();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function release(lockPath) {
|
|
69
|
+
try {
|
|
70
|
+
fs.unlinkSync(lockPath);
|
|
71
|
+
} catch (_) {
|
|
72
|
+
/* already gone — fine */
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function withLock(lockPath, fn) {
|
|
77
|
+
acquire(lockPath);
|
|
78
|
+
try {
|
|
79
|
+
return fn();
|
|
80
|
+
} finally {
|
|
81
|
+
release(lockPath);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
module.exports = { acquire, release, withLock, STALE_MS, RETRY_MS, MAX_WAIT_MS, sleepSync };
|