@extentos/mcp-server 0.0.1

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 (202) hide show
  1. package/README.md +56 -0
  2. package/dist/cli/login.d.ts +2 -0
  3. package/dist/cli/login.d.ts.map +1 -0
  4. package/dist/cli/login.js +71 -0
  5. package/dist/cli/login.js.map +1 -0
  6. package/dist/cli/logout.d.ts +2 -0
  7. package/dist/cli/logout.d.ts.map +1 -0
  8. package/dist/cli/logout.js +65 -0
  9. package/dist/cli/logout.js.map +1 -0
  10. package/dist/cli/privacy.d.ts +3 -0
  11. package/dist/cli/privacy.d.ts.map +1 -0
  12. package/dist/cli/privacy.js +39 -0
  13. package/dist/cli/privacy.js.map +1 -0
  14. package/dist/cli/status.d.ts +2 -0
  15. package/dist/cli/status.d.ts.map +1 -0
  16. package/dist/cli/status.js +9 -0
  17. package/dist/cli/status.js.map +1 -0
  18. package/dist/cli/update.d.ts +2 -0
  19. package/dist/cli/update.d.ts.map +1 -0
  20. package/dist/cli/update.js +8 -0
  21. package/dist/cli/update.js.map +1 -0
  22. package/dist/cli/whoami.d.ts +2 -0
  23. package/dist/cli/whoami.d.ts.map +1 -0
  24. package/dist/cli/whoami.js +8 -0
  25. package/dist/cli/whoami.js.map +1 -0
  26. package/dist/cli.d.ts +3 -0
  27. package/dist/cli.d.ts.map +1 -0
  28. package/dist/cli.js +69 -0
  29. package/dist/cli.js.map +1 -0
  30. package/dist/generated/schemas.d.ts +4 -0
  31. package/dist/generated/schemas.d.ts.map +1 -0
  32. package/dist/generated/schemas.js +2697 -0
  33. package/dist/generated/schemas.js.map +1 -0
  34. package/dist/index.d.ts +3 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +69 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/stub.d.ts +15 -0
  39. package/dist/stub.d.ts.map +1 -0
  40. package/dist/stub.js +20 -0
  41. package/dist/stub.js.map +1 -0
  42. package/dist/telemetry/client.d.ts +73 -0
  43. package/dist/telemetry/client.d.ts.map +1 -0
  44. package/dist/telemetry/client.js +207 -0
  45. package/dist/telemetry/client.js.map +1 -0
  46. package/dist/telemetry/consent.d.ts +19 -0
  47. package/dist/telemetry/consent.d.ts.map +1 -0
  48. package/dist/telemetry/consent.js +68 -0
  49. package/dist/telemetry/consent.js.map +1 -0
  50. package/dist/telemetry/index.d.ts +56 -0
  51. package/dist/telemetry/index.d.ts.map +1 -0
  52. package/dist/telemetry/index.js +151 -0
  53. package/dist/telemetry/index.js.map +1 -0
  54. package/dist/telemetry/installRegistry.d.ts +18 -0
  55. package/dist/telemetry/installRegistry.d.ts.map +1 -0
  56. package/dist/telemetry/installRegistry.js +102 -0
  57. package/dist/telemetry/installRegistry.js.map +1 -0
  58. package/dist/tools/data/capabilities.d.ts +566 -0
  59. package/dist/tools/data/capabilities.d.ts.map +1 -0
  60. package/dist/tools/data/capabilities.js +243 -0
  61. package/dist/tools/data/capabilities.js.map +1 -0
  62. package/dist/tools/data/examplePatterns.d.ts +4 -0
  63. package/dist/tools/data/examplePatterns.d.ts.map +1 -0
  64. package/dist/tools/data/examplePatterns.js +546 -0
  65. package/dist/tools/data/examplePatterns.js.map +1 -0
  66. package/dist/tools/data/presetTriggers.d.ts +4 -0
  67. package/dist/tools/data/presetTriggers.d.ts.map +1 -0
  68. package/dist/tools/data/presetTriggers.js +47 -0
  69. package/dist/tools/data/presetTriggers.js.map +1 -0
  70. package/dist/tools/data/version.d.ts +31 -0
  71. package/dist/tools/data/version.d.ts.map +1 -0
  72. package/dist/tools/data/version.js +34 -0
  73. package/dist/tools/data/version.js.map +1 -0
  74. package/dist/tools/definitions.d.ts +13 -0
  75. package/dist/tools/definitions.d.ts.map +1 -0
  76. package/dist/tools/definitions.js +347 -0
  77. package/dist/tools/definitions.js.map +1 -0
  78. package/dist/tools/docs/index.d.ts +10 -0
  79. package/dist/tools/docs/index.d.ts.map +1 -0
  80. package/dist/tools/docs/index.js +220 -0
  81. package/dist/tools/docs/index.js.map +1 -0
  82. package/dist/tools/handlers/completeAuthLink.d.ts +3 -0
  83. package/dist/tools/handlers/completeAuthLink.d.ts.map +1 -0
  84. package/dist/tools/handlers/completeAuthLink.js +152 -0
  85. package/dist/tools/handlers/completeAuthLink.js.map +1 -0
  86. package/dist/tools/handlers/createSimulatorSession.d.ts +3 -0
  87. package/dist/tools/handlers/createSimulatorSession.d.ts.map +1 -0
  88. package/dist/tools/handlers/createSimulatorSession.js +231 -0
  89. package/dist/tools/handlers/createSimulatorSession.js.map +1 -0
  90. package/dist/tools/handlers/generateConnectionModule.d.ts +3 -0
  91. package/dist/tools/handlers/generateConnectionModule.d.ts.map +1 -0
  92. package/dist/tools/handlers/generateConnectionModule.js +222 -0
  93. package/dist/tools/handlers/generateConnectionModule.js.map +1 -0
  94. package/dist/tools/handlers/generateConsumer.d.ts +3 -0
  95. package/dist/tools/handlers/generateConsumer.d.ts.map +1 -0
  96. package/dist/tools/handlers/generateConsumer.js +257 -0
  97. package/dist/tools/handlers/generateConsumer.js.map +1 -0
  98. package/dist/tools/handlers/getCredentialGuide.d.ts +3 -0
  99. package/dist/tools/handlers/getCredentialGuide.d.ts.map +1 -0
  100. package/dist/tools/handlers/getCredentialGuide.js +296 -0
  101. package/dist/tools/handlers/getCredentialGuide.js.map +1 -0
  102. package/dist/tools/handlers/getEventLog.d.ts +3 -0
  103. package/dist/tools/handlers/getEventLog.d.ts.map +1 -0
  104. package/dist/tools/handlers/getEventLog.js +90 -0
  105. package/dist/tools/handlers/getEventLog.js.map +1 -0
  106. package/dist/tools/handlers/getExampleSpec.d.ts +3 -0
  107. package/dist/tools/handlers/getExampleSpec.d.ts.map +1 -0
  108. package/dist/tools/handlers/getExampleSpec.js +44 -0
  109. package/dist/tools/handlers/getExampleSpec.js.map +1 -0
  110. package/dist/tools/handlers/getPermissions.d.ts +3 -0
  111. package/dist/tools/handlers/getPermissions.d.ts.map +1 -0
  112. package/dist/tools/handlers/getPermissions.js +50 -0
  113. package/dist/tools/handlers/getPermissions.js.map +1 -0
  114. package/dist/tools/handlers/getPlatformInfo.d.ts +3 -0
  115. package/dist/tools/handlers/getPlatformInfo.d.ts.map +1 -0
  116. package/dist/tools/handlers/getPlatformInfo.js +78 -0
  117. package/dist/tools/handlers/getPlatformInfo.js.map +1 -0
  118. package/dist/tools/handlers/getProductionChecklist.d.ts +3 -0
  119. package/dist/tools/handlers/getProductionChecklist.d.ts.map +1 -0
  120. package/dist/tools/handlers/getProductionChecklist.js +238 -0
  121. package/dist/tools/handlers/getProductionChecklist.js.map +1 -0
  122. package/dist/tools/handlers/getSimulatorStatus.d.ts +3 -0
  123. package/dist/tools/handlers/getSimulatorStatus.d.ts.map +1 -0
  124. package/dist/tools/handlers/getSimulatorStatus.js +56 -0
  125. package/dist/tools/handlers/getSimulatorStatus.js.map +1 -0
  126. package/dist/tools/handlers/getVoiceCommandGuidance.d.ts +3 -0
  127. package/dist/tools/handlers/getVoiceCommandGuidance.d.ts.map +1 -0
  128. package/dist/tools/handlers/getVoiceCommandGuidance.js +200 -0
  129. package/dist/tools/handlers/getVoiceCommandGuidance.js.map +1 -0
  130. package/dist/tools/handlers/initSpec.d.ts +3 -0
  131. package/dist/tools/handlers/initSpec.d.ts.map +1 -0
  132. package/dist/tools/handlers/initSpec.js +234 -0
  133. package/dist/tools/handlers/initSpec.js.map +1 -0
  134. package/dist/tools/handlers/inspectIntegration.d.ts +3 -0
  135. package/dist/tools/handlers/inspectIntegration.d.ts.map +1 -0
  136. package/dist/tools/handlers/inspectIntegration.js +204 -0
  137. package/dist/tools/handlers/inspectIntegration.js.map +1 -0
  138. package/dist/tools/handlers/planIntegration.d.ts +3 -0
  139. package/dist/tools/handlers/planIntegration.d.ts.map +1 -0
  140. package/dist/tools/handlers/planIntegration.js +279 -0
  141. package/dist/tools/handlers/planIntegration.js.map +1 -0
  142. package/dist/tools/handlers/searchDocs.d.ts +3 -0
  143. package/dist/tools/handlers/searchDocs.d.ts.map +1 -0
  144. package/dist/tools/handlers/searchDocs.js +41 -0
  145. package/dist/tools/handlers/searchDocs.js.map +1 -0
  146. package/dist/tools/handlers/updateSpec.d.ts +3 -0
  147. package/dist/tools/handlers/updateSpec.d.ts.map +1 -0
  148. package/dist/tools/handlers/updateSpec.js +453 -0
  149. package/dist/tools/handlers/updateSpec.js.map +1 -0
  150. package/dist/tools/handlers/validateIntegration.d.ts +3 -0
  151. package/dist/tools/handlers/validateIntegration.d.ts.map +1 -0
  152. package/dist/tools/handlers/validateIntegration.js +546 -0
  153. package/dist/tools/handlers/validateIntegration.js.map +1 -0
  154. package/dist/tools/handlers/validateSpec.d.ts +3 -0
  155. package/dist/tools/handlers/validateSpec.d.ts.map +1 -0
  156. package/dist/tools/handlers/validateSpec.js +26 -0
  157. package/dist/tools/handlers/validateSpec.js.map +1 -0
  158. package/dist/tools/registry.d.ts +4 -0
  159. package/dist/tools/registry.d.ts.map +1 -0
  160. package/dist/tools/registry.js +43 -0
  161. package/dist/tools/registry.js.map +1 -0
  162. package/dist/tools/response.d.ts +12 -0
  163. package/dist/tools/response.d.ts.map +1 -0
  164. package/dist/tools/response.js +19 -0
  165. package/dist/tools/response.js.map +1 -0
  166. package/dist/tools/templates/androidBootstrap.d.ts +2 -0
  167. package/dist/tools/templates/androidBootstrap.d.ts.map +1 -0
  168. package/dist/tools/templates/androidBootstrap.js +40 -0
  169. package/dist/tools/templates/androidBootstrap.js.map +1 -0
  170. package/dist/tools/templates/callbackHandler.d.ts +11 -0
  171. package/dist/tools/templates/callbackHandler.d.ts.map +1 -0
  172. package/dist/tools/templates/callbackHandler.js +177 -0
  173. package/dist/tools/templates/callbackHandler.js.map +1 -0
  174. package/dist/tools/templates/iosBootstrap.d.ts +3 -0
  175. package/dist/tools/templates/iosBootstrap.d.ts.map +1 -0
  176. package/dist/tools/templates/iosBootstrap.js +50 -0
  177. package/dist/tools/templates/iosBootstrap.js.map +1 -0
  178. package/dist/tools/templates/streamConsumer.d.ts +8 -0
  179. package/dist/tools/templates/streamConsumer.d.ts.map +1 -0
  180. package/dist/tools/templates/streamConsumer.js +248 -0
  181. package/dist/tools/templates/streamConsumer.js.map +1 -0
  182. package/dist/tools/util/appPackage.d.ts +4 -0
  183. package/dist/tools/util/appPackage.d.ts.map +1 -0
  184. package/dist/tools/util/appPackage.js +16 -0
  185. package/dist/tools/util/appPackage.js.map +1 -0
  186. package/dist/tools/util/backendClient.d.ts +25 -0
  187. package/dist/tools/util/backendClient.d.ts.map +1 -0
  188. package/dist/tools/util/backendClient.js +144 -0
  189. package/dist/tools/util/backendClient.js.map +1 -0
  190. package/dist/tools/util/manifest.d.ts +9 -0
  191. package/dist/tools/util/manifest.d.ts.map +1 -0
  192. package/dist/tools/util/manifest.js +62 -0
  193. package/dist/tools/util/manifest.js.map +1 -0
  194. package/dist/tools/util/permissions.d.ts +32 -0
  195. package/dist/tools/util/permissions.d.ts.map +1 -0
  196. package/dist/tools/util/permissions.js +165 -0
  197. package/dist/tools/util/permissions.js.map +1 -0
  198. package/dist/tools/validation/validateSpec.d.ts +22 -0
  199. package/dist/tools/validation/validateSpec.d.ts.map +1 -0
  200. package/dist/tools/validation/validateSpec.js +370 -0
  201. package/dist/tools/validation/validateSpec.js.map +1 -0
  202. package/package.json +58 -0
