@deepseek-ai/dsh-experimental-client-ui-forge 0.0.0-stage → 0.2.2-alpha.2

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.
Files changed (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.i18n.yaml +37 -0
  3. package/README.md +134 -2
  4. package/README.zh.md +135 -0
  5. package/lib/client.js +8745 -0
  6. package/lib/index.js +3131 -0
  7. package/lib/typert.host.d.ts +3 -0
  8. package/lib/typert.host.js +2222 -0
  9. package/lib/typert.remote-client.d.ts +79 -0
  10. package/lib/typert.remote-client.js +1284 -0
  11. package/lib/types/client/ActionToast.d.ts +14 -0
  12. package/lib/types/client/ChangeRequestCard.d.ts +54 -0
  13. package/lib/types/client/ChangesTab.d.ts +49 -0
  14. package/lib/types/client/ChangesTabTitle.d.ts +13 -0
  15. package/lib/types/client/DiffFile.d.ts +75 -0
  16. package/lib/types/client/FileLabel.d.ts +20 -0
  17. package/lib/types/client/ForgeTab.d.ts +54 -0
  18. package/lib/types/client/ForgeTabTitle.d.ts +11 -0
  19. package/lib/types/client/HeaderButton.d.ts +27 -0
  20. package/lib/types/client/LocalChangesCard.d.ts +29 -0
  21. package/lib/types/client/RefreshGlyph.d.ts +18 -0
  22. package/lib/types/client/SessionHoverForge.d.ts +20 -0
  23. package/lib/types/client/SessionRowForge.d.ts +39 -0
  24. package/lib/types/client/WorktreeProgress.d.ts +44 -0
  25. package/lib/types/client/WorktreeToggle.d.ts +42 -0
  26. package/lib/types/client/changes-address.d.ts +70 -0
  27. package/lib/types/client/changes-store.d.ts +39 -0
  28. package/lib/types/client/checkout.d.ts +34 -0
  29. package/lib/types/client/diff-rows.d.ts +96 -0
  30. package/lib/types/client/format.d.ts +21 -0
  31. package/lib/types/client/glyphs.d.ts +33 -0
  32. package/lib/types/client/index.d.ts +25 -0
  33. package/lib/types/client/locales.d.ts +228 -0
  34. package/lib/types/client/mount.d.ts +17 -0
  35. package/lib/types/client/session-list.d.ts +46 -0
  36. package/lib/types/client/source.d.ts +146 -0
  37. package/lib/types/client/status.d.ts +95 -0
  38. package/lib/types/diff.d.ts +32 -0
  39. package/lib/types/git.d.ts +93 -0
  40. package/lib/types/index.d.ts +275 -0
  41. package/lib/types/local-diff.d.ts +93 -0
  42. package/lib/types/panel.d.ts +135 -0
  43. package/lib/types/parse.d.ts +57 -0
  44. package/lib/types/patch-cache.d.ts +33 -0
  45. package/lib/types/states.d.ts +89 -0
  46. package/lib/types/types.d.ts +395 -0
  47. package/lib/types/worktree.d.ts +225 -0
  48. package/locale/de.json +6 -0
  49. package/locale/en.json +6 -0
  50. package/locale/es.json +6 -0
  51. package/locale/fr.json +6 -0
  52. package/locale/ja.json +6 -0
  53. package/locale/pt.json +6 -0
  54. package/locale/ru.json +6 -0
  55. package/locale/zh.json +6 -0
  56. package/package.json +123 -3
@@ -0,0 +1,135 @@
1
+ /** Live panel state of one followed Session, shared by all of its followers. */
2
+ import type { Context } from '@deepseek-ai/cordis';
3
+ import type { Session, SessionEvent } from '@deepseek-ai/dsh-session';
4
+ import type { ProjectionHandle } from '@deepseek-ai/dsh-session-projection';
5
+ import type { GitConfig } from './git.ts';
6
+ import type { DiffConfig } from './local-diff.ts';
7
+ import type { ForgeMissingWorktree, ForgePanelState, ForgeWorktreeState } from './types.ts';
8
+ import type { WorktreeCreations } from './worktree.ts';
9
+ /** Git and diff limits plus the sign-in probe deadline. */
10
+ export interface PanelConfig extends DiffConfig {
11
+ /** Deadline in milliseconds for one provider sign-in probe. */
12
+ readonly readinessTimeoutMs: number;
13
+ }
14
+ /**
15
+ * Panel state of one Session. Construction starts the first checkout
16
+ * inspection and watches the Session's change requests. Inspections run one at
17
+ * a time; a request that arrives during one runs once more after it, and a
18
+ * result for a directory the Session has since left is dropped. A sign-in
19
+ * probe runs when an inspection recognizes a new code host and on `refresh`;
20
+ * a probe result for a host the panel no longer shows is dropped. Each change
21
+ * request keeps the latest snapshot a poll returned while later polls fail.
22
+ * When an inspection finds an upstream branch on a remote a provider
23
+ * recognizes, the open change requests of that branch are bound as discovered,
24
+ * once per remote and branch until a refresh. The
25
+ * worktree facts follow the `forgeWorktree` projection, the live creation, and the last failed one;
26
+ * each inspection also decides whether the Session's sandbox can write the
27
+ * checkout and its shared Git directory, which a new worktree needs, whether
28
+ * the worktree the Session created and works in is gone, and how many lines
29
+ * the `branch` scope changes; a measurement that fails leaves that null.
30
+ */
31
+ export declare class SessionPanel {
32
+ private readonly ctx;
33
+ private readonly config;
34
+ readonly session: Session;
35
+ private readonly worktreeStates;
36
+ private readonly creations;
37
+ private readonly onIdle;
38
+ private current;
39
+ private readonly followers;
40
+ private readonly lifetime;
41
+ private readonly tasks;
42
+ private readonly stopWatching;
43
+ private readonly snapshots;
44
+ private blocker;
45
+ private missing;
46
+ private inspection;
47
+ private rerun;
48
+ /** Remote URL and branch of the upstream that the last branch lookup covered, until a refresh. */
49
+ private discovered;
50
+ /**
51
+ * @param ctx - service context that provides the forge, Session, directory, and process services.
52
+ * @param config - Git limits and the sign-in probe deadline.
53
+ * @param session - Session the panel describes.
54
+ * @param worktreeStates - reads the `forgeWorktree` projection of the Session.
55
+ * @param creations - reads the running creation and restoration, the last failed creation, and what a message of the
56
+ * Session waits for.
57
+ * @param onIdle - called when the last follower leaves.
58
+ */
59
+ constructor(ctx: Context, config: PanelConfig, session: Session, worktreeStates: ProjectionHandle<ForgeWorktreeState>, creations: Pick<WorktreeCreations, 'of' | 'restorationOf' | 'failureOf' | 'waitingOf'>, onIdle: () => void);
60
+ /**
61
+ * Yield the current state, then each later state, until `signal` aborts or the panel stops.
62
+ * @param signal - ends this follower.
63
+ * @returns the states in publication order; intermediate states may be skipped.
64
+ */
65
+ follow(signal: AbortSignal): AsyncGenerator<ForgePanelState>;
66
+ /**
67
+ * React to one committed event of the Session: a directory change moves the
68
+ * panel and reinspects; a tool result reinspects, because the tool may have
69
+ * changed the checkout; a sandbox mode change reinspects, because it decides
70
+ * whether a worktree can be created; the first turn, the first step, and
71
+ * worktree records update the worktree facts.
72
+ * @param event - committed Session event.
73
+ */
74
+ observe(event: SessionEvent): void;
75
+ /** Republish the worktree facts when they changed, such as after a creation moved or a worktree service appeared or left. */
76
+ updateWorktree(): void;
77
+ /** Forget the missing worktree once it was checked out again; the next publication carries it, and a reinspection confirms it. */
78
+ restored(): void;
79
+ /** Reinspect the checkout, such as after its directory was created again. */
80
+ reinspect(): void;
81
+ /**
82
+ * Check again whether the worktree the Session works in is gone, publishing a change.
83
+ * @param signal - cancellation of the check.
84
+ * @returns the unavailable worktree, or null for a valid checkout or a Session working elsewhere.
85
+ * @throws when the filesystem or Git cannot answer.
86
+ */
87
+ checkMissing(signal: AbortSignal): Promise<ForgeMissingWorktree | null>;
88
+ /**
89
+ * Reinspect the checkout, probe sign-in again, and poll every bound change request at once.
90
+ * @returns settles once the inspection and the sign-in probe have ended; each poll publishes its result when it finishes.
91
+ */
92
+ refresh(): Promise<void>;
93
+ /**
94
+ * Stop inspections, probes, and the change request watch, end every follower, and wait for pending work.
95
+ * @returns settles once pending inspections and probes have ended.
96
+ */
97
+ dispose(): Promise<void>;
98
+ private entries;
99
+ private worktree;
100
+ private publish;
101
+ /** Track `task` for disposal; the returned promise resolves once it settles, whatever the outcome. */
102
+ private run;
103
+ /**
104
+ * Inspect the checkout, one inspection at a time; calls during an
105
+ * inspection share one trailing rerun.
106
+ * @returns resolves once an inspection that started after the call has ended.
107
+ */
108
+ private inspect;
109
+ private inspectOnce;
110
+ /** The upstream branch with the first URL of its remote that a provider recognizes. */
111
+ private upstreamOf;
112
+ /** Bind the open change requests of the upstream branch, once per remote and branch until a refresh. */
113
+ private discover;
114
+ /** Decide whether the Session's sandbox lets the worktree service write the checkout and its shared Git directory. */
115
+ private blockerOf;
116
+ /** Measure the `branch` scope; a failed measurement only hides the local changes card. */
117
+ private localOf;
118
+ private recognize;
119
+ /** Probe sign-in on the repository's host; resolves once the probe has ended. */
120
+ private probe;
121
+ }
122
+ /**
123
+ * Decide whether a Session works inside the worktree it created while that
124
+ * worktree's directory is gone, and whether its branch still exists.
125
+ * @param ctx - context that provides `fs` and the process services.
126
+ * @param config - Git limits.
127
+ * @param session - Session to check.
128
+ * @param state - recorded worktree and restoration completion.
129
+ * @param directory - the Session's current directory.
130
+ * @param signal - cancellation of the check.
131
+ * @returns the unavailable worktree, or null for a valid checkout or a Session working elsewhere.
132
+ * @throws when the filesystem or Git cannot answer.
133
+ */
134
+ export declare function missingWorktree(ctx: Context, config: GitConfig, session: Session, state: ForgeWorktreeState, directory: string, signal: AbortSignal): Promise<ForgeMissingWorktree | null>;
135
+ //# sourceMappingURL=panel.d.ts.map
@@ -0,0 +1,57 @@
1
+ /** Parsers for the porcelain output of the read-only Git commands the panel runs. */
2
+ /** One remote with the URLs `git remote -v` prints for it. */
3
+ export interface GitRemote {
4
+ /** Remote name such as `origin`. */
5
+ readonly name: string;
6
+ /** Distinct URLs, fetch URL first. */
7
+ readonly urls: readonly string[];
8
+ }
9
+ /**
10
+ * Read the first line that `git rev-parse` prints for a directory query such as `--show-toplevel`.
11
+ * @param output - stdout of the command.
12
+ * @returns the directory.
13
+ * @throws when the output is empty.
14
+ */
15
+ export declare function parseTopLevel(output: string): string;
16
+ /**
17
+ * Read the first line of a one-name output such as `git symbolic-ref --short HEAD`.
18
+ * @param output - stdout of the command.
19
+ * @returns the name, or null when the command printed none.
20
+ */
21
+ export declare function parseName(output: string): string | null;
22
+ /**
23
+ * Order worktree base branches: the checked-out branch first, then the other
24
+ * listed branches in listed order.
25
+ * @param current - checked-out branch, or null when HEAD is detached.
26
+ * @param output - stdout of `git for-each-ref --format=%(refname:lstrip=2) refs/heads/`.
27
+ * @param limit - most names to return.
28
+ * @returns distinct branch names, at most `limit`.
29
+ */
30
+ export declare function baseBranches(current: string | null, output: string, limit: number): string[];
31
+ /**
32
+ * Group the lines of `git remote -v` by remote.
33
+ * @param output - stdout of the command.
34
+ * @returns remotes in first-listed order.
35
+ */
36
+ export declare function parseRemotes(output: string): GitRemote[];
37
+ /**
38
+ * Split an upstream branch such as `origin/feature/x` into its remote and the
39
+ * branch on that remote. The remote is the longest remote name followed by `/`
40
+ * at the start of the upstream branch.
41
+ * @param upstream - upstream branch such as `origin/main`, or null.
42
+ * @param remotes - remotes in listed order.
43
+ * @returns the remote and branch, or undefined without an upstream or a remote it starts with.
44
+ */
45
+ export declare function upstreamBranch(upstream: string | null, remotes: readonly GitRemote[]): {
46
+ readonly remote: GitRemote;
47
+ readonly branch: string;
48
+ } | undefined;
49
+ /**
50
+ * Order remotes for code host recognition: the upstream's remote first, then
51
+ * `origin`, then the rest in listed order.
52
+ * @param upstream - upstream branch such as `origin/main`, or null.
53
+ * @param remotes - remotes in listed order.
54
+ * @returns the same remotes in recognition order.
55
+ */
56
+ export declare function remoteOrder(upstream: string | null, remotes: readonly GitRemote[]): GitRemote[];
57
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Change request patches kept in memory, so the changes view reads no diff
3
+ * from the code host again while a change request keeps its head commit and base branch.
4
+ */
5
+ import type { ChangeRequestKey } from '@deepseek-ai/dsh-experimental-forge';
6
+ /**
7
+ * One patch per change request, bounded by the total UTF-8 size of the kept
8
+ * patches; the least recently read patch leaves first.
9
+ */
10
+ export declare class PatchCache {
11
+ private readonly maxBytes;
12
+ private readonly entries;
13
+ private bytes;
14
+ /** @param maxBytes - most UTF-8 bytes kept together; a larger patch is not kept. */
15
+ constructor(maxBytes: number);
16
+ /**
17
+ * Read the patch kept for a change request at a version, marking it the most recently read.
18
+ * @param key - the change request.
19
+ * @param version - head commit and base branch the reader needs.
20
+ * @returns the patch, or undefined when none is kept at that version.
21
+ */
22
+ get(key: ChangeRequestKey, version: string): string | undefined;
23
+ /**
24
+ * Keep a patch in place of the change request's earlier one, then drop the
25
+ * least recently read patches until the rest fit within `maxBytes`.
26
+ * @param key - the change request.
27
+ * @param version - head commit and base branch the patch was read at.
28
+ * @param patch - the patch.
29
+ */
30
+ set(key: ChangeRequestKey, version: string, patch: string): void;
31
+ private remove;
32
+ }
33
+ //# sourceMappingURL=patch-cache.d.ts.map
@@ -0,0 +1,89 @@
1
+ /**
2
+ * The last known state of every change request that a listed Session binds,
3
+ * for the Session list. One run starts with the first stream and stops with
4
+ * the last: it reads the stored states, lists the Sessions with their
5
+ * bindings, follows binding changes of loaded Sessions, and polls each bound
6
+ * change request, once however many Sessions bind it. The forge service
7
+ * owns polling cadence and terminal-state refresh. Every state change is stored, so a restart shows it before the
8
+ * first poll.
9
+ */
10
+ import { z } from 'zod';
11
+ import type { ChangeRequestListener, ChangeRequestRef } from '@deepseek-ai/dsh-experimental-forge/types';
12
+ import type { SessionId } from '@deepseek-ai/dsh-session/types';
13
+ import type { ForgeChangeRequestListState, ForgeChangeRequestStatesFrame } from './types.ts';
14
+ /** Stored states keyed by {@link storedKey}; derived data, so a record that fails its schema is set aside. */
15
+ export declare const changeRequestStatesDomain: {
16
+ name: string;
17
+ version: number;
18
+ layout: "per-record";
19
+ invalidRecords: "backup-and-skip";
20
+ tables: {
21
+ states: {
22
+ valueSchema: z.ZodType<ForgeChangeRequestListState, unknown, z.core.$ZodTypeInternals<ForgeChangeRequestListState, unknown>>;
23
+ };
24
+ };
25
+ };
26
+ /**
27
+ * The storage key of a change request's state: a path-safe digest of its URL.
28
+ * @param url - the change request's web URL.
29
+ * @returns the key.
30
+ */
31
+ export declare function storedKey(url: string): string;
32
+ /** The stored states the run reads and writes. */
33
+ export interface StoredStates {
34
+ /** The state stored under a key. */
35
+ get(key: string): ForgeChangeRequestListState | undefined;
36
+ /** Every stored state. */
37
+ entries(): IterableIterator<[string, ForgeChangeRequestListState]>;
38
+ /** Store a state durably. */
39
+ put(key: string, value: ForgeChangeRequestListState): Promise<void>;
40
+ /** Remove a stored state durably. */
41
+ delete(key: string): Promise<boolean>;
42
+ }
43
+ /** One listed Session and the URLs of its visible bindings, undefined when they are not known without loading it. */
44
+ export interface ListedSession {
45
+ readonly id: SessionId;
46
+ readonly urls: readonly string[] | undefined;
47
+ }
48
+ /** What a run reads, follows, and polls. */
49
+ export interface ChangeRequestStateSources {
50
+ /** List every Session with its visible bindings. */
51
+ readonly sessions: (signal: AbortSignal) => Promise<readonly ListedSession[]>;
52
+ /** Follow the visible bindings of loaded Sessions; returns the disposer. */
53
+ readonly onBindings: (listener: (id: SessionId, urls: readonly string[]) => void) => () => void;
54
+ /** The change request a URL names, or undefined when no provider recognizes it. */
55
+ readonly refOf: (url: string) => ChangeRequestRef | undefined;
56
+ /** Poll a change request until the returned disposer runs. */
57
+ readonly watch: (ref: ChangeRequestRef, listener: ChangeRequestListener) => () => void;
58
+ /** Open the stored states. */
59
+ readonly open: () => Promise<StoredStates>;
60
+ /** Report a failed durable write; the state stays in memory. */
61
+ readonly report: (error: unknown) => void;
62
+ }
63
+ /** Streams the states of the change requests that listed Sessions bind. */
64
+ export declare class ChangeRequestStates {
65
+ private readonly sources;
66
+ private readonly readers;
67
+ private stopping;
68
+ private disposed;
69
+ private run;
70
+ /** @param sources - what runs read, follow, and poll. */
71
+ constructor(sources: ChangeRequestStateSources);
72
+ /**
73
+ * Stream the known states the reader may see first, then each state that
74
+ * changes or becomes visible to it. The stream ends when `signal` aborts or
75
+ * the hub is disposed.
76
+ * @param allowed - whether the reader may read a Session.
77
+ * @param signal - ends the stream.
78
+ * @returns frames in publication order.
79
+ */
80
+ stream(allowed: (id: SessionId) => boolean, signal: AbortSignal): AsyncIterable<ForgeChangeRequestStatesFrame>;
81
+ /**
82
+ * End every stream, stop polling, and wait for initialization and accepted storage writes.
83
+ * @returns settles after all owned work stops; subsequent streams end without starting work.
84
+ */
85
+ dispose(): Promise<void>;
86
+ private ensureRun;
87
+ private stopRun;
88
+ }
89
+ //# sourceMappingURL=states.d.ts.map