@sayknow-cli/coding-agent 0.5.1 → 0.5.6
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 +185 -14
- package/dist/types/cli/update-cli.d.ts +8 -1
- package/dist/types/commands/session.d.ts +7 -0
- package/dist/types/config/atomic-yaml-patch.d.ts +20 -1
- package/dist/types/config/keybindings.d.ts +10 -0
- package/dist/types/config/model-registry.d.ts +1 -1
- package/dist/types/config/models-config-schema.d.ts +4 -0
- package/dist/types/config/settings-schema.d.ts +9 -0
- package/dist/types/config/telegram-autostart.d.ts +9 -1
- package/dist/types/dap/client.d.ts +1 -0
- package/dist/types/lsp/client.d.ts +5 -0
- package/dist/types/modes/components/pet-capability.d.ts +8 -7
- package/dist/types/modes/components/pet-selector.d.ts +1 -1
- package/dist/types/modes/components/sayknow-pet-widget.d.ts +1 -1
- package/dist/types/modes/components/welcome.d.ts +1 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +3 -1
- package/dist/types/modes/interactive-mode.d.ts +13 -1
- package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +7 -0
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +2 -0
- package/dist/types/modes/types.d.ts +7 -1
- package/dist/types/runtime-mcp/transports/stdio.d.ts +2 -0
- package/dist/types/session/agent-session.d.ts +9 -0
- package/dist/types/session/internal/managed-session-scope.d.ts +3 -1
- package/dist/types/session/internal/managed-session-storage.d.ts +2 -0
- package/dist/types/session/session-manager.d.ts +9 -0
- package/dist/types/session/session-storage.d.ts +17 -0
- package/dist/types/session-import/claude.d.ts +26 -0
- package/dist/types/session-import/codex.d.ts +22 -0
- package/dist/types/session-import/command.d.ts +20 -0
- package/dist/types/session-import/detect.d.ts +22 -0
- package/dist/types/session-import/index.d.ts +7 -0
- package/dist/types/session-import/redact.d.ts +23 -0
- package/dist/types/session-import/service.d.ts +28 -0
- package/dist/types/session-import/types.d.ts +125 -0
- package/dist/types/skc-runtime/boot-generation.d.ts +59 -0
- package/dist/types/skc-runtime/launch-tmux.d.ts +10 -2
- package/dist/types/skc-runtime/launch-worktree.d.ts +17 -1
- package/dist/types/skc-runtime/session-restore-runtime.d.ts +41 -0
- package/dist/types/skc-runtime/session-restore.d.ts +99 -0
- package/dist/types/skc-runtime/tmux-owner-isolation.d.ts +160 -0
- package/dist/types/skc-runtime/tmux-sessions.d.ts +26 -1
- package/dist/types/slash-commands/builtin-registry.d.ts +4 -0
- package/dist/types/slash-commands/types.d.ts +5 -0
- package/dist/types/tools/ask.d.ts +169 -4
- package/package.json +16 -7
- package/scripts/generate-sdk-operation-inventory.ts +5 -6
- package/src/cli/config-cli.ts +23 -8
- package/src/cli/update-cli.ts +265 -21
- package/src/commands/session.ts +88 -2
- package/src/config/atomic-yaml-patch.ts +167 -30
- package/src/config/keybindings.ts +10 -0
- package/src/config/model-profiles.ts +69 -1
- package/src/config/model-registry.ts +72 -38
- package/src/config/models-config-schema.ts +1 -1
- package/src/config/settings-schema.ts +9 -0
- package/src/config/settings.ts +13 -2
- package/src/config/telegram-autostart.ts +11 -4
- package/src/dap/client.ts +78 -30
- package/src/defaults/skc/skills/deep-interview/SKILL.md +29 -3
- package/src/internal-urls/docs-index.generated.ts +5 -4
- package/src/lsp/client.ts +17 -29
- package/src/main.ts +1 -1
- package/src/modes/action-registry.ts +2 -0
- package/src/modes/components/pet-capability.ts +22 -13
- package/src/modes/components/pet-selector.ts +1 -1
- package/src/modes/components/sayknow-pet-widget.ts +41 -7
- package/src/modes/components/welcome.ts +5 -0
- package/src/modes/controllers/event-controller.ts +1 -1
- package/src/modes/controllers/goal-mode-controller.ts +7 -2
- package/src/modes/controllers/input-controller.ts +71 -6
- package/src/modes/controllers/plan-mode-controller.ts +8 -1
- package/src/modes/controllers/runtime-mcp-command-controller.ts +14 -0
- package/src/modes/controllers/selector-controller.ts +47 -19
- package/src/modes/interactive-mode.ts +54 -4
- package/src/modes/shared/agent-wire/unattended-session.ts +40 -9
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +2 -0
- package/src/modes/types.ts +5 -1
- package/src/notifications/lifecycle-control-runtime.ts +258 -179
- package/src/prompts/system/eager-todo.md +2 -0
- package/src/prompts/system/plan-mode-approved.md +1 -1
- package/src/prompts/system/system-prompt.md +4 -2
- package/src/runtime-mcp/transports/stdio.ts +96 -33
- package/src/sdk/broker/lifecycle.ts +6 -5
- package/src/sdk/bus/lifecycle-control-runtime.ts +189 -110
- package/src/sdk/protocol/operation-inventory.generated.json +33 -0
- package/src/sdk/session.ts +25 -18
- package/src/session/agent-session.ts +120 -25
- package/src/session/internal/managed-session-scope.ts +41 -6
- package/src/session/internal/managed-session-storage.ts +14 -0
- package/src/session/session-manager.ts +113 -11
- package/src/session/session-storage.ts +70 -0
- package/src/session-import/claude.ts +382 -0
- package/src/session-import/codex.ts +458 -0
- package/src/session-import/command.ts +61 -0
- package/src/session-import/detect.ts +133 -0
- package/src/session-import/index.ts +27 -0
- package/src/session-import/redact.ts +125 -0
- package/src/session-import/service.ts +749 -0
- package/src/session-import/types.ts +163 -0
- package/src/skc-runtime/boot-generation.ts +172 -0
- package/src/skc-runtime/launch-tmux.ts +219 -41
- package/src/skc-runtime/launch-worktree.ts +277 -4
- package/src/skc-runtime/session-restore-runtime.ts +120 -0
- package/src/skc-runtime/session-restore.ts +296 -0
- package/src/skc-runtime/session-state-sidecar.ts +41 -0
- package/src/skc-runtime/tmux-owner-isolation.ts +665 -0
- package/src/skc-runtime/tmux-sessions.ts +284 -108
- package/src/slash-commands/acp-builtins.ts +5 -1
- package/src/slash-commands/builtin-registry.ts +109 -5
- package/src/slash-commands/types.ts +5 -0
- package/src/tools/ask.ts +188 -10
- package/src/tools/eval.ts +2 -2
- package/src/export/html/template.css +0 -1060
- package/src/export/html/template.html +0 -47
- package/src/export/html/template.js +0 -2348
- package/vendor/insane-search/engine/tests/test_hardening.py +0 -57
- package/vendor/insane-search/engine/tests/test_smoke.py +0 -152
- package/vendor/insane-search/engine/tests/test_u1.py +0 -200
- package/vendor/insane-search/engine/tests/test_u4.py +0 -131
- package/vendor/insane-search/engine/tests/test_u5.py +0 -163
- package/vendor/insane-search/engine/tests/test_u7.py +0 -124
- package/vendor/insane-search/engine/tests/test_u8.py +0 -216
|
@@ -244,6 +244,8 @@ export interface AgentSessionConfig {
|
|
|
244
244
|
/** Rebuild the SSH tool from current capability discovery results. */
|
|
245
245
|
reloadSshTool?: () => Promise<AgentTool | null>;
|
|
246
246
|
requestedToolNames?: ReadonlySet<string>;
|
|
247
|
+
/** True only when the caller explicitly selected no tools. */
|
|
248
|
+
explicitlyDisabledTools?: boolean;
|
|
247
249
|
/** Optional per-session allowlist for tools exposed through search_tool_bm25. */
|
|
248
250
|
discoverableToolAllowedNames?: readonly string[];
|
|
249
251
|
/** Optional accessor for live MCP server instructions, injected as untrusted user-role request data. */
|
|
@@ -528,6 +530,7 @@ export declare class StreamingEditFileCache {
|
|
|
528
530
|
has(path: string): boolean;
|
|
529
531
|
get totalBytes(): number;
|
|
530
532
|
}
|
|
533
|
+
export declare function buildTodoWriteFailureReminder(errorText: string | undefined, failureCount: number): string;
|
|
531
534
|
export declare class AgentSession {
|
|
532
535
|
#private;
|
|
533
536
|
readonly agent: Agent;
|
|
@@ -757,6 +760,8 @@ export declare class AgentSession {
|
|
|
757
760
|
refreshSshTool(options?: {
|
|
758
761
|
activateIfAvailable?: boolean;
|
|
759
762
|
}): Promise<void>;
|
|
763
|
+
/** Whether the caller explicitly selected no tools for this session. */
|
|
764
|
+
hasExplicitlyDisabledTools(): boolean;
|
|
760
765
|
/**
|
|
761
766
|
* Set active tools by name.
|
|
762
767
|
* Only tools in the registry can be enabled. Unknown tool names are ignored.
|
|
@@ -1208,6 +1213,8 @@ export declare class AgentSession {
|
|
|
1208
1213
|
prepareContributionPrep(options?: ContributionPrepOptions): Promise<ContributionPrepResult>;
|
|
1209
1214
|
/** Test seam: override the emergency-compaction resource sampler so tests never read real RSS. */
|
|
1210
1215
|
setResourceSampler(sampler: () => EmergencyCompactionSample): void;
|
|
1216
|
+
/** Test seam: drive the pre-prompt emergency/threshold check directly. */
|
|
1217
|
+
runPrePromptContextCheckForTests(pendingMessages?: readonly AgentMessage[]): Promise<void>;
|
|
1211
1218
|
setRetainedMemorySampler(sampler: (() => RetainedMemorySample) | undefined): void;
|
|
1212
1219
|
/**
|
|
1213
1220
|
* Toggle auto-compaction setting.
|
|
@@ -1346,10 +1353,12 @@ export declare class AgentSession {
|
|
|
1346
1353
|
* Switch to a different session file.
|
|
1347
1354
|
* Aborts current operation, loads messages, restores model/thinking.
|
|
1348
1355
|
* Listeners are preserved and will continue receiving events.
|
|
1356
|
+
* `requireIdle` rejects an active turn and fences new admissions for the transition.
|
|
1349
1357
|
* @returns true if switch completed, false if cancelled by hook
|
|
1350
1358
|
*/
|
|
1351
1359
|
switchSession(sessionPath: string, options?: {
|
|
1352
1360
|
transition?: SessionSwitchEvent["transition"];
|
|
1361
|
+
requireIdle?: boolean;
|
|
1353
1362
|
}): Promise<boolean>;
|
|
1354
1363
|
/**
|
|
1355
1364
|
* Create a branch from a specific entry.
|
|
@@ -120,7 +120,9 @@ export declare function fsyncCanonicalBinding(bindingPath: string, expected: str
|
|
|
120
120
|
export declare function ensureManagedScope(scope: ManagedScope, policy?: ManagedSessionSecurityPolicy): Promise<ManagedScopeResolution>;
|
|
121
121
|
/** Synchronously create and validate the v2 binding before a default session writer exists. */
|
|
122
122
|
export declare function prepareManagedSessionScopeForWriteSync(scope: ManagedScope, policy?: ManagedSessionSecurityPolicy, authority?: ManagedCandidateWriteAuthority): ManagedScopeResolution;
|
|
123
|
-
export declare function listManagedCandidates(scope: ManagedScope
|
|
123
|
+
export declare function listManagedCandidates(scope: ManagedScope, options?: {
|
|
124
|
+
maxCandidates?: number;
|
|
125
|
+
}): ManagedCandidateListing;
|
|
124
126
|
type DetachedArtifactRoot = {
|
|
125
127
|
originalPath: string;
|
|
126
128
|
detachedPath: string;
|
|
@@ -74,6 +74,8 @@ export declare class ManagedSessionDescendantStore {
|
|
|
74
74
|
appendSync(relativePath: string, bytes: Uint8Array): void;
|
|
75
75
|
/** Read an exact managed file without exposing its pathname as authority. */
|
|
76
76
|
readExpected(relativePath: string): ManagedFileSnapshot | null;
|
|
77
|
+
/** Read only the exact managed file size through the retained root authority. */
|
|
78
|
+
sizeSync(relativePath: string): number | null;
|
|
77
79
|
/** Remove an exact captured file without reopening its pathname as authority. */
|
|
78
80
|
removeExpected(relativePath: string, expected: ManagedFileSnapshot): void;
|
|
79
81
|
/** Read and remove one managed descendant through retained authority. */
|
|
@@ -705,6 +705,12 @@ export declare class SessionManager {
|
|
|
705
705
|
listForResumePickerReadOnly(): Promise<SessionInfo[]>;
|
|
706
706
|
getSessionId(): string;
|
|
707
707
|
getSessionFile(): string | undefined;
|
|
708
|
+
/**
|
|
709
|
+
* Managed on-disk transcript size in bytes. Returns undefined when the
|
|
710
|
+
* destination is explicit, the file does not exist yet, or its identity
|
|
711
|
+
* cannot be verified.
|
|
712
|
+
*/
|
|
713
|
+
getTranscriptFileBytes(): number | undefined;
|
|
708
714
|
acquireMemoryGuardParticipantIngressLease(): MemoryGuardParticipantIngressLease;
|
|
709
715
|
createMemoryGuardCheckpoint(input: MemoryGuardCreateCheckpointInput): Promise<MemoryGuardSessionManagerCheckpointV1>;
|
|
710
716
|
/**
|
|
@@ -1048,6 +1054,9 @@ export declare class SessionManager {
|
|
|
1048
1054
|
sessionDir?: string;
|
|
1049
1055
|
storage?: SessionStorage;
|
|
1050
1056
|
destination?: SessionDestination;
|
|
1057
|
+
maxCandidates?: number;
|
|
1058
|
+
maxTotalBytes?: number;
|
|
1059
|
+
filterOtherWorkspaces?: boolean;
|
|
1051
1060
|
}): StrictInventoryResult;
|
|
1052
1061
|
/**
|
|
1053
1062
|
* Propagate the storage-layer verified hard delete bound to exact identity evidence.
|
|
@@ -110,6 +110,8 @@ export interface SessionStorage {
|
|
|
110
110
|
readBytesSync?(path: string): Uint8Array;
|
|
111
111
|
/** Exact bytes and descriptor-bound identity captured from one opened regular file. */
|
|
112
112
|
readSnapshotSync?(path: string): SessionStorageSnapshot;
|
|
113
|
+
/** Exact descriptor-bound bytes, refusing growth or allocation beyond maxBytes. */
|
|
114
|
+
readSnapshotBoundedSync?(path: string, maxBytes: number): SessionStorageSnapshot;
|
|
113
115
|
statSync(path: string): SessionStorageStat;
|
|
114
116
|
listFilesSync(dir: string, pattern: string): string[];
|
|
115
117
|
/** List matching files with mtimes without issuing one JavaScript stat call per path. */
|
|
@@ -122,6 +124,11 @@ export interface SessionStorage {
|
|
|
122
124
|
* authorization inventory; the forgiving {@link listFilesSync} stays display-only.
|
|
123
125
|
*/
|
|
124
126
|
listFilesStrictSync?(dir: string, pattern: string): string[];
|
|
127
|
+
/** Strict bounded scan; `truncated` means completeness was not granted. */
|
|
128
|
+
listFilesStrictBoundedSync?(dir: string, pattern: string, maxFiles: number): {
|
|
129
|
+
files: string[];
|
|
130
|
+
truncated: boolean;
|
|
131
|
+
};
|
|
125
132
|
exists(path: string): Promise<boolean>;
|
|
126
133
|
readText(path: string): Promise<string>;
|
|
127
134
|
readTextPrefix(path: string, maxBytes: number): Promise<string>;
|
|
@@ -270,6 +277,7 @@ export declare class FileSessionStorage implements SessionStorage {
|
|
|
270
277
|
readTextSync(fpath: string): string;
|
|
271
278
|
readBytesSync(fpath: string): Uint8Array;
|
|
272
279
|
readSnapshotSync(fpath: string): SessionStorageSnapshot;
|
|
280
|
+
readSnapshotBoundedSync(fpath: string, maxBytes: number): SessionStorageSnapshot;
|
|
273
281
|
statSync(path: string): SessionStorageStat;
|
|
274
282
|
listFilesSync(dir: string, pattern: string): string[];
|
|
275
283
|
listFilesByMtime(dir: string, pattern: string): Promise<Array<{
|
|
@@ -277,6 +285,10 @@ export declare class FileSessionStorage implements SessionStorage {
|
|
|
277
285
|
mtimeMs: number;
|
|
278
286
|
}>>;
|
|
279
287
|
listFilesStrictSync(dir: string, pattern: string): string[];
|
|
288
|
+
listFilesStrictBoundedSync(dir: string, pattern: string, maxFiles: number): {
|
|
289
|
+
files: string[];
|
|
290
|
+
truncated: boolean;
|
|
291
|
+
};
|
|
280
292
|
exists(path: string): Promise<boolean>;
|
|
281
293
|
readText(path: string): Promise<string>;
|
|
282
294
|
readTextPrefix(path: string, maxBytes: number): Promise<string>;
|
|
@@ -306,6 +318,7 @@ export declare class MemorySessionStorage implements SessionStorage {
|
|
|
306
318
|
readTextSync(path: string): string;
|
|
307
319
|
readBytesSync(path: string): Uint8Array;
|
|
308
320
|
readSnapshotSync(path: string): SessionStorageSnapshot;
|
|
321
|
+
readSnapshotBoundedSync(path: string, maxBytes: number): SessionStorageSnapshot;
|
|
309
322
|
statSync(path: string): SessionStorageStat;
|
|
310
323
|
listFilesSync(dir: string, pattern: string): string[];
|
|
311
324
|
listFilesByMtime(dir: string, pattern: string): Promise<Array<{
|
|
@@ -313,6 +326,10 @@ export declare class MemorySessionStorage implements SessionStorage {
|
|
|
313
326
|
mtimeMs: number;
|
|
314
327
|
}>>;
|
|
315
328
|
listFilesStrictSync(dir: string, pattern: string): string[];
|
|
329
|
+
listFilesStrictBoundedSync(dir: string, pattern: string, maxFiles: number): {
|
|
330
|
+
files: string[];
|
|
331
|
+
truncated: boolean;
|
|
332
|
+
};
|
|
316
333
|
exists(path: string): Promise<boolean>;
|
|
317
334
|
readText(path: string): Promise<string>;
|
|
318
335
|
readTextPrefix(path: string, maxBytes: number): Promise<string>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude adapter (issue #3709).
|
|
3
|
+
*
|
|
4
|
+
* Parses two first-party observable Claude transcript/export shapes:
|
|
5
|
+
*
|
|
6
|
+
* 1. `claude-code-jsonl` — Claude Code session transcripts
|
|
7
|
+
* (`~/.claude/projects/<project-slug>/<session-uuid>.jsonl`), one JSON object
|
|
8
|
+
* per line with `type: "user" | "assistant" | "summary" | "system" | …`.
|
|
9
|
+
* 2. `claude-export-json` — the claude.ai data export (`conversations.json`):
|
|
10
|
+
* a JSON array of conversations (or a single conversation object) whose
|
|
11
|
+
* `chat_messages` carry `sender: "human" | "assistant"` and `content` blocks.
|
|
12
|
+
*
|
|
13
|
+
* The same quarantine contract as the Codex adapter applies: unmappable
|
|
14
|
+
* records/messages are counted and digested, never silently dropped.
|
|
15
|
+
*/
|
|
16
|
+
import { type ImportedConversation, type ImportQuarantineRecord, type SessionImportCounts } from "./types";
|
|
17
|
+
export interface ClaudeParseResult {
|
|
18
|
+
conversation: ImportedConversation;
|
|
19
|
+
quarantine: ImportQuarantineRecord[];
|
|
20
|
+
counts: SessionImportCounts;
|
|
21
|
+
redactionKinds: string[];
|
|
22
|
+
}
|
|
23
|
+
/** Parse a Claude Code session JSONL transcript. */
|
|
24
|
+
export declare function parseClaudeCodeTranscript(text: string): ClaudeParseResult;
|
|
25
|
+
/** Parse a claude.ai data-export conversation (array or single object). */
|
|
26
|
+
export declare function parseClaudeExport(text: string): ClaudeParseResult;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex adapter (issue #3709).
|
|
3
|
+
*
|
|
4
|
+
* Parses the Codex CLI rollout transcript: one JSON object per line
|
|
5
|
+
* (`rollout-*.jsonl`, e.g. `~/.codex/sessions/2026/08/01/rollout-….jsonl`).
|
|
6
|
+
* This is Codex's own observable transcript format; the file the user passes is
|
|
7
|
+
* treated as an explicit export and is only read.
|
|
8
|
+
*
|
|
9
|
+
* Strictness contract: records that fail to parse or lack required fields are
|
|
10
|
+
* quarantined with deterministic digests — never silently dropped. Unknown
|
|
11
|
+
* record/event types are mapped when their payload shape is recognized and
|
|
12
|
+
* quarantined otherwise.
|
|
13
|
+
*/
|
|
14
|
+
import { type ImportedConversation, type ImportQuarantineRecord, type SessionImportCounts } from "./types";
|
|
15
|
+
export interface CodexParseResult {
|
|
16
|
+
conversation: ImportedConversation;
|
|
17
|
+
quarantine: ImportQuarantineRecord[];
|
|
18
|
+
counts: SessionImportCounts;
|
|
19
|
+
redactionKinds: string[];
|
|
20
|
+
}
|
|
21
|
+
/** Parse a Codex rollout JSONL transcript into the provider-neutral IR. */
|
|
22
|
+
export declare function parseCodexRollout(text: string): CodexParseResult;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { SessionImportCompleted, SessionImportProviderId } from "./types";
|
|
2
|
+
export declare const IMPORT_SESSION_USAGE = "Usage: /import-session <transcript-file> [--provider codex|claude]";
|
|
3
|
+
export type ParsedImportSessionArgs = {
|
|
4
|
+
kind: "ok";
|
|
5
|
+
sourcePath: string;
|
|
6
|
+
provider?: SessionImportProviderId;
|
|
7
|
+
} | {
|
|
8
|
+
kind: "error";
|
|
9
|
+
message: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function parseImportSessionArgs(args: string): ParsedImportSessionArgs;
|
|
12
|
+
export type SessionImportCommandOutcome = {
|
|
13
|
+
kind: "imported";
|
|
14
|
+
result: SessionImportCompleted;
|
|
15
|
+
} | {
|
|
16
|
+
kind: "error";
|
|
17
|
+
message: string;
|
|
18
|
+
};
|
|
19
|
+
/** Imports a new session only. The caller owns the current-session switch/resume seam. */
|
|
20
|
+
export declare function runSessionImportCommand(args: string, cwd: string): Promise<SessionImportCommandOutcome>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic source-format detection (issue #3709).
|
|
3
|
+
*
|
|
4
|
+
* Detection inspects only the already-read source bytes: a bounded leading
|
|
5
|
+
* sample decides JSONL-vs-JSON and provider by envelope markers. An explicit
|
|
6
|
+
* `--provider` selection narrows candidates; a sample that matches a different
|
|
7
|
+
* provider than requested fails closed with `format_mismatch`. Detection never
|
|
8
|
+
* guesses: a sample matching no supported envelope fails with
|
|
9
|
+
* `unsupported_format` rather than falling back to a speculative parse.
|
|
10
|
+
*/
|
|
11
|
+
import { type SessionImportFormatId, type SessionImportProviderId } from "./types";
|
|
12
|
+
export interface SessionImportDetection {
|
|
13
|
+
provider: SessionImportProviderId;
|
|
14
|
+
format: SessionImportFormatId;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Detect the provider/format of an explicit transcript file.
|
|
18
|
+
*
|
|
19
|
+
* @param text Full source text (already size-bounded by the caller).
|
|
20
|
+
* @param requestedProvider Explicit provider selection; undefined = auto.
|
|
21
|
+
*/
|
|
22
|
+
export declare function detectSessionImportFormat(text: string, requestedProvider?: SessionImportProviderId): SessionImportDetection;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { type ClaudeParseResult, parseClaudeCodeTranscript, parseClaudeExport } from "./claude";
|
|
2
|
+
export { type CodexParseResult, parseCodexRollout } from "./codex";
|
|
3
|
+
export { IMPORT_SESSION_USAGE, type ParsedImportSessionArgs, parseImportSessionArgs, runSessionImportCommand, type SessionImportCommandOutcome, } from "./command";
|
|
4
|
+
export { detectSessionImportFormat, type SessionImportDetection } from "./detect";
|
|
5
|
+
export { IMPORT_SANITIZER_VERSION, redactImportedText, sanitizeImportedString } from "./redact";
|
|
6
|
+
export { formatSessionImportError, formatSessionImportSummary, IMPORT_CONVERTER_VERSION, importExternalSession, materializeSessionImport, prepareSessionImport, SESSION_IMPORT_COMPLETION_CUSTOM_TYPE, SESSION_IMPORT_CONTEXT_CUSTOM_TYPE, SESSION_IMPORT_PROVENANCE_CUSTOM_TYPE, SESSION_IMPORT_QUARANTINE_CUSTOM_TYPE, SESSION_IMPORT_SOURCE_MAX_BYTES, type SessionImportRequest, type SessionImportTestProbe, } from "./service";
|
|
7
|
+
export * from "./types";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fail-closed secret redaction for imported session content (issue #3709).
|
|
3
|
+
*
|
|
4
|
+
* Every string that crosses the import boundary passes through
|
|
5
|
+
* {@link redactImportedText}. Patterns are conservative: a false positive costs
|
|
6
|
+
* one `[REDACTED]` span in reconstructed context, a false negative leaks a
|
|
7
|
+
* credential into a new session transcript, so the balance favors redaction.
|
|
8
|
+
*/
|
|
9
|
+
export declare const IMPORT_REDACTED_PLACEHOLDER = "[REDACTED]";
|
|
10
|
+
/** Bumped when patterns change; persisted in import provenance. */
|
|
11
|
+
export declare const IMPORT_SANITIZER_VERSION = 3;
|
|
12
|
+
export interface ImportRedactionResult {
|
|
13
|
+
value: string;
|
|
14
|
+
redacted: number;
|
|
15
|
+
kinds: string[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Redact every known credential shape from imported text. The same placeholder
|
|
19
|
+
* is used for all kinds so a partial pattern overlap cannot leak fragments.
|
|
20
|
+
*/
|
|
21
|
+
export declare function redactImportedText(input: string): ImportRedactionResult;
|
|
22
|
+
/** Redact a string, returning only the sanitized value. */
|
|
23
|
+
export declare function sanitizeImportedString(input: string): string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type SessionDestinationInput } from "../session/session-manager";
|
|
2
|
+
import { type PreparedSessionImport, type SessionImportCompleted, type SessionImportProviderId } from "./types";
|
|
3
|
+
export declare const IMPORT_CONVERTER_VERSION = 1;
|
|
4
|
+
/** Durable metadata only; it is not added to model context. */
|
|
5
|
+
export declare const SESSION_IMPORT_PROVENANCE_CUSTOM_TYPE = "session-import";
|
|
6
|
+
export declare const SESSION_IMPORT_QUARANTINE_CUSTOM_TYPE = "session-import-quarantine";
|
|
7
|
+
export declare const SESSION_IMPORT_COMPLETION_CUSTOM_TYPE = "session-import-complete";
|
|
8
|
+
/** Displayed custom-message context reconstructed from the imported transcript. */
|
|
9
|
+
export declare const SESSION_IMPORT_CONTEXT_CUSTOM_TYPE = "session-import";
|
|
10
|
+
export declare const SESSION_IMPORT_SOURCE_MAX_BYTES: number;
|
|
11
|
+
export interface SessionImportRequest {
|
|
12
|
+
sourcePath: string;
|
|
13
|
+
provider?: SessionImportProviderId;
|
|
14
|
+
cwd: string;
|
|
15
|
+
destination?: SessionDestinationInput;
|
|
16
|
+
now?: () => Date;
|
|
17
|
+
}
|
|
18
|
+
/** Invocation-scoped mutation seam used only by TOCTOU regression tests. */
|
|
19
|
+
export interface SessionImportTestProbe {
|
|
20
|
+
afterSourceOpen?: (resolvedSourcePath: string) => void | Promise<void>;
|
|
21
|
+
afterSourceIdentityCheck?: (resolvedSourcePath: string) => void | Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
/** Read, detect, parse, normalize, redact, and bound without session mutation. */
|
|
24
|
+
export declare function prepareSessionImport(request: Pick<SessionImportRequest, "sourcePath" | "provider">, testProbe?: SessionImportTestProbe): Promise<PreparedSessionImport>;
|
|
25
|
+
export declare function importExternalSession(request: SessionImportRequest): Promise<SessionImportCompleted>;
|
|
26
|
+
export declare function materializeSessionImport(prepared: PreparedSessionImport, options: Pick<SessionImportRequest, "cwd" | "destination" | "now">): Promise<SessionImportCompleted>;
|
|
27
|
+
export declare function formatSessionImportSummary(result: SessionImportCompleted): string;
|
|
28
|
+
export declare function formatSessionImportError(error: unknown): string;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-neutral session-import contract (issue #3709).
|
|
3
|
+
*
|
|
4
|
+
* An import accepts ONE explicit user-selected Codex or Claude transcript/export
|
|
5
|
+
* file, normalizes it into the intermediate representation below, and rebuilds a
|
|
6
|
+
* bounded, redacted continuation context in one workspace-scoped native SKC
|
|
7
|
+
* session. A verified identical import is reused; otherwise a new session is
|
|
8
|
+
* published. The source file is only ever read; provider process state is never scraped.
|
|
9
|
+
*/
|
|
10
|
+
/** Providers with a first-party observable transcript/export format. */
|
|
11
|
+
export type SessionImportProviderId = "codex" | "claude";
|
|
12
|
+
/** Concrete on-disk format variants the adapters understand. */
|
|
13
|
+
export type SessionImportFormatId = "codex-rollout-jsonl" | "claude-code-jsonl" | "claude-export-json";
|
|
14
|
+
/** Maximum quarantined-record digests retained in memory during import. */
|
|
15
|
+
export declare const SESSION_IMPORT_QUARANTINE_MAX_RECORDS = 512;
|
|
16
|
+
/** One normalized conversational unit produced by a provider adapter. */
|
|
17
|
+
export interface ImportedMessage {
|
|
18
|
+
/** Conversational role. Tool evidence is attached to assistant turns. */
|
|
19
|
+
role: "user" | "assistant";
|
|
20
|
+
/** Visible text (may be empty when only tool evidence exists). */
|
|
21
|
+
text: string;
|
|
22
|
+
/** ISO-8601 source timestamp when the record carried one. */
|
|
23
|
+
timestamp?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Bounded, already redacted tool/file evidence lines (e.g. `$ ls` → `ok`).
|
|
26
|
+
* Rendered inline after the text so completed work stays visible.
|
|
27
|
+
*/
|
|
28
|
+
toolEvidence?: string[];
|
|
29
|
+
}
|
|
30
|
+
/** Provider-neutral normalized conversation. */
|
|
31
|
+
export interface ImportedConversation {
|
|
32
|
+
provider: SessionImportProviderId;
|
|
33
|
+
format: SessionImportFormatId;
|
|
34
|
+
/** Source-side session/conversation identifier when the format carries one. */
|
|
35
|
+
sourceSessionId?: string;
|
|
36
|
+
/** Source title when the format carries one. */
|
|
37
|
+
title?: string;
|
|
38
|
+
/** Source workspace cwd when the format carries one. */
|
|
39
|
+
cwd?: string;
|
|
40
|
+
messages: ImportedMessage[];
|
|
41
|
+
}
|
|
42
|
+
/** Deterministic, actionable import failure codes. */
|
|
43
|
+
export type SessionImportErrorCode = "invalid_request" | "source_not_found" | "source_unreadable" | "source_changed" | "unsupported_format" | "format_mismatch" | "malformed_input" | "content_too_large" | "destination_conflict" | "io_failed";
|
|
44
|
+
/** Import pipeline phase a failure belongs to. */
|
|
45
|
+
export type SessionImportPhase = "request" | "read" | "detect" | "parse" | "normalize" | "persist" | "cleanup" | "switch";
|
|
46
|
+
export declare class SessionImportError extends Error {
|
|
47
|
+
readonly code: SessionImportErrorCode;
|
|
48
|
+
readonly phase: SessionImportPhase;
|
|
49
|
+
readonly retryable: boolean;
|
|
50
|
+
readonly limitBytes?: number;
|
|
51
|
+
readonly observedBytes?: number;
|
|
52
|
+
constructor(code: SessionImportErrorCode, phase: SessionImportPhase, message: string, options?: {
|
|
53
|
+
retryable?: boolean;
|
|
54
|
+
limitBytes?: number;
|
|
55
|
+
observedBytes?: number;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/** One record the adapter could not map. Never carries raw content. */
|
|
59
|
+
export interface ImportQuarantineRecord {
|
|
60
|
+
/** 1-based record/line number in the source. */
|
|
61
|
+
record: number;
|
|
62
|
+
byteLength: number;
|
|
63
|
+
sha256: string;
|
|
64
|
+
reason: "invalid_json" | "unknown_record" | "missing_fields" | "oversized_record";
|
|
65
|
+
}
|
|
66
|
+
/** Bounded tallies reported to the user and persisted in provenance. */
|
|
67
|
+
export interface SessionImportCounts {
|
|
68
|
+
/** Records successfully mapped into the normalized conversation. */
|
|
69
|
+
mapped: number;
|
|
70
|
+
/** Records quarantined (never silently dropped). */
|
|
71
|
+
quarantined: number;
|
|
72
|
+
/** Secret/credential redactions applied to imported text. */
|
|
73
|
+
redacted: number;
|
|
74
|
+
/** Messages omitted from the rendered context by head/tail bounding. */
|
|
75
|
+
omitted: number;
|
|
76
|
+
}
|
|
77
|
+
/** Provenance persisted as a `custom` session entry on the import target. */
|
|
78
|
+
export interface SessionImportProvenance {
|
|
79
|
+
schemaVersion: 1;
|
|
80
|
+
customType: "session-import";
|
|
81
|
+
provider: SessionImportProviderId;
|
|
82
|
+
format: SessionImportFormatId;
|
|
83
|
+
/** Basename of the explicit user-selected source file (never a full path). */
|
|
84
|
+
sourceFileName: string;
|
|
85
|
+
sourceSessionId?: string;
|
|
86
|
+
sourceTitle?: string;
|
|
87
|
+
/** SHA-256 over the exact source bytes that were imported. */
|
|
88
|
+
sourceSha256: string;
|
|
89
|
+
sourceBytes: number;
|
|
90
|
+
/** RFC 4122 UUID of the SKC session that received the import. */
|
|
91
|
+
targetSessionId: string;
|
|
92
|
+
importedAt: string;
|
|
93
|
+
converterVersion: number;
|
|
94
|
+
sanitizerVersion: number;
|
|
95
|
+
counts: SessionImportCounts;
|
|
96
|
+
/** True when head/tail bounding elided part of the conversation. */
|
|
97
|
+
truncated: boolean;
|
|
98
|
+
quarantine: {
|
|
99
|
+
present: boolean;
|
|
100
|
+
truncated: boolean;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/** Fully prepared import: parsed, normalized, redacted, bounded. No session state mutated yet. */
|
|
104
|
+
export interface PreparedSessionImport {
|
|
105
|
+
conversation: ImportedConversation;
|
|
106
|
+
/** Rendered continuation context for the `custom_message` entry. */
|
|
107
|
+
contextText: string;
|
|
108
|
+
provenance: Omit<SessionImportProvenance, "targetSessionId" | "importedAt">;
|
|
109
|
+
counts: SessionImportCounts;
|
|
110
|
+
/** Distinct redaction pattern ids that fired (for the user-facing summary). */
|
|
111
|
+
redactionKinds: string[];
|
|
112
|
+
/** Bounded digest-only records for durable quarantine metadata. */
|
|
113
|
+
quarantineRecords: ImportQuarantineRecord[];
|
|
114
|
+
sourceSha256: string;
|
|
115
|
+
sourceBytes: number;
|
|
116
|
+
}
|
|
117
|
+
/** Result of a completed or idempotently reused imported session. */
|
|
118
|
+
export interface SessionImportCompleted {
|
|
119
|
+
targetSessionId: string;
|
|
120
|
+
targetPath: string;
|
|
121
|
+
title: string;
|
|
122
|
+
prepared: PreparedSessionImport;
|
|
123
|
+
/** True when the same source/version import already existed in this workspace. */
|
|
124
|
+
reused: boolean;
|
|
125
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boot-generation evidence for reboot-only session restore.
|
|
3
|
+
*
|
|
4
|
+
* Restore exists to survive a reboot, and only a reboot. The eligibility rule is
|
|
5
|
+
* therefore narrow on purpose: a session may be restored only when the recorded
|
|
6
|
+
* and current boot values come from the SAME source and differ. Anything else —
|
|
7
|
+
* equal values, a missing or malformed record, an unreadable probe, or two
|
|
8
|
+
* different sources — is inconclusive and must never spawn.
|
|
9
|
+
*
|
|
10
|
+
* The same-source requirement is not pedantry. Linux can report `boot-id` at
|
|
11
|
+
* record time and fall back to `proc-btime` later; those two values are always
|
|
12
|
+
* unequal even on one boot, so comparing across sources would read every launch
|
|
13
|
+
* as a reboot and duplicate live sessions.
|
|
14
|
+
*/
|
|
15
|
+
/** Where a boot value came from. Values are only ever compared within one source. */
|
|
16
|
+
export type BootGenerationSource = "darwin-kern-boottime" | "linux-boot-id" | "linux-proc-btime" | "unavailable";
|
|
17
|
+
export interface BootGeneration {
|
|
18
|
+
source: BootGenerationSource;
|
|
19
|
+
/** Opaque; only equality within the same source is meaningful. */
|
|
20
|
+
value: string | null;
|
|
21
|
+
}
|
|
22
|
+
export type BootComparison = "changed" | "same_boot" | "boot_unknown";
|
|
23
|
+
export interface RecordedBootGeneration {
|
|
24
|
+
schema_version: number;
|
|
25
|
+
source: string;
|
|
26
|
+
value: string;
|
|
27
|
+
}
|
|
28
|
+
export interface BootGenerationProbeDeps {
|
|
29
|
+
platform?: NodeJS.Platform;
|
|
30
|
+
readFile?: (file: string) => string;
|
|
31
|
+
runCommand?: (command: string, args: string[]) => {
|
|
32
|
+
exitCode: number | null;
|
|
33
|
+
stdout: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** `{ sec = 1785305532, usec = 377197 } Wed Jul 29 ...` -> `1785305532.377197`. */
|
|
37
|
+
export declare function parseDarwinBootTime(raw: string): string | null;
|
|
38
|
+
/** A boot id is a UUID that changes on every boot; anything else is not usable. */
|
|
39
|
+
export declare function parseLinuxBootId(raw: string): string | null;
|
|
40
|
+
/** `/proc/stat` carries `btime <seconds>` once, as the kernel boot wall-clock. */
|
|
41
|
+
export declare function parseLinuxProcBtime(raw: string): string | null;
|
|
42
|
+
/**
|
|
43
|
+
* Reads the strongest boot evidence this platform offers.
|
|
44
|
+
*
|
|
45
|
+
* Windows returns `unavailable`: restore is unsupported there (no immutable
|
|
46
|
+
* native tmux session identity), so there is nothing to gate.
|
|
47
|
+
*/
|
|
48
|
+
export declare function readBootGeneration(deps?: BootGenerationProbeDeps): BootGeneration;
|
|
49
|
+
export declare function isBootValueWellFormed(source: string, value: string): boolean;
|
|
50
|
+
export declare function isRecordedBootGeneration(value: unknown): value is RecordedBootGeneration;
|
|
51
|
+
export declare function recordBootGeneration(current: BootGeneration): RecordedBootGeneration | null;
|
|
52
|
+
/**
|
|
53
|
+
* Decides whether the machine rebooted since the session was recorded.
|
|
54
|
+
*
|
|
55
|
+
* `changed` is the ONLY executable answer. It requires a well-formed record, a
|
|
56
|
+
* readable current probe, an identical source, and different values. Source
|
|
57
|
+
* mismatch is deliberately `boot_unknown` rather than `changed`.
|
|
58
|
+
*/
|
|
59
|
+
export declare function compareBootGeneration(recorded: unknown, current: BootGeneration): BootComparison;
|
|
@@ -30,14 +30,16 @@ export interface TmuxSpawnResult {
|
|
|
30
30
|
exitCode: number | null;
|
|
31
31
|
signalCode?: string | null;
|
|
32
32
|
stderr?: string;
|
|
33
|
+
/** Populated only when the caller asked for `stdout: "pipe"`. */
|
|
34
|
+
stdout?: string;
|
|
33
35
|
}
|
|
34
36
|
export type TmuxSpawnSync = (command: string, args: string[], options: TmuxSpawnOptions) => TmuxSpawnResult;
|
|
35
37
|
export interface TmuxSpawnOptions {
|
|
36
38
|
cwd: string;
|
|
37
39
|
env: NodeJS.ProcessEnv;
|
|
38
40
|
stdin: "inherit";
|
|
39
|
-
stdout: "inherit";
|
|
40
|
-
stderr: "inherit";
|
|
41
|
+
stdout: "inherit" | "pipe";
|
|
42
|
+
stderr: "inherit" | "pipe";
|
|
41
43
|
}
|
|
42
44
|
export interface TmuxLaunchPlan {
|
|
43
45
|
tmuxCommand: string;
|
|
@@ -50,6 +52,12 @@ export interface TmuxLaunchPlan {
|
|
|
50
52
|
project?: string | null;
|
|
51
53
|
sessionId?: string | null;
|
|
52
54
|
sessionStateFile?: string | null;
|
|
55
|
+
/**
|
|
56
|
+
* Capability of the RESOLVED provider, not a platform guess. psmux has no
|
|
57
|
+
* immutable native session identity, so it stays outside the native-proof
|
|
58
|
+
* create fence and keeps its existing spawn/profile/attach behavior.
|
|
59
|
+
*/
|
|
60
|
+
isPsmux: boolean;
|
|
53
61
|
}
|
|
54
62
|
export interface SkcTmuxProfileResult {
|
|
55
63
|
skipped: boolean;
|
|
@@ -20,6 +20,9 @@ export interface SkcLaunchWorktreePlan {
|
|
|
20
20
|
detached: boolean;
|
|
21
21
|
baseRef: string;
|
|
22
22
|
branchName: string | null;
|
|
23
|
+
sourceCheckoutRoot: string;
|
|
24
|
+
relativeCwd: string;
|
|
25
|
+
relativeDependencyRoot: string | null;
|
|
23
26
|
}
|
|
24
27
|
export interface SkcLaunchWorktreeResult extends SkcLaunchWorktreePlan {
|
|
25
28
|
created: boolean;
|
|
@@ -36,7 +39,19 @@ export declare function ensureLaunchWorktree(plan: SkcLaunchWorktreePlan | {
|
|
|
36
39
|
}): SkcLaunchWorktreeResult | {
|
|
37
40
|
enabled: false;
|
|
38
41
|
};
|
|
39
|
-
|
|
42
|
+
type WorktreePackageManager = "bun" | "npm" | "pnpm";
|
|
43
|
+
interface WorktreeDependencyProbes {
|
|
44
|
+
isExecutableAvailable?: (name: Exclude<WorktreePackageManager, "bun">) => boolean;
|
|
45
|
+
version?: (name: WorktreePackageManager) => string;
|
|
46
|
+
spawnInstall?: (command: readonly string[], cwd: string) => {
|
|
47
|
+
exitCode: number;
|
|
48
|
+
stderr: string;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/** Package worktrees own their complete lockfile-resolved dependency graph. */
|
|
52
|
+
export declare function ensureReusableNodeModules(sourceRoot: string, worktreePath: string, probes?: WorktreeDependencyProbes): "symlink" | "present" | "missing";
|
|
53
|
+
export declare function launchWorktreeCwd(plan: SkcLaunchWorktreePlan): string;
|
|
54
|
+
export declare function ensureLaunchWorktreeDependencies(plan: SkcLaunchWorktreePlan): "symlink" | "present" | "missing";
|
|
40
55
|
/** Result of {@link prepareLaunchWorktree}: the effective working directory, remaining args, and resolved worktree plan. */
|
|
41
56
|
export interface PreparedLaunchWorktree {
|
|
42
57
|
cwd: string;
|
|
@@ -46,3 +61,4 @@ export interface PreparedLaunchWorktree {
|
|
|
46
61
|
};
|
|
47
62
|
}
|
|
48
63
|
export declare function prepareLaunchWorktree(cwd: string, args: string[]): PreparedLaunchWorktree;
|
|
64
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { BootGeneration } from "./boot-generation";
|
|
2
|
+
import { type RestoreCandidateDeps, type RestorePointer, type RestoreSidecarFacts } from "./session-restore";
|
|
3
|
+
/**
|
|
4
|
+
* Strict re-read of the sidecar a pointer names.
|
|
5
|
+
*
|
|
6
|
+
* Returns null for missing, unreadable, or malformed content: restore must never
|
|
7
|
+
* infer a session's identity from the pointer alone.
|
|
8
|
+
*/
|
|
9
|
+
export declare function readSidecarFacts(pointer: RestorePointer): RestoreSidecarFacts | null;
|
|
10
|
+
/**
|
|
11
|
+
* True when a tmux session already carries this exact coordinator identity.
|
|
12
|
+
*
|
|
13
|
+
* An unreadable tmux is reported as a collision on purpose: not being able to
|
|
14
|
+
* see the server is not evidence that the identity is free.
|
|
15
|
+
*/
|
|
16
|
+
export declare function hasLiveIdentity(pointer: RestorePointer, env?: NodeJS.ProcessEnv): boolean;
|
|
17
|
+
/** psmux exposes no immutable native session identity, so restore cannot prove ownership there. */
|
|
18
|
+
export declare function ownerProofAvailable(env?: NodeJS.ProcessEnv): boolean;
|
|
19
|
+
export declare function buildRestoreCandidateDeps(currentBoot: BootGeneration, env?: NodeJS.ProcessEnv): RestoreCandidateDeps;
|
|
20
|
+
export type RestoreOutcome = {
|
|
21
|
+
ok: true;
|
|
22
|
+
pointer: RestorePointer;
|
|
23
|
+
tmuxSession: string;
|
|
24
|
+
} | {
|
|
25
|
+
ok: false;
|
|
26
|
+
pointer: RestorePointer;
|
|
27
|
+
code: string;
|
|
28
|
+
detail: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Restores exactly one eligible candidate.
|
|
32
|
+
*
|
|
33
|
+
* Deliberately goes through the ordinary fenced creator rather than spawning
|
|
34
|
+
* tmux directly: restore must inherit the same identity fence, owner-isolation
|
|
35
|
+
* proof, and exact cleanup as every other producer. The only differences are the
|
|
36
|
+
* working directory and the `--resume` argv handed to the child.
|
|
37
|
+
*
|
|
38
|
+
* Never cleans up another owner's session. A fence refusal is reported and the
|
|
39
|
+
* candidate is skipped.
|
|
40
|
+
*/
|
|
41
|
+
export declare function restoreSession(pointer: RestorePointer, env?: NodeJS.ProcessEnv): RestoreOutcome;
|