dsh-rewind-plugin 0.7.4 → 0.8.0-alpha.1
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.en.md +2 -1
- package/README.md +2 -1
- package/docs/architecture.md +5 -4
- package/docs/compat/audit.md +26 -29
- package/docs/contract/client-contract.md +1 -1
- package/docs/contract/client-contract.zh.md +1 -1
- package/docs/harness-reference.md +3 -4
- package/docs/release/release.md +80 -24
- package/docs/release/release.zh.md +61 -16
- package/lib/client.js +18 -43
- package/lib/index.js +14 -28
- package/lib/types/client/hidden.d.ts +26 -33
- package/lib/types/client/index.d.ts +19 -1
- package/lib/types/client/popover.d.ts +8 -9
- package/lib/types/client/portals.d.ts +27 -38
- package/lib/types/client/settings-card.d.ts +4 -4
- package/lib/types/client/styles.d.ts +1 -1
- package/lib/types/snapshot-cleanup.d.ts +3 -3
- package/package.json +44 -41
- package/lib/types/session-events.d.ts +0 -34
- package/lib/types/settings-locale.d.ts +0 -32
package/lib/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { createAssistantMessage } from "@deepseek-ai/dsh-llm";
|
|
3
3
|
import { unlink as unlink2 } from "node:fs/promises";
|
|
4
|
-
import * as dshSettings from "@deepseek-ai/dsh-settings";
|
|
5
4
|
import "@deepseek-ai/schemastery";
|
|
6
5
|
|
|
7
6
|
// src/locales.ts
|
|
@@ -111,20 +110,6 @@ function translate(lang, key, params = {}) {
|
|
|
111
110
|
return text;
|
|
112
111
|
}
|
|
113
112
|
|
|
114
|
-
// src/session-events.ts
|
|
115
|
-
function eventsOf(session) {
|
|
116
|
-
const s = session;
|
|
117
|
-
if (s.snapshotEvents !== void 0) return s.snapshotEvents();
|
|
118
|
-
if (s.events !== void 0) return s.events;
|
|
119
|
-
return [];
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// src/settings-locale.ts
|
|
123
|
-
function readSettingsSection(provider, ns, brand) {
|
|
124
|
-
const key = brand?.(ns) ?? ns;
|
|
125
|
-
return provider.get(key);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
113
|
// src/rewind.ts
|
|
129
114
|
var RewindError = class extends Error {
|
|
130
115
|
constructor(code, message) {
|
|
@@ -1524,7 +1509,7 @@ function mutationPathOf(exec) {
|
|
|
1524
1509
|
return void 0;
|
|
1525
1510
|
}
|
|
1526
1511
|
function anchorSeqOf(session, cache) {
|
|
1527
|
-
const events =
|
|
1512
|
+
const events = session.snapshotEvents();
|
|
1528
1513
|
const cached = cache.get(session);
|
|
1529
1514
|
if (cached !== void 0 && cached.eventsLength === events.length) return cached.anchor;
|
|
1530
1515
|
let anchor = cached?.anchor;
|
|
@@ -1702,15 +1687,15 @@ async function executeRewind(ctx, store, fs, invocation, rawTarget, mode, inflig
|
|
|
1702
1687
|
}
|
|
1703
1688
|
let plan;
|
|
1704
1689
|
try {
|
|
1705
|
-
plan = resolveOrError(
|
|
1690
|
+
plan = resolveOrError(agent.session.snapshotEvents(), agent.session.surface.nodes, rawTarget);
|
|
1706
1691
|
} catch (error) {
|
|
1707
1692
|
return rewindErrorResult(error);
|
|
1708
1693
|
}
|
|
1709
1694
|
const marker = buildMarker();
|
|
1710
1695
|
let event;
|
|
1711
1696
|
try {
|
|
1712
|
-
const turn = markerTurnOf(
|
|
1713
|
-
const step = markerStepOf(
|
|
1697
|
+
const turn = markerTurnOf(agent.session.snapshotEvents());
|
|
1698
|
+
const step = markerStepOf(agent.session.snapshotEvents(), turn);
|
|
1714
1699
|
agent.session.append("step/start", { turn, step });
|
|
1715
1700
|
try {
|
|
1716
1701
|
event = agent.session.append("assistant/message", { turn, step, message: marker }, {
|
|
@@ -1764,7 +1749,7 @@ async function handleRewind(ctx, store, fs, invocation, inflight) {
|
|
|
1764
1749
|
const session = invocation.agent.session;
|
|
1765
1750
|
const input = invocation.rawInput.trim();
|
|
1766
1751
|
if (input === "") {
|
|
1767
|
-
const candidates = listRewindCandidates(
|
|
1752
|
+
const candidates = listRewindCandidates(session.snapshotEvents(), session.surface.nodes, 1);
|
|
1768
1753
|
if (candidates.length === 0) {
|
|
1769
1754
|
return { kind: "error", text: t("noUserMessages") };
|
|
1770
1755
|
}
|
|
@@ -1776,7 +1761,7 @@ async function handleRewind(ctx, store, fs, invocation, inflight) {
|
|
|
1776
1761
|
if (target2 === void 0) return { kind: "error", text: usage() };
|
|
1777
1762
|
let plan;
|
|
1778
1763
|
try {
|
|
1779
|
-
plan = resolveOrError(
|
|
1764
|
+
plan = resolveOrError(session.snapshotEvents(), session.surface.nodes, target2);
|
|
1780
1765
|
} catch (error) {
|
|
1781
1766
|
return rewindErrorResult(error);
|
|
1782
1767
|
}
|
|
@@ -1784,7 +1769,7 @@ async function handleRewind(ctx, store, fs, invocation, inflight) {
|
|
|
1784
1769
|
return { kind: "success", text: formatPlan(plan, impacts) };
|
|
1785
1770
|
}
|
|
1786
1771
|
if (parts[0] === "__candidates") {
|
|
1787
|
-
const candidates = listRewindCandidates(
|
|
1772
|
+
const candidates = listRewindCandidates(session.snapshotEvents(), session.surface.nodes);
|
|
1788
1773
|
return { kind: "success", text: formatCandidateList(candidates) };
|
|
1789
1774
|
}
|
|
1790
1775
|
const target = parts[0];
|
|
@@ -1930,15 +1915,16 @@ function apply(ctx, config) {
|
|
|
1930
1915
|
const trackedBySession = /* @__PURE__ */ new Map();
|
|
1931
1916
|
let fsService;
|
|
1932
1917
|
ctx.inject(["settings"], (settingsCtx) => {
|
|
1933
|
-
const
|
|
1934
|
-
|
|
1935
|
-
"locale",
|
|
1936
|
-
dshSettings.settingsNamespace
|
|
1937
|
-
);
|
|
1918
|
+
const settings = settingsCtx;
|
|
1919
|
+
const section = settings.settings.get("locale");
|
|
1938
1920
|
if (section?.preference === "zh" || section?.preference === "en") {
|
|
1939
1921
|
activeLocale = section.preference;
|
|
1940
1922
|
}
|
|
1941
|
-
const cleanupScope =
|
|
1923
|
+
const cleanupScope = settings.settings.register(
|
|
1924
|
+
CLEANUP_SETTINGS_NAMESPACE,
|
|
1925
|
+
CleanupConfigSchema,
|
|
1926
|
+
{ base: DEFAULT_CLEANUP_CONFIG }
|
|
1927
|
+
);
|
|
1942
1928
|
cleanupStore = settingsCleanupStore(cleanupScope);
|
|
1943
1929
|
void migrateLegacyCleanupConfig(
|
|
1944
1930
|
resolveCleanupConfigPath(dshHome),
|
|
@@ -5,7 +5,17 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module dsh-rewind/client/hidden
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
8
|
+
import type { CommandNode } from '@deepseek-ai/dsh-client-ui-conversation/client';
|
|
9
|
+
/** A chat-snapshot view node as the hiding / composer-refill logic reads it.
|
|
10
|
+
* The harness's view node shape plus the `anchorSeq` the chat snapshot carries
|
|
11
|
+
* (the plugin reads `anchorSeq` off each node; it is not declared on the
|
|
12
|
+
* harness's `ConversationViewNode`). */
|
|
13
|
+
export interface ChatConversationViewNode {
|
|
14
|
+
readonly key: string;
|
|
15
|
+
readonly kind?: string;
|
|
16
|
+
readonly data?: unknown;
|
|
17
|
+
readonly anchorSeq: number;
|
|
18
|
+
}
|
|
9
19
|
/** Minimal chat snapshot reader the hiding logic needs. */
|
|
10
20
|
export interface HiddenChat {
|
|
11
21
|
readonly order: readonly string[];
|
|
@@ -14,53 +24,36 @@ export interface HiddenChat {
|
|
|
14
24
|
};
|
|
15
25
|
}
|
|
16
26
|
/**
|
|
17
|
-
* Reader for one session's live chat snapshot.
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* dsh-client-ui-chat through the uiSession slot hook).
|
|
27
|
+
* Reader for one session's live chat snapshot. On the 0.1.2-rc.1 line (the
|
|
28
|
+
* plugin's single baseline) the chat is served by the `uiConversation`
|
|
29
|
+
* service's named "chat" view (contributed by dsh-client-ui-chat through the
|
|
30
|
+
* uiSession slot hook).
|
|
22
31
|
*/
|
|
23
32
|
export type ChatOf = (session: {
|
|
24
33
|
readonly sessionId: string;
|
|
25
|
-
getSnapshot(): {
|
|
26
|
-
chat?: unknown;
|
|
27
|
-
};
|
|
28
34
|
} | undefined) => HiddenChat | undefined;
|
|
29
35
|
/**
|
|
30
36
|
* Subscribe to one session's live chat-update signal, for waiting on a chat
|
|
31
|
-
* snapshot change without polling.
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* chat-update signal). `cb` fires whenever the chat snapshot invalidates.
|
|
37
|
+
* snapshot change without polling. The 0.1.2-rc.1 `uiConversation` "chat"
|
|
38
|
+
* view's own `subscribe` is the chat-update signal; `cb` fires whenever the
|
|
39
|
+
* chat snapshot invalidates.
|
|
35
40
|
*/
|
|
36
41
|
export type ChatWatch = (sessionId: string, cb: () => void) => () => void;
|
|
37
42
|
/**
|
|
38
|
-
* Choose the chat-update subscription for `waitForCommand`:
|
|
39
|
-
* `uiConversation` "chat" view's own `subscribe
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* chat-update signal). Extracted as a pure channel-selection step so the
|
|
43
|
-
* "view vs face" branch is unit-testable; the resolvers are injected by the
|
|
44
|
-
* caller (see `watchChat` in index.ts). Never throws.
|
|
43
|
+
* Choose the chat-update subscription for `waitForCommand`: the
|
|
44
|
+
* `uiConversation` "chat" view's own `subscribe`. Extracted as a pure
|
|
45
|
+
* channel-selection step so the resolver is unit-testable; the resolver is
|
|
46
|
+
* injected by the caller (see `watchChat` in index.ts). Never throws.
|
|
45
47
|
*/
|
|
46
48
|
export declare function resolveChatWatch(resolveView: (sessionId: string) => {
|
|
47
49
|
subscribe?(cb: () => void): () => void;
|
|
48
|
-
} | undefined, resolveFace: (sessionId: string) => {
|
|
49
|
-
subscribe(cb: () => void): () => void;
|
|
50
50
|
} | undefined, sessionId: string, cb: () => void): () => void;
|
|
51
51
|
/**
|
|
52
|
-
* Resolve the chat snapshot
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* `getSnapshot()` returns undefined until the named view is registered, so
|
|
56
|
-
* both channels missing degrades to `undefined` (no targets, no hiding —
|
|
57
|
-
* never a crash).
|
|
52
|
+
* Resolve the chat snapshot from the `uiConversation` "chat" view. The view's
|
|
53
|
+
* `getSnapshot()` returns undefined until the named view is registered, which
|
|
54
|
+
* degrades to `undefined` (no targets, no hiding — never a crash).
|
|
58
55
|
*/
|
|
59
|
-
export declare function chatSnapshotOf(
|
|
60
|
-
getSnapshot(): {
|
|
61
|
-
chat?: unknown;
|
|
62
|
-
};
|
|
63
|
-
} | undefined, chatView: {
|
|
56
|
+
export declare function chatSnapshotOf(chatView: {
|
|
64
57
|
getSnapshot(): unknown;
|
|
65
58
|
} | undefined): HiddenChat | undefined;
|
|
66
59
|
/**
|
|
@@ -26,9 +26,27 @@
|
|
|
26
26
|
*
|
|
27
27
|
* @module dsh-rewind/client
|
|
28
28
|
*/
|
|
29
|
-
import type {
|
|
29
|
+
import type { ISessions } from '@deepseek-ai/dsh-api-session-controller/client';
|
|
30
30
|
export declare const name = "dsh-rewind";
|
|
31
31
|
export declare const inject: string[];
|
|
32
|
+
/**
|
|
33
|
+
* The client plugin root context read by `apply(ctx)`. Local structural face:
|
|
34
|
+
* the harness client context is a cordis `Context` augmented by runtime
|
|
35
|
+
* services, so the plugin declares the subset it reads. `sessions` is the real
|
|
36
|
+
* `ISessions` from `@deepseek-ai/dsh-api-session-controller`.
|
|
37
|
+
*/
|
|
38
|
+
export interface ClientContext {
|
|
39
|
+
effect(execute: () => Iterable<unknown>, label?: string): unknown;
|
|
40
|
+
locale: {
|
|
41
|
+
register(namespace: string, messages: Record<string, Record<string, string>>): unknown;
|
|
42
|
+
bind(namespace: string): (key: string) => string;
|
|
43
|
+
subscribe(cb: () => void): () => void;
|
|
44
|
+
};
|
|
45
|
+
sessions: ISessions;
|
|
46
|
+
get(name: string): unknown;
|
|
47
|
+
slots: unknown;
|
|
48
|
+
commandUi: unknown;
|
|
49
|
+
}
|
|
32
50
|
/**
|
|
33
51
|
* Client plugin body: command decoration + parameterized guard + locale + the
|
|
34
52
|
* portal bridge.
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
*
|
|
14
14
|
* @module dsh-rewind/client/popover
|
|
15
15
|
*/
|
|
16
|
-
import type { SessionFace } from '@deepseek-ai/dsh-
|
|
17
|
-
import type { CommandNode } from '@deepseek-ai/dsh-client-
|
|
16
|
+
import type { SessionFace } from '@deepseek-ai/dsh-api-session-controller/client';
|
|
17
|
+
import type { CommandNode } from '@deepseek-ai/dsh-client-ui-conversation/client';
|
|
18
18
|
import { type ChatOf, type ChatWatch } from './hidden.ts';
|
|
19
19
|
import type { RewindKey } from './locales.ts';
|
|
20
20
|
type Translate = (key: RewindKey, params?: Record<string, unknown>) => string;
|
|
@@ -33,16 +33,15 @@ export interface PopoverOptions {
|
|
|
33
33
|
readonly onRetract?: () => void;
|
|
34
34
|
readonly preview: string;
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
36
|
+
* Chat reader on the 0.1.2-rc.1 `uiConversation` "chat" view: the durable
|
|
37
|
+
* variant's command probes scan the chat through it. Unused by the
|
|
38
|
+
* pending-retract variant.
|
|
39
39
|
*/
|
|
40
40
|
readonly chatOf: ChatOf;
|
|
41
41
|
/**
|
|
42
42
|
* Subscribe to one session's live chat-update signal, so a probe waiting on
|
|
43
|
-
* a command's chat node can be woken when the chat snapshot changes
|
|
44
|
-
*
|
|
45
|
-
* to `waitForCommand`.
|
|
43
|
+
* a command's chat node can be woken when the chat snapshot changes. Passed
|
|
44
|
+
* straight through to `waitForCommand`.
|
|
46
45
|
*/
|
|
47
46
|
readonly watchChat: ChatWatch;
|
|
48
47
|
/** The button that opened the popover (outside-click ignore target). */
|
|
@@ -70,7 +69,7 @@ export declare function knownCommandSeqs(session: SessionFace, chatOf: ChatOf, m
|
|
|
70
69
|
* session snapshot (command/run + command/done land as one CommandNode).
|
|
71
70
|
* @returns the outcome text-bearing node, or null on timeout.
|
|
72
71
|
*/
|
|
73
|
-
export declare function waitForCommand(session: SessionFace, chatOf: ChatOf, match: (node: CommandNode) => boolean, timeoutMs
|
|
72
|
+
export declare function waitForCommand(session: SessionFace, chatOf: ChatOf, match: (node: CommandNode) => boolean, timeoutMs: number | undefined, watch: (cb: () => void) => () => void): Promise<{
|
|
74
73
|
kind: 'success' | 'error';
|
|
75
74
|
text?: string;
|
|
76
75
|
} | null>;
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* @module dsh-rewind/client/portals
|
|
24
24
|
*/
|
|
25
25
|
import { type ReactNode } from 'react';
|
|
26
|
-
import type { SessionFace } from '@deepseek-ai/dsh-
|
|
26
|
+
import type { SessionFace } from '@deepseek-ai/dsh-api-session-controller/client';
|
|
27
27
|
import { type ChatOf, type ChatWatch, type HiddenChat } from './hidden.ts';
|
|
28
28
|
import type { RewindKey } from './locales.ts';
|
|
29
29
|
type Translate = (key: RewindKey, params?: Record<string, unknown>) => string;
|
|
@@ -53,26 +53,23 @@ export type PortalTarget = {
|
|
|
53
53
|
export interface RewindBridgeDeps {
|
|
54
54
|
readonly sessionOf: (sessionId: string) => SessionFace | undefined;
|
|
55
55
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* `chatSnapshotOf` in hidden.ts for the channel precedence.
|
|
56
|
+
* Chat reader on the 0.1.2-rc.1 `uiConversation` "chat" view: every chat
|
|
57
|
+
* snapshot read goes through it. See `chatSnapshotOf` in hidden.ts.
|
|
59
58
|
*/
|
|
60
59
|
readonly chatOf: ChatOf;
|
|
61
60
|
/**
|
|
62
61
|
* Subscribe to one session's live chat-update signal, so the composer refill
|
|
63
62
|
* waiting on an executed rewind's chat node can be woken when the chat
|
|
64
|
-
* snapshot changes
|
|
65
|
-
* update). Passed through to `waitForCommand`.
|
|
63
|
+
* snapshot changes. Passed through to `waitForCommand`.
|
|
66
64
|
*/
|
|
67
65
|
readonly watchChat: ChatWatch;
|
|
68
66
|
readonly currentSessionId: () => string | undefined;
|
|
69
67
|
readonly t: Translate;
|
|
70
68
|
readonly subscribeLocale: (cb: () => void) => () => void;
|
|
71
69
|
/**
|
|
72
|
-
* Session-aware
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* session that just rewound.
|
|
70
|
+
* Session-aware composer writer (see `writeComposer`): the 0.1.2-rc.1
|
|
71
|
+
* `conversation.input` facade `setDraft` when reachable, else the DOM fill.
|
|
72
|
+
* Session-scoped so the refill only lands in the session that just rewound.
|
|
76
73
|
*/
|
|
77
74
|
readonly setComposerText: (sessionId: string, text: string) => boolean;
|
|
78
75
|
}
|
|
@@ -90,7 +87,7 @@ export interface SlotsLike {
|
|
|
90
87
|
}
|
|
91
88
|
/** Join the text blocks of a user message into one plain preview. */
|
|
92
89
|
/**
|
|
93
|
-
* The
|
|
90
|
+
* The 0.1.2-rc.1 session input facade's write face (structural, so the plugin
|
|
94
91
|
* never imports the conversation UI package). `setDraft` replaces the whole
|
|
95
92
|
* composer draft through the harness's own Lexical editor — the correct way
|
|
96
93
|
* to restore the withdrawn text.
|
|
@@ -99,22 +96,20 @@ interface ComposerDraftWriter {
|
|
|
99
96
|
setDraft(text: string): void;
|
|
100
97
|
}
|
|
101
98
|
/**
|
|
102
|
-
* Fill the dsh composer with `text
|
|
103
|
-
*
|
|
104
|
-
* `
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
* never a throw.
|
|
99
|
+
* Fill the dsh composer with `text` through the 0.1.2-rc.1 `contenteditable`
|
|
100
|
+
* DOM path. Used by `setComposerText` (the harness-facade-aware writer) as the
|
|
101
|
+
* last-resort and by `runRewindAndFill` to put the withdrawn target message
|
|
102
|
+
* back into the composer after a rewind. Best-effort — no composer match means
|
|
103
|
+
* false, never a throw.
|
|
108
104
|
*/
|
|
109
105
|
export declare function fillComposer(text: string): boolean;
|
|
110
106
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* still restores the text. Never throws.
|
|
107
|
+
* Composer write: prefer the harness facade's `setDraft` (0.1.2-rc.1, correct
|
|
108
|
+
* whole-draft replace), then degrade to the DOM `fillComposer` (0.1.2-rc.1
|
|
109
|
+
* contenteditable). A facade that throws (session teardown) is treated as
|
|
110
|
+
* absent so the DOM path still restores the text. Never throws.
|
|
116
111
|
* @param text - the withdrawn target message text.
|
|
117
|
-
* @param facade - the
|
|
112
|
+
* @param facade - the 0.1.2-rc.1 session input draft writer, when reachable.
|
|
118
113
|
* @returns whether a channel applied the text.
|
|
119
114
|
*/
|
|
120
115
|
export declare function writeComposer(text: string, facade: ComposerDraftWriter | undefined): boolean;
|
|
@@ -136,21 +131,15 @@ export declare function runRewindAndFill(session: SessionFace, seq: number, mode
|
|
|
136
131
|
* Locate the actions container of a user/steering seat row — the element the
|
|
137
132
|
* ↶ button portals into (the copy/branch IconActions row).
|
|
138
133
|
*
|
|
139
|
-
*
|
|
140
|
-
* -
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
* - alpha.4 (0.1.2-alpha.4): the marker was removed from user rows (it now
|
|
145
|
-
* lives only on the per-turn tail footer, `TurnTailNodeView`), and the user
|
|
146
|
-
* action row is revealed via CSS `:has()`. The container is instead located
|
|
147
|
-
* structurally: the direct holder of the copy `<button>` (the
|
|
148
|
-
* `MessageIconActions` container, which mounts that button as a direct
|
|
149
|
-
* child — `MessageIconActions.tsx:83,86`).
|
|
134
|
+
* On the 0.1.2-rc.1 line the `data-time-hover-root` marker lives only on the
|
|
135
|
+
* per-turn tail footer (`TurnTailNodeView`), and the user action row is
|
|
136
|
+
* revealed via CSS `:has()`. The container is located structurally: the direct
|
|
137
|
+
* holder of the copy `<button>` (the `MessageIconActions` container, which
|
|
138
|
+
* mounts that button as a direct child — `MessageIconActions.tsx:83,86`).
|
|
150
139
|
*
|
|
151
140
|
* Returns undefined when no qualifying container is found; the caller refuses
|
|
152
141
|
* to portal (never a crash, never a wrong attachment). Exported as a test seam
|
|
153
|
-
* (see `collectTargets`) so the
|
|
142
|
+
* (see `collectTargets`) so the row-shape finder is exercised directly for
|
|
154
143
|
* both durable and pending row shapes without a full React portal render.
|
|
155
144
|
*/
|
|
156
145
|
export declare function actionsContainerOf(row: HTMLElement | undefined): HTMLElement | undefined;
|
|
@@ -171,9 +160,9 @@ interface RewindPortalsProps extends RewindBridgeDeps {
|
|
|
171
160
|
* synchronous full-transcript scan inside a commit microtask.
|
|
172
161
|
*/
|
|
173
162
|
export declare function RewindPortals({ sessionId, sessionOf, chatOf, currentSessionId, watchChat, t, subscribeLocale, setComposerText }: RewindPortalsProps): ReactNode;
|
|
174
|
-
/** The current composer draft
|
|
175
|
-
*
|
|
176
|
-
*
|
|
163
|
+
/** The current composer draft: the 0.1.2-rc.1 contenteditable `textContent`.
|
|
164
|
+
* Empty when the composer is absent. Exported as a test seam (the
|
|
165
|
+
* empty-composer guard in `retractPending`). */
|
|
177
166
|
export declare function composerText(): string;
|
|
178
167
|
/**
|
|
179
168
|
* Build the slot-entry component for the plugin apply(): a tiny bridge that
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
* host schema enforces). "Discard changes" restores the last-read baseline.
|
|
12
12
|
*
|
|
13
13
|
* It neither imports the client settings typed contract nor depends on the
|
|
14
|
-
*
|
|
15
|
-
* the `set(field, value)` method
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* 0.1.2-rc.1-only `mutate` write API: it reads `getSnapshot().value` and writes
|
|
15
|
+
* via the `set(field, value)` method, and the card receives a tiny structural
|
|
16
|
+
* `CleanupCardApi` supplied by `src/client/index.ts` so the component stays
|
|
17
|
+
* harness-agnostic and unit-testable in isolation.
|
|
18
18
|
*
|
|
19
19
|
* @module dsh-rewind/client/settings-card
|
|
20
20
|
*/
|
|
@@ -23,4 +23,4 @@ export declare const CLASS: {
|
|
|
23
23
|
/** The ↶ glyph, drawn inline so the bundle stays dependency-free. */
|
|
24
24
|
export declare const REWIND_ICON_SVG: string;
|
|
25
25
|
/** One injected stylesheet (scoped under `.dsh-rewind-*`). */
|
|
26
|
-
export declare const STYLE = "\n.dsh-rewind-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 6px;\n border: none;\n border-radius: 28px;\n background: transparent;\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n.dsh-rewind-btn:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-secondary);\n}\n\n.dsh-rewind-popover {\n position: fixed;\n z-index: 1000;\n width: 288px;\n padding: 12px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n background: var(--dsw-specific-menu, var(--dsw-alias-bg-layer-3));\n box-shadow: var(--dsw-shadow-lv3);\n font-size: 14px;\n line-height: 20px;\n color: var(--dsw-alias-label-primary);\n}\n.dsh-rewind-popover-title {\n font-size: 14px;\n font-weight: 600;\n line-height: 20px;\n}\n.dsh-rewind-popover-target {\n margin: 4px 0 10px;\n font-size: 12px;\n line-height: 16px;\n color: var(--dsw-alias-label-tertiary);\n word-break: break-all;\n}\n.dsh-rewind-popover-option {\n display: flex;\n flex-direction: column;\n gap: 2px;\n width: 100%;\n margin: 0 0 6px;\n padding: 8px 10px;\n border: 1px solid transparent;\n border-radius: 8px;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n.dsh-rewind-popover-option:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-rewind-popover-option:disabled {\n opacity: 0.5;\n cursor: default;\n}\n.dsh-rewind-popover-option-label {\n font-weight: 500;\n}\n.dsh-rewind-popover-option-hint {\n font-size: 12px;\n line-height: 16px;\n color: var(--dsw-alias-label-tertiary);\n}\n.dsh-rewind-popover-impact {\n margin: 4px 0 10px;\n padding: 8px 10px;\n border-radius: 8px;\n background: var(--dsw-alias-interactive-bg-hover);\n font-size: 12px;\n line-height: 16px;\n color: var(--dsw-alias-label-secondary);\n white-space: pre-wrap;\n max-height: 160px;\n overflow: auto;\n}\n.dsh-rewind-popover-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n}\n.dsh-rewind-popover-primary,\n.dsh-rewind-popover-ghost {\n padding: 5px 12px;\n border: none;\n border-radius: 8px;\n font: inherit;\n font-size: 13px;\n line-height: 18px;\n cursor: pointer;\n}\n.dsh-rewind-popover-primary {\n background: var(--dsw-alias-button-primary-fill);\n color: var(--dsw-alias-label-primary-foreground);\n}\n.dsh-rewind-popover-primary:hover:not(:disabled) {\n background: var(--dsw-alias-button-primary-hover);\n}\n.dsh-rewind-popover-primary:disabled {\n opacity: 0.5;\n cursor: default;\n}\n.dsh-rewind-popover-ghost {\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n}\n.dsh-rewind-popover-ghost:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.dsh-rewind-guard-hint {\n position: fixed;\n z-index: 1000;\n max-width: min(440px, calc(100vw - 24px));\n padding: 8px 12px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 10px;\n background: var(--dsw-specific-menu, var(--dsw-alias-bg-layer-3));\n box-shadow: var(--dsw-shadow-lv3);\n font-size: 13px;\n line-height: 18px;\n color: var(--dsw-alias-label-primary);\n pointer-events: none;\n}\n\n/* ---- Snapshot-cleanup settings card (mirrors the harness PluginCard look) ---- */\n/*
|
|
26
|
+
export declare const STYLE = "\n.dsh-rewind-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 6px;\n border: none;\n border-radius: 28px;\n background: transparent;\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n.dsh-rewind-btn:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-secondary);\n}\n\n.dsh-rewind-popover {\n position: fixed;\n z-index: 1000;\n width: 288px;\n padding: 12px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n background: var(--dsw-specific-menu, var(--dsw-alias-bg-layer-3));\n box-shadow: var(--dsw-shadow-lv3);\n font-size: 14px;\n line-height: 20px;\n color: var(--dsw-alias-label-primary);\n}\n.dsh-rewind-popover-title {\n font-size: 14px;\n font-weight: 600;\n line-height: 20px;\n}\n.dsh-rewind-popover-target {\n margin: 4px 0 10px;\n font-size: 12px;\n line-height: 16px;\n color: var(--dsw-alias-label-tertiary);\n word-break: break-all;\n}\n.dsh-rewind-popover-option {\n display: flex;\n flex-direction: column;\n gap: 2px;\n width: 100%;\n margin: 0 0 6px;\n padding: 8px 10px;\n border: 1px solid transparent;\n border-radius: 8px;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n.dsh-rewind-popover-option:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.dsh-rewind-popover-option:disabled {\n opacity: 0.5;\n cursor: default;\n}\n.dsh-rewind-popover-option-label {\n font-weight: 500;\n}\n.dsh-rewind-popover-option-hint {\n font-size: 12px;\n line-height: 16px;\n color: var(--dsw-alias-label-tertiary);\n}\n.dsh-rewind-popover-impact {\n margin: 4px 0 10px;\n padding: 8px 10px;\n border-radius: 8px;\n background: var(--dsw-alias-interactive-bg-hover);\n font-size: 12px;\n line-height: 16px;\n color: var(--dsw-alias-label-secondary);\n white-space: pre-wrap;\n max-height: 160px;\n overflow: auto;\n}\n.dsh-rewind-popover-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n}\n.dsh-rewind-popover-primary,\n.dsh-rewind-popover-ghost {\n padding: 5px 12px;\n border: none;\n border-radius: 8px;\n font: inherit;\n font-size: 13px;\n line-height: 18px;\n cursor: pointer;\n}\n.dsh-rewind-popover-primary {\n background: var(--dsw-alias-button-primary-fill);\n color: var(--dsw-alias-label-primary-foreground);\n}\n.dsh-rewind-popover-primary:hover:not(:disabled) {\n background: var(--dsw-alias-button-primary-hover);\n}\n.dsh-rewind-popover-primary:disabled {\n opacity: 0.5;\n cursor: default;\n}\n.dsh-rewind-popover-ghost {\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n}\n.dsh-rewind-popover-ghost:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.dsh-rewind-guard-hint {\n position: fixed;\n z-index: 1000;\n max-width: min(440px, calc(100vw - 24px));\n padding: 8px 12px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 10px;\n background: var(--dsw-specific-menu, var(--dsw-alias-bg-layer-3));\n box-shadow: var(--dsw-shadow-lv3);\n font-size: 13px;\n line-height: 18px;\n color: var(--dsw-alias-label-primary);\n pointer-events: none;\n}\n\n/* ---- Snapshot-cleanup settings card (mirrors the harness PluginCard look) ---- */\n/* Standardized on the 0.1.2 harness card look (border-radius 16px + 0.5px\n border-l4, 0.5px internal separators). */\n.dsh-rewind-cleanup-card {\n list-style: none;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 16px;\n background: var(--dsw-alias-bg-layer-3);\n transition: border-color .16s, background .16s;\n}\n.dsh-rewind-cleanup-card:hover {\n border-color: var(--dsw-alias-label-dimmed);\n}\n.dsh-rewind-cleanup-card-open {\n background: var(--dsw-alias-bg-layer-2);\n border-color: var(--dsw-alias-label-dimmed);\n}\n.dsh-rewind-cleanup-header {\n width: 100%;\n appearance: none;\n border: 0;\n background: none;\n font: inherit;\n color: inherit;\n text-align: left;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n border-radius: 12px;\n}\n.dsh-rewind-cleanup-header:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n.dsh-rewind-cleanup-head-text {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.dsh-rewind-cleanup-name {\n font-size: 15px;\n font-weight: 600;\n line-height: 1.4;\n color: var(--dsw-alias-label-primary);\n}\n.dsh-rewind-cleanup-desc {\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n.dsh-rewind-cleanup-chevron {\n flex: none;\n color: var(--dsw-alias-label-tertiary);\n transition: transform .16s;\n}\n.dsh-rewind-cleanup-chevron-open {\n transform: rotate(180deg);\n}\n.dsh-rewind-cleanup-pending {\n flex: none;\n border-radius: 999px;\n padding: 1px 8px;\n font-size: 11px;\n line-height: 17px;\n font-weight: 500;\n white-space: nowrap;\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-secondary);\n}\n.dsh-rewind-cleanup-body {\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n margin: 0 16px;\n padding: 4px 0 8px;\n}\n.dsh-rewind-cleanup-readonly {\n margin: 12px 0 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n.dsh-rewind-cleanup-permission {\n display: grid;\n gap: 6px;\n padding: 12px 0;\n}\n.dsh-rewind-cleanup-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px 0;\n}\n.dsh-rewind-cleanup-field + .dsh-rewind-cleanup-field {\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n.dsh-rewind-cleanup-head {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.dsh-rewind-cleanup-label {\n flex: 1;\n min-width: 0;\n font-size: 13px;\n font-weight: 500;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n}\n.dsh-rewind-cleanup-hint {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n.dsh-rewind-cleanup-error {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-error);\n}\n/* Switch row: label left, role=switch button right, hint below (Subagent module). */\n.dsh-rewind-cleanup-toggle-row {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n}\n.dsh-rewind-cleanup-toggle-label {\n flex: 1;\n min-width: 0;\n}\n.dsh-rewind-cleanup-switch {\n box-sizing: border-box;\n position: relative;\n flex: 0 0 auto;\n width: 36px;\n height: 20px;\n padding: 2px;\n border: 0;\n border-radius: 10px;\n background: var(--dsw-alias-border-l3);\n cursor: pointer;\n}\n.dsh-rewind-cleanup-switch-on {\n background: var(--dsw-alias-brand-primary);\n}\n.dsh-rewind-cleanup-switch:disabled {\n cursor: default;\n opacity: 0.5;\n}\n.dsh-rewind-cleanup-switch:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 2px;\n}\n.dsh-rewind-cleanup-thumb {\n display: block;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n corner-shape: round;\n background: var(--dsw-alias-label-primary-foreground);\n transition: transform 120ms ease;\n}\n.dsh-rewind-cleanup-switch-on .dsh-rewind-cleanup-thumb {\n transform: translateX(16px);\n}\n.dsh-rewind-cleanup-input {\n box-sizing: border-box;\n height: 34px;\n padding: 0 12px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-3);\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n}\n.dsh-rewind-cleanup-input:focus-visible {\n outline: none;\n border-color: var(--dsw-alias-brand-primary);\n}\n.dsh-rewind-cleanup-input:disabled {\n color: var(--dsw-alias-label-tertiary);\n cursor: default;\n}\n.dsh-rewind-cleanup-input-invalid {\n border-color: var(--dsw-alias-label-error);\n}\n.dsh-rewind-cleanup-footer {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n padding: 12px 0 4px;\n border-top: 1px solid var(--dsw-alias-border-l2);\n}\n.dsh-rewind-cleanup-failed {\n flex: 1;\n min-width: 0;\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-error);\n}\n.dsh-rewind-cleanup-discard,\n.dsh-rewind-cleanup-save {\n appearance: none;\n border: 1px solid transparent;\n border-radius: 8px;\n padding: 5px 14px;\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n cursor: pointer;\n}\n.dsh-rewind-cleanup-discard {\n border-color: var(--dsw-alias-border-l2);\n background: none;\n color: var(--dsw-alias-label-secondary);\n}\n.dsh-rewind-cleanup-discard:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n border-color: var(--dsw-alias-label-dimmed);\n}\n.dsh-rewind-cleanup-save {\n background: var(--dsw-alias-label-primary);\n color: var(--dsw-alias-bg-layer-3);\n}\n.dsh-rewind-cleanup-discard:disabled,\n.dsh-rewind-cleanup-save:disabled {\n opacity: 0.4;\n cursor: default;\n}\n.dsh-rewind-cleanup-discard:focus-visible,\n.dsh-rewind-cleanup-save:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n";
|
|
@@ -46,9 +46,9 @@ export declare const CleanupConfigSchema: z<CleanupConfig>;
|
|
|
46
46
|
/**
|
|
47
47
|
* Structural face of the settings scope the host needs for the policy: a
|
|
48
48
|
* resolved read and a validated write. Kept local (never imports the settings
|
|
49
|
-
* contract) so the host bundle
|
|
50
|
-
* API
|
|
51
|
-
*
|
|
49
|
+
* contract) so the host bundle does not type-couple on the client settings
|
|
50
|
+
* API (0.1.2 adds `mutate`; it is unused here), and the seam the host passes
|
|
51
|
+
* in isolates the drift to this module.
|
|
52
52
|
*/
|
|
53
53
|
export interface CleanupSettingsScope {
|
|
54
54
|
/** The resolved policy: schema defaults, then base, then the user layer. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-rewind-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0-alpha.1",
|
|
4
4
|
"description": "DSH 插件:真正便捷无感的同窗口内对话回退,从不新建分支;自带轻量工作区备份,可一并还原文件(完整 Claude Code /rewind 语义)。 · DSH plugin: genuinely effortless in-window conversation rewind — never forking a new session; ships a lightweight workspace backup that restores files together with the rewind (full Claude Code /rewind semantics).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
|
@@ -52,7 +52,6 @@
|
|
|
52
52
|
"client": {
|
|
53
53
|
"inject": [
|
|
54
54
|
"@deepseek-ai/dsh-client-locale",
|
|
55
|
-
"@deepseek-ai/dsh-client-runtime",
|
|
56
55
|
"@deepseek-ai/dsh-client-ui-commands",
|
|
57
56
|
"@deepseek-ai/dsh-client-ui-conversation",
|
|
58
57
|
"@deepseek-ai/dsh-client-ui-settings"
|
|
@@ -74,19 +73,18 @@
|
|
|
74
73
|
"peerDependencies": {
|
|
75
74
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
76
75
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
77
|
-
"@deepseek-ai/dsh-client-locale": "^0.1.
|
|
78
|
-
"@deepseek-ai/dsh-client-
|
|
79
|
-
"@deepseek-ai/dsh-client-ui-
|
|
80
|
-
"@deepseek-ai/dsh-client-ui-
|
|
81
|
-
"@deepseek-ai/dsh-
|
|
82
|
-
"@deepseek-ai/dsh-
|
|
83
|
-
"@deepseek-ai/dsh-
|
|
84
|
-
"@deepseek-ai/dsh-
|
|
85
|
-
"@deepseek-ai/dsh-
|
|
86
|
-
"@deepseek-ai/dsh-
|
|
87
|
-
"@deepseek-ai/dsh-
|
|
88
|
-
"@deepseek-ai/dsh-
|
|
89
|
-
"@deepseek-ai/dsh-tools": "^0.1.0-rc.6 || ^0.1.1-rc.2 || ^0.1.2-alpha.2"
|
|
76
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.2-rc.1",
|
|
77
|
+
"@deepseek-ai/dsh-client-ui-commands": "^0.1.2-rc.1",
|
|
78
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.2-rc.1",
|
|
79
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.2-rc.1",
|
|
80
|
+
"@deepseek-ai/dsh-commands": "^0.1.2-rc.1",
|
|
81
|
+
"@deepseek-ai/dsh-fs": "^0.1.2-rc.1",
|
|
82
|
+
"@deepseek-ai/dsh-home-paths": "^0.1.2-rc.1",
|
|
83
|
+
"@deepseek-ai/dsh-llm": "^0.1.2-rc.1",
|
|
84
|
+
"@deepseek-ai/dsh-sandbox": "^0.1.2-rc.1",
|
|
85
|
+
"@deepseek-ai/dsh-session": "^0.1.2-rc.1",
|
|
86
|
+
"@deepseek-ai/dsh-settings": "^0.1.2-rc.1",
|
|
87
|
+
"@deepseek-ai/dsh-tools": "^0.1.2-rc.1"
|
|
90
88
|
},
|
|
91
89
|
"peerDependenciesMeta": {
|
|
92
90
|
"@deepseek-ai/cordis": {
|
|
@@ -98,9 +96,6 @@
|
|
|
98
96
|
"@deepseek-ai/dsh-client-locale": {
|
|
99
97
|
"optional": true
|
|
100
98
|
},
|
|
101
|
-
"@deepseek-ai/dsh-client-runtime": {
|
|
102
|
-
"optional": true
|
|
103
|
-
},
|
|
104
99
|
"@deepseek-ai/dsh-client-ui-commands": {
|
|
105
100
|
"optional": true
|
|
106
101
|
},
|
|
@@ -138,29 +133,37 @@
|
|
|
138
133
|
"devDependencies": {
|
|
139
134
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
140
135
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
141
|
-
"@deepseek-ai/dsh-agent": "^0.1.
|
|
142
|
-
"@deepseek-ai/dsh-
|
|
143
|
-
"@deepseek-ai/dsh-client-
|
|
144
|
-
"@deepseek-ai/dsh-client-
|
|
145
|
-
"@deepseek-ai/dsh-client-
|
|
146
|
-
"@deepseek-ai/dsh-client-ui-
|
|
147
|
-
"@deepseek-ai/dsh-
|
|
148
|
-
"@deepseek-ai/dsh-
|
|
149
|
-
"@deepseek-ai/dsh-
|
|
150
|
-
"@deepseek-ai/dsh-
|
|
151
|
-
"@deepseek-ai/dsh-
|
|
152
|
-
"@deepseek-ai/dsh-
|
|
153
|
-
"@deepseek-ai/dsh-
|
|
154
|
-
"@deepseek-ai/dsh-
|
|
155
|
-
"@deepseek-ai/dsh-
|
|
156
|
-
"@deepseek-ai/dsh-
|
|
157
|
-
"@deepseek-ai/dsh-
|
|
158
|
-
"@deepseek-ai/dsh-
|
|
159
|
-
"@deepseek-ai/dsh-
|
|
160
|
-
"@deepseek-ai/dsh-
|
|
161
|
-
"@deepseek-ai/dsh-
|
|
162
|
-
"@deepseek-ai/dsh-
|
|
163
|
-
"@deepseek-ai/dsh-
|
|
136
|
+
"@deepseek-ai/dsh-agent": "^0.1.2-rc.1",
|
|
137
|
+
"@deepseek-ai/dsh-attachment": "^0.1.2-rc.1",
|
|
138
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.2-rc.1",
|
|
139
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.2-rc.1",
|
|
140
|
+
"@deepseek-ai/dsh-client-store": "^0.1.2-rc.1",
|
|
141
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-rc.1",
|
|
142
|
+
"@deepseek-ai/dsh-api-session-controller": "^0.1.2-rc.1",
|
|
143
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.2-rc.1",
|
|
144
|
+
"@deepseek-ai/dsh-scope": "^0.1.2-rc.1",
|
|
145
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.2-rc.1",
|
|
146
|
+
"@deepseek-ai/dsh-user-questions": "^0.1.2-rc.1",
|
|
147
|
+
"@deepseek-ai/dsh-client-ui-commands": "^0.1.2-rc.1",
|
|
148
|
+
"@deepseek-ai/dsh-client-ui-input-trigger": "^0.1.2-rc.1",
|
|
149
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.2-rc.1",
|
|
150
|
+
"@deepseek-ai/dsh-command-compact": "^0.1.2-rc.1",
|
|
151
|
+
"@deepseek-ai/dsh-commands": "^0.1.2-rc.1",
|
|
152
|
+
"@deepseek-ai/dsh-compaction": "^0.1.2-rc.1",
|
|
153
|
+
"@deepseek-ai/dsh-compaction-basic": "^0.1.2-rc.1",
|
|
154
|
+
"@deepseek-ai/dsh-fs": "^0.1.2-rc.1",
|
|
155
|
+
"@deepseek-ai/dsh-goal": "^0.1.2-rc.1",
|
|
156
|
+
"@deepseek-ai/dsh-home-paths": "^0.1.2-rc.1",
|
|
157
|
+
"@deepseek-ai/dsh-llm": "^0.1.2-rc.1",
|
|
158
|
+
"@deepseek-ai/dsh-plan-mode": "^0.1.2-rc.1",
|
|
159
|
+
"@deepseek-ai/dsh-sandbox": "^0.1.2-rc.1",
|
|
160
|
+
"@deepseek-ai/dsh-session": "^0.1.2-rc.1",
|
|
161
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.2-rc.1",
|
|
162
|
+
"@deepseek-ai/dsh-session-stats": "^0.1.2-rc.1",
|
|
163
|
+
"@deepseek-ai/dsh-session-title": "^0.1.2-rc.1",
|
|
164
|
+
"@deepseek-ai/dsh-settings": "^0.1.2-rc.1",
|
|
165
|
+
"@deepseek-ai/dsh-token-meter": "^0.1.2-rc.1",
|
|
166
|
+
"@deepseek-ai/dsh-tools": "^0.1.2-rc.1",
|
|
164
167
|
"@types/node": "^24.0.0",
|
|
165
168
|
"@types/react": "^18.3.31",
|
|
166
169
|
"@types/react-dom": "^18.3.7",
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cross-channel session event-log reader.
|
|
3
|
-
*
|
|
4
|
-
* Harness 0.1.1-rc.2 exposes the full log as `Session.events`
|
|
5
|
-
* (`get events(): readonly SessionEvent[]`), while 0.1.2-alpha.4 removed that
|
|
6
|
-
* member and replaced it with the on-demand APIs `snapshotEvents(from?, to?)`
|
|
7
|
-
* (half-open range, internally cached), `eventAt(seq)`, `ownEvents()` and
|
|
8
|
-
* `seq`. This module reads the full log through whichever channel the host
|
|
9
|
-
* exposes, so the plugin keeps one code path across both.
|
|
10
|
-
*
|
|
11
|
-
* `snapshotEvents()` is deliberately preferred over `ownEvents()`:
|
|
12
|
-
* `snapshotEvents()` defaults to the whole log (including any fork-inherited
|
|
13
|
-
* prefix), which is exactly what `Session.events` returned on rc.2 — the
|
|
14
|
-
* rewind semantics are preserved for fork-seeded sessions. `ownEvents()`
|
|
15
|
-
* would drop the inherited prefix and change behaviour.
|
|
16
|
-
*
|
|
17
|
-
* @module dsh-rewind/session-events
|
|
18
|
-
*/
|
|
19
|
-
import type { Session, SessionEvent } from '@deepseek-ai/dsh-session';
|
|
20
|
-
/**
|
|
21
|
-
* Read the full event log of a session, transparently across harness channels:
|
|
22
|
-
* - 0.1.1-rc.2 (`Session.events`): the live immutable log array.
|
|
23
|
-
* - 0.1.2-alpha.4 (`Session.snapshotEvents()`): a deep-frozen snapshot, cached
|
|
24
|
-
* by the session until the next append.
|
|
25
|
-
*
|
|
26
|
-
* Falls back to an empty log when the session exposes neither member (a future
|
|
27
|
-
* harness shape) rather than throwing — callers already treat the empty log as
|
|
28
|
-
* "no candidates".
|
|
29
|
-
*
|
|
30
|
-
* @param session - the session to read.
|
|
31
|
-
* @returns the full event log in log order (the same shape rc.2's `events`
|
|
32
|
-
* returned, so existing consumers are unchanged).
|
|
33
|
-
*/
|
|
34
|
-
export declare function eventsOf(session: Session): readonly SessionEvent[];
|