opencode-stm 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +128 -2
- package/config.example.yaml +20 -0
- package/dist/src/config.d.ts +35 -0
- package/dist/src/config.js +295 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/index.d.ts +14 -0
- package/dist/src/index.js +211 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/injection.d.ts +63 -0
- package/dist/src/injection.js +103 -0
- package/dist/src/injection.js.map +1 -0
- package/dist/src/scheduler.d.ts +25 -0
- package/dist/src/scheduler.js +182 -0
- package/dist/src/scheduler.js.map +1 -0
- package/dist/src/sdk.d.ts +50 -0
- package/dist/src/sdk.js +101 -0
- package/dist/src/sdk.js.map +1 -0
- package/dist/src/state.d.ts +70 -0
- package/dist/src/state.js +278 -0
- package/dist/src/state.js.map +1 -0
- package/dist/src/tools.d.ts +33 -0
- package/dist/src/tools.js +596 -0
- package/dist/src/tools.js.map +1 -0
- package/dist/src/transcript.d.ts +87 -0
- package/dist/src/transcript.js +376 -0
- package/dist/src/transcript.js.map +1 -0
- package/package.json +39 -4
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { PluginInput } from "@opencode-ai/plugin";
|
|
2
|
+
export type Client = PluginInput["client"];
|
|
3
|
+
export type SdkResult<T> = {
|
|
4
|
+
ok: true;
|
|
5
|
+
value: T;
|
|
6
|
+
} | {
|
|
7
|
+
ok: false;
|
|
8
|
+
reason: string;
|
|
9
|
+
};
|
|
10
|
+
export type SessionInfo = {
|
|
11
|
+
id: string;
|
|
12
|
+
title: string;
|
|
13
|
+
parentID?: string;
|
|
14
|
+
};
|
|
15
|
+
export declare const MESSAGE_PAGE_LIMIT = 8;
|
|
16
|
+
export declare function readSession(client: Client, sessionID: string, signal?: AbortSignal): Promise<SdkResult<SessionInfo>>;
|
|
17
|
+
export declare function writeTitle(client: Client, sessionID: string, title: string, signal?: AbortSignal): Promise<SdkResult<{
|
|
18
|
+
id: string;
|
|
19
|
+
}>>;
|
|
20
|
+
export type PagePart = {
|
|
21
|
+
id?: string;
|
|
22
|
+
type?: string;
|
|
23
|
+
text?: string;
|
|
24
|
+
synthetic?: boolean;
|
|
25
|
+
ignored?: boolean;
|
|
26
|
+
tool?: string;
|
|
27
|
+
messageID?: string;
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
};
|
|
30
|
+
export type PageMessage = {
|
|
31
|
+
info: {
|
|
32
|
+
id: string;
|
|
33
|
+
sessionID: string;
|
|
34
|
+
role: string;
|
|
35
|
+
summary?: unknown;
|
|
36
|
+
};
|
|
37
|
+
parts: PagePart[];
|
|
38
|
+
};
|
|
39
|
+
export type PageResult = {
|
|
40
|
+
items: PageMessage[];
|
|
41
|
+
nextCursor: string | null;
|
|
42
|
+
};
|
|
43
|
+
export declare function page(client: Client, sessionID: string, cursor: string | undefined, signal?: AbortSignal): Promise<SdkResult<PageResult>>;
|
|
44
|
+
export type RootCache = {
|
|
45
|
+
isRoot(sessionID: string, signal?: AbortSignal): Promise<SdkResult<boolean>>;
|
|
46
|
+
remember(sessionID: string, value: boolean): void;
|
|
47
|
+
invalidate(sessionID: string): void;
|
|
48
|
+
clear(): void;
|
|
49
|
+
};
|
|
50
|
+
export declare function createRootCache(client: Client, max?: number): RootCache;
|
package/dist/src/sdk.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
export const MESSAGE_PAGE_LIMIT = 8;
|
|
2
|
+
export async function readSession(client, sessionID, signal) {
|
|
3
|
+
try {
|
|
4
|
+
const result = await client.session.get({ path: { id: sessionID }, signal });
|
|
5
|
+
if (result.error !== undefined && result.error !== null) {
|
|
6
|
+
return { ok: false, reason: "sdk: session read rejected" };
|
|
7
|
+
}
|
|
8
|
+
const data = result.data;
|
|
9
|
+
if (data === undefined || data.id !== sessionID || typeof data.title !== "string") {
|
|
10
|
+
return { ok: false, reason: "sdk: session read returned unexpected data" };
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
ok: true,
|
|
14
|
+
value: data.parentID === undefined
|
|
15
|
+
? { id: data.id, title: data.title }
|
|
16
|
+
: { id: data.id, title: data.title, parentID: data.parentID },
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return { ok: false, reason: "sdk: session read failed" };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export async function writeTitle(client, sessionID, title, signal) {
|
|
24
|
+
try {
|
|
25
|
+
const result = await client.session.update({ path: { id: sessionID }, body: { title }, signal });
|
|
26
|
+
if (result.error !== undefined && result.error !== null) {
|
|
27
|
+
return { ok: false, reason: "sdk: title update rejected" };
|
|
28
|
+
}
|
|
29
|
+
const data = result.data;
|
|
30
|
+
if (data === undefined || data.id !== sessionID) {
|
|
31
|
+
return { ok: false, reason: "sdk: title update returned unexpected data" };
|
|
32
|
+
}
|
|
33
|
+
return { ok: true, value: { id: data.id } };
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return { ok: false, reason: "sdk: title update failed" };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export async function page(client, sessionID, cursor, signal) {
|
|
40
|
+
// The published v1 query type omits `before`; the 1.18.35 runtime accepts it.
|
|
41
|
+
// Keep this single additive cast here so no other module depends on the gap.
|
|
42
|
+
const query = {
|
|
43
|
+
limit: MESSAGE_PAGE_LIMIT,
|
|
44
|
+
...(cursor === undefined ? {} : { before: cursor }),
|
|
45
|
+
};
|
|
46
|
+
try {
|
|
47
|
+
const result = await client.session.messages({ path: { id: sessionID }, query, signal });
|
|
48
|
+
if (result.error !== undefined && result.error !== null) {
|
|
49
|
+
return { ok: false, reason: "sdk: message page rejected" };
|
|
50
|
+
}
|
|
51
|
+
if (!Array.isArray(result.data)) {
|
|
52
|
+
return { ok: false, reason: "sdk: message page returned unexpected data" };
|
|
53
|
+
}
|
|
54
|
+
const header = result.response?.headers?.get("x-next-cursor") ?? null;
|
|
55
|
+
return {
|
|
56
|
+
ok: true,
|
|
57
|
+
value: { items: result.data, nextCursor: header !== null && header.length > 0 ? header : null },
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return { ok: false, reason: "sdk: message page failed" };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export function createRootCache(client, max = 256) {
|
|
65
|
+
const entries = new Map();
|
|
66
|
+
const insert = (sessionID, value) => {
|
|
67
|
+
entries.delete(sessionID);
|
|
68
|
+
entries.set(sessionID, value);
|
|
69
|
+
while (entries.size > max) {
|
|
70
|
+
const oldest = entries.keys().next().value;
|
|
71
|
+
if (oldest === undefined)
|
|
72
|
+
break;
|
|
73
|
+
entries.delete(oldest);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
return {
|
|
77
|
+
async isRoot(sessionID, signal) {
|
|
78
|
+
const cached = entries.get(sessionID);
|
|
79
|
+
if (cached !== undefined) {
|
|
80
|
+
insert(sessionID, cached);
|
|
81
|
+
return { ok: true, value: cached };
|
|
82
|
+
}
|
|
83
|
+
const read = await readSession(client, sessionID, signal);
|
|
84
|
+
if (!read.ok)
|
|
85
|
+
return { ok: false, reason: read.reason };
|
|
86
|
+
const isRoot = read.value.parentID === undefined;
|
|
87
|
+
insert(sessionID, isRoot);
|
|
88
|
+
return { ok: true, value: isRoot };
|
|
89
|
+
},
|
|
90
|
+
remember(sessionID, value) {
|
|
91
|
+
insert(sessionID, value);
|
|
92
|
+
},
|
|
93
|
+
invalidate(sessionID) {
|
|
94
|
+
entries.delete(sessionID);
|
|
95
|
+
},
|
|
96
|
+
clear() {
|
|
97
|
+
entries.clear();
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/sdk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export declare const STATE_SCHEMA_VERSION = 1;
|
|
2
|
+
export declare const FRONTIER_MAX = 64;
|
|
3
|
+
export declare const ANCHOR_MAX = 32;
|
|
4
|
+
export type LockReason = "none" | "manual" | "external" | "non-default-title" | "historical" | "unreadable-state" | "invalid-config";
|
|
5
|
+
export type ReviewState = {
|
|
6
|
+
id: string;
|
|
7
|
+
remindersSent: number;
|
|
8
|
+
nextTriggerAt: number;
|
|
9
|
+
};
|
|
10
|
+
export type AnchorState = {
|
|
11
|
+
reviewID: string;
|
|
12
|
+
reminderIndex: number;
|
|
13
|
+
anchorMessageID: string;
|
|
14
|
+
partID: string;
|
|
15
|
+
obsolete: boolean;
|
|
16
|
+
};
|
|
17
|
+
export type SessionMeta = {
|
|
18
|
+
schemaVersion: 1;
|
|
19
|
+
activity: number;
|
|
20
|
+
baselineMessageID: string | null;
|
|
21
|
+
frontier: string[];
|
|
22
|
+
review: ReviewState | null;
|
|
23
|
+
anchors: AnchorState[];
|
|
24
|
+
locked: boolean;
|
|
25
|
+
lockReason: LockReason;
|
|
26
|
+
titleDigest: string | null;
|
|
27
|
+
};
|
|
28
|
+
export declare function initialMeta(): SessionMeta;
|
|
29
|
+
export declare function hashSessionID(sessionID: string): string;
|
|
30
|
+
export declare function hashTitle(title: string): string;
|
|
31
|
+
export declare function resolveStateDir(env: NodeJS.ProcessEnv, home: string): string;
|
|
32
|
+
export declare function parseMeta(value: unknown): SessionMeta | null;
|
|
33
|
+
export type LoadResult = {
|
|
34
|
+
ok: true;
|
|
35
|
+
value: SessionMeta | null;
|
|
36
|
+
} | {
|
|
37
|
+
ok: false;
|
|
38
|
+
reason: string;
|
|
39
|
+
};
|
|
40
|
+
export type SaveResult = {
|
|
41
|
+
ok: true;
|
|
42
|
+
} | {
|
|
43
|
+
ok: false;
|
|
44
|
+
reason: string;
|
|
45
|
+
};
|
|
46
|
+
export type UpdateResult<T> = {
|
|
47
|
+
ok: true;
|
|
48
|
+
value: T;
|
|
49
|
+
} | {
|
|
50
|
+
ok: false;
|
|
51
|
+
reason: string;
|
|
52
|
+
};
|
|
53
|
+
export type StateStoreOptions = {
|
|
54
|
+
stateDir: string;
|
|
55
|
+
now?: () => number;
|
|
56
|
+
};
|
|
57
|
+
export interface StateStore {
|
|
58
|
+
load(sessionID: string): Promise<LoadResult>;
|
|
59
|
+
save(sessionID: string, meta: SessionMeta): Promise<SaveResult>;
|
|
60
|
+
update<T>(sessionID: string, fn: (current: SessionMeta | null) => {
|
|
61
|
+
next: SessionMeta;
|
|
62
|
+
result: T;
|
|
63
|
+
}): Promise<UpdateResult<T>>;
|
|
64
|
+
removeOwned(sessionID: string): Promise<void>;
|
|
65
|
+
}
|
|
66
|
+
export type OperationGuard = {
|
|
67
|
+
run<T>(key: string, fn: () => Promise<T>): Promise<T>;
|
|
68
|
+
};
|
|
69
|
+
export declare function createOperationGuard(): OperationGuard;
|
|
70
|
+
export declare function createStateStore(options: StateStoreOptions): StateStore;
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { chmodSync, closeSync, fchmodSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, writeSync } from "node:fs";
|
|
3
|
+
import { isAbsolute, join } from "node:path";
|
|
4
|
+
export const STATE_SCHEMA_VERSION = 1;
|
|
5
|
+
export const FRONTIER_MAX = 64;
|
|
6
|
+
export const ANCHOR_MAX = 32;
|
|
7
|
+
export function initialMeta() {
|
|
8
|
+
return {
|
|
9
|
+
schemaVersion: STATE_SCHEMA_VERSION,
|
|
10
|
+
activity: 0,
|
|
11
|
+
baselineMessageID: null,
|
|
12
|
+
frontier: [],
|
|
13
|
+
review: null,
|
|
14
|
+
anchors: [],
|
|
15
|
+
locked: false,
|
|
16
|
+
lockReason: "none",
|
|
17
|
+
titleDigest: null,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function hashSessionID(sessionID) {
|
|
21
|
+
return createHash("sha256").update(sessionID, "utf8").digest("hex");
|
|
22
|
+
}
|
|
23
|
+
export function hashTitle(title) {
|
|
24
|
+
return createHash("sha256").update(title, "utf8").digest("hex");
|
|
25
|
+
}
|
|
26
|
+
export function resolveStateDir(env, home) {
|
|
27
|
+
const xdg = env.XDG_STATE_HOME;
|
|
28
|
+
const base = xdg !== undefined && xdg.length > 0 && isAbsolute(xdg) ? xdg : join(home, ".local", "state");
|
|
29
|
+
return join(base, "opencode-stm");
|
|
30
|
+
}
|
|
31
|
+
function isRecord(value) {
|
|
32
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
33
|
+
}
|
|
34
|
+
function hasOnlyKeys(value, keys) {
|
|
35
|
+
const actual = Object.keys(value);
|
|
36
|
+
return actual.length === keys.length && actual.every((key) => keys.includes(key));
|
|
37
|
+
}
|
|
38
|
+
const LOCK_REASONS = [
|
|
39
|
+
"none", "manual", "external", "non-default-title", "historical", "unreadable-state", "invalid-config",
|
|
40
|
+
];
|
|
41
|
+
const META_KEYS = [
|
|
42
|
+
"schemaVersion", "activity", "baselineMessageID", "frontier", "review", "anchors", "locked", "lockReason", "titleDigest",
|
|
43
|
+
];
|
|
44
|
+
const REVIEW_KEYS = ["id", "remindersSent", "nextTriggerAt"];
|
|
45
|
+
const ANCHOR_KEYS = ["reviewID", "reminderIndex", "anchorMessageID", "partID", "obsolete"];
|
|
46
|
+
function isReviewState(value) {
|
|
47
|
+
if (!isRecord(value))
|
|
48
|
+
return false;
|
|
49
|
+
if (!hasOnlyKeys(value, REVIEW_KEYS))
|
|
50
|
+
return false;
|
|
51
|
+
return (typeof value.id === "string" &&
|
|
52
|
+
Number.isInteger(value.remindersSent) &&
|
|
53
|
+
value.remindersSent >= 0 &&
|
|
54
|
+
Number.isInteger(value.nextTriggerAt) &&
|
|
55
|
+
value.nextTriggerAt >= 0);
|
|
56
|
+
}
|
|
57
|
+
function isAnchorState(value) {
|
|
58
|
+
if (!isRecord(value))
|
|
59
|
+
return false;
|
|
60
|
+
if (!hasOnlyKeys(value, ANCHOR_KEYS))
|
|
61
|
+
return false;
|
|
62
|
+
return (typeof value.reviewID === "string" &&
|
|
63
|
+
Number.isInteger(value.reminderIndex) &&
|
|
64
|
+
value.reminderIndex >= 0 &&
|
|
65
|
+
typeof value.anchorMessageID === "string" &&
|
|
66
|
+
typeof value.partID === "string" &&
|
|
67
|
+
typeof value.obsolete === "boolean");
|
|
68
|
+
}
|
|
69
|
+
export function parseMeta(value) {
|
|
70
|
+
if (!isRecord(value))
|
|
71
|
+
return null;
|
|
72
|
+
if (!hasOnlyKeys(value, META_KEYS))
|
|
73
|
+
return null;
|
|
74
|
+
if (value.schemaVersion !== STATE_SCHEMA_VERSION)
|
|
75
|
+
return null;
|
|
76
|
+
if (!Number.isInteger(value.activity) || value.activity < 0)
|
|
77
|
+
return null;
|
|
78
|
+
if (!(value.baselineMessageID === null || typeof value.baselineMessageID === "string"))
|
|
79
|
+
return null;
|
|
80
|
+
if (!Array.isArray(value.frontier) || value.frontier.length > FRONTIER_MAX || !value.frontier.every((item) => typeof item === "string"))
|
|
81
|
+
return null;
|
|
82
|
+
if (!(value.review === null || isReviewState(value.review)))
|
|
83
|
+
return null;
|
|
84
|
+
if (!Array.isArray(value.anchors) || value.anchors.length > ANCHOR_MAX || !value.anchors.every(isAnchorState))
|
|
85
|
+
return null;
|
|
86
|
+
if (typeof value.locked !== "boolean")
|
|
87
|
+
return null;
|
|
88
|
+
if (typeof value.lockReason !== "string" || !LOCK_REASONS.includes(value.lockReason))
|
|
89
|
+
return null;
|
|
90
|
+
if (!(value.titleDigest === null || typeof value.titleDigest === "string"))
|
|
91
|
+
return null;
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
export function createOperationGuard() {
|
|
95
|
+
const tails = new Map();
|
|
96
|
+
return {
|
|
97
|
+
run(key, fn) {
|
|
98
|
+
const previous = tails.get(key) ?? Promise.resolve();
|
|
99
|
+
const result = previous.then(fn, fn);
|
|
100
|
+
const tail = result.then(() => undefined, () => undefined);
|
|
101
|
+
tails.set(key, tail);
|
|
102
|
+
void tail.then(() => {
|
|
103
|
+
if (tails.get(key) === tail)
|
|
104
|
+
tails.delete(key);
|
|
105
|
+
});
|
|
106
|
+
return result;
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
export function createStateStore(options) {
|
|
111
|
+
const queueTails = new Map();
|
|
112
|
+
function enqueue(key, task) {
|
|
113
|
+
const previous = queueTails.get(key) ?? Promise.resolve();
|
|
114
|
+
const result = previous.then(task, task);
|
|
115
|
+
const tail = result.then(() => undefined, () => undefined);
|
|
116
|
+
queueTails.set(key, tail);
|
|
117
|
+
void tail.then(() => {
|
|
118
|
+
if (queueTails.get(key) === tail)
|
|
119
|
+
queueTails.delete(key);
|
|
120
|
+
});
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
function paths(sessionID) {
|
|
124
|
+
const name = hashSessionID(sessionID);
|
|
125
|
+
return {
|
|
126
|
+
file: join(options.stateDir, `${name}.json`),
|
|
127
|
+
lock: join(options.stateDir, `${name}.lock`),
|
|
128
|
+
temp: () => join(options.stateDir, `${name}.${process.pid}.${randomUUID()}.tmp`),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function ensureDir() {
|
|
132
|
+
// Fails closed: a directory that cannot be created or locked to mode 0700
|
|
133
|
+
// must disable persistence instead of falling back to permissive defaults.
|
|
134
|
+
mkdirSync(options.stateDir, { recursive: true, mode: 0o700 });
|
|
135
|
+
chmodSync(options.stateDir, 0o700);
|
|
136
|
+
}
|
|
137
|
+
class StoreLockError extends Error {
|
|
138
|
+
reason;
|
|
139
|
+
constructor(reason) {
|
|
140
|
+
super(reason);
|
|
141
|
+
this.reason = reason;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function withFileLock(sessionID, fn) {
|
|
145
|
+
let lockFd;
|
|
146
|
+
try {
|
|
147
|
+
lockFd = openSync(paths(sessionID).lock, "wx", 0o600);
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
if (error.code === "EEXIST")
|
|
151
|
+
throw new StoreLockError("state: lock contention");
|
|
152
|
+
throw new StoreLockError("state: lock unavailable");
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
return fn();
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
closeSync(lockFd);
|
|
159
|
+
rmSync(paths(sessionID).lock, { force: true });
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function readUnlocked(sessionID) {
|
|
163
|
+
let text;
|
|
164
|
+
try {
|
|
165
|
+
text = readFileSync(paths(sessionID).file, "utf8");
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
if (error.code === "ENOENT")
|
|
169
|
+
return { ok: true, value: null };
|
|
170
|
+
return { ok: false, reason: "state: unreadable" };
|
|
171
|
+
}
|
|
172
|
+
let parsed;
|
|
173
|
+
try {
|
|
174
|
+
parsed = JSON.parse(text);
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return { ok: false, reason: "state: malformed or unsupported" };
|
|
178
|
+
}
|
|
179
|
+
const meta = parseMeta(parsed);
|
|
180
|
+
if (meta === null)
|
|
181
|
+
return { ok: false, reason: "state: malformed or unsupported" };
|
|
182
|
+
return { ok: true, value: meta };
|
|
183
|
+
}
|
|
184
|
+
function writeUnlocked(sessionID, meta) {
|
|
185
|
+
const temp = paths(sessionID).temp();
|
|
186
|
+
try {
|
|
187
|
+
const fd = openSync(temp, "w", 0o600);
|
|
188
|
+
try {
|
|
189
|
+
fchmodSync(fd, 0o600);
|
|
190
|
+
writeSync(fd, `${JSON.stringify(meta)}\n`);
|
|
191
|
+
fsyncSync(fd);
|
|
192
|
+
}
|
|
193
|
+
finally {
|
|
194
|
+
closeSync(fd);
|
|
195
|
+
}
|
|
196
|
+
renameSync(temp, paths(sessionID).file);
|
|
197
|
+
return { ok: true };
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
rmSync(temp, { force: true });
|
|
201
|
+
return { ok: false, reason: "state: save failed" };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
load(sessionID) {
|
|
206
|
+
return enqueue(sessionID, async () => {
|
|
207
|
+
try {
|
|
208
|
+
ensureDir();
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
return { ok: false, reason: "state: directory unavailable" };
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
return withFileLock(sessionID, () => readUnlocked(sessionID));
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
if (error instanceof StoreLockError)
|
|
218
|
+
return { ok: false, reason: error.reason };
|
|
219
|
+
return { ok: false, reason: "state: failed" };
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
},
|
|
223
|
+
save(sessionID, meta) {
|
|
224
|
+
return enqueue(sessionID, async () => {
|
|
225
|
+
try {
|
|
226
|
+
ensureDir();
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
return { ok: false, reason: "state: directory unavailable" };
|
|
230
|
+
}
|
|
231
|
+
try {
|
|
232
|
+
return withFileLock(sessionID, () => writeUnlocked(sessionID, meta));
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
if (error instanceof StoreLockError)
|
|
236
|
+
return { ok: false, reason: error.reason };
|
|
237
|
+
return { ok: false, reason: "state: failed" };
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
},
|
|
241
|
+
update(sessionID, fn) {
|
|
242
|
+
return enqueue(sessionID, async () => {
|
|
243
|
+
try {
|
|
244
|
+
ensureDir();
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
return { ok: false, reason: "state: directory unavailable" };
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
return withFileLock(sessionID, () => {
|
|
251
|
+
const current = readUnlocked(sessionID);
|
|
252
|
+
if (!current.ok)
|
|
253
|
+
return { ok: false, reason: current.reason };
|
|
254
|
+
const { next, result } = fn(current.value);
|
|
255
|
+
const saved = writeUnlocked(sessionID, next);
|
|
256
|
+
if (!saved.ok)
|
|
257
|
+
return { ok: false, reason: saved.reason };
|
|
258
|
+
return { ok: true, value: result };
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
if (error instanceof StoreLockError)
|
|
263
|
+
return { ok: false, reason: error.reason };
|
|
264
|
+
return { ok: false, reason: "state: failed" };
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
},
|
|
268
|
+
async removeOwned(sessionID) {
|
|
269
|
+
try {
|
|
270
|
+
rmSync(paths(sessionID).file, { force: true });
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
// Session lifecycle cleanup is best effort; stale metadata is allowed.
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACvI,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAE5C,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAA;AACrC,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAA;AAC9B,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAA;AAiC5B,MAAM,UAAU,WAAW;IACzB,OAAO;QACL,aAAa,EAAE,oBAAoB;QACnC,QAAQ,EAAE,CAAC;QACX,iBAAiB,EAAE,IAAI;QACvB,QAAQ,EAAE,EAAE;QACZ,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,EAAE;QACX,MAAM,EAAE,KAAK;QACb,UAAU,EAAE,MAAM;QAClB,WAAW,EAAE,IAAI;KAClB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC7C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AACrE,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AACjE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAsB,EAAE,IAAY;IAClE,MAAM,GAAG,GAAG,GAAG,CAAC,cAAc,CAAA;IAC9B,MAAM,IAAI,GAAG,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;IACzG,OAAO,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAA;AACnC,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7E,CAAC;AAED,SAAS,WAAW,CAAC,KAA8B,EAAE,IAAuB;IAC1E,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACjC,OAAO,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAA;AACnF,CAAC;AAED,MAAM,YAAY,GAA0B;IAC1C,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,mBAAmB,EAAE,YAAY,EAAE,kBAAkB,EAAE,gBAAgB;CACtG,CAAA;AAED,MAAM,SAAS,GAAG;IAChB,eAAe,EAAE,UAAU,EAAE,mBAAmB,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa;CAChH,CAAA;AACV,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,eAAe,EAAE,eAAe,CAAU,CAAA;AACrE,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,eAAe,EAAE,iBAAiB,EAAE,QAAQ,EAAE,UAAU,CAAU,CAAA;AAEnG,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IAClC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC;QAAE,OAAO,KAAK,CAAA;IAClD,OAAO,CACL,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ;QAC5B,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC;QACpC,KAAK,CAAC,aAAwB,IAAI,CAAC;QACpC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC;QACpC,KAAK,CAAC,aAAwB,IAAI,CAAC,CACrC,CAAA;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IAClC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC;QAAE,OAAO,KAAK,CAAA;IAClD,OAAO,CACL,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ;QAClC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC;QACpC,KAAK,CAAC,aAAwB,IAAI,CAAC;QACpC,OAAO,KAAK,CAAC,eAAe,KAAK,QAAQ;QACzC,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;QAChC,OAAO,KAAK,CAAC,QAAQ,KAAK,SAAS,CACpC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACjC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC;QAAE,OAAO,IAAI,CAAA;IAC/C,IAAI,KAAK,CAAC,aAAa,KAAK,oBAAoB;QAAE,OAAO,IAAI,CAAA;IAC7D,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAK,KAAK,CAAC,QAAmB,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IACpF,IAAI,CAAC,CAAC,KAAK,CAAC,iBAAiB,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,iBAAiB,KAAK,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAA;IACnG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,YAAY,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAA;IACpJ,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,IAAI,IAAI,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IACxE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC;QAAE,OAAO,IAAI,CAAA;IAC1H,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IAClD,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAwB,CAAC;QAAE,OAAO,IAAI,CAAA;IAC/G,IAAI,CAAC,CAAC,KAAK,CAAC,WAAW,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAA;IACvF,OAAO,KAAoB,CAAA;AAC7B,CAAC;AAgBD,MAAM,UAAU,oBAAoB;IAClC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAA;IAC9C,OAAO;QACL,GAAG,CAAI,GAAW,EAAE,EAAoB;YACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAA;YACpD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;YACpC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CACtB,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CAChB,CAAA;YACD,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;YACpB,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;gBAClB,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI;oBAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAChD,CAAC,CAAC,CAAA;YACF,OAAO,MAAM,CAAA;QACf,CAAC;KACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAA0B;IACzD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAyB,CAAA;IAEnD,SAAS,OAAO,CAAI,GAAW,EAAE,IAAsB;QACrD,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAA;QACzD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACxC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CACtB,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CAChB,CAAA;QACD,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QACzB,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;YAClB,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI;gBAAE,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC1D,CAAC,CAAC,CAAA;QACF,OAAO,MAAM,CAAA;IACf,CAAC;IAED,SAAS,KAAK,CAAC,SAAiB;QAC9B,MAAM,IAAI,GAAG,aAAa,CAAC,SAAS,CAAC,CAAA;QACrC,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,IAAI,OAAO,CAAC;YAC5C,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,IAAI,OAAO,CAAC;YAC5C,IAAI,EAAE,GAAW,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,IAAI,UAAU,EAAE,MAAM,CAAC;SACzF,CAAA;IACH,CAAC;IAED,SAAS,SAAS;QAChB,0EAA0E;QAC1E,2EAA2E;QAC3E,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAC7D,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IACpC,CAAC;IAED,MAAM,cAAe,SAAQ,KAAK;QACX;QAArB,YAAqB,MAAc;YACjC,KAAK,CAAC,MAAM,CAAC,CAAA;YADM,WAAM,GAAN,MAAM,CAAQ;QAEnC,CAAC;KACF;IAED,SAAS,YAAY,CAAI,SAAiB,EAAE,EAAW;QACrD,IAAI,MAAc,CAAA;QAClB,IAAI,CAAC;YACH,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,IAAI,cAAc,CAAC,wBAAwB,CAAC,CAAA;YAC1G,MAAM,IAAI,cAAc,CAAC,yBAAyB,CAAC,CAAA;QACrD,CAAC;QACD,IAAI,CAAC;YACH,OAAO,EAAE,EAAE,CAAA;QACb,CAAC;gBAAS,CAAC;YACT,SAAS,CAAC,MAAM,CAAC,CAAA;YACjB,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QAChD,CAAC;IACH,CAAC;IAED,SAAS,YAAY,CAAC,SAAiB;QACrC,IAAI,IAAY,CAAA;QAChB,IAAI,CAAC;YACH,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;YACxF,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAA;QACnD,CAAC;QACD,IAAI,MAAe,CAAA;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iCAAiC,EAAE,CAAA;QACjE,CAAC;QACD,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAA;QAC9B,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iCAAiC,EAAE,CAAA;QAClF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IAClC,CAAC;IAED,SAAS,aAAa,CAAC,SAAiB,EAAE,IAAiB;QACzD,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAA;QACpC,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAA;YACrC,IAAI,CAAC;gBACH,UAAU,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;gBACrB,SAAS,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBAC1C,SAAS,CAAC,EAAE,CAAC,CAAA;YACf,CAAC;oBAAS,CAAC;gBACT,SAAS,CAAC,EAAE,CAAC,CAAA;YACf,CAAC;YACD,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAA;YACvC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;YAC7B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAA;QACpD,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,CAAC,SAAS;YACZ,OAAO,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;gBACnC,IAAI,CAAC;oBACH,SAAS,EAAE,CAAA;gBACb,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAA;gBAC9D,CAAC;gBACD,IAAI,CAAC;oBACH,OAAO,YAAY,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAA;gBAC/D,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,KAAK,YAAY,cAAc;wBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAA;oBAC/E,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAA;gBAC/C,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,IAAI,CAAC,SAAS,EAAE,IAAI;YAClB,OAAO,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;gBACnC,IAAI,CAAC;oBACH,SAAS,EAAE,CAAA;gBACb,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAA;gBAC9D,CAAC;gBACD,IAAI,CAAC;oBACH,OAAO,YAAY,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAA;gBACtE,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,KAAK,YAAY,cAAc;wBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAA;oBAC/E,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAA;gBAC/C,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,MAAM,CAAI,SAAiB,EAAE,EAAqE;YAChG,OAAO,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;gBACnC,IAAI,CAAC;oBACH,SAAS,EAAE,CAAA;gBACb,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAA;gBAC9D,CAAC;gBACD,IAAI,CAAC;oBACH,OAAO,YAAY,CAAkB,SAAS,EAAE,GAAG,EAAE;wBACnD,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;wBACvC,IAAI,CAAC,OAAO,CAAC,EAAE;4BAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAA;wBAC7D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;wBAC1C,MAAM,KAAK,GAAG,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;wBAC5C,IAAI,CAAC,KAAK,CAAC,EAAE;4BAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAA;wBACzD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;oBACpC,CAAC,CAAC,CAAA;gBACJ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,KAAK,YAAY,cAAc;wBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAA;oBAC/E,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAA;gBAC/C,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,KAAK,CAAC,WAAW,CAAC,SAAS;YACzB,IAAI,CAAC;gBACH,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;YAChD,CAAC;YAAC,MAAM,CAAC;gBACP,uEAAuE;YACzE,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type ToolDefinition } from "@opencode-ai/plugin";
|
|
2
|
+
import type { StmConfig } from "./config.js";
|
|
3
|
+
import { type SessionMeta, type StateStore, type OperationGuard } from "./state.js";
|
|
4
|
+
import { type Client, type RootCache } from "./sdk.js";
|
|
5
|
+
import { type TranscriptQueue } from "./transcript.js";
|
|
6
|
+
export declare const TITLE_MAX_CODE_POINTS = 120;
|
|
7
|
+
export type TitleValidation = {
|
|
8
|
+
ok: true;
|
|
9
|
+
value: string;
|
|
10
|
+
} | {
|
|
11
|
+
ok: false;
|
|
12
|
+
reason: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function validateTitle(raw: string): TitleValidation;
|
|
15
|
+
export type StmServices = {
|
|
16
|
+
client: Client;
|
|
17
|
+
config: StmConfig;
|
|
18
|
+
state: StateStore;
|
|
19
|
+
queue: TranscriptQueue;
|
|
20
|
+
roots: RootCache;
|
|
21
|
+
guard: OperationGuard;
|
|
22
|
+
blocked: Map<string, Set<string>>;
|
|
23
|
+
now: () => number;
|
|
24
|
+
};
|
|
25
|
+
export declare function establishBaseline(services: StmServices, sessionID: string, signal?: AbortSignal, knownTitle?: string): Promise<{
|
|
26
|
+
ok: true;
|
|
27
|
+
meta: SessionMeta;
|
|
28
|
+
} | {
|
|
29
|
+
ok: false;
|
|
30
|
+
reason: string;
|
|
31
|
+
}>;
|
|
32
|
+
export declare function createCurrentTools(services: StmServices): Record<string, ToolDefinition>;
|
|
33
|
+
export declare function createHistoricalTools(services: StmServices): Record<string, ToolDefinition>;
|