@parall/daemon 1.31.0 → 1.32.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 (52) hide show
  1. package/bundle/manifest.json +16 -11
  2. package/bundle/package.json +1 -0
  3. package/bundle/parall-claude-agent.js +27556 -339
  4. package/bundle/parall-codex-agent.js +27603 -372
  5. package/bundle/parall-daemon.js +30204 -1760
  6. package/bundle/parall-openclaw-agent.js +49 -24
  7. package/dist/cli.d.ts +1 -1
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +83 -83
  10. package/dist/clip-runtime/clip-installer.d.ts +44 -0
  11. package/dist/clip-runtime/clip-installer.d.ts.map +1 -0
  12. package/dist/clip-runtime/clip-installer.js +501 -0
  13. package/dist/clip-runtime/clip-provider.d.ts +76 -0
  14. package/dist/clip-runtime/clip-provider.d.ts.map +1 -0
  15. package/dist/clip-runtime/clip-provider.js +402 -0
  16. package/dist/clip-runtime/index.d.ts +7 -0
  17. package/dist/clip-runtime/index.d.ts.map +1 -0
  18. package/dist/clip-runtime/index.js +5 -0
  19. package/dist/clip-runtime/ipc.d.ts +94 -0
  20. package/dist/clip-runtime/ipc.d.ts.map +1 -0
  21. package/dist/clip-runtime/ipc.js +98 -0
  22. package/dist/clip-runtime/manifest.d.ts +74 -0
  23. package/dist/clip-runtime/manifest.d.ts.map +1 -0
  24. package/dist/clip-runtime/manifest.js +181 -0
  25. package/dist/clip-runtime/process-manager.d.ts +57 -0
  26. package/dist/clip-runtime/process-manager.d.ts.map +1 -0
  27. package/dist/clip-runtime/process-manager.js +354 -0
  28. package/dist/clip-runtime/process.d.ts +59 -0
  29. package/dist/clip-runtime/process.d.ts.map +1 -0
  30. package/dist/clip-runtime/process.js +350 -0
  31. package/dist/config.d.ts.map +1 -1
  32. package/dist/config.js +24 -24
  33. package/dist/filesystem.d.ts +1 -1
  34. package/dist/filesystem.d.ts.map +1 -1
  35. package/dist/filesystem.js +51 -53
  36. package/dist/index.js +20 -15
  37. package/dist/runtimes.d.ts +3 -2
  38. package/dist/runtimes.d.ts.map +1 -1
  39. package/dist/runtimes.js +24 -20
  40. package/dist/supervisor.d.ts +9 -4
  41. package/dist/supervisor.d.ts.map +1 -1
  42. package/dist/supervisor.js +244 -76
  43. package/dist/updater-manifest.d.ts +2 -0
  44. package/dist/updater-manifest.d.ts.map +1 -1
  45. package/dist/updater-manifest.js +6 -6
  46. package/dist/updater.d.ts +2 -2
  47. package/dist/updater.d.ts.map +1 -1
  48. package/dist/updater.js +55 -37
  49. package/dist/workspace.d.ts +2 -2
  50. package/dist/workspace.d.ts.map +1 -1
  51. package/dist/workspace.js +112 -112
  52. package/package.json +6 -6
