@workjournal/shared 2.7.0 → 2.10.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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=connections.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connections.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/connections.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,53 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { allCombos, clients, connectionTypeLabels, defaultPlatform, matrix, platformsFor, slugFor, typesFor, } from '../connections.js';
3
+ describe('allCombos', () => {
4
+ it('yields the 20 known combos', () => {
5
+ expect(allCombos()).toHaveLength(20);
6
+ });
7
+ it('produces unique slugs', () => {
8
+ const slugs = allCombos().map((c) => c.slug);
9
+ expect(new Set(slugs).size).toBe(slugs.length);
10
+ });
11
+ it('only emits clients that exist in the clients list', () => {
12
+ const known = new Set(clients.map((c) => c.id));
13
+ for (const combo of allCombos()) {
14
+ expect(known.has(combo.client)).toBe(true);
15
+ }
16
+ });
17
+ });
18
+ describe('slugFor', () => {
19
+ it('joins the triplet with hyphens', () => {
20
+ expect(slugFor('claude-code', 'shell', 'skill')).toBe('claude-code-shell-skill');
21
+ });
22
+ it('replaces the slash in n/a', () => {
23
+ expect(slugFor('claude', 'web', 'n/a')).toBe('claude-web-n-a');
24
+ });
25
+ });
26
+ describe('platformsFor / typesFor / defaultPlatform', () => {
27
+ it('returns the matrix platforms for a known client', () => {
28
+ expect(platformsFor('claude')).toEqual(['web', 'desktop']);
29
+ });
30
+ it('returns empty for an unknown client', () => {
31
+ expect(platformsFor('not-a-client')).toEqual([]);
32
+ expect(typesFor('not-a-client', 'web')).toEqual([]);
33
+ expect(defaultPlatform('not-a-client')).toBeUndefined();
34
+ });
35
+ it('defaultPlatform is the first listed platform', () => {
36
+ expect(defaultPlatform('claude-code')).toBe('shell');
37
+ });
38
+ });
39
+ describe('matrix integrity', () => {
40
+ it('every platform entry has at least one connection type', () => {
41
+ for (const platformMap of Object.values(matrix)) {
42
+ for (const types of Object.values(platformMap)) {
43
+ expect(types.length).toBeGreaterThan(0);
44
+ }
45
+ }
46
+ });
47
+ it('every emitted connection type has a label', () => {
48
+ for (const combo of allCombos()) {
49
+ expect(connectionTypeLabels[combo.type]).toBeTruthy();
50
+ }
51
+ });
52
+ });
53
+ //# sourceMappingURL=connections.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connections.test.js","sourceRoot":"","sources":["../../src/__tests__/connections.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=theme.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/theme.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,50 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { isThemePreference, resolveTheme, THEME_INIT_SCRIPT, THEME_PREFERENCES, THEME_STORAGE_KEY, } from '../theme.js';
3
+ describe('isThemePreference', () => {
4
+ it('accepts the three valid preferences', () => {
5
+ expect(isThemePreference('system')).toBe(true);
6
+ expect(isThemePreference('light')).toBe(true);
7
+ expect(isThemePreference('dark')).toBe(true);
8
+ });
9
+ it('rejects anything else', () => {
10
+ expect(isThemePreference('Dark')).toBe(false);
11
+ expect(isThemePreference('')).toBe(false);
12
+ expect(isThemePreference(null)).toBe(false);
13
+ expect(isThemePreference(undefined)).toBe(false);
14
+ expect(isThemePreference(0)).toBe(false);
15
+ });
16
+ });
17
+ describe('resolveTheme', () => {
18
+ it('returns the explicit preference regardless of the OS signal', () => {
19
+ expect(resolveTheme('light', true)).toBe('light');
20
+ expect(resolveTheme('light', false)).toBe('light');
21
+ expect(resolveTheme('dark', true)).toBe('dark');
22
+ expect(resolveTheme('dark', false)).toBe('dark');
23
+ });
24
+ it('follows the OS signal when preference is system', () => {
25
+ expect(resolveTheme('system', true)).toBe('dark');
26
+ expect(resolveTheme('system', false)).toBe('light');
27
+ });
28
+ });
29
+ describe('theme constants', () => {
30
+ it('cycles system -> light -> dark', () => {
31
+ expect(THEME_PREFERENCES).toEqual(['system', 'light', 'dark']);
32
+ });
33
+ it('hard-codes the storage key inside the bootstrap script (no drift)', () => {
34
+ // The init script can't interpolate the constant at runtime in every
35
+ // build target, so it inlines the literal — guard the two against drift.
36
+ expect(THEME_INIT_SCRIPT).toContain(`'${THEME_STORAGE_KEY}'`);
37
+ });
38
+ it('bootstrap script toggles the dark class and swallows errors', () => {
39
+ expect(THEME_INIT_SCRIPT).toContain("classList.toggle('dark'");
40
+ expect(THEME_INIT_SCRIPT).toContain('catch');
41
+ expect(THEME_INIT_SCRIPT).toContain('prefers-color-scheme: dark');
42
+ });
43
+ it('bootstrap script normalizes untrusted storage values to system', () => {
44
+ // Must mirror the runtime isThemePreference fallback so pre-paint and
45
+ // hydrated results never disagree (CR #694).
46
+ expect(THEME_INIT_SCRIPT).toContain("p!=='light'&&p!=='dark'&&p!=='system'");
47
+ expect(THEME_INIT_SCRIPT).toContain("p='system'");
48
+ });
49
+ });
50
+ //# sourceMappingURL=theme.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.test.js","sourceRoot":"","sources":["../../src/__tests__/theme.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Client × platform × connection-method matrix for "connect your AI" pickers.
3
+ * Single source of truth consumed by the landing get-started page
4
+ * (`apps/landing/src/components/connection-picker.astro`) and the web app's
5
+ * empty-state picker (`apps/web/src/components/connect-ai-picker.tsx`).
6
+ * Exposed as the `@workjournal/shared/connections` subpath — NOT re-exported
7
+ * from the package index, because `ClientOption` would collide with the
8
+ * support-labels export. Human-readable mirror: `docs/connections.yaml`.
9
+ * Each combo's slug maps to a setup-guide markdown file in both apps.
10
+ */
11
+ export type ClientId = 'claude' | 'claude-code' | 'codex' | 'chatgpt' | 'perplexity' | 'grok' | 'opera-neon' | 'other';
12
+ export type PlatformId = 'web' | 'desktop' | 'mobile' | 'shell' | 'other';
13
+ export type ConnectionType = 'skill' | 'plugin' | 'cli' | 'remote-mcp' | 'local-mcp' | 'gpt-action' | 'n/a';
14
+ export interface ClientOption {
15
+ id: ClientId;
16
+ label: string;
17
+ provider: 'openai' | 'anthropic' | 'perplexity' | 'xai' | 'opera' | 'other';
18
+ }
19
+ export interface PlatformOption {
20
+ id: PlatformId;
21
+ label: string;
22
+ }
23
+ export declare const clients: ClientOption[];
24
+ export declare const platforms: PlatformOption[];
25
+ export declare const connectionTypeLabels: Record<ConnectionType, string>;
26
+ type Matrix = Partial<Record<ClientId, Partial<Record<PlatformId, ConnectionType[]>>>>;
27
+ export declare const matrix: Matrix;
28
+ export interface Combo {
29
+ client: ClientId;
30
+ platform: PlatformId;
31
+ type: ConnectionType;
32
+ slug: string;
33
+ }
34
+ export declare function allCombos(): Combo[];
35
+ export declare function slugFor(client: ClientId, platform: PlatformId, type: ConnectionType): string;
36
+ export declare function platformsFor(client: ClientId): PlatformId[];
37
+ export declare function typesFor(client: ClientId, platform: PlatformId): ConnectionType[];
38
+ export declare function defaultPlatform(client: ClientId): PlatformId | undefined;
39
+ export {};
40
+ //# sourceMappingURL=connections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connections.d.ts","sourceRoot":"","sources":["../src/connections.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,MAAM,QAAQ,GACjB,QAAQ,GACR,aAAa,GACb,OAAO,GACP,SAAS,GACT,YAAY,GACZ,MAAM,GACN,YAAY,GACZ,OAAO,CAAC;AACX,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAC1E,MAAM,MAAM,cAAc,GACvB,OAAO,GACP,QAAQ,GACR,KAAK,GACL,YAAY,GACZ,WAAW,GACX,YAAY,GACZ,KAAK,CAAC;AAET,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,QAAQ,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,GAAG,WAAW,GAAG,YAAY,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,CAAC;CAC5E;AAED,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,UAAU,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,OAAO,EAAE,YAAY,EASjC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,cAAc,EAMrC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAQ/D,CAAC;AAEF,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAEvF,eAAO,MAAM,MAAM,EAAE,MAgCpB,CAAC;AAEF,MAAM,WAAW,KAAK;IACrB,MAAM,EAAE,QAAQ,CAAC;IACjB,QAAQ,EAAE,UAAU,CAAC;IACrB,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,SAAS,IAAI,KAAK,EAAE,CAgBnC;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CAE5F;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,QAAQ,GAAG,UAAU,EAAE,CAI3D;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,GAAG,cAAc,EAAE,CAEjF;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,CAExE"}
@@ -0,0 +1,92 @@
1
+ export const clients = [
2
+ { id: 'claude', label: 'Claude', provider: 'anthropic' },
3
+ { id: 'claude-code', label: 'Claude Code', provider: 'anthropic' },
4
+ { id: 'codex', label: 'Codex', provider: 'openai' },
5
+ { id: 'chatgpt', label: 'ChatGPT', provider: 'openai' },
6
+ { id: 'perplexity', label: 'Perplexity', provider: 'perplexity' },
7
+ { id: 'grok', label: 'Grok', provider: 'xai' },
8
+ { id: 'opera-neon', label: 'Opera Neon', provider: 'opera' },
9
+ { id: 'other', label: 'Other', provider: 'other' },
10
+ ];
11
+ export const platforms = [
12
+ { id: 'web', label: 'Web' },
13
+ { id: 'desktop', label: 'Desktop app' },
14
+ { id: 'mobile', label: 'Mobile app' },
15
+ { id: 'shell', label: 'Shell / CLI' },
16
+ { id: 'other', label: 'Other' },
17
+ ];
18
+ export const connectionTypeLabels = {
19
+ skill: 'Skill',
20
+ plugin: 'Plugin',
21
+ cli: 'CLI',
22
+ 'remote-mcp': 'Remote MCP',
23
+ 'local-mcp': 'Local MCP',
24
+ 'gpt-action': 'Custom GPT',
25
+ 'n/a': 'Not applicable',
26
+ };
27
+ export const matrix = {
28
+ claude: {
29
+ web: ['remote-mcp'],
30
+ desktop: ['remote-mcp', 'local-mcp'],
31
+ },
32
+ 'claude-code': {
33
+ shell: ['plugin', 'skill', 'cli'],
34
+ },
35
+ codex: {
36
+ shell: ['plugin', 'skill', 'cli'],
37
+ },
38
+ chatgpt: {
39
+ web: ['remote-mcp', 'gpt-action'],
40
+ desktop: ['remote-mcp'],
41
+ mobile: ['remote-mcp'],
42
+ },
43
+ perplexity: {
44
+ web: ['remote-mcp'],
45
+ desktop: ['remote-mcp'],
46
+ },
47
+ grok: {
48
+ web: ['remote-mcp'],
49
+ mobile: ['remote-mcp'],
50
+ },
51
+ 'opera-neon': {
52
+ desktop: ['remote-mcp'],
53
+ },
54
+ // Catch-all for clients not in the list: any Open-Agent-Skills agent can
55
+ // run the skill; anything MCP-capable can use the remote server.
56
+ other: {
57
+ other: ['skill', 'remote-mcp'],
58
+ },
59
+ };
60
+ export function allCombos() {
61
+ const out = [];
62
+ for (const client of clients) {
63
+ const platformsForClient = matrix[client.id] ?? {};
64
+ for (const [platform, types] of Object.entries(platformsForClient)) {
65
+ for (const type of types ?? []) {
66
+ out.push({
67
+ client: client.id,
68
+ platform: platform,
69
+ type,
70
+ slug: slugFor(client.id, platform, type),
71
+ });
72
+ }
73
+ }
74
+ }
75
+ return out;
76
+ }
77
+ export function slugFor(client, platform, type) {
78
+ return `${client}-${platform}-${type.replace('/', '-')}`;
79
+ }
80
+ export function platformsFor(client) {
81
+ const m = matrix[client];
82
+ if (!m)
83
+ return [];
84
+ return Object.keys(m);
85
+ }
86
+ export function typesFor(client, platform) {
87
+ return matrix[client]?.[platform] ?? [];
88
+ }
89
+ export function defaultPlatform(client) {
90
+ return platformsFor(client)[0];
91
+ }
92
+ //# sourceMappingURL=connections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connections.js","sourceRoot":"","sources":["../src/connections.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -7,6 +7,8 @@ export { proposeWorkspaceNameFromEmail } from './propose-workspace-name.js';
7
7
  export { isReservedSlug, MAX_NAME_LENGTH, MAX_SLUG_LENGTH, RESERVED_SLUGS, slugify, } from './slug.js';