@@ -0,0 +1,165 @@
1
+ // Shared derivations for spec → platform permissions / Info.plist / DAT needs.
2
+ // Consumed by initSpec, generateConsumer, getPermissions, and validateSpec's stats.
3
+ const ANDROID_MIN_SDK = 28;
4
+ const ANDROID_COMPILE_SDK = 34;
5
+ const ANDROID_TARGET_SDK = 34;
6
+ const IOS_PRIVACY_STRINGS = {
7
+ NSCameraUsageDescription: "Used to capture photos and video from your glasses.",
8
+ NSMicrophoneUsageDescription: "Used to capture audio from your glasses for voice commands.",
9
+ NSSpeechRecognitionUsageDescription: "Used to transcribe voice commands from your glasses.",
10
+ NSLocationWhenInUseUsageDescription: "Used to deliver location-aware glasses experiences.",
11
+ NSBluetoothAlwaysUsageDescription: "Used to connect to your Meta Ray-Ban glasses.",
12
+ };
13
+ const IOS_REASONS = {
14
+ NSCameraUsageDescription: "capture_photo / capture_video block or video_frames / outgoing_video_stream.",
15
+ NSMicrophoneUsageDescription: "record_audio block, voice triggers, or audio_chunks / transcription_incremental stream.",
16
+ NSSpeechRecognitionUsageDescription: "voice_command / wake_word / push_to_talk trigger or transcription_incremental stream.",
17
+ NSLocationWhenInUseUsageDescription: "location_updated trigger.",
18
+ NSBluetoothAlwaysUsageDescription: "Required by Meta DAT SDK for all glasses connections.",
19
+ };
20
+ export function derivePermissions(blocks, streams, triggers) {
21
+ const set = new Set();
22
+ const add = (v) => set.add(v);
23
+ for (const b of blocks) {
24
+ if (b.type === "capture_photo" || b.type === "capture_video")
25
+ add("android.permission.CAMERA");
26
+ if (b.type === "capture_video" || b.type === "record_audio")
27
+ add("android.permission.RECORD_AUDIO");
28
+ }
29
+ for (const st of streams) {
30
+ if (st.type === "video_frames" || st.type === "outgoing_video_stream")
31
+ add("android.permission.CAMERA");
32
+ if (st.type === "audio_chunks" ||
33
+ st.type === "transcription_incremental" ||
34
+ st.type === "outgoing_audio_stream")
35
+ add("android.permission.RECORD_AUDIO");
36
+ add("android.permission.FOREGROUND_SERVICE");
37
+ }
38
+ for (const t of triggers) {
39
+ if (t.type === "voice_command" || t.type === "wake_word" || t.type === "push_to_talk")
40
+ add("android.permission.RECORD_AUDIO");
41
+ if (t.type === "location_updated")
42
+ add("android.permission.ACCESS_FINE_LOCATION");
43
+ if (t.type === "phone_notification_forwarded")
44
+ add("android.permission.BIND_NOTIFICATION_LISTENER_SERVICE");
45
+ if (t.type === "incoming_call_detected")
46
+ add("android.permission.READ_PHONE_STATE");
47
+ }
48
+ add("android.permission.BLUETOOTH_CONNECT");
49
+ add("android.permission.BLUETOOTH_SCAN");
50
+ add("android.permission.INTERNET");
51
+ return [...set].sort();
52
+ }
53
+ export function deriveAndroid(spec) {
54
+ const blocks = arr(spec.blocks);
55
+ const streams = arr(spec.streams);
56
+ const triggers = arr(spec.triggers);
57
+ const permissions = derivePermissions(blocks, streams, triggers);
58
+ const manifestEntries = permissions.map((p) => `<uses-permission android:name="${p}" />`);
59
+ const fgTypes = new Set();
60
+ for (const s of streams) {
61
+ if (s.type === "video_frames" || s.type === "outgoing_video_stream")
62
+ fgTypes.add("camera");
63
+ if (s.type === "audio_chunks" ||
64
+ s.type === "transcription_incremental" ||
65
+ s.type === "outgoing_audio_stream")
66
+ fgTypes.add("microphone");
67
+ }
68
+ const fgRequired = fgTypes.size > 0;
69
+ const fgDecl = fgRequired
70
+ ? `<service android:name=".extentos.ExtentosForegroundService" android:foregroundServiceType="${[...fgTypes].sort().join("|")}" android:exported="false" />`
71
+ : null;
72
+ return {
73
+ permissions,
74
+ manifestEntries,
75
+ foregroundService: {
76
+ required: fgRequired,
77
+ types: [...fgTypes].sort(),
78
+ declaration: fgDecl,
79
+ },
80
+ minimumSdk: ANDROID_MIN_SDK,
81
+ compileSdk: ANDROID_COMPILE_SDK,
82
+ targetSdk: ANDROID_TARGET_SDK,
83
+ };
84
+ }
85
+ export function deriveIos(spec) {
86
+ const blocks = arr(spec.blocks);
87
+ const streams = arr(spec.streams);
88
+ const triggers = arr(spec.triggers);
89
+ const needed = new Set();
90
+ needed.add("NSBluetoothAlwaysUsageDescription");
91
+ for (const b of blocks) {
92
+ if (b.type === "capture_photo" || b.type === "capture_video")
93
+ needed.add("NSCameraUsageDescription");
94
+ if (b.type === "capture_video" || b.type === "record_audio")
95
+ needed.add("NSMicrophoneUsageDescription");
96
+ }
97
+ for (const s of streams) {
98
+ if (s.type === "video_frames" || s.type === "outgoing_video_stream")
99
+ needed.add("NSCameraUsageDescription");
100
+ if (s.type === "audio_chunks" ||
101
+ s.type === "transcription_incremental" ||
102
+ s.type === "outgoing_audio_stream") {
103
+ needed.add("NSMicrophoneUsageDescription");
104
+ needed.add("NSSpeechRecognitionUsageDescription");
105
+ }
106
+ }
107
+ for (const t of triggers) {
108
+ if (t.type === "voice_command" || t.type === "wake_word" || t.type === "push_to_talk") {
109
+ needed.add("NSMicrophoneUsageDescription");
110
+ needed.add("NSSpeechRecognitionUsageDescription");
111
+ }
112
+ if (t.type === "location_updated")
113
+ needed.add("NSLocationWhenInUseUsageDescription");
114
+ }
115
+ const plistKeys = [...needed].sort().map((key) => ({
116
+ key,
117
+ value: IOS_PRIVACY_STRINGS[key] ?? "Required by this Extentos spec.",
118
+ reason: IOS_REASONS[key] ?? "Required by this Extentos spec.",
119
+ }));
120
+ return { plistKeys };
121
+ }
122
+ export function deriveMetaDat(spec) {
123
+ const blocks = arr(spec.blocks);
124
+ const streams = arr(spec.streams);
125
+ const scopes = new Set(["glasses.connection"]);
126
+ for (const b of blocks) {
127
+ if (b.type === "capture_photo")
128
+ scopes.add("glasses.camera.photo");
129
+ if (b.type === "capture_video")
130
+ scopes.add("glasses.camera.video");
131
+ if (b.type === "record_audio")
132
+ scopes.add("glasses.audio.record");
133
+ }
134
+ for (const s of streams) {
135
+ if (s.type === "video_frames" || s.type === "outgoing_video_stream")
136
+ scopes.add("glasses.camera.stream");
137
+ if (s.type === "audio_chunks" ||
138
+ s.type === "transcription_incremental" ||
139
+ s.type === "outgoing_audio_stream")
140
+ scopes.add("glasses.audio.stream");
141
+ }
142
+ return {
143
+ scopes: [...scopes].sort(),
144
+ registrationRequired: true,
145
+ registrationSteps: [
146
+ "Create a Meta for Developers app at https://developers.facebook.com/apps/.",
147
+ "Enable the Meta Wearables Developer Access Toolkit (DAT) product.",
148
+ "Add your Android package / iOS bundle ID to the app settings.",
149
+ "Copy the Meta App ID and Client Token into extentos.manifest.json (MVP) or platform config.",
150
+ ],
151
+ };
152
+ }
153
+ export function derivesInfoPlistPatch(spec) {
154
+ const { plistKeys } = deriveIos(spec);
155
+ if (!plistKeys.length)
156
+ return undefined;
157
+ const added = {};
158
+ for (const { key, value } of plistKeys)
159
+ added[key] = value;
160
+ return { added };
161
+ }
162
+ function arr(v) {
163
+ return Array.isArray(v) ? v : [];
164
+ }
165
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../../src/tools/util/permissions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface SpecValidationIssue {
2
+ path: string;
3
+ rule: string;
4
+ message: string;
5
+ suggestion?: string;
6
+ }
7
+ export interface SpecValidationResult {
8
+ status: "valid" | "invalid";
9
+ valid: boolean;
10
+ errors: SpecValidationIssue[];
11
+ warnings: SpecValidationIssue[];
12
+ stats: {
13
+ blocks: number;
14
+ streams: number;
15
+ triggers: number;
16
+ actions: number;
17
+ handlerNames: string[];
18
+ permissions: string[];
19
+ };
20
+ }
21
+ export declare function validateSpec(spec: unknown): SpecValidationResult;
22
+ //# sourceMappingURL=validateSpec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateSpec.d.ts","sourceRoot":"","sources":["../../../src/tools/validation/validateSpec.ts"],"names":[],"mappings":"AA6CA,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,KAAK,EAAE;QACL,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,WAAW,EAAE,MAAM,EAAE,CAAC;KACvB,CAAC;CACH;AAcD,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,oBAAoB,CAoKhE"}
@@ -0,0 +1,370 @@
1
+ // Full spec validator. Runs:
2
+ // 1. JSON Schema (draft 2020-12) via ajv against the embedded extentos-spec.schema.json
3
+ // 2. 12 cross-reference / semantic rules from SPEC_SCHEMA.md § Spec validation rules
4
+ // Rule labels mirror the canonical numbering in the doc.
5
+ import { Ajv2020 } from "ajv/dist/2020.js";
6
+ import { specSchema } from "../../generated/schemas.js";
7
+ import { derivePermissions } from "../util/permissions.js";
8
+ const TOGGLE_KEYS = new Set([
9
+ "listening_mode",
10
+ "camera_streaming_enabled",
11
+ "audio_capture_enabled",
12
+ "transcription_enabled",
13
+ "battery_save_mode",
14
+ "voice_confirmations",
15
+ "audio_video_coexistence_policy",
16
+ "privacy_mode",
17
+ ]);
18
+ const HARDWARE_STATE_FIELDS = new Set([
19
+ "hardware_state.connected",
20
+ "hardware_state.thermal",
21
+ "hardware_state.battery",
22
+ "hardware_state.audio_route",
23
+ ]);
24
+ const TRIGGER_PAYLOAD_PREFIX = "trigger_payload.";
25
+ const TOGGLES_PREFIX = "toggles.";
26
+ const HARDWARE_STATE_PREFIX = "hardware_state.";
27
+ const WRAPPER_ACTION_TYPES = new Set(["retry_with_backoff", "when_connected"]);
28
+ const AUDIO_ROUTES = new Set([
29
+ "glasses_speaker",
30
+ "phone_speaker",
31
+ "bluetooth_earbuds",
32
+ "wired_earbuds",
33
+ ]);
34
+ const THERMAL_LEVELS = new Set(["none", "light", "moderate", "severe", "critical"]);
35
+ const ID_PATTERN = /^[a-z][a-z0-9_]{0,31}$/;
36
+ const TEMPLATE_PATTERN = /\{\{([a-zA-Z0-9_.]+)\}\}/g;
37
+ let cachedAjv = null;
38
+ let cachedValidate = null;
39
+ function ensureAjv() {
40
+ if (cachedAjv && cachedValidate)
41
+ return { ajv: cachedAjv, validate: cachedValidate };
42
+ const ajv = new Ajv2020({ allErrors: true, strict: false });
43
+ const validate = ajv.compile(specSchema);
44
+ cachedAjv = ajv;
45
+ cachedValidate = validate;
46
+ return { ajv, validate };
47
+ }
48
+ export function validateSpec(spec) {
49
+ const errors = [];
50
+ const warnings = [];
51
+ const { validate } = ensureAjv();
52
+ const schemaOk = validate(spec);
53
+ if (!schemaOk && Array.isArray(validate.errors)) {
54
+ for (const e of validate.errors) {
55
+ errors.push({
56
+ path: e.instancePath || "/",
57
+ rule: `schema:${e.keyword}`,
58
+ message: e.message ?? "schema violation",
59
+ });
60
+ }
61
+ }
62
+ if (!spec || typeof spec !== "object") {
63
+ return emptyResult(errors, warnings);
64
+ }
65
+ const s = spec;
66
+ // Rule 1: extentos_version
67
+ if (!s.extentos_version) {
68
+ errors.push({
69
+ path: "/extentos_version",
70
+ rule: "R1:VersionMissing",
71
+ message: "extentos_version is required.",
72
+ suggestion: 'Add "extentos_version": "1.0" at the top level.',
73
+ });
74
+ }
75
+ else if (s.extentos_version !== "1.0") {
76
+ errors.push({
77
+ path: "/extentos_version",
78
+ rule: "R1:VersionUnknown",
79
+ message: `Unsupported extentos_version ${JSON.stringify(s.extentos_version)}; only "1.0" is valid for MVP.`,
80
+ });
81
+ }
82
+ // Rule 2: target.vendor
83
+ const target = s.target;
84
+ if (!target || !target.vendor) {
85
+ errors.push({
86
+ path: "/target/vendor",
87
+ rule: "R2:VendorMissing",
88
+ message: "target.vendor is required.",
89
+ suggestion: 'Add "target": { "vendor": "meta_rayban" }.',
90
+ });
91
+ }
92
+ else if (target.vendor !== "meta_rayban") {
93
+ errors.push({
94
+ path: "/target/vendor",
95
+ rule: "R2:VendorUnknown",
96
+ message: `Unknown target.vendor ${JSON.stringify(target.vendor)}; only "meta_rayban" is supported for MVP.`,
97
+ });
98
+ }
99
+ const blocks = Array.isArray(s.blocks) ? s.blocks : [];
100
+ const streams = Array.isArray(s.streams) ? s.streams : [];
101
+ const triggers = Array.isArray(s.triggers) ? s.triggers : [];
102
+ // Rule 5: id uniqueness & pattern across blocks, streams
103
+ const usedIds = new Map();
104
+ function claimId(where, value, path) {
105
+ if (typeof value !== "string")
106
+ return null;
107
+ if (!ID_PATTERN.test(value)) {
108
+ errors.push({
109
+ path,
110
+ rule: "R5:IdPattern",
111
+ message: `id "${value}" must match ${ID_PATTERN}.`,
112
+ });
113
+ return null;
114
+ }
115
+ const prior = usedIds.get(value);
116
+ if (prior) {
117
+ errors.push({
118
+ path,
119
+ rule: "R5:IdDuplicate",
120
+ message: `id "${value}" is already used in ${prior}.`,
121
+ });
122
+ return null;
123
+ }
124
+ usedIds.set(value, where);
125
+ return value;
126
+ }
127
+ blocks.forEach((b, i) => claimId(`blocks[${i}]`, b.id, `/blocks/${i}/id`));
128
+ streams.forEach((st, i) => claimId(`streams[${i}]`, st.id, `/streams/${i}/id`));
129
+ // Triggers participate in id uniqueness per the same rule surface
130
+ triggers.forEach((t, i) => {
131
+ if (t.id !== undefined)
132
+ claimId(`triggers[${i}]`, t.id, `/triggers/${i}/id`);
133
+ });
134
+ // Rule 8: only one fallback trigger
135
+ const fallbackCount = triggers.filter((t) => t.type === "fallback").length;
136
+ if (fallbackCount > 1) {
137
+ errors.push({
138
+ path: "/triggers",
139
+ rule: "R8:FallbackOnce",
140
+ message: `Found ${fallbackCount} fallback triggers; at most one is allowed.`,
141
+ });
142
+ }
143
+ // Rule 7: mode: parallel reserved
144
+ triggers.forEach((t, i) => {
145
+ if (t.mode === "parallel") {
146
+ errors.push({
147
+ path: `/triggers/${i}/mode`,
148
+ rule: "R7:ParallelReserved",
149
+ message: 'mode: "parallel" is reserved and not allowed.',
150
+ suggestion: "Use mode: restart | single | queued.",
151
+ });
152
+ }
153
+ });
154
+ // Per-trigger action walking — branch depth, wrapper nesting, set_toggle keys, template refs
155
+ const blockIds = new Set(blocks.map((b) => b.id).filter((x) => typeof x === "string"));
156
+ const handlerNames = new Set();
157
+ let actionCount = 0;
158
+ triggers.forEach((trigger, ti) => {
159
+ const triggerPath = `/triggers/${ti}`;
160
+ const knownVars = new Set();
161
+ if (trigger.type === "voice_command" && typeof trigger.phrase === "string") {
162
+ // Named captures are promoted to top-level variables
163
+ const capturePattern = /\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g;
164
+ let m;
165
+ while ((m = capturePattern.exec(trigger.phrase)) !== null) {
166
+ knownVars.add(m[1]);
167
+ }
168
+ }
169
+ const actions = Array.isArray(trigger.actions) ? trigger.actions : [];
170
+ walkActions(actions, `${triggerPath}/actions`, 0, knownVars, {
171
+ errors,
172
+ warnings,
173
+ blockIds,
174
+ handlerNames,
175
+ countAction: () => actionCount++,
176
+ });
177
+ });
178
+ // Validate block_call references to block ids
179
+ triggers.forEach((trigger, ti) => {
180
+ const actions = Array.isArray(trigger.actions) ? trigger.actions : [];
181
+ actions.forEach((a, ai) => checkBlockCallRefs(a, `/triggers/${ti}/actions/${ai}`, blockIds, errors));
182
+ });
183
+ // Derived permissions (minimal surface — expanded by getPermissions tool)
184
+ const permissions = derivePermissions(blocks, streams, triggers);
185
+ const valid = errors.length === 0;
186
+ return {
187
+ status: valid ? "valid" : "invalid",
188
+ valid,
189
+ errors,
190
+ warnings,
191
+ stats: {
192
+ blocks: blocks.length,
193
+ streams: streams.length,
194
+ triggers: triggers.length,
195
+ actions: actionCount,
196
+ handlerNames: [...handlerNames].sort(),
197
+ permissions,
198
+ },
199
+ };
200
+ }
201
+ function walkActions(actions, basePath, branchDepth, knownVars, ctx, inWrapper = false) {
202
+ actions.forEach((action, idx) => {
203
+ ctx.countAction();
204
+ const path = `${basePath}/${idx}`;
205
+ const type = action.type;
206
+ if (type === "branch") {
207
+ // Rule 3
208
+ if (branchDepth >= 1) {
209
+ ctx.errors.push({
210
+ path,
211
+ rule: "R3:BranchDepth",
212
+ message: "branch is nested inside another branch; max depth is 1.",
213
+ suggestion: "Flatten the logic using sibling actions or a set_variable gate.",
214
+ });
215
+ }
216
+ checkTemplatesInObject(action.condition, `${path}/condition`, knownVars, ctx);
217
+ const thenActions = Array.isArray(action.then) ? action.then : [];
218
+ const elseActions = Array.isArray(action.else) ? action.else : [];
219
+ walkActions(thenActions, `${path}/then`, branchDepth + 1, knownVars, ctx, inWrapper);
220
+ walkActions(elseActions, `${path}/else`, branchDepth + 1, knownVars, ctx, inWrapper);
221
+ return;
222
+ }
223
+ if (type === "set_toggle") {
224
+ const key = action.key;
225
+ if (typeof key !== "string" || !TOGGLE_KEYS.has(key)) {
226
+ ctx.errors.push({
227
+ path: `${path}/key`,
228
+ rule: "R10:UnknownToggle",
229
+ message: `set_toggle.key ${JSON.stringify(key)} is not a known toggle name.`,
230
+ suggestion: `Known toggles: ${[...TOGGLE_KEYS].sort().join(", ")}.`,
231
+ });
232
+ }
233
+ }
234
+ if (type === "retry_with_backoff" || type === "when_connected") {
235
+ if (inWrapper) {
236
+ ctx.errors.push({
237
+ path,
238
+ rule: "R11:WrapperNesting",
239
+ message: `${type} cannot be nested inside another wrapper action.`,
240
+ });
241
+ }
242
+ // Rule 12: when_connected.require predicates
243
+ if (type === "when_connected" && Array.isArray(action.require)) {
244
+ for (let i = 0; i < action.require.length; i++) {
245
+ const pred = action.require[i];
246
+ if (typeof pred !== "string" || !isValidWhenConnectedPredicate(pred)) {
247
+ ctx.errors.push({
248
+ path: `${path}/require/${i}`,
249
+ rule: "R12:UnknownPredicate",
250
+ message: `when_connected.require predicate ${JSON.stringify(pred)} is not a known form.`,
251
+ suggestion: "Valid: connected, phone_battery_above:<0-100>, thermal_below:<level>, audio_route:<route>, toggle_on:<key>, toggle_off:<key>.",
252
+ });
253
+ }
254
+ }
255
+ }
256
+ // Wrappers contain a single nested action
257
+ const wrapped = action.action;
258
+ if (wrapped) {
259
+ if (typeof wrapped.type === "string" && WRAPPER_ACTION_TYPES.has(wrapped.type)) {
260
+ ctx.errors.push({
261
+ path: `${path}/action`,
262
+ rule: "R11:WrapperNesting",
263
+ message: `${type} wraps a ${wrapped.type}; wrapper actions may not nest other wrapper actions.`,
264
+ });
265
+ }
266
+ walkActions([wrapped], `${path}/action`, branchDepth, knownVars, ctx, true);
267
+ }
268
+ return;
269
+ }
270
+ // Variables produced by this action flow forward
271
+ if (type === "block_call" && typeof action.save_as === "string") {
272
+ knownVars.add(action.save_as);
273
+ }
274
+ if (type === "app_callback") {
275
+ if (typeof action.handler === "string")
276
+ ctx.handlerNames.add(action.handler);
277
+ if (typeof action.save_as === "string")
278
+ knownVars.add(action.save_as);
279
+ }
280
+ if (type === "set_variable" && typeof action.name === "string") {
281
+ knownVars.add(action.name);
282
+ }
283
+ if (type === "prompt" && typeof action.save_as === "string") {
284
+ knownVars.add(action.save_as);
285
+ }
286
+ checkTemplatesInObject(action, path, knownVars, ctx);
287
+ });
288
+ }
289
+ function isValidWhenConnectedPredicate(p) {
290
+ if (p === "connected")
291
+ return true;
292
+ const batteryMatch = /^phone_battery_above:(\d{1,3})$/.exec(p);
293
+ if (batteryMatch) {
294
+ const n = Number(batteryMatch[1]);
295
+ return n >= 0 && n <= 100;
296
+ }
297
+ const thermalMatch = /^thermal_below:(\w+)$/.exec(p);
298
+ if (thermalMatch)
299
+ return THERMAL_LEVELS.has(thermalMatch[1]);
300
+ const audioMatch = /^audio_route:(\w+)$/.exec(p);
301
+ if (audioMatch)
302
+ return AUDIO_ROUTES.has(audioMatch[1]);
303
+ const toggleMatch = /^toggle_(on|off):(\w+)$/.exec(p);
304
+ if (toggleMatch)
305
+ return TOGGLE_KEYS.has(toggleMatch[2]);
306
+ return false;
307
+ }
308
+ function checkTemplatesInObject(obj, path, knownVars, ctx) {
309
+ walkTemplates(obj, path, (template, ownerPath) => {
310
+ const root = template.split(".")[0];
311
+ if (template.startsWith(TOGGLES_PREFIX) ||
312
+ template.startsWith(HARDWARE_STATE_PREFIX) ||
313
+ template.startsWith(TRIGGER_PAYLOAD_PREFIX) ||
314
+ HARDWARE_STATE_FIELDS.has(template)) {
315
+ return;
316
+ }
317
+ if (knownVars.has(root))
318
+ return;
319
+ ctx.errors.push({
320
+ path: ownerPath,
321
+ rule: "R6:TemplateUnresolved",
322
+ message: `Template {{${template}}} does not resolve to any variable written earlier, toggle, trigger_payload, or hardware_state.`,
323
+ suggestion: "Produce the variable earlier in the flow via block_call.save_as / app_callback.save_as / set_variable, or reference toggles.<key>, trigger_payload.<field>, or hardware_state.<field>.",
324
+ });
325
+ });
326
+ }
327
+ function walkTemplates(v, path, onFound) {
328
+ if (typeof v === "string") {
329
+ let m;
330
+ TEMPLATE_PATTERN.lastIndex = 0;
331
+ while ((m = TEMPLATE_PATTERN.exec(v)) !== null) {
332
+ onFound(m[1], path);
333
+ }
334
+ return;
335
+ }
336
+ if (Array.isArray(v)) {
337
+ v.forEach((item, i) => walkTemplates(item, `${path}/${i}`, onFound));
338
+ return;
339
+ }
340
+ if (v && typeof v === "object") {
341
+ for (const [k, val] of Object.entries(v)) {
342
+ walkTemplates(val, `${path}/${k}`, onFound);
343
+ }
344
+ }
345
+ }
346
+ function checkBlockCallRefs(action, path, blockIds, errors) {
347
+ if (action.type === "block_call" && typeof action.block_id === "string" && !blockIds.has(action.block_id)) {
348
+ errors.push({
349
+ path: `${path}/block_id`,
350
+ rule: "X:UnknownBlockRef",
351
+ message: `block_call references block_id "${action.block_id}" which is not declared in the blocks array.`,
352
+ });
353
+ }
354
+ if (action.type === "branch") {
355
+ const thenA = Array.isArray(action.then) ? action.then : [];
356
+ const elseA = Array.isArray(action.else) ? action.else : [];
357
+ thenA.forEach((a, i) => checkBlockCallRefs(a, `${path}/then/${i}`, blockIds, errors));
358
+ elseA.forEach((a, i) => checkBlockCallRefs(a, `${path}/else/${i}`, blockIds, errors));
359
+ }
360
+ }
361
+ function emptyResult(errors, warnings) {
362
+ return {
363
+ status: "invalid",
364
+ valid: false,
365
+ errors,
366
+ warnings,
367
+ stats: { blocks: 0, streams: 0, triggers: 0, actions: 0, handlerNames: [], permissions: [] },
368
+ };
369
+ }
370
+ //# sourceMappingURL=validateSpec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateSpec.js","sourceRoot":"","sources":["../../../src/tools/validation/validateSpec.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@extentos/mcp-server",
3
+ "version": "0.0.1",
4
+ "description": "Extentos MCP server — deterministic tools for building Meta-glasses apps.",
5
+ "type": "module",
6
+ "bin": {
7
+ "extentos-mcp": "./dist/cli.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "files": [
12
+ "dist",
13
+ "README.md"
14
+ ],
15
+ "scripts": {
16
+ "prebuild": "node scripts/generate-embedded-schemas.mjs",
17
+ "build": "tsc",
18
+ "start": "node dist/index.js",
19
+ "cli": "node dist/cli.js",
20
+ "dev": "tsc --watch",
21
+ "typecheck": "npm run prebuild && tsc --noEmit",
22
+ "smoke": "npm run build && node scripts/example-flow-smoke.mjs",
23
+ "smoke:telemetry": "npm run build && node scripts/telemetry-smoke.mjs",
24
+ "prepublishOnly": "npm run build"
25
+ },
26
+ "keywords": [
27
+ "mcp",
28
+ "model-context-protocol",
29
+ "meta-glasses",
30
+ "ray-ban",
31
+ "extentos",
32
+ "ai-agents",
33
+ "claude-code"
34
+ ],
35
+ "dependencies": {
36
+ "@modelcontextprotocol/sdk": "^1.0.0",
37
+ "ajv": "^8.18.0",
38
+ "commander": "^12.1.0",
39
+ "ws": "^8.20.0"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^22.10.0",
43
+ "typescript": "^5.6.0"
44
+ },
45
+ "engines": {
46
+ "node": ">=20"
47
+ },
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://github.com/Asgermolgaard/vibe-hardware.git",
51
+ "directory": "mcp-server"
52
+ },
53
+ "homepage": "https://github.com/Asgermolgaard/vibe-hardware/tree/master/mcp-server#readme",
54
+ "bugs": {
55
+ "url": "https://github.com/Asgermolgaard/vibe-hardware/issues"
56
+ },
57
+ "license": "MIT"
58
+ }