@sidequest-007/dsh-atlas 1.0.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.
Files changed (58) hide show
  1. package/CHANGELOG.md +269 -0
  2. package/CONTRIBUTING.md +50 -0
  3. package/LICENSE +21 -0
  4. package/LICENSE-ORIGINAL +21 -0
  5. package/NOTICE +29 -0
  6. package/README.md +297 -0
  7. package/README.zh.md +289 -0
  8. package/assets/diagrams/atlas-overview.svg +53 -0
  9. package/assets/diagrams/atlas-seam.svg +32 -0
  10. package/assets/screenshots/file-mention-composer.png +0 -0
  11. package/assets/screenshots/file-mention-settings.png +0 -0
  12. package/assets/screenshots/menu-mixed.png +0 -0
  13. package/cordis.patch.yml +14 -0
  14. package/dsh.plugin.json +12 -0
  15. package/lib/client.js +20615 -0
  16. package/lib/index.js +17458 -0
  17. package/lib/invariant.js +13 -0
  18. package/lib/types/abort.d.ts +22 -0
  19. package/lib/types/atlas.d.ts +181 -0
  20. package/lib/types/client/DraftLinks.d.ts +21 -0
  21. package/lib/types/client/FilesDock.d.ts +75 -0
  22. package/lib/types/client/FolderPicker.d.ts +66 -0
  23. package/lib/types/client/FolderTab.d.ts +50 -0
  24. package/lib/types/client/MentionNavigator.d.ts +96 -0
  25. package/lib/types/client/MenuIcons.d.ts +16 -0
  26. package/lib/types/client/ReferenceLinks.d.ts +85 -0
  27. package/lib/types/client/SettingsSection.d.ts +31 -0
  28. package/lib/types/client/draft-links.d.ts +205 -0
  29. package/lib/types/client/draft-scope.d.ts +22 -0
  30. package/lib/types/client/git-provider.d.ts +45 -0
  31. package/lib/types/client/icons.d.ts +48 -0
  32. package/lib/types/client/index.d.ts +8 -0
  33. package/lib/types/client/locales.d.ts +267 -0
  34. package/lib/types/client/model.d.ts +38 -0
  35. package/lib/types/client/reference-links.d.ts +100 -0
  36. package/lib/types/client/remote.d.ts +54 -0
  37. package/lib/types/client/search.d.ts +9 -0
  38. package/lib/types/client/source.d.ts +325 -0
  39. package/lib/types/client/styles.d.ts +15 -0
  40. package/lib/types/contract.d.ts +512 -0
  41. package/lib/types/defaults.d.ts +115 -0
  42. package/lib/types/external.d.ts +58 -0
  43. package/lib/types/files.d.ts +76 -0
  44. package/lib/types/git.d.ts +44 -0
  45. package/lib/types/index.d.ts +88 -0
  46. package/lib/types/invariant.d.ts +15 -0
  47. package/lib/types/mention.d.ts +80 -0
  48. package/lib/types/paste.d.ts +13 -0
  49. package/lib/types/reference.d.ts +16 -0
  50. package/lib/types/references.d.ts +126 -0
  51. package/lib/types/runtime-info.d.ts +30 -0
  52. package/lib/types/runtime.d.ts +180 -0
  53. package/lib/types/settings.d.ts +25 -0
  54. package/lib/types/tokens.d.ts +35 -0
  55. package/lib/types/tools.d.ts +94 -0
  56. package/lib/types/typert.d.ts +13 -0
  57. package/lib/types/types.d.ts +12 -0
  58. package/package.json +208 -0
