@amalgm/shell 0.1.126 → 0.1.127
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/PURPOSE.md +17 -7
- package/dist/content-cache-host.d.ts +4 -0
- package/dist/content-cache-host.js +7 -0
- package/dist/content-cache-host.js.map +1 -1
- package/dist/user-ground-host.js +136 -33
- package/dist/user-ground-host.js.map +1 -1
- package/dist/workspace-add-staging.d.ts +98 -0
- package/dist/workspace-add-staging.js +306 -0
- package/dist/workspace-add-staging.js.map +1 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direct-to-staging content placement for Cold Add.
|
|
3
|
+
*
|
|
4
|
+
* During Cold Add each ordinary file's bytes are written once, directly into
|
|
5
|
+
* their hidden staged destination: every chunk is verified before its
|
|
6
|
+
* positioned write, the whole-file hash is proven from that same stream, the
|
|
7
|
+
* complete file is fsynced, and the workspace is revealed later by one atomic
|
|
8
|
+
* rename. A second cache copy is not part of the critical path.
|
|
9
|
+
*
|
|
10
|
+
* SQLite chunk evidence makes an interrupted staging resumable. Retained
|
|
11
|
+
* staged bytes are never trusted: every retained chunk is re-read and
|
|
12
|
+
* re-hashed against its manifest before it may satisfy the download, and the
|
|
13
|
+
* whole-file digest is proven again from that same stream.
|
|
14
|
+
*/
|
|
15
|
+
import type { ContentManifest, TransferArtifact } from "@amalgm/live";
|
|
16
|
+
import type { SealedContentFile } from "./content-cache-host.js";
|
|
17
|
+
/** The shape every download-set target satisfies, whether it stages bytes in
|
|
18
|
+
* the machine cache or directly inside a hidden Add staging root. */
|
|
19
|
+
export interface ContentDownloadTarget {
|
|
20
|
+
hasChunk(index: number): Promise<boolean>;
|
|
21
|
+
putChunk(index: number, bytes: Uint8Array): Promise<void>;
|
|
22
|
+
seal(): Promise<SealedContentFile>;
|
|
23
|
+
close(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
/** Routing one download set applies when an Add stages ordinary files
|
|
26
|
+
* directly: which content hashes land at which staged destinations, and
|
|
27
|
+
* where their durable resume evidence lives. */
|
|
28
|
+
export interface AddStagingRouting {
|
|
29
|
+
readonly evidenceDir: string;
|
|
30
|
+
readonly destinations: ReadonlyMap<string, readonly string[]>;
|
|
31
|
+
}
|
|
32
|
+
/** The device-scoped home of one workspace Add's staging resume evidence.
|
|
33
|
+
* It lives beside the ground database — never inside the staging root, which
|
|
34
|
+
* the reveal renames into user-visible ground. */
|
|
35
|
+
export declare function addStagingEvidenceDir(databasePath: string, workspaceId: string): string;
|
|
36
|
+
export declare function clearAddStagingEvidence(databasePath: string, workspaceId: string): void;
|
|
37
|
+
/** Chunk-level resume evidence for one Add's staged files. Disposable: the
|
|
38
|
+
* staged bytes are re-proven against the manifest whenever a row is used. */
|
|
39
|
+
declare class AddStagingEvidence {
|
|
40
|
+
private readonly database;
|
|
41
|
+
constructor(evidenceDir: string);
|
|
42
|
+
chunk(contentHash: string, index: number): {
|
|
43
|
+
sha256: string;
|
|
44
|
+
bytes: number;
|
|
45
|
+
} | null;
|
|
46
|
+
record(contentHash: string, index: number, sha256: string, bytes: number): void;
|
|
47
|
+
forget(contentHash: string, index: number): void;
|
|
48
|
+
close(): void;
|
|
49
|
+
}
|
|
50
|
+
/** One ordinary file downloading directly into its staged destination.
|
|
51
|
+
*
|
|
52
|
+
* Chunks may arrive in any order; each lands with a positioned write, and a
|
|
53
|
+
* serialized drain feeds the whole-file hasher strictly in chunk order — from
|
|
54
|
+
* the arriving bytes when the next expected chunk is at hand, otherwise by
|
|
55
|
+
* reading an already-written later chunk when its turn arrives. This keeps no
|
|
56
|
+
* unaccounted buffers and cannot deadlock failure settlement. Resume rereads
|
|
57
|
+
* every retained chunk by necessity so local staging can never stand in for
|
|
58
|
+
* content proof. */
|
|
59
|
+
export declare class StagedContentFile implements ContentDownloadTarget {
|
|
60
|
+
private readonly evidence;
|
|
61
|
+
readonly artifact: TransferArtifact;
|
|
62
|
+
readonly manifest: ContentManifest;
|
|
63
|
+
private readonly destinations;
|
|
64
|
+
private readonly primary;
|
|
65
|
+
private readonly offsets;
|
|
66
|
+
private readonly hasher;
|
|
67
|
+
private readonly ready;
|
|
68
|
+
private nextChunk;
|
|
69
|
+
private hashTurn;
|
|
70
|
+
private prepared;
|
|
71
|
+
private sealed;
|
|
72
|
+
constructor(evidence: AddStagingEvidence, artifact: TransferArtifact, manifest: ContentManifest, destinations: readonly string[]);
|
|
73
|
+
private prepare;
|
|
74
|
+
/** Feed the whole-file hasher every chunk that is now in order. Turns are
|
|
75
|
+
* serialized: parallel chunk arrivals only mark readiness. */
|
|
76
|
+
private queueHash;
|
|
77
|
+
/** Re-prove one retained staged chunk before it may satisfy the download.
|
|
78
|
+
* Evidence rows only say what should be there; the bytes decide. */
|
|
79
|
+
hasChunk(index: number): Promise<boolean>;
|
|
80
|
+
/** Persist one block already verified by @amalgm/live with a positioned
|
|
81
|
+
* write, then advance the streaming whole-file proof. */
|
|
82
|
+
putChunk(index: number, bytes: Uint8Array): Promise<void>;
|
|
83
|
+
/** Prove the streamed whole-file digest, fsync, and place every duplicate
|
|
84
|
+
* destination. The staged file needs no rename of its own: the whole
|
|
85
|
+
* staging root is revealed by one atomic rename after rows commit. */
|
|
86
|
+
seal(): Promise<SealedContentFile>;
|
|
87
|
+
/** Keep staged bytes and evidence for the next attempt. */
|
|
88
|
+
close(): Promise<void>;
|
|
89
|
+
}
|
|
90
|
+
/** One evidence database shared by every staged file in a download set. */
|
|
91
|
+
export declare class StagedContentSet {
|
|
92
|
+
private readonly evidence;
|
|
93
|
+
private closed;
|
|
94
|
+
constructor(evidenceDir: string);
|
|
95
|
+
target(artifact: TransferArtifact, manifest: ContentManifest, destinations: readonly string[]): StagedContentFile;
|
|
96
|
+
close(): void;
|
|
97
|
+
}
|
|
98
|
+
export {};
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direct-to-staging content placement for Cold Add.
|
|
3
|
+
*
|
|
4
|
+
* During Cold Add each ordinary file's bytes are written once, directly into
|
|
5
|
+
* their hidden staged destination: every chunk is verified before its
|
|
6
|
+
* positioned write, the whole-file hash is proven from that same stream, the
|
|
7
|
+
* complete file is fsynced, and the workspace is revealed later by one atomic
|
|
8
|
+
* rename. A second cache copy is not part of the critical path.
|
|
9
|
+
*
|
|
10
|
+
* SQLite chunk evidence makes an interrupted staging resumable. Retained
|
|
11
|
+
* staged bytes are never trusted: every retained chunk is re-read and
|
|
12
|
+
* re-hashed against its manifest before it may satisfy the download, and the
|
|
13
|
+
* whole-file digest is proven again from that same stream.
|
|
14
|
+
*/
|
|
15
|
+
import { createHash } from "node:crypto";
|
|
16
|
+
import { chmodSync, constants, rmSync } from "node:fs";
|
|
17
|
+
import { open } from "node:fs/promises";
|
|
18
|
+
import { dirname, join } from "node:path";
|
|
19
|
+
import Database from "better-sqlite3";
|
|
20
|
+
import { atomicCopy, ensurePrivateDir, ensureUserDir } from "./filesystem.js";
|
|
21
|
+
const sha256Hex = (input) => createHash("sha256").update(input).digest("hex");
|
|
22
|
+
/** The device-scoped home of one workspace Add's staging resume evidence.
|
|
23
|
+
* It lives beside the ground database — never inside the staging root, which
|
|
24
|
+
* the reveal renames into user-visible ground. */
|
|
25
|
+
export function addStagingEvidenceDir(databasePath, workspaceId) {
|
|
26
|
+
return join(dirname(databasePath), "add-staging", workspaceId);
|
|
27
|
+
}
|
|
28
|
+
export function clearAddStagingEvidence(databasePath, workspaceId) {
|
|
29
|
+
rmSync(addStagingEvidenceDir(databasePath, workspaceId), { recursive: true, force: true });
|
|
30
|
+
}
|
|
31
|
+
/** Chunk-level resume evidence for one Add's staged files. Disposable: the
|
|
32
|
+
* staged bytes are re-proven against the manifest whenever a row is used. */
|
|
33
|
+
class AddStagingEvidence {
|
|
34
|
+
database;
|
|
35
|
+
constructor(evidenceDir) {
|
|
36
|
+
ensurePrivateDir(evidenceDir);
|
|
37
|
+
this.database = new Database(join(evidenceDir, "staging.sqlite"));
|
|
38
|
+
this.database.pragma("busy_timeout = 5000");
|
|
39
|
+
this.database.pragma("journal_mode = WAL");
|
|
40
|
+
this.database.pragma("synchronous = NORMAL");
|
|
41
|
+
this.database.exec(`
|
|
42
|
+
CREATE TABLE IF NOT EXISTS staged_blocks (
|
|
43
|
+
content_hash TEXT NOT NULL,
|
|
44
|
+
block_index INTEGER NOT NULL,
|
|
45
|
+
sha256 TEXT NOT NULL,
|
|
46
|
+
bytes INTEGER NOT NULL,
|
|
47
|
+
PRIMARY KEY (content_hash, block_index)
|
|
48
|
+
);
|
|
49
|
+
`);
|
|
50
|
+
}
|
|
51
|
+
chunk(contentHash, index) {
|
|
52
|
+
const row = this.database.prepare(`
|
|
53
|
+
SELECT sha256, bytes FROM staged_blocks WHERE content_hash = ? AND block_index = ?
|
|
54
|
+
`).get(contentHash, index);
|
|
55
|
+
return row ?? null;
|
|
56
|
+
}
|
|
57
|
+
record(contentHash, index, sha256, bytes) {
|
|
58
|
+
this.database.prepare(`
|
|
59
|
+
INSERT INTO staged_blocks (content_hash, block_index, sha256, bytes)
|
|
60
|
+
VALUES (?, ?, ?, ?)
|
|
61
|
+
ON CONFLICT (content_hash, block_index) DO UPDATE SET
|
|
62
|
+
sha256 = excluded.sha256,
|
|
63
|
+
bytes = excluded.bytes
|
|
64
|
+
`).run(contentHash, index, sha256, bytes);
|
|
65
|
+
}
|
|
66
|
+
forget(contentHash, index) {
|
|
67
|
+
this.database.prepare(`
|
|
68
|
+
DELETE FROM staged_blocks WHERE content_hash = ? AND block_index = ?
|
|
69
|
+
`).run(contentHash, index);
|
|
70
|
+
}
|
|
71
|
+
close() {
|
|
72
|
+
this.database.close();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function readFileRange(file, offset, bytes) {
|
|
76
|
+
const handle = await openRegularFile(file, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
77
|
+
const output = Buffer.allocUnsafe(bytes);
|
|
78
|
+
try {
|
|
79
|
+
let cursor = 0;
|
|
80
|
+
while (cursor < bytes) {
|
|
81
|
+
const result = await handle.read(output, cursor, bytes - cursor, offset + cursor);
|
|
82
|
+
if (result.bytesRead === 0)
|
|
83
|
+
throw new Error("staged content range is truncated");
|
|
84
|
+
cursor += result.bytesRead;
|
|
85
|
+
}
|
|
86
|
+
return output;
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
await handle.close();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function writeFileRange(file, offset, bytes) {
|
|
93
|
+
const handle = await openRegularFile(file, constants.O_RDWR | constants.O_NOFOLLOW);
|
|
94
|
+
try {
|
|
95
|
+
let cursor = 0;
|
|
96
|
+
while (cursor < bytes.byteLength) {
|
|
97
|
+
const result = await handle.write(bytes, cursor, bytes.byteLength - cursor, offset + cursor);
|
|
98
|
+
if (result.bytesWritten === 0)
|
|
99
|
+
throw new Error("staged content write made no progress");
|
|
100
|
+
cursor += result.bytesWritten;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
await handle.close();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async function fsyncFile(file) {
|
|
108
|
+
const handle = await openRegularFile(file, constants.O_RDWR | constants.O_NOFOLLOW);
|
|
109
|
+
try {
|
|
110
|
+
await handle.sync();
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
await handle.close();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/** Open only the regular file named at this exact path. Retained staging is
|
|
117
|
+
* untrusted until re-proven, so neither a stale symlink nor a special file may
|
|
118
|
+
* redirect Add's reads, writes, truncation, or durability boundary. */
|
|
119
|
+
async function openRegularFile(file, flags, mode) {
|
|
120
|
+
const handle = await open(file, flags, mode);
|
|
121
|
+
try {
|
|
122
|
+
if (!(await handle.stat()).isFile()) {
|
|
123
|
+
throw new Error(`staged content is not a regular file: ${file}`);
|
|
124
|
+
}
|
|
125
|
+
return handle;
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
await handle.close();
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/** One ordinary file downloading directly into its staged destination.
|
|
133
|
+
*
|
|
134
|
+
* Chunks may arrive in any order; each lands with a positioned write, and a
|
|
135
|
+
* serialized drain feeds the whole-file hasher strictly in chunk order — from
|
|
136
|
+
* the arriving bytes when the next expected chunk is at hand, otherwise by
|
|
137
|
+
* reading an already-written later chunk when its turn arrives. This keeps no
|
|
138
|
+
* unaccounted buffers and cannot deadlock failure settlement. Resume rereads
|
|
139
|
+
* every retained chunk by necessity so local staging can never stand in for
|
|
140
|
+
* content proof. */
|
|
141
|
+
export class StagedContentFile {
|
|
142
|
+
evidence;
|
|
143
|
+
artifact;
|
|
144
|
+
manifest;
|
|
145
|
+
destinations;
|
|
146
|
+
primary;
|
|
147
|
+
offsets;
|
|
148
|
+
hasher = createHash("sha256");
|
|
149
|
+
ready = new Set();
|
|
150
|
+
nextChunk = 0;
|
|
151
|
+
hashTurn = Promise.resolve();
|
|
152
|
+
prepared = null;
|
|
153
|
+
sealed = false;
|
|
154
|
+
constructor(evidence, artifact, manifest, destinations) {
|
|
155
|
+
this.evidence = evidence;
|
|
156
|
+
this.artifact = artifact;
|
|
157
|
+
this.manifest = manifest;
|
|
158
|
+
this.destinations = destinations;
|
|
159
|
+
if (destinations.length === 0)
|
|
160
|
+
throw new Error("staged content has no destination");
|
|
161
|
+
this.primary = destinations[0];
|
|
162
|
+
let offset = 0;
|
|
163
|
+
this.offsets = manifest.chunks.map((chunk) => {
|
|
164
|
+
const result = offset;
|
|
165
|
+
offset += chunk.bytes;
|
|
166
|
+
return result;
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
prepare() {
|
|
170
|
+
if (!this.prepared) {
|
|
171
|
+
this.prepared = (async () => {
|
|
172
|
+
ensureUserDir(dirname(this.primary));
|
|
173
|
+
let handle;
|
|
174
|
+
try {
|
|
175
|
+
handle = await openRegularFile(this.primary, constants.O_RDWR | constants.O_NOFOLLOW);
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
if (error.code !== "ENOENT")
|
|
179
|
+
throw error;
|
|
180
|
+
handle = await openRegularFile(this.primary, constants.O_RDWR | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o644);
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
await handle.truncate(this.manifest.bytes);
|
|
184
|
+
}
|
|
185
|
+
finally {
|
|
186
|
+
await handle.close();
|
|
187
|
+
}
|
|
188
|
+
})();
|
|
189
|
+
}
|
|
190
|
+
return this.prepared;
|
|
191
|
+
}
|
|
192
|
+
/** Feed the whole-file hasher every chunk that is now in order. Turns are
|
|
193
|
+
* serialized: parallel chunk arrivals only mark readiness. */
|
|
194
|
+
queueHash(arrived, arrivedBytes) {
|
|
195
|
+
const turn = this.hashTurn.then(async () => {
|
|
196
|
+
this.ready.add(arrived);
|
|
197
|
+
while (this.ready.has(this.nextChunk)) {
|
|
198
|
+
const index = this.nextChunk;
|
|
199
|
+
const chunk = this.manifest.chunks[index];
|
|
200
|
+
const offset = this.offsets[index];
|
|
201
|
+
if (!chunk || offset === undefined)
|
|
202
|
+
throw new Error(`content manifest has no chunk ${index}`);
|
|
203
|
+
const bytes = index === arrived
|
|
204
|
+
? arrivedBytes
|
|
205
|
+
: await readFileRange(this.primary, offset, chunk.bytes);
|
|
206
|
+
this.hasher.update(bytes);
|
|
207
|
+
this.ready.delete(index);
|
|
208
|
+
this.nextChunk += 1;
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
// A failed turn already rejected its own caller; keep the chain usable so
|
|
212
|
+
// later chunks fail on their own evidence, not on a poisoned chain.
|
|
213
|
+
this.hashTurn = turn.catch(() => { });
|
|
214
|
+
return turn;
|
|
215
|
+
}
|
|
216
|
+
/** Re-prove one retained staged chunk before it may satisfy the download.
|
|
217
|
+
* Evidence rows only say what should be there; the bytes decide. */
|
|
218
|
+
async hasChunk(index) {
|
|
219
|
+
const expected = this.manifest.chunks[index];
|
|
220
|
+
const offset = this.offsets[index];
|
|
221
|
+
if (!expected || offset === undefined)
|
|
222
|
+
throw new Error(`content manifest has no chunk ${index}`);
|
|
223
|
+
const retained = this.evidence.chunk(this.artifact.contentHash, index);
|
|
224
|
+
if (retained?.sha256 === expected.sha256 && retained.bytes === expected.bytes) {
|
|
225
|
+
try {
|
|
226
|
+
const bytes = await readFileRange(this.primary, offset, expected.bytes);
|
|
227
|
+
if (sha256Hex(bytes) === expected.sha256) {
|
|
228
|
+
await this.queueHash(index, bytes);
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
// The staged bytes disappeared or shrank after their evidence row.
|
|
234
|
+
}
|
|
235
|
+
this.evidence.forget(this.artifact.contentHash, index);
|
|
236
|
+
}
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
/** Persist one block already verified by @amalgm/live with a positioned
|
|
240
|
+
* write, then advance the streaming whole-file proof. */
|
|
241
|
+
async putChunk(index, bytes) {
|
|
242
|
+
const expected = this.manifest.chunks[index];
|
|
243
|
+
const offset = this.offsets[index];
|
|
244
|
+
if (!expected || offset === undefined)
|
|
245
|
+
throw new Error(`content manifest has no chunk ${index}`);
|
|
246
|
+
if (bytes.byteLength !== expected.bytes)
|
|
247
|
+
throw new Error("content block byte count is invalid");
|
|
248
|
+
await this.prepare();
|
|
249
|
+
await writeFileRange(this.primary, offset, bytes);
|
|
250
|
+
this.evidence.record(this.artifact.contentHash, index, expected.sha256, expected.bytes);
|
|
251
|
+
await this.queueHash(index, bytes);
|
|
252
|
+
}
|
|
253
|
+
/** Prove the streamed whole-file digest, fsync, and place every duplicate
|
|
254
|
+
* destination. The staged file needs no rename of its own: the whole
|
|
255
|
+
* staging root is revealed by one atomic rename after rows commit. */
|
|
256
|
+
async seal() {
|
|
257
|
+
if (this.sealed)
|
|
258
|
+
throw new Error("staged artifact is already sealed");
|
|
259
|
+
this.sealed = true;
|
|
260
|
+
await this.prepare();
|
|
261
|
+
await this.hashTurn;
|
|
262
|
+
if (this.nextChunk !== this.manifest.chunks.length) {
|
|
263
|
+
throw new Error(`cloud content ${this.manifest.contentHash} did not stream every chunk`);
|
|
264
|
+
}
|
|
265
|
+
if (this.hasher.digest("hex") !== this.manifest.contentHash) {
|
|
266
|
+
throw new Error(`cloud content ${this.manifest.contentHash} is corrupt`);
|
|
267
|
+
}
|
|
268
|
+
await fsyncFile(this.primary);
|
|
269
|
+
chmodSync(this.primary, 0o644);
|
|
270
|
+
for (const duplicate of this.destinations.slice(1)) {
|
|
271
|
+
ensureUserDir(dirname(duplicate));
|
|
272
|
+
atomicCopy(this.primary, duplicate, 0o644);
|
|
273
|
+
await fsyncFile(duplicate);
|
|
274
|
+
}
|
|
275
|
+
return {
|
|
276
|
+
file: this.primary,
|
|
277
|
+
bytes: this.manifest.bytes,
|
|
278
|
+
contentHash: this.manifest.contentHash,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
/** Keep staged bytes and evidence for the next attempt. */
|
|
282
|
+
async close() {
|
|
283
|
+
if (this.prepared)
|
|
284
|
+
await this.prepared.catch(() => { });
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/** One evidence database shared by every staged file in a download set. */
|
|
288
|
+
export class StagedContentSet {
|
|
289
|
+
evidence;
|
|
290
|
+
closed = false;
|
|
291
|
+
constructor(evidenceDir) {
|
|
292
|
+
this.evidence = new AddStagingEvidence(evidenceDir);
|
|
293
|
+
}
|
|
294
|
+
target(artifact, manifest, destinations) {
|
|
295
|
+
if (this.closed)
|
|
296
|
+
throw new Error("staged content set is closed");
|
|
297
|
+
return new StagedContentFile(this.evidence, artifact, manifest, destinations);
|
|
298
|
+
}
|
|
299
|
+
close() {
|
|
300
|
+
if (this.closed)
|
|
301
|
+
return;
|
|
302
|
+
this.closed = true;
|
|
303
|
+
this.evidence.close();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
//# sourceMappingURL=workspace-add-staging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-add-staging.js","sourceRoot":"","sources":["../src/workspace-add-staging.ts"],"names":[],"mappings":"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"}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amalgm/shell",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.127",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@amalgm/shell",
|
|
9
|
-
"version": "0.1.
|
|
9
|
+
"version": "0.1.127",
|
|
10
10
|
"license": "UNLICENSED",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@amalgm/agents": "0.2.0",
|