@bolt-foundry/gambit 0.6.6 → 0.6.8

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/CHANGELOG.md CHANGED
@@ -5,79 +5,9 @@ since = "225456917f75e92cc095af525201373c4be37944"
5
5
 
6
6
  # Changelog
7
7
 
8
- ## Unreleased (v0.6.3)
8
+ ## Unreleased (v0.6.8)
9
9
 
10
- - TBD
11
-
12
- ## v0.6.2
13
-
14
- ### Release and packaging
15
-
16
- - Bump gambit + gambit-core to 0.6.2.
17
-
18
- ## v0.6.1
19
-
20
- ### Release and packaging
21
-
22
- - Bump gambit + gambit-core to 0.6.1.
23
-
24
- ## v0.6.0
25
-
26
- ### Release and packaging
27
-
28
- - Add an npm CLI wrapper that downloads prebuilt Gambit binaries with checksum
29
- verification.
30
- - Normalize release binary asset names and checksum generation for predictable
31
- npm downloads.
32
- - Fix the npm build to resolve gambit-core in the gambitmono layout and derive
33
- import-map targets from the detected path.
34
- - Add `@deno/dnt` to the Gambit package and refresh release/npm docs.
35
-
36
- ## v0.5.5
37
-
38
- ### Release and packaging
39
-
40
- - Publish a minimal `@bolt-foundry/gambit` npm package alongside gambit-core
41
- (runtime-only; no CLI/bin yet).
42
- - Document DNT/npm status and release notes for the npm publish flow.
43
-
44
- ## v0.5.0
45
-
46
- ### Runtime and API
47
-
48
- - Synthetic tools refreshed: `gambit_init`, `gambit_respond`, `gambit_complete`
49
- (function-style tools, underscore names).
50
- - Envelope simplification: init carries run/action IDs plus guardrails/model
51
- hints; respond wraps payload/message/status/code/meta (default status 200 for
52
- success, 500 for handled errors unless overridden).
53
- - Runtime behavior: child completions and handled errors emit `gambit_complete`;
54
- interval handlers surface mid-run updates; roots stay conversational-only.
55
- - `gambit_init` only fires when `--init` is provided and its payload is the raw
56
- input (no run/action metadata).
57
- - Added trace timestamps for latency metrics and persisted streamed assistant
58
- text before tool calls.
59
- - Added OpenAI chat completions compatibility (`renderDeck` plus wrapper).
60
- - Increased default guardrail `maxPasses`.
61
-
62
- ### Simulator UI and test bot
63
-
64
- - New React simulator UI with sessions, recents, nested trace hierarchy, and
65
- session notes/ratings.
66
- - Pivoted the simulator to debug/test/calibrate workflows with a new editor
67
- assistant endpoint and UI tab.
68
- - Test bot upgrades: per-run streaming + debug link, init/scenario panels,
69
- default scenario schema, deck input config, feedback on all bubbles, and
70
- session routing/persistence.
71
- - Calibration/grading updates: deck-defined grading flows, streamed results,
72
- reference samples, compact context previews, and renaming calibration runs to
73
- grading runs.
74
-
75
- ### Decks and examples (voice front desk)
76
-
77
- - Added voice front desk example decks and modularized the deck set.
78
- - Added new patient intake + additional voice front desk test decks.
79
- - Added appointment lookup orchestration and scheduling confirmation flow.
80
- - Enabled scheduling service deck and shared patient identity test input schema.
10
+ - Repl fixes.
81
11
  - Replaced voice front desk graders and expanded FAQ persona/grading coverage.
82
12
 
83
13
  ### CLI and UX
package/README.md CHANGED
@@ -21,7 +21,7 @@ Downloads example files and sets environment variables.
21
21
  Run an example in the terminal (`repl`):
22
22
 
23
23
  ```
24
- deno run -A jsr:@bolt-foundry/gambit/cli repl examples/hello.deck.md
24
+ deno run -A jsr:@bolt-foundry/gambit/cli repl examples/init/hello.deck.md
25
25
  ```
26
26
 
27
27
  This example just says "hello" and repeats your message back to you.
@@ -29,7 +29,7 @@ This example just says "hello" and repeats your message back to you.
29
29
  Run an example in the browser (`serve`):
30
30
 