@@ -0,0 +1,31 @@
1
+ /** Settings section for global and workspace-specific file filter rules. */
2
+ import type { PropsLocale, PropsRuntime, InjectFace } from '@deepseek-ai/dsh-client-ui-slots';
3
+ import type { FileIgnoreRuleInput, FolderOpenTarget } from '../contract.ts';
4
+ import type { AtFileSettingsSource } from './FilesDock.tsx';
5
+ export type AtFileFilterScope = 'global' | 'workspace';
6
+ /** Ephemeral settings navigation retained while the plugin stays mounted. */
7
+ export interface AtFileSectionViewState {
8
+ filterScope: AtFileFilterScope;
9
+ selectedWorkspace: string;
10
+ }
11
+ /** Injected business face: the live scope, retained view, and durable write verbs. */
12
+ export interface AtFileSectionInjected {
13
+ hooks: {
14
+ scope: AtFileSettingsSource;
15
+ };
16
+ viewState: AtFileSectionViewState;
17
+ setEnabled: (enabled: boolean) => Promise<void>;
18
+ setEnableSkills: (enableSkills: boolean) => Promise<void>;
19
+ setEnableChats: (enableChats: boolean) => Promise<void>;
20
+ setEnablePlugins: (enablePlugins: boolean) => Promise<void>;
21
+ setIgnorePastedMentions: (ignore: boolean) => Promise<void>;
22
+ setFolderOpen: (target: FolderOpenTarget) => Promise<void>;
23
+ setIgnoreFiles: (ignoreFiles: readonly FileIgnoreRuleInput[]) => Promise<void>;
24
+ setWorkspaceIgnoreFiles: (workspace: string, ignoreFiles: readonly FileIgnoreRuleInput[]) => Promise<void>;
25
+ }
26
+ /** Full section props: runtime share + injected face + locale seat. */
27
+ export type AtFileSectionProps = PropsRuntime<'settings.section'> & InjectFace<AtFileSectionInjected> & PropsLocale<'atlas'>;
28
+ /** Trim one legacy exact basename; retained for callers using the old helper. */
29
+ export declare function parseIgnoreFile(value: string): string | undefined;
30
+ /** Render the enable switch and scoped file-filter manager. */
31
+ export declare function AtFileSection({ useScope, useSessions, useWorkspaces, viewState, setEnabled, setEnableSkills, setEnableChats, setEnablePlugins, setIgnorePastedMentions, setFolderOpen, setIgnoreFiles, setWorkspaceIgnoreFiles, t, }: AtFileSectionProps): import("react").JSX.Element;
@@ -0,0 +1,205 @@
1
+ import { type ReferenceLink } from './reference-links.ts';
2
+ import type { ReferenceOutcome } from './ReferenceLinks.tsx';
3
+ /** The attribute Lexical puts on the composer's contenteditable root. */
4
+ export declare const EDITOR_SELECTOR = "[data-lexical-editor=\"true\"]";
5
+ /** The attribute the framework puts on a text node it decorated as a reference. */
6
+ export declare const TEXT_REF_SELECTOR = "[data-composer-text-ref]";
7
+ /** The highlight name every draft link is painted under. */
8
+ export declare const DRAFT_HIGHLIGHT = "dsh-atlas-draft-ref";
9
+ /** The highlight name a reference whose target is gone is painted under. */
10
+ export declare const MISSING_HIGHLIGHT = "dsh-atlas-draft-missing";
11
+ /** The action one click on a draft reference performs. */
12
+ export type DraftAction = () => ReferenceOutcome | Promise<ReferenceOutcome>;
13
+ /** One token the plugin can act on, decoded. */
14
+ export interface DraftActivation {
15
+ readonly link: ReferenceLink;
16
+ readonly run: DraftAction;
17
+ }
18
+ /**
19
+ * The block child of the editor root that holds `node`.
20
+ *
21
+ * Lexical draws one block element per line, so this is the line a caret belongs
22
+ * to; offsets are then counted inside that one line, never across the whole
23
+ * draft (which is what keeps the mapping exact without knowing how the editor
24
+ * spells its line breaks).
25
+ * @param root - one editor root.
26
+ * @param node - a node inside it.
27
+ * @returns the block, or undefined when the node is not inside this root.
28
+ */
29
+ export declare function blockOf(root: Element, node: Node): Element | undefined;
30
+ /** One line's text plus the offset each of its text nodes starts at. */
31
+ export interface LineIndex {
32
+ readonly text: string;
33
+ readonly nodes: readonly {
34
+ readonly node: Text;
35
+ readonly start: number;
36
+ }[];
37
+ }
38
+ /** Index one line so a character offset and a text node convert into each other. */
39
+ export declare function indexLine(block: Element): LineIndex;
40
+ /**
41
+ * The DOM point of one character offset inside an indexed line.
42
+ * @param index - the indexed line.
43
+ * @param offset - a character offset in its text.
44
+ * @returns the text node and offset to build a Range from, or undefined past the end.
45
+ */
46
+ export declare function pointAt(index: LineIndex, offset: number): {
47
+ readonly node: Text;
48
+ readonly offset: number;
49
+ } | undefined;
50
+ /** One `@` token's span inside a line's text. */
51
+ export interface TokenRun {
52
+ readonly token: string;
53
+ readonly start: number;
54
+ readonly end: number;
55
+ }
56
+ /**
57
+ * The `@` token run that covers one character offset of a line.
58
+ *
59
+ * The run is bounded by whitespace and by a second `@` (the grammar is `@` plus
60
+ * a run of non-whitespace, non-`@` characters), so a click anywhere inside a
61
+ * token — including its undecorated tail — resolves to the same whole token.
62
+ * @param text - one line's text.
63
+ * @param offset - the character offset the caret sits at.
64
+ * @returns the token and its span, or undefined when no `@` governs that offset.
65
+ */
66
+ export declare function tokenRunAt(text: string, offset: number): TokenRun | undefined;
67
+ /** One reference token under a caret position. */
68
+ export interface InlineToken extends TokenRun {
69
+ readonly line: Element;
70
+ readonly index: LineIndex;
71
+ /** Where the caret sits inside the line's text. */
72
+ readonly local: number;
73
+ /** Whether the user has finished typing the token (see {@link DraftToken}). */
74
+ readonly settled: boolean;
75
+ /**
76
+ * The offset at which the framework's own colouring stops, when it drew the
77
+ * token's head at all. Only used by a browser that cannot paint a range: there
78
+ * the framework's colour is the only "this is a link" the user can see.
79
+ */
80
+ readonly decoratedEnd?: number;
81
+ }
82
+ /**
83
+ * The reference token a caret position in the composer resolves to.
84
+ *
85
+ * The token is read from the line's text, not from the framework's decoration:
86
+ * a hand-typed token the editor never recognised is the same reference as one it
87
+ * did, and the caller decides what may be offered (see {@link draftActivation}).
88
+ * @param root - one editor root.
89
+ * @param node - the caret's container node.
90
+ * @param offset - the caret's offset inside that node.
91
+ * @returns the token, or undefined when no `@` token covers the point.
92
+ */
93
+ export declare function tokenAtPoint(root: Element, node: Node, offset: number): InlineToken | undefined;
94
+ /** One `@` token of the composer, with the line it lives in. */
95
+ export interface DraftToken extends TokenRun {
96
+ readonly line: Element;
97
+ readonly index: LineIndex;
98
+ /**
99
+ * Whether the user has finished typing this token: a whitespace character
100
+ * follows it, or its line is followed by another line (Enter). A token that
101
+ * ends the draft is still being written, and every prefix of a real path is a
102
+ * path the Host has never heard of — judging one would strike it through
103
+ * halfway through typing it.
104
+ */
105
+ readonly settled: boolean;
106
+ }
107
+ /**
108
+ * Every `@` token the composer currently shows, in document order.
109
+ *
110
+ * The tokens are read per line, so the mapping from a token to a DOM range needs
111
+ * no knowledge of how the editor spells its line breaks.
112
+ * @returns the tokens, with the offsets they occupy in their line.
113
+ */
114
+ export declare function draftTokens(): readonly DraftToken[];
115
+ /**
116
+ * The action one draft token offers, or undefined when it offers none.
117
+ *
118
+ * This is the plugin's own definition of a draft link, and it deliberately does
119
+ * NOT consult the framework's decoration: a hand-typed `@AGENTS.md` names the
120
+ * same reference whether or not the editor happened to recognise the name.
121
+ *
122
+ * A file or folder token is offered only while the Host CONFIRMS its target: the
123
+ * dock above the composer already inspects exactly those tokens and marks a
124
+ * vanished one `已失效`, so an unknown verdict means "not yet" rather than "yes" —
125
+ * a link drawn before the answer arrives would have to be taken back a moment
126
+ * later, and a link that opens nothing must never be handed to the pointer. A
127
+ * provider or skill token has no such verdict: whether it is openable is its
128
+ * owner's answer, asked through `actionFor`.
129
+ * @param token - one draft token, `@` included.
130
+ * @param actionFor - the session's action lookup.
131
+ * @param verdict - the dock's last inspection verdict for one referenced path.
132
+ * @returns the action, or undefined when there is nothing to open.
133
+ */
134
+ export declare function draftActivation(token: string, actionFor: (link: ReferenceLink) => DraftAction | undefined, verdict: DraftVerdictLookup): DraftActivation | undefined;
135
+ /** The Host's inspection verdict for one referenced path. */
136
+ export interface DraftVerdict {
137
+ /** Whether the target exists right now. */
138
+ readonly exists: boolean;
139
+ /** The target's kind, when the Host reported one. */
140
+ readonly kind?: 'file' | 'dir';
141
+ }
142
+ /** Look one referenced path up among the dock's verdicts. */
143
+ export type DraftVerdictLookup = (path: string) => DraftVerdict | undefined;
144
+ /**
145
+ * Whether one draft token is a reference whose target the Host reports as gone.
146
+ *
147
+ * This is the dock's own `已失效` state, said in the composer: the token names a
148
+ * file or a folder, the inspection answered, and the answer was no. It is NOT
149
+ * the same as an unanswered inspection (nothing is claimed then) and not the
150
+ * same as a token that decodes into no reference at all (`@plugin:x` is a label,
151
+ * not a path) — neither of those is a claim the plugin can make about a file.
152
+ * @param token - one draft token, `@` included.
153
+ * @param verdict - the dock's last inspection verdict for one referenced path.
154
+ * @returns true when the token names a target that is gone.
155
+ */
156
+ export declare function draftMissing(token: string, verdict: DraftVerdictLookup): boolean;
157
+ /**
158
+ * Decode one draft token into the reference it names.
159
+ *
160
+ * {@link decodeDraftReference} owns the vocabulary. A file token may still carry
161
+ * the line-range spelling (`@src/view.ts:12-40`), which that decoder accepts as
162
+ * a path because its colon is not in the first segment; the range is a reading
163
+ * instruction rather than part of the path, so it is dropped here exactly as the
164
+ * dock's rows drop it. A handle spelling (`@file:12-40`) is refused by the
165
+ * decoder itself, and stays refused.
166
+ * @param token - one draft token, `@` included.
167
+ * @returns the reference, or undefined when the token names nothing openable.
168
+ */
169
+ export declare function draftLink(token: string): ReferenceLink | undefined;
170
+ /** Whether this browser can colour text ranges without touching the editor's DOM. */
171
+ export declare function canPaintTails(): boolean;
172
+ /** How one draft token should be drawn: an openable link, or a stale reference. */
173
+ export type DraftPaint = 'link' | 'missing';
174
+ /** How many tokens of each kind the last {@link paintDraftLinks} pass drew. */
175
+ export interface DraftPaintCount {
176
+ readonly link: number;
177
+ readonly missing: number;
178
+ }
179
+ /**
180
+ * Paint every draft token `decide` classifies.
181
+ *
182
+ * The whole token is painted, not just the part the framework happened to
183
+ * colour: a link that opens on a click must look like a link along its entire
184
+ * length, and the framework's own colour (when it drew one) is the same design
185
+ * token, so nothing shifts for a token it did recognise. A token whose target is
186
+ * gone is painted the other way — stale, the dock's own language — so a
187
+ * reference that cannot open is visibly a reference rather than ordinary prose.
188
+ * The API paints ranges over the existing text, so the editor's node structure
189
+ * is untouched.
190
+ * @param decide - classifies one token; it receives the token with its line and
191
+ * its `settled` flag, because a token still being typed must not be judged.
192
+ * @returns how many tokens of each kind were painted.
193
+ */
194
+ export declare function paintDraftLinks(decide: (token: DraftToken) => DraftPaint | undefined): DraftPaintCount;
195
+ /**
196
+ * Show or clear the link pointer on one composer.
197
+ *
198
+ * The cursor cannot be part of a highlight — it is a property of the element
199
+ * under the pointer, and the undecorated tail shares its element with whatever
200
+ * prose follows — so the bridge hit-tests the pointer and publishes the answer
201
+ * on the editor root.
202
+ * @param root - one editor root.
203
+ * @param hot - whether the pointer is over an openable reference token.
204
+ */
205
+ export declare function setEditorCursor(root: Element, hot: boolean): void;
@@ -0,0 +1,22 @@
1
+ /** What {@link draftScopeOf} cannot read for itself. */
2
+ export interface ScopeProbe {
3
+ /**
4
+ * Whether the Host's own verdict calls this path a directory. A path token
5
+ * without a trailing separator is a file by syntax (`@e:/work/docs`), and only the
6
+ * Host knows it is the folder the user meant.
7
+ * @param path - the token's decoded path.
8
+ * @returns true when the Host says `dir`.
9
+ */
10
+ isFolder(path: string): Promise<boolean>;
11
+ }
12
+ /**
13
+ * The folder path a draft is scoped by, or undefined when it names none.
14
+ *
15
+ * Tokens are scanned back to front, so the reference nearest the active token
16
+ * wins; the active token itself names no folder (a category handle like `file:`
17
+ * decodes to nothing, which is what keeps `@file:Ea` from scoping itself).
18
+ * @param tokens - the composer's `@` tokens in document order, trigger included.
19
+ * @param probe - the Host verdict lookup for plain path tokens.
20
+ * @returns the scoping folder path, or undefined.
21
+ */
22
+ export declare function draftScopeOf(tokens: readonly string[], probe: ScopeProbe): Promise<string | undefined>;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The built-in `@git` provider's menu half — and the seam's worked example of a
3
+ * browser-side provider that reads Host data.
4
+ *
5
+ * A provider's `list` runs in the browser, where there is no repository to read,
6
+ * so this half asks the Host through the `atlas/gitChanges` endpoint. That is
7
+ * the intended shape for any provider whose data is not already in the page: the
8
+ * wire call belongs to the provider, not to the menu.
9
+ *
10
+ * Nothing here is cached: the menu may re-ask on every keystroke, and a provider
11
+ * that wants a cache owns it.
12
+ */
13
+ import type { AtlasCallContext, AtlasItem, AtlasOpenOutcome, AtlasProvider } from '../atlas.ts';
14
+ import { type GitChange } from '../contract.ts';
15
+ /** Beyond this the change list stops being a menu and starts being a file dump. */
16
+ export declare const GIT_ITEM_LIMIT = 50;
17
+ /**
18
+ * One changed path as a menu row.
19
+ * @param change - the change from the Host.
20
+ * @returns the item the seam will hand back to `resolve` verbatim.
21
+ */
22
+ export declare function gitChangeItem(change: GitChange): AtlasItem;
23
+ /** How this half reaches the Host's repository state and the user's viewer. */
24
+ export interface GitMenuDeps {
25
+ /**
26
+ * Ask the Host for the workspace's changed paths.
27
+ * @param sessionId - the answered session (the Host resolves its workspace).
28
+ * @param signal - caller lifetime; superseded per keystroke.
29
+ */
30
+ changes(sessionId: AtlasCallContext['sessionId'], signal: AbortSignal): Promise<readonly GitChange[]>;
31
+ /**
32
+ * Open one changed path for the user — the click action of a committed
33
+ * `@atlas:git/<path>` mention in an already sent message.
34
+ * @param sessionId - the session the mention was clicked in.
35
+ * @param path - the workspace-relative path, as git reported it.
36
+ * @returns `'gone'` when the path is no longer there, so the chip reads stale.
37
+ */
38
+ open(sessionId: AtlasCallContext['sessionId'], path: string): AtlasOpenOutcome | void | Promise<AtlasOpenOutcome | void>;
39
+ }
40
+ /**
41
+ * Build the built-in `@git` menu provider.
42
+ * @param deps - the Host bridge for the candidate list and the viewer bridge.
43
+ * @returns the declaration the browser half registers.
44
+ */
45
+ export declare function createGitMenuProvider(deps: GitMenuDeps): AtlasProvider;
@@ -0,0 +1,48 @@
1
+ /** Tabler-based vector icons (single icon library) with per-kind semantic colors. */
2
+ import type { ReactElement } from 'react';
3
+ import type { FileEntry } from './remote.ts';
4
+ export type FileIconKind = 'folder' | 'code' | 'text' | 'pdf' | 'image' | 'data' | 'archive' | 'file';
5
+ /** Classify one indexed path without reading it. */
6
+ export declare function fileIconKind(file: Pick<FileEntry, 'kind' | 'relative'>): FileIconKind;
7
+ /**
8
+ * One file-kind icon rendered at menu size. The wrapper span keeps the stable
9
+ * `data-file-icon` marker for classification consumers and tests.
10
+ */
11
+ export declare function fileIcon(file: Pick<FileEntry, 'kind' | 'relative'>): ReactElement;
12
+ /** Mention kinds that carry their own accent icon. */
13
+ export type MentionIconKind = 'file' | 'folder' | 'skill' | 'chat' | 'plugin' | 'back';
14
+ /** One category/dock icon with its semantic accent color (sparse glyphs compensated). */
15
+ export declare function mentionIcon(kind: MentionIconKind): ReactElement;
16
+ /**
17
+ * A leaf-row icon for result rows (skills/chats/plugins), replacing the empty
18
+ * indentation slot. Sizes match the category menu icons (skill 36px, others 28px)
19
+ * so the same kind reads identically everywhere.
20
+ */
21
+ export declare function leafIcon(kind: 'skill' | 'chat' | 'plugin'): ReactElement;
22
+ /**
23
+ * The framework kind that RESERVES an icon box on one of our menu rows.
24
+ *
25
+ * The framework's row renders an icon only when the candidate carries one, and
26
+ * it can only draw `session`, `file` and `folder`. So a row of ours always
27
+ * carries one of those three: not for the glyph (which `MenuIcons` draws itself
28
+ * over it), but for the BOX — a fixed 16 px slot that indents every name by the
29
+ * same amount, which is what makes the column line up.
30
+ * @param kind - the row's kind in this plugin's vocabulary.
31
+ * @returns the framework kind to declare.
32
+ */
33
+ export declare function menuIconKind(kind: MentionIconKind): 'file' | 'folder' | 'session';
34
+ /** The row facts one menu glyph is chosen from. */
35
+ export interface MenuGlyphRow {
36
+ readonly mentionKind: string;
37
+ readonly value?: string;
38
+ readonly atFileKind?: 'file' | 'dir';
39
+ readonly providerId?: string;
40
+ }
41
+ /**
42
+ * The colour one menu row's glyph is drawn in.
43
+ * @param row - the candidate row.
44
+ * @returns the accent for a category row (its prefix, else its provider id), or
45
+ * undefined for a row that carries data, which keeps the neutral glyph colour.
46
+ */
47
+ export declare function menuGlyphColor(row: MenuGlyphRow): string | undefined;
48
+ export declare function menuGlyph(row: MenuGlyphRow, size?: number): ReactElement;
@@ -0,0 +1,8 @@
1
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
2
+ /** Required services: picker pipeline, session projection, carrier, Remote face, slots, and locale. */
3
+ export declare const inject: string[];
4
+ /**
5
+ * Compose the @ mention surface.
6
+ * @param ctx - client root context.
7
+ */
8
+ export declare function apply(ctx: ClientContext): void;
@@ -0,0 +1,267 @@
1
+ /**
2
+ * `atlas` locale namespace: reference dock, category menu, and settings copy.
3
+ * Chinese is the product copy; English mirrors it.
4
+ */
5
+ /** Simplified Chinese dictionary (the key-set source of truth). */
6
+ export declare const zh: {
7
+ 'dock.aria': string;
8
+ 'dock.remove': string;
9
+ 'dock.missing': string;
10
+ 'dock.missingTitle': string;
11
+ 'dock.cost': string;
12
+ 'dock.costWarn': string;
13
+ nav: string;
14
+ 'cat.file': string;
15
+ 'cat.folder': string;
16
+ 'cat.skill': string;
17
+ 'cat.chat': string;
18
+ 'cat.plugin': string;
19
+ 'cat.tag.chat': string;
20
+ 'hint.complete': string;
21
+ 'nav.back': string;
22
+ 'group.expand': string;
23
+ 'group.collapse': string;
24
+ 'plugin.scope.other': string;
25
+ 'section.recent': string;
26
+ 'section.usage': string;
27
+ 'section.relevance': string;
28
+ 'folder.outside': string;
29
+ 'settings.folderOpen': string;
30
+ 'settings.folderOpenDesc': string;
31
+ 'settings.folderOpen.both': string;
32
+ 'settings.folderOpen.sidebar': string;
33
+ 'settings.folderOpen.native': string;
34
+ 'time.now': string;
35
+ 'time.minutes': string;
36
+ 'time.hours': string;
37
+ 'time.days': string;
38
+ 'time.months': string;
39
+ 'time.years': string;
40
+ 'group.ungrouped': string;
41
+ 'tier.system': string;
42
+ 'tier.user': string;
43
+ 'tier.project': string;
44
+ 'tier.custom': string;
45
+ 'tier.plugin': string;
46
+ 'settings.title': string;
47
+ 'settings.subtitle': string;
48
+ 'settings.enabled': string;
49
+ 'settings.enabledDesc': string;
50
+ 'settings.enableSkills': string;
51
+ 'settings.enableSkillsDesc': string;
52
+ 'settings.enableChats': string;
53
+ 'settings.enableChatsDesc': string;
54
+ 'settings.enablePlugins': string;
55
+ 'settings.enablePluginsDesc': string;
56
+ 'settings.ignorePastedMentions': string;
57
+ 'settings.ignorePastedMentionsDesc': string;
58
+ 'settings.ignoreFiles': string;
59
+ 'settings.ignoreFilesDesc': string;
60
+ 'settings.scope': string;
61
+ 'settings.global': string;
62
+ 'settings.workspace': string;
63
+ 'settings.globalTitle': string;
64
+ 'settings.globalDesc': string;
65
+ 'settings.workspaceTitle': string;
66
+ 'settings.workspaceDesc': string;
67
+ 'settings.workspaceSelect': string;
68
+ 'settings.noWorkspace': string;
69
+ 'settings.restoreDefaults': string;
70
+ 'settings.clearWorkspace': string;
71
+ 'settings.emptyGlobal': string;
72
+ 'settings.emptyWorkspace': string;
73
+ 'settings.namePlaceholder': string;
74
+ 'settings.regexPlaceholder': string;
75
+ 'settings.nameHint': string;
76
+ 'settings.regexHint': string;
77
+ 'settings.invalidName': string;
78
+ 'settings.invalidRegex': string;
79
+ 'settings.duplicateName': string;
80
+ 'settings.inheritedName': string;
81
+ 'settings.add': string;
82
+ 'settings.saving': string;
83
+ 'settings.remove': string;
84
+ 'settings.inherited': string;
85
+ 'settings.ruleType': string;
86
+ 'settings.kind.exact': string;
87
+ 'settings.kind.regex': string;
88
+ 'settings.caseSensitive': string;
89
+ 'settings.caseInsensitive': string;
90
+ 'settings.caseSensitiveOption': string;
91
+ 'folder.title': string;
92
+ 'folder.aria': string;
93
+ 'folder.drives': string;
94
+ 'folder.up': string;
95
+ 'folder.system': string;
96
+ 'folder.loading': string;
97
+ 'folder.empty': string;
98
+ 'folder.truncated': string;
99
+ 'folder.error.outside': string;
100
+ 'folder.error.missing': string;
101
+ 'folder.error.notDirectory': string;
102
+ 'folder.choose': string;
103
+ 'folder.chooseHint': string;
104
+ 'folder.outsideGroup': string;
105
+ 'folder.workspaceGroup': string;
106
+ 'folder.pathGroup': string;
107
+ 'file.scopeGroup': string;
108
+ 'folder.drive': string;
109
+ 'folder.error.unavailable': string;
110
+ 'picker.title': string;
111
+ 'picker.path': string;
112
+ 'picker.go': string;
113
+ 'picker.editPath': string;
114
+ 'picker.crumbs': string;
115
+ 'picker.home': string;
116
+ 'picker.list': string;
117
+ 'picker.loading': string;
118
+ 'picker.empty': string;
119
+ 'picker.truncated': string;
120
+ 'picker.newFolder': string;
121
+ 'picker.folderName': string;
122
+ 'picker.create': string;
123
+ 'picker.showHidden': string;
124
+ 'picker.cancel': string;
125
+ 'picker.open': string;
126
+ 'picker.error': string;
127
+ };
128
+ /** The `at-file` namespace key union. */
129
+ export type AtFileKey = keyof typeof zh;
130
+ /** English dictionary, checked complete against the zh key set. */
131
+ export declare const en: {
132
+ 'dock.aria': string;
133
+ 'dock.remove': string;
134
+ 'dock.missing': string;
135
+ 'dock.missingTitle': string;
136
+ 'dock.cost': string;
137
+ 'dock.costWarn': string;
138
+ nav: string;
139
+ 'cat.file': string;
140
+ 'cat.folder': string;
141
+ 'cat.skill': string;
142
+ 'cat.chat': string;
143
+ 'cat.plugin': string;
144
+ 'cat.tag.chat': string;
145
+ 'hint.complete': string;
146
+ 'nav.back': string;
147
+ 'group.expand': string;
148
+ 'group.collapse': string;
149
+ 'plugin.scope.other': string;
150
+ 'section.recent': string;
151
+ 'section.usage': string;
152
+ 'section.relevance': string;
153
+ 'settings.folderOpen': string;
154
+ 'settings.folderOpenDesc': string;
155
+ 'settings.folderOpen.both': string;
156
+ 'settings.folderOpen.sidebar': string;
157
+ 'settings.folderOpen.native': string;
158
+ 'folder.outside': string;
159
+ 'time.now': string;
160
+ 'time.minutes': string;
161
+ 'time.hours': string;
162
+ 'time.days': string;
163
+ 'time.months': string;
164
+ 'time.years': string;
165
+ 'group.ungrouped': string;
166
+ 'tier.system': string;
167
+ 'tier.user': string;
168
+ 'tier.project': string;
169
+ 'tier.custom': string;
170
+ 'tier.plugin': string;
171
+ 'settings.title': string;
172
+ 'settings.subtitle': string;
173
+ 'settings.enabled': string;
174
+ 'settings.enabledDesc': string;
175
+ 'settings.enableSkills': string;
176
+ 'settings.enableSkillsDesc': string;
177
+ 'settings.enableChats': string;
178
+ 'settings.enableChatsDesc': string;
179
+ 'settings.enablePlugins': string;
180
+ 'settings.enablePluginsDesc': string;
181
+ 'settings.ignorePastedMentions': string;
182
+ 'settings.ignorePastedMentionsDesc': string;
183
+ 'settings.ignoreFiles': string;
184
+ 'settings.ignoreFilesDesc': string;
185
+ 'settings.scope': string;
186
+ 'settings.global': string;
187
+ 'settings.workspace': string;
188
+ 'settings.globalTitle': string;
189
+ 'settings.globalDesc': string;
190
+ 'settings.workspaceTitle': string;
191
+ 'settings.workspaceDesc': string;
192
+ 'settings.workspaceSelect': string;
193
+ 'settings.noWorkspace': string;
194
+ 'settings.restoreDefaults': string;
195
+ 'settings.clearWorkspace': string;
196
+ 'settings.emptyGlobal': string;
197
+ 'settings.emptyWorkspace': string;
198
+ 'settings.namePlaceholder': string;
199
+ 'settings.regexPlaceholder': string;
200
+ 'settings.nameHint': string;
201
+ 'settings.regexHint': string;
202
+ 'settings.invalidName': string;
203
+ 'settings.invalidRegex': string;
204
+ 'settings.duplicateName': string;
205
+ 'settings.inheritedName': string;
206
+ 'settings.add': string;
207
+ 'settings.saving': string;
208
+ 'settings.remove': string;
209
+ 'settings.inherited': string;
210
+ 'settings.ruleType': string;
211
+ 'settings.kind.exact': string;
212
+ 'settings.kind.regex': string;
213
+ 'settings.caseSensitive': string;
214
+ 'settings.caseInsensitive': string;
215
+ 'settings.caseSensitiveOption': string;
216
+ 'folder.title': string;
217
+ 'folder.aria': string;
218
+ 'folder.drives': string;
219
+ 'folder.up': string;
220
+ 'folder.system': string;
221
+ 'folder.loading': string;
222
+ 'folder.empty': string;
223
+ 'folder.truncated': string;
224
+ 'folder.error.outside': string;
225
+ 'folder.error.missing': string;
226
+ 'folder.error.notDirectory': string;
227
+ 'folder.choose': string;
228
+ 'folder.chooseHint': string;
229
+ 'folder.outsideGroup': string;
230
+ 'folder.workspaceGroup': string;
231
+ 'folder.pathGroup': string;
232
+ 'file.scopeGroup': string;
233
+ 'folder.drive': string;
234
+ 'folder.error.unavailable': string;
235
+ 'picker.title': string;
236
+ 'picker.path': string;
237
+ 'picker.go': string;
238
+ 'picker.editPath': string;
239
+ 'picker.crumbs': string;
240
+ 'picker.home': string;
241
+ 'picker.list': string;
242
+ 'picker.loading': string;
243
+ 'picker.empty': string;
244
+ 'picker.truncated': string;
245
+ 'picker.newFolder': string;
246
+ 'picker.folderName': string;
247
+ 'picker.create': string;
248
+ 'picker.showHidden': string;
249
+ 'picker.cancel': string;
250
+ 'picker.open': string;
251
+ 'picker.error': string;
252
+ };
253
+ /** Locale namespace id registered under ctx.locale. */
254
+ export declare const NS = "atlas";
255
+ /**
256
+ * Fill one dictionary template's `{name}`-style placeholders.
257
+ * @param template - dictionary text.
258
+ * @param params - placeholder values; absent params replace nothing.
259
+ * @returns the filled text.
260
+ */
261
+ export declare function fmt(template: string, params?: Record<string, string>): string;
262
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
263
+ interface LocaleNamespaceMap {
264
+ /** The @file reference and settings copy. */
265
+ [NS]: AtFileKey;
266
+ }
267
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Pure display projections for the @file picker: the split of a relative path
3
+ * into basename + directory for the picker rows. The Host validates selected
4
+ * paths and adds existence-only reference markers at send time.
5
+ */
6
+ /** The directory prefix of a forward-slash relative path ('' for root-level files). */
7
+ export declare function dirnameOf(relative: string): string;
8
+ /** The basename of a forward-slash relative path. */
9
+ export declare function basenameOf(relative: string): string;
10
+ /**
11
+ * Derive the canonical workspace path from an absolute file path and its
12
+ * workspace-relative path (the index walk emits forward-slash relatives).
13
+ */
14
+ export declare function workspaceFromAbsolute(absolute: string, relative: string): string;
15
+ /**
16
+ * The canonical key one referenced path is looked up under.
17
+ *
18
+ * A verdict and the token it answers for do not always spell a path the same
19
+ * way: the Host answers an out-of-workspace path in its own canonical spelling
20
+ * (forward slashes) while the user typed the platform's (`@E:\…`), and a folder
21
+ * mention may carry a trailing separator the path itself has not. Every verdict
22
+ * map is keyed — and every lookup made — through this, so the answer is found
23
+ * whichever spelling the draft used.
24
+ * @param value - a referenced path in either separator spelling.
25
+ * @returns the key both sides agree on.
26
+ */
27
+ export declare function referenceKey(value: string): string;
28
+ /**
29
+ * One child path under one directory, safe at a drive root.
30
+ *
31
+ * A listing's `path` carries a trailing separator only when it IS a drive root
32
+ * (`E:/`), so a plain `${path}/${name}` would produce `E://name` there. Both the
33
+ * folder tab and the menu browser join paths through this.
34
+ * @param path - the listing's own canonical path.
35
+ * @param name - one entry name.
36
+ * @returns the child's canonical path.
37
+ */
38
+ export declare function childOf(path: string, name: string): string;