@happyvertical/smrt-mcp-openai 0.0.0-stage → 0.51.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/AGENTS.md +11 -0
  2. package/CLAUDE.md +1 -0
  3. package/FILES.md +77 -0
  4. package/FORMS-TEST-DESIGN.md +42 -0
  5. package/FORMS.md +112 -0
  6. package/LICENSE +7 -0
  7. package/README.md +175 -2
  8. package/dist/client.d.ts +27 -0
  9. package/dist/client.d.ts.map +1 -0
  10. package/dist/client.js +125 -0
  11. package/dist/client.js.map +1 -0
  12. package/dist/context.d.ts +47 -0
  13. package/dist/context.d.ts.map +1 -0
  14. package/dist/context.js +110 -0
  15. package/dist/context.js.map +1 -0
  16. package/dist/file-contracts.d.ts +34 -0
  17. package/dist/file-contracts.d.ts.map +1 -0
  18. package/dist/file-contracts.js +98 -0
  19. package/dist/file-contracts.js.map +1 -0
  20. package/dist/files-server.d.ts +6 -0
  21. package/dist/files-server.d.ts.map +1 -0
  22. package/dist/files-server.js +45 -0
  23. package/dist/files-server.js.map +1 -0
  24. package/dist/files.d.ts +38 -0
  25. package/dist/files.d.ts.map +1 -0
  26. package/dist/files.js +288 -0
  27. package/dist/files.js.map +1 -0
  28. package/dist/forms-server.d.ts +53 -0
  29. package/dist/forms-server.d.ts.map +1 -0
  30. package/dist/forms-server.js +115 -0
  31. package/dist/forms-server.js.map +1 -0
  32. package/dist/forms-view.d.ts +14 -0
  33. package/dist/forms-view.d.ts.map +1 -0
  34. package/dist/forms-view.js +213 -0
  35. package/dist/forms-view.js.map +1 -0
  36. package/dist/forms.d.ts +118 -0
  37. package/dist/forms.d.ts.map +1 -0
  38. package/dist/forms.js +389 -0
  39. package/dist/forms.js.map +1 -0
  40. package/dist/index.d.ts +47 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +205 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/mentions.d.ts +30 -0
  45. package/dist/mentions.d.ts.map +1 -0
  46. package/dist/mentions.js +149 -0
  47. package/dist/mentions.js.map +1 -0
  48. package/dist/messages.d.ts +19 -0
  49. package/dist/messages.d.ts.map +1 -0
  50. package/dist/messages.js +47 -0
  51. package/dist/messages.js.map +1 -0
  52. package/dist/settings.d.ts +45 -0
  53. package/dist/settings.d.ts.map +1 -0
  54. package/dist/settings.js +158 -0
  55. package/dist/settings.js.map +1 -0
  56. package/dist/validation.d.ts +15 -0
  57. package/dist/validation.d.ts.map +1 -0
  58. package/dist/validation.js +121 -0
  59. package/dist/validation.js.map +1 -0
  60. package/package.json +96 -3