31
31
  ```
32
- deno run -A jsr:@bolt-foundry/gambit/cli serve examples/hello.deck.md
32
+ deno run -A jsr:@bolt-foundry/gambit/cli serve examples/init/hello.deck.md
33
33
  open http://localhost:8000/debug
34
34
  ```
35
35
 
@@ -0,0 +1,14 @@
1
+ import type { ModelMessage } from "@bolt-foundry/gambit-core";
2
+ import type { SavedState } from "@bolt-foundry/gambit-core";
3
+ export declare function parsePortValue(value: unknown, label?: string): number | undefined;
4
+ export declare function normalizeFlagList(value: string | Array<string> | undefined): Array<string>;
5
+ export declare function slugifyDeckPath(deckPath: string): string;
6
+ export declare function defaultSessionRoot(deckPath: string): string;
7
+ export declare function defaultTestBotStatePath(deckPath: string): string;
8
+ export declare function enrichStateMeta(state: SavedState, deckPath: string): SavedState;
9
+ export declare function parseInit(raw?: string): unknown;
10
+ export declare function parseMessage(raw?: string): unknown;
11
+ export declare function parseBotInput(raw?: string): unknown;
12
+ export declare function findLastAssistantMessage(messages: Array<ModelMessage>): string | undefined;
13
+ export declare function extractInitInput(state?: SavedState): unknown;
14
+ //# sourceMappingURL=cli_utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli_utils.d.ts","sourceRoot":"","sources":["../../src/src/cli_utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,wBAAgB,cAAc,CAC5B,KAAK,EAAE,OAAO,EACd,KAAK,SAAS,GACb,MAAM,GAAG,SAAS,CAOpB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,GACxC,KAAK,CAAC,MAAM,CAAC,CAGf;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQxD;AAuBD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM3D;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQhE;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,MAAM,GACf,UAAU,CAOZ;AAED,wBAAgB,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAO/C;AAED,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAOlD;AAED,wBAAgB,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAOnD;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,GAC5B,MAAM,GAAG,SAAS,CAUpB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,OAAO,CAe5D"}
@@ -0,0 +1,126 @@
1
+ import * as dntShim from "../_dnt.shims.js";
2
+ import * as path from "../deps/jsr.io/@std/path/1.1.4/mod.js";
3
+ import { GAMBIT_TOOL_INIT } from "@bolt-foundry/gambit-core";
4
+ export function parsePortValue(value, label = "port") {
5
+ if (value === undefined || value === null || value === "")
6
+ return undefined;
7
+ const n = Number(value);
8
+ if (!Number.isInteger(n) || n <= 0 || n > 65535) {
9
+ throw new Error(`Invalid ${label}: ${value}`);
10
+ }
11
+ return n;
12
+ }
13
+ export function normalizeFlagList(value) {
14
+ if (!value)
15
+ return [];
16
+ return Array.isArray(value) ? value.filter(Boolean) : [value];
17
+ }
18
+ export function slugifyDeckPath(deckPath) {
19
+ const baseName = path.basename(deckPath || "deck");
20
+ const withoutExt = baseName.replace(/\.[^.]+$/, "");
21
+ const slug = withoutExt.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
22
+ return slug || "session";
23
+ }
24
+ const PROJECT_ROOT_MARKERS = ["deno.json", "deno.jsonc", "package.json"];
25
+ function findProjectRoot(startDir) {
26
+ let current = startDir;
27
+ while (true) {
28
+ for (const marker of PROJECT_ROOT_MARKERS) {
29
+ try {
30
+ const candidate = path.join(current, marker);
31
+ const info = dntShim.Deno.statSync(candidate);
32
+ if (info.isFile)
33
+ return current;
34
+ }
35
+ catch {
36
+ // ignore
37
+ }
38
+ }
39
+ const parent = path.dirname(current);
40
+ if (parent === current)
41
+ break;
42
+ current = parent;
43
+ }
44
+ return undefined;
45
+ }
46
+ export function defaultSessionRoot(deckPath) {
47
+ const resolvedDeckPath = path.resolve(deckPath);
48
+ const deckDir = path.dirname(resolvedDeckPath);
49
+ const projectRoot = findProjectRoot(deckDir);
50
+ const baseDir = projectRoot ?? deckDir;
51
+ return path.join(baseDir, ".gambit", "sessions");
52
+ }
53
+ export function defaultTestBotStatePath(deckPath) {
54
+ const slug = slugifyDeckPath(deckPath);
55
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-");
56
+ return path.join(defaultSessionRoot(deckPath), `${slug}-${stamp}`, "state.json");
57
+ }
58
+ export function enrichStateMeta(state, deckPath) {
59
+ const meta = { ...(state.meta ?? {}) };
60
+ if (typeof meta.deck !== "string")
61
+ meta.deck = deckPath;
62
+ if (typeof meta.deckSlug !== "string") {
63
+ meta.deckSlug = slugifyDeckPath(deckPath);
64
+ }
65
+ return { ...state, meta };
66
+ }
67
+ export function parseInit(raw) {
68
+ if (raw === undefined)
69
+ return undefined;
70
+ try {
71
+ return JSON.parse(raw);
72
+ }
73
+ catch {
74
+ return raw;
75
+ }
76
+ }
77
+ export function parseMessage(raw) {
78
+ if (raw === undefined)
79
+ return undefined;
80
+ try {
81
+ return JSON.parse(raw);
82
+ }
83
+ catch {
84
+ return raw;
85
+ }
86
+ }
87
+ export function parseBotInput(raw) {
88
+ if (raw === undefined)
89
+ return undefined;
90
+ try {
91
+ return JSON.parse(raw);
92
+ }
93
+ catch {
94
+ return raw;
95
+ }
96
+ }
97
+ export function findLastAssistantMessage(messages) {
98
+ for (let i = messages.length - 1; i >= 0; i--) {
99
+ const msg = messages[i];
100
+ if (msg?.role === "assistant") {
101
+ return typeof msg.content === "string"
102
+ ? msg.content
103
+ : JSON.stringify(msg.content ?? "");
104
+ }
105
+ }
106
+ return undefined;
107
+ }
108
+ export function extractInitInput(state) {
109
+ if (!state?.messages)
110
+ return undefined;
111
+ for (let i = state.messages.length - 1; i >= 0; i--) {
112
+ const msg = state.messages[i];
113
+ if (msg.role === "tool" && msg.name === GAMBIT_TOOL_INIT) {
114
+ const content = msg.content;
115
+ if (typeof content !== "string")
116
+ return undefined;
117
+ try {
118
+ return JSON.parse(content);
119
+ }
120
+ catch {
121
+ return content;
122
+ }
123
+ }
124
+ }
125
+ return undefined;
126
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAW5C,OAAO,KAAK,EAGV,aAAa,EAEd,MAAM,2BAA2B,CAAC;AA+ZnC;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAwnExC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAY5C,OAAO,KAAK,EAGV,aAAa,EAEd,MAAM,2BAA2B,CAAC;AA+ZnC;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAwnExC"}
package/esm/src/server.js CHANGED
@@ -3,6 +3,7 @@ import * as path from "../deps/jsr.io/@std/path/1.1.4/mod.js";
3
3
  import { isGambitEndSignal, runDeck } from "@bolt-foundry/gambit-core";
4
4
  import { sanitizeNumber } from "./test_bot.js";
5
5
  import { makeConsoleTracer } from "./trace.js";
6
+ import { defaultSessionRoot } from "./cli_utils.js";
6
7
  import { loadDeck } from "@bolt-foundry/gambit-core";
7
8
  import { appendDurableStreamEvent, handleDurableStreamRequest, } from "./durable_streams.js";
8
9
  const logger = console;
@@ -316,7 +317,7 @@ export function startWebSocketSimulator(opts) {
316
317
  const sessionsRoot = (() => {
317
318
  const base = opts.sessionDir
318
319
  ? path.resolve(opts.sessionDir)
319
- : path.resolve(dntShim.Deno.cwd(), ".gambit", "sessions");
320
+ : defaultSessionRoot(resolvedDeckPath);
320
321
  try {
321
322
  dntShim.Deno.mkdirSync(base, { recursive: true });
322
323
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bolt-foundry/gambit",
3
- "version": "0.6.6",
3
+ "version": "0.6.8",
4
4
  "description": "Agent harness framework for building, running, and verifying LLM workflows in Markdown and code.",
5
5
  "homepage": "https://github.com/bolt-foundry/gambit",
6
6
  "repository": {
@@ -24,7 +24,7 @@
24
24
  "gambit": "bin/gambit.cjs"
25
25
  },
26
26
  "dependencies": {
27
- "@bolt-foundry/gambit-core": "^0.6.6",
27
+ "@bolt-foundry/gambit-core": "^0.6.8",
28
28
  "zod": "^3.23.8",
29
29
  "@deno/shim-deno": "~0.18.0"
30
30
  },
@@ -0,0 +1,14 @@
1
+ import type { ModelMessage } from "@bolt-foundry/gambit-core";
2
+ import type { SavedState } from "@bolt-foundry/gambit-core";
3
+ export declare function parsePortValue(value: unknown, label?: string): number | undefined;
4
+ export declare function normalizeFlagList(value: string | Array<string> | undefined): Array<string>;
5
+ export declare function slugifyDeckPath(deckPath: string): string;
6
+ export declare function defaultSessionRoot(deckPath: string): string;
7
+ export declare function defaultTestBotStatePath(deckPath: string): string;
8
+ export declare function enrichStateMeta(state: SavedState, deckPath: string): SavedState;
9
+ export declare function parseInit(raw?: string): unknown;
10
+ export declare function parseMessage(raw?: string): unknown;
11
+ export declare function parseBotInput(raw?: string): unknown;
12
+ export declare function findLastAssistantMessage(messages: Array<ModelMessage>): string | undefined;
13
+ export declare function extractInitInput(state?: SavedState): unknown;
14
+ //# sourceMappingURL=cli_utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli_utils.d.ts","sourceRoot":"","sources":["../../src/src/cli_utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,wBAAgB,cAAc,CAC5B,KAAK,EAAE,OAAO,EACd,KAAK,SAAS,GACb,MAAM,GAAG,SAAS,CAOpB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,GACxC,KAAK,CAAC,MAAM,CAAC,CAGf;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQxD;AAuBD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM3D;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQhE;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,MAAM,GACf,UAAU,CAOZ;AAED,wBAAgB,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAO/C;AAED,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAOlD;AAED,wBAAgB,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAOnD;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,GAC5B,MAAM,GAAG,SAAS,CAUpB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,OAAO,CAe5D"}
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.parsePortValue = parsePortValue;
37
+ exports.normalizeFlagList = normalizeFlagList;
38
+ exports.slugifyDeckPath = slugifyDeckPath;
39
+ exports.defaultSessionRoot = defaultSessionRoot;
40
+ exports.defaultTestBotStatePath = defaultTestBotStatePath;
41
+ exports.enrichStateMeta = enrichStateMeta;
42
+ exports.parseInit = parseInit;
43
+ exports.parseMessage = parseMessage;
44
+ exports.parseBotInput = parseBotInput;
45
+ exports.findLastAssistantMessage = findLastAssistantMessage;
46
+ exports.extractInitInput = extractInitInput;
47
+ const dntShim = __importStar(require("../_dnt.shims.js"));
48
+ const path = __importStar(require("../deps/jsr.io/@std/path/1.1.4/mod.js"));
49
+ const gambit_core_1 = require("@bolt-foundry/gambit-core");
50
+ function parsePortValue(value, label = "port") {
51
+ if (value === undefined || value === null || value === "")
52
+ return undefined;
53
+ const n = Number(value);
54
+ if (!Number.isInteger(n) || n <= 0 || n > 65535) {
55
+ throw new Error(`Invalid ${label}: ${value}`);
56
+ }
57
+ return n;
58
+ }
59
+ function normalizeFlagList(value) {
60
+ if (!value)
61
+ return [];
62
+ return Array.isArray(value) ? value.filter(Boolean) : [value];
63
+ }
64
+ function slugifyDeckPath(deckPath) {
65
+ const baseName = path.basename(deckPath || "deck");
66
+ const withoutExt = baseName.replace(/\.[^.]+$/, "");
67
+ const slug = withoutExt.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
68
+ return slug || "session";
69
+ }
70
+ const PROJECT_ROOT_MARKERS = ["deno.json", "deno.jsonc", "package.json"];
71
+ function findProjectRoot(startDir) {
72
+ let current = startDir;
73
+ while (true) {
74
+ for (const marker of PROJECT_ROOT_MARKERS) {
75
+ try {
76
+ const candidate = path.join(current, marker);
77
+ const info = dntShim.Deno.statSync(candidate);
78
+ if (info.isFile)
79
+ return current;
80
+ }
81
+ catch {
82
+ // ignore
83
+ }
84
+ }
85
+ const parent = path.dirname(current);
86
+ if (parent === current)
87
+ break;
88
+ current = parent;
89
+ }
90
+ return undefined;
91
+ }
92
+ function defaultSessionRoot(deckPath) {
93
+ const resolvedDeckPath = path.resolve(deckPath);
94
+ const deckDir = path.dirname(resolvedDeckPath);
95
+ const projectRoot = findProjectRoot(deckDir);
96
+ const baseDir = projectRoot ?? deckDir;
97
+ return path.join(baseDir, ".gambit", "sessions");
98
+ }
99
+ function defaultTestBotStatePath(deckPath) {
100
+ const slug = slugifyDeckPath(deckPath);
101
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-");
102
+ return path.join(defaultSessionRoot(deckPath), `${slug}-${stamp}`, "state.json");
103
+ }
104
+ function enrichStateMeta(state, deckPath) {
105
+ const meta = { ...(state.meta ?? {}) };
106
+ if (typeof meta.deck !== "string")
107
+ meta.deck = deckPath;
108
+ if (typeof meta.deckSlug !== "string") {
109
+ meta.deckSlug = slugifyDeckPath(deckPath);
110
+ }
111
+ return { ...state, meta };
112
+ }
113
+ function parseInit(raw) {
114
+ if (raw === undefined)
115
+ return undefined;
116
+ try {
117
+ return JSON.parse(raw);
118
+ }
119
+ catch {
120
+ return raw;
121
+ }
122
+ }
123
+ function parseMessage(raw) {
124
+ if (raw === undefined)
125
+ return undefined;
126
+ try {
127
+ return JSON.parse(raw);
128
+ }
129
+ catch {
130
+ return raw;
131
+ }
132
+ }
133
+ function parseBotInput(raw) {
134
+ if (raw === undefined)
135
+ return undefined;
136
+ try {
137
+ return JSON.parse(raw);
138
+ }
139
+ catch {
140
+ return raw;
141
+ }
142
+ }
143
+ function findLastAssistantMessage(messages) {
144
+ for (let i = messages.length - 1; i >= 0; i--) {
145
+ const msg = messages[i];
146
+ if (msg?.role === "assistant") {
147
+ return typeof msg.content === "string"
148
+ ? msg.content
149
+ : JSON.stringify(msg.content ?? "");
150
+ }
151
+ }
152
+ return undefined;
153
+ }
154
+ function extractInitInput(state) {
155
+ if (!state?.messages)
156
+ return undefined;
157
+ for (let i = state.messages.length - 1; i >= 0; i--) {
158
+ const msg = state.messages[i];
159
+ if (msg.role === "tool" && msg.name === gambit_core_1.GAMBIT_TOOL_INIT) {
160
+ const content = msg.content;
161
+ if (typeof content !== "string")
162
+ return undefined;
163
+ try {
164
+ return JSON.parse(content);
165
+ }
166
+ catch {
167
+ return content;
168
+ }
169
+ }
170
+ }
171
+ return undefined;
172
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAW5C,OAAO,KAAK,EAGV,aAAa,EAEd,MAAM,2BAA2B,CAAC;AA+ZnC;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAwnExC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAY5C,OAAO,KAAK,EAGV,aAAa,EAEd,MAAM,2BAA2B,CAAC;AA+ZnC;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAwnExC"}
@@ -39,6 +39,7 @@ const path = __importStar(require("../deps/jsr.io/@std/path/1.1.4/mod.js"));
39
39
  const gambit_core_1 = require("@bolt-foundry/gambit-core");
40
40
  const test_bot_js_1 = require("./test_bot.js");
41
41
  const trace_js_1 = require("./trace.js");
42
+ const cli_utils_js_1 = require("./cli_utils.js");
42
43
  const gambit_core_2 = require("@bolt-foundry/gambit-core");
43
44
  const durable_streams_js_1 = require("./durable_streams.js");
44
45
  const logger = console;
@@ -352,7 +353,7 @@ function startWebSocketSimulator(opts) {
352
353
  const sessionsRoot = (() => {
353
354
  const base = opts.sessionDir
354
355
  ? path.resolve(opts.sessionDir)
355
- : path.resolve(dntShim.Deno.cwd(), ".gambit", "sessions");
356
+ : (0, cli_utils_js_1.defaultSessionRoot)(resolvedDeckPath);
356
357
  try {
357
358
  dntShim.Deno.mkdirSync(base, { recursive: true });
358
359
  }