@runcore-sh/runcore 0.1.8 → 0.1.10

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 (225) hide show
  1. package/dist/access/manifest.d.ts +59 -0
  2. package/dist/access/manifest.d.ts.map +1 -0
  3. package/dist/access/manifest.js +251 -0
  4. package/dist/access/manifest.js.map +1 -0
  5. package/dist/activity/log.d.ts +1 -1
  6. package/dist/activity/log.d.ts.map +1 -1
  7. package/dist/agents/autonomous.d.ts.map +1 -1
  8. package/dist/agents/autonomous.js +38 -0
  9. package/dist/agents/autonomous.js.map +1 -1
  10. package/dist/agents/governance.d.ts +70 -0
  11. package/dist/agents/governance.d.ts.map +1 -0
  12. package/dist/agents/governance.js +220 -0
  13. package/dist/agents/governance.js.map +1 -0
  14. package/dist/agents/governed-spawn.d.ts +83 -0
  15. package/dist/agents/governed-spawn.d.ts.map +1 -0
  16. package/dist/agents/governed-spawn.js +186 -0
  17. package/dist/agents/governed-spawn.js.map +1 -0
  18. package/dist/agents/heartbeat.d.ts +91 -0
  19. package/dist/agents/heartbeat.d.ts.map +1 -0
  20. package/dist/agents/heartbeat.js +323 -0
  21. package/dist/agents/heartbeat.js.map +1 -0
  22. package/dist/agents/index.d.ts +4 -1
  23. package/dist/agents/index.d.ts.map +1 -1
  24. package/dist/agents/index.js +6 -1
  25. package/dist/agents/index.js.map +1 -1
  26. package/dist/agents/spawn-policy.d.ts +45 -0
  27. package/dist/agents/spawn-policy.d.ts.map +1 -0
  28. package/dist/agents/spawn-policy.js +202 -0
  29. package/dist/agents/spawn-policy.js.map +1 -0
  30. package/dist/alert.d.ts +16 -0
  31. package/dist/alert.d.ts.map +1 -0
  32. package/dist/alert.js +70 -0
  33. package/dist/alert.js.map +1 -0
  34. package/dist/cli.js +261 -32
  35. package/dist/cli.js.map +1 -1
  36. package/dist/credentials/store.d.ts +1 -1
  37. package/dist/credentials/store.d.ts.map +1 -1
  38. package/dist/credentials/store.js +14 -3
  39. package/dist/credentials/store.js.map +1 -1
  40. package/dist/crystallizer.d.ts +56 -0
  41. package/dist/crystallizer.d.ts.map +1 -0
  42. package/dist/crystallizer.js +159 -0
  43. package/dist/crystallizer.js.map +1 -0
  44. package/dist/distiller.d.ts +48 -0
  45. package/dist/distiller.d.ts.map +1 -0
  46. package/dist/distiller.js +140 -0
  47. package/dist/distiller.js.map +1 -0
  48. package/dist/files/deep-index.d.ts +59 -0
  49. package/dist/files/deep-index.d.ts.map +1 -0
  50. package/dist/files/deep-index.js +337 -0
  51. package/dist/files/deep-index.js.map +1 -0
  52. package/dist/files/import.d.ts +44 -0
  53. package/dist/files/import.d.ts.map +1 -0
  54. package/dist/files/import.js +213 -0
  55. package/dist/files/import.js.map +1 -0
  56. package/dist/files/index-local.d.ts +37 -0
  57. package/dist/files/index-local.d.ts.map +1 -0
  58. package/dist/files/index-local.js +198 -0
  59. package/dist/files/index-local.js.map +1 -0
  60. package/dist/google/auth.d.ts +2 -0
  61. package/dist/google/auth.d.ts.map +1 -1
  62. package/dist/google/auth.js +2 -0
  63. package/dist/google/auth.js.map +1 -1
  64. package/dist/integrations/gate.d.ts +40 -0
  65. package/dist/integrations/gate.d.ts.map +1 -0
  66. package/dist/integrations/gate.js +100 -0
  67. package/dist/integrations/gate.js.map +1 -0
  68. package/dist/lib/audit.d.ts +43 -0
  69. package/dist/lib/audit.d.ts.map +1 -0
  70. package/dist/lib/audit.js +120 -0
  71. package/dist/lib/audit.js.map +1 -0
  72. package/dist/lib/brain-io.d.ts.map +1 -1
  73. package/dist/lib/brain-io.js +52 -0
  74. package/dist/lib/brain-io.js.map +1 -1
  75. package/dist/lib/dpapi.d.ts +14 -0
  76. package/dist/lib/dpapi.d.ts.map +1 -0
  77. package/dist/lib/dpapi.js +104 -0
  78. package/dist/lib/dpapi.js.map +1 -0
  79. package/dist/lib/glob-match.d.ts +22 -0
  80. package/dist/lib/glob-match.d.ts.map +1 -0
  81. package/dist/lib/glob-match.js +64 -0
  82. package/dist/lib/glob-match.js.map +1 -0
  83. package/dist/lib/locked.d.ts +40 -0
  84. package/dist/lib/locked.d.ts.map +1 -0
  85. package/dist/lib/locked.js +130 -0
  86. package/dist/lib/locked.js.map +1 -0
  87. package/dist/llm/complete.d.ts.map +1 -1
  88. package/dist/llm/complete.js +5 -2
  89. package/dist/llm/complete.js.map +1 -1
  90. package/dist/llm/fetch-guard.d.ts +16 -0
  91. package/dist/llm/fetch-guard.d.ts.map +1 -0
  92. package/dist/llm/fetch-guard.js +61 -0
  93. package/dist/llm/fetch-guard.js.map +1 -0
  94. package/dist/llm/guard.d.ts +40 -0
  95. package/dist/llm/guard.d.ts.map +1 -0
  96. package/dist/llm/guard.js +88 -0
  97. package/dist/llm/guard.js.map +1 -0
  98. package/dist/llm/membrane.d.ts +46 -0
  99. package/dist/llm/membrane.d.ts.map +1 -0
  100. package/dist/llm/membrane.js +123 -0
  101. package/dist/llm/membrane.js.map +1 -0
  102. package/dist/llm/providers/index.d.ts +5 -1
  103. package/dist/llm/providers/index.d.ts.map +1 -1
  104. package/dist/llm/providers/index.js +8 -1
  105. package/dist/llm/providers/index.js.map +1 -1
  106. package/dist/llm/redact.d.ts +39 -0
  107. package/dist/llm/redact.d.ts.map +1 -0
  108. package/dist/llm/redact.js +155 -0
  109. package/dist/llm/redact.js.map +1 -0
  110. package/dist/llm/sensitive-registry.d.ts +33 -0
  111. package/dist/llm/sensitive-registry.d.ts.map +1 -0
  112. package/dist/llm/sensitive-registry.js +106 -0
  113. package/dist/llm/sensitive-registry.js.map +1 -0
  114. package/dist/mcp-server.d.ts +11 -0
  115. package/dist/mcp-server.d.ts.map +1 -0
  116. package/dist/mcp-server.js +520 -0
  117. package/dist/mcp-server.js.map +1 -0
  118. package/dist/mdns.d.ts +17 -0
  119. package/dist/mdns.d.ts.map +1 -0
  120. package/dist/mdns.js +110 -0
  121. package/dist/mdns.js.map +1 -0
  122. package/dist/nerve/push.d.ts +26 -0
  123. package/dist/nerve/push.d.ts.map +1 -0
  124. package/dist/nerve/push.js +170 -0
  125. package/dist/nerve/push.js.map +1 -0
  126. package/dist/nerve/state.d.ts +35 -0
  127. package/dist/nerve/state.d.ts.map +1 -0
  128. package/dist/nerve/state.js +257 -0
  129. package/dist/nerve/state.js.map +1 -0
  130. package/dist/posture/engine.d.ts +41 -0
  131. package/dist/posture/engine.d.ts.map +1 -0
  132. package/dist/posture/engine.js +217 -0
  133. package/dist/posture/engine.js.map +1 -0
  134. package/dist/posture/index.d.ts +11 -0
  135. package/dist/posture/index.d.ts.map +1 -0
  136. package/dist/posture/index.js +10 -0
  137. package/dist/posture/index.js.map +1 -0
  138. package/dist/posture/middleware.d.ts +30 -0
  139. package/dist/posture/middleware.d.ts.map +1 -0
  140. package/dist/posture/middleware.js +92 -0
  141. package/dist/posture/middleware.js.map +1 -0
  142. package/dist/posture/types.d.ts +61 -0
  143. package/dist/posture/types.d.ts.map +1 -0
  144. package/dist/posture/types.js +48 -0
  145. package/dist/posture/types.js.map +1 -0
  146. package/dist/resend/inbox.d.ts +23 -0
  147. package/dist/resend/inbox.d.ts.map +1 -0
  148. package/dist/resend/inbox.js +198 -0
  149. package/dist/resend/inbox.js.map +1 -0
  150. package/dist/resend/webhooks.d.ts +30 -0
  151. package/dist/resend/webhooks.d.ts.map +1 -0
  152. package/dist/resend/webhooks.js +244 -0
  153. package/dist/resend/webhooks.js.map +1 -0
  154. package/dist/server.d.ts +5 -1
  155. package/dist/server.d.ts.map +1 -1
  156. package/dist/server.js +773 -58
  157. package/dist/server.js.map +1 -1
  158. package/dist/settings.d.ts +14 -1
  159. package/dist/settings.d.ts.map +1 -1
  160. package/dist/settings.js +32 -1
  161. package/dist/settings.js.map +1 -1
  162. package/dist/tier/bond.d.ts +51 -0
  163. package/dist/tier/bond.d.ts.map +1 -0
  164. package/dist/tier/bond.js +154 -0
  165. package/dist/tier/bond.js.map +1 -0
  166. package/dist/tier/freeze.d.ts +21 -0
  167. package/dist/tier/freeze.d.ts.map +1 -0
  168. package/dist/tier/freeze.js +73 -0
  169. package/dist/tier/freeze.js.map +1 -0
  170. package/dist/tier/gate.d.ts +11 -0
  171. package/dist/tier/gate.d.ts.map +1 -0
  172. package/dist/tier/gate.js +25 -0
  173. package/dist/tier/gate.js.map +1 -0
  174. package/dist/tier/heartbeat.d.ts +22 -0
  175. package/dist/tier/heartbeat.d.ts.map +1 -0
  176. package/dist/tier/heartbeat.js +128 -0
  177. package/dist/tier/heartbeat.js.map +1 -0
  178. package/dist/tier/token.d.ts +22 -0
  179. package/dist/tier/token.d.ts.map +1 -0
  180. package/dist/tier/token.js +100 -0
  181. package/dist/tier/token.js.map +1 -0
  182. package/dist/tier/types.d.ts +44 -0
  183. package/dist/tier/types.d.ts.map +1 -0
  184. package/dist/tier/types.js +61 -0
  185. package/dist/tier/types.js.map +1 -0
  186. package/dist/updater.d.ts +32 -0
  187. package/dist/updater.d.ts.map +1 -0
  188. package/dist/updater.js +145 -0
  189. package/dist/updater.js.map +1 -0
  190. package/dist/vault/policy.d.ts +42 -0
  191. package/dist/vault/policy.d.ts.map +1 -0
  192. package/dist/vault/policy.js +159 -0
  193. package/dist/vault/policy.js.map +1 -0
  194. package/dist/vault/store.d.ts +6 -0
  195. package/dist/vault/store.d.ts.map +1 -1
  196. package/dist/vault/store.js +15 -5
  197. package/dist/vault/store.js.map +1 -1
  198. package/dist/vault/transfer.d.ts +33 -0
  199. package/dist/vault/transfer.d.ts.map +1 -0
  200. package/dist/vault/transfer.js +187 -0
  201. package/dist/vault/transfer.js.map +1 -0
  202. package/dist/voucher.d.ts +39 -0
  203. package/dist/voucher.d.ts.map +1 -0
  204. package/dist/voucher.js +105 -0
  205. package/dist/voucher.js.map +1 -0
  206. package/dist/webhooks/handlers.d.ts +10 -0
  207. package/dist/webhooks/handlers.d.ts.map +1 -1
  208. package/dist/webhooks/handlers.js +53 -0
  209. package/dist/webhooks/handlers.js.map +1 -1
  210. package/dist/webhooks/index.d.ts +2 -2
  211. package/dist/webhooks/index.d.ts.map +1 -1
  212. package/dist/webhooks/index.js +2 -2
  213. package/dist/webhooks/index.js.map +1 -1
  214. package/dist/webhooks/verify.d.ts +8 -0
  215. package/dist/webhooks/verify.d.ts.map +1 -1
  216. package/dist/webhooks/verify.js +56 -0
  217. package/dist/webhooks/verify.js.map +1 -1
  218. package/package.json +8 -2
  219. package/public/board.html +8 -3
  220. package/public/browser.html +8 -3
  221. package/public/library.html +8 -3
  222. package/public/observatory.html +8 -3
  223. package/public/ops.html +8 -3
  224. package/public/registry.html +627 -0
  225. package/public/roadmap.html +975 -0
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Posture Engine — observes interaction patterns and adapts UI surface.
3
+ *
4
+ * The UI assembles itself around the user:
5
+ * - No interaction → silent mode, Core reaches out proactively
6
+ * - Light touches (pulse checks) → pulse mode
7
+ * - Deep dives (pages, agent logs, settings) → board mode
8
+ *
9
+ * Transitions happen automatically based on intent accumulation.
10
+ * The user can also pin a posture to lock it.
11
+ * Posture decays toward silent over time — if you stop looking, the UI fades.
12
+ */
13
+ import type { PostureName, PostureState, PostureSurface, InteractionSignal } from "./types.js";
14
+ /** Get current posture. */
15
+ export declare function getPosture(): PostureName;
16
+ /** Get current posture state (full details). */
17
+ export declare function getPostureState(): PostureState;
18
+ /** Get the surface map for the current posture. */
19
+ export declare function getSurface(): PostureSurface;
20
+ /** Check if a specific surface is available. */
21
+ export declare function hasSurface(surface: keyof PostureSurface): boolean;
22
+ /**
23
+ * Record an interaction signal. This is the primary input to the posture engine.
24
+ * Called by route handlers, middleware, or UI events.
25
+ */
26
+ export declare function recordInteraction(signal: InteractionSignal): void;
27
+ /**
28
+ * Pin the current posture — locks auto-transitions until unpinned.
29
+ * User explicitly chose this level. Respect it.
30
+ */
31
+ export declare function pinPosture(posture: PostureName): void;
32
+ /** Unpin — allow auto-transitions again. */
33
+ export declare function unpinPosture(): void;
34
+ /** Check for decay — called on a timer or at startup. */
35
+ export declare function evaluateDecay(): void;
36
+ /** Load posture state from brain/settings.json. */
37
+ export declare function loadPosture(): Promise<void>;
38
+ /** Start the decay check timer — runs hourly. */
39
+ export declare function startDecayTimer(): void;
40
+ export declare function stopDecayTimer(): void;
41
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/posture/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,cAAc,EACd,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAyCpB,2BAA2B;AAC3B,wBAAgB,UAAU,IAAI,WAAW,CAExC;AAED,gDAAgD;AAChD,wBAAgB,eAAe,IAAI,YAAY,CAE9C;AAED,mDAAmD;AACnD,wBAAgB,UAAU,IAAI,cAAc,CAE3C;AAED,gDAAgD;AAChD,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,cAAc,GAAG,OAAO,CAEjE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAgBjE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAMrD;AAED,4CAA4C;AAC5C,wBAAgB,YAAY,IAAI,IAAI,CAInC;AAiCD,yDAAyD;AACzD,wBAAgB,aAAa,IAAI,IAAI,CAgBpC;AAoBD,mDAAmD;AACnD,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAqBjD;AA8BD,iDAAiD;AACjD,wBAAgB,eAAe,IAAI,IAAI,CAItC;AAED,wBAAgB,cAAc,IAAI,IAAI,CAKrC"}
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Posture Engine — observes interaction patterns and adapts UI surface.
3
+ *
4
+ * The UI assembles itself around the user:
5
+ * - No interaction → silent mode, Core reaches out proactively
6
+ * - Light touches (pulse checks) → pulse mode
7
+ * - Deep dives (pages, agent logs, settings) → board mode
8
+ *
9
+ * Transitions happen automatically based on intent accumulation.
10
+ * The user can also pin a posture to lock it.
11
+ * Posture decays toward silent over time — if you stop looking, the UI fades.
12
+ */
13
+ import { readFile, writeFile } from "node:fs/promises";
14
+ import { join, resolve } from "node:path";
15
+ import { createLogger } from "../utils/logger.js";
16
+ import { POSTURE_SURFACE } from "./types.js";
17
+ const log = createLogger("posture");
18
+ const BRAIN_DIR = resolve(process.cwd(), "brain");
19
+ const STATE_PATH = join(BRAIN_DIR, "settings.json");
20
+ // ── In-memory state ─────────────────────────────────────────────────────────
21
+ const DEFAULT_STATE = {
22
+ current: "silent",
23
+ changedAt: new Date().toISOString(),
24
+ pinned: false,
25
+ interactions: {},
26
+ windowStart: new Date().toISOString(),
27
+ };
28
+ let state = { ...DEFAULT_STATE };
29
+ // ── Thresholds ──────────────────────────────────────────────────────────────
30
+ /** Interactions in a 24h window to trigger escalation */
31
+ const ESCALATION_THRESHOLDS = {
32
+ /** Any interaction at all → at least pulse */
33
+ toPulse: 1,
34
+ /** Deep interactions (pages, agents, settings) → board */
35
+ toBoard: 5,
36
+ };
37
+ /** Hours of silence before decay */
38
+ const DECAY_HOURS = {
39
+ /** Board → pulse after this many hours of no interaction */
40
+ boardToPulse: 48,
41
+ /** Pulse → silent after this many hours of no interaction */
42
+ pulseToSilent: 168, // 1 week
43
+ };
44
+ const WINDOW_MS = 24 * 60 * 60 * 1000; // 24h rolling window
45
+ // ── Core API ────────────────────────────────────────────────────────────────
46
+ /** Get current posture. */
47
+ export function getPosture() {
48
+ return state.current;
49
+ }
50
+ /** Get current posture state (full details). */
51
+ export function getPostureState() {
52
+ return { ...state };
53
+ }
54
+ /** Get the surface map for the current posture. */
55
+ export function getSurface() {
56
+ return POSTURE_SURFACE[state.current];
57
+ }
58
+ /** Check if a specific surface is available. */
59
+ export function hasSurface(surface) {
60
+ return POSTURE_SURFACE[state.current][surface];
61
+ }
62
+ /**
63
+ * Record an interaction signal. This is the primary input to the posture engine.
64
+ * Called by route handlers, middleware, or UI events.
65
+ */
66
+ export function recordInteraction(signal) {
67
+ // Reset window if expired
68
+ const windowAge = Date.now() - new Date(state.windowStart).getTime();
69
+ if (windowAge > WINDOW_MS) {
70
+ state.interactions = {};
71
+ state.windowStart = new Date().toISOString();
72
+ }
73
+ // Increment counter for this surface
74
+ const key = signal.detail ? `${signal.surface}:${signal.detail}` : signal.surface;
75
+ state.interactions[key] = (state.interactions[key] || 0) + 1;
76
+ // Evaluate transition
77
+ if (!state.pinned) {
78
+ evaluateEscalation(signal);
79
+ }
80
+ }
81
+ /**
82
+ * Pin the current posture — locks auto-transitions until unpinned.
83
+ * User explicitly chose this level. Respect it.
84
+ */
85
+ export function pinPosture(posture) {
86
+ state.current = posture;
87
+ state.pinned = true;
88
+ state.changedAt = new Date().toISOString();
89
+ log.info(`Posture pinned: ${posture}`);
90
+ saveState();
91
+ }
92
+ /** Unpin — allow auto-transitions again. */
93
+ export function unpinPosture() {
94
+ state.pinned = false;
95
+ log.info("Posture unpinned — auto-transitions enabled");
96
+ saveState();
97
+ }
98
+ // ── Transition logic ────────────────────────────────────────────────────────
99
+ function evaluateEscalation(signal) {
100
+ const prev = state.current;
101
+ const deepSurfaces = ["pages", "agents", "settings", "page-view"];
102
+ const isDeep = deepSurfaces.includes(signal.surface);
103
+ // Count deep interactions in current window
104
+ const deepCount = Object.entries(state.interactions)
105
+ .filter(([k]) => deepSurfaces.some(s => k.startsWith(s)))
106
+ .reduce((sum, [, v]) => sum + v, 0);
107
+ const totalCount = Object.values(state.interactions)
108
+ .reduce((sum, v) => sum + v, 0);
109
+ if (state.current === "silent") {
110
+ if (totalCount >= ESCALATION_THRESHOLDS.toPulse) {
111
+ transition("pulse");
112
+ }
113
+ }
114
+ else if (state.current === "pulse") {
115
+ if (isDeep && deepCount >= ESCALATION_THRESHOLDS.toBoard) {
116
+ transition("board");
117
+ }
118
+ }
119
+ // Board doesn't escalate further — it's the max
120
+ if (state.current !== prev) {
121
+ log.info(`Posture escalated: ${prev} → ${state.current} (${signal.surface})`);
122
+ }
123
+ }
124
+ /** Check for decay — called on a timer or at startup. */
125
+ export function evaluateDecay() {
126
+ if (state.pinned)
127
+ return;
128
+ const hoursSinceChange = (Date.now() - new Date(state.changedAt).getTime()) / (60 * 60 * 1000);
129
+ const hoursSinceInteraction = getHoursSinceLastInteraction();
130
+ const prev = state.current;
131
+ if (state.current === "board" && hoursSinceInteraction >= DECAY_HOURS.boardToPulse) {
132
+ transition("pulse");
133
+ }
134
+ else if (state.current === "pulse" && hoursSinceInteraction >= DECAY_HOURS.pulseToSilent) {
135
+ transition("silent");
136
+ }
137
+ if (state.current !== prev) {
138
+ log.info(`Posture decayed: ${prev} → ${state.current} (${hoursSinceInteraction.toFixed(0)}h silent)`);
139
+ }
140
+ }
141
+ function getHoursSinceLastInteraction() {
142
+ // Use window start + max interaction timestamp
143
+ const windowAge = Date.now() - new Date(state.windowStart).getTime();
144
+ if (Object.keys(state.interactions).length === 0) {
145
+ return (Date.now() - new Date(state.changedAt).getTime()) / (60 * 60 * 1000);
146
+ }
147
+ // If there are interactions in the window, consider the window recent
148
+ return windowAge / (60 * 60 * 1000);
149
+ }
150
+ function transition(to) {
151
+ state.current = to;
152
+ state.changedAt = new Date().toISOString();
153
+ saveState();
154
+ }
155
+ // ── Persistence ─────────────────────────────────────────────────────────────
156
+ /** Load posture state from brain/settings.json. */
157
+ export async function loadPosture() {
158
+ try {
159
+ const raw = await readFile(STATE_PATH, "utf-8");
160
+ const settings = JSON.parse(raw);
161
+ if (settings.posture) {
162
+ state = {
163
+ current: settings.posture.current || "silent",
164
+ changedAt: settings.posture.changedAt || new Date().toISOString(),
165
+ pinned: settings.posture.pinned || false,
166
+ interactions: settings.posture.interactions || {},
167
+ windowStart: settings.posture.windowStart || new Date().toISOString(),
168
+ };
169
+ log.info(`Posture loaded: ${state.current}${state.pinned ? " (pinned)" : ""}`);
170
+ }
171
+ }
172
+ catch {
173
+ // No settings yet — start silent
174
+ state = { ...DEFAULT_STATE };
175
+ }
176
+ // Check for decay on load
177
+ evaluateDecay();
178
+ }
179
+ async function saveState() {
180
+ try {
181
+ let settings = {};
182
+ try {
183
+ const raw = await readFile(STATE_PATH, "utf-8");
184
+ settings = JSON.parse(raw);
185
+ }
186
+ catch { /* new file */ }
187
+ settings.posture = {
188
+ current: state.current,
189
+ changedAt: state.changedAt,
190
+ pinned: state.pinned,
191
+ interactions: state.interactions,
192
+ windowStart: state.windowStart,
193
+ };
194
+ await writeFile(STATE_PATH, JSON.stringify(settings, null, 2), "utf-8");
195
+ }
196
+ catch (err) {
197
+ log.warn("Failed to save posture state", {
198
+ error: err instanceof Error ? err.message : String(err),
199
+ });
200
+ }
201
+ }
202
+ // ── Decay timer ─────────────────────────────────────────────────────────────
203
+ let decayTimer = null;
204
+ /** Start the decay check timer — runs hourly. */
205
+ export function startDecayTimer() {
206
+ if (decayTimer)
207
+ return;
208
+ decayTimer = setInterval(() => evaluateDecay(), 60 * 60 * 1000);
209
+ log.info("Posture decay timer started (1h interval)");
210
+ }
211
+ export function stopDecayTimer() {
212
+ if (decayTimer) {
213
+ clearInterval(decayTimer);
214
+ decayTimer = null;
215
+ }
216
+ }
217
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/posture/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Posture module — UI surface assembly around the user.
3
+ *
4
+ * Three modes: silent → pulse → board.
5
+ * Driven by intent accumulation, not configuration.
6
+ */
7
+ export { getPosture, getPostureState, getSurface, hasSurface, recordInteraction, pinPosture, unpinPosture, evaluateDecay, loadPosture, startDecayTimer, stopDecayTimer, } from "./engine.js";
8
+ export { postureTracker, pageViewTracker, requireSurface, postureHeader, } from "./middleware.js";
9
+ export type { PostureName, PostureState, PostureSurface, InteractionSignal, } from "./types.js";
10
+ export { POSTURE_SURFACE, POSTURE_LEVEL } from "./types.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/posture/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,UAAU,EACV,eAAe,EACf,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,EACd,eAAe,EACf,cAAc,EACd,aAAa,GACd,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,WAAW,EACX,YAAY,EACZ,cAAc,EACd,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Posture module — UI surface assembly around the user.
3
+ *
4
+ * Three modes: silent → pulse → board.
5
+ * Driven by intent accumulation, not configuration.
6
+ */
7
+ export { getPosture, getPostureState, getSurface, hasSurface, recordInteraction, pinPosture, unpinPosture, evaluateDecay, loadPosture, startDecayTimer, stopDecayTimer, } from "./engine.js";
8
+ export { postureTracker, pageViewTracker, requireSurface, postureHeader, } from "./middleware.js";
9
+ export { POSTURE_SURFACE, POSTURE_LEVEL } from "./types.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/posture/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,UAAU,EACV,eAAe,EACf,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,EACd,eAAe,EACf,cAAc,EACd,aAAa,GACd,MAAM,iBAAiB,CAAC;AASzB,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Posture middleware — gates routes by current UI surface level
3
+ * and records interaction signals for intent accumulation.
4
+ *
5
+ * Routes return 404 (not 403) when posture is below threshold.
6
+ * The surface doesn't exist yet — it's not forbidden, it's not assembled.
7
+ */
8
+ import type { MiddlewareHandler } from "hono";
9
+ import type { PostureSurface } from "./types.js";
10
+ /**
11
+ * Middleware: record every API interaction as a signal.
12
+ * Mounted early — runs for all /api/* routes.
13
+ */
14
+ export declare function postureTracker(): MiddlewareHandler;
15
+ /**
16
+ * Middleware: record page views (HTML page loads).
17
+ * Mounted on page routes like /board, /ops, /observatory, etc.
18
+ */
19
+ export declare function pageViewTracker(pageName: string): MiddlewareHandler;
20
+ /**
21
+ * Require a minimum posture level for a route group.
22
+ * Returns 404 if the surface isn't assembled yet.
23
+ */
24
+ export declare function requireSurface(surface: keyof PostureSurface): MiddlewareHandler;
25
+ /**
26
+ * Add posture info to API responses via header.
27
+ * Clients use this to know what to render.
28
+ */
29
+ export declare function postureHeader(): MiddlewareHandler;
30
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/posture/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAE9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,iBAAiB,CAsClD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CASnE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,cAAc,GAAG,iBAAiB,CAO/E;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,iBAAiB,CAMjD"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Posture middleware — gates routes by current UI surface level
3
+ * and records interaction signals for intent accumulation.
4
+ *
5
+ * Routes return 404 (not 403) when posture is below threshold.
6
+ * The surface doesn't exist yet — it's not forbidden, it's not assembled.
7
+ */
8
+ import { hasSurface, recordInteraction, getSurface } from "./engine.js";
9
+ /**
10
+ * Middleware: record every API interaction as a signal.
11
+ * Mounted early — runs for all /api/* routes.
12
+ */
13
+ export function postureTracker() {
14
+ return async (c, next) => {
15
+ const path = c.req.path;
16
+ // Classify the interaction
17
+ let surface = "chat";
18
+ let detail;
19
+ if (path.startsWith("/api/nerve") || path.startsWith("/api/pulse")) {
20
+ surface = "pulse";
21
+ }
22
+ else if (path.startsWith("/api/board")) {
23
+ surface = "pages";
24
+ detail = "board";
25
+ }
26
+ else if (path.startsWith("/api/ops")) {
27
+ surface = "pages";
28
+ detail = "ops";
29
+ }
30
+ else if (path.startsWith("/api/agents")) {
31
+ surface = "agents";
32
+ }
33
+ else if (path.startsWith("/api/settings") || path.startsWith("/api/admin")) {
34
+ surface = "settings";
35
+ }
36
+ else if (path.startsWith("/api/open-loops") || path.startsWith("/api/insights") || path.startsWith("/api/metrics")) {
37
+ surface = "pages";
38
+ detail = "observatory";
39
+ }
40
+ else if (path.startsWith("/api/chat")) {
41
+ surface = "chat";
42
+ }
43
+ else if (path.startsWith("/api/browse") || path.startsWith("/api/search")) {
44
+ surface = "pages";
45
+ detail = "browser";
46
+ }
47
+ recordInteraction({
48
+ timestamp: new Date().toISOString(),
49
+ surface,
50
+ detail,
51
+ });
52
+ await next();
53
+ };
54
+ }
55
+ /**
56
+ * Middleware: record page views (HTML page loads).
57
+ * Mounted on page routes like /board, /ops, /observatory, etc.
58
+ */
59
+ export function pageViewTracker(pageName) {
60
+ return async (c, next) => {
61
+ recordInteraction({
62
+ timestamp: new Date().toISOString(),
63
+ surface: "page-view",
64
+ detail: pageName,
65
+ });
66
+ await next();
67
+ };
68
+ }
69
+ /**
70
+ * Require a minimum posture level for a route group.
71
+ * Returns 404 if the surface isn't assembled yet.
72
+ */
73
+ export function requireSurface(surface) {
74
+ return async (c, next) => {
75
+ if (!hasSurface(surface)) {
76
+ return c.json({ error: "not_available", posture: "surface not assembled" }, 404);
77
+ }
78
+ await next();
79
+ };
80
+ }
81
+ /**
82
+ * Add posture info to API responses via header.
83
+ * Clients use this to know what to render.
84
+ */
85
+ export function postureHeader() {
86
+ return async (c, next) => {
87
+ await next();
88
+ const surface = getSurface();
89
+ c.header("X-Posture-Surface", JSON.stringify(surface));
90
+ };
91
+ }
92
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/posture/middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Posture — how much UI surface assembles around the user.
3
+ *
4
+ * Three modes:
5
+ * - silent: No UI. Core works in background. Reaches out via chat/SMS/email.
6
+ * - pulse: Three dots only. Tap for drill-down. Zero-to-one interaction.
7
+ * - board: Full visibility. Threads, agents, memory, operations.
8
+ *
9
+ * Posture is orthogonal to tier (capabilities) and bonding (trust).
10
+ * A BYOK user might be silent. A Spawn user might only want pulse.
11
+ * UI is a symptom of unresolved autonomy — buttons exist because
12
+ * Core couldn't handle it alone yet.
13
+ *
14
+ * Posture is observed, not configured. Intent accumulation drives transitions.
15
+ * The system records interaction patterns and adapts surface area.
16
+ */
17
+ export type PostureName = "silent" | "pulse" | "board";
18
+ export declare const POSTURE_LEVEL: Record<PostureName, number>;
19
+ /** What UI surfaces are available at each posture. */
20
+ export interface PostureSurface {
21
+ /** Chat channel (always available — the minimum) */
22
+ chat: boolean;
23
+ /** Three-dot pulse strip */
24
+ pulse: boolean;
25
+ /** Drill-down panels when tapping dots */
26
+ drilldown: boolean;
27
+ /** Full page views: observatory, ops, board, library, etc. */
28
+ pages: boolean;
29
+ /** Agent task management UI */
30
+ agents: boolean;
31
+ /** Settings/configuration UI */
32
+ settings: boolean;
33
+ }
34
+ export declare const POSTURE_SURFACE: Record<PostureName, PostureSurface>;
35
+ /**
36
+ * An interaction signal — recorded every time the user does something.
37
+ * Intent accumulation uses these to decide posture transitions.
38
+ */
39
+ export interface InteractionSignal {
40
+ timestamp: string;
41
+ /** What surface the user touched */
42
+ surface: keyof PostureSurface | "page-view";
43
+ /** Specific detail — page name, dot tapped, etc. */
44
+ detail?: string;
45
+ }
46
+ /**
47
+ * Posture state — persisted in brain/settings.json alongside other settings.
48
+ */
49
+ export interface PostureState {
50
+ /** Current posture */
51
+ current: PostureName;
52
+ /** When the posture last changed */
53
+ changedAt: string;
54
+ /** Whether the user explicitly set this (locks auto-transition) */
55
+ pinned: boolean;
56
+ /** Interaction count per surface in the current window */
57
+ interactions: Record<string, number>;
58
+ /** When the interaction window started */
59
+ windowStart: string;
60
+ }
61
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/posture/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAEvD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAIrD,CAAC;AAEF,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC7B,oDAAoD;IACpD,IAAI,EAAE,OAAO,CAAC;IACd,4BAA4B;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,0CAA0C;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,8DAA8D;IAC9D,KAAK,EAAE,OAAO,CAAC;IACf,+BAA+B;IAC/B,MAAM,EAAE,OAAO,CAAC;IAChB,gCAAgC;IAChC,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,WAAW,EAAE,cAAc,CAyB/D,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,OAAO,EAAE,MAAM,cAAc,GAAG,WAAW,CAAC;IAC5C,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,sBAAsB;IACtB,OAAO,EAAE,WAAW,CAAC;IACrB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,MAAM,EAAE,OAAO,CAAC;IAChB,0DAA0D;IAC1D,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAC;CACrB"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Posture — how much UI surface assembles around the user.
3
+ *
4
+ * Three modes:
5
+ * - silent: No UI. Core works in background. Reaches out via chat/SMS/email.
6
+ * - pulse: Three dots only. Tap for drill-down. Zero-to-one interaction.
7
+ * - board: Full visibility. Threads, agents, memory, operations.
8
+ *
9
+ * Posture is orthogonal to tier (capabilities) and bonding (trust).
10
+ * A BYOK user might be silent. A Spawn user might only want pulse.
11
+ * UI is a symptom of unresolved autonomy — buttons exist because
12
+ * Core couldn't handle it alone yet.
13
+ *
14
+ * Posture is observed, not configured. Intent accumulation drives transitions.
15
+ * The system records interaction patterns and adapts surface area.
16
+ */
17
+ export const POSTURE_LEVEL = {
18
+ silent: 0,
19
+ pulse: 1,
20
+ board: 2,
21
+ };
22
+ export const POSTURE_SURFACE = {
23
+ silent: {
24
+ chat: true,
25
+ pulse: false,
26
+ drilldown: false,
27
+ pages: false,
28
+ agents: false,
29
+ settings: false,
30
+ },
31
+ pulse: {
32
+ chat: true,
33
+ pulse: true,
34
+ drilldown: true,
35
+ pages: false,
36
+ agents: false,
37
+ settings: false,
38
+ },
39
+ board: {
40
+ chat: true,
41
+ pulse: true,
42
+ drilldown: true,
43
+ pages: true,
44
+ agents: true,
45
+ settings: true,
46
+ },
47
+ };
48
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/posture/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,MAAM,CAAC,MAAM,aAAa,GAAgC;IACxD,MAAM,EAAE,CAAC;IACT,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;CACT,CAAC;AAkBF,MAAM,CAAC,MAAM,eAAe,GAAwC;IAClE,MAAM,EAAE;QACN,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,KAAK;QACZ,SAAS,EAAE,KAAK;QAChB,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,KAAK;KAChB;IACD,KAAK,EAAE;QACL,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,IAAI;QACf,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,KAAK;KAChB;IACD,KAAK,EAAE;QACL,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,IAAI;QACf,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,IAAI;KACf;CACF,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Resend inbound email inbox — pull-on-activity pattern.
3
+ *
4
+ * Instead of a timer, Core checks for pending emails whenever it's
5
+ * already doing work. The check is debounced: at most once every 2 minutes.
6
+ * Emails are pulled from the Cloudflare Worker's KV-backed inbox,
7
+ * processed through the Brain pipeline, and acknowledged.
8
+ *
9
+ * Call `checkResendInbox()` from any activity hook — it's cheap when
10
+ * there's nothing to do (single GET, empty array).
11
+ */
12
+ /**
13
+ * Check the Resend Worker inbox for pending emails.
14
+ * Debounced — returns immediately if checked recently.
15
+ * Safe to call frequently from any activity path.
16
+ */
17
+ export declare function checkResendInbox(): Promise<void>;
18
+ /**
19
+ * Force an immediate inbox check, bypassing the debounce.
20
+ * Useful for manual triggers (e.g., "check email" command).
21
+ */
22
+ export declare function forceCheckResendInbox(): Promise<number>;
23
+ //# sourceMappingURL=inbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../src/resend/inbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA+FH;;;;GAIG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAgDtD;AAmED;;;GAGG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC,CAuB7D"}