@sayknow-cli/coding-agent 0.3.1 → 0.3.4
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/bin/skc.js +4 -0
- package/dist/types/cli/mcp-cli.d.ts +25 -0
- package/dist/types/cli/plugin-cli.d.ts +2 -0
- package/dist/types/cli.d.ts +6 -0
- package/dist/types/commands/mcp.d.ts +70 -0
- package/dist/types/commands/plugin.d.ts +6 -0
- package/dist/types/commands/session.d.ts +6 -0
- package/dist/types/config/keybindings.d.ts +2 -2
- package/dist/types/config/model-profile-activation.d.ts +8 -1
- package/dist/types/config/model-profiles.d.ts +2 -2
- package/dist/types/config/model-registry.d.ts +3 -3
- package/dist/types/config/models-config-schema.d.ts +0 -5
- package/dist/types/config/settings-schema.d.ts +79 -68
- package/dist/types/deep-interview/plaintext-gate-guard.d.ts +11 -0
- package/dist/types/export/html/template.generated.d.ts +1 -1
- package/dist/types/extensibility/skc-plugins/compiler.d.ts +19 -0
- package/dist/types/extensibility/skc-plugins/constrained-hooks.d.ts +29 -0
- package/dist/types/extensibility/skc-plugins/index.d.ts +9 -0
- package/dist/types/extensibility/skc-plugins/injection.d.ts +9 -0
- package/dist/types/extensibility/skc-plugins/installer.d.ts +13 -0
- package/dist/types/extensibility/skc-plugins/mcp-policy.d.ts +26 -0
- package/dist/types/extensibility/skc-plugins/observability.d.ts +27 -0
- package/dist/types/extensibility/skc-plugins/prompt-appendix.d.ts +16 -0
- package/dist/types/extensibility/skc-plugins/registry.d.ts +32 -0
- package/dist/types/extensibility/skc-plugins/runtime-adapters.d.ts +64 -0
- package/dist/types/extensibility/skc-plugins/session-validation.d.ts +42 -0
- package/dist/types/extensibility/skc-plugins/types.d.ts +158 -2
- package/dist/types/extensibility/skc-plugins/validation.d.ts +8 -1
- package/dist/types/i18n/messages/en.d.ts +0 -1
- package/dist/types/main.d.ts +2 -0
- package/dist/types/modes/components/custom-editor.d.ts +1 -1
- package/dist/types/modes/components/model-selector.d.ts +8 -0
- package/dist/types/modes/components/settings-defs.d.ts +0 -1
- package/dist/types/modes/components/status-line/git-utils.d.ts +6 -0
- package/dist/types/modes/theme/defaults/index.d.ts +99 -0
- package/dist/types/modes/theme/theme.d.ts +1 -1
- package/dist/types/notifications/html-format.d.ts +11 -0
- package/dist/types/notifications/index.d.ts +149 -1
- package/dist/types/notifications/lifecycle-commands.d.ts +60 -0
- package/dist/types/notifications/lifecycle-control-runtime.d.ts +98 -0
- package/dist/types/notifications/lifecycle-orchestrator.d.ts +144 -0
- package/dist/types/notifications/operator-runtime.d.ts +52 -0
- package/dist/types/notifications/rate-limit-pool.d.ts +2 -0
- package/dist/types/notifications/recent-activity.d.ts +35 -0
- package/dist/types/notifications/telegram-daemon.d.ts +114 -16
- package/dist/types/notifications/telegram-reference.d.ts +3 -1
- package/dist/types/notifications/topic-registry.d.ts +12 -9
- package/dist/types/runtime-mcp/types.d.ts +7 -0
- package/dist/types/sdk.d.ts +2 -0
- package/dist/types/session/agent-session.d.ts +14 -4
- package/dist/types/session/blob-store.d.ts +25 -0
- package/dist/types/session/session-manager.d.ts +57 -0
- package/dist/types/skc-runtime/launch-tmux.d.ts +1 -0
- package/dist/types/skc-runtime/psmux-detect.d.ts +78 -0
- package/dist/types/skc-runtime/state-renderer.d.ts +5 -0
- package/dist/types/skc-runtime/team-runtime.d.ts +2 -0
- package/dist/types/skc-runtime/tmux-common.d.ts +30 -2
- package/dist/types/skc-runtime/tmux-sessions.d.ts +18 -0
- package/dist/types/skc-runtime/ultragoal-guard.d.ts +37 -1
- package/dist/types/skc-runtime/ultragoal-runtime.d.ts +80 -0
- package/dist/types/slash-commands/helpers/fast-status-report.d.ts +6 -0
- package/dist/types/system-prompt.d.ts +2 -0
- package/dist/types/task/executor.d.ts +9 -1
- package/dist/types/tools/browser/tab-supervisor.d.ts +31 -0
- package/dist/types/tools/composer-bash-policy.d.ts +14 -0
- package/dist/types/tools/computer-gc.d.ts +23 -0
- package/dist/types/tools/cron.d.ts +36 -61
- package/dist/types/tools/index.d.ts +3 -2
- package/dist/types/tools/resource-gc.d.ts +54 -0
- package/dist/types/utils/changelog.d.ts +1 -0
- package/dist/types/web/insane/url-guard.d.ts +6 -3
- package/dist/types/web/scrapers/types.d.ts +5 -0
- package/dist/types/web/scrapers/utils.d.ts +7 -1
- package/dist/types/web/search/index.d.ts +1 -0
- package/dist/types/web/search/providers/utils.d.ts +11 -4
- package/package.json +11 -9
- package/scripts/g004-tmux-smoke.ts +100 -0
- package/scripts/g005-daemon-smoke.ts +180 -0
- package/scripts/g011-daemon-path-smoke.ts +153 -0
- package/src/cli/args.ts +0 -1
- package/src/cli/fast-help.ts +29 -2
- package/src/cli/mcp-cli.ts +272 -0
- package/src/cli/plugin-cli.ts +66 -3
- package/src/cli/web-search-cli.ts +5 -0
- package/src/cli.ts +30 -12
- package/src/commands/mcp.ts +117 -0
- package/src/commands/plugin.ts +4 -0
- package/src/commands/session.ts +18 -0
- package/src/config/keybindings.ts +2 -2
- package/src/config/model-profile-activation.ts +62 -8
- package/src/config/model-profiles.ts +3 -4
- package/src/config/model-registry.ts +3 -6
- package/src/config/models-config-schema.ts +1 -1
- package/src/config/settings-schema.ts +88 -103
- package/src/deep-interview/plaintext-gate-guard.ts +94 -0
- package/src/defaults/skc/extensions/grok-cli-vendor/biome.json +1 -1
- package/src/defaults/skc/skills/deep-interview/SKILL.md +7 -6
- package/src/defaults/skc/skills/team/SKILL.md +5 -3
- package/src/defaults/skc/skills/ultragoal/SKILL.md +41 -13
- package/src/export/html/index.ts +2 -2
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +0 -12
- package/src/extensibility/extensions/runner.ts +1 -0
- package/src/extensibility/skc-plugins/compiler.ts +351 -0
- package/src/extensibility/skc-plugins/constrained-hooks.ts +170 -0
- package/src/extensibility/skc-plugins/index.ts +9 -0
- package/src/extensibility/skc-plugins/injection.ts +109 -0
- package/src/extensibility/skc-plugins/installer.ts +434 -0
- package/src/extensibility/skc-plugins/loader.ts +3 -1
- package/src/extensibility/skc-plugins/mcp-policy.ts +239 -0
- package/src/extensibility/skc-plugins/observability.ts +84 -0
- package/src/extensibility/skc-plugins/paths.ts +1 -1
- package/src/extensibility/skc-plugins/prompt-appendix.ts +109 -0
- package/src/extensibility/skc-plugins/registry.ts +180 -0
- package/src/extensibility/skc-plugins/runtime-adapters.ts +234 -0
- package/src/extensibility/skc-plugins/schema.ts +250 -20
- package/src/extensibility/skc-plugins/session-validation.ts +147 -0
- package/src/extensibility/skc-plugins/types.ts +199 -3
- package/src/extensibility/skc-plugins/validation.ts +80 -0
- package/src/extensibility/skills.ts +15 -0
- package/src/goals/tools/goal-tool.ts +14 -1
- package/src/hooks/skill-state.ts +57 -0
- package/src/i18n/messages/de.ts +0 -1
- package/src/i18n/messages/en.ts +0 -1
- package/src/i18n/messages/es.ts +0 -1
- package/src/i18n/messages/fr.ts +0 -1
- package/src/i18n/messages/ja.ts +0 -1
- package/src/i18n/messages/ko.ts +0 -1
- package/src/i18n/messages/zh.ts +0 -1
- package/src/internal-urls/docs-index.generated.ts +14 -11
- package/src/main.ts +14 -3
- package/src/modes/bridge/bridge-mode.ts +11 -0
- package/src/modes/components/assistant-message.ts +49 -1
- package/src/modes/components/custom-editor.ts +2 -0
- package/src/modes/components/footer.ts +2 -3
- package/src/modes/components/hook-editor.ts +1 -1
- package/src/modes/components/hook-selector.ts +67 -43
- package/src/modes/components/model-selector.ts +65 -12
- package/src/modes/components/settings-defs.ts +1 -2
- package/src/modes/components/settings-selector.ts +2 -7
- package/src/modes/components/status-line/git-utils.ts +25 -0
- package/src/modes/components/status-line.ts +10 -11
- package/src/modes/components/welcome.ts +2 -3
- package/src/modes/controllers/extension-ui-controller.ts +0 -27
- package/src/modes/controllers/selector-controller.ts +59 -11
- package/src/modes/interactive-mode.ts +4 -1
- package/src/modes/shared/agent-wire/scopes.ts +1 -1
- package/src/modes/theme/defaults/gruvbox-dark.json +99 -0
- package/src/modes/theme/defaults/index.ts +2 -0
- package/src/modes/theme/theme.ts +0 -4
- package/src/modes/utils/hotkeys-markdown.ts +1 -1
- package/src/notifications/html-format.ts +38 -0
- package/src/notifications/index.ts +242 -12
- package/src/notifications/lifecycle-commands.ts +238 -0
- package/src/notifications/lifecycle-control-runtime.ts +405 -0
- package/src/notifications/lifecycle-orchestrator.ts +358 -0
- package/src/notifications/operator-runtime.ts +171 -0
- package/src/notifications/rate-limit-pool.ts +19 -0
- package/src/notifications/recent-activity.ts +132 -0
- package/src/notifications/telegram-daemon.ts +778 -257
- package/src/notifications/telegram-reference.ts +25 -7
- package/src/notifications/topic-registry.ts +23 -9
- package/src/prompts/agents/executor.md +2 -2
- package/src/prompts/system/system-prompt.md +2 -2
- package/src/prompts/tools/cron.md +5 -3
- package/src/prompts/tools/read.md +1 -1
- package/src/runtime-mcp/transports/stdio.ts +38 -4
- package/src/runtime-mcp/types.ts +7 -0
- package/src/sdk.ts +162 -10
- package/src/session/agent-session.ts +210 -74
- package/src/session/blob-store.ts +196 -8
- package/src/session/session-manager.ts +762 -12
- package/src/skc-runtime/launch-tmux.ts +68 -19
- package/src/skc-runtime/psmux-detect.ts +239 -0
- package/src/skc-runtime/state-renderer.ts +13 -0
- package/src/skc-runtime/team-runtime.ts +56 -23
- package/src/skc-runtime/tmux-common.ts +88 -4
- package/src/skc-runtime/tmux-sessions.ts +111 -9
- package/src/skc-runtime/ultragoal-guard.ts +192 -8
- package/src/skc-runtime/ultragoal-runtime.ts +296 -16
- package/src/slash-commands/builtin-registry.ts +23 -3
- package/src/slash-commands/helpers/fast-status-report.ts +13 -3
- package/src/slash-commands/helpers/parse.ts +2 -1
- package/src/system-prompt.ts +9 -0
- package/src/task/executor.ts +31 -7
- package/src/task/index.ts +2 -0
- package/src/tools/ask.ts +5 -1
- package/src/tools/bash.ts +9 -0
- package/src/tools/browser/tab-supervisor.ts +86 -2
- package/src/tools/composer-bash-policy.ts +96 -0
- package/src/tools/computer-gc.ts +66 -0
- package/src/tools/computer.ts +2 -0
- package/src/tools/cron.ts +75 -112
- package/src/tools/fetch.ts +18 -2
- package/src/tools/index.ts +5 -9
- package/src/tools/read.ts +25 -55
- package/src/tools/renderers.ts +0 -2
- package/src/tools/resource-gc.ts +291 -0
- package/src/tools/ultragoal-ask-guard.ts +7 -1
- package/src/utils/changelog.ts +8 -0
- package/src/web/insane/url-guard.ts +18 -14
- package/src/web/scrapers/types.ts +143 -45
- package/src/web/scrapers/utils.ts +70 -19
- package/src/web/search/index.ts +1 -0
- package/src/web/search/providers/utils.ts +22 -5
- package/vendor/insane-search/MANIFEST.json +3 -1
- package/vendor/insane-search/engine/__init__.py +14 -0
- package/vendor/insane-search/engine/content_safety.py +151 -0
- package/vendor/insane-search/engine/fetch_chain.py +32 -0
- package/vendor/insane-search/engine/tests/test_u8.py +216 -0
- package/dist/types/tools/inspect-image-renderer.d.ts +0 -26
- package/dist/types/tools/inspect-image.d.ts +0 -31
- package/src/prompts/tools/inspect-image-system.md +0 -20
- package/src/prompts/tools/inspect-image.md +0 -32
- package/src/tools/inspect-image-renderer.ts +0 -103
- package/src/tools/inspect-image.ts +0 -172
|
@@ -11,6 +11,82 @@ export interface BlobPutResult {
|
|
|
11
11
|
get ref(): string;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
export interface CheckedBlobPutResult extends BlobPutResult {
|
|
15
|
+
bytes: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class BlobCorruptError extends Error {
|
|
19
|
+
constructor(
|
|
20
|
+
readonly hash: string,
|
|
21
|
+
readonly path: string,
|
|
22
|
+
) {
|
|
23
|
+
super(`Blob ${hash} at ${path} failed SHA-256 verification`);
|
|
24
|
+
this.name = "BlobCorruptError";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function sha256Hex(data: Buffer): string {
|
|
29
|
+
return new Bun.SHA256().update(data).digest("hex");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function makeBlobPutResult(hash: string, blobPath: string): BlobPutResult;
|
|
33
|
+
function makeBlobPutResult(hash: string, blobPath: string, bytes: number): CheckedBlobPutResult;
|
|
34
|
+
function makeBlobPutResult(hash: string, blobPath: string, bytes?: number): BlobPutResult | CheckedBlobPutResult {
|
|
35
|
+
const result = {
|
|
36
|
+
hash,
|
|
37
|
+
path: blobPath,
|
|
38
|
+
get ref() {
|
|
39
|
+
return `${BLOB_PREFIX}${hash}`;
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
if (bytes === undefined) return result;
|
|
43
|
+
return { ...result, bytes };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function fsyncDirBestEffortSync(dir: string): void {
|
|
47
|
+
let fd: number | null = null;
|
|
48
|
+
try {
|
|
49
|
+
fd = fs.openSync(dir, "r");
|
|
50
|
+
fs.fsyncSync(fd);
|
|
51
|
+
} catch {
|
|
52
|
+
// Best-effort only: some platforms/filesystems do not support fsync on directories.
|
|
53
|
+
} finally {
|
|
54
|
+
if (fd !== null) fs.closeSync(fd);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Best-effort fsync of an installed blob file. Used on install paths that
|
|
60
|
+
* create the destination by copy (not hard-link from an already-fsynced temp),
|
|
61
|
+
* so the durable-install contract holds there too. Failures are best-effort:
|
|
62
|
+
* some platforms/filesystems reject fsync on read-only handles.
|
|
63
|
+
*/
|
|
64
|
+
function fsyncFileBestEffortSync(filePath: string): void {
|
|
65
|
+
let fd: number | null = null;
|
|
66
|
+
try {
|
|
67
|
+
fd = fs.openSync(filePath, "r");
|
|
68
|
+
fs.fsyncSync(fd);
|
|
69
|
+
} catch {
|
|
70
|
+
// Best-effort only.
|
|
71
|
+
} finally {
|
|
72
|
+
if (fd !== null) fs.closeSync(fd);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function uniqueTempBlobPath(dir: string, hash: string): string {
|
|
77
|
+
return path.join(dir, `${hash}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function verifyBlobBytesSync(hash: string, blobPath: string, data: Buffer): void {
|
|
81
|
+
if (sha256Hex(data) !== hash) throw new BlobCorruptError(hash, blobPath);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function verifyBlobFileSync(hash: string, blobPath: string): Buffer {
|
|
85
|
+
const data = fs.readFileSync(blobPath);
|
|
86
|
+
verifyBlobBytesSync(hash, blobPath, data);
|
|
87
|
+
return data;
|
|
88
|
+
}
|
|
89
|
+
|
|
14
90
|
/**
|
|
15
91
|
* Content-addressed blob store for externalizing large binary data (images) from session JSONL files.
|
|
16
92
|
*
|
|
@@ -60,6 +136,79 @@ export class BlobStore {
|
|
|
60
136
|
return result;
|
|
61
137
|
}
|
|
62
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Durably install binary data as an immutable content-addressed blob.
|
|
141
|
+
*
|
|
142
|
+
* Callers that persist references to this blob must mutate canonical session entries only
|
|
143
|
+
* after this method returns successfully. A corrupt pre-existing target is reported with
|
|
144
|
+
* {@link BlobCorruptError}; it is never silently overwritten or trusted.
|
|
145
|
+
*/
|
|
146
|
+
putImmutableSync(data: Buffer): CheckedBlobPutResult {
|
|
147
|
+
const hash = sha256Hex(data);
|
|
148
|
+
const blobPath = path.join(this.dir, hash);
|
|
149
|
+
const result = makeBlobPutResult(hash, blobPath, data.byteLength);
|
|
150
|
+
fs.mkdirSync(this.dir, { recursive: true });
|
|
151
|
+
|
|
152
|
+
if (fs.existsSync(blobPath)) {
|
|
153
|
+
verifyBlobFileSync(hash, blobPath);
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const tempPath = uniqueTempBlobPath(this.dir, hash);
|
|
158
|
+
try {
|
|
159
|
+
const fd = fs.openSync(tempPath, "wx");
|
|
160
|
+
try {
|
|
161
|
+
fs.writeFileSync(fd, data);
|
|
162
|
+
fs.fsyncSync(fd);
|
|
163
|
+
} finally {
|
|
164
|
+
fs.closeSync(fd);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
try {
|
|
168
|
+
fs.linkSync(tempPath, blobPath);
|
|
169
|
+
} catch (err) {
|
|
170
|
+
if (isEnoent(err)) throw err;
|
|
171
|
+
const code = typeof err === "object" && err !== null && "code" in err ? err.code : undefined;
|
|
172
|
+
if (code === "EEXIST") {
|
|
173
|
+
verifyBlobFileSync(hash, blobPath);
|
|
174
|
+
return result;
|
|
175
|
+
}
|
|
176
|
+
if (code === "EPERM" || code === "ENOTSUP" || code === "EOPNOTSUPP") {
|
|
177
|
+
// Hard links unsupported (e.g. cross-device / some network FS). Use an
|
|
178
|
+
// EXCLUSIVE copy so a concurrently installed winner is never overwritten;
|
|
179
|
+
// verify it by hash on EEXIST instead of clobbering it.
|
|
180
|
+
try {
|
|
181
|
+
fs.copyFileSync(tempPath, blobPath, fs.constants.COPYFILE_EXCL);
|
|
182
|
+
// The temp was fsync'd before install, but copyFileSync creates a
|
|
183
|
+
// fresh destination whose bytes are not yet durable — fsync it so the
|
|
184
|
+
// durable-install contract holds on hard-link-unsupported paths too.
|
|
185
|
+
fsyncFileBestEffortSync(blobPath);
|
|
186
|
+
} catch (copyErr) {
|
|
187
|
+
const copyCode =
|
|
188
|
+
typeof copyErr === "object" && copyErr !== null && "code" in copyErr ? copyErr.code : undefined;
|
|
189
|
+
if (copyCode === "EEXIST") {
|
|
190
|
+
verifyBlobFileSync(hash, blobPath);
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
throw copyErr;
|
|
194
|
+
}
|
|
195
|
+
} else {
|
|
196
|
+
throw err;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
verifyBlobFileSync(hash, blobPath);
|
|
201
|
+
fsyncDirBestEffortSync(this.dir);
|
|
202
|
+
return result;
|
|
203
|
+
} finally {
|
|
204
|
+
try {
|
|
205
|
+
fs.unlinkSync(tempPath);
|
|
206
|
+
} catch {
|
|
207
|
+
// Best-effort temp cleanup: never mask the primary result or throw.
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
63
212
|
/** Read blob by hash, returns Buffer or null if not found. */
|
|
64
213
|
async get(hash: string): Promise<Buffer | null> {
|
|
65
214
|
const blobPath = path.join(this.dir, hash);
|
|
@@ -84,6 +233,22 @@ export class BlobStore {
|
|
|
84
233
|
}
|
|
85
234
|
}
|
|
86
235
|
|
|
236
|
+
/** Read blob by hash and verify its content hash; returns null if not found. */
|
|
237
|
+
async getChecked(hash: string): Promise<Buffer | null> {
|
|
238
|
+
return this.getCheckedSync(hash);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** Synchronously read blob by hash and verify its content hash; returns null if not found. */
|
|
242
|
+
getCheckedSync(hash: string): Buffer | null {
|
|
243
|
+
const blobPath = path.join(this.dir, hash);
|
|
244
|
+
try {
|
|
245
|
+
return verifyBlobFileSync(hash, blobPath);
|
|
246
|
+
} catch (err) {
|
|
247
|
+
if (isEnoent(err)) return null;
|
|
248
|
+
throw err;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
87
252
|
/** Check if a blob exists. */
|
|
88
253
|
async has(hash: string): Promise<boolean> {
|
|
89
254
|
try {
|
|
@@ -134,6 +299,12 @@ export class EphemeralBlobStore extends BlobStore {
|
|
|
134
299
|
return result;
|
|
135
300
|
}
|
|
136
301
|
|
|
302
|
+
putImmutableSync(data: Buffer): CheckedBlobPutResult {
|
|
303
|
+
const result = super.putImmutableSync(data);
|
|
304
|
+
this.#cachePut(result.hash, Buffer.from(data));
|
|
305
|
+
return result;
|
|
306
|
+
}
|
|
307
|
+
|
|
137
308
|
getSync(hash: string): Buffer | null {
|
|
138
309
|
const cached = this.#bufferCache.get(hash);
|
|
139
310
|
if (cached) {
|
|
@@ -152,6 +323,12 @@ export class EphemeralBlobStore extends BlobStore {
|
|
|
152
323
|
return data;
|
|
153
324
|
}
|
|
154
325
|
|
|
326
|
+
getCheckedSync(hash: string): Buffer | null {
|
|
327
|
+
const data = super.getCheckedSync(hash);
|
|
328
|
+
if (data) this.#cachePut(hash, Buffer.from(data));
|
|
329
|
+
return data;
|
|
330
|
+
}
|
|
331
|
+
|
|
155
332
|
clear(): void {
|
|
156
333
|
this.#bufferCache.clear();
|
|
157
334
|
this.#bufferCacheBytes = 0;
|
|
@@ -208,15 +385,15 @@ export class MemoryBlobStore extends BlobStore {
|
|
|
208
385
|
}
|
|
209
386
|
|
|
210
387
|
putSync(data: Buffer): BlobPutResult {
|
|
211
|
-
const hash =
|
|
388
|
+
const hash = sha256Hex(data);
|
|
212
389
|
this.#store(hash, Buffer.from(data));
|
|
213
|
-
return {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
};
|
|
390
|
+
return makeBlobPutResult(hash, `memory:${hash}`);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
putImmutableSync(data: Buffer): CheckedBlobPutResult {
|
|
394
|
+
const hash = sha256Hex(data);
|
|
395
|
+
this.#store(hash, Buffer.from(data));
|
|
396
|
+
return makeBlobPutResult(hash, `memory:${hash}`, data.byteLength);
|
|
220
397
|
}
|
|
221
398
|
|
|
222
399
|
async get(hash: string): Promise<Buffer | null> {
|
|
@@ -232,6 +409,17 @@ export class MemoryBlobStore extends BlobStore {
|
|
|
232
409
|
return Buffer.from(data);
|
|
233
410
|
}
|
|
234
411
|
|
|
412
|
+
async getChecked(hash: string): Promise<Buffer | null> {
|
|
413
|
+
return this.getCheckedSync(hash);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
getCheckedSync(hash: string): Buffer | null {
|
|
417
|
+
const data = this.getSync(hash);
|
|
418
|
+
if (!data) return null;
|
|
419
|
+
verifyBlobBytesSync(hash, `memory:${hash}`, data);
|
|
420
|
+
return data;
|
|
421
|
+
}
|
|
422
|
+
|
|
235
423
|
async has(hash: string): Promise<boolean> {
|
|
236
424
|
return this.#blobs.has(hash);
|
|
237
425
|
}
|