openrouter-genimage-kote-opencode 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/.opencode/skills/openrouter-image-generation/SKILL.md +379 -0
  2. package/CHANGELOG.md +10 -0
  3. package/LICENSE +21 -0
  4. package/README.md +229 -0
  5. package/README.ru.md +229 -0
  6. package/SECURITY.md +31 -0
  7. package/THIRD_PARTY_NOTICES.md +16 -0
  8. package/dist/cli.d.ts +20 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +277 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/commands/balance-command.d.ts +5 -0
  13. package/dist/commands/balance-command.d.ts.map +1 -0
  14. package/dist/commands/balance-command.js +20 -0
  15. package/dist/commands/balance-command.js.map +1 -0
  16. package/dist/config/resolve.d.ts +5 -0
  17. package/dist/config/resolve.d.ts.map +1 -0
  18. package/dist/config/resolve.js +113 -0
  19. package/dist/config/resolve.js.map +1 -0
  20. package/dist/config/schema.d.ts +188 -0
  21. package/dist/config/schema.d.ts.map +1 -0
  22. package/dist/config/schema.js +144 -0
  23. package/dist/config/schema.js.map +1 -0
  24. package/dist/config/types.d.ts +75 -0
  25. package/dist/config/types.d.ts.map +1 -0
  26. package/dist/config/types.js +30 -0
  27. package/dist/config/types.js.map +1 -0
  28. package/dist/logging.d.ts +46 -0
  29. package/dist/logging.d.ts.map +1 -0
  30. package/dist/logging.js +58 -0
  31. package/dist/logging.js.map +1 -0
  32. package/dist/openrouter/capabilities.d.ts +22 -0
  33. package/dist/openrouter/capabilities.d.ts.map +1 -0
  34. package/dist/openrouter/capabilities.js +137 -0
  35. package/dist/openrouter/capabilities.js.map +1 -0
  36. package/dist/openrouter/client.d.ts +54 -0
  37. package/dist/openrouter/client.d.ts.map +1 -0
  38. package/dist/openrouter/client.js +440 -0
  39. package/dist/openrouter/client.js.map +1 -0
  40. package/dist/openrouter/errors.d.ts +22 -0
  41. package/dist/openrouter/errors.d.ts.map +1 -0
  42. package/dist/openrouter/errors.js +75 -0
  43. package/dist/openrouter/errors.js.map +1 -0
  44. package/dist/openrouter/models.d.ts +37 -0
  45. package/dist/openrouter/models.d.ts.map +1 -0
  46. package/dist/openrouter/models.js +113 -0
  47. package/dist/openrouter/models.js.map +1 -0
  48. package/dist/openrouter/requests.d.ts +6 -0
  49. package/dist/openrouter/requests.d.ts.map +1 -0
  50. package/dist/openrouter/requests.js +74 -0
  51. package/dist/openrouter/requests.js.map +1 -0
  52. package/dist/openrouter/schemas.d.ts +37 -0
  53. package/dist/openrouter/schemas.d.ts.map +1 -0
  54. package/dist/openrouter/schemas.js +2 -0
  55. package/dist/openrouter/schemas.js.map +1 -0
  56. package/dist/output/attachments.d.ts +10 -0
  57. package/dist/output/attachments.d.ts.map +1 -0
  58. package/dist/output/attachments.js +13 -0
  59. package/dist/output/attachments.js.map +1 -0
  60. package/dist/output/formats.d.ts +42 -0
  61. package/dist/output/formats.d.ts.map +1 -0
  62. package/dist/output/formats.js +126 -0
  63. package/dist/output/formats.js.map +1 -0
  64. package/dist/output/index.d.ts +5 -0
  65. package/dist/output/index.d.ts.map +1 -0
  66. package/dist/output/index.js +5 -0
  67. package/dist/output/index.js.map +1 -0
  68. package/dist/output/paths.d.ts +38 -0
  69. package/dist/output/paths.d.ts.map +1 -0
  70. package/dist/output/paths.js +296 -0
  71. package/dist/output/paths.js.map +1 -0
  72. package/dist/output/writer.d.ts +33 -0
  73. package/dist/output/writer.d.ts.map +1 -0
  74. package/dist/output/writer.js +176 -0
  75. package/dist/output/writer.js.map +1 -0
  76. package/dist/references/attachments.d.ts +82 -0
  77. package/dist/references/attachments.d.ts.map +1 -0
  78. package/dist/references/attachments.js +238 -0
  79. package/dist/references/attachments.js.map +1 -0
  80. package/dist/references/data-url.d.ts +12 -0
  81. package/dist/references/data-url.d.ts.map +1 -0
  82. package/dist/references/data-url.js +75 -0
  83. package/dist/references/data-url.js.map +1 -0
  84. package/dist/references/formats.d.ts +13 -0
  85. package/dist/references/formats.d.ts.map +1 -0
  86. package/dist/references/formats.js +50 -0
  87. package/dist/references/formats.js.map +1 -0
  88. package/dist/references/index.d.ts +7 -0
  89. package/dist/references/index.d.ts.map +1 -0
  90. package/dist/references/index.js +7 -0
  91. package/dist/references/index.js.map +1 -0
  92. package/dist/references/limits.d.ts +15 -0
  93. package/dist/references/limits.d.ts.map +1 -0
  94. package/dist/references/limits.js +62 -0
  95. package/dist/references/limits.js.map +1 -0
  96. package/dist/references/project-files.d.ts +13 -0
  97. package/dist/references/project-files.d.ts.map +1 -0
  98. package/dist/references/project-files.js +148 -0
  99. package/dist/references/project-files.js.map +1 -0
  100. package/dist/references/remote-urls.d.ts +3 -0
  101. package/dist/references/remote-urls.d.ts.map +1 -0
  102. package/dist/references/remote-urls.js +22 -0
  103. package/dist/references/remote-urls.js.map +1 -0
  104. package/dist/server.d.ts +8 -0
  105. package/dist/server.d.ts.map +1 -0
  106. package/dist/server.js +97 -0
  107. package/dist/server.js.map +1 -0
  108. package/dist/tools/balance.d.ts +8 -0
  109. package/dist/tools/balance.d.ts.map +1 -0
  110. package/dist/tools/balance.js +133 -0
  111. package/dist/tools/balance.js.map +1 -0
  112. package/dist/tools/common.d.ts +3 -0
  113. package/dist/tools/common.d.ts.map +1 -0
  114. package/dist/tools/common.js +18 -0
  115. package/dist/tools/common.js.map +1 -0
  116. package/dist/tools/edit-image.d.ts +90 -0
  117. package/dist/tools/edit-image.d.ts.map +1 -0
  118. package/dist/tools/edit-image.js +47 -0
  119. package/dist/tools/edit-image.js.map +1 -0
  120. package/dist/tools/generate-image.d.ts +70 -0
  121. package/dist/tools/generate-image.d.ts.map +1 -0
  122. package/dist/tools/generate-image.js +36 -0
  123. package/dist/tools/generate-image.js.map +1 -0
  124. package/dist/tools/generation.d.ts +19 -0
  125. package/dist/tools/generation.d.ts.map +1 -0
  126. package/dist/tools/generation.js +154 -0
  127. package/dist/tools/generation.js.map +1 -0
  128. package/dist/tools/schema.d.ts +127 -0
  129. package/dist/tools/schema.d.ts.map +1 -0
  130. package/dist/tools/schema.js +47 -0
  131. package/dist/tools/schema.js.map +1 -0
  132. package/dist/tools/types.d.ts +18 -0
  133. package/dist/tools/types.d.ts.map +1 -0
  134. package/dist/tools/types.js +2 -0
  135. package/dist/tools/types.js.map +1 -0
  136. package/dist/transport/direct.d.ts +10 -0
  137. package/dist/transport/direct.d.ts.map +1 -0
  138. package/dist/transport/direct.js +15 -0
  139. package/dist/transport/direct.js.map +1 -0
  140. package/dist/transport/index.d.ts +4 -0
  141. package/dist/transport/index.d.ts.map +1 -0
  142. package/dist/transport/index.js +4 -0
  143. package/dist/transport/index.js.map +1 -0
  144. package/dist/transport/kote-gateway.d.ts +19 -0
  145. package/dist/transport/kote-gateway.d.ts.map +1 -0
  146. package/dist/transport/kote-gateway.js +224 -0
  147. package/dist/transport/kote-gateway.js.map +1 -0
  148. package/dist/transport/types.d.ts +10 -0
  149. package/dist/transport/types.d.ts.map +1 -0
  150. package/dist/transport/types.js +9 -0
  151. package/dist/transport/types.js.map +1 -0
  152. package/dist/utils/abort.d.ts +19 -0
  153. package/dist/utils/abort.d.ts.map +1 -0
  154. package/dist/utils/abort.js +121 -0
  155. package/dist/utils/abort.js.map +1 -0
  156. package/docs/architecture.md +75 -0
  157. package/docs/configuration.md +110 -0
  158. package/docs/image-to-image.md +101 -0
  159. package/docs/security.md +49 -0
  160. package/docs/testing.md +81 -0
  161. package/docs/troubleshooting.md +73 -0
  162. package/package.json +88 -0
  163. package/schema/plugin-options.schema.json +182 -0