@@ -0,0 +1,47 @@
1
+ import type { McpAppBridge } from '@happyvertical/smrt-mcp-apps';
2
+ export declare const OPENAI_MODEL_CONTEXT_CAPABILITY = "openai/modelContext";
3
+ export interface OpenAiIcon {
4
+ src: string;
5
+ mimeType?: string;
6
+ sizes?: string[];
7
+ theme?: 'light' | 'dark';
8
+ }
9
+ export interface OpenAiContextText {
10
+ text: string;
11
+ title?: string;
12
+ thumbnail?: OpenAiIcon;
13
+ /** Hidden from the person, never hidden from the model or provider. */
14
+ background?: boolean;
15
+ }
16
+ export interface OpenAiModelContextUpdate {
17
+ content?: Array<Record<string, unknown>>;
18
+ structuredContent?: Record<string, unknown>;
19
+ }
20
+ /**
21
+ * Builds only the pinned OpenAI extension fields. `_meta` crosses the provider
22
+ * boundary, so `background` is a visibility choice and never a privacy grant.
23
+ */
24
+ export declare function openAiContextText(value: OpenAiContextText): Record<string, unknown>;
25
+ /** Validates a bounded, idempotent replacement for this app instance's context. */
26
+ export declare function openAiModelContextUpdate(value: {
27
+ text?: OpenAiContextText;
28
+ structuredContent?: Record<string, unknown>;
29
+ }): OpenAiModelContextUpdate;
30
+ /** Capability detection is explicit; unknown/malformed data cannot enable native metadata. */
31
+ export declare function hasOpenAiModelContext(rawCapabilities: unknown): boolean;
32
+ /**
33
+ * Sends a portable text/structured fallback through the existing bridge when
34
+ * native support was not negotiated. Native callers receive the exact wire
35
+ * payload and may transport title/thumbnail/background without leaking them
36
+ * into portable public types.
37
+ */
38
+ export declare function updateOpenAiModelContext(options: {
39
+ bridge: McpAppBridge;
40
+ value: {
41
+ text?: OpenAiContextText;
42
+ structuredContent?: Record<string, unknown>;
43
+ };
44
+ native?(params: OpenAiModelContextUpdate, signal?: AbortSignal): Promise<void>;
45
+ signal?: AbortSignal;
46
+ }): Promise<'native' | 'portable'>;
47
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAGjE,eAAO,MAAM,+BAA+B,wBAAwB,CAAC;AAErE,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,uEAAuE;IACvE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACzC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7C;AAqBD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,iBAAiB,GACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAmBzB;AAED,mFAAmF;AACnF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7C,GAAG,wBAAwB,CAc3B;AAED,8FAA8F;AAC9F,wBAAgB,qBAAqB,CAAC,eAAe,EAAE,OAAO,GAAG,OAAO,CAcvE;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAAC,OAAO,EAAE;IACtD,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE;QACL,IAAI,CAAC,EAAE,iBAAiB,CAAC;QACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC7C,CAAC;IACF,MAAM,CAAC,CACL,MAAM,EAAE,wBAAwB,EAChC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GAAG,OAAO,CAAC,QAAQ,GAAG,UAAU,CAAC,CA0BjC"}
@@ -0,0 +1,110 @@
1
+ import { json, keys, record, text } from './validation.js';
2
+ export const OPENAI_MODEL_CONTEXT_CAPABILITY = 'openai/modelContext';
3
+ function icon(value) {
4
+ json(value);
5
+ const input = record(value);
6
+ keys(input, ['src', 'mimeType', 'sizes', 'theme']);
7
+ const result = { src: text(input.src, 2048) };
8
+ if (input.mimeType !== undefined)
9
+ result.mimeType = text(input.mimeType, 128);
10
+ if (input.sizes !== undefined) {
11
+ if (!Array.isArray(input.sizes) || input.sizes.length > 8)
12
+ throw new TypeError('Invalid icon sizes');
13
+ result.sizes = input.sizes.map((size) => text(size, 32));
14
+ }
15
+ if (input.theme !== undefined) {
16
+ if (input.theme !== 'light' && input.theme !== 'dark')
17
+ throw new TypeError('Invalid icon theme');
18
+ result.theme = input.theme;
19
+ }
20
+ return result;
21
+ }
22
+ /**
23
+ * Builds only the pinned OpenAI extension fields. `_meta` crosses the provider
24
+ * boundary, so `background` is a visibility choice and never a privacy grant.
25
+ */
26
+ export function openAiContextText(value) {
27
+ json(value);
28
+ const input = record(value);
29
+ keys(input, ['text', 'title', 'thumbnail', 'background']);
30
+ const result = {
31
+ type: 'text',
32
+ text: text(input.text, 16384),
33
+ };
34
+ const meta = {};
35
+ if (input.title !== undefined)
36
+ meta['openai/title'] = text(input.title, 512);
37
+ if (input.thumbnail !== undefined)
38
+ meta['openai/thumbnail'] = icon(input.thumbnail);
39
+ if (Object.keys(meta).length)
40
+ result._meta = meta;
41
+ if (input.background !== undefined) {
42
+ if (typeof input.background !== 'boolean')
43
+ throw new TypeError('Expected background boolean');
44
+ if (input.background)
45
+ result.annotations = { audience: ['assistant'] };
46
+ }
47
+ return result;
48
+ }
49
+ /** Validates a bounded, idempotent replacement for this app instance's context. */
50
+ export function openAiModelContextUpdate(value) {
51
+ json(value);
52
+ const input = record(value);
53
+ keys(input, ['text', 'structuredContent']);
54
+ if (input.text === undefined && input.structuredContent === undefined)
55
+ throw new TypeError('Model context requires content or structuredContent');
56
+ return {
57
+ ...(input.text === undefined
58
+ ? {}
59
+ : { content: [openAiContextText(input.text)] }),
60
+ ...(input.structuredContent === undefined
61
+ ? {}
62
+ : { structuredContent: record(input.structuredContent) }),
63
+ };
64
+ }
65
+ /** Capability detection is explicit; unknown/malformed data cannot enable native metadata. */
66
+ export function hasOpenAiModelContext(rawCapabilities) {
67
+ try {
68
+ json(rawCapabilities);
69
+ const capabilities = record(rawCapabilities);
70
+ const experimental = capabilities.experimental;
71
+ return (experimental !== undefined &&
72
+ record(experimental)[OPENAI_MODEL_CONTEXT_CAPABILITY] !== undefined &&
73
+ record(record(experimental)[OPENAI_MODEL_CONTEXT_CAPABILITY]) !==
74
+ undefined);
75
+ }
76
+ catch {
77
+ return false;
78
+ }
79
+ }
80
+ /**
81
+ * Sends a portable text/structured fallback through the existing bridge when
82
+ * native support was not negotiated. Native callers receive the exact wire
83
+ * payload and may transport title/thumbnail/background without leaking them
84
+ * into portable public types.
85
+ */
86
+ export async function updateOpenAiModelContext(options) {
87
+ const params = openAiModelContextUpdate(options.value);
88
+ if (options.native &&
89
+ hasOpenAiModelContext(options.bridge.snapshot.rawHostCapabilities)) {
90
+ try {
91
+ await options.native(params, options.signal);
92
+ return 'native';
93
+ }
94
+ catch (error) {
95
+ // An aborted or disposed request must not be revived on the portable path.
96
+ if (options.signal?.aborted)
97
+ throw error;
98
+ }
99
+ }
100
+ await options.bridge.updateModelContext({
101
+ ...(options.value.text === undefined
102
+ ? {}
103
+ : { text: options.value.text.text }),
104
+ ...(params.structuredContent === undefined
105
+ ? {}
106
+ : { structuredContent: params.structuredContent }),
107
+ }, options.signal);
108
+ return 'portable';
109
+ }
110
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE3D,MAAM,CAAC,MAAM,+BAA+B,GAAG,qBAAqB,CAAC;AAsBrE,SAAS,IAAI,CAAC,KAAc;IAC1B,IAAI,CAAC,KAAK,CAAC,CAAC;IACZ,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,MAAM,MAAM,GAAe,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;IAC1D,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;QAAE,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC9E,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;YACvD,MAAM,IAAI,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM;YACnD,MAAM,IAAI,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC7B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAwB;IAExB,IAAI,CAAC,KAAK,CAAC,CAAC;IACZ,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;IAC1D,MAAM,MAAM,GAA4B;QACtC,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;KAC9B,CAAC;IACF,MAAM,IAAI,GAA4B,EAAE,CAAC;IACzC,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,IAAI,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC7E,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;QAC/B,IAAI,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACnD,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM;QAAE,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC;IAClD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACnC,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,SAAS;YACvC,MAAM,IAAI,SAAS,CAAC,6BAA6B,CAAC,CAAC;QACrD,IAAI,KAAK,CAAC,UAAU;YAAE,MAAM,CAAC,WAAW,GAAG,EAAE,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;IACzE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,wBAAwB,CAAC,KAGxC;IACC,IAAI,CAAC,KAAK,CAAC,CAAC;IACZ,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAC3C,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,iBAAiB,KAAK,SAAS;QACnE,MAAM,IAAI,SAAS,CAAC,qDAAqD,CAAC,CAAC;IAC7E,OAAO;QACL,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;YAC1B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAyB,CAAC,CAAC,EAAE,CAAC;QACtE,GAAG,CAAC,KAAK,CAAC,iBAAiB,KAAK,SAAS;YACvC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,iBAAiB,EAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;KAC5D,CAAC;AACJ,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,qBAAqB,CAAC,eAAwB;IAC5D,IAAI,CAAC;QACH,IAAI,CAAC,eAAe,CAAC,CAAC;QACtB,MAAM,YAAY,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;QAC7C,MAAM,YAAY,GAAG,YAAY,CAAC,YAAY,CAAC;QAC/C,OAAO,CACL,YAAY,KAAK,SAAS;YAC1B,MAAM,CAAC,YAAY,CAAC,CAAC,+BAA+B,CAAC,KAAK,SAAS;YACnE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,+BAA+B,CAAC,CAAC;gBAC3D,SAAS,CACZ,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,OAW9C;IACC,MAAM,MAAM,GAAG,wBAAwB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACvD,IACE,OAAO,CAAC,MAAM;QACd,qBAAqB,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAClE,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YAC7C,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,2EAA2E;YAC3E,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO;gBAAE,MAAM,KAAK,CAAC;QAC3C,CAAC;IACH,CAAC;IACD,MAAM,OAAO,CAAC,MAAM,CAAC,kBAAkB,CACrC;QACE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;YAClC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACtC,GAAG,CAAC,MAAM,CAAC,iBAAiB,KAAK,SAAS;YACxC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,EAAE,CAAC;KACrD,EACD,OAAO,CAAC,MAAM,CACf,CAAC;IACF,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,34 @@
1
+ export interface OpenAiFileInput {
2
+ file: {
3
+ name: string;
4
+ resourceUri: string;
5
+ };
6
+ }
7
+ export type FileContent = {
8
+ text: string;
9
+ blob?: never;
10
+ } | {
11
+ blob: string;
12
+ text?: never;
13
+ };
14
+ export type FileWriteResult = {
15
+ outcome: 'saved' | 'conflict';
16
+ etag: string;
17
+ } | {
18
+ outcome: 'too-large';
19
+ maxBytes: number;
20
+ };
21
+ export interface FileRead {
22
+ uri: string;
23
+ mimeType: string;
24
+ content: FileContent;
25
+ writable: boolean;
26
+ etag?: string;
27
+ }
28
+ /** The URI is retained verbatim and is never decoded into a filesystem path. */
29
+ export declare function validateFileInput(value: unknown): OpenAiFileInput;
30
+ export declare function fileExtensions(value: readonly string[]): string[];
31
+ export declare function fileContent(value: unknown, maxBytes: number): FileContent;
32
+ export declare function fileRead(value: unknown, uri: string, maxBytes: number, mimeTypes: readonly string[]): FileRead;
33
+ export declare function fileWriteResult(value: unknown): FileWriteResult;
34
+ //# sourceMappingURL=file-contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-contracts.d.ts","sourceRoot":"","sources":["../src/file-contracts.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C;AACD,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AACnC,MAAM,MAAM,eAAe,GACvB;IAAE,OAAO,EAAE,OAAO,GAAG,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/C,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AACD,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CA0BjE;AACD,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAiBjE;AACD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAwBzE;AACD,wBAAgB,QAAQ,CACtB,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,QAAQ,CA8BV;AACD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAY/D"}
@@ -0,0 +1,98 @@
1
+ import { json, keys, record, text } from './validation.js';
2
+ /** The URI is retained verbatim and is never decoded into a filesystem path. */
3
+ export function validateFileInput(value) {
4
+ json(value);
5
+ const root = record(value);
6
+ keys(root, ['file']);
7
+ const file = record(root.file);
8
+ keys(file, ['name', 'resourceUri']);
9
+ const name = text(file.name, 255);
10
+ if (/[\\/]/.test(name) ||
11
+ [...name].some((char) => char.charCodeAt(0) < 32 || char.charCodeAt(0) === 127) ||
12
+ name === '.' ||
13
+ name === '..')
14
+ throw new TypeError('Expected filename without path');
15
+ const uri = text(file.resourceUri, 2048);
16
+ // Conservative local policy: opaque host/provider URI, never a URL or file path.
17
+ if (!/^[a-z][a-z0-9+.-]*:/i.test(uri) ||
18
+ /^(file|https?|data|javascript):/i.test(uri) ||
19
+ /^[a-z]:/i.test(uri) ||
20
+ /[\s\\]/.test(uri))
21
+ throw new TypeError('Expected opaque resource URI');
22
+ return { file: { name, resourceUri: uri } };
23
+ }
24
+ export function fileExtensions(value) {
25
+ if (!Array.isArray(value) ||
26
+ !value.length ||
27
+ value.length > 32 ||
28
+ new Set(value.map((extension) => typeof extension === 'string' ? extension.toLowerCase() : extension)).size !== value.length)
29
+ throw new TypeError('Expected bounded unique file extensions');
30
+ return value.map((extension) => {
31
+ if (!/^\.[a-z0-9][a-z0-9._-]{0,31}$/i.test(extension))
32
+ throw new TypeError('Expected file extension');
33
+ return extension.toLowerCase();
34
+ });
35
+ }
36
+ export function fileContent(value, maxBytes) {
37
+ json(value);
38
+ const content = record(value);
39
+ keys(content, ['text', 'blob']);
40
+ let bytes;
41
+ if (typeof content.text === 'string' && !Object.hasOwn(content, 'blob')) {
42
+ bytes = new TextEncoder().encode(content.text).length;
43
+ }
44
+ else if (typeof content.blob === 'string' &&
45
+ !Object.hasOwn(content, 'text')) {
46
+ const blob = content.blob;
47
+ if (!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(blob))
48
+ throw new TypeError('Expected base64 content');
49
+ bytes =
50
+ (blob.length / 4) * 3 -
51
+ (blob.endsWith('==') ? 2 : blob.endsWith('=') ? 1 : 0);
52
+ }
53
+ else
54
+ throw new TypeError('Expected exactly one representation');
55
+ if (bytes > maxBytes)
56
+ throw new TypeError('File exceeds byte limit');
57
+ return structuredClone(content);
58
+ }
59
+ export function fileRead(value, uri, maxBytes, mimeTypes) {
60
+ const root = record(value);
61
+ if (!Array.isArray(root.contents) || root.contents.length !== 1)
62
+ throw new TypeError('Expected one granted resource');
63
+ const item = record(root.contents[0]);
64
+ if (item.uri !== uri)
65
+ throw new TypeError('Resource URI mismatch');
66
+ const mimeType = text(item.mimeType, 128);
67
+ if (!mimeTypes.includes(mimeType))
68
+ throw new TypeError('File MIME denied');
69
+ const content = fileContent({
70
+ ...(Object.hasOwn(item, 'text') ? { text: item.text } : {}),
71
+ ...(Object.hasOwn(item, 'blob') ? { blob: item.blob } : {}),
72
+ }, maxBytes);
73
+ const metadata = item._meta === undefined
74
+ ? {}
75
+ : record(record(item._meta)['openai/resource'] ?? {});
76
+ if (metadata.writable !== undefined && typeof metadata.writable !== 'boolean')
77
+ throw new TypeError('Invalid writable metadata');
78
+ const etag = metadata.etag === undefined ? undefined : text(metadata.etag, 1024);
79
+ return {
80
+ uri,
81
+ mimeType,
82
+ content,
83
+ writable: metadata.writable === true,
84
+ ...(etag ? { etag } : {}),
85
+ };
86
+ }
87
+ export function fileWriteResult(value) {
88
+ json(value);
89
+ const result = record(value);
90
+ if (result.outcome === 'saved' || result.outcome === 'conflict')
91
+ return { outcome: result.outcome, etag: text(result.etag, 1024) };
92
+ if (result.outcome === 'too-large' &&
93
+ Number.isSafeInteger(result.maxBytes) &&
94
+ Number(result.maxBytes) >= 0)
95
+ return { outcome: 'too-large', maxBytes: Number(result.maxBytes) };
96
+ throw new TypeError('Invalid file write result');
97
+ }
98
+ //# sourceMappingURL=file-contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-contracts.js","sourceRoot":"","sources":["../src/file-contracts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type McpWorkflowToolDefinition } from '@happyvertical/smrt-app-mcp';
2
+ export type { OpenAiFileInput } from './file-contracts.js';
3
+ export { validateFileInput } from './file-contracts.js';
4
+ /** Wrap an existing authorized provider/view workflow. Input is a reference, never a grant. */
5
+ export declare function withOpenAiFileEntrypoint(definition: McpWorkflowToolDefinition, extensions: readonly string[]): McpWorkflowToolDefinition;
6
+ //# sourceMappingURL=files-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files-server.d.ts","sourceRoot":"","sources":["../src/files-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,6BAA6B,CAAC;AAGrC,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,+FAA+F;AAC/F,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,yBAAyB,EACrC,UAAU,EAAE,SAAS,MAAM,EAAE,GAC5B,yBAAyB,CA6C3B"}
@@ -0,0 +1,45 @@
1
+ import { createMcpWorkflowTool, } from '@happyvertical/smrt-app-mcp';
2
+ import { fileExtensions, validateFileInput } from './file-contracts.js';
3
+ export { validateFileInput } from './file-contracts.js';
4
+ /** Wrap an existing authorized provider/view workflow. Input is a reference, never a grant. */
5
+ export function withOpenAiFileEntrypoint(definition, extensions) {
6
+ createMcpWorkflowTool(definition);
7
+ const allowed = fileExtensions(extensions);
8
+ if (!definition.ui?.resourceUri ||
9
+ definition.effect !== 'read' ||
10
+ !definition.idempotent)
11
+ throw new TypeError('File entrypoint requires idempotent read UI workflow');
12
+ if (definition.metadata && Object.hasOwn(definition.metadata, 'openai/ui'))
13
+ throw new TypeError('File entrypoint metadata already declared');
14
+ return {
15
+ ...definition,
16
+ inputSchema: {
17
+ type: 'object',
18
+ properties: {
19
+ file: {
20
+ type: 'object',
21
+ properties: {
22
+ name: { type: 'string' },
23
+ resourceUri: { type: 'string' },
24
+ },
25
+ required: ['name', 'resourceUri'],
26
+ additionalProperties: false,
27
+ },
28
+ },
29
+ required: ['file'],
30
+ additionalProperties: false,
31
+ },
32
+ metadata: {
33
+ ...structuredClone(definition.metadata ?? {}),
34
+ 'openai/ui': { entrypoints: [{ type: 'file', extensions: allowed }] },
35
+ },
36
+ execute(context) {
37
+ const input = validateFileInput(context.arguments);
38
+ if (!allowed.some((extension) => input.file.name.toLowerCase().endsWith(extension)))
39
+ throw new TypeError('File extension denied');
40
+ // Existing handler must resolve ownership/tenant from context.principal, never metadata.
41
+ return definition.execute({ ...context, arguments: { ...input } });
42
+ },
43
+ };
44
+ }
45
+ //# sourceMappingURL=files-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files-server.js","sourceRoot":"","sources":["../src/files-server.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,GAEtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,+FAA+F;AAC/F,MAAM,UAAU,wBAAwB,CACtC,UAAqC,EACrC,UAA6B;IAE7B,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAC3C,IACE,CAAC,UAAU,CAAC,EAAE,EAAE,WAAW;QAC3B,UAAU,CAAC,MAAM,KAAK,MAAM;QAC5B,CAAC,UAAU,CAAC,UAAU;QAEtB,MAAM,IAAI,SAAS,CAAC,sDAAsD,CAAC,CAAC;IAC9E,IAAI,UAAU,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,WAAW,CAAC;QACxE,MAAM,IAAI,SAAS,CAAC,2CAA2C,CAAC,CAAC;IACnE,OAAO;QACL,GAAG,UAAU;QACb,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBACxB,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;qBAChC;oBACD,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC;oBACjC,oBAAoB,EAAE,KAAK;iBAC5B;aACF;YACD,QAAQ,EAAE,CAAC,MAAM,CAAC;YAClB,oBAAoB,EAAE,KAAK;SAC5B;QACD,QAAQ,EAAE;YACR,GAAG,eAAe,CAAC,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC;YAC7C,WAAW,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,EAAE;SACtE;QACD,OAAO,CAAC,OAAO;YACb,MAAM,KAAK,GAAG,iBAAiB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACnD,IACE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAC1B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAClD;gBAED,MAAM,IAAI,SAAS,CAAC,uBAAuB,CAAC,CAAC;YAC/C,yFAAyF;YACzF,OAAO,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,EAAE,GAAG,KAAK,EAAE,EAAE,CAAC,CAAC;QACrE,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { McpAppBridge, ToolResult } from '@happyvertical/smrt-mcp-apps';
2
+ import { type FileContent, type FileRead, type FileWriteResult, type OpenAiFileInput } from './file-contracts.js';
3
+ export type { FileContent, FileRead, FileWriteResult, OpenAiFileInput, } from './file-contracts.js';
4
+ export { validateFileInput } from './file-contracts.js';
5
+ export type FileOperation = 'read' | 'write' | 'subscribe' | 'open';
6
+ export interface OpenAiFileOptions {
7
+ bridge: McpAppBridge;
8
+ input: OpenAiFileInput;
9
+ /** Existing app workflow: fresh principal/owner/tenant/grant check on every call. */
10
+ authorityTool: string;
11
+ /** Ordinary import/open/download workflow, used when native capability is absent. */
12
+ fallbackTool: string;
13
+ /** Application policy, capped below the portable bridge's JSON envelope limit. */
14
+ maxBytes: number;
15
+ mimeTypes: readonly string[];
16
+ }
17
+ /** One initial tool-input grant, one lifetime; create a new session after reconnect/input change. */
18
+ export declare class OpenAiFileSession {
19
+ #private;
20
+ constructor(options: OpenAiFileOptions);
21
+ get native(): boolean;
22
+ get signal(): AbortSignal;
23
+ fallback(operation: FileOperation): Promise<ToolResult>;
24
+ read(representation?: 'text' | 'blob'): Promise<FileRead | ToolResult>;
25
+ write(content: FileContent): Promise<FileWriteResult | ToolResult>;
26
+ subscribe(onRead: (file: FileRead) => void, onError: (error: unknown) => void): Promise<void>;
27
+ dispose(): void;
28
+ }
29
+ /** User action calls this after the existing provider selects and authorizes an exact path. */
30
+ export declare function openOpenAiFile(options: {
31
+ bridge: McpAppBridge;
32
+ resolveTool: string;
33
+ arguments: Record<string, unknown>;
34
+ allowedPaths: readonly string[];
35
+ /** Explicit application confirmation UI; false cancels without resolving or opening. */
36
+ confirm(): Promise<boolean>;
37
+ }): Promise<ToolResult | undefined>;
38
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,eAAe,EAIpB,KAAK,eAAe,EAErB,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EACV,WAAW,EACX,QAAQ,EACR,eAAe,EACf,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAKxD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,WAAW,GAAG,MAAM,CAAC;AACpE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,eAAe,CAAC;IACvB,qFAAqF;IACrF,aAAa,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,YAAY,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AAeD,qGAAqG;AACrG,qBAAa,iBAAiB;;gBAYhB,OAAO,EAAE,iBAAiB;IAkDtC,IAAI,MAAM,IAAI,OAAO,CAEpB;IACD,IAAI,MAAM,IAAI,WAAW,CAExB;IAkBK,QAAQ,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC;IAWvD,IAAI,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,UAAU,CAAC;IAiCtE,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,GAAG,UAAU,CAAC;IAkClE,SAAS,CACb,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,EAChC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAChC,OAAO,CAAC,IAAI,CAAC;IAwEhB,OAAO,IAAI,IAAI;CAsBhB;AAED,+FAA+F;AAC/F,wBAAsB,cAAc,CAAC,OAAO,EAAE;IAC5C,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,wFAAwF;IACxF,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7B,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CA6BlC"}