@gotcos/glasses-server 6.61.7 → 6.63.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 (70) hide show
  1. package/.env.example +6 -0
  2. package/CHANGELOG.md +39 -0
  3. package/README.md +5 -1
  4. package/bin/cli.cjs +50 -3
  5. package/bin/hooks/cos-cursor-observer.cjs +11 -4
  6. package/bin/hooks/cos-session-hook +46 -11
  7. package/docs/provider-parity.md +43 -0
  8. package/managed-runtime-contract.json +1 -0
  9. package/package.json +4 -2
  10. package/server/index.ts +141 -17
  11. package/server/lib/agent-session-binding-store.ts +9 -3
  12. package/server/lib/agent-session-store.ts +7 -4
  13. package/server/lib/attached-provider-adapter.ts +158 -45
  14. package/server/lib/banned-permission-args.ts +42 -1
  15. package/server/lib/claude-bridge.ts +17 -8
  16. package/server/lib/claude-hooks-installer.ts +22 -2
  17. package/server/lib/codex-bridge.ts +17 -2
  18. package/server/lib/codex-hooks-installer.ts +538 -0
  19. package/server/lib/codex-live-queue.ts +1 -1
  20. package/server/lib/codex-model-catalog.ts +49 -2
  21. package/server/lib/codex-rollout-state.ts +90 -0
  22. package/server/lib/codex-session-posture.ts +528 -0
  23. package/server/lib/continue-plan.ts +180 -0
  24. package/server/lib/continue-read-health.ts +26 -0
  25. package/server/lib/cursor-bridge.ts +26 -6
  26. package/server/lib/cursor-fork-context.ts +140 -0
  27. package/server/lib/cursor-model-catalog.ts +62 -5
  28. package/server/lib/cursor-observer-installer.ts +48 -7
  29. package/server/lib/cursor-session-model.ts +339 -0
  30. package/server/lib/cursor-spawn-env.ts +210 -0
  31. package/server/lib/fork-job-ledger.ts +194 -0
  32. package/server/lib/fork-thread.ts +169 -25
  33. package/server/lib/health-static-probes.ts +21 -11
  34. package/server/lib/lens-gist-engines.ts +15 -4
  35. package/server/lib/lens-gist.ts +1 -1
  36. package/server/lib/live-cues-cursor.ts +16 -6
  37. package/server/lib/occupancy-probes.ts +45 -1
  38. package/server/lib/permission-broker.ts +24 -9
  39. package/server/lib/provider-actions.ts +149 -0
  40. package/server/lib/provider-failure-text.ts +27 -0
  41. package/server/lib/provider-observe.ts +212 -0
  42. package/server/lib/provider-proof.ts +23 -14
  43. package/server/lib/query-job-runtime.ts +16 -1
  44. package/server/lib/query-job-types.ts +2 -1
  45. package/server/lib/session-act-fields.ts +61 -0
  46. package/server/lib/session-cancel.ts +95 -4
  47. package/server/lib/session-continue-facts-real.ts +74 -0
  48. package/server/lib/session-continue-facts.ts +267 -0
  49. package/server/lib/session-halt.ts +67 -6
  50. package/server/lib/session-hook-events.ts +57 -0
  51. package/server/lib/session-hook-ledger.ts +21 -3
  52. package/server/lib/session-hook-spool.ts +68 -6
  53. package/server/lib/session-hooks-runtime.ts +32 -2
  54. package/server/lib/session-peer-inbox-deps.ts +7 -6
  55. package/server/lib/session-recommendation.ts +3 -2
  56. package/server/lib/session-signal-store.ts +74 -5
  57. package/server/lib/session-stream-events.ts +32 -1
  58. package/server/lib/thread-attach-capability.ts +15 -1
  59. package/server/lib/thread-drain-kick.ts +4 -2
  60. package/server/lib/thread-occupancy.ts +44 -0
  61. package/server/lib/thread-turn-queue-deliver.ts +6 -1
  62. package/server/lib/thread-turn-queue.ts +6 -0
  63. package/server/lib/turn-request.ts +274 -0
  64. package/server/routes/agent-session-bindings.ts +349 -26
  65. package/server/routes/agent-session-stream.ts +26 -7
  66. package/server/routes/agent-sessions.ts +155 -10
  67. package/server/routes/health.ts +27 -2
  68. package/server/routes/session-hooks.ts +56 -5
  69. package/server/routes/thread-turn-queue.ts +37 -9
  70. package/server/scripts/hooks-cli.ts +33 -7
@@ -1,15 +1,21 @@
1
1
  #!/usr/bin/env tsx
2
2
  import { installCursorObserver } from '../lib/cursor-observer-installer.js'
3
- // Install, inspect or remove the COS session hook in ~/.claude/settings.json.
3
+ // Install, inspect or remove the COS session hook in ~/.claude/settings.json, and (6.62.0) in
4
+ // ~/.codex/hooks.json when Codex is on this Mac.
4
5
  //
5
- // npx --yes @gotcos/glasses-server@latest --hooks install [--dry-run] [--port 3141]
6
+ // npx --yes @gotcos/glasses-server@latest --hooks install [--dry-run] [--port 3141] [--codex]
6
7
  // npx --yes @gotcos/glasses-server@latest --hooks status
7
- // npx --yes @gotcos/glasses-server@latest --hooks uninstall [--dry-run]
8
+ // npx --yes @gotcos/glasses-server@latest --hooks uninstall [--dry-run] [--codex]
9
+ //
10
+ // `--codex` acts on Codex ONLY (the rollback runbook's `--hooks uninstall --codex` leaves the
11
+ // Claude hooks in place). Without it, Codex rides along when present and never changes the
12
+ // exit code: a Codex refusal is reported under `codex` and Claude's answer stands (B2).
8
13
  //
