@ahpd/agent-claude 0.3.0 → 0.5.0
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 +6 -0
- package/dist/claude.d.ts +6 -8
- package/dist/claude.d.ts.map +1 -1
- package/dist/claude.js +93 -17
- package/dist/claude.js.map +1 -1
- package/dist/kinds.d.ts +29 -0
- package/dist/kinds.d.ts.map +1 -0
- package/dist/kinds.js +42 -0
- package/dist/kinds.js.map +1 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +198 -9
- package/dist/session.js.map +1 -1
- package/dist/transcript.d.ts.map +1 -1
- package/dist/transcript.js +5 -0
- package/dist/transcript.js.map +1 -1
- package/package.json +2 -2
- package/src/claude.ts +94 -27
- package/src/kinds.ts +46 -0
- package/src/session.ts +191 -11
- package/src/transcript.ts +5 -0
package/dist/session.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { rmSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
1
4
|
import { createSdkMcpServer, query } from '@anthropic-ai/claude-agent-sdk';
|
|
2
5
|
import { z } from 'zod';
|
|
3
6
|
import { protectedResource, urlOf } from './mcp.js';
|
|
7
|
+
import { toolMetaOf } from './kinds.js';
|
|
4
8
|
import { Status, idOf, tail } from '@ahpd/sdk';
|
|
5
9
|
/**
|
|
6
10
|
* The effort levels this backend has, weakest first.
|
|
@@ -39,6 +43,39 @@ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
|
39
43
|
const bag = (value) => (typeof value === 'object' && value !== null ? value : {});
|
|
40
44
|
const list = (value) => (Array.isArray(value) ? value : []);
|
|
41
45
|
const str = (value) => (typeof value === 'string' ? value : undefined);
|
|
46
|
+
/** A generated script is a few hundred bytes; anything near this is not one. */
|
|
47
|
+
const MAX_SHELL_INIT_SCRIPT = 64 * 1024;
|
|
48
|
+
/**
|
|
49
|
+
* The `shellInitScripts` value, checked to the reference host's rule.
|
|
50
|
+
*
|
|
51
|
+
* A list of `{ shell, script }`, each script non-empty and no longer than a
|
|
52
|
+
* generated one could be. `undefined` for anything else, which is what lets
|
|
53
|
+
* `setConfig` refuse it rather than write it to disk.
|
|
54
|
+
*/
|
|
55
|
+
const shellInitScripts = (value) => {
|
|
56
|
+
if (!Array.isArray(value))
|
|
57
|
+
return undefined;
|
|
58
|
+
const list = [];
|
|
59
|
+
for (const entry of value) {
|
|
60
|
+
const one = bag(entry);
|
|
61
|
+
if ((one.shell !== 'bash' && one.shell !== 'powershell') || typeof one.script !== 'string')
|
|
62
|
+
return undefined;
|
|
63
|
+
if (one.script.length === 0 || one.script.length > MAX_SHELL_INIT_SCRIPT)
|
|
64
|
+
return undefined;
|
|
65
|
+
list.push({ shell: one.shell, script: one.script });
|
|
66
|
+
}
|
|
67
|
+
return list;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* What goes in front of a shell command while a script is in force.
|
|
71
|
+
*
|
|
72
|
+
* Sourced, so what it sets is there for the command; its stderr dropped, as
|
|
73
|
+
* the reference runtime drops it; and a nonzero status reported rather than
|
|
74
|
+
* hidden, since a profile that fails is something the model should hear.
|
|
75
|
+
*/
|
|
76
|
+
const sourcing = (path) => `{ . '${path.replaceAll("'", "'\\''")}'; } 2>/dev/null || printf 'shell init script exited %s\\n' "$?"`;
|
|
77
|
+
/** The CLI's sandbox setting for the reference host's three words; `null` clears it back to the settings files. */
|
|
78
|
+
const sandboxOf = (value) => (value === 'on' ? { enabled: true } : value === 'off' ? { enabled: false } : null);
|
|
42
79
|
/**
|
|
43
80
|
* What a tool call is *about*, in one line.
|
|
44
81
|
*
|
|
@@ -498,6 +535,48 @@ export function createSession(options) {
|
|
|
498
535
|
* backend declared a string are narrowed where they are read.
|
|
499
536
|
*/
|
|
500
537
|
const settings = { permissionMode: 'default', ...options.settings };
|
|
538
|
+
/*
|
|
539
|
+
* The shell init script, on disk where a shell can source it.
|
|
540
|
+
*
|
|
541
|
+
* The reference client pushes `shellInitScripts` for the profile and the
|
|
542
|
+
* Python environment it has selected, and the SDK's shell tool has no
|
|
543
|
+
* setting for one - so a `PreToolUse` hook on `Bash` puts a `source` of
|
|
544
|
+
* this file in front of every command. One path for the session's life,
|
|
545
|
+
* rewritten on each change, because the hook is built once with the query
|
|
546
|
+
* and reads the file by name. The bash entry only: the CLI's shell tool is
|
|
547
|
+
* bash on every platform it runs on.
|
|
548
|
+
*/
|
|
549
|
+
const initScript = join(tmpdir(), `ahpd-shell-init-${crypto.randomUUID()}.sh`);
|
|
550
|
+
let sourced = false;
|
|
551
|
+
const setShellInit = (value) => {
|
|
552
|
+
const list = shellInitScripts(value);
|
|
553
|
+
if (list === undefined)
|
|
554
|
+
return 'shellInitScripts takes a list of { shell, script }';
|
|
555
|
+
const bash = list.find((one) => one.shell === 'bash');
|
|
556
|
+
try {
|
|
557
|
+
if (bash === undefined)
|
|
558
|
+
rmSync(initScript, { force: true });
|
|
559
|
+
else
|
|
560
|
+
writeFileSync(initScript, bash.script, { mode: 0o600 });
|
|
561
|
+
}
|
|
562
|
+
catch (error) {
|
|
563
|
+
return `Could not write the shell init script: ${error instanceof Error ? error.message : String(error)}`;
|
|
564
|
+
}
|
|
565
|
+
sourced = bash !== undefined;
|
|
566
|
+
settings.shellInitScripts = list;
|
|
567
|
+
return true;
|
|
568
|
+
};
|
|
569
|
+
if (settings.shellInitScripts !== undefined)
|
|
570
|
+
setShellInit(settings.shellInitScripts);
|
|
571
|
+
const sourceFirst = async (input) => {
|
|
572
|
+
if (!sourced || input.hook_event_name !== 'PreToolUse')
|
|
573
|
+
return {};
|
|
574
|
+
const given = bag(input.tool_input);
|
|
575
|
+
const command = str(given.command);
|
|
576
|
+
if (command === undefined)
|
|
577
|
+
return {};
|
|
578
|
+
return { hookSpecificOutput: { hookEventName: 'PreToolUse', updatedInput: { ...given, command: `${sourcing(initScript)}\n${command}` } } };
|
|
579
|
+
};
|
|
501
580
|
/**
|
|
502
581
|
* The MCP server a tool belongs to, out of its name.
|
|
503
582
|
*
|
|
@@ -866,12 +945,17 @@ export function createSession(options) {
|
|
|
866
945
|
const contributor = from === undefined
|
|
867
946
|
? undefined
|
|
868
947
|
: { kind: 'mcp', customizationId: `mcp:${from}` };
|
|
948
|
+
// What kind of row to draw, from the name and from the first frame:
|
|
949
|
+
// a client that waited for the arguments to know it was a shell
|
|
950
|
+
// command would draw a generic box and then redraw it.
|
|
951
|
+
const meta = toolMetaOf(name);
|
|
869
952
|
const call = {
|
|
870
953
|
toolCallId: id,
|
|
871
954
|
toolName: name,
|
|
872
955
|
displayName: name,
|
|
873
956
|
status: 'streaming',
|
|
874
957
|
...(contributor ? { contributor } : {}),
|
|
958
|
+
...(meta ? { _meta: meta } : {}),
|
|
875
959
|
};
|
|
876
960
|
const part = { id, kind: 'toolCall', toolCall: call };
|
|
877
961
|
parts.set(id, part);
|
|
@@ -883,6 +967,7 @@ export function createSession(options) {
|
|
|
883
967
|
toolName: name,
|
|
884
968
|
displayName: name,
|
|
885
969
|
...(contributor ? { contributor } : {}),
|
|
970
|
+
...(meta ? { _meta: meta } : {}),
|
|
886
971
|
});
|
|
887
972
|
return;
|
|
888
973
|
}
|
|
@@ -999,12 +1084,14 @@ export function createSession(options) {
|
|
|
999
1084
|
// up waiting on a sign-in rather than on its own work.
|
|
1000
1085
|
if (from !== undefined)
|
|
1001
1086
|
onServer.set(id, { server: from, turnId: str(turn.id) ?? '', blocked: false });
|
|
1087
|
+
const meta = toolMetaOf(name);
|
|
1002
1088
|
const call = open !== undefined ? bag(open.toolCall) : {
|
|
1003
1089
|
toolCallId: id,
|
|
1004
1090
|
toolName: name,
|
|
1005
1091
|
displayName: name,
|
|
1006
1092
|
status: 'running',
|
|
1007
1093
|
...(contributor ? { contributor } : {}),
|
|
1094
|
+
...(meta ? { _meta: meta } : {}),
|
|
1008
1095
|
/*
|
|
1009
1096
|
* On the call, and not only on the action that announces it.
|
|
1010
1097
|
*
|
|
@@ -1056,6 +1143,7 @@ export function createSession(options) {
|
|
|
1056
1143
|
toolName: name,
|
|
1057
1144
|
displayName: name,
|
|
1058
1145
|
...(contributor ? { contributor } : {}),
|
|
1146
|
+
...(meta ? { _meta: meta } : {}),
|
|
1059
1147
|
});
|
|
1060
1148
|
}
|
|
1061
1149
|
emit('chat', {
|
|
@@ -1138,6 +1226,24 @@ export function createSession(options) {
|
|
|
1138
1226
|
* itself, and it is checked against the state it completes.
|
|
1139
1227
|
*/
|
|
1140
1228
|
Object.assign(call, result);
|
|
1229
|
+
/*
|
|
1230
|
+
* The progress line goes with the running state it described.
|
|
1231
|
+
*
|
|
1232
|
+
* Meaningful only while the call runs, and a completed row that still
|
|
1233
|
+
* carries "Running Grep" is a row that says two things. Sent on the
|
|
1234
|
+
* completion only when there was one to take off, because an action
|
|
1235
|
+
* carrying `_meta` replaces the bag whole and an absent one leaves
|
|
1236
|
+
* the kind stamped at the start alone.
|
|
1237
|
+
*/
|
|
1238
|
+
const meta = bag(call._meta);
|
|
1239
|
+
const progressed = meta.progressMessage !== undefined;
|
|
1240
|
+
if (progressed) {
|
|
1241
|
+
const { progressMessage: _gone, ...rest } = meta;
|
|
1242
|
+
if (Object.keys(rest).length > 0)
|
|
1243
|
+
call._meta = rest;
|
|
1244
|
+
else
|
|
1245
|
+
delete call._meta;
|
|
1246
|
+
}
|
|
1141
1247
|
// And as it is now the tool has run. Paired with the `before` above by
|
|
1142
1248
|
// the call's own id, which is the only thing that survives the gap.
|
|
1143
1249
|
const changed = id === undefined ? undefined : editing.get(id);
|
|
@@ -1150,6 +1256,7 @@ export function createSession(options) {
|
|
|
1150
1256
|
turnId: active?.id,
|
|
1151
1257
|
toolCallId: id,
|
|
1152
1258
|
result,
|
|
1259
|
+
...(progressed ? { _meta: call._meta ?? {} } : {}),
|
|
1153
1260
|
});
|
|
1154
1261
|
}
|
|
1155
1262
|
};
|
|
@@ -1241,11 +1348,13 @@ export function createSession(options) {
|
|
|
1241
1348
|
// The call the assistant message opened, if it arrived first. Which of
|
|
1242
1349
|
// the two comes first is the CLI's business; either order is one call.
|
|
1243
1350
|
const held = parts.get(id);
|
|
1351
|
+
const meta = toolMetaOf(toolName);
|
|
1244
1352
|
const call = held ? bag(held.toolCall) : {
|
|
1245
1353
|
toolCallId: id,
|
|
1246
1354
|
toolName,
|
|
1247
1355
|
displayName,
|
|
1248
1356
|
...(command ? { toolInput: command } : {}),
|
|
1357
|
+
...(meta ? { _meta: meta } : {}),
|
|
1249
1358
|
};
|
|
1250
1359
|
call.status = 'pending-confirmation';
|
|
1251
1360
|
call.confirmationTitle = confirmationTitle;
|
|
@@ -1257,7 +1366,10 @@ export function createSession(options) {
|
|
|
1257
1366
|
const part = { id, kind: 'toolCall', toolCall: call };
|
|
1258
1367
|
parts.set(id, part);
|
|
1259
1368
|
holdPart(turn, part);
|
|
1260
|
-
emit('chat', {
|
|
1369
|
+
emit('chat', {
|
|
1370
|
+
type: 'chat/toolCallStart', turnId: turn.id, toolCallId: id, toolName, displayName,
|
|
1371
|
+
...(meta ? { _meta: meta } : {}),
|
|
1372
|
+
});
|
|
1261
1373
|
}
|
|
1262
1374
|
emit('chat', {
|
|
1263
1375
|
type: 'chat/toolCallReady',
|
|
@@ -1301,6 +1413,17 @@ export function createSession(options) {
|
|
|
1301
1413
|
* `setMcpServers` does not touch servers that came from a settings file.
|
|
1302
1414
|
*/
|
|
1303
1415
|
...(Object.keys(declared).length > 0 ? { mcpServers: declared } : {}),
|
|
1416
|
+
/*
|
|
1417
|
+
* What the host wants said, after the CLI's own prompt.
|
|
1418
|
+
*
|
|
1419
|
+
* The preset with an `append`, not a prompt of this backend's own: the
|
|
1420
|
+
* CLI's prompt is what makes it the CLI. `snapshot`, so the prompt is
|
|
1421
|
+
* recorded once for the conversation and a resume does not rewrite it
|
|
1422
|
+
* under the model's reasoning.
|
|
1423
|
+
*/
|
|
1424
|
+
...(options.instructions && options.instructions.length > 0
|
|
1425
|
+
? { systemPrompt: { type: 'preset', preset: 'claude_code', append: options.instructions.join('\n\n'), snapshot: true } }
|
|
1426
|
+
: {}),
|
|
1304
1427
|
includePartialMessages: true,
|
|
1305
1428
|
/*
|
|
1306
1429
|
* Over the daemon's own environment, never instead of it.
|
|
@@ -1316,6 +1439,11 @@ export function createSession(options) {
|
|
|
1316
1439
|
// From the settings, which is where it lives: it is a config key like
|
|
1317
1440
|
// the others, and a second way in was a second thing to keep in step.
|
|
1318
1441
|
...(typeof settings.permissionMode === 'string' ? { permissionMode: settings.permissionMode } : {}),
|
|
1442
|
+
// The flag settings layer, which `applyFlagSettings` moves later: one
|
|
1443
|
+
// place for the sandbox, whether it was set at creation or since.
|
|
1444
|
+
...(sandboxOf(settings.sandboxEnabled) !== null ? { settings: { sandbox: sandboxOf(settings.sandboxEnabled) } } : {}),
|
|
1445
|
+
// Before every shell command, while a client has a script in force.
|
|
1446
|
+
hooks: { PreToolUse: [{ matcher: 'Bash', hooks: [sourceFirst] }] },
|
|
1319
1447
|
/*
|
|
1320
1448
|
* The lists, at the moment the query is built.
|
|
1321
1449
|
*
|
|
@@ -1397,7 +1525,7 @@ export function createSession(options) {
|
|
|
1397
1525
|
* remembers giving.
|
|
1398
1526
|
*/
|
|
1399
1527
|
const ends = new Map();
|
|
1400
|
-
const beginTurn = (turnId, text, model, queuedMessageId) => {
|
|
1528
|
+
const beginTurn = (turnId, text, model, queuedMessageId, from) => {
|
|
1401
1529
|
if (model !== undefined && model.id !== chosen) {
|
|
1402
1530
|
chosen = model.id;
|
|
1403
1531
|
void handle.setModel(model.id === 'default' ? undefined : model.id).catch(() => { });
|
|
@@ -1422,7 +1550,8 @@ export function createSession(options) {
|
|
|
1422
1550
|
startedAt: new Date().toISOString(),
|
|
1423
1551
|
message: {
|
|
1424
1552
|
text,
|
|
1425
|
-
origin: { kind: 'user' },
|
|
1553
|
+
origin: from?.origin ?? { kind: 'user' },
|
|
1554
|
+
...(from?._meta ? { _meta: from._meta } : {}),
|
|
1426
1555
|
...(chosen ? { model: { id: chosen, ...(model?.config ? { config: model.config } : {}) } } : {}),
|
|
1427
1556
|
},
|
|
1428
1557
|
responseParts: [],
|
|
@@ -1480,7 +1609,14 @@ export function createSession(options) {
|
|
|
1480
1609
|
let model;
|
|
1481
1610
|
if (id !== undefined)
|
|
1482
1611
|
model = named.config ? { id, config: named.config } : { id };
|
|
1483
|
-
|
|
1612
|
+
// With whose it was: a message an agent queued is still an agent's when
|
|
1613
|
+
// its turn comes.
|
|
1614
|
+
const from = {};
|
|
1615
|
+
if (message.origin !== undefined)
|
|
1616
|
+
from.origin = bag(message.origin);
|
|
1617
|
+
if (message._meta !== undefined)
|
|
1618
|
+
from._meta = bag(message._meta);
|
|
1619
|
+
beginTurn(crypto.randomUUID(), str(message.text) ?? '', model, str(next.id), from);
|
|
1484
1620
|
};
|
|
1485
1621
|
/**
|
|
1486
1622
|
* Ask the CLI what it can do, without asking it to do anything.
|
|
@@ -1699,6 +1835,39 @@ export function createSession(options) {
|
|
|
1699
1835
|
if (entry !== undefined)
|
|
1700
1836
|
ends.set(String(active.id), entry);
|
|
1701
1837
|
}
|
|
1838
|
+
/*
|
|
1839
|
+
* A running subagent, saying how far it has got.
|
|
1840
|
+
*
|
|
1841
|
+
* `task_progress` is the harness's own status line for a `Task`
|
|
1842
|
+
* that is still running: a model-written summary when the option
|
|
1843
|
+
* is on, or the last tool it reached for. It goes on the call as
|
|
1844
|
+
* `_meta.progressMessage` - the reference client's word for a line
|
|
1845
|
+
* drawn on a running row and dropped when the row ends - and never
|
|
1846
|
+
* into the result, which is what the tool answered and not what it
|
|
1847
|
+
* was doing on the way. The reducer replaces a call's whole `_meta`
|
|
1848
|
+
* on any action that carries one, so the kind stamped at the start
|
|
1849
|
+
* is carried along rather than lost. The same line twice is said
|
|
1850
|
+
* once.
|
|
1851
|
+
*/
|
|
1852
|
+
if (type === 'system' && str(message.subtype) === 'task_progress') {
|
|
1853
|
+
const id = str(message.tool_use_id);
|
|
1854
|
+
const part = id === undefined ? undefined : parts.get(id);
|
|
1855
|
+
const call = part === undefined ? undefined : bag(part.toolCall);
|
|
1856
|
+
const line = str(message.summary)
|
|
1857
|
+
?? (str(message.last_tool_name) !== undefined ? `Running ${String(message.last_tool_name)}` : undefined);
|
|
1858
|
+
if (call !== undefined && line !== undefined && str(call.status) === 'running'
|
|
1859
|
+
&& str(bag(call._meta).progressMessage) !== line) {
|
|
1860
|
+
call._meta = { ...bag(call._meta), progressMessage: line };
|
|
1861
|
+
emit('chat', {
|
|
1862
|
+
type: 'chat/toolCallContentChanged',
|
|
1863
|
+
turnId: active?.id,
|
|
1864
|
+
toolCallId: id,
|
|
1865
|
+
content: list(call.content),
|
|
1866
|
+
_meta: call._meta,
|
|
1867
|
+
});
|
|
1868
|
+
}
|
|
1869
|
+
continue;
|
|
1870
|
+
}
|
|
1702
1871
|
if (type === 'stream_event') {
|
|
1703
1872
|
streamed(bag(message.event));
|
|
1704
1873
|
continue;
|
|
@@ -1921,7 +2090,16 @@ export function createSession(options) {
|
|
|
1921
2090
|
settings.permissions = held;
|
|
1922
2091
|
return true;
|
|
1923
2092
|
}
|
|
2093
|
+
if (key === 'shellInitScripts')
|
|
2094
|
+
return setShellInit(value);
|
|
1924
2095
|
const said = typeof value === 'string' ? value : '';
|
|
2096
|
+
if (key === 'sandboxEnabled') {
|
|
2097
|
+
if (said !== 'default' && said !== 'on' && said !== 'off')
|
|
2098
|
+
return `sandboxEnabled takes default, on or off, not ${said}`;
|
|
2099
|
+
settings.sandboxEnabled = said;
|
|
2100
|
+
void handle.applyFlagSettings({ sandbox: sandboxOf(said) }).catch(() => { });
|
|
2101
|
+
return true;
|
|
2102
|
+
}
|
|
1925
2103
|
if (key === 'model') {
|
|
1926
2104
|
try {
|
|
1927
2105
|
await handle.setModel(said === 'default' ? undefined : said);
|
|
@@ -2106,7 +2284,9 @@ export function createSession(options) {
|
|
|
2106
2284
|
* that cannot, because the transcript would then credit a turn to a model
|
|
2107
2285
|
* that never ran it.
|
|
2108
2286
|
*/
|
|
2109
|
-
begin: (turnId, text, model) => beginTurn(turnId, text, model),
|
|
2287
|
+
begin: (turnId, text, model, from) => beginTurn(turnId, text, model, undefined, from),
|
|
2288
|
+
setTitle: (said) => { if (said !== '')
|
|
2289
|
+
title = said; },
|
|
2110
2290
|
/**
|
|
2111
2291
|
* A turn this host answered itself, with a shell rather than the agent.
|
|
2112
2292
|
*
|
|
@@ -2159,11 +2339,15 @@ export function createSession(options) {
|
|
|
2159
2339
|
// The person typed it themselves, so there is nobody left to ask.
|
|
2160
2340
|
confirmed: 'not-needed',
|
|
2161
2341
|
status: 'running',
|
|
2342
|
+
_meta: { toolKind: 'terminal' },
|
|
2162
2343
|
};
|
|
2163
|
-
|
|
2344
|
+
// As a part, the way every other call is held: the bare call went
|
|
2345
|
+
// into the snapshot with no `kind`, so a client that subscribed after
|
|
2346
|
+
// the command ran had a row it could not draw.
|
|
2347
|
+
holdPart(turn, { id: toolCallId, kind: 'toolCall', toolCall: call });
|
|
2164
2348
|
emit('chat', {
|
|
2165
2349
|
type: 'chat/toolCallStart', turnId, toolCallId, toolName: 'terminal',
|
|
2166
|
-
displayName: 'Terminal', intention: command,
|
|
2350
|
+
displayName: 'Terminal', intention: command, _meta: { toolKind: 'terminal' },
|
|
2167
2351
|
});
|
|
2168
2352
|
emit('chat', {
|
|
2169
2353
|
type: 'chat/toolCallReady', turnId, toolCallId,
|
|
@@ -2256,12 +2440,13 @@ export function createSession(options) {
|
|
|
2256
2440
|
* immediately started, which is a queue entry a client sees appear and
|
|
2257
2441
|
* leave rather than one that was never there.
|
|
2258
2442
|
*/
|
|
2259
|
-
queue: (id, text, model) => {
|
|
2443
|
+
queue: (id, text, model, from) => {
|
|
2260
2444
|
const entry = {
|
|
2261
2445
|
id,
|
|
2262
2446
|
message: {
|
|
2263
2447
|
text,
|
|
2264
|
-
origin: { kind: 'user' },
|
|
2448
|
+
origin: from?.origin ?? { kind: 'user' },
|
|
2449
|
+
...(from?._meta ? { _meta: from._meta } : {}),
|
|
2265
2450
|
...(model ? { model: { id: model.id, ...(model.config ? { config: model.config } : {}) } } : {}),
|
|
2266
2451
|
},
|
|
2267
2452
|
};
|
|
@@ -2575,6 +2760,10 @@ export function createSession(options) {
|
|
|
2575
2760
|
one.settle({ behavior: 'deny', message: 'The session was disposed' });
|
|
2576
2761
|
}
|
|
2577
2762
|
releaseCalls('The session was disposed');
|
|
2763
|
+
try {
|
|
2764
|
+
rmSync(initScript, { force: true });
|
|
2765
|
+
}
|
|
2766
|
+
catch { /* a script that was never written */ }
|
|
2578
2767
|
handle.close();
|
|
2579
2768
|
},
|
|
2580
2769
|
};
|