@opencode/codemode 0.0.0-beta-19507 → 0.0.0-dev-19276
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/README.md +0 -6
- package/dist/codemode.d.ts +12 -9
- package/dist/codemode.js +9 -5
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/interpreter/errors.d.ts +6 -4
- package/dist/interpreter/errors.js +10 -25
- package/dist/interpreter/execute.d.ts +3 -4
- package/dist/interpreter/execute.js +18 -11
- package/dist/interpreter/iterator.d.ts +13 -0
- package/dist/interpreter/iterator.js +4 -0
- package/dist/interpreter/methods.d.ts +16 -3
- package/dist/interpreter/methods.js +290 -101
- package/dist/interpreter/model.d.ts +79 -10
- package/dist/interpreter/model.js +102 -2
- package/dist/interpreter/promises.d.ts +13 -15
- package/dist/interpreter/promises.js +52 -70
- package/dist/interpreter/references.d.ts +0 -1
- package/dist/interpreter/references.js +77 -57
- package/dist/interpreter/runtime.d.ts +95 -16
- package/dist/interpreter/runtime.js +960 -549
- package/dist/openapi/spec.js +6 -3
- package/dist/stdlib/collections.d.ts +1 -6
- package/dist/stdlib/collections.js +1 -117
- package/dist/stdlib/console.d.ts +2 -3
- package/dist/stdlib/console.js +28 -39
- package/dist/stdlib/date.d.ts +4 -5
- package/dist/stdlib/date.js +12 -34
- package/dist/stdlib/json.d.ts +6 -3
- package/dist/stdlib/json.js +63 -40
- package/dist/stdlib/math.d.ts +7 -3
- package/dist/stdlib/math.js +153 -85
- package/dist/stdlib/number.d.ts +4 -2
- package/dist/stdlib/number.js +37 -30
- package/dist/stdlib/object.d.ts +6 -6
- package/dist/stdlib/object.js +87 -84
- package/dist/stdlib/promise.d.ts +2 -0
- package/dist/stdlib/promise.js +1 -0
- package/dist/stdlib/regexp.d.ts +7 -6
- package/dist/stdlib/regexp.js +34 -48
- package/dist/stdlib/string.d.ts +3 -1
- package/dist/stdlib/string.js +17 -20
- package/dist/stdlib/url.d.ts +6 -10
- package/dist/stdlib/url.js +25 -102
- package/dist/stdlib/value.d.ts +7 -8
- package/dist/stdlib/value.js +56 -56
- package/dist/tool-runtime.d.ts +15 -16
- package/dist/tool-runtime.js +150 -13
- package/dist/values.d.ts +16 -22
- package/dist/values.js +17 -23
- package/package.json +1 -1
- package/dist/data.d.ts +0 -25
- package/dist/data.js +0 -153
- package/dist/interpreter/globals.d.ts +0 -13
- package/dist/interpreter/globals.js +0 -63
- package/dist/interpreter/host.d.ts +0 -41
- package/dist/interpreter/host.js +0 -44
- package/dist/interpreter/objects.d.ts +0 -37
- package/dist/interpreter/objects.js +0 -151
- package/dist/interpreter/runner.d.ts +0 -24
- package/dist/interpreter/runner.js +0 -45
- package/dist/stdlib/array.d.ts +0 -3
- package/dist/stdlib/array.js +0 -68
- package/dist/stdlib/web.d.ts +0 -4
- package/dist/stdlib/web.js +0 -20
package/dist/stdlib/regexp.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { sync, syncCall } from "../interpreter/host.js";
|
|
2
1
|
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { isBlockedMember } from "../tool-runtime.js";
|
|
3
|
+
import { CodeModeRegExp } from "../values.js";
|
|
5
4
|
import { coerceToNumber, coerceToString } from "./value.js";
|
|
6
5
|
export const regexpMethods = new Set(["test", "exec", "toString"]);
|
|
6
|
+
export const regexpStatics = new Set(["escape"]);
|
|
7
7
|
export const regexpProperties = new Set([
|
|
8
8
|
"source",
|
|
9
9
|
"flags",
|
|
@@ -17,13 +17,13 @@ export const regexpProperties = new Set([
|
|
|
17
17
|
"unicodeSets",
|
|
18
18
|
"dotAll",
|
|
19
19
|
]);
|
|
20
|
-
const regexFailureReason = (error) => (error instanceof Error ? error.message : String(error)).replace(/^Invalid regular expression:\s*/i, "");
|
|
21
|
-
const escapeRegexHint = 'To match special characters like ( ) [ ] { } + * ? . literally, escape them with a backslash (e.g. "\\\\(") or test for them with String.includes instead.';
|
|
20
|
+
export const regexFailureReason = (error) => (error instanceof Error ? error.message : String(error)).replace(/^Invalid regular expression:\s*/i, "");
|
|
21
|
+
export const escapeRegexHint = 'To match special characters like ( ) [ ] { } + * ? . literally, escape them with a backslash (e.g. "\\\\(") or test for them with String.includes instead.';
|
|
22
22
|
export const toHostRegex = (arg, method, node, extraFlags = "") => {
|
|
23
23
|
// Native parity: an undefined pattern behaves as an empty pattern.
|
|
24
24
|
if (arg === undefined)
|
|
25
25
|
return new RegExp("", extraFlags);
|
|
26
|
-
if (arg instanceof
|
|
26
|
+
if (arg instanceof CodeModeRegExp)
|
|
27
27
|
return arg.regex;
|
|
28
28
|
if (typeof arg === "string") {
|
|
29
29
|
try {
|
|
@@ -36,48 +36,29 @@ export const toHostRegex = (arg, method, node, extraFlags = "") => {
|
|
|
36
36
|
throw new InterpreterRuntimeError(`String.${method} expects a regular expression (a /pattern/flags literal or new RegExp(...)) or a string pattern, not ${arg === null ? "null" : typeof arg}.`, node);
|
|
37
37
|
};
|
|
38
38
|
export const matchToValue = (match) => {
|
|
39
|
-
const result =
|
|
39
|
+
const result = Array.from(match, (group) => group);
|
|
40
40
|
if (match.index !== undefined)
|
|
41
|
-
|
|
42
|
-
if (match.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
result.index = match.index;
|
|
42
|
+
if (match.groups) {
|
|
43
|
+
const groups = Object.create(null);
|
|
44
|
+
for (const [key, group] of Object.entries(match.groups)) {
|
|
45
|
+
if (!isBlockedMember(key))
|
|
46
|
+
groups[key] = group;
|
|
47
|
+
}
|
|
48
|
+
result.groups = groups;
|
|
49
|
+
}
|
|
46
50
|
if (match.indices)
|
|
47
|
-
|
|
51
|
+
result.indices = indicesToValue(match.indices);
|
|
48
52
|
return result;
|
|
49
53
|
};
|
|
50
|
-
export const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
throw new InterpreterRuntimeError(`RegExp flags must be a string of flag characters (e.g. "g", "gi"), not ${flagsArg === null ? "null" : typeof flagsArg}.`, node).as("SyntaxError");
|
|
56
|
-
}
|
|
57
|
-
const flags = flagsArg ?? (first instanceof Values.RegExp ? first.regex.flags : "");
|
|
58
|
-
try {
|
|
59
|
-
return new Values.RegExp(pattern, flags);
|
|
60
|
-
}
|
|
61
|
-
catch (error) {
|
|
62
|
-
const reason = regexFailureReason(error);
|
|
63
|
-
throw new InterpreterRuntimeError(/flag/i.test(reason)
|
|
64
|
-
? `new RegExp(...) received invalid flags ${JSON.stringify(flags)} (${reason}). Valid flags are d, g, i, m, s, u, v, and y.`
|
|
65
|
-
: `new RegExp(...) received ${JSON.stringify(pattern)}, which is not a valid regular expression pattern (${reason}). ${escapeRegexHint}`, node).as("SyntaxError");
|
|
54
|
+
export const invokeRegExpStatic = (name, args, node) => {
|
|
55
|
+
if (name !== "escape")
|
|
56
|
+
throw new InterpreterRuntimeError(`RegExp.${name} is not available.`, node);
|
|
57
|
+
if (typeof args[0] !== "string") {
|
|
58
|
+
throw new InterpreterRuntimeError("RegExp.escape expects a string.", node).as("TypeError");
|
|
66
59
|
}
|
|
60
|
+
return RegExp.escape(args[0]);
|
|
67
61
|
};
|
|
68
|
-
// RegExp constructs identically with or without new, like JS.
|
|
69
|
-
export const regexpGlobal = sync("RegExp", constructRegExp, {
|
|
70
|
-
construct: syncCall(constructRegExp),
|
|
71
|
-
instanceOf: (value) => value instanceof Values.RegExp,
|
|
72
|
-
members: {
|
|
73
|
-
escape: sync("RegExp.escape", (args, node) => {
|
|
74
|
-
if (typeof args[0] !== "string") {
|
|
75
|
-
throw new InterpreterRuntimeError("RegExp.escape expects a string.", node).as("TypeError");
|
|
76
|
-
}
|
|
77
|
-
return RegExp.escape(args[0]);
|
|
78
|
-
}),
|
|
79
|
-
},
|
|
80
|
-
});
|
|
81
62
|
export const invokeRegExpMethod = (value, name, args, node) => {
|
|
82
63
|
switch (name) {
|
|
83
64
|
case "test":
|
|
@@ -110,11 +91,16 @@ const toLength = (value) => {
|
|
|
110
91
|
return Math.min(Math.floor(number), Number.MAX_SAFE_INTEGER);
|
|
111
92
|
};
|
|
112
93
|
const indicesToValue = (indices) => {
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
94
|
+
const result = Array.from(indices, (range) => (range === undefined ? undefined : [...range]));
|
|
95
|
+
if (indices.groups) {
|
|
96
|
+
const groups = Object.create(null);
|
|
97
|
+
for (const [key, range] of Object.entries(indices.groups)) {
|
|
98
|
+
if (!isBlockedMember(key))
|
|
99
|
+
groups[key] = range === undefined ? undefined : [...range];
|
|
100
|
+
}
|
|
101
|
+
result.groups = groups;
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
result.groups = undefined;
|
|
119
105
|
return result;
|
|
120
106
|
};
|
package/dist/stdlib/string.d.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export declare const stringMethods: Set<string>;
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const stringStatics: Set<string>;
|
|
3
|
+
export declare const invokeStringStatic: (name: string, args: Array<unknown>, node: AstNode) => unknown;
|
|
4
|
+
import { type AstNode } from "../interpreter/model.js";
|
package/dist/stdlib/string.js
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
import { sync } from "../interpreter/host.js";
|
|
2
|
-
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
3
|
-
import { coercion } from "./value.js";
|
|
4
1
|
export const stringMethods = new Set([
|
|
5
2
|
"toLowerCase",
|
|
6
3
|
"toUpperCase",
|
|
7
4
|
"trim",
|
|
8
5
|
"trimStart",
|
|
9
6
|
"trimEnd",
|
|
10
|
-
"trimLeft",
|
|
11
|
-
"trimRight",
|
|
12
7
|
"split",
|
|
13
8
|
"slice",
|
|
14
9
|
"substring",
|
|
15
|
-
"substr",
|
|
16
10
|
"includes",
|
|
17
11
|
"startsWith",
|
|
18
12
|
"endsWith",
|
|
@@ -34,18 +28,21 @@ export const stringMethods = new Set([
|
|
|
34
28
|
"search",
|
|
35
29
|
"localeCompare",
|
|
36
30
|
"normalize",
|
|
37
|
-
"isWellFormed",
|
|
38
|
-
"toWellFormed",
|
|
39
31
|
]);
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
32
|
+
export const stringStatics = new Set(["fromCharCode", "fromCodePoint"]);
|
|
33
|
+
export const invokeStringStatic = (name, args, node) => {
|
|
34
|
+
const codes = args.map((arg) => {
|
|
35
|
+
if (typeof arg !== "number")
|
|
36
|
+
throw new InterpreterRuntimeError(`String.${name} expects number arguments.`, node);
|
|
37
|
+
return arg;
|
|
38
|
+
});
|
|
39
|
+
switch (name) {
|
|
40
|
+
case "fromCharCode":
|
|
41
|
+
return String.fromCharCode(...codes);
|
|
42
|
+
case "fromCodePoint":
|
|
43
|
+
return String.fromCodePoint(...codes);
|
|
44
|
+
default:
|
|
45
|
+
throw new InterpreterRuntimeError(`String.${name} is not available.`, node);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
package/dist/stdlib/url.d.ts
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import { HostFunction } from "../interpreter/host.js";
|
|
2
|
-
import { type AstNode } from "../interpreter/model.js";
|
|
3
|
-
import { type Runner } from "../interpreter/runner.js";
|
|
4
|
-
import { Values } from "../values.js";
|
|
5
1
|
export declare const urlProperties: Set<string>;
|
|
6
2
|
export declare const urlWritableProperties: Set<string>;
|
|
7
3
|
export declare const urlMethods: Set<string>;
|
|
4
|
+
export declare const urlStatics: Set<string>;
|
|
8
5
|
export declare const urlSearchParamsMethods: Set<string>;
|
|
9
6
|
export declare const uriArgument: (value: unknown, label: string) => string;
|
|
10
|
-
|
|
11
|
-
export declare const uriGlobal: (name: UriFunction) => HostFunction<never>;
|
|
7
|
+
export declare const invokeUriFunction: (ref: UriFunction, args: Array<unknown>, node: AstNode) => string;
|
|
12
8
|
export declare const urlArgument: (value: unknown, label: string) => string;
|
|
13
|
-
export declare const
|
|
14
|
-
export declare const
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
export declare const invokeURLStatic: (name: string, args: Array<unknown>, node: AstNode) => unknown;
|
|
10
|
+
export declare const invokeURLMethod: (value: CodeModeURL, name: string, node: AstNode) => string;
|
|
11
|
+
import { type AstNode, UriFunction } from "../interpreter/model.js";
|
|
12
|
+
import { CodeModeURL } from "../values.js";
|
package/dist/stdlib/url.js
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import { toProgram } from "../data.js";
|
|
3
|
-
import { HostFunction, requiresNew, sync, syncCall } from "../interpreter/host.js";
|
|
4
|
-
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
5
|
-
import { ownEntries, ProgramObject } from "../interpreter/objects.js";
|
|
6
|
-
import { isRuntimeReference } from "../interpreter/references.js";
|
|
7
|
-
import { preserveConsumerError } from "../interpreter/runner.js";
|
|
8
|
-
import { Values } from "../values.js";
|
|
9
|
-
import { coerceToString } from "./value.js";
|
|
10
1
|
export const urlProperties = new Set([
|
|
11
2
|
"href",
|
|
12
3
|
"origin",
|
|
@@ -33,6 +24,7 @@ export const urlWritableProperties = new Set([
|
|
|
33
24
|
"hash",
|
|
34
25
|
]);
|
|
35
26
|
export const urlMethods = new Set(["toString", "toJSON"]);
|
|
27
|
+
export const urlStatics = new Set(["canParse", "parse"]);
|
|
36
28
|
export const urlSearchParamsMethods = new Set([
|
|
37
29
|
"append",
|
|
38
30
|
"delete",
|
|
@@ -47,115 +39,46 @@ export const urlSearchParamsMethods = new Set([
|
|
|
47
39
|
"entries",
|
|
48
40
|
"toString",
|
|
49
41
|
]);
|
|
50
|
-
export const uriArgument = (value, label) => coerceToString(
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
encodeURIComponent,
|
|
54
|
-
decodeURI,
|
|
55
|
-
decodeURIComponent,
|
|
56
|
-
};
|
|
57
|
-
export const uriGlobal = (name) => sync(name, (args, node) => {
|
|
58
|
-
const value = uriArgument(args[0], `${name} input`);
|
|
42
|
+
export const uriArgument = (value, label) => coerceToString(boundedData(value, label));
|
|
43
|
+
export const invokeUriFunction = (ref, args, node) => {
|
|
44
|
+
const value = uriArgument(args[0], `${ref.name} input`);
|
|
59
45
|
try {
|
|
60
|
-
|
|
46
|
+
switch (ref.name) {
|
|
47
|
+
case "encodeURI":
|
|
48
|
+
return encodeURI(value);
|
|
49
|
+
case "encodeURIComponent":
|
|
50
|
+
return encodeURIComponent(value);
|
|
51
|
+
case "decodeURI":
|
|
52
|
+
return decodeURI(value);
|
|
53
|
+
case "decodeURIComponent":
|
|
54
|
+
return decodeURIComponent(value);
|
|
55
|
+
}
|
|
61
56
|
}
|
|
62
57
|
catch (error) {
|
|
63
|
-
throw new InterpreterRuntimeError(`${name} received malformed URI data: ${error instanceof Error ? error.message : String(error)}`, node).as("URIError");
|
|
58
|
+
throw new InterpreterRuntimeError(`${ref.name} received malformed URI data: ${error instanceof Error ? error.message : String(error)}`, node).as("URIError");
|
|
64
59
|
}
|
|
65
|
-
}
|
|
66
|
-
export const urlArgument = (value, label) => value instanceof
|
|
67
|
-
const
|
|
68
|
-
if (
|
|
60
|
+
};
|
|
61
|
+
export const urlArgument = (value, label) => value instanceof CodeModeURL ? value.url.href : uriArgument(value, label);
|
|
62
|
+
export const invokeURLStatic = (name, args, node) => {
|
|
63
|
+
if (!urlStatics.has(name))
|
|
64
|
+
throw new InterpreterRuntimeError(`URL.${name} is not available.`, node);
|
|
65
|
+
if (args.length === 0)
|
|
69
66
|
throw new InterpreterRuntimeError(`URL.${name} requires a URL argument.`, node).as("TypeError");
|
|
70
|
-
}
|
|
71
67
|
const input = urlArgument(args[0], `URL.${name} input`);
|
|
72
68
|
const base = args[1] === undefined ? undefined : urlArgument(args[1], `URL.${name} base`);
|
|
73
69
|
try {
|
|
74
70
|
const url = new URL(input, base);
|
|
75
|
-
return name === "canParse" ? true : new
|
|
71
|
+
return name === "canParse" ? true : new CodeModeURL(url);
|
|
76
72
|
}
|
|
77
73
|
catch {
|
|
78
74
|
return name === "canParse" ? false : null;
|
|
79
75
|
}
|
|
80
|
-
});
|
|
81
|
-
const constructURL = (args, node) => {
|
|
82
|
-
if (args.length === 0) {
|
|
83
|
-
throw new InterpreterRuntimeError("new URL(...) requires a URL string and an optional base URL.", node).as("TypeError");
|
|
84
|
-
}
|
|
85
|
-
const input = urlArgument(args[0], "new URL input");
|
|
86
|
-
const base = args[1] === undefined ? undefined : urlArgument(args[1], "new URL base");
|
|
87
|
-
try {
|
|
88
|
-
return new Values.URL(new URL(input, base));
|
|
89
|
-
}
|
|
90
|
-
catch {
|
|
91
|
-
throw new InterpreterRuntimeError(`new URL(...) received an invalid URL${base === undefined ? "" : " or base URL"}.`, node).as("TypeError");
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
export const urlGlobal = new HostFunction({
|
|
95
|
-
name: "URL",
|
|
96
|
-
call: requiresNew("URL"),
|
|
97
|
-
construct: syncCall(constructURL),
|
|
98
|
-
instanceOf: (value) => value instanceof Values.URL,
|
|
99
|
-
members: { canParse: urlStatic("canParse"), parse: urlStatic("parse") },
|
|
100
|
-
});
|
|
101
|
-
const readURLSearchParamsPair = (runner, value, node) => Effect.gen(function* () {
|
|
102
|
-
const cursor = yield* runner.syncIterator(value, node);
|
|
103
|
-
if (cursor === undefined) {
|
|
104
|
-
throw new InterpreterRuntimeError("new URLSearchParams(...) expects iterable [name, value] pairs.", node).as("TypeError");
|
|
105
|
-
}
|
|
106
|
-
const items = [];
|
|
107
|
-
while (true) {
|
|
108
|
-
const step = yield* cursor.next;
|
|
109
|
-
if (step.done)
|
|
110
|
-
return items;
|
|
111
|
-
items.push(yield* preserveConsumerError(cursor, Effect.sync(() => uriArgument(step.value, "URLSearchParams pair value"))));
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
const constructURLSearchParams = (runner, init, node) => {
|
|
115
|
-
if (init === undefined)
|
|
116
|
-
return Effect.succeed(new Values.URLSearchParams(new URLSearchParams()));
|
|
117
|
-
if (init instanceof Values.URLSearchParams) {
|
|
118
|
-
return Effect.succeed(new Values.URLSearchParams(new URLSearchParams(init.params)));
|
|
119
|
-
}
|
|
120
|
-
if (typeof init === "string")
|
|
121
|
-
return Effect.succeed(new Values.URLSearchParams(new URLSearchParams(init)));
|
|
122
|
-
if (init === null || typeof init === "number" || typeof init === "boolean") {
|
|
123
|
-
return Effect.succeed(new Values.URLSearchParams(new URLSearchParams(coerceToString(init))));
|
|
124
|
-
}
|
|
125
|
-
return Effect.gen(function* () {
|
|
126
|
-
const cursor = yield* runner.syncIterator(init, node);
|
|
127
|
-
if (cursor !== undefined) {
|
|
128
|
-
const entries = [];
|
|
129
|
-
while (true) {
|
|
130
|
-
const step = yield* cursor.next;
|
|
131
|
-
if (step.done) {
|
|
132
|
-
if (entries.some((entry) => entry.length !== 2)) {
|
|
133
|
-
throw new InterpreterRuntimeError("new URLSearchParams(...) expects iterable [name, value] pairs.", node).as("TypeError");
|
|
134
|
-
}
|
|
135
|
-
return new Values.URLSearchParams(new URLSearchParams(entries.map((entry) => [entry[0] ?? "", entry[1] ?? ""])));
|
|
136
|
-
}
|
|
137
|
-
entries.push(yield* preserveConsumerError(cursor, readURLSearchParamsPair(runner, step.value, node)));
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
if (isRuntimeReference(init)) {
|
|
141
|
-
throw new InterpreterRuntimeError("new URLSearchParams(...) expects a query string, data object, or synchronous iterable pairs.", node).as("TypeError");
|
|
142
|
-
}
|
|
143
|
-
if (Values.isValue(init))
|
|
144
|
-
return new Values.URLSearchParams(new URLSearchParams());
|
|
145
|
-
if (!(init instanceof ProgramObject)) {
|
|
146
|
-
throw new InterpreterRuntimeError("new URLSearchParams(...) expects a query string, data object, iterable pairs, or URLSearchParams.", node).as("TypeError");
|
|
147
|
-
}
|
|
148
|
-
return new Values.URLSearchParams(new URLSearchParams(Object.fromEntries(ownEntries(init).map(([key, value]) => [key, coerceToString(value)]))));
|
|
149
|
-
});
|
|
150
76
|
};
|
|
151
|
-
export const urlSearchParamsGlobal = (runner) => new HostFunction({
|
|
152
|
-
name: "URLSearchParams",
|
|
153
|
-
call: requiresNew("URLSearchParams"),
|
|
154
|
-
construct: (args, node) => constructURLSearchParams(runner, args[0], node),
|
|
155
|
-
instanceOf: (value) => value instanceof Values.URLSearchParams,
|
|
156
|
-
});
|
|
157
77
|
export const invokeURLMethod = (value, name, node) => {
|
|
158
78
|
if (name === "toString" || name === "toJSON")
|
|
159
79
|
return value.url.href;
|
|
160
80
|
throw new InterpreterRuntimeError(`URL method '${name}' is not available.`, node);
|
|
161
81
|
};
|
|
82
|
+
import { InterpreterRuntimeError, UriFunction } from "../interpreter/model.js";
|
|
83
|
+
import { CodeModeURL } from "../values.js";
|
|
84
|
+
import { boundedData, coerceToString } from "./value.js";
|
package/dist/stdlib/value.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { type HostFunction, type SyncOptions } from "../interpreter/host.js";
|
|
2
|
-
import { ProgramError } from "../interpreter/objects.js";
|
|
3
1
|
export declare const errorConstructors: Set<string>;
|
|
2
|
+
export declare const valueConstructors: Set<string>;
|
|
4
3
|
export declare const compoundOperators: Set<string>;
|
|
5
|
-
export declare const createErrorValue: (name: string, message: string) =>
|
|
6
|
-
export declare const createAggregateErrorValue: (errors: Array<unknown>, message: string) =>
|
|
4
|
+
export declare const createErrorValue: (name: string, message: string) => SafeObject;
|
|
5
|
+
export declare const createAggregateErrorValue: (errors: Array<unknown>, message: string) => SafeObject;
|
|
7
6
|
export declare const errorBrandName: (value: unknown) => string | undefined;
|
|
7
|
+
export declare const boundedData: (value: unknown, label: string) => unknown;
|
|
8
8
|
export declare const coerceToString: (value: unknown) => string;
|
|
9
9
|
export declare const coerceToNumber: (value: unknown) => number;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export {};
|
|
10
|
+
export declare const invokeCoercion: (ref: CoercionFunction, args: Array<unknown>, node: AstNode) => unknown;
|
|
11
|
+
import { type AstNode, CoercionFunction } from "../interpreter/model.js";
|
|
12
|
+
import { type SafeObject } from "../tool-runtime.js";
|
package/dist/stdlib/value.js
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import { sync } from "../interpreter/host.js";
|
|
2
|
-
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
3
|
-
import { toProgram } from "../data.js";
|
|
4
|
-
import { get, ProgramArray, ProgramError, set } from "../interpreter/objects.js";
|
|
5
|
-
import { Values } from "../values.js";
|
|
6
1
|
export const errorConstructors = new Set([
|
|
7
2
|
"Error",
|
|
8
3
|
"TypeError",
|
|
@@ -13,108 +8,113 @@ export const errorConstructors = new Set([
|
|
|
13
8
|
"URIError",
|
|
14
9
|
"AggregateError",
|
|
15
10
|
]);
|
|
11
|
+
export const valueConstructors = new Set(["Date", "RegExp", "Map", "Set", "URL", "URLSearchParams"]);
|
|
16
12
|
export const compoundOperators = new Set(["+=", "-=", "*=", "/=", "%=", "**=", "&=", "|=", "^=", "<<=", ">>=", ">>>="]);
|
|
13
|
+
const ErrorBrand = Symbol("codemode.error");
|
|
17
14
|
export const createErrorValue = (name, message) => {
|
|
18
|
-
const value =
|
|
19
|
-
|
|
20
|
-
set(value, "message", message);
|
|
15
|
+
const value = Object.assign(Object.create(null), { name, message });
|
|
16
|
+
Object.defineProperty(value, ErrorBrand, { value: name });
|
|
21
17
|
return value;
|
|
22
18
|
};
|
|
23
|
-
export const createAggregateErrorValue = (errors, message) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
export const errorBrandName = (value) => value instanceof ProgramError ? value.errorName : undefined;
|
|
19
|
+
export const createAggregateErrorValue = (errors, message) => Object.assign(createErrorValue("AggregateError", message), { errors });
|
|
20
|
+
export const errorBrandName = (value) => value !== null && typeof value === "object"
|
|
21
|
+
? value[ErrorBrand]
|
|
22
|
+
: undefined;
|
|
23
|
+
export const boundedData = (value, label) => copyIn(value, label, true);
|
|
29
24
|
export const coerceToString = (value) => {
|
|
30
25
|
if (value === null)
|
|
31
26
|
return "null";
|
|
32
27
|
if (value === undefined)
|
|
33
28
|
return "undefined";
|
|
34
|
-
if (value instanceof
|
|
29
|
+
if (value instanceof CodeModeDate)
|
|
35
30
|
return Number.isFinite(value.time) ? new Date(value.time).toISOString() : "Invalid Date";
|
|
36
|
-
if (value instanceof
|
|
31
|
+
if (value instanceof CodeModeRegExp)
|
|
37
32
|
return `/${value.regex.source}/${value.regex.flags}`;
|
|
38
|
-
if (value instanceof
|
|
33
|
+
if (value instanceof CodeModeMap)
|
|
39
34
|
return "[object Map]";
|
|
40
|
-
if (value instanceof
|
|
35
|
+
if (value instanceof CodeModeSet)
|
|
41
36
|
return "[object Set]";
|
|
42
|
-
if (value instanceof
|
|
37
|
+
if (value instanceof CodeModeURL)
|
|
43
38
|
return value.url.href;
|
|
44
|
-
if (value instanceof
|
|
39
|
+
if (value instanceof CodeModeURLSearchParams)
|
|
45
40
|
return value.params.toString();
|
|
46
|
-
if (value
|
|
41
|
+
if (errorBrandName(value) !== undefined) {
|
|
47
42
|
// Match Error.prototype.toString: "name: message", or just one when the other is empty.
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return `${shownName}: ${shownMessage}`;
|
|
43
|
+
const error = value;
|
|
44
|
+
const name = typeof error.name === "string" ? error.name : "Error";
|
|
45
|
+
const message = typeof error.message === "string" ? error.message : "";
|
|
46
|
+
if (message === "")
|
|
47
|
+
return name;
|
|
48
|
+
if (name === "")
|
|
49
|
+
return message;
|
|
50
|
+
return `${name}: ${message}`;
|
|
57
51
|
}
|
|
58
|
-
if (value
|
|
59
|
-
return
|
|
52
|
+
if (typeof value === "object") {
|
|
53
|
+
return Array.isArray(value)
|
|
54
|
+
? value.map((item) => (item === null || item === undefined ? "" : coerceToString(item))).join(",")
|
|
55
|
+
: "[object Object]";
|
|
60
56
|
}
|
|
61
|
-
if (typeof value === "object")
|
|
62
|
-
return "[object Object]";
|
|
63
57
|
return String(value);
|
|
64
58
|
};
|
|
65
59
|
export const coerceToNumber = (value) => {
|
|
66
|
-
if (value instanceof
|
|
60
|
+
if (value instanceof CodeModeDate)
|
|
67
61
|
return value.time;
|
|
68
|
-
if (
|
|
62
|
+
if (isCodeModeValue(value))
|
|
69
63
|
return Number.NaN;
|
|
70
|
-
|
|
64
|
+
// Arrays coerce through our own string coercion: host Number(array) joins with host
|
|
65
|
+
// ToPrimitive, which throws on the null-prototype objects the interpreter produces.
|
|
66
|
+
if (Array.isArray(value))
|
|
71
67
|
return Number(coerceToString(value));
|
|
72
68
|
return value !== null && typeof value === "object" ? Number.NaN : Number(value);
|
|
73
69
|
};
|
|
74
|
-
const
|
|
70
|
+
export const invokeCoercion = (ref, args, node) => {
|
|
75
71
|
// Native: Number() is 0 and String() is "", unlike their undefined-argument forms; the
|
|
76
72
|
// other coercers match native through the undefined-argument path below.
|
|
77
73
|
if (args.length === 0) {
|
|
78
|
-
if (name === "Number")
|
|
74
|
+
if (ref.name === "Number")
|
|
79
75
|
return 0;
|
|
80
|
-
if (name === "String")
|
|
76
|
+
if (ref.name === "String")
|
|
81
77
|
return "";
|
|
82
78
|
}
|
|
83
79
|
const raw = args[0];
|
|
84
|
-
|
|
85
|
-
|
|
80
|
+
// Error values are plain SafeObjects; the boundedData path below would strip their brand.
|
|
81
|
+
if (ref.name === "String" && errorBrandName(raw) !== undefined)
|
|
82
|
+
return coerceToString(raw);
|
|
83
|
+
if (isCodeModeValue(raw)) {
|
|
84
|
+
if (ref.name === "Boolean")
|
|
86
85
|
return true;
|
|
87
|
-
if (name === "Number")
|
|
86
|
+
if (ref.name === "Number")
|
|
88
87
|
return coerceToNumber(raw);
|
|
89
|
-
if (name === "String")
|
|
88
|
+
if (ref.name === "String")
|
|
90
89
|
return coerceToString(raw);
|
|
91
|
-
if (name === "isFinite")
|
|
90
|
+
if (ref.name === "isFinite")
|
|
92
91
|
return Number.isFinite(coerceToNumber(raw));
|
|
93
|
-
if (name === "isNaN")
|
|
92
|
+
if (ref.name === "isNaN")
|
|
94
93
|
return Number.isNaN(coerceToNumber(raw));
|
|
95
|
-
if (name === "parseInt")
|
|
94
|
+
if (ref.name === "parseInt")
|
|
96
95
|
return parseInt(coerceToString(raw));
|
|
97
96
|
return parseFloat(coerceToString(raw));
|
|
98
97
|
}
|
|
99
|
-
const value =
|
|
100
|
-
if (name === "Number")
|
|
98
|
+
const value = boundedData(raw, `${ref.name} input`);
|
|
99
|
+
if (ref.name === "Number")
|
|
101
100
|
return coerceToNumber(value);
|
|
102
|
-
if (name === "Boolean")
|
|
101
|
+
if (ref.name === "Boolean")
|
|
103
102
|
return Boolean(value);
|
|
104
|
-
if (name === "isFinite")
|
|
103
|
+
if (ref.name === "isFinite")
|
|
105
104
|
return Number.isFinite(coerceToNumber(value));
|
|
106
|
-
if (name === "isNaN")
|
|
105
|
+
if (ref.name === "isNaN")
|
|
107
106
|
return Number.isNaN(coerceToNumber(value));
|
|
108
|
-
if (name === "parseInt") {
|
|
107
|
+
if (ref.name === "parseInt") {
|
|
109
108
|
const radix = args[1];
|
|
110
109
|
if (radix !== undefined && typeof radix !== "number") {
|
|
111
110
|
throw new InterpreterRuntimeError("parseInt expects a numeric radix.", node);
|
|
112
111
|
}
|
|
113
112
|
return parseInt(coerceToString(value), radix);
|
|
114
113
|
}
|
|
115
|
-
if (name === "parseFloat")
|
|
114
|
+
if (ref.name === "parseFloat")
|
|
116
115
|
return parseFloat(coerceToString(value));
|
|
117
116
|
return coerceToString(value);
|
|
118
117
|
};
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
import { CoercionFunction, InterpreterRuntimeError } from "../interpreter/model.js";
|
|
119
|
+
import { copyIn } from "../tool-runtime.js";
|
|
120
|
+
import { isCodeModeValue, CodeModeDate, CodeModeMap, CodeModeRegExp, CodeModeSet, CodeModeURL, CodeModeURLSearchParams, } from "../values.js";
|
package/dist/tool-runtime.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import { type Namespace } from "./namespace.js";
|
|
3
|
-
import { type Tool } from "./tool.js";
|
|
4
2
|
import type { Tools } from "./tools.js";
|
|
5
|
-
export declare const compareText: (left: string, right: string) => 1 | -1 | 0;
|
|
6
3
|
export type Services<T> = ServicesOf<T, []>;
|
|
7
4
|
type ServicesOf<T, Depth extends ReadonlyArray<unknown>> = Depth["length"] extends 8 ? never : T extends {
|
|
8
5
|
readonly _tag: "CodeModeTool";
|
|
@@ -25,9 +22,7 @@ export type ToolCallEnded = {
|
|
|
25
22
|
readonly message?: string;
|
|
26
23
|
};
|
|
27
24
|
export type ToolCallHooks<R = never> = {
|
|
28
|
-
/** Observes decoded tool input immediately before tool execution. */
|
|
29
25
|
readonly onToolCallStart?: ((call: ToolCallStarted) => Effect.Effect<void, never, R>) | undefined;
|
|
30
|
-
/** Observes each admitted tool call as it succeeds, fails, or is interrupted. */
|
|
31
26
|
readonly onToolCallEnd?: ((call: ToolCallEnded) => Effect.Effect<void, never, R>) | undefined;
|
|
32
27
|
};
|
|
33
28
|
export type ToolDescription = {
|
|
@@ -35,19 +30,22 @@ export type ToolDescription = {
|
|
|
35
30
|
readonly description: string;
|
|
36
31
|
readonly signature: string;
|
|
37
32
|
};
|
|
33
|
+
export type SafeObject = Record<string, unknown>;
|
|
38
34
|
export declare const toolExpression: (path: string) => string;
|
|
39
35
|
export declare class ToolReference {
|
|
40
36
|
readonly path: ReadonlyArray<string>;
|
|
41
37
|
constructor(path: ReadonlyArray<string>);
|
|
42
38
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export
|
|
50
|
-
|
|
39
|
+
export declare class ToolRuntimeError extends Error {
|
|
40
|
+
readonly kind: "UnknownTool" | "InvalidToolInput" | "InvalidToolOutput" | "InvalidDataValue" | "ToolCallLimitExceeded";
|
|
41
|
+
readonly suggestions: ReadonlyArray<string>;
|
|
42
|
+
constructor(kind: "UnknownTool" | "InvalidToolInput" | "InvalidToolOutput" | "InvalidDataValue" | "ToolCallLimitExceeded", message: string, suggestions?: ReadonlyArray<string>);
|
|
43
|
+
}
|
|
44
|
+
export declare const isBlockedMember: (name: string) => boolean;
|
|
45
|
+
export declare const copyIn: (value: unknown, label: string, preserveCodeModeValues?: boolean) => unknown;
|
|
46
|
+
export type CopyOutMode = "json" | "nullify";
|
|
47
|
+
export declare const copyOut: (value: unknown, mode: CopyOutMode) => unknown;
|
|
48
|
+
export type DiscoveryPlan = {
|
|
51
49
|
readonly catalog: ReadonlyArray<ToolDescription>;
|
|
52
50
|
readonly searchIndex: ReadonlyArray<SearchEntry>;
|
|
53
51
|
};
|
|
@@ -57,13 +55,14 @@ export type SearchEntry = {
|
|
|
57
55
|
};
|
|
58
56
|
/** Exact callable signature of the built-in `search` function, for host-owned instructions. */
|
|
59
57
|
export declare const searchSignature: string;
|
|
60
|
-
export declare const
|
|
58
|
+
export declare const searchIndex: <R>(tools: Tools<R>) => ReadonlyArray<SearchEntry>;
|
|
59
|
+
export declare const prepare: <R>(tools: Tools<R>) => DiscoveryPlan;
|
|
61
60
|
export type ToolRuntime<R = never> = {
|
|
61
|
+
readonly root: ToolReference;
|
|
62
62
|
readonly calls: Array<ToolCall>;
|
|
63
63
|
readonly execute: (path: ReadonlyArray<string>, args: Array<unknown>) => Effect.Effect<unknown, unknown, R>;
|
|
64
64
|
readonly search: (args: Array<unknown>) => Effect.Effect<unknown, unknown, R>;
|
|
65
65
|
readonly keys: (path: ReadonlyArray<string>) => ReadonlyArray<string>;
|
|
66
66
|
};
|
|
67
|
-
|
|
68
|
-
export declare const make: <R>(prepared: Prepared<R>, maxToolCalls: number | undefined, hooks?: ToolCallHooks<R>) => ToolRuntime<R>;
|
|
67
|
+
export declare const make: <R>(tools: Tools<R>, maxToolCalls: number | undefined, searchIndex: ReadonlyArray<SearchEntry>, hooks?: ToolCallHooks<R>) => ToolRuntime<R>;
|
|
69
68
|
export * as ToolRuntime from "./tool-runtime.js";
|