9
14
  // Prints one JSON document. Exit 0 on success, 2 on a refusal (unparseable or symlinked
10
15
  // settings, a missing packaged script), 64 on a bad argument. Never prints the token.
11
16
 
12
17
  import { hookStatus, hookStatusAdvice, installClaudeHooks, uninstallClaudeHooks } from '../lib/claude-hooks-installer.js'
18
+ import { codexHookAdvice, codexHookStatus, codexPresent, installCodexHooks, refreshCodexHookTrust, uninstallCodexHooks } from '../lib/codex-hooks-installer.js'
13
19
  import { sessionHooksEnabled } from '../lib/session-hooks-runtime.js'
14
20
 
15
21
  const args = process.argv.slice(2)
@@ -20,36 +26,56 @@ const port = portIndex >= 0 ? Number(args[portIndex + 1]) : Number(process.env.P
20
26
  const deskIndex = args.indexOf('--desk-idle-s')
21
27
  const deskIdleSeconds = deskIndex >= 0 ? Number(args[deskIndex + 1]) : Number(process.env.COS_PERMISSION_BROKER_DESK_IDLE_S ?? 90)
22
28
 
29
+ const codexOnly = args.includes('--codex')
30
+
23
31
  function print(value: unknown): void {
24
32
  console.log(JSON.stringify(value, null, 2))
25
33
  }
26
34
 
35
+ /** The Codex half: skipped when Codex is not here; with trust read from Codex itself (K3). */
36
+ async function codexPart(action: 'status' | 'install' | 'uninstall'): Promise<Record<string, unknown> & { ok: boolean }> {
37
+ if (!codexPresent()) return { ok: true, skipped: 'codex_not_present' }
38
+ const result = action === 'status' ? { ok: true, status: codexHookStatus() }
39
+ : action === 'install' ? installCodexHooks({ dryRun }) : uninstallCodexHooks({ dryRun })
40
+ const trust = result.status.installed && !dryRun ? await refreshCodexHookTrust({ fresh: true }) : null
41
+ const advice = action === 'uninstall' ? null : codexHookAdvice(result.status, trust?.trust ?? 'unknown')
42
+ // QA W4: why the trust word is what it is (a failed read's code, `not_listed`), or null.
43
+ return { ...result, ...(trust ? { trust: trust.trust, trustReason: trust.reason } : {}), ...(advice ? { advice } : {}) }
44
+ }
45
+
27
46
  // `serverApplies` says whether the running server would READ the spool into rows: the
28
47
  // hooks can be installed while the feature is off (COS_CLAUDE_SESSIONS_ENABLED unset),
29
48
  // and a status that said only "installed" would hide that.
30
49
  const serverApplies = sessionHooksEnabled()
31
50
  const flagsNote = serverApplies ? undefined : 'Rows change only when the server runs with COS_CLAUDE_SESSIONS_ENABLED=1 (or COS_SESSION_HOOKS=1).'
32
51
 
52
+ if ((action === 'install' || action === 'uninstall') && codexOnly) {
53
+ const codex = await codexPart(action)
54
+ print({ action, dryRun, codexOnly: true, codex })
55
+ process.exit(codex.ok ? 0 : 2)
56
+ }
33
57
  if (action === 'status') {
34
58
  const status = hookStatus()
35
59
  // 6.53.3: say in words what the state means and what fixes it (`script_outdated` after an
36
60
  // update that changed the script, until Install hooks).
37
61
  const advice = hookStatusAdvice(status)
38
- print({ action, serverApplies, ...(flagsNote ? { note: flagsNote } : {}), ...(advice ? { advice } : {}), ...status })
62
+ print({ action, serverApplies, ...(flagsNote ? { note: flagsNote } : {}), ...(advice ? { advice } : {}), ...status, codex: await codexPart('status') })
39
63
  process.exit(0)
40
64
  }
41
65
  if (action === 'install') {
42
66
  if (!Number.isFinite(port) || port <= 0) { console.error('Bad --port'); process.exit(64) }
43
67
  const result = installClaudeHooks({ port, deskIdleSeconds: Number.isFinite(deskIdleSeconds) ? deskIdleSeconds : 90, dryRun })
44
68
  const cursorObserver = result.ok ? installCursorObserver({ dryRun }) : undefined
45
- print({ action, dryRun, serverApplies, ...(flagsNote ? { note: flagsNote } : {}), ...result, cursorObserver })
69
+ const codex = result.ok ? await codexPart('install') : undefined
70
+ print({ action, dryRun, serverApplies, ...(flagsNote ? { note: flagsNote } : {}), ...result, cursorObserver, codex })
46
71
  process.exit(result.ok && cursorObserver?.ok ? 0 : 2)
47
72
  }
48
73
  if (action === 'uninstall') {
49
74
  const result = uninstallClaudeHooks({ dryRun })
50
75
  const cursorObserver = result.ok ? installCursorObserver({ dryRun, uninstall: true }) : undefined
51
- print({ action, dryRun, ...result, cursorObserver })
76
+ const codex = result.ok ? await codexPart('uninstall') : undefined
77
+ print({ action, dryRun, ...result, cursorObserver, codex })
52
78
  process.exit(result.ok && cursorObserver?.ok ? 0 : 2)
53
79
  }
54
- console.error('Usage: --hooks install|status|uninstall [--dry-run] [--port N] [--desk-idle-s N]')
80
+ console.error('Usage: --hooks install|status|uninstall [--dry-run] [--port N] [--desk-idle-s N] [--codex]')
55
81
  process.exit(64)