@@ -0,0 +1,113 @@
1
+ function isRecord(value) {
2
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3
+ }
4
+ function parseFiniteNumber(value) {
5
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
6
+ }
7
+ function parseCapability(value) {
8
+ if (!isRecord(value))
9
+ return undefined;
10
+ if (value.type === "boolean")
11
+ return { type: "boolean" };
12
+ if (value.type === "enum" && Array.isArray(value.values)) {
13
+ const values = value.values.filter((entry) => typeof entry === "string" ||
14
+ (typeof entry === "number" && Number.isFinite(entry)));
15
+ return values.length === value.values.length
16
+ ? { type: "enum", values }
17
+ : undefined;
18
+ }
19
+ const min = parseFiniteNumber(value.min);
20
+ const max = parseFiniteNumber(value.max);
21
+ if (value.type === "range" && min !== undefined && max !== undefined && min <= max) {
22
+ return { type: "range", min, max };
23
+ }
24
+ return undefined;
25
+ }
26
+ function parseSupportedParameters(value) {
27
+ if (!isRecord(value))
28
+ return {};
29
+ const result = {};
30
+ for (const [name, descriptor] of Object.entries(value)) {
31
+ const parsed = parseCapability(descriptor);
32
+ if (parsed !== undefined)
33
+ result[name] = parsed;
34
+ }
35
+ return result;
36
+ }
37
+ function parseModalities(value) {
38
+ if (!Array.isArray(value) || !value.every((item) => typeof item === "string")) {
39
+ return [];
40
+ }
41
+ return value;
42
+ }
43
+ function parseImageModel(value) {
44
+ if (!isRecord(value) || typeof value.id !== "string" || !isRecord(value.architecture)) {
45
+ return undefined;
46
+ }
47
+ return {
48
+ id: value.id,
49
+ ...(typeof value.name === "string" ? { name: value.name } : {}),
50
+ architecture: {
51
+ input_modalities: parseModalities(value.architecture.input_modalities),
52
+ output_modalities: parseModalities(value.architecture.output_modalities),
53
+ },
54
+ supported_parameters: parseSupportedParameters(value.supported_parameters),
55
+ ...(typeof value.endpoints === "string" ? { endpoints: value.endpoints } : {}),
56
+ ...(typeof value.supports_streaming === "boolean"
57
+ ? { supports_streaming: value.supports_streaming }
58
+ : {}),
59
+ };
60
+ }
61
+ export function parseImageModelsResponse(value) {
62
+ if (!isRecord(value) || !Array.isArray(value.data)) {
63
+ throw new TypeError("OpenRouter image-model response has an invalid shape.");
64
+ }
65
+ const models = value.data.map(parseImageModel);
66
+ if (models.some((model) => model === undefined)) {
67
+ throw new TypeError("OpenRouter image-model response contains an invalid record.");
68
+ }
69
+ return models;
70
+ }
71
+ function parseEndpoint(value) {
72
+ if (!isRecord(value))
73
+ return undefined;
74
+ return {
75
+ ...(typeof value.provider_name === "string"
76
+ ? { provider_name: value.provider_name }
77
+ : {}),
78
+ ...(typeof value.provider_slug === "string"
79
+ ? { provider_slug: value.provider_slug }
80
+ : {}),
81
+ ...(typeof value.provider_tag === "string" || value.provider_tag === null
82
+ ? { provider_tag: value.provider_tag }
83
+ : {}),
84
+ supported_parameters: parseSupportedParameters(value.supported_parameters),
85
+ ...(typeof value.supports_streaming === "boolean"
86
+ ? { supports_streaming: value.supports_streaming }
87
+ : {}),
88
+ };
89
+ }
90
+ export function parseImageModelEndpointsResponse(value) {
91
+ if (!isRecord(value) || typeof value.id !== "string" || !Array.isArray(value.endpoints)) {
92
+ throw new TypeError("OpenRouter image endpoint response has an invalid shape.");
93
+ }
94
+ const endpoints = value.endpoints.map(parseEndpoint);
95
+ if (endpoints.some((endpoint) => endpoint === undefined)) {
96
+ throw new TypeError("OpenRouter image endpoint response contains an invalid record.");
97
+ }
98
+ return { id: value.id, endpoints: endpoints };
99
+ }
100
+ export function capabilitySupports(descriptor, value) {
101
+ if (descriptor === undefined)
102
+ return false;
103
+ if (descriptor.type === "boolean")
104
+ return true;
105
+ if (descriptor.type === "enum")
106
+ return descriptor.values.includes(value);
107
+ const numericValue = Array.isArray(value) ? value.length : value;
108
+ return (typeof numericValue === "number" &&
109
+ Number.isFinite(numericValue) &&
110
+ numericValue >= descriptor.min &&
111
+ numericValue <= descriptor.max);
112
+ }
113
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/openrouter/models.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { ImageGenerationParameters, ResolvedPluginOptions } from "../config/types.js";
2
+ import type { GenerateImageArgs, OpenRouterImageRequest, OpenRouterInputReference } from "./schemas.js";
3
+ export declare function mergeGenerationParameters(defaults: ImageGenerationParameters, overrides: ImageGenerationParameters): ImageGenerationParameters;
4
+ export declare function buildTextToImageRequest(options: Pick<ResolvedPluginOptions, "model" | "defaults">, args: GenerateImageArgs): OpenRouterImageRequest;
5
+ export declare function buildImageToImageRequest(options: Pick<ResolvedPluginOptions, "model" | "defaults" | "input">, args: GenerateImageArgs, inputReferences: readonly OpenRouterInputReference[]): OpenRouterImageRequest;
6
+ //# sourceMappingURL=requests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../src/openrouter/requests.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,qBAAqB,EACtB,MAAM,oBAAoB,CAAA;AAM3B,OAAO,KAAK,EACV,iBAAiB,EACjB,sBAAsB,EACtB,wBAAwB,EACzB,MAAM,cAAc,CAAA;AAgDrB,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,yBAAyB,EACnC,SAAS,EAAE,yBAAyB,GACnC,yBAAyB,CAW3B;AAgBD,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,OAAO,GAAG,UAAU,CAAC,EAC1D,IAAI,EAAE,iBAAiB,GACtB,sBAAsB,CAExB;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC,EACpE,IAAI,EAAE,iBAAiB,EACvB,eAAe,EAAE,SAAS,wBAAwB,EAAE,GACnD,sBAAsB,CAyBxB"}
@@ -0,0 +1,74 @@
1
+ import { generateImageArgsSchema, generationParametersSchema, } from "../config/schema.js";
2
+ import { PluginError } from "./errors.js";
3
+ const PARAMETER_KEYS = [
4
+ "aspect_ratio",
5
+ "background",
6
+ "n",
7
+ "output_format",
8
+ "output_compression",
9
+ "quality",
10
+ "resolution",
11
+ "seed",
12
+ ];
13
+ function parameterError() {
14
+ return new PluginError("GENIMAGE_PARAMETER_UNSUPPORTED", "Image generation parameters are invalid or incompatible.", {
15
+ suggestion: "Check the prompt, output format, background, compression, and generation limits.",
16
+ });
17
+ }
18
+ function parseArgs(rawArgs) {
19
+ const result = generateImageArgsSchema.safeParse(rawArgs);
20
+ if (!result.success) {
21
+ throw parameterError();
22
+ }
23
+ return result.data;
24
+ }
25
+ function copyDefinedParameters(source) {
26
+ const result = {};
27
+ for (const key of PARAMETER_KEYS) {
28
+ const value = source[key];
29
+ if (value !== undefined) {
30
+ Object.assign(result, { [key]: value });
31
+ }
32
+ }
33
+ return result;
34
+ }
35
+ export function mergeGenerationParameters(defaults, overrides) {
36
+ const merged = {
37
+ ...copyDefinedParameters(defaults),
38
+ ...copyDefinedParameters(overrides),
39
+ };
40
+ const result = generationParametersSchema.safeParse(merged);
41
+ if (!result.success) {
42
+ throw parameterError();
43
+ }
44
+ return copyDefinedParameters(result.data);
45
+ }
46
+ function createBaseRequest(options, rawArgs) {
47
+ const args = parseArgs(rawArgs);
48
+ const parameters = mergeGenerationParameters(options.defaults, args);
49
+ return {
50
+ model: options.model,
51
+ prompt: args.prompt,
52
+ ...parameters,
53
+ };
54
+ }
55
+ export function buildTextToImageRequest(options, args) {
56
+ return createBaseRequest(options, args);
57
+ }
58
+ export function buildImageToImageRequest(options, args, inputReferences) {
59
+ if (inputReferences.length === 0) {
60
+ throw new PluginError("GENIMAGE_REFERENCE_REQUIRED", "Image editing requires at least one visual reference.");
61
+ }
62
+ if (inputReferences.length > options.input.maxReferences) {
63
+ throw new PluginError("GENIMAGE_TOO_MANY_REFERENCES", "The number of image references exceeds the configured limit.", { details: { maxReferences: options.input.maxReferences } });
64
+ }
65
+ const references = inputReferences.map((reference) => ({
66
+ type: reference.type,
67
+ image_url: { url: reference.image_url.url },
68
+ }));
69
+ return {
70
+ ...createBaseRequest(options, args),
71
+ input_references: references,
72
+ };
73
+ }
74
+ //# sourceMappingURL=requests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests.js","sourceRoot":"","sources":["../../src/openrouter/requests.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { ImageAspectRatio, ImageBackground, ImageGenerationParameters, ImageOutputFormat, ImageQuality, ImageResolution } from "../config/types.js";
2
+ export interface GenerateImageArgs extends ImageGenerationParameters {
3
+ prompt: string;
4
+ output_path?: string | undefined;
5
+ }
6
+ export interface OpenRouterInputReference {
7
+ type: "image_url";
8
+ image_url: {
9
+ url: string;
10
+ };
11
+ }
12
+ export interface OpenRouterImageRequest {
13
+ model: string;
14
+ prompt: string;
15
+ input_references?: OpenRouterInputReference[] | undefined;
16
+ aspect_ratio?: ImageAspectRatio | undefined;
17
+ background?: ImageBackground | undefined;
18
+ n?: number | undefined;
19
+ output_format?: ImageOutputFormat | undefined;
20
+ output_compression?: number | undefined;
21
+ quality?: ImageQuality | undefined;
22
+ resolution?: ImageResolution | undefined;
23
+ seed?: number | undefined;
24
+ }
25
+ export interface OpenRouterGeneratedImage {
26
+ b64_json: string;
27
+ media_type?: string | undefined;
28
+ }
29
+ export interface OpenRouterImageUsage {
30
+ cost?: number | undefined;
31
+ [key: string]: unknown;
32
+ }
33
+ export interface OpenRouterImageResponse {
34
+ data: OpenRouterGeneratedImage[];
35
+ usage?: OpenRouterImageUsage | undefined;
36
+ }
37
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/openrouter/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,yBAAyB,EACzB,iBAAiB,EACjB,YAAY,EACZ,eAAe,EAChB,MAAM,oBAAoB,CAAA;AAE3B,MAAM,WAAW,iBAAkB,SAAQ,yBAAyB;IAClE,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACjC;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,WAAW,CAAA;IACjB,SAAS,EAAE;QACT,GAAG,EAAE,MAAM,CAAA;KACZ,CAAA;CACF;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB,CAAC,EAAE,wBAAwB,EAAE,GAAG,SAAS,CAAA;IACzD,YAAY,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAA;IAC3C,UAAU,CAAC,EAAE,eAAe,GAAG,SAAS,CAAA;IACxC,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACtB,aAAa,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAA;IAC7C,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,OAAO,CAAC,EAAE,YAAY,GAAG,SAAS,CAAA;IAClC,UAAU,CAAC,EAAE,eAAe,GAAG,SAAS,CAAA;IACxC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC1B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,wBAAwB,EAAE,CAAA;IAChC,KAAK,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAA;CACzC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/openrouter/schemas.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ import type { SavedImage } from "./writer.js";
2
+ export interface ToolFileAttachment {
3
+ type: "file";
4
+ mime: SavedImage["mime"];
5
+ filename: string;
6
+ url: string;
7
+ }
8
+ export declare function createToolAttachment(image: SavedImage): ToolFileAttachment;
9
+ export declare function createToolAttachments(images: readonly SavedImage[]): ToolFileAttachment[];
10
+ //# sourceMappingURL=attachments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../src/output/attachments.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,kBAAkB,CAO1E;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,UAAU,EAAE,GAC5B,kBAAkB,EAAE,CAEtB"}
@@ -0,0 +1,13 @@
1
+ import { imageBytesToDataUrl } from "../references/data-url.js";
2
+ export function createToolAttachment(image) {
3
+ return {
4
+ type: "file",
5
+ mime: image.mime,
6
+ filename: image.filename,
7
+ url: imageBytesToDataUrl(image.data, image.mime),
8
+ };
9
+ }
10
+ export function createToolAttachments(images) {
11
+ return images.map(createToolAttachment);
12
+ }
13
+ //# sourceMappingURL=attachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/output/attachments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAU/D,MAAM,UAAU,oBAAoB,CAAC,KAAiB;IACpD,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,GAAG,EAAE,mBAAmB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;KACjD,CAAA;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,MAA6B;IAE7B,OAAO,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;AACzC,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { Buffer } from "node:buffer";
2
+ import type { ImageOutputFormat } from "../config/types.js";
3
+ import { type DetectedImageFormat } from "../references/formats.js";
4
+ export interface EncodedOutputImage {
5
+ b64_json: string;
6
+ media_type?: string | undefined;
7
+ }
8
+ export interface ValidatedImage {
9
+ bytes: Buffer;
10
+ detected: DetectedImageFormat;
11
+ warnings?: readonly string[] | undefined;
12
+ }
13
+ export interface DecodedImage extends ValidatedImage {
14
+ warnings: string[];
15
+ }
16
+ export interface DecodeOutputImageOptions {
17
+ maxDecodedBytes: number;
18
+ expectedFormat?: ImageOutputFormat | undefined;
19
+ /** One-based result index, used only in safe diagnostic messages. */
20
+ index?: number | undefined;
21
+ }
22
+ export interface DecodeOutputImagesOptions {
23
+ maxDecodedBytes: number;
24
+ expectedFormat?: ImageOutputFormat | undefined;
25
+ }
26
+ export interface DecodedOutputImages {
27
+ images: DecodedImage[];
28
+ warnings: string[];
29
+ invalidCount: number;
30
+ }
31
+ /**
32
+ * Strictly decodes one OpenRouter image result and classifies it from magic
33
+ * bytes. Provider media-type fields are advisory and can only produce a
34
+ * warning; they never override the binary format.
35
+ */
36
+ export declare function decodeOutputImage(image: unknown, options: DecodeOutputImageOptions): DecodedImage;
37
+ /**
38
+ * Decodes a response defensively. Invalid entries are skipped so callers can
39
+ * report partial success. The decoded-byte budget applies to the full set.
40
+ */
41
+ export declare function decodeOutputImages(data: unknown, options: DecodeOutputImagesOptions): DecodedOutputImages;
42
+ //# sourceMappingURL=formats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formats.d.ts","sourceRoot":"","sources":["../../src/output/formats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAG3D,OAAO,EAGL,KAAK,mBAAmB,EAEzB,MAAM,0BAA0B,CAAA;AAEjC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,mBAAmB,CAAA;IAC7B,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;CACzC;AAED,MAAM,WAAW,YAAa,SAAQ,cAAc;IAClD,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,wBAAwB;IACvC,eAAe,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAA;IAC9C,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC3B;AAED,MAAM,WAAW,yBAAyB;IACxC,eAAe,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAA;CAC/C;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,YAAY,EAAE,CAAA;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;CACrB;AAgED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,wBAAwB,GAChC,YAAY,CA2Dd;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,yBAAyB,GACjC,mBAAmB,CA8CrB"}
@@ -0,0 +1,126 @@
1
+ import { PluginError, isPluginError } from "../openrouter/errors.js";
2
+ import { decodeStrictBase64 } from "../references/data-url.js";
3
+ import { detectImageFormat, isSupportedImageMime, } from "../references/formats.js";
4
+ function imageLabel(index) {
5
+ return index === undefined ? "The returned image" : `Returned image ${index}`;
6
+ }
7
+ function invalidImage(message, cause) {
8
+ return new PluginError("GENIMAGE_IMAGE_INVALID", message, {
9
+ ...(cause === undefined ? {} : { cause }),
10
+ });
11
+ }
12
+ function extractEncodedPayload(value) {
13
+ if (!value.startsWith("data:"))
14
+ return { encoded: value };
15
+ const match = /^data:([^;,]+);base64,(.*)$/u.exec(value);
16
+ const declaredMime = match?.[1];
17
+ const encoded = match?.[2];
18
+ if (declaredMime === undefined || encoded === undefined || encoded === "") {
19
+ throw invalidImage("OpenRouter returned an invalid image data URL.");
20
+ }
21
+ return { encoded, declaredMime };
22
+ }
23
+ function normalizeDeclaredMime(value) {
24
+ return value.trim().toLowerCase();
25
+ }
26
+ function addDeclaredMimeWarning(warnings, declaredMime, actualMime, index) {
27
+ if (declaredMime === undefined)
28
+ return;
29
+ const normalized = normalizeDeclaredMime(declaredMime);
30
+ if (normalized === actualMime)
31
+ return;
32
+ const declaration = isSupportedImageMime(normalized)
33
+ ? normalized
34
+ : "an unsupported media type";
35
+ warnings.push(`${imageLabel(index)} was declared as ${declaration}, but its bytes are ${actualMime}; the binary format was used.`);
36
+ }
37
+ function addExpectedFormatWarning(warnings, expectedFormat, detected, index) {
38
+ if (expectedFormat === undefined || expectedFormat === detected.format)
39
+ return;
40
+ warnings.push(`${imageLabel(index)} is ${detected.format.toUpperCase()}, although ${expectedFormat.toUpperCase()} was requested; it will be saved with the actual format extension.`);
41
+ }
42
+ /**
43
+ * Strictly decodes one OpenRouter image result and classifies it from magic
44
+ * bytes. Provider media-type fields are advisory and can only produce a
45
+ * warning; they never override the binary format.
46
+ */
47
+ export function decodeOutputImage(image, options) {
48
+ if (!Number.isSafeInteger(options.maxDecodedBytes) || options.maxDecodedBytes <= 0) {
49
+ throw new TypeError("maxDecodedBytes must be a positive safe integer");
50
+ }
51
+ if (typeof image !== "object" ||
52
+ image === null ||
53
+ Array.isArray(image) ||
54
+ !("b64_json" in image) ||
55
+ typeof image.b64_json !== "string" ||
56
+ image.b64_json === "" ||
57
+ ("media_type" in image &&
58
+ image.media_type !== undefined &&
59
+ typeof image.media_type !== "string")) {
60
+ throw invalidImage("OpenRouter returned an image without valid base64 data.");
61
+ }
62
+ const encodedImage = image;
63
+ const payload = extractEncodedPayload(encodedImage.b64_json);
64
+ let bytes;
65
+ try {
66
+ bytes = decodeStrictBase64(payload.encoded, options.maxDecodedBytes);
67
+ }
68
+ catch (error) {
69
+ throw invalidImage("OpenRouter returned invalid or oversized base64 image data.", error);
70
+ }
71
+ const detected = detectImageFormat(bytes);
72
+ if (detected === undefined) {
73
+ throw invalidImage("OpenRouter returned an unsupported image binary; only PNG, JPEG, and WebP are accepted.");
74
+ }
75
+ const warnings = [];
76
+ addDeclaredMimeWarning(warnings, payload.declaredMime, detected.mime, options.index);
77
+ if (encodedImage.media_type !== undefined &&
78
+ normalizeDeclaredMime(encodedImage.media_type) !==
79
+ normalizeDeclaredMime(payload.declaredMime ?? "")) {
80
+ addDeclaredMimeWarning(warnings, encodedImage.media_type, detected.mime, options.index);
81
+ }
82
+ addExpectedFormatWarning(warnings, options.expectedFormat, detected, options.index);
83
+ return { bytes, detected, warnings };
84
+ }
85
+ /**
86
+ * Decodes a response defensively. Invalid entries are skipped so callers can
87
+ * report partial success. The decoded-byte budget applies to the full set.
88
+ */
89
+ export function decodeOutputImages(data, options) {
90
+ if (!Array.isArray(data) || data.length === 0) {
91
+ throw new PluginError("GENIMAGE_RESPONSE_INVALID", "OpenRouter returned no generated images.");
92
+ }
93
+ if (!Number.isSafeInteger(options.maxDecodedBytes) || options.maxDecodedBytes <= 0) {
94
+ throw new TypeError("maxDecodedBytes must be a positive safe integer");
95
+ }
96
+ const entries = data;
97
+ const images = [];
98
+ const warnings = [];
99
+ let decodedBytes = 0;
100
+ let invalidCount = 0;
101
+ for (const [zeroBasedIndex, image] of entries.entries()) {
102
+ const index = zeroBasedIndex + 1;
103
+ try {
104
+ const decoded = decodeOutputImage(image, {
105
+ maxDecodedBytes: options.maxDecodedBytes - decodedBytes,
106
+ ...(options.expectedFormat === undefined
107
+ ? {}
108
+ : { expectedFormat: options.expectedFormat }),
109
+ index,
110
+ });
111
+ decodedBytes += decoded.bytes.byteLength;
112
+ images.push(decoded);
113
+ warnings.push(...decoded.warnings);
114
+ }
115
+ catch (error) {
116
+ invalidCount += 1;
117
+ const code = isPluginError(error) ? error.code : "GENIMAGE_IMAGE_INVALID";
118
+ warnings.push(`Returned image ${index} was invalid and was skipped (${code}).`);
119
+ }
120
+ }
121
+ if (images.length === 0) {
122
+ throw new PluginError("GENIMAGE_IMAGE_INVALID", "OpenRouter did not return any valid PNG, JPEG, or WebP images.", { details: { returnedCount: entries.length, invalidCount } });
123
+ }
124
+ return { images, warnings, invalidCount };
125
+ }
126
+ //# sourceMappingURL=formats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formats.js","sourceRoot":"","sources":["../../src/output/formats.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { createToolAttachment, createToolAttachments, type ToolFileAttachment, } from "./attachments.js";
2
+ export { decodeOutputImage, decodeOutputImages, type DecodeOutputImageOptions, type DecodeOutputImagesOptions, type DecodedImage, type DecodedOutputImages, type EncodedOutputImage, type ValidatedImage, } from "./formats.js";
3
+ export { addCollisionSuffix, assertOutputParentContained, assertSafeOutputRelativePath, ensureSafeOutputParent, findNearestExistingAncestor, isExistingPathError, planOutputPaths, recheckSafeOutputParent, type OutputPathPlan, type OutputPathRequest, type PlannedOutputPath, } from "./paths.js";
4
+ export { ImageSaveError, saveImages, type SavedImage, type SaveImagesOptions, } from "./writer.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/output/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,KAAK,kBAAkB,GACxB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,kBAAkB,EAClB,2BAA2B,EAC3B,4BAA4B,EAC5B,sBAAsB,EACtB,2BAA2B,EAC3B,mBAAmB,EACnB,eAAe,EACf,uBAAuB,EACvB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,GACvB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,cAAc,EACd,UAAU,EACV,KAAK,UAAU,EACf,KAAK,iBAAiB,GACvB,MAAM,aAAa,CAAA"}
@@ -0,0 +1,5 @@
1
+ export { createToolAttachment, createToolAttachments, } from "./attachments.js";
2
+ export { decodeOutputImage, decodeOutputImages, } from "./formats.js";
3
+ export { addCollisionSuffix, assertOutputParentContained, assertSafeOutputRelativePath, ensureSafeOutputParent, findNearestExistingAncestor, isExistingPathError, planOutputPaths, recheckSafeOutputParent, } from "./paths.js";
4
+ export { ImageSaveError, saveImages, } from "./writer.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/output/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GAEtB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,iBAAiB,EACjB,kBAAkB,GAOnB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,kBAAkB,EAClB,2BAA2B,EAC3B,4BAA4B,EAC5B,sBAAsB,EACtB,2BAA2B,EAC3B,mBAAmB,EACnB,eAAe,EACf,uBAAuB,GAIxB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,cAAc,EACd,UAAU,GAGX,MAAM,aAAa,CAAA"}
@@ -0,0 +1,38 @@
1
+ import { type DetectedImageFormat } from "../references/formats.js";
2
+ export interface OutputPathRequest {
3
+ worktree: string;
4
+ outputDirectory: string;
5
+ outputPath?: string | undefined;
6
+ detectedFormats: readonly DetectedImageFormat[];
7
+ sourcePaths?: readonly string[] | undefined;
8
+ now?: Date | undefined;
9
+ randomId?: (() => string) | undefined;
10
+ }
11
+ export interface PlannedOutputPath {
12
+ absolutePath: string;
13
+ relativePath: string;
14
+ filename: string;
15
+ warnings: string[];
16
+ /** Unsuffixed candidate used to continue a collision sequence atomically. */
17
+ collisionBaseRelativePath: string;
18
+ collisionNumber: number;
19
+ }
20
+ export interface OutputPathPlan {
21
+ canonicalWorktree: string;
22
+ paths: PlannedOutputPath[];
23
+ }
24
+ /** Validate a portable, worktree-relative path without resolving it. */
25
+ export declare function assertSafeOutputRelativePath(value: string, kind?: "file" | "directory"): string;
26
+ export declare function isExistingPathError(error: unknown): boolean;
27
+ export declare function findNearestExistingAncestor(value: string): Promise<string>;
28
+ export declare function assertOutputParentContained(canonicalWorktree: string, parent: string): Promise<void>;
29
+ /** Create an output parent, then canonicalize it again to catch symlink escapes. */
30
+ export declare function ensureSafeOutputParent(canonicalWorktree: string, parent: string): Promise<string>;
31
+ export declare function recheckSafeOutputParent(canonicalWorktree: string, parent: string): Promise<void>;
32
+ export declare function addCollisionSuffix(relativePath: string, collision: number): string;
33
+ /**
34
+ * Plans non-conflicting destinations. This is advisory only: the writer still
35
+ * uses an atomic no-clobber operation to close the check/write race.
36
+ */
37
+ export declare function planOutputPaths(request: OutputPathRequest): Promise<OutputPathPlan>;
38
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/output/paths.ts"],"names":[],"mappings":"AASA,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,0BAA0B,CAAA;AAEjC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,EAAE,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,eAAe,EAAE,SAAS,mBAAmB,EAAE,CAAA;IAC/C,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;IAC3C,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;IACtB,QAAQ,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAA;CACtC;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,6EAA6E;IAC7E,yBAAyB,EAAE,MAAM,CAAA;IACjC,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,iBAAiB,EAAE,MAAM,CAAA;IACzB,KAAK,EAAE,iBAAiB,EAAE,CAAA;CAC3B;AA4CD,wEAAwE;AACxE,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,MAAM,GAAG,WAAoB,GAClC,MAAM,CAuBR;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAO3D;AAED,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAehF;AAED,wBAAsB,2BAA2B,CAC/C,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED,oFAAoF;AACpF,wBAAsB,sBAAsB,CAC1C,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAED,wBAAsB,uBAAuB,CAC3C,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAcf;AAgDD,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAMlF;AAkFD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,cAAc,CAAC,CAwGzB"}