@sumeru/server 0.1.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 (95) hide show
  1. package/LICENSE +18 -0
  2. package/dist/.build-fingerprint +1 -0
  3. package/dist/config.d.ts +14 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +142 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/envelope.d.ts +28 -0
  8. package/dist/envelope.d.ts.map +1 -0
  9. package/dist/envelope.js +43 -0
  10. package/dist/envelope.js.map +1 -0
  11. package/dist/export/bundle.d.ts +28 -0
  12. package/dist/export/bundle.d.ts.map +1 -0
  13. package/dist/export/bundle.js +78 -0
  14. package/dist/export/bundle.js.map +1 -0
  15. package/dist/export/handler.d.ts +24 -0
  16. package/dist/export/handler.d.ts.map +1 -0
  17. package/dist/export/handler.js +102 -0
  18. package/dist/export/handler.js.map +1 -0
  19. package/dist/export/index.d.ts +3 -0
  20. package/dist/export/index.d.ts.map +1 -0
  21. package/dist/export/index.js +3 -0
  22. package/dist/export/index.js.map +1 -0
  23. package/dist/handler.d.ts +24 -0
  24. package/dist/handler.d.ts.map +1 -0
  25. package/dist/handler.js +622 -0
  26. package/dist/handler.js.map +1 -0
  27. package/dist/index.d.ts +12 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +10 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/ocas/index.d.ts +3 -0
  32. package/dist/ocas/index.d.ts.map +1 -0
  33. package/dist/ocas/index.js +3 -0
  34. package/dist/ocas/index.js.map +1 -0
  35. package/dist/ocas/schemas.d.ts +41 -0
  36. package/dist/ocas/schemas.d.ts.map +1 -0
  37. package/dist/ocas/schemas.js +108 -0
  38. package/dist/ocas/schemas.js.map +1 -0
  39. package/dist/ocas/store.d.ts +58 -0
  40. package/dist/ocas/store.d.ts.map +1 -0
  41. package/dist/ocas/store.js +139 -0
  42. package/dist/ocas/store.js.map +1 -0
  43. package/dist/search/handler.d.ts +54 -0
  44. package/dist/search/handler.d.ts.map +1 -0
  45. package/dist/search/handler.js +178 -0
  46. package/dist/search/handler.js.map +1 -0
  47. package/dist/search/index.d.ts +4 -0
  48. package/dist/search/index.d.ts.map +1 -0
  49. package/dist/search/index.js +3 -0
  50. package/dist/search/index.js.map +1 -0
  51. package/dist/search/sqlite-index.d.ts +49 -0
  52. package/dist/search/sqlite-index.d.ts.map +1 -0
  53. package/dist/search/sqlite-index.js +508 -0
  54. package/dist/search/sqlite-index.js.map +1 -0
  55. package/dist/search/types.d.ts +143 -0
  56. package/dist/search/types.d.ts.map +1 -0
  57. package/dist/search/types.js +10 -0
  58. package/dist/search/types.js.map +1 -0
  59. package/dist/session/cwd.d.ts +31 -0
  60. package/dist/session/cwd.d.ts.map +1 -0
  61. package/dist/session/cwd.js +54 -0
  62. package/dist/session/cwd.js.map +1 -0
  63. package/dist/session/id.d.ts +12 -0
  64. package/dist/session/id.d.ts.map +1 -0
  65. package/dist/session/id.js +76 -0
  66. package/dist/session/id.js.map +1 -0
  67. package/dist/session/index.d.ts +5 -0
  68. package/dist/session/index.d.ts.map +1 -0
  69. package/dist/session/index.js +4 -0
  70. package/dist/session/index.js.map +1 -0
  71. package/dist/session/store.d.ts +89 -0
  72. package/dist/session/store.d.ts.map +1 -0
  73. package/dist/session/store.js +258 -0
  74. package/dist/session/store.js.map +1 -0
  75. package/dist/sse/buffer.d.ts +53 -0
  76. package/dist/sse/buffer.d.ts.map +1 -0
  77. package/dist/sse/buffer.js +119 -0
  78. package/dist/sse/buffer.js.map +1 -0
  79. package/dist/sse/index.d.ts +3 -0
  80. package/dist/sse/index.d.ts.map +1 -0
  81. package/dist/sse/index.js +3 -0
  82. package/dist/sse/index.js.map +1 -0
  83. package/dist/sse/messages.d.ts +30 -0
  84. package/dist/sse/messages.d.ts.map +1 -0
  85. package/dist/sse/messages.js +489 -0
  86. package/dist/sse/messages.js.map +1 -0
  87. package/dist/start.d.ts +22 -0
  88. package/dist/start.d.ts.map +1 -0
  89. package/dist/start.js +86 -0
  90. package/dist/start.js.map +1 -0
  91. package/dist/types.d.ts +252 -0
  92. package/dist/types.d.ts.map +1 -0
  93. package/dist/types.js +10 -0
  94. package/dist/types.js.map +1 -0
  95. package/package.json +31 -0
