@extentos/mcp-server 0.0.75 → 0.0.77
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/dist/tools/data/codeExamples.d.ts +53 -0
- package/dist/tools/data/codeExamples.d.ts.map +1 -1
- package/dist/tools/data/codeExamples.js +254 -62
- package/dist/tools/data/codeExamples.js.map +1 -1
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +6 -8
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/docs/index.d.ts.map +1 -1
- package/dist/tools/docs/index.js +16 -7
- package/dist/tools/docs/index.js.map +1 -1
- package/dist/tools/handlers/createSimulatorSession.d.ts.map +1 -1
- package/dist/tools/handlers/createSimulatorSession.js +12 -1
- package/dist/tools/handlers/createSimulatorSession.js.map +1 -1
- package/dist/tools/handlers/generateConnectionModule.d.ts.map +1 -1
- package/dist/tools/handlers/generateConnectionModule.js +20 -13
- package/dist/tools/handlers/generateConnectionModule.js.map +1 -1
- package/dist/tools/handlers/getCodeExample.d.ts.map +1 -1
- package/dist/tools/handlers/getCodeExample.js +11 -1
- package/dist/tools/handlers/getCodeExample.js.map +1 -1
- package/dist/tools/handlers/getCredentialGuide.js +57 -8
- package/dist/tools/handlers/getCredentialGuide.js.map +1 -1
- package/dist/tools/handlers/getEventLog.d.ts.map +1 -1
- package/dist/tools/handlers/getEventLog.js +8 -10
- package/dist/tools/handlers/getEventLog.js.map +1 -1
- package/dist/tools/handlers/inspectIntegration.d.ts.map +1 -1
- package/dist/tools/handlers/inspectIntegration.js +8 -3
- package/dist/tools/handlers/inspectIntegration.js.map +1 -1
- package/dist/tools/handlers/validateIntegration.d.ts.map +1 -1
- package/dist/tools/handlers/validateIntegration.js +9 -3
- package/dist/tools/handlers/validateIntegration.js.map +1 -1
- package/dist/tools/util/generatedHash.d.ts +24 -8
- package/dist/tools/util/generatedHash.d.ts.map +1 -1
- package/dist/tools/util/generatedHash.js +88 -11
- package/dist/tools/util/generatedHash.js.map +1 -1
- package/package.json +1 -1
- package/dist/tools/data/examplePatterns.d.ts +0 -4
- package/dist/tools/data/examplePatterns.d.ts.map +0 -1
- package/dist/tools/data/examplePatterns.js +0 -546
- package/dist/tools/data/examplePatterns.js.map +0 -1
- package/dist/tools/data/presetTriggers.d.ts +0 -4
- package/dist/tools/data/presetTriggers.d.ts.map +0 -1
- package/dist/tools/data/presetTriggers.js +0 -47
- package/dist/tools/data/presetTriggers.js.map +0 -1
- package/dist/tools/handlers/generateConsumer.d.ts +0 -3
- package/dist/tools/handlers/generateConsumer.d.ts.map +0 -1
- package/dist/tools/handlers/generateConsumer.js +0 -477
- package/dist/tools/handlers/generateConsumer.js.map +0 -1
- package/dist/tools/handlers/getExampleSpec.d.ts +0 -3
- package/dist/tools/handlers/getExampleSpec.d.ts.map +0 -1
- package/dist/tools/handlers/getExampleSpec.js +0 -50
- package/dist/tools/handlers/getExampleSpec.js.map +0 -1
- package/dist/tools/handlers/initSpec.d.ts +0 -3
- package/dist/tools/handlers/initSpec.d.ts.map +0 -1
- package/dist/tools/handlers/initSpec.js +0 -350
- package/dist/tools/handlers/initSpec.js.map +0 -1
- package/dist/tools/handlers/planIntegration.d.ts +0 -3
- package/dist/tools/handlers/planIntegration.d.ts.map +0 -1
- package/dist/tools/handlers/planIntegration.js +0 -293
- package/dist/tools/handlers/planIntegration.js.map +0 -1
- package/dist/tools/handlers/updateSpec.d.ts +0 -3
- package/dist/tools/handlers/updateSpec.d.ts.map +0 -1
- package/dist/tools/handlers/updateSpec.js +0 -579
- package/dist/tools/handlers/updateSpec.js.map +0 -1
- package/dist/tools/handlers/validateSpec.d.ts +0 -3
- package/dist/tools/handlers/validateSpec.d.ts.map +0 -1
- package/dist/tools/handlers/validateSpec.js +0 -33
- package/dist/tools/handlers/validateSpec.js.map +0 -1
- package/dist/tools/templates/callbackHandler.d.ts +0 -11
- package/dist/tools/templates/callbackHandler.d.ts.map +0 -1
- package/dist/tools/templates/callbackHandler.js +0 -215
- package/dist/tools/templates/callbackHandler.js.map +0 -1
- package/dist/tools/templates/streamConsumer.d.ts +0 -8
- package/dist/tools/templates/streamConsumer.d.ts.map +0 -1
- package/dist/tools/templates/streamConsumer.js +0 -322
- package/dist/tools/templates/streamConsumer.js.map +0 -1
- package/dist/tools/util/userCodeMerge.d.ts +0 -69
- package/dist/tools/util/userCodeMerge.d.ts.map +0 -1
- package/dist/tools/util/userCodeMerge.js +0 -168
- package/dist/tools/util/userCodeMerge.js.map +0 -1
- package/dist/tools/validation/validateSpec.d.ts +0 -22
- package/dist/tools/validation/validateSpec.d.ts.map +0 -1
- package/dist/tools/validation/validateSpec.js +0 -623
- package/dist/tools/validation/validateSpec.js.map +0 -1
|
@@ -1,350 +0,0 @@
|
|
|
1
|
-
// initSpec — populate the first real spec + emit the ExtentosCallbacks dispatch template.
|
|
2
|
-
// Spec: docs/mcp/MCP_TOOLS.md § initSpec
|
|
3
|
-
// The MCP server has no filesystem — "refuse if spec already populated" is advisory
|
|
4
|
-
// and enforced by the agent calling inspectIntegration first (see tool description).
|
|
5
|
-
//
|
|
6
|
-
// Manifest contract: when the agent passes `currentManifest` (the manifest
|
|
7
|
-
// returned by inspectIntegration / generateConnectionModule), this tool
|
|
8
|
-
// applies its patch in-memory and returns the full next-state manifest under
|
|
9
|
-
// `manifest: { path, content }`. The agent overwrites the file verbatim, no
|
|
10
|
-
// agent-side merging required. Falls back to returning only `manifestPatch`
|
|
11
|
-
// when `currentManifest` is omitted (legacy callers).
|
|
12
|
-
import { createHash } from "node:crypto";
|
|
13
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
14
|
-
import { join } from "node:path";
|
|
15
|
-
import { androidSourcePath, iosModuleName } from "../util/appPackage.js";
|
|
16
|
-
import { validateSpec } from "../validation/validateSpec.js";
|
|
17
|
-
import { renderAndroidCallbacks, renderIosCallbacks } from "../templates/callbackHandler.js";
|
|
18
|
-
import { PRESET_TRIGGERS, PRESET_TRIGGER_IDS } from "../data/presetTriggers.js";
|
|
19
|
-
import { derivesInfoPlistPatch } from "../util/permissions.js";
|
|
20
|
-
import { applyManifestPatch, manifestPath, } from "../util/manifest.js";
|
|
21
|
-
import { okResponse, errorResponse } from "../response.js";
|
|
22
|
-
import { hashGeneratedContent } from "../util/generatedHash.js";
|
|
23
|
-
import { mergeUserCodeBlocks } from "../util/userCodeMerge.js";
|
|
24
|
-
export function handleInitSpec(raw) {
|
|
25
|
-
const parsed = parseArgs(raw);
|
|
26
|
-
if ("error" in parsed)
|
|
27
|
-
return parsed.error;
|
|
28
|
-
const args = parsed.args;
|
|
29
|
-
const mergedTriggers = mergeTriggers(args.presetTriggers, args.triggers);
|
|
30
|
-
const spec = {
|
|
31
|
-
$schema: "extentos://schema/v1",
|
|
32
|
-
extentos_version: "1.0",
|
|
33
|
-
target: { vendor: "meta_rayban" },
|
|
34
|
-
blocks: args.blocks,
|
|
35
|
-
streams: args.streams,
|
|
36
|
-
triggers: mergedTriggers,
|
|
37
|
-
};
|
|
38
|
-
const validation = validateSpec(spec);
|
|
39
|
-
const specContent = JSON.stringify(spec, null, 2);
|
|
40
|
-
const specHash = sha256(specContent);
|
|
41
|
-
const nowIso = new Date().toISOString();
|
|
42
|
-
const handlerNames = validation.stats.handlerNames;
|
|
43
|
-
const rawFiles = buildFiles(args.platform, args.appPackage, handlerNames);
|
|
44
|
-
// If the agent passed projectPath, do server-side USER-CODE merge for any
|
|
45
|
-
// create_or_merge file that already exists on disk. The action is upgraded
|
|
46
|
-
// to "write" (verbatim) and the manifest hash is recomputed over the merged
|
|
47
|
-
// content so live-vs-recorded matches by construction. See
|
|
48
|
-
// util/userCodeMerge.ts for the full contract.
|
|
49
|
-
//
|
|
50
|
-
// F-R3-6: compute removed handler names from the manifest diff so true
|
|
51
|
-
// orphans (handler removed from spec) get the ORPHANED label, while
|
|
52
|
-
// developer-created shared utility blocks are preserved silently.
|
|
53
|
-
const removedHandlerNames = removedTrackedNamesFromManifest(args.currentManifest, handlerNames);
|
|
54
|
-
const files = rawFiles.map((f) => maybeMerge(f, args.projectPath, removedHandlerNames));
|
|
55
|
-
const specPath = specPathFor(args.platform, args.appPackage);
|
|
56
|
-
const permissionsDelta = args.platform === "android"
|
|
57
|
-
? {
|
|
58
|
-
added: validation.stats.permissions,
|
|
59
|
-
manifestEntries: validation.stats.permissions.map((p) => `<uses-permission android:name="${p}" />`),
|
|
60
|
-
}
|
|
61
|
-
: undefined;
|
|
62
|
-
const infoPlistPatch = args.platform === "ios" ? derivesInfoPlistPatch(spec) : undefined;
|
|
63
|
-
// Same rationale as updateSpec: manifest.permissions reflects the spec,
|
|
64
|
-
// full-replace via permissionsSet so an empty/stale manifest self-heals on
|
|
65
|
-
// first init. validation.stats.permissions covers Android only — iOS uses
|
|
66
|
-
// Info.plist keys, which derivesInfoPlistPatch surfaces separately and which
|
|
67
|
-
// don't get tracked in manifest.permissions today.
|
|
68
|
-
const manifestPatch = {
|
|
69
|
-
lastUpdatedAt: nowIso,
|
|
70
|
-
integrationAdded: {
|
|
71
|
-
blocks: args.blocks.map((b) => b.type).filter((x) => typeof x === "string").sort(),
|
|
72
|
-
streams: args.streams.map((s) => s.type).filter((x) => typeof x === "string").sort(),
|
|
73
|
-
triggers: Array.from(new Set(mergedTriggers.map((t) => t.type).filter((x) => typeof x === "string"))).sort(),
|
|
74
|
-
handlerNames,
|
|
75
|
-
togglesOverridden: collectTogglesOverridden(mergedTriggers),
|
|
76
|
-
},
|
|
77
|
-
generatedFilesAdded: files.map((f) => ({
|
|
78
|
-
path: f.path,
|
|
79
|
-
template: "callback_handler",
|
|
80
|
-
hash: hashGeneratedContent(f.content),
|
|
81
|
-
generatedAt: nowIso,
|
|
82
|
-
generatedByTool: "initSpec",
|
|
83
|
-
})),
|
|
84
|
-
permissionsSet: args.platform === "android" ? [...validation.stats.permissions].sort() : undefined,
|
|
85
|
-
specUpdated: { path: specPath, hash: `sha256:${specHash}`, updatedAt: nowIso },
|
|
86
|
-
};
|
|
87
|
-
const summary = buildSummary(args, handlerNames, validation);
|
|
88
|
-
const response = {
|
|
89
|
-
spec: { path: specPath, content: spec },
|
|
90
|
-
files,
|
|
91
|
-
permissionsDelta,
|
|
92
|
-
validation: {
|
|
93
|
-
passed: validation.valid,
|
|
94
|
-
errors: validation.errors,
|
|
95
|
-
warnings: validation.warnings,
|
|
96
|
-
},
|
|
97
|
-
basedOn: { hash: `sha256:${specHash}`, timestamp: nowIso },
|
|
98
|
-
summary,
|
|
99
|
-
};
|
|
100
|
-
// Manifest contract (matches updateSpec, generateConsumer):
|
|
101
|
-
// - currentManifest supplied → return `manifest: { path, content }` (full
|
|
102
|
-
// next-state). Agent writes that file verbatim. manifestPatch is omitted
|
|
103
|
-
// because two sources of truth invite double-apply bugs.
|
|
104
|
-
// - currentManifest omitted → return `manifestPatch` only. Legacy fallback
|
|
105
|
-
// for callers who haven't migrated to the round-trip pattern.
|
|
106
|
-
if (args.currentManifest) {
|
|
107
|
-
const next = applyManifestPatch(args.currentManifest, manifestPatch);
|
|
108
|
-
response.manifest = { path: manifestPath(), content: next };
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
response.manifestPatch = manifestPatch;
|
|
112
|
-
}
|
|
113
|
-
if (infoPlistPatch)
|
|
114
|
-
response.infoPlistPatch = infoPlistPatch;
|
|
115
|
-
return okResponse(response);
|
|
116
|
-
}
|
|
117
|
-
function parseArgs(raw) {
|
|
118
|
-
if (!raw || typeof raw !== "object") {
|
|
119
|
-
return {
|
|
120
|
-
error: errorResponse({
|
|
121
|
-
code: "invalid_arguments",
|
|
122
|
-
message: "initSpec requires an object argument.",
|
|
123
|
-
fixHint: "Pass { blocks, triggers, platform, appPackage, ... }.",
|
|
124
|
-
retryable: false,
|
|
125
|
-
}),
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
const obj = raw;
|
|
129
|
-
if (!Array.isArray(obj.blocks)) {
|
|
130
|
-
return {
|
|
131
|
-
error: errorResponse({
|
|
132
|
-
code: "invalid_arguments",
|
|
133
|
-
message: "blocks is required and must be an array (may be empty).",
|
|
134
|
-
fixHint: "Pass blocks: []",
|
|
135
|
-
retryable: false,
|
|
136
|
-
}),
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
if (!Array.isArray(obj.triggers)) {
|
|
140
|
-
return {
|
|
141
|
-
error: errorResponse({
|
|
142
|
-
code: "invalid_arguments",
|
|
143
|
-
message: "triggers is required and must be an array.",
|
|
144
|
-
fixHint: "Pass triggers: [{ type, id, actions: [...] }, ...]",
|
|
145
|
-
retryable: false,
|
|
146
|
-
}),
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
if (obj.platform !== "android" && obj.platform !== "ios") {
|
|
150
|
-
return {
|
|
151
|
-
error: errorResponse({
|
|
152
|
-
code: "invalid_arguments",
|
|
153
|
-
message: `platform must be "android" or "ios" (got ${JSON.stringify(obj.platform)}).`,
|
|
154
|
-
fixHint: "Pass platform: \"android\" or \"ios\".",
|
|
155
|
-
retryable: false,
|
|
156
|
-
}),
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
if (typeof obj.appPackage !== "string" || obj.appPackage.length === 0) {
|
|
160
|
-
return {
|
|
161
|
-
error: errorResponse({
|
|
162
|
-
code: "invalid_arguments",
|
|
163
|
-
message: "appPackage is required and must be a non-empty string.",
|
|
164
|
-
fixHint: "Pass the developer's package/bundle id, e.g. com.example.myapp.",
|
|
165
|
-
retryable: false,
|
|
166
|
-
}),
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
const streams = Array.isArray(obj.streams) ? obj.streams : [];
|
|
170
|
-
const rawPreset = Array.isArray(obj.presetTriggers) ? obj.presetTriggers : [];
|
|
171
|
-
const presetTriggers = [];
|
|
172
|
-
for (const p of rawPreset) {
|
|
173
|
-
if (typeof p !== "string" || !PRESET_TRIGGER_IDS.includes(p)) {
|
|
174
|
-
return {
|
|
175
|
-
error: errorResponse({
|
|
176
|
-
code: "invalid_arguments",
|
|
177
|
-
message: `presetTriggers contains unknown preset ${JSON.stringify(p)}.`,
|
|
178
|
-
fixHint: `Valid presets: ${PRESET_TRIGGER_IDS.join(", ")}.`,
|
|
179
|
-
retryable: false,
|
|
180
|
-
}),
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
presetTriggers.push(p);
|
|
184
|
-
}
|
|
185
|
-
const currentManifest = obj.currentManifest && typeof obj.currentManifest === "object" && !Array.isArray(obj.currentManifest)
|
|
186
|
-
? obj.currentManifest
|
|
187
|
-
: undefined;
|
|
188
|
-
const projectPath = typeof obj.projectPath === "string" && obj.projectPath ? obj.projectPath : undefined;
|
|
189
|
-
return {
|
|
190
|
-
args: {
|
|
191
|
-
blocks: obj.blocks,
|
|
192
|
-
streams,
|
|
193
|
-
triggers: obj.triggers,
|
|
194
|
-
presetTriggers,
|
|
195
|
-
platform: obj.platform,
|
|
196
|
-
appPackage: obj.appPackage,
|
|
197
|
-
currentManifest,
|
|
198
|
-
projectPath,
|
|
199
|
-
},
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
// Compute names that were tracked by the spec last cycle (per the manifest)
|
|
203
|
-
// but aren't tracked now — the diff that lets the merge utility decide which
|
|
204
|
-
// in-existing-only USER-CODE blocks are TRUE orphans (handler removed from
|
|
205
|
-
// spec; gets ORPHANED label) vs developer-created shared utility blocks
|
|
206
|
-
// (preserved silently). See util/userCodeMerge.ts MergeOptions.
|
|
207
|
-
function removedTrackedNamesFromManifest(manifest, newHandlerNames) {
|
|
208
|
-
if (!manifest)
|
|
209
|
-
return [];
|
|
210
|
-
const integration = manifest.integration;
|
|
211
|
-
if (!integration)
|
|
212
|
-
return [];
|
|
213
|
-
const previousHandlers = Array.isArray(integration.handlerNames)
|
|
214
|
-
? integration.handlerNames.filter((n) => typeof n === "string")
|
|
215
|
-
: [];
|
|
216
|
-
const previous = new Set([...previousHandlers, "imports"]);
|
|
217
|
-
const next = new Set([...newHandlerNames, "imports"]);
|
|
218
|
-
return [...previous].filter((n) => !next.has(n));
|
|
219
|
-
}
|
|
220
|
-
// When projectPath is provided, the action upgrades to "write" — the
|
|
221
|
-
// server has done all the merge work the agent would otherwise have to
|
|
222
|
-
// do, so the agent writes content verbatim. Two cases:
|
|
223
|
-
//
|
|
224
|
-
// - File exists on disk: run the server-side USER-CODE merge,
|
|
225
|
-
// return action "write" with merged content + mergeReport.
|
|
226
|
-
// - File doesn't exist (fresh integration): nothing to merge, but
|
|
227
|
-
// still return action "write" with the raw template + an empty
|
|
228
|
-
// mergeReport. F-R3-4: previously returned "create_or_merge" in
|
|
229
|
-
// this case, contradicting the docstring "action becomes 'write'".
|
|
230
|
-
// Functionally equivalent (both = "write the file fresh") but the
|
|
231
|
-
// contract was inconsistent, so a strict agent that switches code
|
|
232
|
-
// paths on the action would do extra work for no reason.
|
|
233
|
-
//
|
|
234
|
-
// When projectPath is omitted, fall through to the legacy
|
|
235
|
-
// create_or_merge contract (agent does its own merge).
|
|
236
|
-
function maybeMerge(raw, projectPath, removedTrackedNames = []) {
|
|
237
|
-
if (!projectPath)
|
|
238
|
-
return { ...raw };
|
|
239
|
-
const abs = join(projectPath, raw.path);
|
|
240
|
-
if (!existsSync(abs)) {
|
|
241
|
-
return {
|
|
242
|
-
path: raw.path,
|
|
243
|
-
content: raw.content,
|
|
244
|
-
action: "write",
|
|
245
|
-
mergeReport: { preserved: [], orphaned: [], extra: [], warnings: [] },
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
const existing = readFileSync(abs, "utf8");
|
|
249
|
-
const result = mergeUserCodeBlocks(existing, raw.content, { removedTrackedNames });
|
|
250
|
-
return {
|
|
251
|
-
path: raw.path,
|
|
252
|
-
content: result.merged,
|
|
253
|
-
action: "write",
|
|
254
|
-
mergeReport: {
|
|
255
|
-
preserved: result.preserved,
|
|
256
|
-
orphaned: result.orphaned,
|
|
257
|
-
extra: result.extra,
|
|
258
|
-
warnings: result.warnings,
|
|
259
|
-
},
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
function mergeTriggers(presetIds, agentTriggers) {
|
|
263
|
-
const agentIds = new Set(agentTriggers.map((t) => t.id).filter((x) => typeof x === "string"));
|
|
264
|
-
const expanded = [];
|
|
265
|
-
for (const pid of presetIds) {
|
|
266
|
-
const preset = PRESET_TRIGGERS[pid];
|
|
267
|
-
if (agentIds.has(preset.id))
|
|
268
|
-
continue;
|
|
269
|
-
expanded.push(JSON.parse(JSON.stringify(preset)));
|
|
270
|
-
}
|
|
271
|
-
return [...expanded, ...agentTriggers];
|
|
272
|
-
}
|
|
273
|
-
function buildFiles(platform, appPackage, handlerNames) {
|
|
274
|
-
// ExtentosCallbacks.{kt,swift} always contains USER-CODE-START/END blocks
|
|
275
|
-
// for handler bodies, so the action MUST be `create_or_merge`. Previously
|
|
276
|
-
// emitted as `create`, which would tell the agent to overwrite — losing
|
|
277
|
-
// the dev's handler implementations on any re-emission. generateConsumer
|
|
278
|
-
// already emits this same file with create_or_merge; this fix aligns
|
|
279
|
-
// initSpec with that contract. See INTEGRATION_SHAPE.md § File-level actions.
|
|
280
|
-
if (platform === "android") {
|
|
281
|
-
const sourcePath = androidSourcePath(appPackage);
|
|
282
|
-
return [
|
|
283
|
-
{
|
|
284
|
-
path: `app/src/main/java/${sourcePath}/extentos/ExtentosCallbacks.kt`,
|
|
285
|
-
action: "create_or_merge",
|
|
286
|
-
content: renderAndroidCallbacks(appPackage, handlerNames),
|
|
287
|
-
},
|
|
288
|
-
];
|
|
289
|
-
}
|
|
290
|
-
const moduleName = iosModuleName(appPackage);
|
|
291
|
-
return [
|
|
292
|
-
{
|
|
293
|
-
path: `Sources/${moduleName}/Extentos/ExtentosCallbacks.swift`,
|
|
294
|
-
action: "create_or_merge",
|
|
295
|
-
content: renderIosCallbacks(handlerNames),
|
|
296
|
-
},
|
|
297
|
-
];
|
|
298
|
-
}
|
|
299
|
-
function specPathFor(platform, appPackage) {
|
|
300
|
-
if (platform === "android")
|
|
301
|
-
return "app/src/main/assets/extentos.spec.json";
|
|
302
|
-
const moduleName = iosModuleName(appPackage);
|
|
303
|
-
return `Sources/${moduleName}/Resources/extentos.spec.json`;
|
|
304
|
-
}
|
|
305
|
-
function collectTogglesOverridden(triggers) {
|
|
306
|
-
const keys = new Set();
|
|
307
|
-
const visit = (actions) => {
|
|
308
|
-
if (!Array.isArray(actions))
|
|
309
|
-
return;
|
|
310
|
-
for (const a of actions) {
|
|
311
|
-
if (!a || typeof a !== "object")
|
|
312
|
-
continue;
|
|
313
|
-
const rec = a;
|
|
314
|
-
if (rec.type === "set_toggle" && typeof rec.key === "string")
|
|
315
|
-
keys.add(rec.key);
|
|
316
|
-
if (rec.type === "branch") {
|
|
317
|
-
visit(rec.then);
|
|
318
|
-
visit(rec.else);
|
|
319
|
-
}
|
|
320
|
-
if (rec.type === "retry_with_backoff" || rec.type === "when_connected") {
|
|
321
|
-
if (rec.action)
|
|
322
|
-
visit([rec.action]);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
};
|
|
326
|
-
for (const t of triggers)
|
|
327
|
-
visit(t.actions);
|
|
328
|
-
return [...keys].sort();
|
|
329
|
-
}
|
|
330
|
-
function buildSummary(args, handlerNames, validation) {
|
|
331
|
-
const parts = [
|
|
332
|
-
`Generated spec with ${args.blocks.length} block${plural(args.blocks.length)}`,
|
|
333
|
-
`${args.streams.length} stream${plural(args.streams.length)}`,
|
|
334
|
-
`${args.triggers.length + args.presetTriggers.length} trigger${plural(args.triggers.length + args.presetTriggers.length)}`,
|
|
335
|
-
];
|
|
336
|
-
const handlersPart = handlerNames.length
|
|
337
|
-
? `Callback handler has ${handlerNames.length} handler stub${plural(handlerNames.length)}: ${handlerNames.join(", ")}.`
|
|
338
|
-
: `No app_callback handlers in this spec; ExtentosCallbacks is empty.`;
|
|
339
|
-
const validationPart = validation.valid
|
|
340
|
-
? "Validation passed."
|
|
341
|
-
: `Validation failed with ${validation.errors.length} error${plural(validation.errors.length)} — see validation.errors.`;
|
|
342
|
-
return `${parts.join(", ")}. ${handlersPart} ${validationPart}`;
|
|
343
|
-
}
|
|
344
|
-
function plural(n) {
|
|
345
|
-
return n === 1 ? "" : "s";
|
|
346
|
-
}
|
|
347
|
-
function sha256(content) {
|
|
348
|
-
return createHash("sha256").update(content).digest("hex");
|
|
349
|
-
}
|
|
350
|
-
//# sourceMappingURL=initSpec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"initSpec.js","sourceRoot":"","sources":["../../../src/tools/handlers/initSpec.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"planIntegration.d.ts","sourceRoot":"","sources":["../../../src/tools/handlers/planIntegration.ts"],"names":[],"mappings":"AAGA,OAAO,EAA6B,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAqG5E,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAgG9D"}
|
|
@@ -1,293 +0,0 @@
|
|
|
1
|
-
// planIntegration — map NL goal to deterministic tool-call sequence + primitive suggestions.
|
|
2
|
-
// Spec: docs/mcp/MCP_TOOLS.md § planIntegration
|
|
3
|
-
import { okResponse, errorResponse } from "../response.js";
|
|
4
|
-
// Order matters: more specific phrases first.
|
|
5
|
-
const KEYWORDS = [
|
|
6
|
-
{
|
|
7
|
-
match: /\btranslat(e|ion|or)\b/,
|
|
8
|
-
streams: ["transcription_incremental"],
|
|
9
|
-
handlers: ["translate"],
|
|
10
|
-
pattern: "live_translation",
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
match: /\b(notification|notify|alerts?)\b/,
|
|
14
|
-
triggers: ["phone_notification_forwarded"],
|
|
15
|
-
handlers: ["summarize_notification"],
|
|
16
|
-
pattern: "notification_reader",
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
match: /\b(describe|description|what.?s|identify|recognize|object|scene|see|look|vision)\b/,
|
|
20
|
-
blocks: ["capture_photo", "speak_text"],
|
|
21
|
-
triggers: ["voice_command"],
|
|
22
|
-
handlers: ["describe_image"],
|
|
23
|
-
pattern: "scene_description",
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
match: /\b(photo|picture|snapshot|capture)\b/,
|
|
27
|
-
blocks: ["capture_photo"],
|
|
28
|
-
triggers: ["voice_command", "capture_button"],
|
|
29
|
-
pattern: "scene_description",
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
match: /\bvideo\b/,
|
|
33
|
-
blocks: ["capture_video"],
|
|
34
|
-
triggers: ["voice_command"],
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
match: /\b(navigat|direction|way|route|map)\b/,
|
|
38
|
-
triggers: ["voice_command", "location_updated"],
|
|
39
|
-
handlers: ["get_directions"],
|
|
40
|
-
pattern: "navigation_guide",
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
match: /\b(call|phone|video.?call|meeting)\b/,
|
|
44
|
-
streams: ["outgoing_video_stream", "outgoing_audio_stream"],
|
|
45
|
-
pattern: "video_call",
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
match: /\bdetect(ion)?\b/,
|
|
49
|
-
streams: ["video_frames"],
|
|
50
|
-
handlers: ["detect_objects"],
|
|
51
|
-
pattern: "object_detection",
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
match: /\b(notes?|dictation|transcrib|memo)\b/,
|
|
55
|
-
blocks: ["record_audio"],
|
|
56
|
-
streams: ["transcription_incremental"],
|
|
57
|
-
triggers: ["voice_command"],
|
|
58
|
-
handlers: ["save_note"],
|
|
59
|
-
pattern: "voice_notes",
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
match: /\b(voice|speak|command|assistant|chat|ask|question)\b/,
|
|
63
|
-
triggers: ["voice_command"],
|
|
64
|
-
blocks: ["speak_text"],
|
|
65
|
-
handlers: ["answer_question"],
|
|
66
|
-
pattern: "voice_assistant",
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
match: /\b(music|audio|sound)\b/,
|
|
70
|
-
blocks: ["speak_text"],
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
match: /\b(tap|gesture)\b/,
|
|
74
|
-
triggers: ["tap"],
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
match: /\b(incoming.?call|ring)\b/,
|
|
78
|
-
triggers: ["incoming_call_detected"],
|
|
79
|
-
},
|
|
80
|
-
];
|
|
81
|
-
export function handlePlanIntegration(raw) {
|
|
82
|
-
const parsed = parseArgs(raw);
|
|
83
|
-
if ("error" in parsed)
|
|
84
|
-
return parsed.error;
|
|
85
|
-
const { goal, platform, hasExistingIntegration } = parsed;
|
|
86
|
-
const lower = goal.toLowerCase();
|
|
87
|
-
const blocks = new Set();
|
|
88
|
-
const streams = new Set();
|
|
89
|
-
const triggers = new Set();
|
|
90
|
-
const handlers = new Set();
|
|
91
|
-
let referencePattern = null;
|
|
92
|
-
// Merge rule (documented in MCP_TOOLS.md § planIntegration):
|
|
93
|
-
// 1. KEYWORDS entries with a `pattern:` field are exclusive — only the
|
|
94
|
-
// FIRST matching pattern entry contributes its primitives. This
|
|
95
|
-
// prevents over-suggestion when a goal mentions both "voice notes"
|
|
96
|
-
// (matches `voice_notes`) and "voice command" (matches
|
|
97
|
-
// `voice_assistant`) — we emit only the voice_notes pattern's
|
|
98
|
-
// primitives, not a noisy union of both.
|
|
99
|
-
// 2. KEYWORDS entries WITHOUT a `pattern:` field are additive (e.g.
|
|
100
|
-
// `tap` adds the tap trigger; `music` adds speak_text). They stack
|
|
101
|
-
// with the chosen pattern.
|
|
102
|
-
for (const kw of KEYWORDS) {
|
|
103
|
-
if (!kw.match.test(lower))
|
|
104
|
-
continue;
|
|
105
|
-
if (kw.pattern) {
|
|
106
|
-
if (referencePattern)
|
|
107
|
-
continue; // already locked in a pattern
|
|
108
|
-
referencePattern = kw.pattern;
|
|
109
|
-
}
|
|
110
|
-
kw.blocks?.forEach((b) => blocks.add(b));
|
|
111
|
-
kw.streams?.forEach((s) => streams.add(s));
|
|
112
|
-
kw.triggers?.forEach((t) => triggers.add(t));
|
|
113
|
-
kw.handlers?.forEach((h) => handlers.add(h));
|
|
114
|
-
}
|
|
115
|
-
if (triggers.has("voice_command") && blocks.size === 0 && streams.size === 0) {
|
|
116
|
-
blocks.add("speak_text");
|
|
117
|
-
}
|
|
118
|
-
const warnings = [];
|
|
119
|
-
const presetTriggers = [];
|
|
120
|
-
if (triggers.has("voice_command") ||
|
|
121
|
-
triggers.has("wake_word") ||
|
|
122
|
-
triggers.has("push_to_talk")) {
|
|
123
|
-
presetTriggers.push("fallback_default");
|
|
124
|
-
}
|
|
125
|
-
if (streams.size > 0) {
|
|
126
|
-
presetTriggers.push("thermal_throttle");
|
|
127
|
-
}
|
|
128
|
-
if (streams.size > 0 && !triggers.has("connection_state_changed")) {
|
|
129
|
-
presetTriggers.push("disconnect_announce");
|
|
130
|
-
}
|
|
131
|
-
if (blocks.size + streams.size + triggers.size === 0) {
|
|
132
|
-
warnings.push("No primitives matched the goal keywords. Consider the 8 canonical patterns (use getExampleSpec) or rephrase the goal with concrete actions.");
|
|
133
|
-
}
|
|
134
|
-
if (triggers.has("voice_command") && blocks.has("speak_text") && handlers.size === 0) {
|
|
135
|
-
warnings.push("Voice-in/voice-out flow without an app_callback — confirm the AI processing step is intentional or add a handler.");
|
|
136
|
-
}
|
|
137
|
-
const toolSequence = buildToolSequence({
|
|
138
|
-
hasExistingIntegration: Boolean(hasExistingIntegration),
|
|
139
|
-
platform,
|
|
140
|
-
handlers: [...handlers],
|
|
141
|
-
streams: [...streams],
|
|
142
|
-
presetTriggers,
|
|
143
|
-
referencePattern,
|
|
144
|
-
});
|
|
145
|
-
const response = {
|
|
146
|
-
toolSequence,
|
|
147
|
-
suggestedBlocks: [...blocks].sort(),
|
|
148
|
-
suggestedStreams: [...streams].sort(),
|
|
149
|
-
suggestedTriggers: [...triggers].sort(),
|
|
150
|
-
suggestedPresets: [...presetTriggers],
|
|
151
|
-
suggestedHandlers: [...handlers].sort(),
|
|
152
|
-
warnings,
|
|
153
|
-
estimatedSetupSteps: toolSequence.length,
|
|
154
|
-
referencePattern,
|
|
155
|
-
summary: buildSummary({
|
|
156
|
-
platform,
|
|
157
|
-
blocks: [...blocks],
|
|
158
|
-
streams: [...streams],
|
|
159
|
-
triggers: [...triggers],
|
|
160
|
-
handlers: [...handlers],
|
|
161
|
-
referencePattern,
|
|
162
|
-
hasExistingIntegration: Boolean(hasExistingIntegration),
|
|
163
|
-
}),
|
|
164
|
-
};
|
|
165
|
-
return okResponse(response);
|
|
166
|
-
}
|
|
167
|
-
function buildToolSequence(opts) {
|
|
168
|
-
const seq = [];
|
|
169
|
-
let step = 1;
|
|
170
|
-
seq.push({
|
|
171
|
-
step: step++,
|
|
172
|
-
tool: "getPlatformInfo",
|
|
173
|
-
params: { sections: ["version", "capabilities"], glasses: "meta_rayban" },
|
|
174
|
-
note: "Fetch library version and capability surface for the current glasses target.",
|
|
175
|
-
});
|
|
176
|
-
if (opts.referencePattern) {
|
|
177
|
-
seq.push({
|
|
178
|
-
step: step++,
|
|
179
|
-
tool: "getExampleSpec",
|
|
180
|
-
params: { pattern: opts.referencePattern },
|
|
181
|
-
note: `Grab the ${opts.referencePattern} reference spec as a starting point.`,
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
if (!opts.hasExistingIntegration) {
|
|
185
|
-
seq.push({
|
|
186
|
-
step: step++,
|
|
187
|
-
tool: "generateConnectionModule",
|
|
188
|
-
params: { platform: opts.platform, glasses: "meta_rayban" },
|
|
189
|
-
note: "One-shot project scaffold: bootstrap, manifest, dependency, empty spec.",
|
|
190
|
-
});
|
|
191
|
-
seq.push({
|
|
192
|
-
step: step++,
|
|
193
|
-
tool: "initSpec",
|
|
194
|
-
params: opts.presetTriggers.length
|
|
195
|
-
? { platform: opts.platform, presetTriggers: opts.presetTriggers }
|
|
196
|
-
: { platform: opts.platform },
|
|
197
|
-
note: "Populate the first real spec with blocks/streams/triggers from the example + keyword matches.",
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
seq.push({
|
|
202
|
-
step: step++,
|
|
203
|
-
tool: "inspectIntegration",
|
|
204
|
-
note: "Read current integration state (manifest + spec + file hashes) to get the basedOn freshness token.",
|
|
205
|
-
});
|
|
206
|
-
seq.push({
|
|
207
|
-
step: step++,
|
|
208
|
-
tool: "updateSpec",
|
|
209
|
-
note: "Apply the new primitives as patch operations against the inspected basedOn.",
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
if (opts.handlers.length) {
|
|
213
|
-
seq.push({
|
|
214
|
-
step: step++,
|
|
215
|
-
tool: "generateConsumer",
|
|
216
|
-
params: {
|
|
217
|
-
kind: "callback",
|
|
218
|
-
platform: opts.platform,
|
|
219
|
-
handlers: opts.handlers.map((name) => ({ name })),
|
|
220
|
-
},
|
|
221
|
-
note: `Stub the ${opts.handlers.length} app_callback handler${opts.handlers.length === 1 ? "" : "s"} on ${opts.platform}.`,
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
if (opts.streams.length) {
|
|
225
|
-
seq.push({
|
|
226
|
-
step: step++,
|
|
227
|
-
tool: "generateConsumer",
|
|
228
|
-
params: {
|
|
229
|
-
kind: "stream",
|
|
230
|
-
platform: opts.platform,
|
|
231
|
-
streams: opts.streams.map((id) => ({ id, type: id })),
|
|
232
|
-
},
|
|
233
|
-
note: `Generate stream consumer scaffolds for ${opts.streams.length} stream${opts.streams.length === 1 ? "" : "s"}.`,
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
seq.push({
|
|
237
|
-
step: step++,
|
|
238
|
-
tool: "validateIntegration",
|
|
239
|
-
note: "Pre-testing correctness gate: spec + files + manifest + permissions + handler coverage.",
|
|
240
|
-
});
|
|
241
|
-
seq.push({
|
|
242
|
-
step: step++,
|
|
243
|
-
tool: "createSimulatorSession",
|
|
244
|
-
note: "Provision a browser simulator session to test the flow end-to-end.",
|
|
245
|
-
});
|
|
246
|
-
return seq;
|
|
247
|
-
}
|
|
248
|
-
function buildSummary(opts) {
|
|
249
|
-
const primitives = opts.blocks.length + opts.streams.length + opts.triggers.length + opts.handlers.length;
|
|
250
|
-
const origin = opts.hasExistingIntegration ? "existing project" : "new project";
|
|
251
|
-
const pattern = opts.referencePattern
|
|
252
|
-
? ` Referenced pattern: ${opts.referencePattern}.`
|
|
253
|
-
: "";
|
|
254
|
-
return `Plan for ${origin} on ${opts.platform}: ${primitives} suggested primitive${primitives === 1 ? "" : "s"} (${opts.blocks.length} block${s(opts.blocks.length)}, ${opts.streams.length} stream${s(opts.streams.length)}, ${opts.triggers.length} trigger${s(opts.triggers.length)}, ${opts.handlers.length} handler${s(opts.handlers.length)}).${pattern}`;
|
|
255
|
-
}
|
|
256
|
-
function s(n) {
|
|
257
|
-
return n === 1 ? "" : "s";
|
|
258
|
-
}
|
|
259
|
-
function parseArgs(raw) {
|
|
260
|
-
if (!raw || typeof raw !== "object") {
|
|
261
|
-
return {
|
|
262
|
-
error: errorResponse({
|
|
263
|
-
code: "invalid_arguments",
|
|
264
|
-
message: "planIntegration requires { goal, platform, glasses }.",
|
|
265
|
-
fixHint: 'Pass { goal: "...", platform: "android" | "ios", glasses: "meta_rayban" }.',
|
|
266
|
-
retryable: false,
|
|
267
|
-
}),
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
const obj = raw;
|
|
271
|
-
if (typeof obj.goal !== "string" || !obj.goal.trim()) {
|
|
272
|
-
return errInvalid("goal is required and must be a non-empty string.", 'Pass goal: "<plain-English goal>".');
|
|
273
|
-
}
|
|
274
|
-
if (obj.platform !== "android" && obj.platform !== "ios") {
|
|
275
|
-
return errInvalid(`platform must be "android" or "ios" (got ${JSON.stringify(obj.platform)}).`, 'Pass platform: "android" or "ios".');
|
|
276
|
-
}
|
|
277
|
-
return {
|
|
278
|
-
goal: obj.goal,
|
|
279
|
-
platform: obj.platform,
|
|
280
|
-
hasExistingIntegration: typeof obj.hasExistingIntegration === "boolean" ? obj.hasExistingIntegration : undefined,
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
function errInvalid(message, fixHint) {
|
|
284
|
-
return {
|
|
285
|
-
error: errorResponse({
|
|
286
|
-
code: "invalid_arguments",
|
|
287
|
-
message,
|
|
288
|
-
fixHint,
|
|
289
|
-
retryable: false,
|
|
290
|
-
}),
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
//# sourceMappingURL=planIntegration.js.map
|