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.
Files changed (61) hide show
  1. package/LICENSE +17 -0
  2. package/README.md +167 -0
  3. package/bin/mauto-session-daemon.js +101 -0
  4. package/bin/mauto.js +13 -0
  5. package/package.json +49 -0
  6. package/src/assertion/evaluator.js +285 -0
  7. package/src/cli.js +1722 -0
  8. package/src/config/coerce.js +97 -0
  9. package/src/config/manager.js +75 -0
  10. package/src/config/schema.js +124 -0
  11. package/src/device/action-catalog.js +99 -0
  12. package/src/device/bridge.js +139 -0
  13. package/src/device/connection.js +65 -0
  14. package/src/device/device-model.js +59 -0
  15. package/src/device/device-resolver.js +34 -0
  16. package/src/device/element-model.js +82 -0
  17. package/src/device/mobile-mcp-client.js +163 -0
  18. package/src/device/resolve-connection.js +156 -0
  19. package/src/device/selection.js +80 -0
  20. package/src/device/semantic-press/index.js +38 -0
  21. package/src/device/semantic-press/labels.js +39 -0
  22. package/src/device/semantic-press/resolver.js +100 -0
  23. package/src/device/session-client.js +173 -0
  24. package/src/device/session-daemon.js +526 -0
  25. package/src/device/session-paths.js +80 -0
  26. package/src/device/session-protocol.js +60 -0
  27. package/src/device/session-spawn.js +67 -0
  28. package/src/device/tool-args.js +14 -0
  29. package/src/guide/content/execute.agnostic.md +207 -0
  30. package/src/guide/content/execute.aware.md +281 -0
  31. package/src/guide/content/execute.invariants.md +4 -0
  32. package/src/guide/content/generate.agnostic.md +236 -0
  33. package/src/guide/content/generate.aware.md +327 -0
  34. package/src/guide/content/generate.invariants.md +5 -0
  35. package/src/guide/content/setup.agnostic.md +63 -0
  36. package/src/guide/content/setup.aware.md +91 -0
  37. package/src/guide/content/setup.invariants.md +3 -0
  38. package/src/guide/emitter.js +137 -0
  39. package/src/guide/placeholders.js +132 -0
  40. package/src/init/adapters.js +162 -0
  41. package/src/init/skill-meta.js +31 -0
  42. package/src/init/skill-renderer.js +60 -0
  43. package/src/mcp/prompts.js +55 -0
  44. package/src/mcp/server.js +55 -0
  45. package/src/memory/entries.js +61 -0
  46. package/src/memory/history.js +86 -0
  47. package/src/memory/lock.js +5 -0
  48. package/src/memory/paths.js +47 -0
  49. package/src/memory/store.js +230 -0
  50. package/src/output/envelope.js +106 -0
  51. package/src/result/capability-catalog.js +144 -0
  52. package/src/result/flags.js +52 -0
  53. package/src/result/store.js +273 -0
  54. package/src/scenario/validator.js +30 -0
  55. package/src/schemas/config_schema.json +68 -0
  56. package/src/schemas/format-error.js +19 -0
  57. package/src/schemas/result_schema.json +211 -0
  58. package/src/schemas/scenario_schema.json +587 -0
  59. package/src/setup/scaffold.js +53 -0
  60. package/src/util/atomic.js +41 -0
  61. package/src/util/lock.js +85 -0
@@ -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 };