@agent-flow-board/bridge 0.1.0 → 0.3.0

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 (62) hide show
  1. package/README.md +29 -1
  2. package/dist/checks/appdir.js +105 -0
  3. package/dist/checks/approve.js +213 -0
  4. package/dist/checks/audit.js +126 -0
  5. package/dist/checks/bind.js +100 -0
  6. package/dist/checks/board.js +107 -0
  7. package/dist/checks/broker.js +439 -0
  8. package/dist/checks/browser.js +275 -0
  9. package/dist/checks/browserpool.js +221 -0
  10. package/dist/checks/cache.js +710 -0
  11. package/dist/checks/child.js +211 -0
  12. package/dist/checks/command.js +267 -0
  13. package/dist/checks/commands.js +219 -0
  14. package/dist/checks/connect.js +79 -0
  15. package/dist/checks/connections.js +42 -0
  16. package/dist/checks/copy.js +320 -0
  17. package/dist/checks/dbpool.js +710 -0
  18. package/dist/checks/doctor.js +649 -0
  19. package/dist/checks/envPolicy.js +212 -0
  20. package/dist/checks/envrules.js +322 -0
  21. package/dist/checks/evidence.js +114 -0
  22. package/dist/checks/fsretry.js +29 -0
  23. package/dist/checks/guard.js +188 -0
  24. package/dist/checks/guardrails.js +155 -0
  25. package/dist/checks/importlegacy.js +300 -0
  26. package/dist/checks/install.js +150 -0
  27. package/dist/checks/live.js +76 -0
  28. package/dist/checks/lock.js +207 -0
  29. package/dist/checks/login.js +203 -0
  30. package/dist/checks/mailguard-hook.cjs +216 -0
  31. package/dist/checks/mailguard.js +98 -0
  32. package/dist/checks/paths.js +85 -0
  33. package/dist/checks/preview.js +577 -0
  34. package/dist/checks/profiles.js +110 -0
  35. package/dist/checks/provision.js +175 -0
  36. package/dist/checks/recipe.js +246 -0
  37. package/dist/checks/redact.js +52 -0
  38. package/dist/checks/registry.js +548 -0
  39. package/dist/checks/repoenv.js +162 -0
  40. package/dist/checks/roots.js +144 -0
  41. package/dist/checks/routing.js +68 -0
  42. package/dist/checks/run.js +443 -0
  43. package/dist/checks/sandbox.js +208 -0
  44. package/dist/checks/scheduler.js +383 -0
  45. package/dist/checks/scope.js +383 -0
  46. package/dist/checks/sealedNames.js +39 -0
  47. package/dist/checks/secrets.js +452 -0
  48. package/dist/checks/secretscmd.js +80 -0
  49. package/dist/checks/service.js +589 -0
  50. package/dist/checks/signin.js +79 -0
  51. package/dist/checks/singleflight.js +307 -0
  52. package/dist/checks/store.js +92 -0
  53. package/dist/checks/surface.js +124 -0
  54. package/dist/checks/types.js +2 -0
  55. package/dist/checks/warm.js +342 -0
  56. package/dist/checks/watch.js +228 -0
  57. package/dist/checks/wire.js +87 -0
  58. package/dist/cli.js +18 -1
  59. package/dist/hooks/adapters.js +3 -1
  60. package/dist/hooks/call.js +6 -1
  61. package/dist/hooks/modVersion.js +26 -0
  62. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -8,6 +8,7 @@
8
8
  // agent-flow-board hook claude|antigravity|gemini [event] one hook event from stdin, one JSON object to stdout
9
9
  // agent-flow-board hooks print claude|antigravity|gemini [--org <slug>] the settings to paste into the tool
10
10
  // agent-flow-board git-hook install|uninstall|check the warn-only post-commit hook
11
+ // agent-flow-board check connect|run|pull|bind|watch|status|doctor|clear|setup|disconnect browser checks on this machine (see check usage)
11
12
  // agent-flow-board mockup push <file.html> --server <url> --org <slug> --item <ref> upload one mockup file (never queued)
12
13
  // agent-flow-board mockup kit <file.html> --server <url> --org <slug> --project <key> upload the project's kit (colours, fonts, icons)
13
14
  // -- DEP-MODULES -- //
@@ -95,6 +96,22 @@ async function belongsToOrg(server, org, token) {
95
96
  }
96
97
  }
