@karmaniverous/jeeves-server-core 0.1.0 → 0.1.2

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.
@@ -34,4 +34,3 @@ export declare function computeDeepShareKey(seed: string, urlPath: string, param
34
34
  * Timing-safe string comparison
35
35
  */
36
36
  export declare function timingSafeEqual(a: string, b: string): boolean;
37
- //# sourceMappingURL=crypto.d.ts.map
@@ -1,13 +1,14 @@
1
+ import crypto from 'node:crypto';
2
+
1
3
  /**
2
4
  * Cryptographic utilities for HMAC key computation and verification.
3
5
  *
4
6
  * @packageDocumentation
5
7
  */
6
- import crypto from 'node:crypto';
7
8
  /**
8
9
  * Compute path-specific key: HMAC-SHA256(apiKey, normalizedPath)
9
10
  */
10
- export function computePathKey(apiKey, urlPath) {
11
+ function computePathKey(apiKey, urlPath) {
11
12
  const normalized = urlPath.toLowerCase().replace(/^\/+|\/+$/g, '');
12
13
  const hash = crypto
13
14
  .createHmac('sha256', apiKey)
@@ -19,7 +20,7 @@ export function computePathKey(apiKey, urlPath) {
19
20
  * Compute insider key: HMAC-SHA256(apiKey, "insider")
20
21
  * Works for any path, grants full navigation
21
22
  */
22
- export function computeInsiderKey(apiKey) {
23
+ function computeInsiderKey(apiKey) {
23
24
  const hash = crypto
24
25
  .createHmac('sha256', apiKey)
25
26
  .update('insider')
@@ -29,7 +30,7 @@ export function computeInsiderKey(apiKey) {
29
30
  /**
30
31
  * Compute outsider key with expiry: HMAC-SHA256(apiKey, path + "|" + expiry)
31
32
  */
32
- export function computeOutsiderKeyWithExpiry(apiKey, urlPath, expiry) {
33
+ function computeOutsiderKeyWithExpiry(apiKey, urlPath, expiry) {
33
34
  const normalized = urlPath.toLowerCase().replace(/^\/+|\/+$/g, '');
34
35
  const data = `${normalized}|${String(expiry)}`;
35
36
  const hash = crypto.createHmac('sha256', apiKey).update(data).digest('hex');
@@ -39,7 +40,7 @@ export function computeOutsiderKeyWithExpiry(apiKey, urlPath, expiry) {
39
40
  * Compute deep share key: HMAC-SHA256(seed, path + "|" + d + "|" + dirs + "|" + stack + "|" + exp)
40
41
  * Used for share links with depth \> 0 or dirs enabled.
41
42
  */
42
- export function computeDeepShareKey(seed, urlPath, params) {
43
+ function computeDeepShareKey(seed, urlPath, params) {
43
44
  const normalized = urlPath.toLowerCase().replace(/^\/+|\/+$/g, '');
44
45
  const data = `${normalized}|${String(params.depth)}|${params.dirs ? '1' : '0'}|${params.stack}|${params.exp ?? ''}`;
45
46
  const hash = crypto.createHmac('sha256', seed).update(data).digest('hex');
@@ -48,7 +49,7 @@ export function computeDeepShareKey(seed, urlPath, params) {
48
49
  /**
49
50
  * Timing-safe string comparison
50
51
  */
51
- export function timingSafeEqual(a, b) {
52
+ function timingSafeEqual(a, b) {
52
53
  try {
53
54
  return crypto.timingSafeEqual(Buffer.from(a), Buffer.from(b));
54
55
  }
@@ -56,3 +57,5 @@ export function timingSafeEqual(a, b) {
56
57
  return false;
57
58
  }
58
59
  }
60
+
61
+ export { computeDeepShareKey, computeInsiderKey, computeOutsiderKeyWithExpiry, computePathKey, timingSafeEqual };
@@ -4,5 +4,5 @@
4
4
  * @packageDocumentation
5
5
  */
6
6
  export { computeDeepShareKey, computeInsiderKey, computeOutsiderKeyWithExpiry, computePathKey, type DeepShareParams, timingSafeEqual, } from './crypto.js';
7
+ export { type AuthMode, authModeSchema, authSchema, DEPRECATED_CONFIG_PROPS, eventConfigSchema, googleAuthSchema, insiderEntrySchema, isScopeName, type JeevesConfig, jeevesConfigSchema, keyEntrySchema, oauthProviderSchema, oauthSchema, scopesObjectSchema, scopesSchema, } from './schema.js';
7
8
  export type { AuthStatusResponse, DriveEntry, ExportCacheClearResponse, ExportLink, FileMutationAction, LinkInfoResponse, OAuthStartRequest, OAuthStartResponse, RotateKeyResponse, ShareForRequest, ShareForResponse, ShareRequest, ShareResponse, } from './types.js';
8
- //# sourceMappingURL=index.d.ts.map
package/dist/src/index.js CHANGED
@@ -1,6 +1,2 @@
1
- /**
2
- * Shared utilities and types for jeeves-server packages.
3
- *
4
- * @packageDocumentation
5
- */
6
- export { computeDeepShareKey, computeInsiderKey, computeOutsiderKeyWithExpiry, computePathKey, timingSafeEqual, } from './crypto.js';
1
+ export { computeDeepShareKey, computeInsiderKey, computeOutsiderKeyWithExpiry, computePathKey, timingSafeEqual } from './crypto.js';
2
+ export { DEPRECATED_CONFIG_PROPS, authModeSchema, authSchema, eventConfigSchema, googleAuthSchema, insiderEntrySchema, isScopeName, jeevesConfigSchema, keyEntrySchema, oauthProviderSchema, oauthSchema, scopesObjectSchema, scopesSchema } from './schema.js';
@@ -0,0 +1,168 @@
1
+ import { z } from 'zod';
2
+ /** Config properties deprecated in v3.6.0 (now resolved via core services). */
3
+ export declare const DEPRECATED_CONFIG_PROPS: readonly ["host", "runnerUrl", "watcherUrl", "metaUrl"];
4
+ /** Supported authentication methods */
5
+ export declare const authModeSchema: z.ZodEnum<{
6
+ google: "google";
7
+ keys: "keys";
8
+ }>;
9
+ /** Google OAuth configuration */
10
+ export declare const googleAuthSchema: z.ZodObject<{
11
+ clientId: z.ZodString;
12
+ clientSecret: z.ZodString;
13
+ }, z.core.$strip>;
14
+ /** Auth configuration */
15
+ export declare const authSchema: z.ZodObject<{
16
+ modes: z.ZodArray<z.ZodEnum<{
17
+ google: "google";
18
+ keys: "keys";
19
+ }>>;
20
+ google: z.ZodOptional<z.ZodObject<{
21
+ clientId: z.ZodString;
22
+ clientSecret: z.ZodString;
23
+ }, z.core.$strip>>;
24
+ sessionSecret: z.ZodOptional<z.ZodString>;
25
+ }, z.core.$strip>;
26
+ /** Event webhook configuration */
27
+ export declare const eventConfigSchema: z.ZodObject<{
28
+ schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
29
+ cmd: z.ZodString;
30
+ map: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
31
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
32
+ }, z.core.$strip>;
33
+ /**
34
+ * Scopes configuration — controls which paths a user/key can access.
35
+ *
36
+ * Three forms:
37
+ * - `string` — single allow pattern (e.g. '/d/*')
38
+ * - `string[]` — array of allow patterns (shorthand for \{ allow: [...] \})
39
+ * - `\{ allow?: string[], deny?: string[] \}` — explicit allow/deny rules
40
+ *
41
+ * Semantics:
42
+ * - Path must match at least one allow rule AND NOT match any deny rule
43
+ * - Omitting `allow` = implicit ['/*'] (allow everything)
44
+ * - Omitting `deny` = no exclusions
45
+ * - Omitting scopes entirely = unrestricted access
46
+ */
47
+ export declare const scopesObjectSchema: z.ZodObject<{
48
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
49
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
50
+ }, z.core.$strip>;
51
+ export declare const scopesSchema: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>, z.ZodObject<{
52
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
53
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
54
+ }, z.core.$strip>]>;
55
+ /** Insider entry (identity + scopes + optional persisted seed) */
56
+ export declare const insiderEntrySchema: z.ZodObject<{
57
+ scopes: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>, z.ZodObject<{
58
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
59
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
60
+ }, z.core.$strip>]>>;
61
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
62
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
63
+ seed: z.ZodOptional<z.ZodString>;
64
+ keyCreatedAt: z.ZodOptional<z.ZodString>;
65
+ }, z.core.$strip>;
66
+ /** Key entry — plain string (seed, no scopes) or object with key + optional scopes */
67
+ export declare const keyEntrySchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
68
+ key: z.ZodString;
69
+ scopes: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>, z.ZodObject<{
70
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
71
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
72
+ }, z.core.$strip>]>>;
73
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
74
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
75
+ }, z.core.$strip>]>;
76
+ /** Check if a string is a named scope identifier (not a path glob). */
77
+ export declare function isScopeName(v: string): boolean;
78
+ /** OAuth provider configuration */
79
+ export declare const oauthProviderSchema: z.ZodObject<{
80
+ authUrl: z.ZodPipe<z.ZodString, z.ZodURL>;
81
+ tokenUrl: z.ZodPipe<z.ZodString, z.ZodURL>;
82
+ pkce: z.ZodDefault<z.ZodBoolean>;
83
+ defaultScopes: z.ZodDefault<z.ZodArray<z.ZodString>>;
84
+ }, z.core.$strip>;
85
+ /** OAuth configuration */
86
+ export declare const oauthSchema: z.ZodObject<{
87
+ credentialDir: z.ZodString;
88
+ providers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
89
+ authUrl: z.ZodPipe<z.ZodString, z.ZodURL>;
90
+ tokenUrl: z.ZodPipe<z.ZodString, z.ZodURL>;
91
+ pkce: z.ZodDefault<z.ZodBoolean>;
92
+ defaultScopes: z.ZodDefault<z.ZodArray<z.ZodString>>;
93
+ }, z.core.$strip>>>;
94
+ }, z.core.$strip>;
95
+ /** Top-level Jeeves Server configuration */
96
+ export declare const jeevesConfigSchema: z.ZodObject<{
97
+ port: z.ZodDefault<z.ZodNumber>;
98
+ chromePath: z.ZodString;
99
+ auth: z.ZodObject<{
100
+ modes: z.ZodArray<z.ZodEnum<{
101
+ google: "google";
102
+ keys: "keys";
103
+ }>>;
104
+ google: z.ZodOptional<z.ZodObject<{
105
+ clientId: z.ZodString;
106
+ clientSecret: z.ZodString;
107
+ }, z.core.$strip>>;
108
+ sessionSecret: z.ZodOptional<z.ZodString>;
109
+ }, z.core.$strip>;
110
+ scopes: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
111
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
112
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
113
+ }, z.core.$strip>>>;
114
+ insiders: z.ZodDefault<z.ZodRecord<z.ZodEmail, z.ZodObject<{
115
+ scopes: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>, z.ZodObject<{
116
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
117
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
118
+ }, z.core.$strip>]>>;
119
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
120
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
121
+ seed: z.ZodOptional<z.ZodString>;
122
+ keyCreatedAt: z.ZodOptional<z.ZodString>;
123
+ }, z.core.$strip>>>;
124
+ keys: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
125
+ key: z.ZodString;
126
+ scopes: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>, z.ZodObject<{
127
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
128
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
129
+ }, z.core.$strip>]>>;
130
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
131
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
132
+ }, z.core.$strip>]>>>;
133
+ events: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
134
+ schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
135
+ cmd: z.ZodString;
136
+ map: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
137
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
138
+ }, z.core.$strip>>>;
139
+ eventTimeoutMs: z.ZodDefault<z.ZodNumber>;
140
+ eventLogPurgeMs: z.ZodDefault<z.ZodNumber>;
141
+ maxZipSizeMb: z.ZodDefault<z.ZodNumber>;
142
+ roots: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
143
+ mermaidCliPath: z.ZodOptional<z.ZodString>;
144
+ plantuml: z.ZodOptional<z.ZodObject<{
145
+ jarPath: z.ZodOptional<z.ZodString>;
146
+ javaPath: z.ZodOptional<z.ZodString>;
147
+ servers: z.ZodOptional<z.ZodArray<z.ZodURL>>;
148
+ }, z.core.$strip>>;
149
+ diagramCachePath: z.ZodOptional<z.ZodString>;
150
+ outsiderPolicy: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>, z.ZodObject<{
151
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
152
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
153
+ }, z.core.$strip>]>>;
154
+ oauth: z.ZodOptional<z.ZodObject<{
155
+ credentialDir: z.ZodString;
156
+ providers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
157
+ authUrl: z.ZodPipe<z.ZodString, z.ZodURL>;
158
+ tokenUrl: z.ZodPipe<z.ZodString, z.ZodURL>;
159
+ pkce: z.ZodDefault<z.ZodBoolean>;
160
+ defaultScopes: z.ZodDefault<z.ZodArray<z.ZodString>>;
161
+ }, z.core.$strip>>>;
162
+ }, z.core.$strip>>;
163
+ go: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
164
+ }, z.core.$strip>;
165
+ /** Inferred config type */
166
+ export type JeevesConfig = z.infer<typeof jeevesConfigSchema>;
167
+ /** Auth mode type */
168
+ export type AuthMode = z.infer<typeof authModeSchema>;
@@ -0,0 +1,252 @@
1
+ import { SERVER_PORT } from '@karmaniverous/jeeves';
2
+ import { z } from 'zod';
3
+
4
+ /** Config properties deprecated in v3.6.0 (now resolved via core services). */
5
+ const DEPRECATED_CONFIG_PROPS = [
6
+ 'host',
7
+ 'runnerUrl',
8
+ 'watcherUrl',
9
+ 'metaUrl',
10
+ ];
11
+ /** Supported authentication methods */
12
+ const authModeSchema = z.enum(['google', 'keys']);
13
+ /** Google OAuth configuration */
14
+ const googleAuthSchema = z.object({
15
+ clientId: z.string().min(1),
16
+ clientSecret: z.string().min(1),
17
+ });
18
+ /** Auth configuration */
19
+ const authSchema = z.object({
20
+ /** Active authentication methods. Order determines priority. */
21
+ modes: z
22
+ .array(authModeSchema)
23
+ .min(1, { message: 'At least one auth mode is required' }),
24
+ /** Google OAuth config. Required if modes includes "google". */
25
+ google: googleAuthSchema.optional(),
26
+ /** Session cookie signing secret. Required if modes includes "google". */
27
+ sessionSecret: z.string().min(1).optional(),
28
+ });
29
+ /** Event webhook configuration */
30
+ const eventConfigSchema = z.object({
31
+ schema: z.record(z.string(), z.unknown()),
32
+ cmd: z.string(),
33
+ map: z.record(z.string(), z.unknown()).optional(),
34
+ timeoutMs: z.number().positive().optional(),
35
+ });
36
+ /**
37
+ * Scopes configuration — controls which paths a user/key can access.
38
+ *
39
+ * Three forms:
40
+ * - `string` — single allow pattern (e.g. '/d/*')
41
+ * - `string[]` — array of allow patterns (shorthand for \{ allow: [...] \})
42
+ * - `\{ allow?: string[], deny?: string[] \}` — explicit allow/deny rules
43
+ *
44
+ * Semantics:
45
+ * - Path must match at least one allow rule AND NOT match any deny rule
46
+ * - Omitting `allow` = implicit ['/*'] (allow everything)
47
+ * - Omitting `deny` = no exclusions
48
+ * - Omitting scopes entirely = unrestricted access
49
+ */
50
+ const scopesObjectSchema = z.object({
51
+ allow: z.array(z.string()).optional(),
52
+ deny: z.array(z.string()).optional(),
53
+ });
54
+ const scopesSchema = z.union([
55
+ z.string(),
56
+ z.array(z.string()),
57
+ scopesObjectSchema,
58
+ ]);
59
+ /** Insider entry (identity + scopes + optional persisted seed) */
60
+ const insiderEntrySchema = z.object({
61
+ scopes: scopesSchema.optional(),
62
+ /** Extra allow patterns merged on top of named scope references */
63
+ allow: z.array(z.string()).optional(),
64
+ /** Extra deny patterns merged on top of named scope references */
65
+ deny: z.array(z.string()).optional(),
66
+ /** Auto-generated insider seed, persisted in config.json */
67
+ seed: z.string().min(1).optional(),
68
+ /** ISO timestamp of when the seed was created */
69
+ keyCreatedAt: z.string().optional(),
70
+ });
71
+ /** Key entry — plain string (seed, no scopes) or object with key + optional scopes */
72
+ const keyEntrySchema = z.union([
73
+ z.string().min(1),
74
+ z.object({
75
+ key: z.string().min(1),
76
+ scopes: scopesSchema.optional(),
77
+ /** Extra allow patterns merged on top of named scope references */
78
+ allow: z.array(z.string()).optional(),
79
+ /** Extra deny patterns merged on top of named scope references */
80
+ deny: z.array(z.string()).optional(),
81
+ }),
82
+ ]);
83
+ /** Check if a string is a named scope identifier (not a path glob). */
84
+ function isScopeName(v) {
85
+ return /^[A-Za-z0-9_-]+$/.test(v);
86
+ }
87
+ /** Helper: collect named scope references from a scopes field value.
88
+ *
89
+ * Backward-compat note: `scopes` has historically accepted path globs like "/**" or ["/a","/b"].
90
+ * We only treat values as *named scope references* if they look like identifiers
91
+ * (e.g. "restricted", "no-vc") rather than path globs.
92
+ */
93
+ function getScopeRefs(scopes) {
94
+ if (typeof scopes === 'string')
95
+ return isScopeName(scopes) ? [scopes] : [];
96
+ if (Array.isArray(scopes) && scopes.length > 0) {
97
+ const strs = scopes.filter((v) => typeof v === 'string');
98
+ if (strs.length !== scopes.length)
99
+ return [];
100
+ return strs.filter((v) => isScopeName(v));
101
+ }
102
+ return [];
103
+ }
104
+ /** OAuth provider configuration */
105
+ const oauthProviderSchema = z.object({
106
+ authUrl: z.string().pipe(z.url()),
107
+ tokenUrl: z.string().pipe(z.url()),
108
+ pkce: z.boolean().default(false),
109
+ defaultScopes: z.array(z.string()).default([]),
110
+ });
111
+ /** OAuth configuration */
112
+ const oauthSchema = z.object({
113
+ credentialDir: z.string(),
114
+ providers: z.record(z.string(), oauthProviderSchema).default({}),
115
+ });
116
+ /** Top-level Jeeves Server configuration */
117
+ const jeevesConfigSchema = z
118
+ .object({
119
+ port: z.number().int().positive().default(SERVER_PORT),
120
+ chromePath: z.string().min(1),
121
+ auth: authSchema,
122
+ /** Named scope definitions, referenced by insiders/keys/outsiderPolicy */
123
+ scopes: z.record(z.string(), scopesObjectSchema).default({}),
124
+ insiders: z.record(z.email(), insiderEntrySchema).default({}),
125
+ keys: z.record(z.string(), keyEntrySchema).default({}),
126
+ events: z.record(z.string(), eventConfigSchema).default({}),
127
+ eventTimeoutMs: z.number().positive().default(30_000),
128
+ eventLogPurgeMs: z.number().positive().default(2_592_000_000),
129
+ /** Maximum directory size in MB for ZIP export. Directories exceeding this are refused. */
130
+ maxZipSizeMb: z.number().positive().default(100),
131
+ /**
132
+ * Filesystem roots for the file browser (Linux only).
133
+ * Map of id → filesystem path. On Windows this is ignored (drives are auto-discovered).
134
+ * Example: \{ home: '/home/user', projects: '/opt/projects' \}
135
+ * Default: \{ root: '/' \}
136
+ */
137
+ roots: z.record(z.string(), z.string()).optional(),
138
+ /** @deprecated Mermaid is now bundled. This field is ignored but kept for backward compatibility. */
139
+ mermaidCliPath: z.string().optional(),
140
+ /**
141
+ * PlantUML rendering configuration.
142
+ * - jarPath: local PlantUML jar (requires Java). Tried first — supports !include.
143
+ * - servers: fallback PlantUML server URLs, tried in order.
144
+ * The public community server (https://www.plantuml.com/plantuml) is always
145
+ * appended as the last resort unless explicitly listed.
146
+ * If omitted entirely, only the community server is used.
147
+ */
148
+ plantuml: z
149
+ .object({
150
+ jarPath: z.string().optional(),
151
+ javaPath: z.string().optional(),
152
+ servers: z.array(z.url()).optional(),
153
+ })
154
+ .optional(),
155
+ /**
156
+ * Directory for cached rendered diagrams (content-addressed by source hash).
157
+ * Defaults to `.diagram-cache` in the server working directory.
158
+ */
159
+ diagramCachePath: z.string().optional(),
160
+ /**
161
+ * Global outsider policy — constrains which paths are eligible for outsider sharing.
162
+ * Uses the same allow/deny model as insider scopes.
163
+ * If omitted, all paths are shareable with outsiders.
164
+ */
165
+ outsiderPolicy: scopesSchema.optional(),
166
+ /** OAuth2 credential management configuration */
167
+ oauth: oauthSchema.optional(),
168
+ /**
169
+ * Shortlink redirects. Keys are slug identifiers (`[a-zA-Z0-9_-]+`),
170
+ * values are redirect targets — either relative paths (e.g. `/browse/...`)
171
+ * or absolute URLs (e.g. `https://example.com`).
172
+ *
173
+ * Accessible at `GET /go/:slug` without authentication.
174
+ */
175
+ go: z
176
+ .record(z.string().regex(/^[a-zA-Z0-9_-]+$/), z
177
+ .string()
178
+ .min(1)
179
+ .refine((v) => v.startsWith('/') || /^[a-z]+:\/\//i.test(v), {
180
+ message: 'Target must be a relative path starting with / or an absolute URL',
181
+ }))
182
+ .default({}),
183
+ })
184
+ .superRefine((config, ctx) => {
185
+ // Google auth mode requires google config + sessionSecret
186
+ if (config.auth.modes.includes('google')) {
187
+ if (!config.auth.google) {
188
+ ctx.addIssue({
189
+ code: 'custom',
190
+ message: 'auth.google is required when auth.modes includes "google"',
191
+ path: ['auth', 'google'],
192
+ });
193
+ }
194
+ if (!config.auth.sessionSecret) {
195
+ ctx.addIssue({
196
+ code: 'custom',
197
+ message: 'auth.sessionSecret is required when auth.modes includes "google"',
198
+ path: ['auth', 'sessionSecret'],
199
+ });
200
+ }
201
+ }
202
+ // Keys auth mode requires at least one key
203
+ if (config.auth.modes.includes('keys') &&
204
+ Object.keys(config.keys).length === 0) {
205
+ ctx.addIssue({
206
+ code: 'custom',
207
+ message: 'At least one key is required when auth.modes includes "keys"',
208
+ path: ['keys'],
209
+ });
210
+ }
211
+ // _internal and _plugin keys must not have scopes
212
+ for (const reserved of ['_internal', '_plugin']) {
213
+ const key = config.keys[reserved];
214
+ if (key && typeof key === 'object' && 'scopes' in key && key.scopes) {
215
+ ctx.addIssue({
216
+ code: 'custom',
217
+ message: `${reserved} key must not have scopes (it is always unscoped)`,
218
+ path: ['keys', reserved],
219
+ });
220
+ }
221
+ }
222
+ // Validate all scope name references resolve to the top-level scopes map
223
+ const scopeNames = new Set(Object.keys(config.scopes));
224
+ const validateRefs = (refs, refPath) => {
225
+ for (const ref of refs) {
226
+ if (!scopeNames.has(ref)) {
227
+ ctx.addIssue({
228
+ code: 'custom',
229
+ message: `Scope "${ref}" is not defined in the top-level scopes map`,
230
+ path: refPath,
231
+ });
232
+ }
233
+ }
234
+ };
235
+ for (const [email, entry] of Object.entries(config.insiders)) {
236
+ const refs = getScopeRefs(entry.scopes);
237
+ if (refs.length > 0)
238
+ validateRefs(refs, ['insiders', email, 'scopes']);
239
+ }
240
+ for (const [name, entry] of Object.entries(config.keys)) {
241
+ if (typeof entry === 'object') {
242
+ const refs = getScopeRefs(entry.scopes);
243
+ if (refs.length > 0)
244
+ validateRefs(refs, ['keys', name, 'scopes']);
245
+ }
246
+ }
247
+ const outsiderRefs = getScopeRefs(config.outsiderPolicy);
248
+ if (outsiderRefs.length > 0)
249
+ validateRefs(outsiderRefs, ['outsiderPolicy']);
250
+ });
251
+
252
+ export { DEPRECATED_CONFIG_PROPS, authModeSchema, authSchema, eventConfigSchema, googleAuthSchema, insiderEntrySchema, isScopeName, jeevesConfigSchema, keyEntrySchema, oauthProviderSchema, oauthSchema, scopesObjectSchema, scopesSchema };
@@ -88,4 +88,3 @@ export interface DriveEntry {
88
88
  letter: string;
89
89
  label: string;
90
90
  }
