@andespindola/brainlink 0.1.0-beta.49 → 0.1.0-beta.50
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
CHANGED
|
@@ -406,6 +406,7 @@ blink agent upgrade
|
|
|
406
406
|
```
|
|
407
407
|
|
|
408
408
|
This configures `~/.codex/config.toml` with Brainlink MCP (`brainlink-mcp`) so Brainlink is available by default in agent sessions.
|
|
409
|
+
`agent install` and `agent upgrade` also apply the MCP `fully-auto` bootstrap policy by default (`enforceBootstrap`, `enforceContextFirst`, `autoBootstrapOnRead`, `autoBootstrapOnStartup` all enabled).
|
|
409
410
|
|
|
410
411
|
If you are inside this repository and want plugin gallery setup too:
|
|
411
412
|
|
|
@@ -17,6 +17,7 @@ const worldCoordinateLimit = 5_000_000
|
|
|
17
17
|
const transformCoordinateLimit = 20_000_000
|
|
18
18
|
const hoverHitTestIntervalMs = 64
|
|
19
19
|
const overviewClusterMaxCount = 1400
|
|
20
|
+
const zoomRecoveryGuardMs = 560
|
|
20
21
|
const state = {
|
|
21
22
|
graph: { nodes: [], edges: [] },
|
|
22
23
|
nodes: [],
|
|
@@ -52,7 +53,8 @@ const state = {
|
|
|
52
53
|
macroRepresentative: null,
|
|
53
54
|
filterWorker: null,
|
|
54
55
|
filterReady: false,
|
|
55
|
-
lastHoverHitAt: 0
|
|
56
|
+
lastHoverHitAt: 0,
|
|
57
|
+
lastManualZoomAt: 0
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
const byId = id => document.getElementById(id)
|
|
@@ -1195,7 +1197,8 @@ const render = now => {
|
|
|
1195
1197
|
computeRenderVisibility()
|
|
1196
1198
|
tick(delta)
|
|
1197
1199
|
const hasVisibleNodeOnScreen = state.renderNodes.some((node) => isNodeVisibleOnScreen(node, width, height))
|
|
1198
|
-
|
|
1200
|
+
const manualZoomGuardActive = now - state.lastManualZoomAt < zoomRecoveryGuardMs
|
|
1201
|
+
if (!hasVisibleNodeOnScreen && state.renderNodes.length > 0 && !manualZoomGuardActive) {
|
|
1199
1202
|
state.offscreenFrameCount += 1
|
|
1200
1203
|
if (state.offscreenFrameCount >= 6 && !state.recoveringViewport) {
|
|
1201
1204
|
state.recoveringViewport = true
|
|
@@ -1395,7 +1398,7 @@ const selectNodeById = id => {
|
|
|
1395
1398
|
if (node) selectNode(node, { openContent: true })
|
|
1396
1399
|
}
|
|
1397
1400
|
|
|
1398
|
-
const zoomAtPoint = (screenX, screenY, factor) => {
|
|
1401
|
+
const zoomAtPoint = (screenX, screenY, factor, source = 'generic') => {
|
|
1399
1402
|
const nextScale = clampScale(state.transform.scale * factor)
|
|
1400
1403
|
if (nextScale === state.transform.scale) return
|
|
1401
1404
|
const worldX = (screenX - state.transform.x) / state.transform.scale
|
|
@@ -1404,6 +1407,9 @@ const zoomAtPoint = (screenX, screenY, factor) => {
|
|
|
1404
1407
|
state.transform.x = clampTransformCoordinate(screenX - worldX * nextScale)
|
|
1405
1408
|
state.transform.y = clampTransformCoordinate(screenY - worldY * nextScale)
|
|
1406
1409
|
state.offscreenFrameCount = 0
|
|
1410
|
+
if (source === 'wheel') {
|
|
1411
|
+
state.lastManualZoomAt = performance.now()
|
|
1412
|
+
}
|
|
1407
1413
|
markRenderDirty()
|
|
1408
1414
|
}
|
|
1409
1415
|
|
|
@@ -1422,32 +1428,24 @@ const wheelZoomFactor = event => {
|
|
|
1422
1428
|
return event.deltaY < 0 ? 1 + adjustedStep : 1 / (1 + adjustedStep)
|
|
1423
1429
|
}
|
|
1424
1430
|
|
|
1425
|
-
const isScreenPointInsideCanvas = (screenX, screenY) => {
|
|
1426
|
-
const rect = canvas.getBoundingClientRect()
|
|
1427
|
-
|
|
1428
|
-
return screenX >= rect.left && screenX <= rect.right && screenY >= rect.top && screenY <= rect.bottom
|
|
1429
|
-
}
|
|
1430
|
-
|
|
1431
1431
|
const handleWheelZoom = event => {
|
|
1432
1432
|
if (elements.contentDialog?.open) {
|
|
1433
1433
|
return
|
|
1434
1434
|
}
|
|
1435
1435
|
|
|
1436
|
-
if (!isScreenPointInsideCanvas(event.clientX, event.clientY)) {
|
|
1437
|
-
return
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
1436
|
event.preventDefault()
|
|
1441
1437
|
const rect = canvas.getBoundingClientRect()
|
|
1442
|
-
const
|
|
1443
|
-
const
|
|
1438
|
+
const rawCursorX = Number.isFinite(event.offsetX) ? event.offsetX : event.clientX - rect.left
|
|
1439
|
+
const rawCursorY = Number.isFinite(event.offsetY) ? event.offsetY : event.clientY - rect.top
|
|
1440
|
+
const cursorX = Math.max(0, Math.min(Math.max(rect.width, 320), rawCursorX))
|
|
1441
|
+
const cursorY = Math.max(0, Math.min(Math.max(rect.height, 320), rawCursorY))
|
|
1444
1442
|
const factor = wheelZoomFactor(event)
|
|
1445
1443
|
|
|
1446
1444
|
if (!Number.isFinite(factor) || factor <= 0 || factor === 1) {
|
|
1447
1445
|
return
|
|
1448
1446
|
}
|
|
1449
1447
|
|
|
1450
|
-
zoomAtPoint(cursorX, cursorY, factor)
|
|
1448
|
+
zoomAtPoint(cursorX, cursorY, factor, 'wheel')
|
|
1451
1449
|
}
|
|
1452
1450
|
|
|
1453
1451
|
const bindEvents = () => {
|
|
@@ -1493,7 +1491,7 @@ const bindEvents = () => {
|
|
|
1493
1491
|
}
|
|
1494
1492
|
if (event.target === elements.contentDialog) elements.contentDialog.close()
|
|
1495
1493
|
})
|
|
1496
|
-
|
|
1494
|
+
canvas.addEventListener('wheel', handleWheelZoom, { passive: false })
|
|
1497
1495
|
canvas.addEventListener('dblclick', event => {
|
|
1498
1496
|
const rect = canvas.getBoundingClientRect()
|
|
1499
1497
|
const cursorX = event.clientX - rect.left
|
|
@@ -141,6 +141,12 @@ const parseAllowedVaults = (value) => {
|
|
|
141
141
|
export const installAgentIntegration = async (input) => {
|
|
142
142
|
const codexConfigPath = getCodexConfigPath();
|
|
143
143
|
const allowedVaults = parseAllowedVaults(input.allowedVaults);
|
|
144
|
+
const bootstrapPolicy = await setBootstrapPolicy({
|
|
145
|
+
enforceBootstrap: true,
|
|
146
|
+
enforceContextFirst: true,
|
|
147
|
+
autoBootstrapOnRead: true,
|
|
148
|
+
autoBootstrapOnStartup: true
|
|
149
|
+
});
|
|
144
150
|
await upsertCodexMcpConfig(codexConfigPath, {
|
|
145
151
|
allowedVaults,
|
|
146
152
|
brainlinkHome: input.brainlinkHome
|
|
@@ -195,6 +201,7 @@ export const installAgentIntegration = async (input) => {
|
|
|
195
201
|
codexConfigPath,
|
|
196
202
|
mcpServer: 'brainlink',
|
|
197
203
|
command: 'brainlink-mcp',
|
|
204
|
+
bootstrapPolicy,
|
|
198
205
|
...(input.mcpOnly !== true ? { pluginSourcePath, pluginSymlinkPath, marketplacePath } : {}),
|
|
199
206
|
...(selfTestResult ? { selfTest: selfTestResult } : {}),
|
|
200
207
|
...(warnings.length > 0 ? { warnings } : {})
|
package/docs/AGENT_USAGE.md
CHANGED
|
@@ -404,6 +404,7 @@ blink agent status
|
|
|
404
404
|
```
|
|
405
405
|
|
|
406
406
|
`agent install` configures Brainlink MCP in `~/.codex/config.toml` so compatible agents can use Brainlink by default.
|
|
407
|
+
`agent install` and `agent upgrade` automatically apply the `fully-auto` MCP bootstrap policy (`enforceBootstrap=true`, `enforceContextFirst=true`, `autoBootstrapOnRead=true`, `autoBootstrapOnStartup=true`) so all plug-and-play Brainlink features start enabled.
|
|
407
408
|
Use `agent upgrade` on legacy installations to reapply the latest defaults and run self-test diagnostics.
|
|
408
409
|
Use `agent policy --preset fully-auto` to keep startup/read auto-bootstrap enabled, or `agent policy --preset strict` to force explicit bootstrap calls.
|
|
409
410
|
|
package/package.json
CHANGED