97
98
  async function main() {
99
+ if (cmd === 'check') {
100
+ // Loaded only here, so the hooks and the MCP forwarder never load the check code or Playwright
101
+ const { checkMain } = await import('./checks/command.js');
102
+ const code = await checkMain({
103
+ args: args.slice(1),
104
+ store,
105
+ fetch: fetchImpl,
106
+ personalToken: (server, org) => tokenFor(server.replace(/\/$/, ''), org, true),
107
+ log,
108
+ out: (line) => process.stdout.write(line + '\n')
109
+ });
110
+ // A browser or a preview may still hold a handle open: the exit code is what the caller reads, so end now
111
+ process.exitCode = code;
112
+ setTimeout(() => process.exit(code), 300).unref();
113
+ return;
114
+ }
98
115
  if (cmd === 'hook') {
99
116
  // A hook prints exactly one JSON object and always exits 0, so it can never break the tool that runs it
100
117
  let out = {};
@@ -258,7 +275,7 @@ async function main() {
258
275
  return;
259
276
  }
260
277
  if (cmd !== 'mcp' && cmd !== 'login') {
261
- log('Usage: agent-flow-board mcp|login|logout --server <url>, setup --org <slug>, queue list|retry <id>|drop <id>, or mockup push <file.html>');
278
+ log('Usage: agent-flow-board mcp|login|logout --server <url>, setup --org <slug>, queue list|retry <id>|drop <id>, mockup push <file.html>, or check connect|run|watch|status');
262
279
  process.exit(2);
263
280
  }
264
281
  const server = serverUrl();
@@ -75,7 +75,9 @@ export const claude = {
75
75
  hookEventName: 'SessionStart',
76
76
  additionalContext: a.context ?? '',
77
77
  ...(a.title ? { sessionTitle: a.title } : {})
78
- }
78
+ },
79
+ // The one line for the person (an older editor status mod), shown once as the conversation starts
80
+ ...(a.notice ? { systemMessage: a.notice } : {})
79
81
  };
80
82
  if (event === 'prompt' && a.title)
81
83
  return { hookSpecificOutput: { hookEventName: 'UserPromptSubmit', sessionTitle: a.title } };
@@ -4,6 +4,7 @@ import { createHash } from 'node:crypto';
4
4
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
5
5
  import { join } from 'node:path';
6
6
  import { configDir } from '../tokenStore.js';
7
+ import { installedModVersion } from './modVersion.js';
7
8
  // -- CONSTANTS -- //
8
9
  const TIMEOUT_MS = 4000;
9
10
  // -- FUNCTIONS -- //
@@ -57,10 +58,14 @@ export async function callHook(o, event) {
57
58
  warnOnce(`the server ${o.server} did not give an organisation for this sign-in.`);
58
59
  return null;
59
60
  }
61
+ // A Claude Code start tells the board which editor status mod is installed, so it can say when a newer one is served
62
+ const modVersion = event.tool === 'claude-code' && event.event === 'start'
63
+ ? installedModVersion(o.home)
64
+ : undefined;
60
65
  const res = await o.fetch(`${o.server}/api/v1/orgs/${org}/hooks`, {
61
66
  method: 'POST',
62
67
  headers: { authorization: `Bearer ${o.token}`, 'content-type': 'application/json' },
63
- body: JSON.stringify(event),
68
+ body: JSON.stringify(modVersion ? { ...event, modVersion } : event),
64
69
  signal: AbortSignal.timeout(TIMEOUT_MS)
65
70
  });
66
71
  if (!res.ok)
@@ -0,0 +1,26 @@
1
+ // THE VERSION OF THE EDITOR STATUS MOD THIS PERSON HAS INSTALLED (AFB-20261108-0856)
2
+ // The setup prompt writes the mod to ~/.claude/skills/afb-flow-status. The hook sends the version on a start so the board can say
3
+ // when a newer one is served. A hook must never fail or slow down because of this file, so every problem means "no version".
4
+ // -- DEP-MODULES -- //
5
+ import { readFileSync } from 'node:fs';
6
+ import { homedir } from 'node:os';
7
+ import { join } from 'node:path';
8
+ // -- CONSTANTS -- //
9
+ const MOD_FOLDER = ['.claude', 'skills', 'afb-flow-status'];
10
+ const VERSION = /^\d{1,6}\.\d{1,6}\.\d{1,6}$/;
11
+ /** A manifest is a few hundred bytes: a file far bigger than that is not read. */
12
+ const MAX_BYTES = 64 * 1024;
13
+ // -- FUNCTIONS -- //
14
+ /** The installed mod's plain major.minor.patch version, or undefined when there is no mod, no readable manifest or no plain version. */
15
+ export function installedModVersion(home = homedir()) {
16
+ try {
17
+ const text = readFileSync(join(home, ...MOD_FOLDER, '.claude-plugin', 'plugin.json'), 'utf8');
18
+ if (text.length > MAX_BYTES)
19
+ return undefined;
20
+ const version = JSON.parse(text).version;
21
+ return typeof version === 'string' && VERSION.test(version) ? version : undefined;
22
+ }
23
+ catch {
24
+ return undefined;
25
+ }
26
+ }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@agent-flow-board/bridge",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
- "description": "Local bridge to an agent-flow-board server: forwards MCP calls over stdio, runs the coding tool hooks and writes the editor status. It holds no tool code.",
5
+ "description": "Local bridge to an agent-flow-board server: forwards MCP calls over stdio, runs the coding tool hooks, writes the editor status and runs browser checks on this machine. It holds no board tool code.",
6
6
  "license": "MIT",
7
7
  "homepage": "https://afb.arbenger.com",
8
8
  "repository": {