@@ -1,4 +1,4 @@
1
- import { verify } from "node:crypto";
1
+ import { verify } from 'node:crypto';
2
2
  /**
3
3
  * Recursively sort all object keys at every depth for deterministic JSON output.
4
4
  * Arrays preserve order; primitives pass through.
@@ -6,7 +6,7 @@ import { verify } from "node:crypto";
6
6
  export function canonicalize(obj) {
7
7
  if (Array.isArray(obj))
8
8
  return obj.map(canonicalize);
9
- if (obj !== null && typeof obj === "object") {
9
+ if (obj !== null && typeof obj === 'object') {
10
10
  const sorted = {};
11
11
  for (const k of Object.keys(obj).sort()) {
12
12
  sorted[k] = canonicalize(obj[k]);
@@ -23,7 +23,7 @@ export function verifyManifestSignature(manifest, publicKey) {
23
23
  const { signature, ...rest } = manifest;
24
24
  const canonical = JSON.stringify(canonicalize(rest));
25
25
  try {
26
- return verify(null, Buffer.from(canonical), publicKey, Buffer.from(signature, "base64"));
26
+ return verify(null, Buffer.from(canonical), publicKey, Buffer.from(signature, 'base64'));
27
27
  }
28
28
  catch {
29
29
  return false;
@@ -69,15 +69,15 @@ export function semverCompare(a, b) {
69
69
  function parseSemver(v) {
70
70
  // Split off prerelease at the first hyphen in the patch component.
71
71
  // e.g. "0.0.0-staging.abc1234" → major=0, minor=0, patch="0", pre="staging.abc1234"
72
- const parts = v.split(".");
72
+ const parts = v.split('.');
73
73
  if (parts.length < 3)
74
74
  return null;
75
75
  // Rejoin any dots beyond the first two (prerelease may contain dots)
76
76
  const major = Number(parts[0]);
77
77
  const minor = Number(parts[1]);
78
- const rest = parts.slice(2).join(".");
78
+ const rest = parts.slice(2).join('.');
79
79
  // Split patch from prerelease: "0-staging.abc" → patch="0", pre="staging.abc"
80
- const hyphen = rest.indexOf("-");
80
+ const hyphen = rest.indexOf('-');
81
81
  let patchStr;
82
82
  let pre;
83
83
  if (hyphen >= 0) {
package/dist/updater.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import type { GatewayLogger } from "@parall/agent-core";
2
- import { type LocalManifest } from "./updater-manifest.js";
1
+ import type { GatewayLogger } from '@parall/agent-core';
2
+ import { type LocalManifest } from './updater-manifest.js';
3
3
  export declare class DaemonUpdater {
4
4
  private readonly bundleDir;
5
5
  private readonly cdnBaseUrl;
@@ -1 +1 @@
1
- {"version":3,"file":"updater.d.ts","sourceRoot":"","sources":["../src/updater.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAEL,KAAK,aAAa,EAGnB,MAAM,uBAAuB,CAAC;AAoB/B,qBAAa,aAAa;IAKtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAPjC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAA+B;gBAGjC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,aAAa,EAClB,cAAc,EAAE,OAAO;IAK1C;;OAEG;IACH,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAU5C,iBAAiB,IAAI,IAAI;IAOzB;;;OAGG;IACG,aAAa,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAa7D;;OAEG;IACG,aAAa,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAQhF;;;;OAIG;IACH,aAAa,IAAI,OAAO;IA6CxB;;;OAGG;IACH,cAAc,IAAI,IAAI;IAYtB;;OAEG;IACH,eAAe,IAAI,MAAM,GAAG,SAAS;IAIrC;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;YAmB1F,QAAQ;IAqGtB,OAAO,CAAC,UAAU;IAmClB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,gBAAgB;IAmBxB,iBAAiB,IAAI,aAAa,GAAG,IAAI;IAUzC,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,OAAO;IA8Bf,OAAO,CAAC,YAAY;IAoCpB,OAAO,CAAC,QAAQ;CAKjB"}
1
+ {"version":3,"file":"updater.d.ts","sourceRoot":"","sources":["../src/updater.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAEL,KAAK,aAAa,EAGnB,MAAM,uBAAuB,CAAC;AAsB/B,qBAAa,aAAa;IAKtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAPjC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAA+B;gBAGjC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,aAAa,EAClB,cAAc,EAAE,OAAO;IAK1C;;OAEG;IACH,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAU5C,iBAAiB,IAAI,IAAI;IAOzB;;;OAGG;IACG,aAAa,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAa7D;;OAEG;IACG,aAAa,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAQhF;;;;OAIG;IACH,aAAa,IAAI,OAAO;IA6CxB;;;OAGG;IACH,cAAc,IAAI,IAAI;IAYtB;;OAEG;IACH,eAAe,IAAI,MAAM,GAAG,SAAS;IAIrC;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC;QAC9B,SAAS,EAAE,OAAO,CAAC;QACnB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;YAuBY,QAAQ;IA4HtB,OAAO,CAAC,UAAU;IAmClB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,gBAAgB;IAmBxB,iBAAiB,IAAI,aAAa,GAAG,IAAI;IAUzC,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,OAAO;IA8Bf,OAAO,CAAC,YAAY;IAoCpB,OAAO,CAAC,QAAQ;CAKjB"}
package/dist/updater.js CHANGED
@@ -1,14 +1,16 @@
1
- import * as fs from "node:fs";
2
- import * as path from "node:path";
3
- import * as https from "node:https";
4
- import * as http from "node:http";
5
- import { createHash } from "node:crypto";
6
- import { verifyManifestSignature, semverCompare, } from "./updater-manifest.js";
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as https from 'node:https';
4
+ import * as http from 'node:http';
5
+ import { createHash } from 'node:crypto';
6
+ import { verifyManifestSignature, semverCompare, } from './updater-manifest.js';
7
7
  const UPDATE_EXIT_CODE = 42;
8
8
  // Ed25519 public key for verifying daemon bundle manifests.
9
9
  // The corresponding private key lives in GitHub Actions secrets (DAEMON_BUNDLE_SIGNING_KEY).
10
- // Placeholder replaced with the real key when the CI signing pipeline is set up.
11
- const SIGNING_PUBLIC_KEY = process.env.PRLL_DAEMON_SIGNING_PUBLIC_KEY ?? "";
10
+ const DEFAULT_SIGNING_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
11
+ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
12
+ -----END PUBLIC KEY-----`;
13
+ const SIGNING_PUBLIC_KEY = process.env.PRLL_DAEMON_SIGNING_PUBLIC_KEY || DEFAULT_SIGNING_PUBLIC_KEY;
12
14
  export class DaemonUpdater {
13
15
  bundleDir;
14
16
  cdnBaseUrl;
@@ -89,13 +91,13 @@ export class DaemonUpdater {
89
91
  return false;
90
92
  if (!state.previous_version)
91
93
  return false;
92
- const previousDir = path.join(this.bundleDir, "versions", state.previous_version);
94
+ const previousDir = path.join(this.bundleDir, 'versions', state.previous_version);
93
95
  if (!fs.existsSync(previousDir))
94
96
  return false;
95
97
  this.log.warn(`rollback: ${current.version} failed ${state.boot_count} boots, reverting to ${state.previous_version}`);
96
- if (process.platform === "win32") {
98
+ if (process.platform === 'win32') {
97
99
  // Windows: copy previous version files into current dir (no symlinks)
98
- const currentDir = path.join(this.bundleDir, "current");
100
+ const currentDir = path.join(this.bundleDir, 'current');
99
101
  if (fs.existsSync(currentDir)) {
100
102
  for (const file of fs.readdirSync(currentDir)) {
101
103
  fs.unlinkSync(path.join(currentDir, file));
@@ -152,7 +154,11 @@ export class DaemonUpdater {
152
154
  const current = local?.version;
153
155
  if (current) {
154
156
  const cmp = semverCompare(remote.version, current);
155
- return { available: cmp !== null && cmp > 0, currentVersion: current, remoteVersion: remote.version };
157
+ return {
158
+ available: cmp !== null && cmp > 0,
159
+ currentVersion: current,
160
+ remoteVersion: remote.version,
161
+ };
156
162
  }
157
163
  return { available: true, remoteVersion: remote.version };
158
164
  }
@@ -179,7 +185,7 @@ export class DaemonUpdater {
179
185
  remote = JSON.parse(remoteJson);
180
186
  }
181
187
  catch {
182
- this.log.warn("update: failed to parse remote manifest");
188
+ this.log.warn('update: failed to parse remote manifest');
183
189
  return false;
184
190
  }
185
191
  // Reject same or older versions (downgrade protection)
@@ -197,7 +203,7 @@ export class DaemonUpdater {
197
203
  // Verify Ed25519 signature (fail-closed: reject when key is missing)
198
204
  if (this.signingEnabled) {
199
205
  if (!SIGNING_PUBLIC_KEY) {
200
- this.log.error("update: signing enabled but PRLL_DAEMON_SIGNING_PUBLIC_KEY is empty — rejecting update");
206
+ this.log.error('update: signing enabled but PRLL_DAEMON_SIGNING_PUBLIC_KEY is empty — rejecting update');
201
207
  return false;
202
208
  }
203
209
  if (!verifyManifestSignature(remote, SIGNING_PUBLIC_KEY)) {
@@ -205,8 +211,20 @@ export class DaemonUpdater {
205
211
  return false;
206
212
  }
207
213
  }
214
+ // Check Node.js version compatibility (fail-closed: reject on unparseable versions)
215
+ if (remote.min_node_version) {
216
+ const cmp = semverCompare(process.versions.node, remote.min_node_version);
217
+ if (cmp === null) {
218
+ this.log.warn(`update: invalid min_node_version "${remote.min_node_version}" in manifest for ${remote.version} — skipping`);
219
+ return false;
220
+ }
221
+ if (cmp < 0) {
222
+ this.log.warn(`update: ${remote.version} requires Node >= ${remote.min_node_version}, running ${process.versions.node} — skipping`);
223
+ return false;
224
+ }
225
+ }
208
226
  // Download all files to staging directory
209
- const stagingDir = path.join(this.bundleDir, "staging");
227
+ const stagingDir = path.join(this.bundleDir, 'staging');
210
228
  this.cleanDir(stagingDir);
211
229
  fs.mkdirSync(stagingDir, { recursive: true });
212
230
  for (const [filename, meta] of Object.entries(remote.files)) {
@@ -222,7 +240,7 @@ export class DaemonUpdater {
222
240
  }
223
241
  // Verify sha256
224
242
  const content = fs.readFileSync(filePath);
225
- const hash = createHash("sha256").update(content).digest("hex");
243
+ const hash = createHash('sha256').update(content).digest('hex');
226
244
  if (hash !== meta.sha256) {
227
245
  this.log.error(`update: sha256 mismatch for ${filename} (expected ${meta.sha256}, got ${hash})`);
228
246
  this.cleanDir(stagingDir);
@@ -236,7 +254,7 @@ export class DaemonUpdater {
236
254
  }
237
255
  }
238
256
  // Write manifest to staging
239
- fs.writeFileSync(path.join(stagingDir, "manifest.json"), JSON.stringify(remote, null, 2));
257
+ fs.writeFileSync(path.join(stagingDir, 'manifest.json'), JSON.stringify(remote, null, 2));
240
258
  // Atomic swap
241
259
  this.atomicSwap(stagingDir, remote.version);
242
260
  // Record pending update state
@@ -248,20 +266,20 @@ export class DaemonUpdater {
248
266
  boot_count: 0,
249
267
  };
250
268
  this.saveUpdateState(newState);
251
- this.log.info(`update: ${local?.version ?? "unknown"} → ${remote.version} applied, restarting`);
269
+ this.log.info(`update: ${local?.version ?? 'unknown'} → ${remote.version} applied, restarting`);
252
270
  return true;
253
271
  }
254
272
  atomicSwap(stagingDir, newVersion) {
255
- const versionsDir = path.join(this.bundleDir, "versions");
273
+ const versionsDir = path.join(this.bundleDir, 'versions');
256
274
  const targetDir = path.join(versionsDir, newVersion);
257
- const currentLink = path.join(this.bundleDir, "current");
275
+ const currentLink = path.join(this.bundleDir, 'current');
258
276
  fs.mkdirSync(versionsDir, { recursive: true });
259
277
  // If target version dir already exists (partial previous attempt), remove it
260
278
  if (fs.existsSync(targetDir)) {
261
279
  fs.rmSync(targetDir, { recursive: true });
262
280
  }
263
281
  fs.renameSync(stagingDir, targetDir);
264
- if (process.platform === "win32") {
282
+ if (process.platform === 'win32') {
265
283
  // Windows: JS files aren't locked, copy directly.
266
284
  // Clean old files first to avoid stale artifacts from previous versions.
267
285
  const currentDir = currentLink;
@@ -283,7 +301,7 @@ export class DaemonUpdater {
283
301
  this.pruneOldVersions(versionsDir, newVersion);
284
302
  }
285
303
  swapSymlink(version) {
286
- const currentLink = path.join(this.bundleDir, "current");
304
+ const currentLink = path.join(this.bundleDir, 'current');
287
305
  const tmpLink = `${currentLink}.new`;
288
306
  try {
289
307
  fs.unlinkSync(tmpLink);
@@ -312,33 +330,33 @@ export class DaemonUpdater {
312
330
  }
313
331
  // --- Manifest & State I/O ---
314
332
  loadLocalManifest() {
315
- const currentDir = path.join(this.bundleDir, "current");
316
- const manifestPath = path.join(currentDir, "manifest.json");
333
+ const currentDir = path.join(this.bundleDir, 'current');
334
+ const manifestPath = path.join(currentDir, 'manifest.json');
317
335
  try {
318
- return JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
336
+ return JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
319
337
  }
320
338
  catch {
321
339
  return null;
322
340
  }
323
341
  }
324
342
  loadUpdateState() {
325
- const statePath = path.join(this.bundleDir, "update-state.json");
343
+ const statePath = path.join(this.bundleDir, 'update-state.json');
326
344
  try {
327
- return JSON.parse(fs.readFileSync(statePath, "utf-8"));
345
+ return JSON.parse(fs.readFileSync(statePath, 'utf-8'));
328
346
  }
329
347
  catch {
330
348
  return null;
331
349
  }
332
350
  }
333
351
  saveUpdateState(state) {
334
- const statePath = path.join(this.bundleDir, "update-state.json");
352
+ const statePath = path.join(this.bundleDir, 'update-state.json');
335
353
  fs.mkdirSync(path.dirname(statePath), { recursive: true });
336
354
  fs.writeFileSync(statePath, JSON.stringify(state, null, 2));
337
355
  }
338
356
  // --- HTTP helpers ---
339
357
  httpGet(url, maxRedirects = 5) {
340
358
  return new Promise((resolve, reject) => {
341
- const mod = url.startsWith("https") ? https : http;
359
+ const mod = url.startsWith('https') ? https : http;
342
360
  const req = mod.get(url, (res) => {
343
361
  if (res.statusCode === 301 || res.statusCode === 302) {
344
362
  if (res.headers.location && maxRedirects > 0) {
@@ -355,11 +373,11 @@ export class DaemonUpdater {
355
373
  return;
356
374
  }
357
375
  const chunks = [];
358
- res.on("data", (chunk) => chunks.push(chunk));
359
- res.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8")));
360
- res.on("error", reject);
376
+ res.on('data', (chunk) => chunks.push(chunk));
377
+ res.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
378
+ res.on('error', reject);
361
379
  });
362
- req.on("error", reject);
380
+ req.on('error', reject);
363
381
  req.setTimeout(30_000, () => {
364
382
  req.destroy(new Error(`timeout fetching ${url}`));
365
383
  });
@@ -367,7 +385,7 @@ export class DaemonUpdater {
367
385
  }
368
386
  downloadFile(url, dest, maxRedirects = 5) {
369
387
  return new Promise((resolve, reject) => {
370
- const mod = url.startsWith("https") ? https : http;
388
+ const mod = url.startsWith('https') ? https : http;
371
389
  const req = mod.get(url, (res) => {
372
390
  if (res.statusCode === 301 || res.statusCode === 302) {
373
391
  if (res.headers.location && maxRedirects > 0) {
@@ -385,16 +403,16 @@ export class DaemonUpdater {
385
403
  }
386
404
  const file = fs.createWriteStream(dest);
387
405
  res.pipe(file);
388
- file.on("finish", () => {
406
+ file.on('finish', () => {
389
407
  file.close();
390
408
  resolve();
391
409
  });
392
- file.on("error", (err) => {
410
+ file.on('error', (err) => {
393
411
  fs.unlinkSync(dest);
394
412
  reject(err);
395
413
  });
396
414
  });
397
- req.on("error", reject);
415
+ req.on('error', reject);
398
416
  req.setTimeout(120_000, () => {
399
417
  req.destroy(new Error(`timeout downloading ${url}`));
400
418
  });
@@ -1,5 +1,5 @@
1
- import type { GatewayLogger } from "@parall/agent-core";
2
- import type { AttachedAgent, ParallClient } from "@parall/sdk";
1
+ import type { GatewayLogger } from '@parall/agent-core';
2
+ import type { AttachedAgent, ParallClient } from '@parall/sdk';
3
3
  export interface PrepareWorkspaceOpts {
4
4
  client: ParallClient;
5
5
  attached: AttachedAgent;
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAA4C,YAAY,EAAE,MAAM,aAAa,CAAC;AAiBzG,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,GAAG,EAAE,aAAa,CAAC;CACpB;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8ClF"}
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EACV,aAAa,EAGb,YAAY,EACb,MAAM,aAAa,CAAC;AAkBrB,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,GAAG,EAAE,aAAa,CAAC;CACpB;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyDlF"}