@opencode/codemode 0.0.0-dev-20782 → 0.0.0-dev-20784
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.
- package/dist/openapi/index.js +1 -1
- package/dist/openapi/runtime.d.ts +1 -1
- package/dist/openapi/runtime.js +1 -1
- package/dist/openapi/types.d.ts +1 -1
- package/dist/openapi/types.js +1 -1
- package/dist/tool-schema.js +32 -18
- package/dist/tool.d.ts +1 -0
- package/package.json +2 -2
package/dist/openapi/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HttpClient } from "effect/
|
|
1
|
+
import { HttpClient } from "effect/http";
|
|
2
2
|
import { make } from "../tool.js";
|
|
3
3
|
import { invoke } from "./runtime.js";
|
|
4
4
|
import { componentDefinitions, hasDirectionalSchemas, inputSchema, isRecord, methods, nonEmptyString, operationInput, operationOutput, operationPath, operationSecurityRequirements, securityRequirements, securitySchemes, specServerUrl, validateBaseUrl, } from "./spec.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import { HttpClient } from "effect/
|
|
2
|
+
import { HttpClient } from "effect/http";
|
|
3
3
|
import type { Plan } from "./types.js";
|
|
4
4
|
export declare const invoke: (plan: Plan, input: unknown) => Effect.Effect<unknown, unknown, HttpClient.HttpClient>;
|
package/dist/openapi/runtime.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Effect, Option, Schema, Stream } from "effect";
|
|
2
|
-
import { HttpClient, HttpClientRequest, HttpClientResponse } from "effect/
|
|
2
|
+
import { HttpClient, HttpClientRequest, HttpClientResponse } from "effect/http";
|
|
3
3
|
import { ToolError, toolError } from "../tool-error.js";
|
|
4
4
|
import { isRecord, own } from "./spec.js";
|
|
5
5
|
const decodeJson = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Unknown));
|
package/dist/openapi/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import { HttpClient } from "effect/
|
|
2
|
+
import { HttpClient } from "effect/http";
|
|
3
3
|
import type { Tool, JsonSchema } from "../tool.js";
|
|
4
4
|
/** A parsed OpenAPI 3.x document. YAML must be parsed by the ctx. */
|
|
5
5
|
export type Document = Record<string, unknown>;
|
package/dist/openapi/types.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import { HttpClient } from "effect/
|
|
2
|
+
import { HttpClient } from "effect/http";
|
package/dist/tool-schema.js
CHANGED
|
@@ -3,10 +3,23 @@ const isEffectSchema = (schema) => Schema.isSchema(schema);
|
|
|
3
3
|
const renderLiteral = (value) => JSON.stringify(value) ?? "unknown";
|
|
4
4
|
export const identifierSegment = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
5
5
|
const renderKey = (name) => (identifierSegment.test(name) ? name : JSON.stringify(name));
|
|
6
|
+
const definitionName = (ref) => {
|
|
7
|
+
const tokens = JsonPointer.parseUriFragment(ref);
|
|
8
|
+
return tokens?.length === 2 && (tokens[0] === "$defs" || tokens[0] === "definitions") ? tokens[1] : undefined;
|
|
9
|
+
};
|
|
10
|
+
// Effect encodes an unchecked `number` as `number | "Infinity" | "-Infinity" | "NaN"`, and older generators emit one
|
|
11
|
+
// singleton enum per value. Rendering them as plain `number` only narrows what the model is told to send.
|
|
6
12
|
const effectNumberSentinel = (schema) => schema.type === "string" &&
|
|
7
13
|
Array.isArray(schema.enum) &&
|
|
8
|
-
schema.enum.length
|
|
9
|
-
|
|
14
|
+
schema.enum.length > 0 &&
|
|
15
|
+
schema.enum.every((value) => value === "NaN" || value === "Infinity" || value === "-Infinity");
|
|
16
|
+
// Effect emits `{ not: { type: "null" } }` only for a struct with no properties or index signatures. With nothing but
|
|
17
|
+
// annotations beside it, it is TypeScript's `{}`. Mirrors `emptyInputJsonSchema` in `@opencode/ai`, which this
|
|
18
|
+
// standalone package cannot import.
|
|
19
|
+
const annotationKeywords = new Set(["title", "description", "default", "examples", "readOnly", "writeOnly"]);
|
|
20
|
+
const isEffectEmptyStruct = (schema) => schema.not?.type === "null" &&
|
|
21
|
+
Object.keys(schema.not).length === 1 &&
|
|
22
|
+
Object.keys(schema).every((key) => key === "not" || annotationKeywords.has(key));
|
|
10
23
|
const intersection = (members) => {
|
|
11
24
|
const concrete = members.filter((member) => member !== "unknown");
|
|
12
25
|
if (concrete.length === 0)
|
|
@@ -21,8 +34,7 @@ const hasUnresolvedRef = (schema, definitions, seen = new Set(), visited = new S
|
|
|
21
34
|
return false;
|
|
22
35
|
const nextVisited = new Set([...visited, schema]);
|
|
23
36
|
if (schema.$ref !== undefined) {
|
|
24
|
-
const
|
|
25
|
-
const name = segment === undefined ? undefined : JsonPointer.unescapeToken(segment);
|
|
37
|
+
const name = definitionName(schema.$ref);
|
|
26
38
|
if (name === undefined || definitions[name] === undefined || seen.has(name))
|
|
27
39
|
return true;
|
|
28
40
|
if (hasUnresolvedRef(definitions[name], definitions, new Set([...seen, name]), nextVisited))
|
|
@@ -124,8 +136,7 @@ const renderSchema = (schema, ctx, depth = 0, seen = new Set()) => {
|
|
|
124
136
|
? ctx
|
|
125
137
|
: { ...ctx, definitions: { ...ctx.definitions, ...(schema.definitions ?? {}), ...(schema.$defs ?? {}) } };
|
|
126
138
|
if (schema.$ref) {
|
|
127
|
-
const
|
|
128
|
-
const name = segment === undefined ? undefined : JsonPointer.unescapeToken(segment);
|
|
139
|
+
const name = definitionName(schema.$ref);
|
|
129
140
|
if (!name || !nested.definitions[name] || seen.has(name))
|
|
130
141
|
return "unknown";
|
|
131
142
|
return intersection([
|
|
@@ -142,6 +153,7 @@ const renderSchema = (schema, ctx, depth = 0, seen = new Set()) => {
|
|
|
142
153
|
if (alternatives.some((item) => item.type === "number") &&
|
|
143
154
|
alternatives.every((item) => item.type === "number" || effectNumberSentinel(item)))
|
|
144
155
|
return "number";
|
|
156
|
+
// Older Effect releases emitted this pair for an empty struct, and raw schemas from their generators still can.
|
|
145
157
|
if (alternatives.length === 2 &&
|
|
146
158
|
alternatives[0]?.type === "object" &&
|
|
147
159
|
alternatives[0].properties === undefined &&
|
|
@@ -196,13 +208,16 @@ const renderSchema = (schema, ctx, depth = 0, seen = new Set()) => {
|
|
|
196
208
|
lines.push(`${pad}[key: string]: ${indexType},`);
|
|
197
209
|
return `{\n${lines.join("\n")}\n${" ".repeat(depth)}}`;
|
|
198
210
|
}
|
|
211
|
+
if (isEffectEmptyStruct(schema))
|
|
212
|
+
return "{}";
|
|
199
213
|
return "unknown";
|
|
200
214
|
};
|
|
201
215
|
export const toTypeScript = (schema, decoded = false, pretty = false) => {
|
|
202
216
|
try {
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
217
|
+
const document = Schema.toJsonSchemaDocument(decoded ? Schema.toType(schema) : schema, {
|
|
218
|
+
onExcessProperty: "error",
|
|
219
|
+
});
|
|
220
|
+
return renderSchema(document.schema, { definitions: document.definitions, pretty });
|
|
206
221
|
}
|
|
207
222
|
catch {
|
|
208
223
|
return "unknown";
|
|
@@ -219,17 +234,15 @@ export const jsonSchemaToTypeScript = (schema, pretty = false) => {
|
|
|
219
234
|
export const inputProperties = (tool) => {
|
|
220
235
|
try {
|
|
221
236
|
const document = isEffectSchema(tool.input)
|
|
222
|
-
? Schema.toJsonSchemaDocument(tool.input)
|
|
237
|
+
? Schema.toJsonSchemaDocument(tool.input, { onExcessProperty: "error" })
|
|
223
238
|
: {
|
|
224
239
|
schema: tool.input,
|
|
225
240
|
definitions: { ...(tool.input.definitions ?? {}), ...(tool.input.$defs ?? {}) },
|
|
226
241
|
};
|
|
227
|
-
const definitions = document.definitions ?? {};
|
|
228
242
|
let schema = document.schema;
|
|
229
243
|
if (schema.$ref !== undefined) {
|
|
230
|
-
const
|
|
231
|
-
const
|
|
232
|
-
const resolved = name === undefined ? undefined : definitions[name];
|
|
244
|
+
const name = definitionName(schema.$ref);
|
|
245
|
+
const resolved = name === undefined ? undefined : document.definitions[name];
|
|
233
246
|
if (resolved === undefined)
|
|
234
247
|
return [];
|
|
235
248
|
schema = resolved;
|
|
@@ -246,10 +259,11 @@ export const inputProperties = (tool) => {
|
|
|
246
259
|
}
|
|
247
260
|
};
|
|
248
261
|
export const inputTypeScript = (tool, pretty = false) => isEffectSchema(tool.input) ? toTypeScript(tool.input, false, pretty) : jsonSchemaToTypeScript(tool.input, pretty);
|
|
249
|
-
//
|
|
250
|
-
//
|
|
251
|
-
|
|
252
|
-
|
|
262
|
+
// Effect inputs are empty only when their encoded root is Effect's empty-struct marker, which records and checked
|
|
263
|
+
// structs never are. Raw JSON Schema inputs keep the `{}` rendering check, which treats `{ type: "object" }` as empty.
|
|
264
|
+
export const isEmptyInput = (tool) => isEffectSchema(tool.input)
|
|
265
|
+
? isEffectEmptyStruct(Schema.toJsonSchemaDocument(tool.input, { referencePolicy: () => undefined }).schema)
|
|
266
|
+
: inputTypeScript(tool) === "{}";
|
|
253
267
|
export const outputTypeScript = (tool, pretty = false) => tool.output === undefined
|
|
254
268
|
? "void"
|
|
255
269
|
: isEffectSchema(tool.output)
|
package/dist/tool.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export type JsonSchema = {
|
|
|
12
12
|
readonly anyOf?: ReadonlyArray<JsonSchema>;
|
|
13
13
|
readonly oneOf?: ReadonlyArray<JsonSchema>;
|
|
14
14
|
readonly allOf?: ReadonlyArray<JsonSchema>;
|
|
15
|
+
readonly not?: JsonSchema;
|
|
15
16
|
readonly properties?: Readonly<Record<string, JsonSchema>>;
|
|
16
17
|
readonly required?: ReadonlyArray<string>;
|
|
17
18
|
readonly items?: JsonSchema;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@opencode/codemode",
|
|
4
|
-
"version": "0.0.0-dev-
|
|
4
|
+
"version": "0.0.0-dev-20784",
|
|
5
5
|
"description": "Effect-native confined code execution over schema-described tools",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"acorn": "8.15.0",
|
|
32
|
-
"effect": "4.0.0-rc.
|
|
32
|
+
"effect": "4.0.0-rc.118"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@tsconfig/bun": "1.0.9",
|