91
- //# sourceMappingURL=types.d.ts.map
package/package.json CHANGED
@@ -1,19 +1,32 @@
1
1
  {
2
2
  "name": "@karmaniverous/jeeves-server-core",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
+ "author": "Jeeves",
5
+ "description": "Shared cryptographic utilities and API types for jeeves-server packages.",
6
+ "license": "MIT",
4
7
  "type": "module",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/karmaniverous/jeeves-server.git",
11
+ "directory": "packages/core"
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
5
16
  "publishConfig": {
6
17
  "access": "public"
7
18
  },
8
19
  "scripts": {
9
20
  "prebuild": "npx rimraf dist",
10
- "build": "tsc",
21
+ "build": "cross-env NO_COLOR=1 rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript",
11
22
  "lint": "eslint .",
12
23
  "lint:fix": "eslint --fix .",
13
24
  "test": "vitest run --passWithNoTests",
14
25
  "typecheck": "tsc --noEmit",
26
+ "changelog": "git-cliff -o CHANGELOG.md",
15
27
  "release": "dotenvx run -f .env.local -- release-it",
16
- "release:pre": "dotenvx run -f .env.local -- release-it --no-git.requireBranch --github.prerelease --preRelease"
28
+ "release:pre": "dotenvx run -f .env.local -- release-it --no-git.requireBranch --github.prerelease --preRelease",
29
+ "postbuild": "npx rimraf dist/rollup.config.d.ts dist/rollup.config.d.ts.map"
17
30
  },
18
31
  "exports": {
19
32
  ".": {
@@ -24,18 +37,28 @@
24
37
  }
25
38
  },
26
39
  "types": "dist/src/index.d.ts",
40
+ "dependencies": {
41
+ "@karmaniverous/jeeves": "^0.5.10",
42
+ "zod": "^4.4.3"
43
+ },
27
44
  "devDependencies": {
28
- "vitest": "^4.1.2",
45
+ "@dotenvx/dotenvx": "^1.65.0",
46
+ "@rollup/plugin-commonjs": "^29.0.2",
47
+ "@rollup/plugin-json": "^6.1.0",
48
+ "@rollup/plugin-node-resolve": "^16.0.3",
49
+ "@rollup/plugin-typescript": "^12.3.0",
50
+ "cross-env": "^10.1.0",
29
51
  "release-it": "^19.2.4",
30
- "auto-changelog": "^2.5.0",
31
- "@dotenvx/dotenvx": "^1.59.1"
52
+ "rollup": "^4.60.3",
53
+ "tslib": "^2.8.1",
54
+ "vitest": "^4.1.6"
32
55
  },
33
56
  "engines": {
34
57
  "node": ">=22"
35
58
  },
36
59
  "release-it": {
37
60
  "git": {
38
- "changelog": "npx auto-changelog --unreleased-only --stdout --template https://raw.githubusercontent.com/release-it/release-it/main/templates/changelog-compact.hbs",
61
+ "changelog": "npx git-cliff --unreleased --strip header",
39
62
  "commitMessage": "chore: release @karmaniverous/jeeves-server-core v${version}",
40
63
  "tagName": "core/${version}",
41
64
  "requireBranch": "main"
@@ -51,7 +74,7 @@
51
74
  "npm run build"
52
75
  ],
53
76
  "before:npm:release": [
54
- "npx auto-changelog -p",
77
+ "npx git-cliff -o CHANGELOG.md",
55
78
  "git add -A"
56
79
  ],
57
80
  "after:release": [
package/.env.local DELETED
@@ -1,13 +0,0 @@
1
- # This file is a template for the .env.local. Add your Personal Access Token
2
- # below to streamline the release process from your desktop! Just follow these
3
- # steps:
4
- #
5
- # 1. Make a copy of this file and rename it to .env.local.
6
- #
7
- # 2. Create a Personal Access Token at https://github.com/settings/tokens and
8
- # enter it below.
9
- #
10
- # .env.local is gitignored and will NOT be persisted to your repo, but don't
11
- # put any secrets in this template!
12
-
13
- GITHUB_TOKEN=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
@@ -1,13 +0,0 @@
1
- # This file is a template for the .env.local. Add your Personal Access Token
2
- # below to streamline the release process from your desktop! Just follow these
3
- # steps:
4
- #
5
- # 1. Make a copy of this file and rename it to .env.local.
6
- #
7
- # 2. Create a Personal Access Token at https://github.com/settings/tokens and
8
- # enter it below.
9
- #
10
- # .env.local is gitignored and will NOT be persisted to your repo, but don't
11
- # put any secrets in this template!
12
-
13
- GITHUB_TOKEN=
package/CHANGELOG.md DELETED
@@ -1,354 +0,0 @@
1
- ### Changelog
2
-
3
- All notable changes to this project will be documented in this file. Dates are displayed in UTC.
4
-
5
- Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
-
7
- #### [v0.1.0](https://github.com/karmaniverous/jeeves-server/compare/v2.9.3...v0.1.0)
8
-
9
- - fix: rename shared to core, add release-it, upgrade client eslint [`#197`](https://github.com/karmaniverous/jeeves-server/pull/197)
10
- - fix: upgrade client eslint to v10, fix lint errors from stricter rules [`#196`](https://github.com/karmaniverous/jeeves-server/pull/196)
11
- - feat: create shared package, add missing plugin tools, DRY types (#194) [`#195`](https://github.com/karmaniverous/jeeves-server/pull/195)
12
- - feat: create shared package, add missing plugin tools, DRY types [`#194`](https://github.com/karmaniverous/jeeves-server/pull/194)
13
- - fix: remove state.json and dead keyRotatedAt code (#192) [`#193`](https://github.com/karmaniverous/jeeves-server/pull/193)
14
- - fix: remove state.json and dead keyRotatedAt code [`#192`](https://github.com/karmaniverous/jeeves-server/pull/192)
15
- - fix: resolve state.json from state root instead of package directory (#185) [`#186`](https://github.com/karmaniverous/jeeves-server/pull/186)
16
- - feat: add copy button to table cell hover controls (#188) [`#189`](https://github.com/karmaniverous/jeeves-server/pull/189)
17
- - fix: add /api prefix to OAuth API routes (#190) [`#191`](https://github.com/karmaniverous/jeeves-server/pull/191)
18
- - fix: add /api prefix to OAuth API routes [`#190`](https://github.com/karmaniverous/jeeves-server/pull/190)
19
- - feat: add copy button to table cell hover controls [`#188`](https://github.com/karmaniverous/jeeves-server/pull/188)
20
- - fix: store insider seeds in config.json instead of state.json (#185) [`#187`](https://github.com/karmaniverous/jeeves-server/pull/187)
21
- - fix: store insider seeds in config.json instead of state.json [`#185`](https://github.com/karmaniverous/jeeves-server/pull/185)
22
- - fix: resolve state.json from state root instead of package directory [`#185`](https://github.com/karmaniverous/jeeves-server/pull/185)
23
- - fix: authenticate embedded images for all outsider shares (#183) [`#184`](https://github.com/karmaniverous/jeeves-server/pull/184)
24
- - feat: /go/:slug shortlink redirects (#180) [`#182`](https://github.com/karmaniverous/jeeves-server/pull/182)
25
- - fix: resolve serverRoot via package.json discovery (#178) [`#179`](https://github.com/karmaniverous/jeeves-server/pull/179)
26
- - fix: edit popup scrollbar and word wrap [`#173`](https://github.com/karmaniverous/jeeves-server/pull/173)
27
- - fix: dev server white screen — serve built client under tsx [`#171`](https://github.com/karmaniverous/jeeves-server/pull/171)
28
- - fix: constrain edit popup height to prevent overflow [`#169`](https://github.com/karmaniverous/jeeves-server/pull/169)
29
- - feat: markdown-it migration, inline block editing, OAuth2 flow (#162, #163) [`#165`](https://github.com/karmaniverous/jeeves-server/pull/165)
30
- - fix: make clear-cache visible to outsiders in download menu [`#161`](https://github.com/karmaniverous/jeeves-server/pull/161)
31
- - refactor: simplify checkbox toggle to fire-and-forget [`#160`](https://github.com/karmaniverous/jeeves-server/pull/160)
32
- - fix: checkbox indexing for loose list items [`#159`](https://github.com/karmaniverous/jeeves-server/pull/159)
33
- - fix: post-merge checkbox toggle, Gemini review, CI wildcard [`#158`](https://github.com/karmaniverous/jeeves-server/pull/158)
34
- - feat: v3.7.0 / v0.8.0 — shareable URLs, insider checkbox toggles, events route fix [`#157`](https://github.com/karmaniverous/jeeves-server/pull/157)
35
- - [V3-7] feat: wire MarkdownView checkbox toggling [`#154`](https://github.com/karmaniverous/jeeves-server/pull/154)
36
- - [V3-7] feat: add POST /api/file/*/toggle-checkbox endpoint [`#154`](https://github.com/karmaniverous/jeeves-server/pull/154)
37
- - [V3-7] feat: add checkbox indexing and mtime to markdown pipeline [`#154`](https://github.com/karmaniverous/jeeves-server/pull/154)
38
- - [V3-7] feat: update TOOLS guidance to note automatic URL rewriting [`#152`](https://github.com/karmaniverous/jeeves-server/pull/152)
39
- - [V3-7] feat: add publicUrl config for shareable URL rewriting [`#145`](https://github.com/karmaniverous/jeeves-server/pull/145)
40
- - [V3-7] fix: correct /events route path to /api/events [`#156`](https://github.com/karmaniverous/jeeves-server/pull/156)
41
- - fix: consume core importMetaUrl for plugin install (#150, #147) [`#151`](https://github.com/karmaniverous/jeeves-server/pull/151)
42
- - [150] fix: consume core importMetaUrl for plugin install [`#150`](https://github.com/karmaniverous/jeeves-server/pull/150)
43
- - chore: dependency updates — jeeves ^0.5.3, jsonmap ^2.1.1, @types/node ^25.5.2, and minor/patch bumps [`#149`](https://github.com/karmaniverous/jeeves-server/pull/149)
44
- - feat: v3.6.0 core v0.5.1 adoption + core service alignment + UX improvements [`#146`](https://github.com/karmaniverous/jeeves-server/pull/146)
45
- - [53] Fix pre-existing lint + knip errors (Commander type resolution) [`#140`](https://github.com/karmaniverous/jeeves-server/pull/140)
46
- - [53] Integrate core v0.4.6: init() before descriptor.run() + knip fixes [`#139`](https://github.com/karmaniverous/jeeves-server/pull/139)
47
- - [51] Integrate descriptor.run from core v0.4.5 [`#137`](https://github.com/karmaniverous/jeeves-server/pull/137)
48
- - Fix config validate test assertion [`#136`](https://github.com/karmaniverous/jeeves-server/pull/136)
49
- - [35] Component SDK adoption (core v0.4.4) + plugin/CLI factories [`#134`](https://github.com/karmaniverous/jeeves-server/pull/134)
50
- - [35] refactor: replace hand-rolled package.json walk with packageDirectorySync [`#96`](https://github.com/karmaniverous/jeeves-server/pull/96)
51
- - [35] fix: show user-friendly search error messages [`#98`](https://github.com/karmaniverous/jeeves-server/pull/98)
52
- - [35] fix: decode HTML entities in TOC heading text [`#102`](https://github.com/karmaniverous/jeeves-server/pull/102)
53
- - Remove /health proxy, rename /stats to /status, align client types [`#122`](https://github.com/karmaniverous/jeeves-server/pull/122)
54
- - Fix runner proxy routes calling wrong endpoints [`#121`](https://github.com/karmaniverous/jeeves-server/pull/121)
55
- - Bump core to v0.3.0 and consolidate status endpoint [`#119`](https://github.com/karmaniverous/jeeves-server/pull/119)
56
- - Add configurable host bind + metaUrl service probe [`#114`](https://github.com/karmaniverous/jeeves-server/pull/114)
57
- - feat: core v0.2.0 SDK adoption [`#111`](https://github.com/karmaniverous/jeeves-server/pull/111)
58
- - feat(openclaw): adopt jeeves core component writer [`#105`](https://github.com/karmaniverous/jeeves-server/pull/105)
59
- - docs: document scope override precedence in OpenClaw skill [`#95`](https://github.com/karmaniverous/jeeves-server/pull/95)
60
- - feat: explicit scope overrides take precedence over named scopes [`#94`](https://github.com/karmaniverous/jeeves-server/pull/94)
61
- - fix: parse inline tokens in heading renderer [`#93`](https://github.com/karmaniverous/jeeves-server/pull/93)
62
- - fix: prevent full data reload on tab switch [`#91`](https://github.com/karmaniverous/jeeves-server/pull/91)
63
- - fix: Rendered tab persists when switching to Raw on watcher-rendered files [`#90`](https://github.com/karmaniverous/jeeves-server/pull/90)
64
- - feat: extend /api/status with ?events=N for recent event log [`#89`](https://github.com/karmaniverous/jeeves-server/pull/89)
65
- - fix: server_share sends POST with JSON body instead of GET [`#87`](https://github.com/karmaniverous/jeeves-server/pull/87)
66
- - docs: guide index content + typedoc jsonl highlight [`#86`](https://github.com/karmaniverous/jeeves-server/pull/86)
67
- - docs: refresh README + guides for v3 [`#85`](https://github.com/karmaniverous/jeeves-server/pull/85)
68
- - feat: named access scopes [`#84`](https://github.com/karmaniverous/jeeves-server/pull/84)
69
- - fix: plugin auth chain, status endpoint improvements [`#83`](https://github.com/karmaniverous/jeeves-server/pull/83)
70
- - fix: resetConfig should reload, not clear [`#82`](https://github.com/karmaniverous/jeeves-server/pull/82)
71
- - chore: integrate client as npm workspace member [`#81`](https://github.com/karmaniverous/jeeves-server/pull/81)
72
- - fix: force white background in panzoom fullscreen (dark mode) [`#80`](https://github.com/karmaniverous/jeeves-server/pull/80)
73
- - chore: make both packages releasable [`#79`](https://github.com/karmaniverous/jeeves-server/pull/79)
74
- - fix: address Gemini code review feedback (PRs #65-#76) [`#78`](https://github.com/karmaniverous/jeeves-server/pull/78)
75
- - chore: fix all gap analysis findings (10 items) [`#77`](https://github.com/karmaniverous/jeeves-server/pull/77)
76
- - Phase 4, Steps 16-18: Document rendering pipeline [`#76`](https://github.com/karmaniverous/jeeves-server/pull/76)
77
- - Phase 3, Steps 11-15: OpenClaw plugin [`#75`](https://github.com/karmaniverous/jeeves-server/pull/75)
78
- - Phase 2, Steps 9-10: Search facets proxy + filter UI [`#74`](https://github.com/karmaniverous/jeeves-server/pull/74)
79
- - Phase 2, Step 8: Scroll anchoring [`#73`](https://github.com/karmaniverous/jeeves-server/pull/73)
80
- - chore: SOLID/DRY/coverage audit pass 2 [`#72`](https://github.com/karmaniverous/jeeves-server/pull/72)
81
- - Phase 2, Step 7: Link availability endpoint [`#71`](https://github.com/karmaniverous/jeeves-server/pull/71)
82
- - Phase 1, Step 6: Port migration [`#70`](https://github.com/karmaniverous/jeeves-server/pull/70)
83
- - Phase 1, Step 5: Diagram dependency internalization [`#69`](https://github.com/karmaniverous/jeeves-server/pull/69)
84
- - Phase 1, Step 4: Server Status API [`#68`](https://github.com/karmaniverous/jeeves-server/pull/68)
85
- - Phase 1, Step 3: CLI commands [`#67`](https://github.com/karmaniverous/jeeves-server/pull/67)
86
- - Phase 1, Step 2: Config migration (jiti → cosmiconfig) [`#66`](https://github.com/karmaniverous/jeeves-server/pull/66)
87
- - Phase 1: Monorepo & Config (v3.0.0) [`#65`](https://github.com/karmaniverous/jeeves-server/pull/65)
88
- - feat: align search browse filter with watcher domains convention [`#64`](https://github.com/karmaniverous/jeeves-server/pull/64)
89
- - fix: exit edit mode after save [`#63`](https://github.com/karmaniverous/jeeves-server/pull/63)
90
- - chore: add default port 1934 [`#62`](https://github.com/karmaniverous/jeeves-server/pull/62)
91
- - chore: add default port 1934 [`#61`](https://github.com/karmaniverous/jeeves-server/pull/61)
92
- - [150] fix: consume core importMetaUrl for plugin install (#150) [`#150`](https://github.com/karmaniverous/jeeves-server/issues/150) [`#147`](https://github.com/karmaniverous/jeeves-server/issues/147)
93
- - [360] feat: Phase 3 — UX improvements (CSV tables, directory item counts, collapsible frontmatter, collapsible TOC) [`#48`](https://github.com/karmaniverous/jeeves-server/issues/48)
94
- - [360] feat: Phase 1 — core service adoption (getServiceUrl, getBindAddress, Node 22 fast-fail) [`#135`](https://github.com/karmaniverous/jeeves-server/issues/135)
95
- - [35] refactor: remove Connected Services from TOOLS.md writer (closes #128) [`#128`](https://github.com/karmaniverous/jeeves-server/issues/128)
96
- - fix: parse inline tokens in heading renderer (code spans, bold, italic) [`#92`](https://github.com/karmaniverous/jeeves-server/issues/92)
97
- - [35] chore: update deps (peer-safe) [`c87c3a1`](https://github.com/karmaniverous/jeeves-server/commit/c87c3a1d10a15654ceac04c493d90abd65fe05d6)
98
- - chore: add docs workflow, gitignore generated docs [`10bffb8`](https://github.com/karmaniverous/jeeves-server/commit/10bffb8b6ce9c45c31e88b07e26c4657cfba0776)
99
- - fix: regenerate lockfile with npm 11.11.0 for Linux CI compatibility [`05c0014`](https://github.com/karmaniverous/jeeves-server/commit/05c00141c9d1df2f2763e535dfca315a3ac29ea8)
100
-
101
- #### [v2.9.3](https://github.com/karmaniverous/jeeves-server/compare/v2.9.2...v2.9.3)
102
-
103
- > 26 February 2026
104
-
105
- - feat: render YAML frontmatter as code block [`#60`](https://github.com/karmaniverous/jeeves-server/pull/60)
106
- - feat: render YAML frontmatter as code block in markdown view [`3045a94`](https://github.com/karmaniverous/jeeves-server/commit/3045a94a2364455cdeac6f36f3446fc561d37737)
107
- - chore: release v2.9.3 [`1475596`](https://github.com/karmaniverous/jeeves-server/commit/1475596bcb2dd22f2c5f1621b670fc50898a11d7)
108
-
109
- #### [v2.9.2](https://github.com/karmaniverous/jeeves-server/compare/v2.9.1...v2.9.2)
110
-
111
- > 24 February 2026
112
-
113
- - feat: sortable columns on runner dashboard [`023a473`](https://github.com/karmaniverous/jeeves-server/commit/023a473b53b1469b52eccda5dff76f4da2d8989f)
114
- - chore: release v2.9.2 [`d3db011`](https://github.com/karmaniverous/jeeves-server/commit/d3db011a3d395de57537b7054e7ad06be160d698)
115
-
116
- #### [v2.9.1](https://github.com/karmaniverous/jeeves-server/compare/v2.9.0...v2.9.1)
117
-
118
- > 24 February 2026
119
-
120
- - fix: dark mode status pills via custom-variant [`30454de`](https://github.com/karmaniverous/jeeves-server/commit/30454dec84984573214abdff5d9fcbe12d3b4e9a)
121
- - chore: release v2.9.1 [`d34fd62`](https://github.com/karmaniverous/jeeves-server/commit/d34fd6205e87bd9ec7f5941ba498d3493a87f6ea)
122
- - chore: release v2.9.0 [`7cdc030`](https://github.com/karmaniverous/jeeves-server/commit/7cdc03037b0bc4c25b69e849bed7f7be0f47be93)
123
-
124
- #### [v2.9.0](https://github.com/karmaniverous/jeeves-server/compare/v2.8.0...v2.9.0)
125
-
126
- > 24 February 2026
127
-
128
- - feat: add runner dashboard [`#59`](https://github.com/karmaniverous/jeeves-server/pull/59)
129
- - fix: event queue byte/char cursor mismatch + postbuild client [`#52`](https://github.com/karmaniverous/jeeves-server/pull/52)
130
- - fix: client TS errors + picomatch dot matching [`#51`](https://github.com/karmaniverous/jeeves-server/pull/51)
131
- - gitignores [`601737f`](https://github.com/karmaniverous/jeeves-server/commit/601737f2218dcd87c6979176541df4795279aa39)
132
- - chore: release v2.9.0 [`7813907`](https://github.com/karmaniverous/jeeves-server/commit/78139078c7c5339e963db21940a7e70b1d4a78c1)
133
-
134
- #### [v2.8.0](https://github.com/karmaniverous/jeeves-server/compare/v2.7.5...v2.8.0)
135
-
136
- > 23 February 2026
137
-
138
- - [GH-46] Semantic search UI [`#47`](https://github.com/karmaniverous/jeeves-server/pull/47)
139
- - [GH-46] GH-46: Semantic search — backend proxy + frontend modal [`80383d1`](https://github.com/karmaniverous/jeeves-server/commit/80383d1ac18b3e7ad3278f384d6d7a533fac10dd)
140
- - [GH-46] GH-46: Date range filtering (relative + absolute) [`e775502`](https://github.com/karmaniverous/jeeves-server/commit/e775502c4c26576bc7d38f2cd2c9dd1b1cf639c0)
141
- - [GH-46] GH-46: Accordion chunks with scrollable container [`d9462e0`](https://github.com/karmaniverous/jeeves-server/commit/d9462e05b6958484f3ded9baf12d48b435818bc2)
142
-
143
- #### [v2.7.5](https://github.com/karmaniverous/jeeves-server/compare/v2.7.4...v2.7.5)
144
-
145
- > 22 February 2026
146
-
147
- - [GH-44] Cache exports + Clear Cache control [`#45`](https://github.com/karmaniverous/jeeves-server/pull/45)
148
- - [GH-44] GH-44: Add export cache + Clear Cache endpoint and UI [`bf41cd0`](https://github.com/karmaniverous/jeeves-server/commit/bf41cd00ac2d56c6f42d763115feb9ae88e1f5aa)
149
- - [GH-44] Clear cache covers standalone diagram files (mmd/puml) [`63ba5c8`](https://github.com/karmaniverous/jeeves-server/commit/63ba5c823ca0be448bebe5c691819d8dd039c79d)
150
- - [GH-44] Add .export-cache/ to gitignore [`80ade63`](https://github.com/karmaniverous/jeeves-server/commit/80ade63660b02ebecede3f08f73cd281bf1fc69e)
151
-
152
- #### [v2.7.4](https://github.com/karmaniverous/jeeves-server/compare/v2.7.3...v2.7.4)
153
-
154
- > 22 February 2026
155
-
156
- - GH-42: Unify raw view on CodeMirror 6 with code folding [`#43`](https://github.com/karmaniverous/jeeves-server/pull/43)
157
- - [GH-42] Replace highlight.js raw view with CodeMirror 6 read-only viewer [`547315c`](https://github.com/karmaniverous/jeeves-server/commit/547315ca640b352d54c6ab58f4dad0c83383a6e8)
158
- - [GH-42] Remove highlight.js — CM6 handles all syntax highlighting [`52415ae`](https://github.com/karmaniverous/jeeves-server/commit/52415aed229b25ad2bb75473b7e1eb0cb28cd769)
159
- - [GH-42] Fix DOCX code block rendering — per-line paragraphs with NBSP indent [`61db677`](https://github.com/karmaniverous/jeeves-server/commit/61db677ca130fa04e3ffba475ed1c11a2676cd2c)
160
-
161
- #### [v2.7.3](https://github.com/karmaniverous/jeeves-server/compare/v2.7.2...v2.7.3)
162
-
163
- > 22 February 2026
164
-
165
- - GH-40: Retry button for failed inline diagram renders [`#41`](https://github.com/karmaniverous/jeeves-server/pull/41)
166
- - [GH-40] Add retry button to failed inline diagram renders [`1fe10bd`](https://github.com/karmaniverous/jeeves-server/commit/1fe10bd731f9429c1cf691317a283d71b6a9592b)
167
- - [GH-40] Improve error message and add reload hint on retry failure [`b0c02c8`](https://github.com/karmaniverous/jeeves-server/commit/b0c02c88cfa5b67f73de5f64dff47d87779e0999)
168
-
169
- #### [v2.7.2](https://github.com/karmaniverous/jeeves-server/compare/v2.7.1...v2.7.2)
170
-
171
- > 22 February 2026
172
-
173
- - GH-38: Terms of Service, Privacy Policy & search engine blocking [`#39`](https://github.com/karmaniverous/jeeves-server/pull/39)
174
-
175
- #### [v2.7.1](https://github.com/karmaniverous/jeeves-server/compare/v2.7.0...v2.7.1)
176
-
177
- > 21 February 2026
178
-
179
- - SOLID/DRY codebase audit — comprehensive refactor [`#37`](https://github.com/karmaniverous/jeeves-server/pull/37)
180
-
181
- #### [v2.7.0](https://github.com/karmaniverous/jeeves-server/compare/v2.6.0...v2.7.0)
182
-
183
- > 21 February 2026
184
-
185
- - GH-32 + GH-33: Diagram cache + lazy-load embedded diagrams [`74b68be`](https://github.com/karmaniverous/jeeves-server/commit/74b68be594735260dbd9645e565f04a73ba76d5e)
186
-
187
- #### [v2.6.0](https://github.com/karmaniverous/jeeves-server/compare/v2.5.0...v2.6.0)
188
-
189
- > 20 February 2026
190
-
191
- - feat: in-browser text editing (GH-30) [`#31`](https://github.com/karmaniverous/jeeves-server/pull/31)
192
- - chore: bump version to 2.6.0 [`7d54aa3`](https://github.com/karmaniverous/jeeves-server/commit/7d54aa3be4c4ae0093ed86bd16d98e57ed3bdf77)
193
-
194
- #### [v2.5.0](https://github.com/karmaniverous/jeeves-server/compare/v2.4.0...v2.5.0)
195
-
196
- > 20 February 2026
197
-
198
- - feat: Render embedded Mermaid/PlantUML code blocks (GH-23) [`#27`](https://github.com/karmaniverous/jeeves-server/pull/27)
199
- - chore: bump version to 2.5.0 [`2c42e14`](https://github.com/karmaniverous/jeeves-server/commit/2c42e14aa5e6324b67c5ef0dc615cece50cf1992)
200
-
201
- #### [v2.4.0](https://github.com/karmaniverous/jeeves-server/compare/v2.3.5...v2.4.0)
202
-
203
- > 20 February 2026
204
-
205
- - feat: Native PlantUML support (GH-22) [`#25`](https://github.com/karmaniverous/jeeves-server/pull/25)
206
- - chore: bump version to 2.4.0 [`ddf9d87`](https://github.com/karmaniverous/jeeves-server/commit/ddf9d87cf8b42420d0bc3e24b46489bbec04aff8)
207
-
208
- #### [v2.3.5](https://github.com/karmaniverous/jeeves-server/compare/v2.3.4...v2.3.5)
209
-
210
- > 20 February 2026
211
-
212
- - fix: case-insensitive email comparison for insider matching [`#24`](https://github.com/karmaniverous/jeeves-server/pull/24)
213
-
214
- #### [v2.3.4](https://github.com/karmaniverous/jeeves-server/compare/v2.3.3...v2.3.4)
215
-
216
- > 19 February 2026
217
-
218
- - refactor: Copy Raw Link builds /api/raw/ URL directly, remove raw=1 redirect [`#21`](https://github.com/karmaniverous/jeeves-server/pull/21)
219
-
220
- #### [v2.3.3](https://github.com/karmaniverous/jeeves-server/compare/v2.3.2...v2.3.3)
221
-
222
- > 19 February 2026
223
-
224
- - feat: raw=1 on /browse/* redirects to /api/raw/* for raw file delivery [`#20`](https://github.com/karmaniverous/jeeves-server/pull/20)
225
-
226
- #### [v2.3.2](https://github.com/karmaniverous/jeeves-server/compare/v2.3.1...v2.3.2)
227
-
228
- > 19 February 2026
229
-
230
- - fix: forward auth params on downloads, show error popup on failure [`#19`](https://github.com/karmaniverous/jeeves-server/pull/19)
231
-
232
- #### [v2.3.1](https://github.com/karmaniverous/jeeves-server/compare/v2.3.0...v2.3.1)
233
-
234
- > 18 February 2026
235
-
236
- - refactor: replace hand-rolled glob matching with picomatch [`#18`](https://github.com/karmaniverous/jeeves-server/pull/18)
237
-
238
- #### [v2.3.0](https://github.com/karmaniverous/jeeves-server/compare/v2.2.1...v2.3.0)
239
-
240
- > 18 February 2026
241
-
242
- - [GH-16] feat(GH-16): utility share-for endpoint + outsider policy [`#17`](https://github.com/karmaniverous/jeeves-server/pull/17)
243
-
244
- #### [v2.2.1](https://github.com/karmaniverous/jeeves-server/compare/v2.2.0...v2.2.1)
245
-
246
- > 18 February 2026
247
-
248
- - Allow/deny scopes for insiders and keys [`#15`](https://github.com/karmaniverous/jeeves-server/pull/15)
249
- - chore: update repo description and add keywords to package.json [`5130698`](https://github.com/karmaniverous/jeeves-server/commit/51306983c3bcf6e8f8af8d49316512437c1cc1ff)
250
-
251
- #### [v2.2.0](https://github.com/karmaniverous/jeeves-server/compare/v2.1.0...v2.2.0)
252
-
253
- > 17 February 2026
254
-
255
- - GH-13: Linux compatibility [`#14`](https://github.com/karmaniverous/jeeves-server/pull/14)
256
-
257
- #### [v2.1.0](https://github.com/karmaniverous/jeeves-server/compare/v2.0.1...v2.1.0)
258
-
259
- > 17 February 2026
260
-
261
- - [GH-11] Deep share links with depth and directory controls [`#12`](https://github.com/karmaniverous/jeeves-server/pull/12)
262
- - docs: add platform support section, sync requirements with GH-11 implementation, call out Linux as next-up [`261ff4d`](https://github.com/karmaniverous/jeeves-server/commit/261ff4d69de26ef7fdc83295c7ea9e255ce9214e)
263
- - fix: header button hover in light mode - use white/10 overlay instead of accent bg [`eeb370c`](https://github.com/karmaniverous/jeeves-server/commit/eeb370c1dfaa79ba03f4685fddd664874f2b3e7a)
264
-
265
- #### [v2.0.1](https://github.com/karmaniverous/jeeves-server/compare/v2.0.0...v2.0.1)
266
-
267
- > 17 February 2026
268
-
269
- - Fix PDF/DOCX export rendering [`#10`](https://github.com/karmaniverous/jeeves-server/pull/10)
270
- - Decommission path routes [`#8`](https://github.com/karmaniverous/jeeves-server/pull/8)
271
- - [GH-9] fix DOCX SVG export — render SVGs in clean isolated pages [`#9`](https://github.com/karmaniverous/jeeves-server/issues/9)
272
- - [GH-9] fix DOCX SVG screenshot offset — use element.screenshot() instead of clip [`#9`](https://github.com/karmaniverous/jeeves-server/issues/9)
273
- - [GH-9] fix SVG rendering in SPA and PDF/DOCX export issues [`#9`](https://github.com/karmaniverous/jeeves-server/issues/9)
274
- - [GH-9] fix PDF/DOCX exports rendering panzoom container chrome [`#9`](https://github.com/karmaniverous/jeeves-server/issues/9)
275
- - [GH-7] decommission /path routes — migrate to /api/raw, /api/export, /browse redirect [`#7`](https://github.com/karmaniverous/jeeves-server/issues/7)
276
- - [GH-7] remove legacy server.js — replaced by src/server.ts [`6a701e6`](https://github.com/karmaniverous/jeeves-server/commit/6a701e6eb9325c39b20799673f5aee58877538ee)
277
- - [GH-7] remove server-rendered about page, templates, and test PDFs [`bad31ca`](https://github.com/karmaniverous/jeeves-server/commit/bad31ca3c4da5eb00ea9183c0b5a1dbb9442a0cf)
278
- - [GH-9] render DOCX SVGs at full page width (1152px) [`dbb5bae`](https://github.com/karmaniverous/jeeves-server/commit/dbb5bae948f762b65da047980fdcdf44c1999727)
279
-
280
- ### [v2.0.0](https://github.com/karmaniverous/jeeves-server/compare/v1.2.1...v2.0.0)
281
-
282
- > 16 February 2026
283
-
284
- - v2.0.0: React SPA migration [`#6`](https://github.com/karmaniverous/jeeves-server/pull/6)
285
- - [GH-5] merge: resolve conflicts with main (keep feature branch for frozen server pages) [`2c57b6f`](https://github.com/karmaniverous/jeeves-server/commit/2c57b6f11a0293c22da9c74c1b80b229b01f0fe0)
286
- - [GH-5] feat: React + Vite scaffold with file browser, API endpoints, and SPA serving (GH-5) [`6a8ffb5`](https://github.com/karmaniverous/jeeves-server/commit/6a8ffb5e932e648a44311ac9a686e5cb1b31c104)
287
- - [GH-5] Dropdown menus, TS config, state separation, local static assets [`16f40b4`](https://github.com/karmaniverous/jeeves-server/commit/16f40b4607037c8b5992a7a3bbf1d586d697cce8)
288
-
289
- #### [v1.2.1](https://github.com/karmaniverous/jeeves-server/compare/v1.2.0...v1.2.1)
290
-
291
- > 15 February 2026
292
-
293
- - fix: wrap entire startup in try/catch, surface errors instead of silent exit [`1913fe1`](https://github.com/karmaniverous/jeeves-server/commit/1913fe13af0bc992df7d49fc2d3a953fb4b1b538)
294
- - fix: mobile header — hide redundant share UI on directories, allow header wrapping (GH-4) [`6306f27`](https://github.com/karmaniverous/jeeves-server/commit/6306f27da93700757a328de83f34c5179b89bfc5)
295
- - fix: header stretches to full content width when zoomed out [`bbebeec`](https://github.com/karmaniverous/jeeves-server/commit/bbebeec052f1d76a1e1b14a7574bf35ffd1a3dc5)
296
-
297
- #### [v1.2.0](https://github.com/karmaniverous/jeeves-server/compare/v1.1.0...v1.2.0)
298
-
299
- > 15 February 2026
300
-
301
- - Merge feature/GH-4-google-oauth: Google OAuth + per-row share icons [`4706828`](https://github.com/karmaniverous/jeeves-server/commit/470682852b610da5a262501a216feaf71c035d34)
302
- - [GH-4] feat: add Google OAuth and cookie sessions (GH-4) [`89b6d72`](https://github.com/karmaniverous/jeeves-server/commit/89b6d729edc6e9a360aa1d8c745de0cdcd8d573f)
303
- - [GH-4] feat: directory outsider links, new share UI, per-insider key age (GH-4) [`4cbc001`](https://github.com/karmaniverous/jeeves-server/commit/4cbc001b1ed163b6735ff1667c70008d20729b43)
304
-
305
- #### [v1.1.0](https://github.com/karmaniverous/jeeves-server/compare/v1.0.3...v1.1.0)
306
-
307
- > 15 February 2026
308
-
309
- - v1.1.0: TypeScript/Fastify refactor, event gateway, named keys with scopes [`f3711f8`](https://github.com/karmaniverous/jeeves-server/commit/f3711f82ed0f30156c7980440ad55dec336be0df)
310
- - Merge feature/GH-3-ts-refactor: TypeScript/Fastify refactor with event gateway and named keys [`a920a99`](https://github.com/karmaniverous/jeeves-server/commit/a920a99e9975215c653a29decad2e9e578b438de)
311
- - [GH-3] TypeScript refactor scaffolding and core modules [`8dd0b92`](https://github.com/karmaniverous/jeeves-server/commit/8dd0b927e70eb89af416ce9708dcbc8de05a41da)
312
-
313
- #### [v1.0.3](https://github.com/karmaniverous/jeeves-server/compare/v1.0.2...v1.0.3)
314
-
315
- > 8 February 2026
316
-
317
- - Reduce PDF/DOCX font sizes to 10pt base [`2617ac9`](https://github.com/karmaniverous/jeeves-server/commit/2617ac969c6dc3d503fdb63760d8d8f68cdae0c7)
318
- - Fix PDF font size - add 10pt to PDF-specific styles [`18b3505`](https://github.com/karmaniverous/jeeves-server/commit/18b35059f3eef267cdcb01e51dd49e1d8a9fb173)
319
-
320
- #### [v1.0.2](https://github.com/karmaniverous/jeeves-server/compare/v1.0.1...v1.0.2)
321
-
322
- > 7 February 2026
323
-
324
- - Fix raw download for markdown files [`25952cd`](https://github.com/karmaniverous/jeeves-server/commit/25952cd0362a47ebdaf4958fc86436a96c1f8c1f)
325
- - Add top hat branding to outsider pages, improve filename display [`cacbb60`](https://github.com/karmaniverous/jeeves-server/commit/cacbb605b58064002aba3911009c5fb3788990ff)
326
- - Add 'Jeeves Server' tooltip to top hat in all modes [`26902d4`](https://github.com/karmaniverous/jeeves-server/commit/26902d45d74aea615f706700ebdf2068c4f95bd7)
327
-
328
- ### [v1.0.1](https://github.com/karmaniverous/jeeves-server/compare/v0.1.2...v1.0.1)
329
-
330
- > 7 February 2026
331
-
332
- #### [v0.1.2](https://github.com/karmaniverous/jeeves-server/compare/v0.1.1...v0.1.2)
333
-
334
- > 7 February 2026
335
-
336
- - Add HTML wrapper for SVG files with proper constraints [`edf794b`](https://github.com/karmaniverous/jeeves-server/commit/edf794beb8e1c81d4c4d698d4fc7ecef2412d66c)
337
- - Allow clickthrough on binary files, block only dangerous executables [`be338eb`](https://github.com/karmaniverous/jeeves-server/commit/be338ebdb7872b60682836ddd761f4e1a215ef5e)
338
- - Fix panzoom overlay sizing for tall SVGs - strip inline styles, size based on aspect ratio [`1fabf75`](https://github.com/karmaniverous/jeeves-server/commit/1fabf753cd0f22531cce2861e2fe80727dc00635)
339
-
340
- #### [v0.1.1](https://github.com/karmaniverous/jeeves-server/compare/v0.1.0...v0.1.1)
341
-
342
- > 7 February 2026
343
-
344
- - Fix DOCX image sizing: preserve aspect ratio within max bounds [`9755b15`](https://github.com/karmaniverous/jeeves-server/commit/9755b15d20e82c78c452e48c220214f1fb238293)
345
- - docs: add integration guide for other projects [`4512d9b`](https://github.com/karmaniverous/jeeves-server/commit/4512d9b881fd3de20f8c9c68fe3097fd4e97b7e7)
346
- - feat: detect text files by content (null bytes) instead of extension whitelist [`cf8c99a`](https://github.com/karmaniverous/jeeves-server/commit/cf8c99a911b268df9761da9efdde7526c4004e2b)
347
-
348
- #### v0.1.0
349
-
350
- > 7 February 2026
351
-
352
- - feat: track key rotation timestamp, display relative time, DRY up header components [`993023e`](https://github.com/karmaniverous/jeeves-server/commit/993023e240174cc420f43ca93187b69d9b49812f)
353
- - Add heading anchors, TOC, and Windows path linking [`f49962d`](https://github.com/karmaniverous/jeeves-server/commit/f49962da01488d244898aaceef4c5d0cecf72915)
354
- - Initial commit: Express server with webhook receiver, file server, and path-key auth [`31c83ca`](https://github.com/karmaniverous/jeeves-server/commit/31c83ca0593a09bfcece5501920dad7f8c78a74f)
@@ -1 +0,0 @@
1
- {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/crypto.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAOtE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMxD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GAAG,MAAM,GACtB,MAAM,CAKR;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,eAAe,GACtB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAM7D"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,4BAA4B,EAC5B,cAAc,EACd,KAAK,eAAe,EACpB,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,kBAAkB,EAClB,UAAU,EACV,wBAAwB,EACxB,UAAU,EACV,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,aAAa,GACd,MAAM,YAAY,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,oCAAoC;AACpC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,gCAAgC;AAChC,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,6CAA6C;AAC7C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,yCAAyC;AACzC,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,SAAS,GAAG,gBAAgB,GAAG,SAAS,GAAG,eAAe,CAAC;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,0CAA0C;AAC1C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,sCAAsC;AACtC,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,mCAAmC;AACnC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B;AAED,+CAA+C;AAC/C,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAED,6CAA6C;AAC7C,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE;QACP,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,kCAAkC;AAClC,MAAM,MAAM,kBAAkB,GAC1B,YAAY,GACZ,cAAc,GACd,cAAc,GACd,WAAW,GACX,iBAAiB,CAAC;AAEtB,qCAAqC;AACrC,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qCAAqC;AACrC,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,sCAAsC;AACtC,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf"}
package/dist/src/types.js DELETED
@@ -1,6 +0,0 @@
1
- /**
2
- * Shared API request/response types between service and plugin.
3
- *
4
- * @packageDocumentation
5
- */
6
- export {};
package/src/crypto.ts DELETED
@@ -1,81 +0,0 @@
1
- /**
2
- * Cryptographic utilities for HMAC key computation and verification.
3
- *
4
- * @packageDocumentation
5
- */
6
-
7
- import crypto from 'node:crypto';
8
-
9
- /**
10
- * Compute path-specific key: HMAC-SHA256(apiKey, normalizedPath)
11
- */
12
- export function computePathKey(apiKey: string, urlPath: string): string {
13
- const normalized = urlPath.toLowerCase().replace(/^\/+|\/+$/g, '');
14
- const hash = crypto
15
- .createHmac('sha256', apiKey)
16
- .update(normalized)
17
- .digest('hex');
18
- return hash.substring(0, 32);
19
- }
20
-
21
- /**
22
- * Compute insider key: HMAC-SHA256(apiKey, "insider")
23
- * Works for any path, grants full navigation
24
- */
25
- export function computeInsiderKey(apiKey: string): string {
26
- const hash = crypto
27
- .createHmac('sha256', apiKey)
28
- .update('insider')
29
- .digest('hex');
30
- return hash.substring(0, 32);
31
- }
32
-
33
- /**
34
- * Compute outsider key with expiry: HMAC-SHA256(apiKey, path + "|" + expiry)
35
- */
36
- export function computeOutsiderKeyWithExpiry(
37
- apiKey: string,
38
- urlPath: string,
39
- expiry: string | number,
40
- ): string {
41
- const normalized = urlPath.toLowerCase().replace(/^\/+|\/+$/g, '');
42
- const data = `${normalized}|${String(expiry)}`;
43
- const hash = crypto.createHmac('sha256', apiKey).update(data).digest('hex');
44
- return hash.substring(0, 32);
45
- }
46
-
47
- /**
48
- * Deep share key parameters
49
- */
50
- export interface DeepShareParams {
51
- depth: number;
52
- dirs: boolean;
53
- stack: string; // lz-string compressToEncodedURIComponent'd path stack
54
- exp?: string;
55
- }
56
-
57
- /**
58
- * Compute deep share key: HMAC-SHA256(seed, path + "|" + d + "|" + dirs + "|" + stack + "|" + exp)
59
- * Used for share links with depth \> 0 or dirs enabled.
60
- */
61
- export function computeDeepShareKey(
62
- seed: string,
63
- urlPath: string,
64
- params: DeepShareParams,
65
- ): string {
66
- const normalized = urlPath.toLowerCase().replace(/^\/+|\/+$/g, '');
67
- const data = `${normalized}|${String(params.depth)}|${params.dirs ? '1' : '0'}|${params.stack}|${params.exp ?? ''}`;
68
- const hash = crypto.createHmac('sha256', seed).update(data).digest('hex');
69
- return hash.substring(0, 32);
70
- }
71
-
72
- /**
73
- * Timing-safe string comparison
74
- */
75
- export function timingSafeEqual(a: string, b: string): boolean {
76
- try {
77
- return crypto.timingSafeEqual(Buffer.from(a), Buffer.from(b));
78
- } catch {
79
- return false;
80
- }
81
- }
package/src/index.ts DELETED
@@ -1,29 +0,0 @@
1
- /**
2
- * Shared utilities and types for jeeves-server packages.
3
- *
4
- * @packageDocumentation
5
- */
6
-
7
- export {
8
- computeDeepShareKey,
9
- computeInsiderKey,
10
- computeOutsiderKeyWithExpiry,
11
- computePathKey,
12
- type DeepShareParams,
13
- timingSafeEqual,
14
- } from './crypto.js';
15
- export type {
16
- AuthStatusResponse,
17
- DriveEntry,
18
- ExportCacheClearResponse,
19
- ExportLink,
20
- FileMutationAction,
21
- LinkInfoResponse,
22
- OAuthStartRequest,
23
- OAuthStartResponse,
24
- RotateKeyResponse,
25
- ShareForRequest,
26
- ShareForResponse,
27
- ShareRequest,
28
- ShareResponse,
29
- } from './types.js';
package/src/types.ts DELETED
@@ -1,108 +0,0 @@
1
- /**
2
- * Shared API request/response types between service and plugin.
3
- *
4
- * @packageDocumentation
5
- */
6
-
7
- /** POST /api/share request body. */
8
- export interface ShareRequest {
9
- path: string;
10
- expiry?: string;
11
- depth?: number;
12
- dirs?: boolean;
13
- }
14
-
15
- /** POST /api/share response. */
16
- export interface ShareResponse {
17
- url: string;
18
- path: string;
19
- exp: string | null;
20
- depth?: number;
21
- dirs?: boolean;
22
- }
23
-
24
- /** POST /api/util/share-for request body. */
25
- export interface ShareForRequest {
26
- path: string;
27
- insiders: string[];
28
- depth?: number;
29
- dirs?: boolean;
30
- enforceOutsiderPolicy?: boolean;
31
- }
32
-
33
- /** POST /api/util/share-for response. */
34
- export interface ShareForResponse {
35
- url: string | null;
36
- type: 'insider' | 'outsider-share' | 'blocked' | 'policy-denied';
37
- reason?: string;
38
- blocked?: string[];
39
- warning?: string;
40
- }
41
-
42
- /** POST /api/oauth/start request body. */
43
- export interface OAuthStartRequest {
44
- provider: string;
45
- account: string;
46
- clientId: string;
47
- clientSecret: string;
48
- scopes?: string[];
49
- origin?: string;
50
- }
51
-
52
- /** POST /api/oauth/start response. */
53
- export interface OAuthStartResponse {
54
- authUrl?: string;
55
- }
56
-
57
- /** GET /api/link-info response. */
58
- export interface LinkInfoResponse {
59
- exists: boolean;
60
- isDirectory?: boolean;
61
- pageUrl?: string;
62
- rawUrl?: string | null;
63
- exportLinks?: ExportLink[];
64
- }
65
-
66
- /** Export link entry in link-info response. */
67
- export interface ExportLink {
68
- format: string;
69
- url: string;
70
- }
71
-
72
- /** GET /api/export-cache DELETE response. */
73
- export interface ExportCacheClearResponse {
74
- cleared: {
75
- exports: number;
76
- diagrams: number;
77
- };
78
- }
79
-
80
- /** File mutation action types. */
81
- export type FileMutationAction =
82
- | 'edit-block'
83
- | 'delete-block'
84
- | 'insert-block'
85
- | 'edit-cell'
86
- | 'toggle-checkbox';
87
-
88
- /** POST /api/rotate-key response. */
89
- export interface RotateKeyResponse {
90
- ok: boolean;
91
- keyCreatedAt: string;
92
- }
93
-
94
- /** GET /api/auth/status response. */
95
- export interface AuthStatusResponse {
96
- authenticated: boolean;
97
- email?: string;
98
- picture?: string;
99
- isInsider: boolean;
100
- keyCreatedAt?: string | null;
101
- searchEnabled?: boolean;
102
- }
103
-
104
- /** GET /api/drives response entry. */
105
- export interface DriveEntry {
106
- letter: string;
107
- label: string;
108
- }
package/tsconfig.json DELETED
@@ -1,21 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "rootDir": ".",
6
- "noEmit": false,
7
- "declaration": true,
8
- "declarationMap": true,
9
- "types": [
10
- "node",
11
- "vitest/globals"
12
- ]
13
- },
14
- "include": [
15
- "src/**/*"
16
- ],
17
- "exclude": [
18
- "dist",
19
- "node_modules"
20
- ]
21
- }