@bolt-foundry/gambit-core 0.8.1 → 0.8.5-rc.3
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 +60 -34
- package/cards/context.card.md +5 -5
- package/cards/generate-test-input.card.md +12 -0
- 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 +20 -10
- package/esm/mod.d.ts.map +1 -1
- package/esm/mod.js +11 -5
- 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/constants.d.ts +4 -0
- package/esm/src/constants.d.ts.map +1 -1
- package/esm/src/constants.js +5 -0
- package/esm/src/definitions.d.ts +5 -1
- package/esm/src/definitions.d.ts.map +1 -1
- package/esm/src/loader.d.ts.map +1 -1
- package/esm/src/loader.js +119 -13
- package/esm/src/markdown.d.ts.map +1 -1
- package/esm/src/markdown.js +222 -53
- 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/render.d.ts.map +1 -1
- package/esm/src/render.js +22 -8
- package/esm/src/runtime.d.ts +28 -2
- package/esm/src/runtime.d.ts.map +1 -1
- package/esm/src/runtime.js +3051 -100
- 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 +4 -1
- package/esm/src/state.d.ts.map +1 -1
- package/esm/src/state.js +48 -2
- package/esm/src/types.d.ts +381 -1
- package/esm/src/types.d.ts.map +1 -1
- package/esm/src/types.js +102 -1
- package/package.json +73 -2
- 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 +15 -0
- 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 +20 -10
- package/script/mod.d.ts.map +1 -1
- package/script/mod.js +25 -9
- 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/constants.d.ts +4 -0
- package/script/src/constants.d.ts.map +1 -1
- package/script/src/constants.js +6 -1
- package/script/src/definitions.d.ts +5 -1
- package/script/src/definitions.d.ts.map +1 -1
- package/script/src/loader.d.ts.map +1 -1
- package/script/src/loader.js +118 -12
- package/script/src/markdown.d.ts.map +1 -1
- package/script/src/markdown.js +221 -52
- 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/render.d.ts.map +1 -1
- package/script/src/render.js +22 -8
- package/script/src/runtime.d.ts +28 -2
- package/script/src/runtime.d.ts.map +1 -1
- package/script/src/runtime.js +3053 -99
- 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 +4 -1
- package/script/src/state.d.ts.map +1 -1
- package/script/src/state.js +48 -2
- package/script/src/types.d.ts +381 -1
- package/script/src/types.d.ts.map +1 -1
- package/script/src/types.js +103 -0
- 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/esm/src/openai_compat.d.ts +0 -63
- package/esm/src/openai_compat.d.ts.map +0 -1
- package/esm/src/openai_compat.js +0 -272
- package/esm/src/providers/openrouter.d.ts +0 -8
- package/esm/src/providers/openrouter.d.ts.map +0 -1
- package/esm/src/providers/openrouter.js +0 -168
- 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
- package/script/src/openai_compat.d.ts +0 -63
- package/script/src/openai_compat.d.ts.map +0 -1
- package/script/src/openai_compat.js +0 -276
- package/script/src/providers/openrouter.d.ts +0 -8
- package/script/src/providers/openrouter.d.ts.map +0 -1
- package/script/src/providers/openrouter.js +0 -207
package/esm/src/markdown.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as dntShim from "../_dnt.shims.js";
|
|
2
2
|
import { extract } from "../deps/jsr.io/@std/front-matter/1.0.9/any.js";
|
|
3
3
|
import * as path from "../deps/jsr.io/@std/path/1.1.4/mod.js";
|
|
4
|
-
import { BUILTIN_TOOL_NAME_SET,
|
|
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;
|
|
@@ -15,8 +16,10 @@ const LEGACY_MARKER_WARNINGS = {
|
|
|
15
16
|
init: false,
|
|
16
17
|
end: false,
|
|
17
18
|
};
|
|
19
|
+
const LEGACY_SCHEMA_WARNINGS = new Set();
|
|
20
|
+
const LEGACY_FRAGMENT_WARNINGS = new Set();
|
|
18
21
|
const INIT_TEXT = `
|
|
19
|
-
You will automatically receive a \`${
|
|
22
|
+
You will automatically receive a \`${GAMBIT_TOOL_CONTEXT}\` tool result at the start that provides run/context info.
|
|
20
23
|
`.trim();
|
|
21
24
|
const RESPOND_TEXT = `
|
|
22
25
|
When you are done, call the \`${GAMBIT_TOOL_RESPOND}\` tool with a JSON object that includes your \`payload\` (validated output) and optional \`status\`/ \`message\`/ \`code\`/ \`meta\`. Do not end with normal assistant text; always finish by calling \`${GAMBIT_TOOL_RESPOND}\`.
|
|
@@ -30,10 +33,41 @@ function warnLegacyMarker(marker, replacement) {
|
|
|
30
33
|
LEGACY_MARKER_WARNINGS[marker] = true;
|
|
31
34
|
logger.warn(`[gambit] "gambit://${marker}" is deprecated; use ${replacement} instead.`);
|
|
32
35
|
}
|
|
36
|
+
function warnLegacySchema(resolvedPath, legacy, replacement) {
|
|
37
|
+
const key = `${resolvedPath}:${legacy}`;
|
|
38
|
+
if (LEGACY_SCHEMA_WARNINGS.has(key))
|
|
39
|
+
return;
|
|
40
|
+
LEGACY_SCHEMA_WARNINGS.add(key);
|
|
41
|
+
logger.warn(`[gambit] deck at ${resolvedPath} uses deprecated "${legacy}"; rename to "${replacement}"`);
|
|
42
|
+
}
|
|
43
|
+
function warnLegacyFragment(resolvedPath, legacy, replacement) {
|
|
44
|
+
const key = `${resolvedPath}:${legacy}`;
|
|
45
|
+
if (LEGACY_FRAGMENT_WARNINGS.has(key))
|
|
46
|
+
return;
|
|
47
|
+
LEGACY_FRAGMENT_WARNINGS.add(key);
|
|
48
|
+
logger.warn(`[gambit] card at ${resolvedPath} uses deprecated "${legacy}"; rename to "${replacement}"`);
|
|
49
|
+
}
|
|
33
50
|
function toFileUrl(p) {
|
|
34
51
|
const abs = path.resolve(p);
|
|
35
52
|
return path.toFileUrl(abs).href;
|
|
36
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
|
+
}
|
|
37
71
|
async function maybeLoadSchema(schemaPath, basePath) {
|
|
38
72
|
if (!schemaPath || typeof schemaPath !== "string")
|
|
39
73
|
return undefined;
|
|
@@ -43,7 +77,7 @@ async function maybeLoadSchema(schemaPath, basePath) {
|
|
|
43
77
|
const mod = await import(toFileUrl(resolved));
|
|
44
78
|
return mod.default;
|
|
45
79
|
}
|
|
46
|
-
function normalizeDeckRefs(refs, basePath) {
|
|
80
|
+
function normalizeDeckRefs(refs, basePath, opts) {
|
|
47
81
|
if (!Array.isArray(refs))
|
|
48
82
|
return [];
|
|
49
83
|
return refs
|
|
@@ -54,14 +88,32 @@ function normalizeDeckRefs(refs, basePath) {
|
|
|
54
88
|
if (!p) {
|
|
55
89
|
throw new Error("Deck reference must include a path");
|
|
56
90
|
}
|
|
91
|
+
if (opts?.requirePrompt && !p.endsWith("PROMPT.md")) {
|
|
92
|
+
throw new Error(`Deck reference must point to PROMPT.md (${basePath})`);
|
|
93
|
+
}
|
|
57
94
|
const normalized = { ...rec };
|
|
58
|
-
normalized.path =
|
|
95
|
+
normalized.path = p.startsWith("gambit://")
|
|
96
|
+
? p
|
|
97
|
+
: path.resolve(path.dirname(basePath), p);
|
|
59
98
|
if (typeof rec.description !== "string")
|
|
60
99
|
delete normalized.description;
|
|
61
100
|
if (typeof rec.label !== "string")
|
|
62
101
|
delete normalized.label;
|
|
63
102
|
if (typeof rec.id !== "string")
|
|
64
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
|
+
}
|
|
65
117
|
return normalized;
|
|
66
118
|
});
|
|
67
119
|
}
|
|
@@ -78,14 +130,92 @@ function mergeDeckRefs(...lists) {
|
|
|
78
130
|
}
|
|
79
131
|
return Array.from(merged.values());
|
|
80
132
|
}
|
|
81
|
-
function normalizeActionDecks(entries, basePath) {
|
|
82
|
-
|
|
83
|
-
|
|
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();
|
|
84
142
|
if (!name) {
|
|
85
143
|
throw new Error(`Action deck must include a name (${basePath})`);
|
|
86
144
|
}
|
|
87
|
-
|
|
88
|
-
|
|
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;
|
|
89
219
|
}
|
|
90
220
|
async function expandEmbedsInBody(args) {
|
|
91
221
|
const { body, resolvedPath, stack } = args;
|
|
@@ -101,17 +231,17 @@ async function expandEmbedsInBody(args) {
|
|
|
101
231
|
const target = match[1];
|
|
102
232
|
out += body.slice(lastIndex, matchIndex);
|
|
103
233
|
if (target === RESPOND_MARKER) {
|
|
104
|
-
warnLegacyMarker("respond", "gambit://
|
|
234
|
+
warnLegacyMarker("respond", "gambit://snippets/respond.md");
|
|
105
235
|
respond = true;
|
|
106
236
|
out += RESPOND_TEXT;
|
|
107
237
|
}
|
|
108
238
|
else if (target === INIT_MARKER) {
|
|
109
|
-
warnLegacyMarker("init", "gambit://
|
|
239
|
+
warnLegacyMarker("init", "gambit://snippets/context.md");
|
|
110
240
|
initHint = true;
|
|
111
241
|
out += INIT_TEXT;
|
|
112
242
|
}
|
|
113
243
|
else if (target === END_MARKER) {
|
|
114
|
-
warnLegacyMarker("end", "gambit://
|
|
244
|
+
warnLegacyMarker("end", "gambit://snippets/end.md");
|
|
115
245
|
endHint = true;
|
|
116
246
|
out += END_TEXT;
|
|
117
247
|
}
|
|
@@ -135,17 +265,7 @@ export async function loadMarkdownCard(filePath, parentPath, stack = []) {
|
|
|
135
265
|
}
|
|
136
266
|
const nextStack = [...stack, resolved];
|
|
137
267
|
const raw = await dntShim.Deno.readTextFile(resolved);
|
|
138
|
-
|
|
139
|
-
let body;
|
|
140
|
-
try {
|
|
141
|
-
const parsed = extract(raw);
|
|
142
|
-
attrs = parsed.attrs;
|
|
143
|
-
body = parsed.body;
|
|
144
|
-
}
|
|
145
|
-
catch (err) {
|
|
146
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
147
|
-
throw new Error(`Failed to parse front matter in ${resolved}: ${message}`);
|
|
148
|
-
}
|
|
268
|
+
const { attrs, body } = parseFrontMatterOrRaw(raw, resolved);
|
|
149
269
|
const candidate = attrs;
|
|
150
270
|
if (isCardDefinition(candidate)) {
|
|
151
271
|
// treat attrs as ts-shaped card
|
|
@@ -155,7 +275,7 @@ export async function loadMarkdownCard(filePath, parentPath, stack = []) {
|
|
|
155
275
|
}
|
|
156
276
|
const hasNewActionField = attrs.actionDecks;
|
|
157
277
|
const legacyActions = attrs.actions;
|
|
158
|
-
const actionDecks = normalizeActionDecks(hasNewActionField ?? legacyActions, resolved);
|
|
278
|
+
const actionDecks = await normalizeActionDecks(hasNewActionField ?? legacyActions, resolved);
|
|
159
279
|
if (!hasNewActionField && legacyActions) {
|
|
160
280
|
logger.warn(`[gambit] card at ${resolved} uses deprecated "actions"; rename to "actionDecks"`);
|
|
161
281
|
}
|
|
@@ -168,8 +288,18 @@ export async function loadMarkdownCard(filePath, parentPath, stack = []) {
|
|
|
168
288
|
throw new Error(`Action name ${a.name} must match ${TOOL_NAME_PATTERN} and be <= ${MAX_TOOL_NAME_LENGTH} characters`);
|
|
169
289
|
}
|
|
170
290
|
});
|
|
171
|
-
const
|
|
172
|
-
const
|
|
291
|
+
const legacyInputSchema = attrs.inputSchema;
|
|
292
|
+
const legacyOutputSchema = attrs.outputSchema;
|
|
293
|
+
const contextFragment = await maybeLoadSchema(attrs.contextFragment ??
|
|
294
|
+
legacyInputSchema, resolved);
|
|
295
|
+
const responseFragment = await maybeLoadSchema(attrs.responseFragment ??
|
|
296
|
+
legacyOutputSchema, resolved);
|
|
297
|
+
if (legacyInputSchema !== undefined) {
|
|
298
|
+
warnLegacyFragment(resolved, "inputSchema", "contextFragment");
|
|
299
|
+
}
|
|
300
|
+
if (legacyOutputSchema !== undefined) {
|
|
301
|
+
warnLegacyFragment(resolved, "outputSchema", "responseFragment");
|
|
302
|
+
}
|
|
173
303
|
const replaced = await expandEmbedsInBody({
|
|
174
304
|
body,
|
|
175
305
|
resolvedPath: resolved,
|
|
@@ -179,6 +309,7 @@ export async function loadMarkdownCard(filePath, parentPath, stack = []) {
|
|
|
179
309
|
const embeddedCards = replaced.embeds;
|
|
180
310
|
const respondFlag = Boolean(attrs.respond);
|
|
181
311
|
const allowEndFlag = Boolean(attrs.allowEnd);
|
|
312
|
+
const permissions = normalizePermissionDeclaration(attrs.permissions, path.dirname(resolved));
|
|
182
313
|
return {
|
|
183
314
|
kind: "gambit.card",
|
|
184
315
|
path: resolved,
|
|
@@ -189,8 +320,11 @@ export async function loadMarkdownCard(filePath, parentPath, stack = []) {
|
|
|
189
320
|
testDecks: normalizeDeckRefs(attrs.testDecks, resolved),
|
|
190
321
|
graderDecks: normalizeDeckRefs(attrs.graderDecks, resolved),
|
|
191
322
|
cards: embeddedCards,
|
|
192
|
-
|
|
193
|
-
|
|
323
|
+
permissions,
|
|
324
|
+
contextFragment,
|
|
325
|
+
responseFragment,
|
|
326
|
+
inputFragment: contextFragment,
|
|
327
|
+
outputFragment: responseFragment,
|
|
194
328
|
respond: respondFlag || replaced.respond,
|
|
195
329
|
};
|
|
196
330
|
}
|
|
@@ -199,26 +333,35 @@ export async function loadMarkdownDeck(filePath, parentPath) {
|
|
|
199
333
|
? path.resolve(path.dirname(parentPath), filePath)
|
|
200
334
|
: path.resolve(filePath);
|
|
201
335
|
const raw = await dntShim.Deno.readTextFile(resolved);
|
|
202
|
-
|
|
203
|
-
let body;
|
|
204
|
-
try {
|
|
205
|
-
const parsed = extract(raw);
|
|
206
|
-
attrs = parsed.attrs;
|
|
207
|
-
body = parsed.body;
|
|
208
|
-
}
|
|
209
|
-
catch (err) {
|
|
210
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
211
|
-
throw new Error(`Failed to parse front matter in ${resolved}: ${message}`);
|
|
212
|
-
}
|
|
336
|
+
const { attrs, body } = parseFrontMatterOrRaw(raw, resolved);
|
|
213
337
|
const deckAttrs = attrs;
|
|
214
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
|
+
}
|
|
215
345
|
const hasNewActionDecks = deckMeta.actionDecks;
|
|
216
|
-
const
|
|
217
|
-
const actionDecks = normalizeActionDecks(
|
|
218
|
-
|
|
219
|
-
|
|
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.`);
|
|
220
354
|
}
|
|
221
|
-
|
|
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) => {
|
|
222
365
|
if (a.name.startsWith(RESERVED_TOOL_PREFIX) &&
|
|
223
366
|
!BUILTIN_TOOL_NAME_SET.has(a.name)) {
|
|
224
367
|
throw new Error(`Action name ${a.name} is reserved`);
|
|
@@ -233,8 +376,18 @@ export async function loadMarkdownDeck(filePath, parentPath) {
|
|
|
233
376
|
stack: [resolved],
|
|
234
377
|
});
|
|
235
378
|
const cards = replaced.embeds;
|
|
236
|
-
const
|
|
237
|
-
const
|
|
379
|
+
const legacyInputSchema = deckMeta.inputSchema;
|
|
380
|
+
const legacyOutputSchema = deckMeta.outputSchema;
|
|
381
|
+
const contextSchema = await maybeLoadSchema(deckMeta.contextSchema ??
|
|
382
|
+
legacyInputSchema, resolved);
|
|
383
|
+
const responseSchema = await maybeLoadSchema(deckMeta.responseSchema ??
|
|
384
|
+
legacyOutputSchema, resolved);
|
|
385
|
+
if (legacyInputSchema !== undefined) {
|
|
386
|
+
warnLegacySchema(resolved, "inputSchema", "contextSchema");
|
|
387
|
+
}
|
|
388
|
+
if (legacyOutputSchema !== undefined) {
|
|
389
|
+
warnLegacySchema(resolved, "outputSchema", "responseSchema");
|
|
390
|
+
}
|
|
238
391
|
const allCards = flattenCards(cards);
|
|
239
392
|
const cleanedBody = replaced.body;
|
|
240
393
|
const allowEnd = Boolean(deckMeta.allowEnd) ||
|
|
@@ -246,15 +399,17 @@ export async function loadMarkdownDeck(filePath, parentPath) {
|
|
|
246
399
|
mergedActions[action.name] = action;
|
|
247
400
|
}
|
|
248
401
|
}
|
|
249
|
-
for (const action of
|
|
402
|
+
for (const action of allActionDecks) {
|
|
250
403
|
mergedActions[action.name] = action;
|
|
251
404
|
}
|
|
252
|
-
let
|
|
253
|
-
let
|
|
405
|
+
let mergedContextSchema = contextSchema;
|
|
406
|
+
let mergedResponseSchema = responseSchema;
|
|
254
407
|
for (const card of allCards) {
|
|
255
|
-
|
|
256
|
-
|
|
408
|
+
mergedContextSchema = mergeZodObjects(mergedContextSchema, card.contextFragment);
|
|
409
|
+
mergedResponseSchema = mergeZodObjects(mergedResponseSchema, card.responseFragment);
|
|
257
410
|
}
|
|
411
|
+
const mergedInputSchema = mergedContextSchema;
|
|
412
|
+
const mergedOutputSchema = mergedResponseSchema;
|
|
258
413
|
const normalizeHandler = (cfg, kind) => {
|
|
259
414
|
if (!cfg)
|
|
260
415
|
return undefined;
|
|
@@ -287,10 +442,18 @@ export async function loadMarkdownDeck(filePath, parentPath) {
|
|
|
287
442
|
}
|
|
288
443
|
: undefined;
|
|
289
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
|
+
}
|
|
290
452
|
const rootTestDecks = normalizeDeckRefs(deckMeta.testDecks, resolved);
|
|
291
453
|
const rootGraderDecks = normalizeDeckRefs(deckMeta.graderDecks, resolved);
|
|
292
454
|
const embeddedTestDecks = allCards.flatMap((card) => card.testDecks ?? []);
|
|
293
455
|
const embeddedGraderDecks = allCards.flatMap((card) => card.graderDecks ?? []);
|
|
456
|
+
const permissions = normalizePermissionDeclaration(deckMeta.permissions, path.dirname(resolved));
|
|
294
457
|
return {
|
|
295
458
|
kind: "gambit.deck",
|
|
296
459
|
path: resolved,
|
|
@@ -298,19 +461,25 @@ export async function loadMarkdownDeck(filePath, parentPath) {
|
|
|
298
461
|
allowEnd,
|
|
299
462
|
actionDecks: mergedActionDecks,
|
|
300
463
|
actions: mergedActionDecks,
|
|
301
|
-
|
|
302
|
-
|
|
464
|
+
tools,
|
|
465
|
+
testDecks: mergeDeckRefs(scenarioDecks, rootTestDecks, embeddedTestDecks),
|
|
466
|
+
graderDecks: mergeDeckRefs(graderDecks, rootGraderDecks, embeddedGraderDecks),
|
|
303
467
|
cards: allCards,
|
|
304
468
|
label: deckMeta.label,
|
|
469
|
+
startMode: deckMeta.startMode,
|
|
305
470
|
modelParams: deckMeta.modelParams,
|
|
306
471
|
guardrails: deckMeta.guardrails,
|
|
472
|
+
contextSchema: mergedContextSchema,
|
|
473
|
+
responseSchema: mergedResponseSchema,
|
|
307
474
|
inputSchema: mergedInputSchema,
|
|
308
475
|
outputSchema: mergedOutputSchema,
|
|
476
|
+
executor: undefined,
|
|
309
477
|
handlers,
|
|
310
478
|
respond: Boolean(deckMeta.respond) ||
|
|
311
479
|
replaced.respond ||
|
|
312
480
|
allCards.some((c) => c.respond),
|
|
313
481
|
inlineEmbeds: true,
|
|
482
|
+
permissions,
|
|
314
483
|
};
|
|
315
484
|
}
|
|
316
485
|
export function isMarkdownFile(filePath) {
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deno-native permission kinds supported by Gambit's permission contract.
|
|
3
|
+
*/
|
|
4
|
+
export declare const PERMISSION_KINDS: readonly ["read", "write", "run", "net", "env"];
|
|
5
|
+
export type PermissionKind = (typeof PERMISSION_KINDS)[number];
|
|
6
|
+
export type PathPermissionInput = boolean | Array<string>;
|
|
7
|
+
export type RunPermissionInput = boolean | Array<string> | {
|
|
8
|
+
paths?: Array<string>;
|
|
9
|
+
commands?: Array<string>;
|
|
10
|
+
};
|
|
11
|
+
export type PermissionDeclarationInput = Partial<{
|
|
12
|
+
read: PathPermissionInput;
|
|
13
|
+
write: PathPermissionInput;
|
|
14
|
+
run: RunPermissionInput;
|
|
15
|
+
net: PathPermissionInput;
|
|
16
|
+
env: PathPermissionInput;
|
|
17
|
+
}>;
|
|
18
|
+
export type SerializedRunPermission = false | true | {
|
|
19
|
+
paths: Array<string>;
|
|
20
|
+
commands: Array<string>;
|
|
21
|
+
};
|
|
22
|
+
export type SerializedPermissionSet = {
|
|
23
|
+
read: false | true | Array<string>;
|
|
24
|
+
write: false | true | Array<string>;
|
|
25
|
+
run: SerializedRunPermission;
|
|
26
|
+
net: false | true | Array<string>;
|
|
27
|
+
env: false | true | Array<string>;
|
|
28
|
+
};
|
|
29
|
+
export type PermissionDeclaration = SerializedPermissionSet;
|
|
30
|
+
type NormalizedScope = {
|
|
31
|
+
all: boolean;
|
|
32
|
+
values: Set<string>;
|
|
33
|
+
};
|
|
34
|
+
type NormalizedRunScope = {
|
|
35
|
+
all: boolean;
|
|
36
|
+
paths: Set<string>;
|
|
37
|
+
commands: Set<string>;
|
|
38
|
+
};
|
|
39
|
+
export type NormalizedPermissionSet = {
|
|
40
|
+
baseDir: string;
|
|
41
|
+
read: NormalizedScope;
|
|
42
|
+
write: NormalizedScope;
|
|
43
|
+
run: NormalizedRunScope;
|
|
44
|
+
net: NormalizedScope;
|
|
45
|
+
env: NormalizedScope;
|
|
46
|
+
};
|
|
47
|
+
export type PermissionLayerName = "parent" | "workspace" | "declaration" | "reference" | "session" | "host";
|
|
48
|
+
export type PermissionLayerTrace = {
|
|
49
|
+
name: PermissionLayerName;
|
|
50
|
+
baseDir: string;
|
|
51
|
+
requested: SerializedPermissionSet;
|
|
52
|
+
effective: SerializedPermissionSet;
|
|
53
|
+
};
|
|
54
|
+
export type PermissionTrace = {
|
|
55
|
+
baseDir: string;
|
|
56
|
+
effective: SerializedPermissionSet;
|
|
57
|
+
layers: Array<PermissionLayerTrace>;
|
|
58
|
+
};
|
|
59
|
+
export declare function cloneNormalizedPermissions(input: NormalizedPermissionSet): NormalizedPermissionSet;
|
|
60
|
+
/**
|
|
61
|
+
* Returns an allow-all permission set anchored to `baseDir`.
|
|
62
|
+
*/
|
|
63
|
+
export declare function allowAllPermissions(baseDir: string): NormalizedPermissionSet;
|
|
64
|
+
/**
|
|
65
|
+
* Normalizes a permission declaration to a serializable, deterministic shape.
|
|
66
|
+
*
|
|
67
|
+
* Relative path grants are resolved against `baseDir`.
|
|
68
|
+
*/
|
|
69
|
+
export declare function normalizePermissionDeclaration(input: PermissionDeclarationInput | undefined, baseDir: string): PermissionDeclaration | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Normalizes a declaration to the internal set form used during intersection.
|
|
72
|
+
*/
|
|
73
|
+
export declare function normalizePermissionDeclarationToSet(input: PermissionDeclarationInput | undefined, baseDir: string): NormalizedPermissionSet | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* Serializes an internal normalized permission set for traces/persistence.
|
|
76
|
+
*/
|
|
77
|
+
export declare function serializePermissions(set: NormalizedPermissionSet): SerializedPermissionSet;
|
|
78
|
+
/**
|
|
79
|
+
* Computes the monotonic intersection between two permission sets.
|
|
80
|
+
*
|
|
81
|
+
* `baseDir` controls how relative checks (`canReadPath`/etc) are evaluated for
|
|
82
|
+
* the returned set.
|
|
83
|
+
*/
|
|
84
|
+
export declare function intersectPermissions(parent: NormalizedPermissionSet, next: NormalizedPermissionSet, baseDir: string): NormalizedPermissionSet;
|
|
85
|
+
/**
|
|
86
|
+
* Resolves effective permissions and emits a layer-by-layer permission trace.
|
|
87
|
+
*
|
|
88
|
+
* Layer precedence:
|
|
89
|
+
* 1. `parent` (or host allow-all for roots)
|
|
90
|
+
* 2. `workspace` (root only)
|
|
91
|
+
* 3. `declaration` (deck/card declaration)
|
|
92
|
+
* 4. `reference` (parent reference override)
|
|
93
|
+
* 5. `session` (root only)
|
|
94
|
+
*/
|
|
95
|
+
export declare function resolveEffectivePermissions(args: {
|
|
96
|
+
baseDir: string;
|
|
97
|
+
parent?: NormalizedPermissionSet;
|
|
98
|
+
workspace?: {
|
|
99
|
+
baseDir: string;
|
|
100
|
+
permissions: PermissionDeclarationInput;
|
|
101
|
+
};
|
|
102
|
+
declaration?: {
|
|
103
|
+
baseDir: string;
|
|
104
|
+
permissions: PermissionDeclarationInput;
|
|
105
|
+
};
|
|
106
|
+
reference?: {
|
|
107
|
+
baseDir: string;
|
|
108
|
+
permissions: PermissionDeclarationInput;
|
|
109
|
+
};
|
|
110
|
+
session?: {
|
|
111
|
+
baseDir: string;
|
|
112
|
+
permissions: PermissionDeclarationInput;
|
|
113
|
+
};
|
|
114
|
+
}): {
|
|
115
|
+
effective: NormalizedPermissionSet;
|
|
116
|
+
trace: PermissionTrace;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Returns whether `targetPath` is readable under `set`.
|
|
120
|
+
*
|
|
121
|
+
* Relative paths are resolved against `set.baseDir`.
|
|
122
|
+
*/
|
|
123
|
+
export declare function canReadPath(set: NormalizedPermissionSet, targetPath: string): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Returns whether `targetPath` is writable under `set`.
|
|
126
|
+
*
|
|
127
|
+
* Relative paths are resolved against `set.baseDir`.
|
|
128
|
+
*/
|
|
129
|
+
export declare function canWritePath(set: NormalizedPermissionSet, targetPath: string): boolean;
|
|
130
|
+
/**
|
|
131
|
+
* Returns whether `targetPath` is executable via run-path grants.
|
|
132
|
+
*
|
|
133
|
+
* Relative paths are resolved against `set.baseDir`.
|
|
134
|
+
*/
|
|
135
|
+
export declare function canRunPath(set: NormalizedPermissionSet, targetPath: string): boolean;
|
|
136
|
+
/**
|
|
137
|
+
* Returns whether `commandName` is executable via run-command grants.
|
|
138
|
+
*
|
|
139
|
+
* This check intentionally does not apply basename/path fallback semantics.
|
|
140
|
+
*/
|
|
141
|
+
export declare function canRunCommand(set: NormalizedPermissionSet, commandName: string): boolean;
|
|
142
|
+
export {};
|
|
143
|
+
//# sourceMappingURL=permissions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/src/permissions.ts"],"names":[],"mappings":"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"}
|