@gakim-digital/dexter-bridge 0.11.14 → 0.11.16
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/README.md +9 -12
- package/package.json +2 -1
- package/src/agent.js +20 -9
- package/src/agentOutput.js +1 -1
- package/src/config.js +1 -3
- package/src/framerAgentTools.js +486 -792
- package/src/framerBehaviorContract.js +124 -1326
- package/src/protocol.js +5 -5
package/README.md
CHANGED
|
@@ -47,18 +47,15 @@ Native shell, filesystem, web, and unrelated-project access are disabled for
|
|
|
47
47
|
Framer outcome runs. Publishing is denied unless a future assignment explicitly
|
|
48
48
|
authorizes it.
|
|
49
49
|
|
|
50
|
-
Bridges advertise `framer-interaction-verification-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
remaining targets are changed. Only a concrete contradiction may receive one
|
|
60
|
-
scoped `SET` repair. Repeated unchanged evidence is bounded and exits as a
|
|
61
|
-
partial result rather than looping.
|
|
50
|
+
Bridges advertise `framer-interaction-verification-v4`. Dexter does not model
|
|
51
|
+
Framer's interaction features: the model builds behaviors with any capability
|
|
52
|
+
the Framer guidance documents, declares each behavior with the nodes that
|
|
53
|
+
should carry it, and then names the Framer property that carries it on each
|
|
54
|
+
node (for example `loopEffect` or `link`). The bridge confirms that property on
|
|
55
|
+
the live node. Results are `verified`, `contradicted` (the value differs), or
|
|
56
|
+
`unknown` (the property was not found). Unknown never blocks edits and is
|
|
57
|
+
reported as unverified; an unchecked target or a contradiction leaves the run
|
|
58
|
+
incomplete.
|
|
62
59
|
|
|
63
60
|
Project connection is handled inside Dexter and completes before the model
|
|
64
61
|
starts:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gakim-digital/dexter-bridge",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.16",
|
|
4
4
|
"description": "Local bridge for InstaWebAI and Dexter — runs Codex, Claude Code, or OpenCode on your machine.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"@openrouter/ai-sdk-provider": "^3.0.0",
|
|
46
46
|
"ai": "^7.0.85",
|
|
47
47
|
"cross-spawn": "^7.0.6",
|
|
48
|
+
"js-tokens": "^10.0.0",
|
|
48
49
|
"jsonrepair": "^3.15.0",
|
|
49
50
|
"zod": "^4.5.4"
|
|
50
51
|
}
|
package/src/agent.js
CHANGED
|
@@ -2579,27 +2579,36 @@ async function executeOutcomeRun(run, send, agent, options = {}) {
|
|
|
2579
2579
|
let providerAttempts = 0;
|
|
2580
2580
|
let result;
|
|
2581
2581
|
try {
|
|
2582
|
-
|
|
2583
|
-
await Promise.race([harnessTools.preflight(), cancellation])
|
|
2584
|
-
|
|
2582
|
+
const preflight = framerAgentOutcome
|
|
2583
|
+
? await Promise.race([harnessTools.preflight(), cancellation])
|
|
2584
|
+
: null;
|
|
2585
2585
|
const framerGuidance = framerAgentOutcome
|
|
2586
2586
|
? await Promise.race([
|
|
2587
2587
|
harnessTools.loadProjectGuidance(),
|
|
2588
2588
|
cancellation,
|
|
2589
2589
|
])
|
|
2590
2590
|
: null;
|
|
2591
|
-
harnessTools.configurePromptContext?.({
|
|
2592
|
-
doctrineLoaded: Boolean(run?.doctrine),
|
|
2593
|
-
doctrineVersion: run?.doctrineVersion,
|
|
2594
|
-
});
|
|
2595
2591
|
prompt = buildOutcomePrompt(executionOutcome, product, {
|
|
2596
2592
|
doctrine: run?.doctrine,
|
|
2597
2593
|
doctrineVersion: run?.doctrineVersion,
|
|
2598
2594
|
framerGuidance: framerGuidance?.content,
|
|
2599
2595
|
});
|
|
2596
|
+
const unresolvedTargets = preflight?.unresolvedTargets || [];
|
|
2597
|
+
if (unresolvedTargets.length > 0) {
|
|
2598
|
+
prompt = [
|
|
2599
|
+
prompt,
|
|
2600
|
+
'',
|
|
2601
|
+
`These selected layer IDs do not resolve to native nodes on the active page: ${unresolvedTargets.map((target) => target.id).join(', ')}. The user still means those layers. Locate them by name and position in the provided context and the live tree, treat the matching native nodes as the selection, and ask only if no layer clearly matches.`,
|
|
2602
|
+
].join('\n');
|
|
2603
|
+
}
|
|
2600
2604
|
if (materializedNativeSkills) {
|
|
2601
2605
|
prompt = claudeNativeSkillPrompt(prompt, materializedNativeSkills);
|
|
2602
2606
|
}
|
|
2607
|
+
harnessTools.configurePromptContext?.({
|
|
2608
|
+
doctrineLoaded: Boolean(run?.doctrine),
|
|
2609
|
+
doctrineVersion: run?.doctrineVersion,
|
|
2610
|
+
promptBytes: Buffer.byteLength(prompt, 'utf8'),
|
|
2611
|
+
});
|
|
2603
2612
|
const gateway =
|
|
2604
2613
|
definition.id === 'codex' ? null : await harnessTools.startGateway();
|
|
2605
2614
|
const mcpServer = gateway
|
|
@@ -2796,7 +2805,7 @@ async function executeOutcomeRun(run, send, agent, options = {}) {
|
|
|
2796
2805
|
rawCompletion.status === successStatus
|
|
2797
2806
|
&& typeof harnessTools.verificationRepairPrompt === 'function'
|
|
2798
2807
|
? harnessTools.verificationRepairPrompt()
|
|
2799
|
-
: null;
|
|
2808
|
+
: harnessTools.unblockedFailurePrompt?.(rawCompletion) || null;
|
|
2800
2809
|
if (
|
|
2801
2810
|
repairPrompt
|
|
2802
2811
|
&& Date.now() - callStartedAt < outcomeMaxDurationMs - 5_000
|
|
@@ -2805,7 +2814,9 @@ async function executeOutcomeRun(run, send, agent, options = {}) {
|
|
|
2805
2814
|
kind: 'status_update',
|
|
2806
2815
|
source: 'harness',
|
|
2807
2816
|
message:
|
|
2808
|
-
|
|
2817
|
+
rawCompletion.status === successStatus
|
|
2818
|
+
? 'I’m completing the final Framer verification before I finish.'
|
|
2819
|
+
: 'Nothing is blocking this change, so I’m continuing the work.',
|
|
2809
2820
|
});
|
|
2810
2821
|
const repairResult = await Promise.race([
|
|
2811
2822
|
executeProviderOutcome(
|
package/src/agentOutput.js
CHANGED
|
@@ -444,7 +444,7 @@ export function createClaudeProgressParser(onProgress, options = {}) {
|
|
|
444
444
|
const block = event?.type === 'content_block_start' ? event.content_block : null;
|
|
445
445
|
if (block?.type !== 'tool_use' || !block.id || drafting.has(block.id)) return;
|
|
446
446
|
const shortName = String(block.name || '').replace(/^mcp__instawebai__/, '');
|
|
447
|
-
if (!['framer_apply_changes', 'framer_update_code_file', 'framer_write'].includes(shortName)) return;
|
|
447
|
+
if (!['framer_apply_changes', 'framer_add_svg', 'framer_update_code_file', 'framer_write'].includes(shortName)) return;
|
|
448
448
|
drafting.set(block.id, true);
|
|
449
449
|
emit({
|
|
450
450
|
kind: 'item_started',
|
package/src/config.js
CHANGED
|
@@ -43,9 +43,7 @@ export const BRIDGE_CAPABILITIES = [
|
|
|
43
43
|
'framer-agent-v1',
|
|
44
44
|
'framer-project-bootstrap-v1',
|
|
45
45
|
'framer-project-verification-v1',
|
|
46
|
-
'framer-interaction-verification-
|
|
47
|
-
'framer-behavior-contract-v1',
|
|
48
|
-
'framer-mechanism-verification-v1',
|
|
46
|
+
'framer-interaction-verification-v4',
|
|
49
47
|
'project-shell-v1',
|
|
50
48
|
'build-fingerprint-v1',
|
|
51
49
|
'tool-schema-parity-v1',
|