@bolt-foundry/gambit-core 0.8.3 → 0.8.5-rc.4
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 +32 -2
- package/{script/deps/jsr.io/@std/collections/1.1.4 → esm/deps/jsr.io/@std/collections/1.1.5}/deep_merge.d.ts +2 -2
- package/esm/deps/jsr.io/@std/collections/{1.1.4 → 1.1.5}/deep_merge.d.ts.map +1 -1
- package/esm/deps/jsr.io/@std/collections/{1.1.4 → 1.1.5}/deep_merge.js +29 -19
- package/esm/deps/jsr.io/@std/toml/1.0.11/_parser.js +1 -1
- package/esm/mod.d.ts +9 -1
- package/esm/mod.d.ts.map +1 -1
- package/esm/mod.js +4 -0
- package/esm/schemas/graders/contexts/conversation.d.ts +22 -0
- package/esm/schemas/graders/contexts/conversation.d.ts.map +1 -0
- package/esm/schemas/graders/contexts/conversation.js +17 -0
- package/esm/schemas/graders/contexts/conversation.zod.d.ts +3 -0
- package/esm/schemas/graders/contexts/conversation.zod.d.ts.map +1 -0
- package/esm/schemas/graders/contexts/conversation.zod.js +2 -0
- package/esm/schemas/graders/contexts/conversation_tools.d.ts +31 -0
- package/esm/schemas/graders/contexts/conversation_tools.d.ts.map +1 -0
- package/esm/schemas/graders/contexts/conversation_tools.js +25 -0
- package/esm/schemas/graders/contexts/conversation_tools.zod.d.ts +3 -0
- package/esm/schemas/graders/contexts/conversation_tools.zod.d.ts.map +1 -0
- package/esm/schemas/graders/contexts/conversation_tools.zod.js +2 -0
- package/esm/schemas/graders/contexts/tools.d.ts +4 -0
- package/esm/schemas/graders/contexts/tools.d.ts.map +1 -0
- package/esm/schemas/graders/contexts/tools.js +3 -0
- package/esm/schemas/graders/contexts/tools.zod.d.ts +3 -0
- package/esm/schemas/graders/contexts/tools.zod.d.ts.map +1 -0
- package/esm/schemas/graders/contexts/tools.zod.js +2 -0
- package/esm/schemas/graders/contexts/turn.d.ts +10 -0
- package/esm/schemas/graders/contexts/turn.d.ts.map +1 -0
- package/esm/schemas/graders/contexts/turn.js +8 -0
- package/esm/schemas/graders/contexts/turn.zod.d.ts +3 -0
- package/esm/schemas/graders/contexts/turn.zod.d.ts.map +1 -0
- package/esm/schemas/graders/contexts/turn.zod.js +2 -0
- package/esm/schemas/graders/contexts/turn_tools.d.ts +32 -0
- package/esm/schemas/graders/contexts/turn_tools.d.ts.map +1 -0
- package/esm/schemas/graders/contexts/turn_tools.js +28 -0
- package/esm/schemas/graders/contexts/turn_tools.zod.d.ts +3 -0
- package/esm/schemas/graders/contexts/turn_tools.zod.d.ts.map +1 -0
- package/esm/schemas/graders/contexts/turn_tools.zod.js +2 -0
- package/esm/schemas/graders/grader_output.d.ts +10 -0
- package/esm/schemas/graders/grader_output.d.ts.map +1 -0
- package/esm/schemas/graders/grader_output.js +8 -0
- package/esm/schemas/graders/grader_output.zod.d.ts +3 -0
- package/esm/schemas/graders/grader_output.zod.d.ts.map +1 -0
- package/esm/schemas/graders/grader_output.zod.js +2 -0
- package/esm/schemas/graders/respond.d.ts +12 -0
- package/esm/schemas/graders/respond.d.ts.map +1 -0
- package/esm/schemas/graders/respond.js +10 -0
- package/esm/schemas/graders/respond.zod.d.ts +3 -0
- package/esm/schemas/graders/respond.zod.d.ts.map +1 -0
- package/esm/schemas/graders/respond.zod.js +2 -0
- package/esm/schemas/scenarios/plain_chat_input_optional.d.ts +5 -0
- package/esm/schemas/scenarios/plain_chat_input_optional.d.ts.map +1 -0
- package/esm/schemas/scenarios/plain_chat_input_optional.js +5 -0
- package/esm/schemas/scenarios/plain_chat_input_optional.zod.d.ts +3 -0
- package/esm/schemas/scenarios/plain_chat_input_optional.zod.d.ts.map +1 -0
- package/esm/schemas/scenarios/plain_chat_input_optional.zod.js +2 -0
- package/esm/schemas/scenarios/plain_chat_output.d.ts +5 -0
- package/esm/schemas/scenarios/plain_chat_output.d.ts.map +1 -0
- package/esm/schemas/scenarios/plain_chat_output.js +4 -0
- package/esm/schemas/scenarios/plain_chat_output.zod.d.ts +3 -0
- package/esm/schemas/scenarios/plain_chat_output.zod.d.ts.map +1 -0
- package/esm/schemas/scenarios/plain_chat_output.zod.js +2 -0
- package/esm/src/builtins.d.ts +2 -0
- package/esm/src/builtins.d.ts.map +1 -1
- package/esm/src/builtins.js +45 -1
- package/esm/src/loader.d.ts.map +1 -1
- package/esm/src/loader.js +58 -11
- package/esm/src/markdown.d.ts.map +1 -1
- package/esm/src/markdown.js +167 -41
- package/esm/src/permissions.d.ts +143 -0
- package/esm/src/permissions.d.ts.map +1 -0
- package/esm/src/permissions.js +406 -0
- package/esm/src/runtime.d.ts +27 -2
- package/esm/src/runtime.d.ts.map +1 -1
- package/esm/src/runtime.js +2755 -63
- package/esm/src/runtime_exec_host.d.ts +6 -0
- package/esm/src/runtime_exec_host.d.ts.map +1 -0
- package/esm/src/runtime_exec_host.js +17 -0
- package/esm/src/runtime_exec_host_contract.d.ts +23 -0
- package/esm/src/runtime_exec_host_contract.d.ts.map +1 -0
- package/esm/src/runtime_exec_host_contract.js +14 -0
- package/esm/src/runtime_exec_host_deno.d.ts +3 -0
- package/esm/src/runtime_exec_host_deno.d.ts.map +1 -0
- package/esm/src/runtime_exec_host_deno.js +35 -0
- package/esm/src/runtime_exec_host_unsupported.d.ts +3 -0
- package/esm/src/runtime_exec_host_unsupported.d.ts.map +1 -0
- package/esm/src/runtime_exec_host_unsupported.js +8 -0
- package/esm/src/runtime_worker_host.d.ts +6 -0
- package/esm/src/runtime_worker_host.d.ts.map +1 -0
- package/esm/src/runtime_worker_host.js +17 -0
- package/esm/src/runtime_worker_host_contract.d.ts +33 -0
- package/esm/src/runtime_worker_host_contract.d.ts.map +1 -0
- package/esm/src/runtime_worker_host_contract.js +14 -0
- package/esm/src/runtime_worker_host_deno.d.ts +3 -0
- package/esm/src/runtime_worker_host_deno.d.ts.map +1 -0
- package/esm/src/runtime_worker_host_deno.js +26 -0
- package/esm/src/runtime_worker_host_unsupported.d.ts +3 -0
- package/esm/src/runtime_worker_host_unsupported.d.ts.map +1 -0
- package/esm/src/runtime_worker_host_unsupported.js +8 -0
- package/esm/src/state.d.ts +1 -0
- package/esm/src/state.d.ts.map +1 -1
- package/esm/src/types.d.ts +235 -3
- package/esm/src/types.d.ts.map +1 -1
- package/package.json +73 -1
- package/schemas/graders/contexts/conversation.ts +32 -9
- package/schemas/graders/contexts/conversation.zod.ts +1 -0
- package/schemas/graders/contexts/conversation_tools.ts +63 -0
- package/schemas/graders/contexts/conversation_tools.zod.ts +1 -0
- package/schemas/graders/contexts/tools.ts +5 -0
- package/schemas/graders/contexts/tools.zod.ts +1 -0
- package/schemas/graders/contexts/turn.ts +8 -1
- package/schemas/graders/contexts/turn.zod.ts +1 -0
- package/schemas/graders/contexts/turn_tools.ts +63 -0
- package/schemas/graders/contexts/turn_tools.zod.ts +1 -0
- package/schemas/graders/grader_output.ts +9 -1
- package/schemas/graders/grader_output.zod.ts +1 -0
- package/schemas/graders/respond.ts +13 -3
- package/schemas/graders/respond.zod.ts +1 -0
- package/schemas/scenarios/plain_chat_input_optional.ts +6 -0
- package/schemas/scenarios/plain_chat_input_optional.zod.ts +1 -0
- package/schemas/scenarios/plain_chat_output.ts +5 -0
- package/schemas/scenarios/plain_chat_output.zod.ts +1 -0
- package/{esm/deps/jsr.io/@std/collections/1.1.4 → script/deps/jsr.io/@std/collections/1.1.5}/deep_merge.d.ts +2 -2
- package/script/deps/jsr.io/@std/collections/{1.1.4 → 1.1.5}/deep_merge.d.ts.map +1 -1
- package/script/deps/jsr.io/@std/collections/{1.1.4 → 1.1.5}/deep_merge.js +29 -19
- package/script/deps/jsr.io/@std/toml/1.0.11/_parser.js +1 -1
- package/script/mod.d.ts +9 -1
- package/script/mod.d.ts.map +1 -1
- package/script/mod.js +12 -1
- package/script/schemas/graders/contexts/conversation.d.ts +22 -0
- package/script/schemas/graders/contexts/conversation.d.ts.map +1 -0
- package/script/schemas/graders/contexts/conversation.js +20 -0
- package/script/schemas/graders/contexts/conversation.zod.d.ts +3 -0
- package/script/schemas/graders/contexts/conversation.zod.d.ts.map +1 -0
- package/script/schemas/graders/contexts/conversation.zod.js +9 -0
- package/script/schemas/graders/contexts/conversation_tools.d.ts +31 -0
- package/script/schemas/graders/contexts/conversation_tools.d.ts.map +1 -0
- package/script/schemas/graders/contexts/conversation_tools.js +28 -0
- package/script/schemas/graders/contexts/conversation_tools.zod.d.ts +3 -0
- package/script/schemas/graders/contexts/conversation_tools.zod.d.ts.map +1 -0
- package/script/schemas/graders/contexts/conversation_tools.zod.js +9 -0
- package/script/schemas/graders/contexts/tools.d.ts +4 -0
- package/script/schemas/graders/contexts/tools.d.ts.map +1 -0
- package/script/schemas/graders/contexts/tools.js +12 -0
- package/script/schemas/graders/contexts/tools.zod.d.ts +3 -0
- package/script/schemas/graders/contexts/tools.zod.d.ts.map +1 -0
- package/script/schemas/graders/contexts/tools.zod.js +9 -0
- package/script/schemas/graders/contexts/turn.d.ts +10 -0
- package/script/schemas/graders/contexts/turn.d.ts.map +1 -0
- package/script/schemas/graders/contexts/turn.js +10 -0
- package/script/schemas/graders/contexts/turn.zod.d.ts +3 -0
- package/script/schemas/graders/contexts/turn.zod.d.ts.map +1 -0
- package/script/schemas/graders/contexts/turn.zod.js +9 -0
- package/script/schemas/graders/contexts/turn_tools.d.ts +32 -0
- package/script/schemas/graders/contexts/turn_tools.d.ts.map +1 -0
- package/script/schemas/graders/contexts/turn_tools.js +31 -0
- package/script/schemas/graders/contexts/turn_tools.zod.d.ts +3 -0
- package/script/schemas/graders/contexts/turn_tools.zod.d.ts.map +1 -0
- package/script/schemas/graders/contexts/turn_tools.zod.js +9 -0
- package/script/schemas/graders/grader_output.d.ts +10 -0
- package/script/schemas/graders/grader_output.d.ts.map +1 -0
- package/script/schemas/graders/grader_output.js +10 -0
- package/script/schemas/graders/grader_output.zod.d.ts +3 -0
- package/script/schemas/graders/grader_output.zod.d.ts.map +1 -0
- package/script/schemas/graders/grader_output.zod.js +9 -0
- package/script/schemas/graders/respond.d.ts +12 -0
- package/script/schemas/graders/respond.d.ts.map +1 -0
- package/script/schemas/graders/respond.js +12 -0
- package/script/schemas/graders/respond.zod.d.ts +3 -0
- package/script/schemas/graders/respond.zod.d.ts.map +1 -0
- package/script/schemas/graders/respond.zod.js +9 -0
- package/script/schemas/scenarios/plain_chat_input_optional.d.ts +5 -0
- package/script/schemas/scenarios/plain_chat_input_optional.d.ts.map +1 -0
- package/script/schemas/scenarios/plain_chat_input_optional.js +7 -0
- package/script/schemas/scenarios/plain_chat_input_optional.zod.d.ts +3 -0
- package/script/schemas/scenarios/plain_chat_input_optional.zod.d.ts.map +1 -0
- package/script/schemas/scenarios/plain_chat_input_optional.zod.js +9 -0
- package/script/schemas/scenarios/plain_chat_output.d.ts +5 -0
- package/script/schemas/scenarios/plain_chat_output.d.ts.map +1 -0
- package/script/schemas/scenarios/plain_chat_output.js +6 -0
- package/script/schemas/scenarios/plain_chat_output.zod.d.ts +3 -0
- package/script/schemas/scenarios/plain_chat_output.zod.d.ts.map +1 -0
- package/script/schemas/scenarios/plain_chat_output.zod.js +9 -0
- package/script/src/builtins.d.ts +2 -0
- package/script/src/builtins.d.ts.map +1 -1
- package/script/src/builtins.js +47 -1
- package/script/src/loader.d.ts.map +1 -1
- package/script/src/loader.js +57 -10
- package/script/src/markdown.d.ts.map +1 -1
- package/script/src/markdown.js +167 -41
- package/script/src/permissions.d.ts +143 -0
- package/script/src/permissions.d.ts.map +1 -0
- package/script/src/permissions.js +453 -0
- package/script/src/runtime.d.ts +27 -2
- package/script/src/runtime.d.ts.map +1 -1
- package/script/src/runtime.js +2758 -63
- package/script/src/runtime_exec_host.d.ts +6 -0
- package/script/src/runtime_exec_host.d.ts.map +1 -0
- package/script/src/runtime_exec_host.js +56 -0
- package/script/src/runtime_exec_host_contract.d.ts +23 -0
- package/script/src/runtime_exec_host_contract.d.ts.map +1 -0
- package/script/src/runtime_exec_host_contract.js +18 -0
- package/script/src/runtime_exec_host_deno.d.ts +3 -0
- package/script/src/runtime_exec_host_deno.d.ts.map +1 -0
- package/script/src/runtime_exec_host_deno.js +71 -0
- package/script/src/runtime_exec_host_unsupported.d.ts +3 -0
- package/script/src/runtime_exec_host_unsupported.d.ts.map +1 -0
- package/script/src/runtime_exec_host_unsupported.js +11 -0
- package/script/src/runtime_worker_host.d.ts +6 -0
- package/script/src/runtime_worker_host.d.ts.map +1 -0
- package/script/src/runtime_worker_host.js +56 -0
- package/script/src/runtime_worker_host_contract.d.ts +33 -0
- package/script/src/runtime_worker_host_contract.d.ts.map +1 -0
- package/script/src/runtime_worker_host_contract.js +18 -0
- package/script/src/runtime_worker_host_deno.d.ts +3 -0
- package/script/src/runtime_worker_host_deno.d.ts.map +1 -0
- package/script/src/runtime_worker_host_deno.js +62 -0
- package/script/src/runtime_worker_host_unsupported.d.ts +3 -0
- package/script/src/runtime_worker_host_unsupported.d.ts.map +1 -0
- package/script/src/runtime_worker_host_unsupported.js +11 -0
- package/script/src/state.d.ts +1 -0
- package/script/src/state.d.ts.map +1 -1
- package/script/src/types.d.ts +235 -3
- package/script/src/types.d.ts.map +1 -1
- package/esm/deps/jsr.io/@std/collections/1.1.4/_utils.d.ts +0 -6
- package/esm/deps/jsr.io/@std/collections/1.1.4/_utils.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/collections/1.1.4/_utils.js +0 -18
- package/script/deps/jsr.io/@std/collections/1.1.4/_utils.d.ts +0 -6
- package/script/deps/jsr.io/@std/collections/1.1.4/_utils.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/collections/1.1.4/_utils.js +0 -21
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plain_chat_input_optional.d.ts","sourceRoot":"","sources":["../../../src/schemas/scenarios/plain_chat_input_optional.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,4BAA4B,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,SAAS,CACnD,CAAC;AAEd,eAAe,4BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plain_chat_input_optional.zod.d.ts","sourceRoot":"","sources":["../../../src/schemas/scenarios/plain_chat_input_optional.zod.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plain_chat_output.d.ts","sourceRoot":"","sources":["../../../src/schemas/scenarios/plain_chat_output.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,qBAAqB,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAc,CAAC;AAE5D,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plain_chat_output.zod.d.ts","sourceRoot":"","sources":["../../../src/schemas/scenarios/plain_chat_output.zod.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC"}
|
package/esm/src/builtins.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export declare function resolveBuiltinCardPath(target: string): string | undefined;
|
|
2
|
+
export declare function resolveBuiltinSnippetPath(target: string): string | undefined;
|
|
2
3
|
export declare function resolveBuiltinSchemaPath(target: string): string | undefined;
|
|
4
|
+
export declare function resolveBuiltinDeckPath(target: string): string | undefined;
|
|
3
5
|
//# sourceMappingURL=builtins.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../../src/src/builtins.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../../src/src/builtins.ts"],"names":[],"mappings":"AAqBA,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAazE;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAO5E;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAgB3E;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAgBzE"}
|
package/esm/src/builtins.js
CHANGED
|
@@ -1,26 +1,70 @@
|
|
|
1
1
|
import * as path from "../deps/jsr.io/@std/path/1.1.4/mod.js";
|
|
2
2
|
const CARDS_PREFIX = "gambit://cards/";
|
|
3
|
+
const SNIPPETS_PREFIX = "gambit://snippets/";
|
|
3
4
|
const SCHEMAS_PREFIX = "gambit://schemas/";
|
|
5
|
+
const DECKS_PREFIX = "gambit://decks/";
|
|
4
6
|
const CARDS_BASE_URL = new URL("../cards/", globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).url);
|
|
7
|
+
const SNIPPETS_BASE_URL = new URL("../snippets/", globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).url);
|
|
5
8
|
const SCHEMAS_BASE_URL = new URL("../schemas/", globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).url);
|
|
9
|
+
const DECKS_BASE_URL = new URL("../decks/", globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).url);
|
|
10
|
+
const LEGACY_CARD_WARNINGS = new Set();
|
|
11
|
+
const LEGACY_SCHEMA_WARNINGS = new Set();
|
|
12
|
+
const LEGACY_DECK_WARNINGS = new Set();
|
|
13
|
+
const logger = console;
|
|
6
14
|
function resolveFromBase(base, relative) {
|
|
7
15
|
return path.fromFileUrl(new URL(relative, base));
|
|
8
16
|
}
|
|
9
17
|
export function resolveBuiltinCardPath(target) {
|
|
10
18
|
if (!target.startsWith(CARDS_PREFIX))
|
|
11
19
|
return undefined;
|
|
20
|
+
if (!LEGACY_CARD_WARNINGS.has(target)) {
|
|
21
|
+
LEGACY_CARD_WARNINGS.add(target);
|
|
22
|
+
logger.warn(`[gambit] "${target}" is deprecated; use gambit://snippets instead.`);
|
|
23
|
+
}
|
|
12
24
|
const relative = target.slice(CARDS_PREFIX.length);
|
|
13
25
|
if (!relative) {
|
|
14
26
|
throw new Error(`Invalid gambit card specifier: ${target}`);
|
|
15
27
|
}
|
|
16
28
|
return resolveFromBase(CARDS_BASE_URL, relative);
|
|
17
29
|
}
|
|
30
|
+
export function resolveBuiltinSnippetPath(target) {
|
|
31
|
+
if (!target.startsWith(SNIPPETS_PREFIX))
|
|
32
|
+
return undefined;
|
|
33
|
+
const relative = target.slice(SNIPPETS_PREFIX.length);
|
|
34
|
+
if (!relative) {
|
|
35
|
+
throw new Error(`Invalid gambit snippet specifier: ${target}`);
|
|
36
|
+
}
|
|
37
|
+
return resolveFromBase(SNIPPETS_BASE_URL, relative);
|
|
38
|
+
}
|
|
18
39
|
export function resolveBuiltinSchemaPath(target) {
|
|
19
40
|
if (!target.startsWith(SCHEMAS_PREFIX))
|
|
20
41
|
return undefined;
|
|
21
|
-
|
|
42
|
+
let relative = target.slice(SCHEMAS_PREFIX.length);
|
|
22
43
|
if (!relative) {
|
|
23
44
|
throw new Error(`Invalid gambit schema specifier: ${target}`);
|
|
24
45
|
}
|
|
46
|
+
if (relative.endsWith(".ts") && !relative.endsWith(".zod.ts")) {
|
|
47
|
+
if (!LEGACY_SCHEMA_WARNINGS.has(target)) {
|
|
48
|
+
LEGACY_SCHEMA_WARNINGS.add(target);
|
|
49
|
+
logger.warn(`[gambit] "${target}" is deprecated; use .zod.ts schema URIs instead.`);
|
|
50
|
+
}
|
|
51
|
+
relative = `${relative.slice(0, -3)}.zod.ts`;
|
|
52
|
+
}
|
|
25
53
|
return resolveFromBase(SCHEMAS_BASE_URL, relative);
|
|
26
54
|
}
|
|
55
|
+
export function resolveBuiltinDeckPath(target) {
|
|
56
|
+
if (!target.startsWith(DECKS_PREFIX))
|
|
57
|
+
return undefined;
|
|
58
|
+
let relative = target.slice(DECKS_PREFIX.length);
|
|
59
|
+
if (!relative) {
|
|
60
|
+
throw new Error(`Invalid gambit deck specifier: ${target}`);
|
|
61
|
+
}
|
|
62
|
+
if (!relative.endsWith("/PROMPT.md")) {
|
|
63
|
+
if (!LEGACY_DECK_WARNINGS.has(target)) {
|
|
64
|
+
LEGACY_DECK_WARNINGS.add(target);
|
|
65
|
+
logger.warn(`[gambit] "${target}" is deprecated; use gambit://decks/.../PROMPT.md instead.`);
|
|
66
|
+
}
|
|
67
|
+
relative = `${relative.replace(/\/?$/, "/")}PROMPT.md`;
|
|
68
|
+
}
|
|
69
|
+
return resolveFromBase(DECKS_BASE_URL, relative);
|
|
70
|
+
}
|
package/esm/src/loader.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/src/loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/src/loader.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAMV,UAAU,EACV,UAAU,EAEX,MAAM,YAAY,CAAC;AAiPpB,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,KAAK,GAAE,KAAK,CAAC,MAAM,CAAM,GACxB,OAAO,CAAC,UAAU,CAAC,CAQrB;AAED,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,CAAC,CA4JrB"}
|
package/esm/src/loader.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import * as dntShim from "../_dnt.shims.js";
|
|
1
2
|
import * as path from "../deps/jsr.io/@std/path/1.1.4/mod.js";
|
|
2
3
|
import { BUILTIN_TOOL_NAME_SET, MAX_TOOL_NAME_LENGTH, RESERVED_TOOL_PREFIX, TOOL_NAME_PATTERN, } from "./constants.js";
|
|
3
4
|
import { isCardDefinition, isDeckDefinition } from "./definitions.js";
|
|
5
|
+
import { normalizePermissionDeclaration, } from "./permissions.js";
|
|
4
6
|
import { mergeZodObjects } from "./schema.js";
|
|
5
7
|
import { isMarkdownFile, loadMarkdownCard, loadMarkdownDeck, } from "./markdown.js";
|
|
6
|
-
import { resolveBuiltinCardPath } from "./builtins.js";
|
|
8
|
+
import { resolveBuiltinCardPath, resolveBuiltinDeckPath, resolveBuiltinSnippetPath, } from "./builtins.js";
|
|
7
9
|
const logger = console;
|
|
8
10
|
const LEGACY_SCHEMA_WARNINGS = new Set();
|
|
9
11
|
const LEGACY_FRAGMENT_WARNINGS = new Set();
|
|
@@ -62,7 +64,10 @@ function normalizeActionDecks(actions, basePath) {
|
|
|
62
64
|
return [];
|
|
63
65
|
return actions.map((a) => ({
|
|
64
66
|
...a,
|
|
65
|
-
path:
|
|
67
|
+
path: a.path.startsWith("gambit://") || !basePath
|
|
68
|
+
? a.path
|
|
69
|
+
: path.resolve(path.dirname(basePath), a.path),
|
|
70
|
+
permissions: normalizePermissionDeclaration(a.permissions, basePath ? path.dirname(basePath) : dntShim.Deno.cwd()),
|
|
66
71
|
}));
|
|
67
72
|
}
|
|
68
73
|
function normalizeCompanionDecks(decks, basePath) {
|
|
@@ -70,9 +75,10 @@ function normalizeCompanionDecks(decks, basePath) {
|
|
|
70
75
|
return [];
|
|
71
76
|
return decks.map((deck) => ({
|
|
72
77
|
...deck,
|
|
73
|
-
path: basePath
|
|
74
|
-
?
|
|
75
|
-
: deck.path,
|
|
78
|
+
path: deck.path.startsWith("gambit://") || !basePath
|
|
79
|
+
? deck.path
|
|
80
|
+
: path.resolve(path.dirname(basePath), deck.path),
|
|
81
|
+
permissions: normalizePermissionDeclaration(deck.permissions, basePath ? path.dirname(basePath) : dntShim.Deno.cwd()),
|
|
76
82
|
}));
|
|
77
83
|
}
|
|
78
84
|
function checkReserved(action) {
|
|
@@ -85,6 +91,30 @@ function checkReserved(action) {
|
|
|
85
91
|
throw new Error(`Action name ${action.name} must match ${TOOL_NAME_PATTERN} and be <= ${MAX_TOOL_NAME_LENGTH} characters`);
|
|
86
92
|
}
|
|
87
93
|
}
|
|
94
|
+
function normalizeExternalTools(tools, resolvedPath) {
|
|
95
|
+
if (!tools)
|
|
96
|
+
return [];
|
|
97
|
+
return tools.map((tool) => {
|
|
98
|
+
const name = String(tool.name ?? "").trim();
|
|
99
|
+
if (!name) {
|
|
100
|
+
throw new Error(`External tool must include a name (${resolvedPath})`);
|
|
101
|
+
}
|
|
102
|
+
if (name.startsWith(RESERVED_TOOL_PREFIX)) {
|
|
103
|
+
throw new Error(`External tool name ${name} is reserved (prefix ${RESERVED_TOOL_PREFIX})`);
|
|
104
|
+
}
|
|
105
|
+
if (!TOOL_NAME_PATTERN.test(name) ||
|
|
106
|
+
name.length > MAX_TOOL_NAME_LENGTH) {
|
|
107
|
+
throw new Error(`External tool name ${name} must match ${TOOL_NAME_PATTERN} and be <= ${MAX_TOOL_NAME_LENGTH} characters`);
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
name,
|
|
111
|
+
description: typeof tool.description === "string"
|
|
112
|
+
? tool.description
|
|
113
|
+
: undefined,
|
|
114
|
+
inputSchema: tool.inputSchema,
|
|
115
|
+
};
|
|
116
|
+
});
|
|
117
|
+
}
|
|
88
118
|
async function loadCardInternal(cardPath, parentPath, stack = []) {
|
|
89
119
|
const resolved = parentPath
|
|
90
120
|
? path.resolve(path.dirname(parentPath), cardPath)
|
|
@@ -120,28 +150,36 @@ async function loadCardInternal(cardPath, parentPath, stack = []) {
|
|
|
120
150
|
path: resolved,
|
|
121
151
|
cards: [],
|
|
122
152
|
...fragments,
|
|
153
|
+
permissions: normalizePermissionDeclaration(card.permissions, path.dirname(resolved)),
|
|
123
154
|
};
|
|
124
155
|
}
|
|
125
156
|
export async function loadCard(cardPath, parentPath, stack = []) {
|
|
126
157
|
const builtinPath = resolveBuiltinCardPath(cardPath);
|
|
127
|
-
const
|
|
158
|
+
const snippetPath = resolveBuiltinSnippetPath(cardPath);
|
|
159
|
+
const normalizedPath = snippetPath ?? builtinPath ?? cardPath;
|
|
128
160
|
if (isMarkdownFile(normalizedPath)) {
|
|
129
161
|
return await loadMarkdownCard(normalizedPath, parentPath, stack);
|
|
130
162
|
}
|
|
131
163
|
return await loadCardInternal(normalizedPath, parentPath, stack);
|
|
132
164
|
}
|
|
133
165
|
export async function loadDeck(deckPath, parentPath) {
|
|
134
|
-
|
|
135
|
-
|
|
166
|
+
const builtinDeck = resolveBuiltinDeckPath(deckPath);
|
|
167
|
+
const normalizedDeckPath = builtinDeck ?? deckPath;
|
|
168
|
+
const markdownParent = builtinDeck ? undefined : parentPath;
|
|
169
|
+
if (isMarkdownFile(normalizedDeckPath)) {
|
|
170
|
+
return await loadMarkdownDeck(normalizedDeckPath, markdownParent);
|
|
136
171
|
}
|
|
137
|
-
const resolved =
|
|
138
|
-
? path.resolve(path.dirname(
|
|
139
|
-
: path.resolve(
|
|
172
|
+
const resolved = markdownParent
|
|
173
|
+
? path.resolve(path.dirname(markdownParent), normalizedDeckPath)
|
|
174
|
+
: path.resolve(normalizedDeckPath);
|
|
140
175
|
const mod = await import(toFileUrl(resolved));
|
|
141
176
|
const deck = mod.default;
|
|
142
177
|
if (!isDeckDefinition(deck)) {
|
|
143
178
|
throw new Error(`Deck at ${resolved} did not export a valid deck definition`);
|
|
144
179
|
}
|
|
180
|
+
if (deck.mcpServers !== undefined) {
|
|
181
|
+
throw new Error(`Deck-level [[mcpServers]] is unsupported in this phase (${resolved})`);
|
|
182
|
+
}
|
|
145
183
|
const deckLabel = deck.label;
|
|
146
184
|
const cards = [];
|
|
147
185
|
const mergedActions = {};
|
|
@@ -161,6 +199,13 @@ export async function loadDeck(deckPath, parentPath) {
|
|
|
161
199
|
mergedActions[action.name] = action;
|
|
162
200
|
}
|
|
163
201
|
const actionDecks = Object.values(mergedActions);
|
|
202
|
+
const tools = normalizeExternalTools(deck.tools, resolved);
|
|
203
|
+
const actionNames = new Set(actionDecks.map((action) => action.name));
|
|
204
|
+
for (const tool of tools) {
|
|
205
|
+
if (actionNames.has(tool.name)) {
|
|
206
|
+
logger.warn(`[gambit] tool ${tool.name} is shadowed by an action in ${resolved}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
164
209
|
const schemaAliases = normalizeDeckSchemas(deck, resolved);
|
|
165
210
|
let inputSchema = schemaAliases.inputSchema;
|
|
166
211
|
let outputSchema = schemaAliases.outputSchema;
|
|
@@ -220,6 +265,7 @@ export async function loadDeck(deckPath, parentPath) {
|
|
|
220
265
|
actions: actionDecks,
|
|
221
266
|
testDecks: normalizeCompanionDecks(deck.testDecks, resolved),
|
|
222
267
|
graderDecks: normalizeCompanionDecks(deck.graderDecks, resolved),
|
|
268
|
+
tools,
|
|
223
269
|
contextSchema,
|
|
224
270
|
responseSchema,
|
|
225
271
|
inputSchema,
|
|
@@ -227,6 +273,7 @@ export async function loadDeck(deckPath, parentPath) {
|
|
|
227
273
|
executor,
|
|
228
274
|
handlers,
|
|
229
275
|
respond: deck.respond,
|
|
276
|
+
permissions: normalizePermissionDeclaration(deck.permissions, path.dirname(resolved)),
|
|
230
277
|
};
|
|
231
278
|
}
|
|
232
279
|
function flattenCards(cards) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/src/markdown.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/src/markdown.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAKV,UAAU,EACV,UAAU,EAEX,MAAM,YAAY,CAAC;AAuVpB,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,KAAK,GAAE,KAAK,CAAC,MAAM,CAAM,GACxB,OAAO,CAAC,UAAU,CAAC,CAsGrB;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,CAAC,CAqPrB;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAExD"}
|
package/esm/src/markdown.js
CHANGED
|
@@ -4,6 +4,7 @@ import * as path from "../deps/jsr.io/@std/path/1.1.4/mod.js";
|
|
|
4
4
|
import { BUILTIN_TOOL_NAME_SET, GAMBIT_TOOL_CONTEXT, GAMBIT_TOOL_END, GAMBIT_TOOL_RESPOND, MAX_TOOL_NAME_LENGTH, RESERVED_TOOL_PREFIX, TOOL_NAME_PATTERN, } from "./constants.js";
|
|
5
5
|
import { isCardDefinition } from "./definitions.js";
|
|
6
6
|
import { loadCard } from "./loader.js";
|
|
7
|
+
import { normalizePermissionDeclaration, } from "./permissions.js";
|
|
7
8
|
import { mergeZodObjects } from "./schema.js";
|
|
8
9
|
import { resolveBuiltinSchemaPath } from "./builtins.js";
|
|
9
10
|
const logger = console;
|
|
@@ -50,6 +51,23 @@ function toFileUrl(p) {
|
|
|
50
51
|
const abs = path.resolve(p);
|
|
51
52
|
return path.toFileUrl(abs).href;
|
|
52
53
|
}
|
|
54
|
+
function startsWithFrontMatterDelimiter(raw) {
|
|
55
|
+
const normalized = raw.startsWith("\uFEFF") ? raw.slice(1) : raw;
|
|
56
|
+
const trimmed = normalized.trimStart();
|
|
57
|
+
return /^(\+\+\+|---)\s*(\r?\n|$)/.test(trimmed);
|
|
58
|
+
}
|
|
59
|
+
function parseFrontMatterOrRaw(raw, resolvedPath) {
|
|
60
|
+
try {
|
|
61
|
+
return extract(raw);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
if (!startsWithFrontMatterDelimiter(raw)) {
|
|
65
|
+
return { attrs: {}, body: raw };
|
|
66
|
+
}
|
|
67
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
68
|
+
throw new Error(`Failed to parse front matter in ${resolvedPath}: ${message}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
53
71
|
async function maybeLoadSchema(schemaPath, basePath) {
|
|
54
72
|
if (!schemaPath || typeof schemaPath !== "string")
|
|
55
73
|
return undefined;
|
|
@@ -59,7 +77,7 @@ async function maybeLoadSchema(schemaPath, basePath) {
|
|
|
59
77
|
const mod = await import(toFileUrl(resolved));
|
|
60
78
|
return mod.default;
|
|
61
79
|
}
|
|
62
|
-
function normalizeDeckRefs(refs, basePath) {
|
|
80
|
+
function normalizeDeckRefs(refs, basePath, opts) {
|
|
63
81
|
if (!Array.isArray(refs))
|
|
64
82
|
return [];
|
|
65
83
|
return refs
|
|
@@ -70,14 +88,32 @@ function normalizeDeckRefs(refs, basePath) {
|
|
|
70
88
|
if (!p) {
|
|
71
89
|
throw new Error("Deck reference must include a path");
|
|
72
90
|
}
|
|
91
|
+
if (opts?.requirePrompt && !p.endsWith("PROMPT.md")) {
|
|
92
|
+
throw new Error(`Deck reference must point to PROMPT.md (${basePath})`);
|
|
93
|
+
}
|
|
73
94
|
const normalized = { ...rec };
|
|
74
|
-
normalized.path =
|
|
95
|
+
normalized.path = p.startsWith("gambit://")
|
|
96
|
+
? p
|
|
97
|
+
: path.resolve(path.dirname(basePath), p);
|
|
75
98
|
if (typeof rec.description !== "string")
|
|
76
99
|
delete normalized.description;
|
|
77
100
|
if (typeof rec.label !== "string")
|
|
78
101
|
delete normalized.label;
|
|
79
102
|
if (typeof rec.id !== "string")
|
|
80
103
|
delete normalized.id;
|
|
104
|
+
if (rec.permissions !== undefined) {
|
|
105
|
+
const parsed = normalizePermissionDeclaration(rec.permissions, path.dirname(basePath));
|
|
106
|
+
if (parsed)
|
|
107
|
+
normalized.permissions = parsed;
|
|
108
|
+
}
|
|
109
|
+
if (opts?.requireDescription) {
|
|
110
|
+
const desc = typeof rec.description === "string"
|
|
111
|
+
? rec.description.trim()
|
|
112
|
+
: "";
|
|
113
|
+
if (!desc) {
|
|
114
|
+
throw new Error(`Action deck must include a description (${basePath})`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
81
117
|
return normalized;
|
|
82
118
|
});
|
|
83
119
|
}
|
|
@@ -94,14 +130,92 @@ function mergeDeckRefs(...lists) {
|
|
|
94
130
|
}
|
|
95
131
|
return Array.from(merged.values());
|
|
96
132
|
}
|
|
97
|
-
function normalizeActionDecks(entries, basePath) {
|
|
98
|
-
|
|
99
|
-
|
|
133
|
+
async function normalizeActionDecks(entries, basePath, opts) {
|
|
134
|
+
if (!Array.isArray(entries))
|
|
135
|
+
return [];
|
|
136
|
+
const out = [];
|
|
137
|
+
for (const rawEntry of entries) {
|
|
138
|
+
if (!rawEntry || typeof rawEntry !== "object")
|
|
139
|
+
continue;
|
|
140
|
+
const rec = rawEntry;
|
|
141
|
+
const name = String(rec.name ?? "").trim();
|
|
100
142
|
if (!name) {
|
|
101
143
|
throw new Error(`Action deck must include a name (${basePath})`);
|
|
102
144
|
}
|
|
103
|
-
|
|
104
|
-
|
|
145
|
+
const desc = typeof rec.description === "string"
|
|
146
|
+
? rec.description.trim()
|
|
147
|
+
: "";
|
|
148
|
+
if (opts?.requireDescription && !desc) {
|
|
149
|
+
throw new Error(`Action deck must include a description (${basePath})`);
|
|
150
|
+
}
|
|
151
|
+
const rawPath = typeof rec.path === "string" ? rec.path.trim() : "";
|
|
152
|
+
const rawExecute = typeof rec.execute === "string"
|
|
153
|
+
? rec.execute.trim()
|
|
154
|
+
: "";
|
|
155
|
+
const hasPath = rawPath.length > 0;
|
|
156
|
+
const hasExecute = rawExecute.length > 0;
|
|
157
|
+
if (hasPath === hasExecute) {
|
|
158
|
+
throw new Error(`Action deck must include exactly one of path or execute (${basePath})`);
|
|
159
|
+
}
|
|
160
|
+
if (hasPath && opts?.requirePrompt && !rawPath.endsWith("PROMPT.md")) {
|
|
161
|
+
throw new Error(`Deck reference must point to PROMPT.md (${basePath})`);
|
|
162
|
+
}
|
|
163
|
+
const actionContextSchema = await maybeLoadSchema(rec.contextSchema, basePath);
|
|
164
|
+
const actionResponseSchema = await maybeLoadSchema(rec.responseSchema, basePath);
|
|
165
|
+
if (hasExecute && (!actionContextSchema || !actionResponseSchema)) {
|
|
166
|
+
throw new Error(`Action execute target must include contextSchema and responseSchema (${basePath})`);
|
|
167
|
+
}
|
|
168
|
+
const selectedTarget = hasPath ? rawPath : rawExecute;
|
|
169
|
+
const normalizedPath = selectedTarget.startsWith("gambit://")
|
|
170
|
+
? selectedTarget
|
|
171
|
+
: path.resolve(path.dirname(basePath), selectedTarget);
|
|
172
|
+
const normalized = {
|
|
173
|
+
name,
|
|
174
|
+
path: normalizedPath,
|
|
175
|
+
description: desc || undefined,
|
|
176
|
+
label: typeof rec.label === "string" ? rec.label : undefined,
|
|
177
|
+
id: typeof rec.id === "string" ? rec.id : undefined,
|
|
178
|
+
execute: hasExecute ? normalizedPath : undefined,
|
|
179
|
+
contextSchema: actionContextSchema,
|
|
180
|
+
responseSchema: actionResponseSchema,
|
|
181
|
+
};
|
|
182
|
+
if (rec.permissions !== undefined) {
|
|
183
|
+
const parsed = normalizePermissionDeclaration(rec.permissions, path.dirname(basePath));
|
|
184
|
+
if (parsed)
|
|
185
|
+
normalized.permissions = parsed;
|
|
186
|
+
}
|
|
187
|
+
out.push(normalized);
|
|
188
|
+
}
|
|
189
|
+
return out;
|
|
190
|
+
}
|
|
191
|
+
async function normalizeExternalTools(refs, basePath) {
|
|
192
|
+
if (!Array.isArray(refs))
|
|
193
|
+
return [];
|
|
194
|
+
const out = [];
|
|
195
|
+
for (const entry of refs) {
|
|
196
|
+
if (!entry || typeof entry !== "object")
|
|
197
|
+
continue;
|
|
198
|
+
const rec = entry;
|
|
199
|
+
const name = String(rec.name ?? "").trim();
|
|
200
|
+
if (!name) {
|
|
201
|
+
throw new Error(`External tool must include a name (${basePath})`);
|
|
202
|
+
}
|
|
203
|
+
if (name.startsWith(RESERVED_TOOL_PREFIX)) {
|
|
204
|
+
throw new Error(`External tool name ${name} is reserved (prefix ${RESERVED_TOOL_PREFIX})`);
|
|
205
|
+
}
|
|
206
|
+
if (!TOOL_NAME_PATTERN.test(name) || name.length > MAX_TOOL_NAME_LENGTH) {
|
|
207
|
+
throw new Error(`External tool name ${name} must match ${TOOL_NAME_PATTERN} and be <= ${MAX_TOOL_NAME_LENGTH} characters`);
|
|
208
|
+
}
|
|
209
|
+
const inputSchema = await maybeLoadSchema(rec.inputSchema, basePath);
|
|
210
|
+
out.push({
|
|
211
|
+
name,
|
|
212
|
+
description: typeof rec.description === "string"
|
|
213
|
+
? rec.description
|
|
214
|
+
: undefined,
|
|
215
|
+
inputSchema,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return out;
|
|
105
219
|
}
|
|
106
220
|
async function expandEmbedsInBody(args) {
|
|
107
221
|
const { body, resolvedPath, stack } = args;
|
|
@@ -117,17 +231,17 @@ async function expandEmbedsInBody(args) {
|
|
|
117
231
|
const target = match[1];
|
|
118
232
|
out += body.slice(lastIndex, matchIndex);
|
|
119
233
|
if (target === RESPOND_MARKER) {
|
|
120
|
-
warnLegacyMarker("respond", "gambit://
|
|
234
|
+
warnLegacyMarker("respond", "gambit://snippets/respond.md");
|
|
121
235
|
respond = true;
|
|
122
236
|
out += RESPOND_TEXT;
|
|
123
237
|
}
|
|
124
238
|
else if (target === INIT_MARKER) {
|
|
125
|
-
warnLegacyMarker("init", "gambit://
|
|
239
|
+
warnLegacyMarker("init", "gambit://snippets/context.md");
|
|
126
240
|
initHint = true;
|
|
127
241
|
out += INIT_TEXT;
|
|
128
242
|
}
|
|
129
243
|
else if (target === END_MARKER) {
|
|
130
|
-
warnLegacyMarker("end", "gambit://
|
|
244
|
+
warnLegacyMarker("end", "gambit://snippets/end.md");
|
|
131
245
|
endHint = true;
|
|
132
246
|
out += END_TEXT;
|
|
133
247
|
}
|
|
@@ -151,17 +265,7 @@ export async function loadMarkdownCard(filePath, parentPath, stack = []) {
|
|
|
151
265
|
}
|
|
152
266
|
const nextStack = [...stack, resolved];
|
|
153
267
|
const raw = await dntShim.Deno.readTextFile(resolved);
|
|
154
|
-
|
|
155
|
-
let body;
|
|
156
|
-
try {
|
|
157
|
-
const parsed = extract(raw);
|
|
158
|
-
attrs = parsed.attrs;
|
|
159
|
-
body = parsed.body;
|
|
160
|
-
}
|
|
161
|
-
catch (err) {
|
|
162
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
163
|
-
throw new Error(`Failed to parse front matter in ${resolved}: ${message}`);
|
|
164
|
-
}
|
|
268
|
+
const { attrs, body } = parseFrontMatterOrRaw(raw, resolved);
|
|
165
269
|
const candidate = attrs;
|
|
166
270
|
if (isCardDefinition(candidate)) {
|
|
167
271
|
// treat attrs as ts-shaped card
|
|
@@ -171,7 +275,7 @@ export async function loadMarkdownCard(filePath, parentPath, stack = []) {
|
|
|
171
275
|
}
|
|
172
276
|
const hasNewActionField = attrs.actionDecks;
|
|
173
277
|
const legacyActions = attrs.actions;
|
|
174
|
-
const actionDecks = normalizeActionDecks(hasNewActionField ?? legacyActions, resolved);
|
|
278
|
+
const actionDecks = await normalizeActionDecks(hasNewActionField ?? legacyActions, resolved);
|
|
175
279
|
if (!hasNewActionField && legacyActions) {
|
|
176
280
|
logger.warn(`[gambit] card at ${resolved} uses deprecated "actions"; rename to "actionDecks"`);
|
|
177
281
|
}
|
|
@@ -205,6 +309,7 @@ export async function loadMarkdownCard(filePath, parentPath, stack = []) {
|
|
|
205
309
|
const embeddedCards = replaced.embeds;
|
|
206
310
|
const respondFlag = Boolean(attrs.respond);
|
|
207
311
|
const allowEndFlag = Boolean(attrs.allowEnd);
|
|
312
|
+
const permissions = normalizePermissionDeclaration(attrs.permissions, path.dirname(resolved));
|
|
208
313
|
return {
|
|
209
314
|
kind: "gambit.card",
|
|
210
315
|
path: resolved,
|
|
@@ -215,6 +320,7 @@ export async function loadMarkdownCard(filePath, parentPath, stack = []) {
|
|
|
215
320
|
testDecks: normalizeDeckRefs(attrs.testDecks, resolved),
|
|
216
321
|
graderDecks: normalizeDeckRefs(attrs.graderDecks, resolved),
|
|
217
322
|
cards: embeddedCards,
|
|
323
|
+
permissions,
|
|
218
324
|
contextFragment,
|
|
219
325
|
responseFragment,
|
|
220
326
|
inputFragment: contextFragment,
|
|
@@ -227,26 +333,35 @@ export async function loadMarkdownDeck(filePath, parentPath) {
|
|
|
227
333
|
? path.resolve(path.dirname(parentPath), filePath)
|
|
228
334
|
: path.resolve(filePath);
|
|
229
335
|
const raw = await dntShim.Deno.readTextFile(resolved);
|
|
230
|
-
|
|
231
|
-
let body;
|
|
232
|
-
try {
|
|
233
|
-
const parsed = extract(raw);
|
|
234
|
-
attrs = parsed.attrs;
|
|
235
|
-
body = parsed.body;
|
|
236
|
-
}
|
|
237
|
-
catch (err) {
|
|
238
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
239
|
-
throw new Error(`Failed to parse front matter in ${resolved}: ${message}`);
|
|
240
|
-
}
|
|
336
|
+
const { attrs, body } = parseFrontMatterOrRaw(raw, resolved);
|
|
241
337
|
const deckAttrs = attrs;
|
|
242
338
|
const deckMeta = (deckAttrs.deck ?? deckAttrs);
|
|
339
|
+
if (deckMeta.mcpServers !== undefined) {
|
|
340
|
+
throw new Error(`Deck-level [[mcpServers]] is unsupported in this phase (${resolved})`);
|
|
341
|
+
}
|
|
342
|
+
if (deckMeta.execute !== undefined) {
|
|
343
|
+
throw new Error(`Top-level execute in PROMPT.md is unsupported (${resolved})`);
|
|
344
|
+
}
|
|
243
345
|
const hasNewActionDecks = deckMeta.actionDecks;
|
|
244
|
-
const
|
|
245
|
-
const actionDecks = normalizeActionDecks(
|
|
246
|
-
|
|
247
|
-
|
|
346
|
+
const canonicalActions = deckMeta.actions;
|
|
347
|
+
const actionDecks = await normalizeActionDecks(canonicalActions, resolved, {
|
|
348
|
+
requirePrompt: true,
|
|
349
|
+
requireDescription: true,
|
|
350
|
+
});
|
|
351
|
+
const legacyActionDecks = await normalizeActionDecks(hasNewActionDecks, resolved);
|
|
352
|
+
if (hasNewActionDecks) {
|
|
353
|
+
logger.warn(`[gambit] deck at ${resolved} uses deprecated "actionDecks"; use "[[actions]]" instead.`);
|
|
248
354
|
}
|
|
249
|
-
|
|
355
|
+
if (deckMeta.testDecks) {
|
|
356
|
+
logger.warn(`[gambit] deck at ${resolved} uses deprecated "testDecks"; use "[[scenarios]]" instead.`);
|
|
357
|
+
}
|
|
358
|
+
if (deckMeta.graderDecks) {
|
|
359
|
+
logger.warn(`[gambit] deck at ${resolved} uses deprecated "graderDecks"; use "[[graders]]" instead.`);
|
|
360
|
+
}
|
|
361
|
+
const scenarioDecks = normalizeDeckRefs(deckMeta.scenarios, resolved, { requirePrompt: true });
|
|
362
|
+
const graderDecks = normalizeDeckRefs(deckMeta.graders, resolved, { requirePrompt: true });
|
|
363
|
+
const allActionDecks = [...actionDecks, ...legacyActionDecks];
|
|
364
|
+
allActionDecks.forEach((a) => {
|
|
250
365
|
if (a.name.startsWith(RESERVED_TOOL_PREFIX) &&
|
|
251
366
|
!BUILTIN_TOOL_NAME_SET.has(a.name)) {
|
|
252
367
|
throw new Error(`Action name ${a.name} is reserved`);
|
|
@@ -284,7 +399,7 @@ export async function loadMarkdownDeck(filePath, parentPath) {
|
|
|
284
399
|
mergedActions[action.name] = action;
|
|
285
400
|
}
|
|
286
401
|
}
|
|
287
|
-
for (const action of
|
|
402
|
+
for (const action of allActionDecks) {
|
|
288
403
|
mergedActions[action.name] = action;
|
|
289
404
|
}
|
|
290
405
|
let mergedContextSchema = contextSchema;
|
|
@@ -327,10 +442,18 @@ export async function loadMarkdownDeck(filePath, parentPath) {
|
|
|
327
442
|
}
|
|
328
443
|
: undefined;
|
|
329
444
|
const mergedActionDecks = Object.values(mergedActions);
|
|
445
|
+
const tools = await normalizeExternalTools(deckMeta.tools, resolved);
|
|
446
|
+
const actionNameSet = new Set(mergedActionDecks.map((action) => action.name));
|
|
447
|
+
for (const tool of tools) {
|
|
448
|
+
if (actionNameSet.has(tool.name)) {
|
|
449
|
+
logger.warn(`[gambit] tool ${tool.name} is shadowed by an action in ${resolved}`);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
330
452
|
const rootTestDecks = normalizeDeckRefs(deckMeta.testDecks, resolved);
|
|
331
453
|
const rootGraderDecks = normalizeDeckRefs(deckMeta.graderDecks, resolved);
|
|
332
454
|
const embeddedTestDecks = allCards.flatMap((card) => card.testDecks ?? []);
|
|
333
455
|
const embeddedGraderDecks = allCards.flatMap((card) => card.graderDecks ?? []);
|
|
456
|
+
const permissions = normalizePermissionDeclaration(deckMeta.permissions, path.dirname(resolved));
|
|
334
457
|
return {
|
|
335
458
|
kind: "gambit.deck",
|
|
336
459
|
path: resolved,
|
|
@@ -338,8 +461,9 @@ export async function loadMarkdownDeck(filePath, parentPath) {
|
|
|
338
461
|
allowEnd,
|
|
339
462
|
actionDecks: mergedActionDecks,
|
|
340
463
|
actions: mergedActionDecks,
|
|
341
|
-
|
|
342
|
-
|
|
464
|
+
tools,
|
|
465
|
+
testDecks: mergeDeckRefs(scenarioDecks, rootTestDecks, embeddedTestDecks),
|
|
466
|
+
graderDecks: mergeDeckRefs(graderDecks, rootGraderDecks, embeddedGraderDecks),
|
|
343
467
|
cards: allCards,
|
|
344
468
|
label: deckMeta.label,
|
|
345
469
|
startMode: deckMeta.startMode,
|
|
@@ -349,11 +473,13 @@ export async function loadMarkdownDeck(filePath, parentPath) {
|
|
|
349
473
|
responseSchema: mergedResponseSchema,
|
|
350
474
|
inputSchema: mergedInputSchema,
|
|
351
475
|
outputSchema: mergedOutputSchema,
|
|
476
|
+
executor: undefined,
|
|
352
477
|
handlers,
|
|
353
478
|
respond: Boolean(deckMeta.respond) ||
|
|
354
479
|
replaced.respond ||
|
|
355
480
|
allCards.some((c) => c.respond),
|
|
356
481
|
inlineEmbeds: true,
|
|
482
|
+
permissions,
|
|
357
483
|
};
|
|
358
484
|
}
|
|
359
485
|
export function isMarkdownFile(filePath) {
|