@@ -0,0 +1,12 @@
1
+ export { loadConfig } from "./config.js";
2
+ export { envelope, errorEnvelope, gatewayEnvelope, gatewayListEnvelope, instanceEnvelope, searchResultEnvelope, sessionEnvelope, sessionListEnvelope, } from "./envelope.js";
3
+ export { buildSessionExport } from "./export/index.js";
4
+ export { createHandler } from "./handler.js";
5
+ export { getRegisteredSchema, openSumeruOcas, recordPayload, SUMERU_SESSION_META_SCHEMA, SUMERU_SESSION_META_SCHEMA_HASH, SUMERU_TURN_SCHEMA, SUMERU_TURN_SCHEMA_HASH, type SumeruOcas, validatePayload, } from "./ocas/index.js";
6
+ export { createSearchIndex, quoteFtsPhrase, rebuildSearchIndex, type SearchHit, type SearchIndex, type SearchOptions, type SearchResult, searchSessions, } from "./search/index.js";
7
+ export type { SessionStore, TransitionResult } from "./session/index.js";
8
+ export { createSessionStore, generateSessionId, type ResolveCwdResult, resolveSessionCwd, } from "./session/index.js";
9
+ export { toWire } from "./session/store.js";
10
+ export { resolveOcasDir, startServer } from "./start.js";
11
+ export type { Envelope, ErrorValue, Gateway, GatewayCapabilities, GatewayConfig, Instance, InstanceConfig, MessageHistoryValue, OcasConfig, SearchResultHit, SearchResultValue, ServerConfig, Session, SessionListEntry, SessionStatus, SessionWire, StartConfig, StartedServer, TurnValue, UserSessionConfig, } from "./types.js";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACN,QAAQ,EACR,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,mBAAmB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EACN,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,0BAA0B,EAC1B,+BAA+B,EAC/B,kBAAkB,EAClB,uBAAuB,EACvB,KAAK,UAAU,EACf,eAAe,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,cAAc,GACd,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EACN,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,iBAAiB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EACX,QAAQ,EACR,UAAU,EACV,OAAO,EACP,mBAAmB,EACnB,aAAa,EACb,QAAQ,EACR,cAAc,EACd,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,WAAW,EACX,aAAa,EACb,SAAS,EACT,iBAAiB,GACjB,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ export { loadConfig } from "./config.js";
2
+ export { envelope, errorEnvelope, gatewayEnvelope, gatewayListEnvelope, instanceEnvelope, searchResultEnvelope, sessionEnvelope, sessionListEnvelope, } from "./envelope.js";
3
+ export { buildSessionExport } from "./export/index.js";
4
+ export { createHandler } from "./handler.js";
5
+ export { getRegisteredSchema, openSumeruOcas, recordPayload, SUMERU_SESSION_META_SCHEMA, SUMERU_SESSION_META_SCHEMA_HASH, SUMERU_TURN_SCHEMA, SUMERU_TURN_SCHEMA_HASH, validatePayload, } from "./ocas/index.js";
6
+ export { createSearchIndex, quoteFtsPhrase, rebuildSearchIndex, searchSessions, } from "./search/index.js";
7
+ export { createSessionStore, generateSessionId, resolveSessionCwd, } from "./session/index.js";
8
+ export { toWire } from "./session/store.js";
9
+ export { resolveOcasDir, startServer } from "./start.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACN,QAAQ,EACR,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,mBAAmB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EACN,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,0BAA0B,EAC1B,+BAA+B,EAC/B,kBAAkB,EAClB,uBAAuB,EAEvB,eAAe,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAKlB,cAAc,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACN,kBAAkB,EAClB,iBAAiB,EAEjB,iBAAiB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { SUMERU_SESSION_META_SCHEMA, SUMERU_SESSION_META_SCHEMA_HASH, SUMERU_TURN_SCHEMA, SUMERU_TURN_SCHEMA_HASH, } from "./schemas.js";
2
+ export { getRegisteredSchema, openSumeruOcas, recordPayload, type SumeruOcas, validatePayload, } from "./store.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ocas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,0BAA0B,EAC1B,+BAA+B,EAC/B,kBAAkB,EAClB,uBAAuB,GACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,KAAK,UAAU,EACf,eAAe,GACf,MAAM,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { SUMERU_SESSION_META_SCHEMA, SUMERU_SESSION_META_SCHEMA_HASH, SUMERU_TURN_SCHEMA, SUMERU_TURN_SCHEMA_HASH, } from "./schemas.js";
2
+ export { getRegisteredSchema, openSumeruOcas, recordPayload, validatePayload, } from "./store.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ocas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,0BAA0B,EAC1B,+BAA+B,EAC/B,kBAAkB,EAClB,uBAAuB,GACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,mBAAmB,EACnB,cAAc,EACd,aAAa,EAEb,eAAe,GACf,MAAM,YAAY,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * JSON Schemas registered against the ocas store at startup.
3
+ *
4
+ * The schema bodies are byte-stable contracts — the schema hash is a function
5
+ * of the schema body, so changing field order or adding properties changes
6
+ * the hash. Treat these definitions as immutable.
7
+ */
8
+ import type { Hash, JSONSchema } from "@ocas/core";
9
+ /**
10
+ * `@sumeru/session-meta` — per-session metadata snapshot, written once at
11
+ * session create. `additionalProperties: false` forces opaque adapter config
12
+ * to live inside the `config` field rather than at the top level.
13
+ *
14
+ * `resolvedCwd` (issue #27) records the absolute path that Sumeru actually
15
+ * forwarded to the adapter under the well-known `config.cwd` key, AFTER
16
+ * `resolveSessionCwd` resolved it against the instance `workspaceRoot`. It is
17
+ * `null` when the client did not send `config.cwd` (no cwd hint), and a
18
+ * non-empty string otherwise. The original opaque `config` blob is preserved
19
+ * verbatim so `config.cwd` (if present) and `resolvedCwd` together describe
20
+ * the request → resolution mapping.
21
+ */
22
+ export declare const SUMERU_SESSION_META_SCHEMA: JSONSchema;
23
+ /**
24
+ * Pre-computed hash of `SUMERU_SESSION_META_SCHEMA`. Hardcoded to avoid
25
+ * requiring WASM init (`initHasher()`) at import time. A test asserts this
26
+ * stays in sync with `computeSelfHashSync(SUMERU_SESSION_META_SCHEMA)`.
27
+ */
28
+ export declare const SUMERU_SESSION_META_SCHEMA_HASH: Hash;
29
+ /**
30
+ * `@sumeru/turn` — one turn in a session. Used for both user and assistant
31
+ * turns; the `role` enum excludes "system" because Sumeru does not record
32
+ * system turns through the message endpoint.
33
+ */
34
+ export declare const SUMERU_TURN_SCHEMA: JSONSchema;
35
+ /**
36
+ * Pre-computed hash of `SUMERU_TURN_SCHEMA`. Hardcoded to avoid requiring
37
+ * WASM init (`initHasher()`) at import time. A test asserts this stays in
38
+ * sync with `computeSelfHashSync(SUMERU_TURN_SCHEMA)`.
39
+ */
40
+ export declare const SUMERU_TURN_SCHEMA_HASH: Hash;
41
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/ocas/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,0BAA0B,EAAE,UAgBxC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,EAAE,IAAsB,CAAC;AAErE;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,UAqDhC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,IAAsB,CAAC"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * JSON Schemas registered against the ocas store at startup.
3
+ *
4
+ * The schema bodies are byte-stable contracts — the schema hash is a function
5
+ * of the schema body, so changing field order or adding properties changes
6
+ * the hash. Treat these definitions as immutable.
7
+ */
8
+ /**
9
+ * `@sumeru/session-meta` — per-session metadata snapshot, written once at
10
+ * session create. `additionalProperties: false` forces opaque adapter config
11
+ * to live inside the `config` field rather than at the top level.
12
+ *
13
+ * `resolvedCwd` (issue #27) records the absolute path that Sumeru actually
14
+ * forwarded to the adapter under the well-known `config.cwd` key, AFTER
15
+ * `resolveSessionCwd` resolved it against the instance `workspaceRoot`. It is
16
+ * `null` when the client did not send `config.cwd` (no cwd hint), and a
17
+ * non-empty string otherwise. The original opaque `config` blob is preserved
18
+ * verbatim so `config.cwd` (if present) and `resolvedCwd` together describe
19
+ * the request → resolution mapping.
20
+ */
21
+ export const SUMERU_SESSION_META_SCHEMA = {
22
+ title: "@sumeru/session-meta",
23
+ description: "Per-session metadata snapshot. Written once at session create.",
24
+ type: "object",
25
+ additionalProperties: false,
26
+ required: ["id", "gateway", "adapter", "createdAt", "config", "resolvedCwd"],
27
+ properties: {
28
+ id: { type: "string", pattern: "^ses_[0-9A-HJKMNP-TV-Z]{26}$" },
29
+ gateway: { type: "string", minLength: 1 },
30
+ adapter: { type: "string", minLength: 1 },
31
+ createdAt: { type: "string", format: "date-time" },
32
+ config: { type: "object" },
33
+ resolvedCwd: {
34
+ anyOf: [{ type: "null" }, { type: "string", minLength: 1 }],
35
+ },
36
+ },
37
+ };
38
+ /**
39
+ * Pre-computed hash of `SUMERU_SESSION_META_SCHEMA`. Hardcoded to avoid
40
+ * requiring WASM init (`initHasher()`) at import time. A test asserts this
41
+ * stays in sync with `computeSelfHashSync(SUMERU_SESSION_META_SCHEMA)`.
42
+ */
43
+ export const SUMERU_SESSION_META_SCHEMA_HASH = "5C30THA7BZ814";
44
+ /**
45
+ * `@sumeru/turn` — one turn in a session. Used for both user and assistant
46
+ * turns; the `role` enum excludes "system" because Sumeru does not record
47
+ * system turns through the message endpoint.
48
+ */
49
+ export const SUMERU_TURN_SCHEMA = {
50
+ title: "@sumeru/turn",
51
+ description: "One turn in a session — a user message OR an assistant response.",
52
+ type: "object",
53
+ additionalProperties: false,
54
+ required: ["index", "role", "content", "timestamp", "toolCalls"],
55
+ properties: {
56
+ index: { type: "integer", minimum: 0 },
57
+ role: { type: "string", enum: ["user", "assistant"] },
58
+ content: { type: "string" },
59
+ timestamp: { type: "string", format: "date-time" },
60
+ toolCalls: {
61
+ anyOf: [
62
+ { type: "null" },
63
+ {
64
+ type: "array",
65
+ items: {
66
+ type: "object",
67
+ additionalProperties: false,
68
+ required: ["tool", "input", "output", "durationMs", "exitCode"],
69
+ properties: {
70
+ tool: { type: "string", minLength: 1 },
71
+ input: { type: "object" },
72
+ output: {
73
+ anyOf: [{ type: "null" }, { type: "string" }],
74
+ },
75
+ durationMs: {
76
+ anyOf: [{ type: "null" }, { type: "integer", minimum: 0 }],
77
+ },
78
+ exitCode: {
79
+ anyOf: [{ type: "null" }, { type: "integer" }],
80
+ },
81
+ },
82
+ },
83
+ },
84
+ ],
85
+ },
86
+ tokens: {
87
+ anyOf: [
88
+ { type: "null" },
89
+ {
90
+ type: "object",
91
+ additionalProperties: false,
92
+ required: ["input", "output"],
93
+ properties: {
94
+ input: { type: "integer", minimum: 0 },
95
+ output: { type: "integer", minimum: 0 },
96
+ },
97
+ },
98
+ ],
99
+ },
100
+ },
101
+ };
102
+ /**
103
+ * Pre-computed hash of `SUMERU_TURN_SCHEMA`. Hardcoded to avoid requiring
104
+ * WASM init (`initHasher()`) at import time. A test asserts this stays in
105
+ * sync with `computeSelfHashSync(SUMERU_TURN_SCHEMA)`.
106
+ */
107
+ export const SUMERU_TURN_SCHEMA_HASH = "718S3WF704TZ6";
108
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/ocas/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAe;IACrD,KAAK,EAAE,sBAAsB;IAC7B,WAAW,EAAE,gEAAgE;IAC7E,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,aAAa,CAAC;IAC5E,UAAU,EAAE;QACX,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,8BAA8B,EAAE;QAC/D,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE;QACzC,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE;QACzC,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE;QAClD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC1B,WAAW,EAAE;YACZ,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;SAC3D;KACD;CACD,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAS,eAAe,CAAC;AAErE;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAe;IAC7C,KAAK,EAAE,cAAc;IACrB,WAAW,EACV,kEAAkE;IACnE,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC;IAChE,UAAU,EAAE;QACX,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QACtC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE;QACrD,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC3B,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE;QAClD,SAAS,EAAE;YACV,KAAK,EAAE;gBACN,EAAE,IAAI,EAAE,MAAM,EAAE;gBAChB;oBACC,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE;wBACN,IAAI,EAAE,QAAQ;wBACd,oBAAoB,EAAE,KAAK;wBAC3B,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,CAAC;wBAC/D,UAAU,EAAE;4BACX,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE;4BACtC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;4BACzB,MAAM,EAAE;gCACP,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;6BAC7C;4BACD,UAAU,EAAE;gCACX,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;6BAC1D;4BACD,QAAQ,EAAE;gCACT,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;6BAC9C;yBACD;qBACD;iBACD;aACD;SACD;QACD,MAAM,EAAE;YACP,KAAK,EAAE;gBACN,EAAE,IAAI,EAAE,MAAM,EAAE;gBAChB;oBACC,IAAI,EAAE,QAAQ;oBACd,oBAAoB,EAAE,KAAK;oBAC3B,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;oBAC7B,UAAU,EAAE;wBACX,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;wBACtC,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;qBACvC;iBACD;aACD;SACD;KACD;CACD,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAS,eAAe,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Sumeru ocas store wrapper — opens an `@ocas/fs` CAS-backed store, runs
3
+ * bootstrap so the schema-of-schemas exists, and registers the two Sumeru
4
+ * schemas. Exposes the resulting `Store` and the schema hashes.
5
+ *
6
+ * The wrapper validates payloads against their schema before writing.
7
+ * `@ocas/core.Store.cas.put` is intentionally non-validating; recording paths
8
+ * always go through {@link recordTurn} / {@link recordSessionMeta} so invalid
9
+ * payloads are rejected before they reach disk.
10
+ */
11
+ import { type Hash, type JSONSchema, type Store } from "@ocas/core";
12
+ import { type SearchIndex } from "../search/index.js";
13
+ /** Hash alias for the schema-of-schemas (assigned at bootstrap). */
14
+ export type SumeruOcas = {
15
+ store: Store;
16
+ turnSchemaHash: Hash;
17
+ sessionMetaSchemaHash: Hash;
18
+ /** Schema-of-schemas hash from `@ocas/core` bootstrap. */
19
+ metaSchemaHash: Hash;
20
+ /** Map: schema hash → human alias for the `/ocas/:hash` endpoint. */
21
+ schemaAliases: Record<Hash, string>;
22
+ /** Phase 5: FTS5-backed session search index. */
23
+ searchIndex: SearchIndex;
24
+ };
25
+ /**
26
+ * Open or create the on-disk store at `dir`. Creates the directory if needed.
27
+ * Bootstraps `@ocas/core` schemas and registers `@sumeru/turn` +
28
+ * `@sumeru/session-meta`.
29
+ *
30
+ * Throws with a `failed to open ocas store at <dir>: <cause>` message when
31
+ * the directory cannot be created or accessed.
32
+ */
33
+ export declare function openSumeruOcas(dir: string): SumeruOcas;
34
+ /**
35
+ * Validate `payload` against the schema identified by `schemaHash`. Throws
36
+ * `SchemaValidationError` if invalid.
37
+ *
38
+ * This is needed because `@ocas/core.Store.cas.put` does not validate — it
39
+ * just hashes and stores. We always validate before writing recording data
40
+ * so corrupted nodes never land in the store.
41
+ *
42
+ * The validator is our own ajv instance (not `@ocas/core`'s internal one)
43
+ * so we can recognise the `date-time` format without pulling in
44
+ * `ajv-formats`.
45
+ */
46
+ export declare function validatePayload(store: Store, schemaHash: Hash, payload: unknown): void;
47
+ /**
48
+ * Validate `payload` and put it in the store. Returns the resulting hash.
49
+ * Wraps `store.cas.put` with a pre-write validation step.
50
+ */
51
+ export declare function recordPayload(store: Store, schemaHash: Hash, payload: unknown): Hash;
52
+ /**
53
+ * Look up a schema body. Returns `null` if `schemaHash` is not in the store.
54
+ * Convenience wrapper kept here so handlers don't need to import @ocas/core
55
+ * directly for trivial reads.
56
+ */
57
+ export declare function getRegisteredSchema(store: Store, schemaHash: Hash): JSONSchema | null;
58
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/ocas/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAEN,KAAK,IAAI,EACT,KAAK,UAAU,EAGf,KAAK,KAAK,EACV,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAyBzE,oEAAoE;AACpE,MAAM,MAAM,UAAU,GAAG;IACxB,KAAK,EAAE,KAAK,CAAC;IACb,cAAc,EAAE,IAAI,CAAC;IACrB,qBAAqB,EAAE,IAAI,CAAC;IAC5B,0DAA0D;IAC1D,cAAc,EAAE,IAAI,CAAC;IACrB,qEAAqE;IACrE,aAAa,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACpC,iDAAiD;IACjD,WAAW,EAAE,WAAW,CAAC;CACzB,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAsDtD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC9B,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,IAAI,EAChB,OAAO,EAAE,OAAO,GACd,IAAI,CAkBN;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC5B,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,IAAI,EAChB,OAAO,EAAE,OAAO,GACd,IAAI,CAGN;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAClC,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,IAAI,GACd,UAAU,GAAG,IAAI,CAInB"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Sumeru ocas store wrapper — opens an `@ocas/fs` CAS-backed store, runs
3
+ * bootstrap so the schema-of-schemas exists, and registers the two Sumeru
4
+ * schemas. Exposes the resulting `Store` and the schema hashes.
5
+ *
6
+ * The wrapper validates payloads against their schema before writing.
7
+ * `@ocas/core.Store.cas.put` is intentionally non-validating; recording paths
8
+ * always go through {@link recordTurn} / {@link recordSessionMeta} so invalid
9
+ * payloads are rejected before they reach disk.
10
+ */
11
+ import { mkdirSync } from "node:fs";
12
+ import { join } from "node:path";
13
+ import { bootstrap, putSchema, SchemaValidationError, } from "@ocas/core";
14
+ import { createFsStore, createSqliteVarStore } from "@ocas/fs";
15
+ import * as AjvModule from "ajv";
16
+ import { createSearchIndex } from "../search/index.js";
17
+ import { SUMERU_SESSION_META_SCHEMA, SUMERU_TURN_SCHEMA } from "./schemas.js";
18
+ // ajv CJS interop: the constructor lives on `.default` at runtime, but the
19
+ // namespace shape is what tsc's verbatimModuleSyntax surfaces.
20
+ // biome-ignore lint/suspicious/noExplicitAny: CJS interop
21
+ const Ajv = (AjvModule.default ??
22
+ AjvModule);
23
+ /**
24
+ * Local ajv instance used for validating Sumeru recording payloads. We do not
25
+ * reuse `@ocas/core`'s internal ajv because we need the `date-time` format
26
+ * registered (without pulling in `ajv-formats`).
27
+ *
28
+ * `date-time` is registered with a permissive ISO-8601 regex matching what
29
+ * `Date.prototype.toISOString` emits — sufficient for validating timestamps
30
+ * the server itself produces.
31
+ */
32
+ const ajv = new Ajv();
33
+ ajv.addFormat("ocas_ref", /^[0-9A-HJKMNP-TV-Z]{13}$/);
34
+ ajv.addFormat("date-time", /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,9})?(Z|[+-]\d{2}:\d{2})$/);
35
+ /**
36
+ * Open or create the on-disk store at `dir`. Creates the directory if needed.
37
+ * Bootstraps `@ocas/core` schemas and registers `@sumeru/turn` +
38
+ * `@sumeru/session-meta`.
39
+ *
40
+ * Throws with a `failed to open ocas store at <dir>: <cause>` message when
41
+ * the directory cannot be created or accessed.
42
+ */
43
+ export function openSumeruOcas(dir) {
44
+ let store;
45
+ try {
46
+ // Ensure parent + dir exist before handing off to @ocas/fs.
47
+ mkdirSync(dir, { recursive: true });
48
+ const cas = createFsStore(dir);
49
+ const sqlite = createSqliteVarStore(dir, cas);
50
+ store = { cas, var: sqlite.var, tag: sqlite.tag };
51
+ }
52
+ catch (err) {
53
+ const cause = err instanceof Error ? err.message : String(err);
54
+ throw new Error(`failed to open ocas store at ${dir}: ${cause}`);
55
+ }
56
+ let aliases;
57
+ try {
58
+ aliases = bootstrap(store);
59
+ }
60
+ catch (err) {
61
+ const cause = err instanceof Error ? err.message : String(err);
62
+ throw new Error(`failed to open ocas store at ${dir}: ${cause}`);
63
+ }
64
+ const turnSchemaHash = putSchema(store, SUMERU_TURN_SCHEMA);
65
+ const sessionMetaSchemaHash = putSchema(store, SUMERU_SESSION_META_SCHEMA);
66
+ const metaSchemaHash = aliases["@ocas/schema"];
67
+ if (metaSchemaHash === undefined) {
68
+ throw new Error(`failed to open ocas store at ${dir}: bootstrap did not register @ocas/schema`);
69
+ }
70
+ const schemaAliases = {
71
+ [metaSchemaHash]: "@ocas/schema",
72
+ [turnSchemaHash]: "@sumeru/turn",
73
+ [sessionMetaSchemaHash]: "@sumeru/session-meta",
74
+ };
75
+ let searchIndex;
76
+ try {
77
+ searchIndex = createSearchIndex(join(dir, "_store.db"));
78
+ }
79
+ catch (err) {
80
+ const cause = err instanceof Error ? err.message : String(err);
81
+ throw new Error(`failed to open ocas store at ${dir}: ${cause}`);
82
+ }
83
+ const indexedTurns = searchIndex.turnCount();
84
+ console.log(`[sumeru] search index ready: ${indexedTurns} turns indexed`);
85
+ return {
86
+ store,
87
+ turnSchemaHash,
88
+ sessionMetaSchemaHash,
89
+ metaSchemaHash,
90
+ schemaAliases,
91
+ searchIndex,
92
+ };
93
+ }
94
+ /**
95
+ * Validate `payload` against the schema identified by `schemaHash`. Throws
96
+ * `SchemaValidationError` if invalid.
97
+ *
98
+ * This is needed because `@ocas/core.Store.cas.put` does not validate — it
99
+ * just hashes and stores. We always validate before writing recording data
100
+ * so corrupted nodes never land in the store.
101
+ *
102
+ * The validator is our own ajv instance (not `@ocas/core`'s internal one)
103
+ * so we can recognise the `date-time` format without pulling in
104
+ * `ajv-formats`.
105
+ */
106
+ export function validatePayload(store, schemaHash, payload) {
107
+ const schemaNode = store.cas.get(schemaHash);
108
+ if (schemaNode === null) {
109
+ throw new SchemaValidationError(`Schema ${schemaHash} is not registered in the store`);
110
+ }
111
+ const schema = schemaNode.payload;
112
+ const valid = ajv.validate(schema, payload);
113
+ if (!valid) {
114
+ const detail = ajv.errors !== null && ajv.errors !== undefined && ajv.errors.length > 0
115
+ ? ajv.errorsText(ajv.errors)
116
+ : "(no detail)";
117
+ throw new SchemaValidationError(`Payload does not validate against schema ${schemaHash}: ${detail}`);
118
+ }
119
+ }
120
+ /**
121
+ * Validate `payload` and put it in the store. Returns the resulting hash.
122
+ * Wraps `store.cas.put` with a pre-write validation step.
123
+ */
124
+ export function recordPayload(store, schemaHash, payload) {
125
+ validatePayload(store, schemaHash, payload);
126
+ return store.cas.put(schemaHash, payload);
127
+ }
128
+ /**
129
+ * Look up a schema body. Returns `null` if `schemaHash` is not in the store.
130
+ * Convenience wrapper kept here so handlers don't need to import @ocas/core
131
+ * directly for trivial reads.
132
+ */
133
+ export function getRegisteredSchema(store, schemaHash) {
134
+ const node = store.cas.get(schemaHash);
135
+ if (node === null)
136
+ return null;
137
+ return node.payload;
138
+ }
139
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/ocas/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Phase 5 — search HTTP handlers.
3
+ *
4
+ * Wired into `createHandler` so:
5
+ * - `GET /sessions?q=...` runs cross-gateway search
6
+ * - `GET /gateways/:name/sessions?q=...` runs per-gateway search
7
+ *
8
+ * When `q` is missing or empty after trimming, the per-gateway route falls
9
+ * back to the existing `@sumeru/session-list` behavior; the top-level route
10
+ * 400s because there is no listing fallback.
11
+ */
12
+ import type { ServerResponse } from "node:http";
13
+ import type { SearchIndex } from "../search/index.js";
14
+ /** Result of parsing the query string for a search request. */
15
+ export type ParsedSearchParams = {
16
+ ok: true;
17
+ value: ParsedSearchParamsOk;
18
+ } | {
19
+ ok: false;
20
+ status: 400;
21
+ error: string;
22
+ message: string;
23
+ };
24
+ export type ParsedSearchParamsOk = {
25
+ /** Trimmed query. Always non-empty when `ok === true`. */
26
+ query: string;
27
+ /** When `null`, the request is for the top-level (cross-gateway) route OR no filter applied. */
28
+ gateway: string | null;
29
+ limit: number;
30
+ offset: number;
31
+ };
32
+ /**
33
+ * Parse `q`, `limit`, `offset`, and (top-level only) `gateway` from a query
34
+ * string. Trimming `q` to empty is treated as "absent" — the caller decides
35
+ * whether that means fall through to listing or 400.
36
+ */
37
+ export declare function parseSearchParams(queryString: string, allowGatewayFilter: boolean): ParsedSearchParams;
38
+ /**
39
+ * Run a cross-gateway search and write the response. Caller must have
40
+ * already validated method == GET / HEAD.
41
+ */
42
+ export declare function handleSearchTopLevel(res: ServerResponse, queryString: string, searchIndex: SearchIndex): void;
43
+ /**
44
+ * Run a per-gateway search and write the response. The route's gateway is
45
+ * authoritative; any `?gateway=` param is ignored (per spec).
46
+ */
47
+ export declare function handleSearchPerGateway(res: ServerResponse, queryString: string, searchIndex: SearchIndex, gateway: string): void;
48
+ /**
49
+ * Detect whether a query string carries a search request (`?q=` non-empty
50
+ * after trimming). Used by the per-gateway sessions route to decide between
51
+ * the Phase-2 listing and Phase-5 search.
52
+ */
53
+ export declare function isSearchRequest(queryString: string): boolean;
54
+ //# sourceMappingURL=handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/search/handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAUtD,+DAA+D;AAC/D,MAAM,MAAM,kBAAkB,GAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,oBAAoB,CAAA;CAAE,GACzC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9D,MAAM,MAAM,oBAAoB,GAAG;IAClC,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,gGAAgG;IAChG,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,iBAAiB,CAChC,WAAW,EAAE,MAAM,EACnB,kBAAkB,EAAE,OAAO,GACzB,kBAAkB,CAsDpB;AAiCD;;;GAGG;AACH,wBAAgB,oBAAoB,CACnC,GAAG,EAAE,cAAc,EACnB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,WAAW,GACtB,IAAI,CAON;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACrC,GAAG,EAAE,cAAc,EACnB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,MAAM,GACb,IAAI,CAQN;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAK5D"}