dsh-plugin-sessiongraph-sessions 0.0.0-stage → 0.1.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CC ZHAO
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/lib/index.d.ts ADDED
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Session-log indexer for the session-graph seam: turns `~/.dsh/sessions` into the SQLite index
3
+ * `dsh-plugin-sessiongraph-sqlite` reads.
4
+ *
5
+ * Registers **only an indexer**, never a store. Indexing is caller-initiated (`sessiongraph_index`)
6
+ * and never runs from a query: a full machine is hundreds of logs and more than a gigabyte of
7
+ * decompressed JSON, so it has its own timeout budget and the query path stays millisecond-fast.
8
+ *
9
+ * The index root is an opaque directory the caller names; `indexRoot` is where `index.db` lives, and
10
+ * `sessionsRoot` (the harness's own log directory) is a separate, configurable input. That split is
11
+ * what lets a test build a fixture-driven index without a real `~/.dsh`.
12
+ *
13
+ * A run is incremental by default — only logs whose mtime or size moved are re-read — and `force`
14
+ * rebuilds every log into a temporary file that replaces the old index atomically. A single bad log
15
+ * is reported in `failed` and never aborts the run.
16
+ *
17
+ * Every session creation also refreshes an **existing** index in the background (`agent/created`,
18
+ * `autoIndex`): a machine that already has one stays fresh without the model remembering to ask. A
19
+ * missing index is deliberately left alone — the first build reads every log on the machine and is
20
+ * the caller's explicit decision (`sessiongraph_index`), not something to trigger on a session start.
21
+ *
22
+ * Sessions the host still holds in memory (`ctx.sessionQuery`) are indexed as well, in a second pass
23
+ * after the file-path transaction commits: a conversation that is still running has no log on disk
24
+ * yet, and "where did I say X" has to include what was just typed. That pass is optional — a host
25
+ * without the service leaves the file-path result exactly as it was, and one that fails degrades to
26
+ * it instead of failing the run.
27
+ *
28
+ * An explicit run is handed to the host's background-job registry too once the store is large enough
29
+ * (`backgroundIndexThreshold`), because a run that grows past a tool's timeout budget must not hold
30
+ * that call open. The seam types `index()` as returning a report, so a delegated run comes back as a
31
+ * report carrying `jobId` — see {@link isBackgroundIndexReport} for the discrimination a consumer
32
+ * needs, and {@link SessiongraphBackgroundIndexReport} for what its other fields then mean.
33
+ * @module dsh-plugin-sessiongraph-sessions
34
+ */
35
+ import type { Context } from '@deepseek-ai/cordis';
36
+ import z from '@deepseek-ai/schemastery';
37
+ import type { SessiongraphIndexer, SessiongraphIndexOptions, SessiongraphIndexReport } from 'dsh-plugin-sessiongraph-service';
38
+ export { decompressSessionLog, parseSessionLog } from './parse.ts';
39
+ export type { ParsedEntry, ParsedSession, SessionParseLimits } from './parse.ts';
40
+ export { scanSessions } from './scan.ts';
41
+ export type { SessionFile } from './scan.ts';
42
+ export { LIVE_SOURCE_PREFIX } from './live.ts';
43
+ export type { LiveIndexOptions, LiveIndexResult, SessionQueryService } from './live.ts';
44
+ export { readIndexState, STATUS_RELATIVE_PATH, writeIndex } from './write.ts';
45
+ export type { ExistingSession, IndexWritePlan, IndexWriteResult, IndexedSession } from './write.ts';
46
+ /** Cordis plugin name for loader diagnostics. */
47
+ export declare const name = "sessiongraph-sessions";
48
+ /** Services required by this plugin. */
49
+ export declare const inject: string[];
50
+ /** Default branded identity this indexer reserves on the seam. */
51
+ export declare const DEFAULT_INDEXER_ID = "sessiongraph-sessions";
52
+ /** Default harness session directory. */
53
+ export declare const DEFAULT_SESSIONS_ROOT: string;
54
+ /**
55
+ * Default index root, matching the tool's own default so a stock profile's automatic refresh writes
56
+ * where its queries read. A deployment that moves one must move the other.
57
+ */
58
+ export declare const DEFAULT_INDEX_ROOT: string;
59
+ /** Stable job kind of a background index run, used for retention and diagnostics. */
60
+ export declare const AUTO_INDEX_JOB_KIND = "sessiongraph-index";
61
+ /** Default number of session logs at which a manual index run becomes a background job. */
62
+ export declare const DEFAULT_BACKGROUND_INDEX_THRESHOLD = 1000;
63
+ /**
64
+ * Default cap on live sessions rebuilt per run. A host normally reports one or two; the cap exists
65
+ * because replaying a live log is not incremental and a host could report many.
66
+ */
67
+ export declare const DEFAULT_MAX_LIVE_SESSIONS = 8;
68
+ /** Engine selection: prefer the native kernel, only the TypeScript indexer, or decide per machine. */
69
+ export type SessiongraphEngineSetting = 'auto' | 'native' | 'typescript';
70
+ /** Which engine produced one run's report. */
71
+ export type SessiongraphIndexEngine = 'native' | 'typescript';
72
+ /** Default engine selection. */
73
+ export declare const DEFAULT_ENGINE: SessiongraphEngineSetting;
74
+ /** Default cap on stored message text, in characters. */
75
+ export declare const DEFAULT_MAX_ENTRY_CHARS = 4000;
76
+ /** Default cap on stored tool-invocation text, in characters. */
77
+ export declare const DEFAULT_TOOL_CALL_CHARS = 2000;
78
+ /**
79
+ * Default cap on one compressed log file, in bytes. The largest session on a real machine is ~42MB
80
+ * decompressed from ~13MB compressed, so 64MB leaves room for a long-running session without
81
+ * letting a pathological log exhaust memory in one decompress.
82
+ */
83
+ export declare const DEFAULT_MAX_FILE_BYTES: number;
84
+ /** Plugin configuration. */
85
+ export interface Config {
86
+ /** Directory the harness writes its session logs to (default `~/.dsh/sessions`). */
87
+ sessionsRoot?: string;
88
+ /**
89
+ * Index root the automatic refresh reads and refreshes (default `~/.dsh/sessiongraph`). Queries
90
+ * route on the root the tool passes, so this must name the same directory as the tool's
91
+ * `indexRoot` or the refresh maintains an index nothing reads.
92
+ */
93
+ indexRoot?: string;
94
+ /** Longest message text stored whole; longer text is clipped (default 4000). */
95
+ maxEntryChars?: number;
96
+ /** Longest tool invocation (name plus arguments) stored whole (default 2000). */
97
+ toolCallChars?: number;
98
+ /** Logs larger than this are skipped and reported in `failed` (default 67108864). */
99
+ maxFileBytes?: number;
100
+ /**
101
+ * Refresh an existing index in the background whenever a session is created (default true). A
102
+ * machine with no index yet is skipped on purpose — see {@link DEFAULT_INDEX_ROOT}.
103
+ */
104
+ autoIndex?: boolean;
105
+ /**
106
+ * Hand an explicit index run to the host's background-job registry once the session store holds at
107
+ * least this many logs (default 1000). Below it the run is synchronous, because a small index is
108
+ * faster than the round-trip through `job_output`.
109
+ */
110
+ backgroundIndexThreshold?: number;
111
+ /**
112
+ * Most live (still-running) sessions to rebuild per run (default 8). They come from the host's
113
+ * `ctx.sessionQuery` and are always rebuilt in full, so the cap bounds the replay cost.
114
+ */
115
+ maxLiveSessions?: number;
116
+ /**
117
+ * Which index engine to run (default `auto`): the native Rust kernel when this machine has a
118
+ * loadable build, else the TypeScript indexer. `native` asks for the kernel explicitly and logs
119
+ * once when it cannot be used before falling back; `typescript` never probes the kernel at all.
120
+ */
121
+ engine?: SessiongraphEngineSetting;
122
+ }
123
+ export declare const Config: z<Config>;
124
+ /** Configuration after the schema filled in every default. */
125
+ export type ResolvedConfig = Required<Config>;
126
+ /**
127
+ * Register the session-log indexer.
128
+ * @param ctx - the plugin context (must inject `sessiongraph`).
129
+ * @param config - the resolved plugin configuration.
130
+ */
131
+ export declare function apply(ctx: Context, config: Config): void;
132
+ /**
133
+ * Build the indexer object this plugin registers.
134
+ * @param ctx - the plugin context; only its optional `jobs` service is consulted.
135
+ * @param config - the resolved plugin configuration.
136
+ * @returns the seam provider.
137
+ */
138
+ export declare function createIndexer(ctx: Context, config: ResolvedConfig): SessiongraphIndexer;
139
+ /**
140
+ * The report a backgrounded index run returns. The seam types `index()` as returning a report, which
141
+ * is what a caller awaits; a run that was delegated instead comes back with this extra field, and a
142
+ * consumer distinguishes the two cases through {@link isBackgroundIndexReport}.
143
+ */
144
+ export interface SessiongraphBackgroundIndexReport extends SessiongraphIndexReport {
145
+ /** Id of the background job that owns the run. */
146
+ readonly jobId: string;
147
+ }
148
+ /**
149
+ * Whether an index result came from a delegated run rather than a completed one.
150
+ *
151
+ * The seam's return type is the completed report, so a job id can only arrive as an extension of it;
152
+ * every other field of a delegated result describes the index as it stood when the job started.
153
+ * @param report - the value `ctx.sessiongraph.index()` resolved with.
154
+ * @returns true when the run is still going in the host's job registry.
155
+ */
156
+ export declare function isBackgroundIndexReport(report: SessiongraphIndexReport): report is SessiongraphBackgroundIndexReport;
157
+ /**
158
+ * Build or refresh one index.
159
+ * @param indexRoot - directory to write `index.db` into.
160
+ * @param options - scope and rebuild switches.
161
+ * @param signal - aborts between sessions.
162
+ * @param config - the resolved plugin configuration.
163
+ * @param ctx - the plugin context, consulted for the optional live-session source. Omitted by
164
+ * callers that only exercise the file path, which then behave exactly as an older host would.
165
+ * @returns what the run did.
166
+ */
167
+ export declare function runIndex(indexRoot: string, options: SessiongraphIndexOptions, signal: AbortSignal | undefined, config: ResolvedConfig, ctx?: Context): Promise<SessiongraphIndexReport>;
168
+ /**
169
+ * Whether a session's workspace matches an optional workspace filter.
170
+ *
171
+ * An exact match always counts. A value without a trailing separator is also a path prefix, which is
172
+ * how one indexed root serves the whole `~/www` subtree; a value with the trailing separator is the
173
+ * exact directory only.
174
+ * @param filter - configured workspace filter, or undefined for "every workspace".
175
+ * @param workspace - the session's working directory.
176
+ * @returns whether the session is in scope.
177
+ */
178
+ export declare function matchesWorkspace(filter: string | undefined, workspace: string): boolean;
179
+ /**
180
+ * Whether a session id matches an optional id filter (full id or any prefix).
181
+ * @param filter - configured session filter, or undefined for "every session".
182
+ * @param id - the session's id.
183
+ * @returns whether the session is in scope.
184
+ */
185
+ export declare function matchesSession(filter: string | undefined, id: string): boolean;
186
+ //# sourceMappingURL=index.d.ts.map