8
8
  export type { ClientOption, InterfaceOption } from './support-labels.js';
9
9
  export { CLIENT_OPTIONS, INTERFACE_OPTIONS, isClientOption, isInterfaceOption, } from './support-labels.js';
10
+ export type { ResolvedTheme, ThemePreference } from './theme.js';
11
+ export { isThemePreference, resolveTheme, THEME_INIT_SCRIPT, THEME_PREFERENCES, THEME_STORAGE_KEY, } from './theme.js';
10
12
  export type { FeatureFlag } from './tiers.js';
11
13
  export { canUseFeature, canUseFeatureForCode } from './tiers.js';
12
14
  export type { AcceptInvitationRequest, AcceptLegalRequest, ApiError, CreateEntryRequest, CreateInvitationRequest, CreateJournalRequest, CreatePromptRequest, CreateTagRequest, CreateWorkspaceRequest, Entry, EntrySummary, EntryWithNeighbors, Invitation, Journal, JournalContributor, JournalContributorRow, JournalContributorWithEmail, JournalPromptInfo, JournalTagAssignment, PaginatedResponse, Prompt, RagSearchRequest, RagSearchResponse, RagSearchResult, SharedJournal, Tag, TagWithAssignment, Tier, TierCode, UpdateEntryRequest, UpdateJournalRequest, UpdatePromptRequest, UpdateTagRequest, UserProfile, Workspace, } from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EACN,SAAS,EACT,WAAW,EACX,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EACN,UAAU,EACV,aAAa,EACb,OAAO,EACP,SAAS,EACT,aAAa,EACb,OAAO,EACP,WAAW,EACX,WAAW,EACX,SAAS,GACT,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EACN,cAAc,EACd,eAAe,EACf,eAAe,EACf,cAAc,EACd,OAAO,GACP,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EACN,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACjE,YAAY,EACX,uBAAuB,EACvB,kBAAkB,EAClB,QAAQ,EACR,kBAAkB,EAClB,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,KAAK,EACL,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,OAAO,EACP,kBAAkB,EAClB,qBAAqB,EACrB,2BAA2B,EAC3B,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,MAAM,EACN,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,GAAG,EACH,iBAAiB,EACjB,IAAI,EACJ,QAAQ,EACR,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,SAAS,GACT,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EACN,SAAS,EACT,WAAW,EACX,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EACN,UAAU,EACV,aAAa,EACb,OAAO,EACP,SAAS,EACT,aAAa,EACb,OAAO,EACP,WAAW,EACX,WAAW,EACX,SAAS,GACT,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EACN,cAAc,EACd,eAAe,EACf,eAAe,EACf,cAAc,EACd,OAAO,GACP,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EACN,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EACN,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,GACjB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACjE,YAAY,EACX,uBAAuB,EACvB,kBAAkB,EAClB,QAAQ,EACR,kBAAkB,EAClB,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,KAAK,EACL,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,OAAO,EACP,kBAAkB,EAClB,qBAAqB,EACrB,2BAA2B,EAC3B,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,MAAM,EACN,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,GAAG,EACH,iBAAiB,EACjB,IAAI,EACJ,QAAQ,EACR,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,SAAS,GACT,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -4,5 +4,6 @@ export { AAD_STRING, isOpaqueToken, KEY_LEN, NONCE_LEN, resolveBearer, TAG_LEN,
4
4
  export { proposeWorkspaceNameFromEmail } from './propose-workspace-name.js';
5
5
  export { isReservedSlug, MAX_NAME_LENGTH, MAX_SLUG_LENGTH, RESERVED_SLUGS, slugify, } from './slug.js';
6
6
  export { CLIENT_OPTIONS, INTERFACE_OPTIONS, isClientOption, isInterfaceOption, } from './support-labels.js';
7
+ export { isThemePreference, resolveTheme, THEME_INIT_SCRIPT, THEME_PREFERENCES, THEME_STORAGE_KEY, } from './theme.js';
7
8
  export { canUseFeature, canUseFeatureForCode } from './tiers.js';
8
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,SAAS,EACT,WAAW,EACX,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EACN,UAAU,EACV,aAAa,EACb,OAAO,EACP,SAAS,EACT,aAAa,EACb,OAAO,EACP,WAAW,EACX,WAAW,EACX,SAAS,GACT,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EACN,cAAc,EACd,eAAe,EACf,eAAe,EACf,cAAc,EACd,OAAO,GACP,MAAM,WAAW,CAAC;AAEnB,OAAO,EACN,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GACjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,SAAS,EACT,WAAW,EACX,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EACN,UAAU,EACV,aAAa,EACb,OAAO,EACP,SAAS,EACT,aAAa,EACb,OAAO,EACP,WAAW,EACX,WAAW,EACX,SAAS,GACT,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EACN,cAAc,EACd,eAAe,EACf,eAAe,EACf,cAAc,EACd,OAAO,GACP,MAAM,WAAW,CAAC;AAEnB,OAAO,EACN,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GACjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACN,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Theme (light / dark) contract shared by every browser surface.
3
+ *
4
+ * `apps/web` (React / Tailwind v4) and `apps/landing` (Astro / plain CSS) both
5
+ * activate dark mode by toggling the `.dark` class on `<html>` — the design
6
+ * system's `tokens.css` carries the full `.dark` palette. The two surfaces must
7
+ * agree on the localStorage key and the system/light/dark resolution semantics
8
+ * or a user who sets dark on the app and opens the marketing site sees the
9
+ * wrong theme. Single-sourcing those primitives here makes that drift
10
+ * impossible — same rationale as `connections.ts`.
11
+ */
12
+ /** What the user picked. `system` defers to the OS `prefers-color-scheme`. */
13
+ export type ThemePreference = 'system' | 'light' | 'dark';
14
+ /** The concrete theme actually applied to the DOM. */
15
+ export type ResolvedTheme = 'light' | 'dark';
16
+ /** localStorage key holding the persisted {@link ThemePreference}. */
17
+ export declare const THEME_STORAGE_KEY = "wj-theme";
18
+ /** The three selectable preferences, in cycle order (toggle steps through these). */
19
+ export declare const THEME_PREFERENCES: readonly ThemePreference[];
20
+ /** Narrow an untrusted value (e.g. a localStorage read) to a {@link ThemePreference}. */
21
+ export declare function isThemePreference(value: unknown): value is ThemePreference;
22
+ /**
23
+ * Collapse a preference + the current OS dark-mode signal into the concrete
24
+ * theme to apply. `prefersDark` is the value of
25
+ * `matchMedia('(prefers-color-scheme: dark)').matches`.
26
+ */
27
+ export declare function resolveTheme(preference: ThemePreference, prefersDark: boolean): ResolvedTheme;
28
+ /**
29
+ * Blocking bootstrap script, inlined in the document `<head>` of every surface
30
+ * BEFORE first paint to prevent a flash of the wrong theme (FOUC). It reads the
31
+ * persisted preference and applies `.dark` synchronously; the runtime provider
32
+ * / toggle takes over once hydrated. Kept dependency-free and self-contained so
33
+ * it can run as a plain inline `<script>`.
34
+ *
35
+ * The literal key here mirrors {@link THEME_STORAGE_KEY}; both must stay in
36
+ * sync (the constant can't be interpolated into a surface's static HTML head in
37
+ * every build target, so this string hard-codes it — tested in theme.test.ts).
38
+ *
39
+ * Untrusted storage values are normalized to a valid preference (fallback
40
+ * `system`) before resolving, so the pre-paint result matches the runtime
41
+ * provider's {@link isThemePreference}-guarded logic exactly — otherwise a junk
42
+ * value + OS-dark would paint light then flip, reintroducing the FOUC.
43
+ */
44
+ export declare const THEME_INIT_SCRIPT = "(function(){try{var p=localStorage.getItem('wj-theme');if(p!=='light'&&p!=='dark'&&p!=='system')p='system';var d=p==='dark'||(p==='system'&&window.matchMedia('(prefers-color-scheme: dark)').matches);document.documentElement.classList.toggle('dark',d);}catch(e){}})();";
45
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,8EAA8E;AAC9E,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAE1D,sDAAsD;AACtD,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;AAE7C,sEAAsE;AACtE,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAE5C,qFAAqF;AACrF,eAAO,MAAM,iBAAiB,EAAE,SAAS,eAAe,EAAgC,CAAC;AAEzF,yFAAyF;AACzF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAE1E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,OAAO,GAAG,aAAa,CAG7F;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,iBAAiB,gRAA4R,CAAC"}
package/dist/theme.js ADDED
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Theme (light / dark) contract shared by every browser surface.
3
+ *
4
+ * `apps/web` (React / Tailwind v4) and `apps/landing` (Astro / plain CSS) both
5
+ * activate dark mode by toggling the `.dark` class on `<html>` — the design
6
+ * system's `tokens.css` carries the full `.dark` palette. The two surfaces must
7
+ * agree on the localStorage key and the system/light/dark resolution semantics
8
+ * or a user who sets dark on the app and opens the marketing site sees the
9
+ * wrong theme. Single-sourcing those primitives here makes that drift
10
+ * impossible — same rationale as `connections.ts`.
11
+ */
12
+ /** localStorage key holding the persisted {@link ThemePreference}. */
13
+ export const THEME_STORAGE_KEY = 'wj-theme';
14
+ /** The three selectable preferences, in cycle order (toggle steps through these). */
15
+ export const THEME_PREFERENCES = ['system', 'light', 'dark'];
16
+ /** Narrow an untrusted value (e.g. a localStorage read) to a {@link ThemePreference}. */
17
+ export function isThemePreference(value) {
18
+ return value === 'system' || value === 'light' || value === 'dark';
19
+ }
20
+ /**
21
+ * Collapse a preference + the current OS dark-mode signal into the concrete
22
+ * theme to apply. `prefersDark` is the value of
23
+ * `matchMedia('(prefers-color-scheme: dark)').matches`.
24
+ */
25
+ export function resolveTheme(preference, prefersDark) {
26
+ if (preference === 'system')
27
+ return prefersDark ? 'dark' : 'light';
28
+ return preference;
29
+ }
30
+ /**
31
+ * Blocking bootstrap script, inlined in the document `<head>` of every surface
32
+ * BEFORE first paint to prevent a flash of the wrong theme (FOUC). It reads the
33
+ * persisted preference and applies `.dark` synchronously; the runtime provider
34
+ * / toggle takes over once hydrated. Kept dependency-free and self-contained so
35
+ * it can run as a plain inline `<script>`.
36
+ *
37
+ * The literal key here mirrors {@link THEME_STORAGE_KEY}; both must stay in
38
+ * sync (the constant can't be interpolated into a surface's static HTML head in
39
+ * every build target, so this string hard-codes it — tested in theme.test.ts).
40
+ *
41
+ * Untrusted storage values are normalized to a valid preference (fallback
42
+ * `system`) before resolving, so the pre-paint result matches the runtime
43
+ * provider's {@link isThemePreference}-guarded logic exactly — otherwise a junk
44
+ * value + OS-dark would paint light then flip, reintroducing the FOUC.
45
+ */
46
+ export const THEME_INIT_SCRIPT = `(function(){try{var p=localStorage.getItem('${THEME_STORAGE_KEY}');if(p!=='light'&&p!=='dark'&&p!=='system')p='system';var d=p==='dark'||(p==='system'&&window.matchMedia('(prefers-color-scheme: dark)').matches);document.documentElement.classList.toggle('dark',d);}catch(e){}})();`;
47
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,sEAAsE;AACtE,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAE5C,qFAAqF;AACrF,MAAM,CAAC,MAAM,iBAAiB,GAA+B,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAEzF,yFAAyF;AACzF,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC/C,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,MAAM,CAAC;AACpE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,UAA2B,EAAE,WAAoB;IAC7E,IAAI,UAAU,KAAK,QAAQ;QAAE,OAAO,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IACnE,OAAO,UAAU,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,+CAA+C,iBAAiB,yNAAyN,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workjournal/shared",
3
- "version": "2.7.0",
3
+ "version": "2.10.0",
4
4
  "description": "Shared types, constants, and credential helpers for the Workjournal CLI and MCP server.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -16,6 +16,10 @@
16
16
  "./auth": {
17
17
  "types": "./dist/auth.d.ts",
18
18
  "import": "./dist/auth.js"
19
+ },
20
+ "./connections": {
21
+ "types": "./dist/connections.d.ts",
22
+ "import": "./dist/connections.js"
19
23
  }
20
24
  },
21
25
  "files": [