@bendyline/docblocks 1.1.2 → 2.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.
- package/README.md +76 -11
- package/dist/chunk-2D7Y4IR3.js +1293 -0
- package/dist/chunk-2D7Y4IR3.js.map +1 -0
- package/dist/chunk-5MYAICRE.js +957 -0
- package/dist/chunk-5MYAICRE.js.map +1 -0
- package/dist/chunk-75UUF6C4.js +802 -0
- package/dist/chunk-75UUF6C4.js.map +1 -0
- package/dist/chunk-AEHCVWU5.js +25 -0
- package/dist/chunk-AEHCVWU5.js.map +1 -0
- package/dist/chunk-AYZ4HN5M.js +20 -0
- package/dist/chunk-AYZ4HN5M.js.map +1 -0
- package/dist/chunk-EGNDADXB.js +111 -0
- package/dist/chunk-EGNDADXB.js.map +1 -0
- package/dist/chunk-EZKJZUNJ.js +13 -0
- package/dist/chunk-EZKJZUNJ.js.map +1 -0
- package/dist/chunk-FNW556FN.js +75 -0
- package/dist/chunk-FNW556FN.js.map +1 -0
- package/dist/chunk-GCPBEMMH.js +563 -0
- package/dist/chunk-GCPBEMMH.js.map +1 -0
- package/dist/chunk-J32GU3F3.js +1664 -0
- package/dist/chunk-J32GU3F3.js.map +1 -0
- package/dist/chunk-PGR7LK6D.js +1062 -0
- package/dist/chunk-PGR7LK6D.js.map +1 -0
- package/dist/chunk-RQJRQF46.js +787 -0
- package/dist/chunk-RQJRQF46.js.map +1 -0
- package/dist/{chunk-ME76RUMR.js → chunk-RVQHY3XU.js} +15 -1
- package/dist/chunk-RVQHY3XU.js.map +1 -0
- package/dist/chunk-SI2LU2RP.js +224 -0
- package/dist/chunk-SI2LU2RP.js.map +1 -0
- package/dist/chunk-W5UUUII5.js +142 -0
- package/dist/chunk-W5UUUII5.js.map +1 -0
- package/dist/document/document-session.d.ts +127 -0
- package/dist/document/document-session.d.ts.map +1 -0
- package/dist/document/document-session.js +749 -0
- package/dist/document/document-session.js.map +1 -0
- package/dist/document/filesystem-target.d.ts +17 -0
- package/dist/document/filesystem-target.d.ts.map +1 -0
- package/dist/document/filesystem-target.js +70 -0
- package/dist/document/filesystem-target.js.map +1 -0
- package/dist/document/index.d.ts +6 -0
- package/dist/document/index.d.ts.map +1 -0
- package/dist/document/index.js +4 -0
- package/dist/document/index.js.map +1 -0
- package/dist/document/recovery-journal.d.ts +125 -0
- package/dist/document/recovery-journal.d.ts.map +1 -0
- package/dist/document/recovery-journal.js +385 -0
- package/dist/document/recovery-journal.js.map +1 -0
- package/dist/document/types.d.ts +89 -0
- package/dist/document/types.d.ts.map +1 -0
- package/dist/document/types.js +9 -0
- package/dist/document/types.js.map +1 -0
- package/dist/filesystem/commit-lock.d.ts +3 -0
- package/dist/filesystem/commit-lock.d.ts.map +1 -0
- package/dist/filesystem/commit-lock.js +20 -0
- package/dist/filesystem/commit-lock.js.map +1 -0
- package/dist/filesystem/dbk-workspace.d.ts +34 -0
- package/dist/filesystem/dbk-workspace.d.ts.map +1 -0
- package/dist/filesystem/dbk-workspace.js +85 -0
- package/dist/filesystem/dbk-workspace.js.map +1 -0
- package/dist/filesystem/electron-provider-v2.d.ts +36 -0
- package/dist/filesystem/electron-provider-v2.d.ts.map +1 -0
- package/dist/filesystem/electron-provider-v2.js +503 -0
- package/dist/filesystem/electron-provider-v2.js.map +1 -0
- package/dist/filesystem/electron-provider.d.ts +6 -3
- package/dist/filesystem/electron-provider.d.ts.map +1 -1
- package/dist/filesystem/electron-provider.js +18 -13
- package/dist/filesystem/electron-provider.js.map +1 -1
- package/dist/filesystem/electron.d.ts +4 -0
- package/dist/filesystem/electron.d.ts.map +1 -0
- package/dist/filesystem/electron.js +4 -0
- package/dist/filesystem/electron.js.map +1 -0
- package/dist/filesystem/filesystem-content-container.d.ts +1 -1
- package/dist/filesystem/filesystem-content-container.d.ts.map +1 -1
- package/dist/filesystem/filesystem-content-container.js +50 -13
- package/dist/filesystem/filesystem-content-container.js.map +1 -1
- package/dist/filesystem/fs-error.d.ts +46 -0
- package/dist/filesystem/fs-error.d.ts.map +1 -0
- package/dist/filesystem/fs-error.js +170 -0
- package/dist/filesystem/fs-error.js.map +1 -0
- package/dist/filesystem/index.d.ts +15 -1
- package/dist/filesystem/index.d.ts.map +1 -1
- package/dist/filesystem/index.js +13 -0
- package/dist/filesystem/index.js.map +1 -1
- package/dist/filesystem/indexeddb-content-container.d.ts +3 -1
- package/dist/filesystem/indexeddb-content-container.d.ts.map +1 -1
- package/dist/filesystem/indexeddb-content-container.js +18 -11
- package/dist/filesystem/indexeddb-content-container.js.map +1 -1
- package/dist/filesystem/indexeddb-provider-v2.d.ts +96 -0
- package/dist/filesystem/indexeddb-provider-v2.d.ts.map +1 -0
- package/dist/filesystem/indexeddb-provider-v2.js +1241 -0
- package/dist/filesystem/indexeddb-provider-v2.js.map +1 -0
- package/dist/filesystem/indexeddb-provider.d.ts +21 -14
- package/dist/filesystem/indexeddb-provider.d.ts.map +1 -1
- package/dist/filesystem/indexeddb-provider.js +111 -261
- package/dist/filesystem/indexeddb-provider.js.map +1 -1
- package/dist/filesystem/indexeddb-store.d.ts +34 -0
- package/dist/filesystem/indexeddb-store.d.ts.map +1 -0
- package/dist/filesystem/indexeddb-store.js +165 -0
- package/dist/filesystem/indexeddb-store.js.map +1 -0
- package/dist/filesystem/indexeddb.d.ts +5 -0
- package/dist/filesystem/indexeddb.d.ts.map +1 -0
- package/dist/filesystem/indexeddb.js +5 -0
- package/dist/filesystem/indexeddb.js.map +1 -0
- package/dist/filesystem/legacy-v2-adapter.d.ts +62 -0
- package/dist/filesystem/legacy-v2-adapter.d.ts.map +1 -0
- package/dist/filesystem/legacy-v2-adapter.js +499 -0
- package/dist/filesystem/legacy-v2-adapter.js.map +1 -0
- package/dist/filesystem/memory-provider-v2.d.ts +92 -0
- package/dist/filesystem/memory-provider-v2.d.ts.map +1 -0
- package/dist/filesystem/memory-provider-v2.js +615 -0
- package/dist/filesystem/memory-provider-v2.js.map +1 -0
- package/dist/filesystem/memory-provider.d.ts +54 -0
- package/dist/filesystem/memory-provider.d.ts.map +1 -0
- package/dist/filesystem/memory-provider.js +132 -0
- package/dist/filesystem/memory-provider.js.map +1 -0
- package/dist/filesystem/memory.d.ts +4 -0
- package/dist/filesystem/memory.d.ts.map +1 -0
- package/dist/filesystem/memory.js +4 -0
- package/dist/filesystem/memory.js.map +1 -0
- package/dist/filesystem/move-entry.d.ts +9 -0
- package/dist/filesystem/move-entry.d.ts.map +1 -0
- package/dist/filesystem/move-entry.js +103 -0
- package/dist/filesystem/move-entry.js.map +1 -0
- package/dist/filesystem/move-error.d.ts +53 -0
- package/dist/filesystem/move-error.d.ts.map +1 -0
- package/dist/filesystem/move-error.js +99 -0
- package/dist/filesystem/move-error.js.map +1 -0
- package/dist/filesystem/native-provider-v2.d.ts +75 -0
- package/dist/filesystem/native-provider-v2.d.ts.map +1 -0
- package/dist/filesystem/native-provider-v2.js +849 -0
- package/dist/filesystem/native-provider-v2.js.map +1 -0
- package/dist/filesystem/native-provider.d.ts +9 -1
- package/dist/filesystem/native-provider.d.ts.map +1 -1
- package/dist/filesystem/native-provider.js +172 -37
- package/dist/filesystem/native-provider.js.map +1 -1
- package/dist/filesystem/native.d.ts +4 -0
- package/dist/filesystem/native.d.ts.map +1 -0
- package/dist/filesystem/native.js +4 -0
- package/dist/filesystem/native.js.map +1 -0
- package/dist/filesystem/types.d.ts +37 -4
- package/dist/filesystem/types.d.ts.map +1 -1
- package/dist/filesystem/types.js +11 -3
- package/dist/filesystem/types.js.map +1 -1
- package/dist/filesystem/v2.d.ts +172 -0
- package/dist/filesystem/v2.d.ts.map +1 -0
- package/dist/filesystem/v2.js +16 -0
- package/dist/filesystem/v2.js.map +1 -0
- package/dist/filesystem/workspace-path.d.ts +21 -0
- package/dist/filesystem/workspace-path.d.ts.map +1 -0
- package/dist/filesystem/workspace-path.js +80 -0
- package/dist/filesystem/workspace-path.js.map +1 -0
- package/dist/host/filesystem-v2.d.ts +45 -0
- package/dist/host/filesystem-v2.d.ts.map +1 -0
- package/dist/host/filesystem-v2.js +13 -0
- package/dist/host/filesystem-v2.js.map +1 -0
- package/dist/host/git.d.ts +200 -0
- package/dist/host/git.d.ts.map +1 -0
- package/dist/host/git.js +15 -0
- package/dist/host/git.js.map +1 -0
- package/dist/host/index.d.ts +4 -1
- package/dist/host/index.d.ts.map +1 -1
- package/dist/host/index.js +2 -0
- package/dist/host/index.js.map +1 -1
- package/dist/host/types.d.ts +114 -31
- package/dist/host/types.d.ts.map +1 -1
- package/dist/host/wire-policy.d.ts +22 -0
- package/dist/host/wire-policy.d.ts.map +1 -0
- package/dist/host/wire-policy.js +92 -0
- package/dist/host/wire-policy.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +4 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/types.d.ts +466 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +25 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/mcp/wire.d.ts +29 -0
- package/dist/mcp/wire.d.ts.map +1 -0
- package/dist/mcp/wire.js +1046 -0
- package/dist/mcp/wire.js.map +1 -0
- package/dist/mcp/zod.d.ts +5763 -0
- package/dist/mcp/zod.d.ts.map +1 -0
- package/dist/mcp/zod.js +908 -0
- package/dist/mcp/zod.js.map +1 -0
- package/dist/types-CX893hgH.d.ts +468 -0
- package/dist/types-CsX6EN2t.d.ts +301 -0
- package/dist/types-eOlt9J7n.d.ts +478 -0
- package/dist/vscode/index.d.ts +3 -0
- package/dist/vscode/index.d.ts.map +1 -0
- package/dist/vscode/index.js +3 -0
- package/dist/vscode/index.js.map +1 -0
- package/dist/vscode/messages.d.ts +204 -0
- package/dist/vscode/messages.d.ts.map +1 -0
- package/dist/vscode/messages.js +494 -0
- package/dist/vscode/messages.js.map +1 -0
- package/dist/workspace/index.d.ts +3 -2
- package/dist/workspace/index.d.ts.map +1 -1
- package/dist/workspace/index.js +2 -1
- package/dist/workspace/index.js.map +1 -1
- package/dist/workspace/reconcile-electron.d.ts +19 -0
- package/dist/workspace/reconcile-electron.d.ts.map +1 -0
- package/dist/workspace/reconcile-electron.js +42 -0
- package/dist/workspace/reconcile-electron.js.map +1 -0
- package/dist/workspace/types.d.ts +41 -1
- package/dist/workspace/types.d.ts.map +1 -1
- package/dist/workspace/types.js +0 -4
- package/dist/workspace/types.js.map +1 -1
- package/dist/workspace/workspace-manager.d.ts +17 -5
- package/dist/workspace/workspace-manager.d.ts.map +1 -1
- package/dist/workspace/workspace-manager.js +55 -11
- package/dist/workspace/workspace-manager.js.map +1 -1
- package/dist/workspace-path-CWVrcuPL.d.ts +21 -0
- package/package.json +43 -2
- package/src/document/document-session.ts +834 -0
- package/src/document/filesystem-target.ts +109 -0
- package/src/document/index.ts +41 -0
- package/src/document/recovery-journal.ts +536 -0
- package/src/document/types.ts +116 -0
- package/src/filesystem/commit-lock.ts +29 -0
- package/src/filesystem/dbk-workspace.ts +135 -0
- package/src/filesystem/electron-provider-v2.ts +630 -0
- package/src/filesystem/electron-provider.ts +25 -14
- package/src/filesystem/electron.ts +3 -0
- package/src/filesystem/filesystem-content-container.ts +53 -15
- package/src/filesystem/fs-error.ts +234 -0
- package/src/filesystem/index.ts +119 -0
- package/src/filesystem/indexeddb-content-container.ts +20 -12
- package/src/filesystem/indexeddb-provider-v2.ts +1740 -0
- package/src/filesystem/indexeddb-provider.ts +126 -300
- package/src/filesystem/indexeddb-store.ts +207 -0
- package/src/filesystem/indexeddb.ts +12 -0
- package/src/filesystem/legacy-v2-adapter.ts +779 -0
- package/src/filesystem/memory-provider-v2.ts +896 -0
- package/src/filesystem/memory-provider.ts +180 -0
- package/src/filesystem/memory.ts +15 -0
- package/src/filesystem/move-entry.ts +142 -0
- package/src/filesystem/move-error.ts +159 -0
- package/src/filesystem/native-provider-v2.ts +1165 -0
- package/src/filesystem/native-provider.ts +194 -41
- package/src/filesystem/native.ts +16 -0
- package/src/filesystem/types.ts +49 -4
- package/src/filesystem/v2.ts +231 -0
- package/src/filesystem/workspace-path.ts +92 -0
- package/src/host/filesystem-v2.ts +104 -0
- package/src/host/git.ts +246 -0
- package/src/host/index.ts +46 -0
- package/src/host/types.ts +155 -34
- package/src/host/wire-policy.ts +103 -0
- package/src/index.ts +2 -1
- package/src/mcp/index.ts +3 -0
- package/src/mcp/types.ts +594 -0
- package/src/mcp/wire.ts +1280 -0
- package/src/mcp/zod.ts +1000 -0
- package/src/vscode/index.ts +2 -0
- package/src/vscode/messages.ts +704 -0
- package/src/workspace/index.ts +8 -1
- package/src/workspace/reconcile-electron.ts +65 -0
- package/src/workspace/types.ts +39 -1
- package/src/workspace/workspace-manager.ts +71 -10
- package/dist/chunk-GUNM43XZ.js +0 -63
- package/dist/chunk-GUNM43XZ.js.map +0 -1
- package/dist/chunk-IM7LCQJ6.js +0 -850
- package/dist/chunk-IM7LCQJ6.js.map +0 -1
- package/dist/chunk-ME76RUMR.js.map +0 -1
- package/dist/index-pgBHBQ9G.d.ts +0 -213
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import type { FsError } from './fs-error.js';
|
|
2
|
+
import type { WorkspacePath } from './workspace-path.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Opaque provider-issued token representing one observed entry/tree state.
|
|
6
|
+
* Tokens support equality only within the issuing provider; callers must not
|
|
7
|
+
* parse them or assume a move or byte-identical rewrite changes the token.
|
|
8
|
+
* A token need not be a content hash, but it must change whenever the issuing
|
|
9
|
+
* provider observes a potentially different kind, payload, or descendant
|
|
10
|
+
* state. Detection of non-cooperating external changes is bounded by the
|
|
11
|
+
* backend's declared capabilities and metadata precision.
|
|
12
|
+
*/
|
|
13
|
+
declare const fileSystemVersionBrand: unique symbol;
|
|
14
|
+
export type FileSystemVersion = string & {
|
|
15
|
+
readonly [fileSystemVersionBrand]: 'FileSystemVersion';
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/** Validate/rebrand a version received from a provider transport. */
|
|
19
|
+
export function parseFileSystemVersion(value: unknown): FileSystemVersion {
|
|
20
|
+
if (typeof value !== 'string' || !value || value.length > 1024 || value.includes('\0')) {
|
|
21
|
+
throw new TypeError('Filesystem version tokens must be non-empty bounded strings.');
|
|
22
|
+
}
|
|
23
|
+
return value as FileSystemVersion;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function tryParseFileSystemVersion(value: unknown): FileSystemVersion | null {
|
|
27
|
+
try {
|
|
28
|
+
return parseFileSystemVersion(value);
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** `process` excludes this provider's local peers; `cross-context` also excludes cooperating tabs/processes. */
|
|
35
|
+
export type FileSystemAtomicity = 'none' | 'process' | 'cross-context';
|
|
36
|
+
export type FileSystemCaseSensitivity = 'sensitive' | 'insensitive' | 'platform';
|
|
37
|
+
export type FileSystemDurability = 'volatile' | 'best-effort' | 'durable';
|
|
38
|
+
export type FileSystemConditionalWriteStrength =
|
|
39
|
+
| 'none'
|
|
40
|
+
| 'process'
|
|
41
|
+
| 'cross-context'
|
|
42
|
+
| 'storage-atomic';
|
|
43
|
+
export type FileSystemSymlinkPolicy = 'unsupported' | 'reject' | 'follow-contained' | 'preserve';
|
|
44
|
+
|
|
45
|
+
/** Serializable feature declaration; consumers never need provider instanceof checks. */
|
|
46
|
+
export interface FileSystemProviderCapabilities {
|
|
47
|
+
/** Isolation of one successful file replacement from cooperating writers. */
|
|
48
|
+
readonly writeAtomicity: FileSystemAtomicity;
|
|
49
|
+
/** Isolation of one successful source-to-destination move. */
|
|
50
|
+
readonly moveAtomicity: FileSystemAtomicity;
|
|
51
|
+
/** Writers excluded while one complete snapshot is captured. */
|
|
52
|
+
readonly snapshotAtomicity: FileSystemAtomicity;
|
|
53
|
+
/** Strongest boundary at which expectedVersion is checked with mutation. */
|
|
54
|
+
readonly conditionalWrite: FileSystemConditionalWriteStrength;
|
|
55
|
+
readonly recursiveRemove: boolean;
|
|
56
|
+
/** True only when watch has a real ready barrier and sequenced events. */
|
|
57
|
+
readonly watch: boolean;
|
|
58
|
+
readonly caseSensitivity: FileSystemCaseSensitivity;
|
|
59
|
+
readonly symlinkPolicy: FileSystemSymlinkPolicy;
|
|
60
|
+
readonly durability: FileSystemDurability;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface FileSystemEntrySnapshotBase {
|
|
64
|
+
readonly path: WorkspacePath;
|
|
65
|
+
readonly name: string;
|
|
66
|
+
readonly version: FileSystemVersion;
|
|
67
|
+
/** ISO-8601 timestamp supplied by the backend; versions remain authoritative. */
|
|
68
|
+
readonly lastModified: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface FileSystemFileSnapshot extends FileSystemEntrySnapshotBase {
|
|
72
|
+
readonly kind: 'file';
|
|
73
|
+
readonly size: number;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface FileSystemDirectorySnapshot extends FileSystemEntrySnapshotBase {
|
|
77
|
+
readonly kind: 'directory';
|
|
78
|
+
readonly size: null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export type FileSystemEntrySnapshot = FileSystemFileSnapshot | FileSystemDirectorySnapshot;
|
|
82
|
+
|
|
83
|
+
/** A read always couples owned bytes to the exact metadata version they represent. */
|
|
84
|
+
export interface FileSystemFileRead {
|
|
85
|
+
readonly entry: FileSystemFileSnapshot;
|
|
86
|
+
readonly data: ArrayBuffer;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface FileSystemSnapshotFile extends FileSystemFileSnapshot {
|
|
90
|
+
readonly data: ArrayBuffer;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export type FileSystemSnapshotEntry = FileSystemSnapshotFile | FileSystemDirectorySnapshot;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Complete best-available tree traversal. `snapshotAtomicity` declares
|
|
97
|
+
* whether concurrent local/cross-context mutations are excluded while it is
|
|
98
|
+
* captured. Implementations must never expose aliased buffers.
|
|
99
|
+
*/
|
|
100
|
+
export interface FileSystemSnapshot {
|
|
101
|
+
readonly version: FileSystemVersion;
|
|
102
|
+
readonly entries: readonly FileSystemSnapshotEntry[];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export type FileSystemWriteMode = 'upsert' | 'create' | 'replace';
|
|
106
|
+
|
|
107
|
+
export interface FileSystemWriteOptions {
|
|
108
|
+
/** Defaults to upsert. */
|
|
109
|
+
readonly mode?: FileSystemWriteMode;
|
|
110
|
+
/** Defaults to false so structure creation is never implicit. */
|
|
111
|
+
readonly createParents?: boolean;
|
|
112
|
+
/** null means the entry must not exist; a token requires an exact match. */
|
|
113
|
+
readonly expectedVersion?: FileSystemVersion | null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export type FileSystemCreateDirectoryMode = 'ensure' | 'create';
|
|
117
|
+
|
|
118
|
+
export interface FileSystemCreateDirectoryOptions {
|
|
119
|
+
/** Defaults to ensure (idempotently return an existing directory). */
|
|
120
|
+
readonly mode?: FileSystemCreateDirectoryMode;
|
|
121
|
+
/** Defaults to false. */
|
|
122
|
+
readonly createParents?: boolean;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface FileSystemRemoveOptions {
|
|
126
|
+
/** Defaults to false; non-empty directories otherwise fail with not-empty. */
|
|
127
|
+
readonly recursive?: boolean;
|
|
128
|
+
/** Defaults to error. */
|
|
129
|
+
readonly missing?: 'ignore' | 'error';
|
|
130
|
+
readonly expectedVersion?: FileSystemVersion;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface FileSystemRemoveResult {
|
|
134
|
+
readonly removed: boolean;
|
|
135
|
+
/** Version of the complete tree after the removal attempt. */
|
|
136
|
+
readonly version: FileSystemVersion;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface FileSystemMoveOptions {
|
|
140
|
+
/** Defaults to false. Destinations are never overwritten. */
|
|
141
|
+
readonly createParents?: boolean;
|
|
142
|
+
readonly expectedVersion?: FileSystemVersion;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export type FileSystemWatchEventType = 'created' | 'modified' | 'removed' | 'moved' | 'overflow';
|
|
146
|
+
export type FileSystemWatchEventOrigin = 'local' | 'external' | 'unknown';
|
|
147
|
+
|
|
148
|
+
interface FileSystemWatchEventBase {
|
|
149
|
+
readonly sequence: number;
|
|
150
|
+
readonly origin: FileSystemWatchEventOrigin;
|
|
151
|
+
readonly path: WorkspacePath;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export interface FileSystemEntryWatchEvent extends FileSystemWatchEventBase {
|
|
155
|
+
readonly type: Exclude<FileSystemWatchEventType, 'overflow'>;
|
|
156
|
+
readonly kind: 'file' | 'directory';
|
|
157
|
+
readonly destinationPath: WorkspacePath | null;
|
|
158
|
+
readonly version: FileSystemVersion | null;
|
|
159
|
+
readonly previousVersion: FileSystemVersion | null;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export interface FileSystemOverflowWatchEvent extends FileSystemWatchEventBase {
|
|
163
|
+
readonly type: 'overflow';
|
|
164
|
+
readonly kind: null;
|
|
165
|
+
readonly destinationPath: null;
|
|
166
|
+
readonly version: null;
|
|
167
|
+
readonly previousVersion: null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export type FileSystemWatchEvent = FileSystemEntryWatchEvent | FileSystemOverflowWatchEvent;
|
|
171
|
+
|
|
172
|
+
export type FileSystemWatchListener = (event: FileSystemWatchEvent) => void;
|
|
173
|
+
export type FileSystemWatchErrorListener = (error: FsError) => void;
|
|
174
|
+
|
|
175
|
+
export interface FileSystemWatchOptions {
|
|
176
|
+
readonly onError?: FileSystemWatchErrorListener;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export interface FileSystemWatchSubscription {
|
|
180
|
+
readonly closed: boolean;
|
|
181
|
+
/** Resolves after the backend watch is installed and no initial event can be missed. */
|
|
182
|
+
readonly ready: Promise<void>;
|
|
183
|
+
/** Idempotent and awaitable so resource release can join provider shutdown. */
|
|
184
|
+
dispose(): Promise<void>;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Correctness-first filesystem contract. Every logical path has exactly one
|
|
189
|
+
* kind and one byte payload; conditional writes and lifecycle disposal are
|
|
190
|
+
* mandatory rather than optional provider extensions.
|
|
191
|
+
*/
|
|
192
|
+
export interface FileSystemProviderV2 {
|
|
193
|
+
readonly id: string;
|
|
194
|
+
readonly label: string;
|
|
195
|
+
readonly capabilities: FileSystemProviderCapabilities;
|
|
196
|
+
|
|
197
|
+
/** Absence is represented only by null; permission/I/O/wrong-kind errors throw FsError. */
|
|
198
|
+
stat(path: WorkspacePath): Promise<FileSystemEntrySnapshot | null>;
|
|
199
|
+
/** Absence is represented only by null; a directory at path is type-mismatch. */
|
|
200
|
+
readFile(path: WorkspacePath): Promise<FileSystemFileRead | null>;
|
|
201
|
+
/** Missing paths and file paths throw; results are canonical and deterministic. */
|
|
202
|
+
readDirectory(path: WorkspacePath): Promise<readonly FileSystemEntrySnapshot[]>;
|
|
203
|
+
|
|
204
|
+
writeFile(
|
|
205
|
+
path: WorkspacePath,
|
|
206
|
+
data: ArrayBuffer | Uint8Array,
|
|
207
|
+
options?: FileSystemWriteOptions,
|
|
208
|
+
): Promise<FileSystemFileSnapshot>;
|
|
209
|
+
createDirectory(
|
|
210
|
+
path: WorkspacePath,
|
|
211
|
+
options?: FileSystemCreateDirectoryOptions,
|
|
212
|
+
): Promise<FileSystemDirectorySnapshot>;
|
|
213
|
+
remove(path: WorkspacePath, options?: FileSystemRemoveOptions): Promise<FileSystemRemoveResult>;
|
|
214
|
+
move(
|
|
215
|
+
oldPath: WorkspacePath,
|
|
216
|
+
newPath: WorkspacePath,
|
|
217
|
+
options?: FileSystemMoveOptions,
|
|
218
|
+
): Promise<FileSystemEntrySnapshot>;
|
|
219
|
+
|
|
220
|
+
snapshot(): Promise<FileSystemSnapshot>;
|
|
221
|
+
/**
|
|
222
|
+
* Always returns a disposable subscription. When `capabilities.watch` is
|
|
223
|
+
* false, `ready` rejects with `FsError('not-supported')` and `onError`
|
|
224
|
+
* observes the same failure; callers can therefore use one cleanup path.
|
|
225
|
+
*/
|
|
226
|
+
watch(
|
|
227
|
+
listener: FileSystemWatchListener,
|
|
228
|
+
options?: FileSystemWatchOptions,
|
|
229
|
+
): FileSystemWatchSubscription;
|
|
230
|
+
dispose(): Promise<void>;
|
|
231
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { FsError } from './fs-error.js';
|
|
2
|
+
|
|
3
|
+
declare const workspacePathBrand: unique symbol;
|
|
4
|
+
|
|
5
|
+
/** Canonical, root-relative, forward-slash path within one workspace. */
|
|
6
|
+
export type WorkspacePath = string & { readonly [workspacePathBrand]: 'WorkspacePath' };
|
|
7
|
+
|
|
8
|
+
export const WORKSPACE_ROOT = '' as WorkspacePath;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Parse a legacy/user path into its one canonical workspace representation.
|
|
12
|
+
* Leading/trailing and repeated separators are normalized; traversal and NUL
|
|
13
|
+
* segments are rejected rather than resolved.
|
|
14
|
+
*/
|
|
15
|
+
export function parseWorkspacePath(input: string): WorkspacePath {
|
|
16
|
+
if (
|
|
17
|
+
[...input].some((character) => {
|
|
18
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
19
|
+
return codePoint <= 0x1f || codePoint === 0x7f;
|
|
20
|
+
})
|
|
21
|
+
) {
|
|
22
|
+
throw invalidPath(input, 'Workspace paths must not contain NUL or other control characters.');
|
|
23
|
+
}
|
|
24
|
+
if (/^[a-zA-Z]:/u.test(input)) {
|
|
25
|
+
throw new FsError('path-escape', 'Workspace paths must not be OS drive-qualified paths.', {
|
|
26
|
+
operation: 'parse-path',
|
|
27
|
+
path: input,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const normalized = input
|
|
32
|
+
.replace(/\\/g, '/')
|
|
33
|
+
.replace(/\/+/g, '/')
|
|
34
|
+
.replace(/^\/|\/$/g, '');
|
|
35
|
+
if (!normalized) return WORKSPACE_ROOT;
|
|
36
|
+
|
|
37
|
+
const segments = normalized.split('/');
|
|
38
|
+
if (segments.some((segment) => segment === '.' || segment === '..')) {
|
|
39
|
+
throw new FsError('path-escape', 'Workspace paths must not contain "." or ".." segments.', {
|
|
40
|
+
operation: 'parse-path',
|
|
41
|
+
path: input,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return normalized as WorkspacePath;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function tryParseWorkspacePath(input: unknown): WorkspacePath | null {
|
|
48
|
+
if (typeof input !== 'string') return null;
|
|
49
|
+
try {
|
|
50
|
+
return parseWorkspacePath(input);
|
|
51
|
+
} catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Convert a canonical path to the slash-prefixed form accepted by v1 providers. */
|
|
57
|
+
export function workspacePathToLegacy(path: WorkspacePath): string {
|
|
58
|
+
return path ? `/${path}` : '/';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function workspacePathJoin(parent: WorkspacePath, child: string): WorkspacePath {
|
|
62
|
+
const childPath = parseWorkspacePath(child);
|
|
63
|
+
if (!parent) return childPath;
|
|
64
|
+
if (!childPath) return parent;
|
|
65
|
+
return parseWorkspacePath(`${parent}/${childPath}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function workspacePathDirname(path: WorkspacePath): WorkspacePath {
|
|
69
|
+
if (!path) return WORKSPACE_ROOT;
|
|
70
|
+
const slash = path.lastIndexOf('/');
|
|
71
|
+
return slash < 0 ? WORKSPACE_ROOT : (path.slice(0, slash) as WorkspacePath);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function workspacePathBasename(path: WorkspacePath): string {
|
|
75
|
+
if (!path) return '';
|
|
76
|
+
const slash = path.lastIndexOf('/');
|
|
77
|
+
return slash < 0 ? path : path.slice(slash + 1);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function workspacePathContains(
|
|
81
|
+
parent: WorkspacePath,
|
|
82
|
+
candidate: WorkspacePath,
|
|
83
|
+
inclusive = true,
|
|
84
|
+
): boolean {
|
|
85
|
+
if (parent === candidate) return inclusive;
|
|
86
|
+
if (!parent) return candidate !== WORKSPACE_ROOT;
|
|
87
|
+
return candidate.startsWith(`${parent}/`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function invalidPath(path: string, message: string): FsError {
|
|
91
|
+
return new FsError('invalid-path', message, { operation: 'parse-path', path });
|
|
92
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
FileSystemCreateDirectoryOptions,
|
|
3
|
+
FileSystemDirectorySnapshot,
|
|
4
|
+
FileSystemEntrySnapshot,
|
|
5
|
+
FileSystemFileRead,
|
|
6
|
+
FileSystemFileSnapshot,
|
|
7
|
+
FileSystemMoveOptions,
|
|
8
|
+
FileSystemProviderCapabilities,
|
|
9
|
+
FileSystemRemoveOptions,
|
|
10
|
+
FileSystemRemoveResult,
|
|
11
|
+
FileSystemSnapshot,
|
|
12
|
+
FileSystemWatchEvent,
|
|
13
|
+
FileSystemWriteOptions,
|
|
14
|
+
SerializedFsError,
|
|
15
|
+
WorkspacePath,
|
|
16
|
+
} from '../filesystem/index.js';
|
|
17
|
+
|
|
18
|
+
/** Stable capabilities shared by the Electron v2 client and native backend. */
|
|
19
|
+
export const ELECTRON_FILE_SYSTEM_V2_CAPABILITIES: FileSystemProviderCapabilities = Object.freeze({
|
|
20
|
+
writeAtomicity: 'process',
|
|
21
|
+
moveAtomicity: 'process',
|
|
22
|
+
snapshotAtomicity: 'process',
|
|
23
|
+
conditionalWrite: 'process',
|
|
24
|
+
recursiveRemove: true,
|
|
25
|
+
watch: true,
|
|
26
|
+
caseSensitivity: 'platform',
|
|
27
|
+
symlinkPolicy: 'follow-contained',
|
|
28
|
+
durability: 'best-effort',
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
/** Explicit result envelope; Electron does not preserve custom Error fields. */
|
|
32
|
+
export type HostFileSystemV2Result<T> =
|
|
33
|
+
| { readonly ok: true; readonly value: T }
|
|
34
|
+
| { readonly ok: false; readonly error: SerializedFsError };
|
|
35
|
+
|
|
36
|
+
export interface HostFileSystemV2OpenRequest {
|
|
37
|
+
readonly instanceId: string;
|
|
38
|
+
/** Main-owned persisted workspace authority, never an absolute path. */
|
|
39
|
+
readonly providerId: string;
|
|
40
|
+
readonly label: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type HostFileSystemV2WatchMessage =
|
|
44
|
+
| {
|
|
45
|
+
readonly instanceId: string;
|
|
46
|
+
readonly subscriptionId: string;
|
|
47
|
+
readonly kind: 'event';
|
|
48
|
+
readonly event: FileSystemWatchEvent;
|
|
49
|
+
}
|
|
50
|
+
| {
|
|
51
|
+
readonly instanceId: string;
|
|
52
|
+
readonly subscriptionId: string;
|
|
53
|
+
readonly kind: 'error';
|
|
54
|
+
readonly error: SerializedFsError;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/** Wire-level filesystem v2 API exposed by preload. */
|
|
58
|
+
export interface DocBlocksHostFsV2API {
|
|
59
|
+
open(
|
|
60
|
+
request: HostFileSystemV2OpenRequest,
|
|
61
|
+
): Promise<HostFileSystemV2Result<FileSystemProviderCapabilities>>;
|
|
62
|
+
stat(
|
|
63
|
+
instanceId: string,
|
|
64
|
+
path: WorkspacePath,
|
|
65
|
+
): Promise<HostFileSystemV2Result<FileSystemEntrySnapshot | null>>;
|
|
66
|
+
readFile(
|
|
67
|
+
instanceId: string,
|
|
68
|
+
path: WorkspacePath,
|
|
69
|
+
): Promise<HostFileSystemV2Result<FileSystemFileRead | null>>;
|
|
70
|
+
readDirectory(
|
|
71
|
+
instanceId: string,
|
|
72
|
+
path: WorkspacePath,
|
|
73
|
+
): Promise<HostFileSystemV2Result<readonly FileSystemEntrySnapshot[]>>;
|
|
74
|
+
writeFile(
|
|
75
|
+
instanceId: string,
|
|
76
|
+
path: WorkspacePath,
|
|
77
|
+
data: ArrayBuffer | Uint8Array,
|
|
78
|
+
options?: FileSystemWriteOptions,
|
|
79
|
+
): Promise<HostFileSystemV2Result<FileSystemFileSnapshot>>;
|
|
80
|
+
createDirectory(
|
|
81
|
+
instanceId: string,
|
|
82
|
+
path: WorkspacePath,
|
|
83
|
+
options?: FileSystemCreateDirectoryOptions,
|
|
84
|
+
): Promise<HostFileSystemV2Result<FileSystemDirectorySnapshot>>;
|
|
85
|
+
remove(
|
|
86
|
+
instanceId: string,
|
|
87
|
+
path: WorkspacePath,
|
|
88
|
+
options?: FileSystemRemoveOptions,
|
|
89
|
+
): Promise<HostFileSystemV2Result<FileSystemRemoveResult>>;
|
|
90
|
+
move(
|
|
91
|
+
instanceId: string,
|
|
92
|
+
oldPath: WorkspacePath,
|
|
93
|
+
newPath: WorkspacePath,
|
|
94
|
+
options?: FileSystemMoveOptions,
|
|
95
|
+
): Promise<HostFileSystemV2Result<FileSystemEntrySnapshot>>;
|
|
96
|
+
snapshot(instanceId: string): Promise<HostFileSystemV2Result<FileSystemSnapshot>>;
|
|
97
|
+
watchSubscribe(instanceId: string, subscriptionId: string): Promise<HostFileSystemV2Result<null>>;
|
|
98
|
+
watchUnsubscribe(
|
|
99
|
+
instanceId: string,
|
|
100
|
+
subscriptionId: string,
|
|
101
|
+
): Promise<HostFileSystemV2Result<null>>;
|
|
102
|
+
dispose(instanceId: string): Promise<HostFileSystemV2Result<null>>;
|
|
103
|
+
onWatchMessage(listener: (message: HostFileSystemV2WatchMessage) => void): () => void;
|
|
104
|
+
}
|
package/src/host/git.ts
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git host API — wire types for the desktop shell's git integration.
|
|
3
|
+
*
|
|
4
|
+
* The desktop app spawns the user's system git from the main process, so
|
|
5
|
+
* credentials (helpers, SSH agent, signing config and raw remote URLs) remain
|
|
6
|
+
* in the main process. Everything here is generic git; the only host-specific
|
|
7
|
+
* conveniences are remote-URL parsing (`GitRemoteInfo.web`) and PR creation
|
|
8
|
+
* via the GitHub CLI when installed.
|
|
9
|
+
*
|
|
10
|
+
* Expected git failures cross IPC as data (`GitResult`), never as thrown
|
|
11
|
+
* errors — `ipcMain.handle` rejections lose structure. Throwing is reserved
|
|
12
|
+
* for contract violations (unregistered root, path escape).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { ElectronWorkspaceInfo } from './types.js';
|
|
16
|
+
|
|
17
|
+
/** Every git operation resolves this — expected failures are data, not throws. */
|
|
18
|
+
export type GitResult<T> = { ok: true; value: T } | { ok: false; error: GitError };
|
|
19
|
+
|
|
20
|
+
export interface GitError {
|
|
21
|
+
code: GitErrorCode;
|
|
22
|
+
/** One-line human summary (classified stderr or synthesized). */
|
|
23
|
+
message: string;
|
|
24
|
+
/** Truncated raw stderr for a details disclosure in the UI. */
|
|
25
|
+
stderr?: string;
|
|
26
|
+
exitCode?: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type GitErrorCode =
|
|
30
|
+
| 'git-not-available'
|
|
31
|
+
| 'not-a-repository'
|
|
32
|
+
| 'auth-failed'
|
|
33
|
+
| 'remote-not-found'
|
|
34
|
+
| 'no-upstream'
|
|
35
|
+
| 'network'
|
|
36
|
+
| 'non-fast-forward'
|
|
37
|
+
| 'merge-conflict'
|
|
38
|
+
| 'uncommitted-changes'
|
|
39
|
+
| 'detached-head'
|
|
40
|
+
| 'unborn-branch'
|
|
41
|
+
| 'identity-not-configured'
|
|
42
|
+
| 'branch-exists'
|
|
43
|
+
| 'invalid-ref-name'
|
|
44
|
+
| 'nothing-to-commit'
|
|
45
|
+
| 'invalid-url'
|
|
46
|
+
| 'destination-exists'
|
|
47
|
+
| 'pr-exists'
|
|
48
|
+
| 'gh-not-available'
|
|
49
|
+
| 'timeout'
|
|
50
|
+
| 'cancelled'
|
|
51
|
+
| 'permission-denied'
|
|
52
|
+
| 'unknown';
|
|
53
|
+
|
|
54
|
+
export interface GitCapabilities {
|
|
55
|
+
/** False in store-sandboxed builds, when git is absent, or git < 2.23. */
|
|
56
|
+
gitAvailable: boolean;
|
|
57
|
+
gitVersion: string | null;
|
|
58
|
+
ghAvailable: boolean;
|
|
59
|
+
ghVersion: string | null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface GitRepoDetection {
|
|
63
|
+
isRepo: boolean;
|
|
64
|
+
/** False when the workspace root is a subdirectory of a larger repo. */
|
|
65
|
+
rootIsToplevel?: boolean;
|
|
66
|
+
/** Main-owned repository authority; absent when expanded access was declined. */
|
|
67
|
+
repositoryId?: string;
|
|
68
|
+
/** True when Git metadata or the work tree extends beyond the workspace grant. */
|
|
69
|
+
requiresExpandedGrant?: boolean;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export type GitFileStatusCode =
|
|
73
|
+
| 'added'
|
|
74
|
+
| 'modified'
|
|
75
|
+
| 'deleted'
|
|
76
|
+
| 'renamed'
|
|
77
|
+
| 'copied'
|
|
78
|
+
| 'type-changed'
|
|
79
|
+
| 'untracked'
|
|
80
|
+
| 'ignored'
|
|
81
|
+
| 'unmerged';
|
|
82
|
+
|
|
83
|
+
export interface GitFileChange {
|
|
84
|
+
/** Slash-prefixed path relative to the WORKSPACE root (fs API convention). */
|
|
85
|
+
path: string;
|
|
86
|
+
/** Previous path for renames/copies (workspace-relative, slash-prefixed). */
|
|
87
|
+
origPath?: string;
|
|
88
|
+
/** Index-vs-HEAD state (staged), if any. */
|
|
89
|
+
index?: GitFileStatusCode;
|
|
90
|
+
/** Worktree-vs-index state (unstaged), if any. */
|
|
91
|
+
worktree?: GitFileStatusCode;
|
|
92
|
+
conflicted: boolean;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface GitStatus {
|
|
96
|
+
/** Branch name; null when detached or unborn with no branch. */
|
|
97
|
+
branch: string | null;
|
|
98
|
+
detached: boolean;
|
|
99
|
+
/** HEAD points at a branch with no commits yet. */
|
|
100
|
+
unborn: boolean;
|
|
101
|
+
/** Full HEAD SHA; null when unborn. */
|
|
102
|
+
head: string | null;
|
|
103
|
+
/** Upstream ref short name, e.g. "origin/main". */
|
|
104
|
+
upstream: string | null;
|
|
105
|
+
ahead: number;
|
|
106
|
+
behind: number;
|
|
107
|
+
changes: GitFileChange[];
|
|
108
|
+
/** True when `changes` was capped. */
|
|
109
|
+
truncated: boolean;
|
|
110
|
+
operation: 'merge' | 'rebase' | 'cherry-pick' | 'revert' | 'bisect' | null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface GitBranchInfo {
|
|
114
|
+
/** "main" for local branches, "origin/main" for remote entries. */
|
|
115
|
+
name: string;
|
|
116
|
+
kind: 'local' | 'remote';
|
|
117
|
+
current: boolean;
|
|
118
|
+
upstream: string | null;
|
|
119
|
+
ahead: number;
|
|
120
|
+
behind: number;
|
|
121
|
+
upstreamGone: boolean;
|
|
122
|
+
headSha: string;
|
|
123
|
+
headSubject: string;
|
|
124
|
+
/** ISO 8601. */
|
|
125
|
+
headDate: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface GitLogOptions {
|
|
129
|
+
/** Workspace-relative file path — per-file history (follows renames). */
|
|
130
|
+
path?: string;
|
|
131
|
+
/** Default 100; the host caps at 1000. */
|
|
132
|
+
maxCount?: number;
|
|
133
|
+
skip?: number;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface GitLogEntry {
|
|
137
|
+
sha: string;
|
|
138
|
+
parents: string[];
|
|
139
|
+
authorName: string;
|
|
140
|
+
authorEmail: string;
|
|
141
|
+
/** ISO 8601. */
|
|
142
|
+
authorDate: string;
|
|
143
|
+
subject: string;
|
|
144
|
+
/** Ref decorations ("HEAD -> main", "origin/main", "tag: v1"). */
|
|
145
|
+
refs: string[];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Typed revision selector — the renderer never passes raw rev strings. */
|
|
149
|
+
export type GitRevision =
|
|
150
|
+
| { kind: 'head' }
|
|
151
|
+
| { kind: 'index' }
|
|
152
|
+
| { kind: 'commit'; sha: string }
|
|
153
|
+
| { kind: 'parent-of'; sha: string };
|
|
154
|
+
|
|
155
|
+
export interface GitFileAtRevision {
|
|
156
|
+
/** Null when the file is absent at that revision, or binary/too large. */
|
|
157
|
+
content: string | null;
|
|
158
|
+
binary: boolean;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export interface GitRemoteInfo {
|
|
162
|
+
name: string;
|
|
163
|
+
/** Sanitized web location. Raw fetch/push URLs never cross IPC. */
|
|
164
|
+
web: { host: string; owner: string; repo: string; webUrl: string } | null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export interface GitCloneProgress {
|
|
168
|
+
/** e.g. "Receiving objects", "Resolving deltas", "Checking out files". */
|
|
169
|
+
phase: string;
|
|
170
|
+
percent: number | null;
|
|
171
|
+
/** Raw progress line for display. */
|
|
172
|
+
detail?: string;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export interface GitCloneHandle {
|
|
176
|
+
/**
|
|
177
|
+
* Resolves `ok(null)` if the user cancels the destination picker; on
|
|
178
|
+
* success resolves the registered workspace ready to open.
|
|
179
|
+
*/
|
|
180
|
+
result: Promise<GitResult<ElectronWorkspaceInfo | null>>;
|
|
181
|
+
/** Kill git and remove the partial clone directory. */
|
|
182
|
+
cancel: () => void;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export interface DocBlocksHostGitAPI {
|
|
186
|
+
capabilities(): Promise<GitCapabilities>;
|
|
187
|
+
/** Detect a persisted workspace by opaque workspace id and mint repository authority. */
|
|
188
|
+
detectRepo(workspaceId: string): Promise<GitResult<GitRepoDetection>>;
|
|
189
|
+
init(workspaceId: string): Promise<GitResult<void>>;
|
|
190
|
+
|
|
191
|
+
status(repositoryId: string): Promise<GitResult<GitStatus>>;
|
|
192
|
+
stage(repositoryId: string, paths: string[]): Promise<GitResult<void>>;
|
|
193
|
+
unstage(repositoryId: string, paths: string[]): Promise<GitResult<void>>;
|
|
194
|
+
/** Revert tracked files to HEAD; delete untracked ones. Destructive — the renderer confirms. */
|
|
195
|
+
discard(repositoryId: string, paths: string[]): Promise<GitResult<void>>;
|
|
196
|
+
/**
|
|
197
|
+
* With `paths`: stages exactly those files (`add -A -- <paths>`) and commits
|
|
198
|
+
* them, leaving other staged entries staged. Without: commits the index as-is.
|
|
199
|
+
*/
|
|
200
|
+
commit(
|
|
201
|
+
repositoryId: string,
|
|
202
|
+
message: string,
|
|
203
|
+
paths?: string[],
|
|
204
|
+
): Promise<GitResult<{ sha: string }>>;
|
|
205
|
+
|
|
206
|
+
push(repositoryId: string, opts?: { setUpstream?: boolean }): Promise<GitResult<void>>;
|
|
207
|
+
pull(repositoryId: string): Promise<GitResult<void>>;
|
|
208
|
+
fetch(repositoryId: string): Promise<GitResult<void>>;
|
|
209
|
+
|
|
210
|
+
listBranches(repositoryId: string): Promise<GitResult<GitBranchInfo[]>>;
|
|
211
|
+
createBranch(
|
|
212
|
+
repositoryId: string,
|
|
213
|
+
name: string,
|
|
214
|
+
opts?: { checkout?: boolean },
|
|
215
|
+
): Promise<GitResult<void>>;
|
|
216
|
+
checkoutBranch(repositoryId: string, name: string): Promise<GitResult<void>>;
|
|
217
|
+
|
|
218
|
+
log(repositoryId: string, opts?: GitLogOptions): Promise<GitResult<GitLogEntry[]>>;
|
|
219
|
+
/** Files changed in one commit plus the full message body. */
|
|
220
|
+
commitFiles(
|
|
221
|
+
repositoryId: string,
|
|
222
|
+
sha: string,
|
|
223
|
+
): Promise<GitResult<{ body: string; files: GitFileChange[] }>>;
|
|
224
|
+
readFileAtRevision(
|
|
225
|
+
repositoryId: string,
|
|
226
|
+
path: string,
|
|
227
|
+
revision: GitRevision,
|
|
228
|
+
): Promise<GitResult<GitFileAtRevision>>;
|
|
229
|
+
|
|
230
|
+
listRemotes(repositoryId: string): Promise<GitResult<GitRemoteInfo[]>>;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Clone a remote repository. The main process shows a native picker for the
|
|
234
|
+
* destination parent directory, then registers the clone as a workspace.
|
|
235
|
+
*/
|
|
236
|
+
clone(url: string, onProgress?: (p: GitCloneProgress) => void): GitCloneHandle;
|
|
237
|
+
|
|
238
|
+
/** `gh pr create --web` (falls back to `gh pr view --web` if one exists). */
|
|
239
|
+
createPullRequest(repositoryId: string): Promise<GitResult<void>>;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Throttled status stream for a workspace root. Emits once immediately on
|
|
243
|
+
* subscribe. Returns an unsubscribe function.
|
|
244
|
+
*/
|
|
245
|
+
onStatusChanged(repositoryId: string, listener: (status: GitStatus) => void): () => void;
|
|
246
|
+
}
|