paseo-plugin-zcode-provider 0.1.0 → 0.2.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/NOTICE.md +1 -1
- package/README.md +20 -6
- package/client/account.tsx +827 -0
- package/client/diagnostics.tsx +2 -20
- package/client/{setup.tsx → runtime.tsx} +3 -54
- package/client/settings.tsx +84 -0
- package/client/value.tsx +20 -0
- package/index.client.tsx +7 -7
- package/index.server.ts +20 -2
- package/package.json +6 -4
- package/server/account.ts +781 -0
- package/server/build-info.ts +1 -1
- package/server/diagnostics.ts +17 -0
- package/server/discovery/discover.ts +1 -1
- package/server/discovery/manifest.ts +1 -1
- package/server/host/bridge.ts +49 -22
- package/server/presentation.ts +48 -6
- package/server/provider-status.ts +81 -0
- package/server/provider.ts +10 -3
- package/server/runtime-setup.ts +4 -29
- package/server/usage.ts +362 -0
- package/shared/account.ts +201 -0
- package/shared/runtime-setup.ts +0 -2
package/server/build-info.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated from package.json by npm prepare / prebuild.
|
|
2
|
-
export const PROVIDER_VERSION = "0.
|
|
2
|
+
export const PROVIDER_VERSION = "0.2.0";
|
package/server/diagnostics.ts
CHANGED
|
@@ -62,6 +62,23 @@ const operations = new Set([
|
|
|
62
62
|
"attachmentChunkV4",
|
|
63
63
|
"attachmentCommitV4",
|
|
64
64
|
"attachmentAbortV4",
|
|
65
|
+
"oauth.restoreCachedSessionState",
|
|
66
|
+
"oauth.getActiveProvider",
|
|
67
|
+
"oauth.startOAuthWithPolling",
|
|
68
|
+
"oauth.pollPendingOAuth",
|
|
69
|
+
"oauth.cancelPending",
|
|
70
|
+
"oauth.logout",
|
|
71
|
+
"setting.get",
|
|
72
|
+
"setting.update",
|
|
73
|
+
"provider-settings.getView",
|
|
74
|
+
"provider-settings.refresh",
|
|
75
|
+
"provider-settings.createPersonalProvider",
|
|
76
|
+
"provider-settings.savePersonalProviderOverlay",
|
|
77
|
+
"provider-settings.deletePersonalProvider",
|
|
78
|
+
"provider-settings.addPersonalModel",
|
|
79
|
+
"provider-settings.deletePersonalModel",
|
|
80
|
+
"provider-settings.setPersonalModelEnabled",
|
|
81
|
+
"usage-stats.getEntitlementSnapshot",
|
|
65
82
|
"event",
|
|
66
83
|
"catalog",
|
|
67
84
|
"session.create",
|
|
@@ -75,7 +75,7 @@ async function configuredPaths(environment: NodeJS.ProcessEnv): Promise<{
|
|
|
75
75
|
if (managed === undefined)
|
|
76
76
|
throw new AdapterError(
|
|
77
77
|
"RUNTIME_SETUP_REQUIRED",
|
|
78
|
-
"ZCode runtime is not set up.
|
|
78
|
+
"ZCode runtime is not set up. Install it in Settings → Plugins → zcode-provider → Settings → Runtime.",
|
|
79
79
|
);
|
|
80
80
|
return { ...managed, source: "managed" };
|
|
81
81
|
}
|
package/server/host/bridge.ts
CHANGED
|
@@ -28,6 +28,12 @@ import {
|
|
|
28
28
|
import type { Logger } from "../logger.js";
|
|
29
29
|
import { PROVIDER_VERSION } from "../build-info.js";
|
|
30
30
|
|
|
31
|
+
export type SettingsChannel =
|
|
32
|
+
| "oauth"
|
|
33
|
+
| "setting"
|
|
34
|
+
| "provider-settings"
|
|
35
|
+
| "usage-stats";
|
|
36
|
+
|
|
31
37
|
export interface HostSubscription {
|
|
32
38
|
readonly id: string;
|
|
33
39
|
dispose(): Promise<void>;
|
|
@@ -265,7 +271,7 @@ export class ZCodeHostBridge implements HostBridge {
|
|
|
265
271
|
}) + "\n",
|
|
266
272
|
);
|
|
267
273
|
const v4 = helloMessageSchema.parse(
|
|
268
|
-
await this.call("zcode-agent", "helloConversationV4",
|
|
274
|
+
await this.call("zcode-agent", "helloConversationV4", [], 10_000),
|
|
269
275
|
);
|
|
270
276
|
if (
|
|
271
277
|
v4.clientMode !== "desktop-continuous" ||
|
|
@@ -278,18 +284,20 @@ export class ZCodeHostBridge implements HostBridge {
|
|
|
278
284
|
await this.call(
|
|
279
285
|
"zcode-agent",
|
|
280
286
|
"initializeConversationV4",
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
+
[
|
|
288
|
+
{
|
|
289
|
+
kind: "clientHello",
|
|
290
|
+
protocolVersion: 3,
|
|
291
|
+
clientId: "paseo-zcode-provider",
|
|
292
|
+
appVersion: PROVIDER_VERSION,
|
|
293
|
+
},
|
|
294
|
+
],
|
|
287
295
|
10_000,
|
|
288
296
|
);
|
|
289
297
|
await this.call(
|
|
290
298
|
"zcode-agent",
|
|
291
299
|
"syncAppRuntimePreferences",
|
|
292
|
-
{ askUserQuestionAutoResolutionEnabled: false },
|
|
300
|
+
[{ askUserQuestionAutoResolutionEnabled: false }],
|
|
293
301
|
10_000,
|
|
294
302
|
);
|
|
295
303
|
}
|
|
@@ -314,7 +322,7 @@ export class ZCodeHostBridge implements HostBridge {
|
|
|
314
322
|
private async call(
|
|
315
323
|
channel: string,
|
|
316
324
|
method: string,
|
|
317
|
-
|
|
325
|
+
args: readonly unknown[],
|
|
318
326
|
timeoutMs: number,
|
|
319
327
|
): Promise<unknown> {
|
|
320
328
|
if (!this.client)
|
|
@@ -323,13 +331,7 @@ export class ZCodeHostBridge implements HostBridge {
|
|
|
323
331
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
324
332
|
try {
|
|
325
333
|
return await Promise.race([
|
|
326
|
-
this.client
|
|
327
|
-
.getChannel(channel)
|
|
328
|
-
.call(
|
|
329
|
-
method,
|
|
330
|
-
params === undefined ? [] : [params],
|
|
331
|
-
cancellation.token,
|
|
332
|
-
),
|
|
334
|
+
this.client.getChannel(channel).call(method, args, cancellation.token),
|
|
333
335
|
new Promise<never>((_, reject) => {
|
|
334
336
|
timer = setTimeout(() => {
|
|
335
337
|
reject(new AdapterError("NATIVE_TIMEOUT", "ZCode RPC timed out"));
|
|
@@ -342,6 +344,12 @@ export class ZCodeHostBridge implements HostBridge {
|
|
|
342
344
|
cancellation.dispose();
|
|
343
345
|
}
|
|
344
346
|
}
|
|
347
|
+
private async ensureOpen(): Promise<void> {
|
|
348
|
+
await this.ready;
|
|
349
|
+
if (this.failure) throw this.failure;
|
|
350
|
+
if (this.closing)
|
|
351
|
+
throw new AdapterError("NATIVE_EXITED", "ZCode Server is closing");
|
|
352
|
+
}
|
|
345
353
|
async request<Schema extends z.ZodType>(
|
|
346
354
|
method: string,
|
|
347
355
|
params: unknown,
|
|
@@ -349,14 +357,12 @@ export class ZCodeHostBridge implements HostBridge {
|
|
|
349
357
|
timeoutMs = 30_000,
|
|
350
358
|
): Promise<z.output<Schema>> {
|
|
351
359
|
try {
|
|
352
|
-
await this.
|
|
353
|
-
|
|
354
|
-
if (this.closing)
|
|
355
|
-
throw new AdapterError("NATIVE_EXITED", "ZCode Server is closing");
|
|
360
|
+
await this.ensureOpen();
|
|
361
|
+
const args = params === undefined ? [] : [params];
|
|
356
362
|
let result: unknown;
|
|
357
363
|
if (method === "readModelSelection")
|
|
358
364
|
result = projectModelSelection(
|
|
359
|
-
await this.call("model-selection", "getView",
|
|
365
|
+
await this.call("model-selection", "getView", args, timeoutMs),
|
|
360
366
|
);
|
|
361
367
|
else
|
|
362
368
|
result = await this.call(
|
|
@@ -365,7 +371,7 @@ export class ZCodeHostBridge implements HostBridge {
|
|
|
365
371
|
? "usage-stats"
|
|
366
372
|
: "zcode-agent",
|
|
367
373
|
method,
|
|
368
|
-
|
|
374
|
+
args,
|
|
369
375
|
timeoutMs,
|
|
370
376
|
);
|
|
371
377
|
return resultSchema.parse(result);
|
|
@@ -377,6 +383,27 @@ export class ZCodeHostBridge implements HostBridge {
|
|
|
377
383
|
});
|
|
378
384
|
}
|
|
379
385
|
}
|
|
386
|
+
/** Calls an official account or settings service with positional arguments. */
|
|
387
|
+
async invoke<Schema extends z.ZodType>(
|
|
388
|
+
channel: SettingsChannel,
|
|
389
|
+
method: string,
|
|
390
|
+
args: readonly unknown[],
|
|
391
|
+
resultSchema: Schema,
|
|
392
|
+
timeoutMs = 30_000,
|
|
393
|
+
): Promise<z.output<Schema>> {
|
|
394
|
+
try {
|
|
395
|
+
await this.ensureOpen();
|
|
396
|
+
return resultSchema.parse(
|
|
397
|
+
await this.call(channel, method, args, timeoutMs),
|
|
398
|
+
);
|
|
399
|
+
} catch (error) {
|
|
400
|
+
throw diagnosticError(error, {
|
|
401
|
+
...this.diagnostic,
|
|
402
|
+
stage: "request",
|
|
403
|
+
operation: `${channel}.${method}`,
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
}
|
|
380
407
|
async subscribe(
|
|
381
408
|
target: { workspacePath: string; sessionId: string },
|
|
382
409
|
handler: (frame: ConversationTopicWireCandidate) => Promise<void> | void,
|
package/server/presentation.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type {
|
|
|
8
8
|
} from "@getpaseo/plugin/server/provider";
|
|
9
9
|
import type {
|
|
10
10
|
ConversationRow,
|
|
11
|
+
HookInvocationRow,
|
|
11
12
|
TimelineMarkerPayload,
|
|
12
13
|
} from "./vendor/zcode/packages/shared/src/zcode-protocol-v4/rows.js";
|
|
13
14
|
import type {
|
|
@@ -160,13 +161,12 @@ export function rowTimeline(
|
|
|
160
161
|
message: `${row.displayName} (${row.artifactType}, ${row.sizeBytes} bytes)`,
|
|
161
162
|
};
|
|
162
163
|
case "hookInvocation":
|
|
163
|
-
return
|
|
164
|
-
id,
|
|
165
|
-
type: "notification",
|
|
166
|
-
level: "info",
|
|
167
|
-
message: `${row.hookEventName}: ${row.executions.map((h) => `${h.displayName} (${h.outcome ?? h.state})`).join(", ")}`,
|
|
168
|
-
};
|
|
164
|
+
return hookTimeline(id, row);
|
|
169
165
|
case "timelineMarker":
|
|
166
|
+
// Paseo appends every notification it receives, so a changing row is
|
|
167
|
+
// reported once, in its final state.
|
|
168
|
+
if (row.marker.type === "compact" && row.marker.status === "running")
|
|
169
|
+
return;
|
|
170
170
|
return {
|
|
171
171
|
id,
|
|
172
172
|
type: "notification",
|
|
@@ -175,6 +175,48 @@ export function rowTimeline(
|
|
|
175
175
|
};
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
|
+
// Like ZCode Desktop, which keeps hooks out of the conversation and lists
|
|
179
|
+
// them on request, successful hooks are not shown. Paseo appends every
|
|
180
|
+
// notification it receives, so an invocation is reported once, after it ends,
|
|
181
|
+
// and only when a hook that ran did not succeed.
|
|
182
|
+
function hookTimeline(
|
|
183
|
+
id: string,
|
|
184
|
+
row: HookInvocationRow,
|
|
185
|
+
): ProviderTimelineItem | undefined {
|
|
186
|
+
if (
|
|
187
|
+
row.state === "running" ||
|
|
188
|
+
row.executions.some((h) => h.state === "running")
|
|
189
|
+
)
|
|
190
|
+
return;
|
|
191
|
+
const problems = row.executions.flatMap((hook) => {
|
|
192
|
+
if (!hook.didExecute) return [];
|
|
193
|
+
const outcome =
|
|
194
|
+
hook.outcome && hook.outcome !== "success"
|
|
195
|
+
? hook.outcome
|
|
196
|
+
: hook.state === "failed"
|
|
197
|
+
? "failed"
|
|
198
|
+
: undefined;
|
|
199
|
+
return outcome ? [{ hook, outcome }] : [];
|
|
200
|
+
});
|
|
201
|
+
if (problems.length === 0) return;
|
|
202
|
+
const outcomes = new Set(problems.map((p) => p.outcome));
|
|
203
|
+
return {
|
|
204
|
+
id,
|
|
205
|
+
type: "notification",
|
|
206
|
+
level: outcomes.has("failed")
|
|
207
|
+
? "error"
|
|
208
|
+
: outcomes.has("blocked") || outcomes.has("timed_out")
|
|
209
|
+
? "warning"
|
|
210
|
+
: "info",
|
|
211
|
+
message: `${row.hookEventName} hook ${problems
|
|
212
|
+
.map(
|
|
213
|
+
({ hook, outcome }) =>
|
|
214
|
+
`${outcome.replace("_", " ")}: ${hook.displayName}${hook.blockReason ? ` (${hook.blockReason})` : ""}`,
|
|
215
|
+
)
|
|
216
|
+
.join("; ")}`,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
178
220
|
export function usage(state: ConversationSnapshot): ProviderUsage {
|
|
179
221
|
return {
|
|
180
222
|
inputTokens: state.usage.cumulative.inputTokens,
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ProviderStatus,
|
|
3
|
+
ProviderStatusRequest,
|
|
4
|
+
} from "@getpaseo/plugin/server/provider";
|
|
5
|
+
import {
|
|
6
|
+
assertRuntimeSupported,
|
|
7
|
+
discoverRuntime,
|
|
8
|
+
} from "./discovery/discover.js";
|
|
9
|
+
import { AdapterError } from "./errors.js";
|
|
10
|
+
import { logger } from "./logger.js";
|
|
11
|
+
|
|
12
|
+
export interface RuntimeStatusOptions {
|
|
13
|
+
readonly environment?: NodeJS.ProcessEnv;
|
|
14
|
+
readonly discover?: typeof discoverRuntime;
|
|
15
|
+
/** How long a result is reused. Paseo asks on every catalog load and agent start. */
|
|
16
|
+
readonly ttlMs?: number;
|
|
17
|
+
readonly now?: () => number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Same shape as Paseo's built-in provider diagnostics; the daemon appends the
|
|
21
|
+
// model count and snapshot status as further indented lines.
|
|
22
|
+
const format = (entries: readonly [string, string][]) =>
|
|
23
|
+
["ZCode", ...entries.map(([label, value]) => ` ${label}: ${value}`)].join(
|
|
24
|
+
"\n",
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
async function check(
|
|
28
|
+
environment: NodeJS.ProcessEnv,
|
|
29
|
+
discover: typeof discoverRuntime,
|
|
30
|
+
): Promise<ProviderStatus> {
|
|
31
|
+
try {
|
|
32
|
+
const runtime = await discover({ environment });
|
|
33
|
+
assertRuntimeSupported(runtime);
|
|
34
|
+
const { appVersion, cliVersion, nodeVersion, platform } = runtime.identity;
|
|
35
|
+
return {
|
|
36
|
+
available: true,
|
|
37
|
+
diagnostic: format([
|
|
38
|
+
[
|
|
39
|
+
"Runtime",
|
|
40
|
+
`${runtime.source === "managed" ? "managed" : "PASEO_ZCODE_RUNTIME"}, Server ${appVersion}, Agent ${cliVersion}`,
|
|
41
|
+
],
|
|
42
|
+
["Node.js", nodeVersion],
|
|
43
|
+
["Platform", platform],
|
|
44
|
+
]),
|
|
45
|
+
};
|
|
46
|
+
} catch (error) {
|
|
47
|
+
// Discovery errors carry fixed messages; anything else stays in the log.
|
|
48
|
+
if (!(error instanceof AdapterError))
|
|
49
|
+
logger.error("zcode.provider.status.failed", error);
|
|
50
|
+
return {
|
|
51
|
+
available: false,
|
|
52
|
+
diagnostic: format([
|
|
53
|
+
[
|
|
54
|
+
"Error",
|
|
55
|
+
error instanceof AdapterError
|
|
56
|
+
? error.message
|
|
57
|
+
: "ZCode runtime could not be inspected",
|
|
58
|
+
],
|
|
59
|
+
]),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Availability for Paseo's provider snapshot and diagnostics (Paseo 0.11+;
|
|
66
|
+
* older daemons ignore it). It inspects the runtime without starting a Server,
|
|
67
|
+
* so sign-in problems still surface when a session opens.
|
|
68
|
+
*/
|
|
69
|
+
export function createRuntimeStatus(options: RuntimeStatusOptions = {}) {
|
|
70
|
+
const environment = options.environment ?? process.env;
|
|
71
|
+
const discover = options.discover ?? discoverRuntime;
|
|
72
|
+
const ttlMs = options.ttlMs ?? 30_000;
|
|
73
|
+
const now = options.now ?? Date.now;
|
|
74
|
+
let cached: { at: number; result: Promise<ProviderStatus> } | undefined;
|
|
75
|
+
return (_request?: ProviderStatusRequest): Promise<ProviderStatus> => {
|
|
76
|
+
if (cached && now() - cached.at < ttlMs) return cached.result;
|
|
77
|
+
const entry = { at: now(), result: check(environment, discover) };
|
|
78
|
+
cached = entry;
|
|
79
|
+
return entry.result;
|
|
80
|
+
};
|
|
81
|
+
}
|
package/server/provider.ts
CHANGED
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
runRuntimeSmoke,
|
|
28
28
|
} from "./discovery/discover.js";
|
|
29
29
|
import { ZCodeHostBridge, type HostBridge } from "./host/bridge.js";
|
|
30
|
+
import { createRuntimeStatus } from "./provider-status.js";
|
|
30
31
|
import { logger } from "./logger.js";
|
|
31
32
|
import { MINIMUM_ZCODE_VERSION } from "./discovery/manifest.js";
|
|
32
33
|
import {
|
|
@@ -68,11 +69,11 @@ export type BridgeFactory = (
|
|
|
68
69
|
workspace?: string,
|
|
69
70
|
) => Promise<HostBridge>;
|
|
70
71
|
|
|
71
|
-
async function createHost(
|
|
72
|
+
export async function createHost(
|
|
72
73
|
environment: Readonly<Record<string, string>>,
|
|
73
74
|
signal: AbortSignal,
|
|
74
75
|
workspace?: string,
|
|
75
|
-
): Promise<
|
|
76
|
+
): Promise<ZCodeHostBridge> {
|
|
76
77
|
const env = { ...process.env, ...environment };
|
|
77
78
|
const runtime = await discoverRuntime({ environment: env, signal });
|
|
78
79
|
assertRuntimeSupported(runtime);
|
|
@@ -114,6 +115,7 @@ interface SessionEntry {
|
|
|
114
115
|
export function createZCodeProvider(
|
|
115
116
|
bridgeFactory: BridgeFactory = createHost,
|
|
116
117
|
persistenceStore = new SessionPersistenceStore(),
|
|
118
|
+
status: ProviderRegistration["status"] = createRuntimeStatus(),
|
|
117
119
|
): ProviderRegistration {
|
|
118
120
|
return {
|
|
119
121
|
id: "zcode",
|
|
@@ -121,6 +123,9 @@ export function createZCodeProvider(
|
|
|
121
123
|
description:
|
|
122
124
|
"ZCode workspace agent with native planning, tools, and model selection",
|
|
123
125
|
icon: "icon.svg",
|
|
126
|
+
// No `command`: Paseo would look it up on PATH, but the runtime is the
|
|
127
|
+
// plugin's managed installation or the PASEO_ZCODE_* override.
|
|
128
|
+
status,
|
|
124
129
|
async connect(request) {
|
|
125
130
|
if (!request.versions.includes(PROVIDER_PROTOCOL_VERSION))
|
|
126
131
|
throw new Error("ZCode requires provider protocol version 1");
|
|
@@ -812,7 +817,9 @@ function publicError(error: unknown): ProviderError {
|
|
|
812
817
|
RUNTIME_DISCOVERY_FAILED:
|
|
813
818
|
"ZCode installation or required host structure could not be inspected. See the diagnostic for the failure stage.",
|
|
814
819
|
RUNTIME_SETUP_REQUIRED:
|
|
815
|
-
"ZCode runtime is not set up.
|
|
820
|
+
"ZCode runtime is not set up. Install it in Settings → Plugins → zcode-provider → Settings → Runtime.",
|
|
821
|
+
AUTH_REQUIRED:
|
|
822
|
+
"No ZCode model provider is usable. Sign in or add a provider in Settings → Plugins → zcode-provider → Settings → Account.",
|
|
816
823
|
PERSISTENCE_VERSION_UNSUPPORTED:
|
|
817
824
|
"ZCode persistence version is unsupported. Create a new Paseo ZCode session.",
|
|
818
825
|
PERSISTENCE_INVALID:
|
package/server/runtime-setup.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
1
|
import type { RuntimeSetupStatus } from "../shared/runtime-setup.js";
|
|
3
2
|
import { AdapterError } from "./errors.js";
|
|
4
3
|
import {
|
|
@@ -14,20 +13,6 @@ const LICENSES = {
|
|
|
14
13
|
"Unofficial build of ZCode (Apache-2.0); third-party terms in THIRD-PARTY-NOTICES.md",
|
|
15
14
|
} as const;
|
|
16
15
|
|
|
17
|
-
// Quoted for the shell a user is most likely to paste into on that OS.
|
|
18
|
-
export function loginCommand(
|
|
19
|
-
executable: string,
|
|
20
|
-
installRoot: string,
|
|
21
|
-
windows = process.platform === "win32",
|
|
22
|
-
): string {
|
|
23
|
-
const script = join(installRoot, "bin", "zcode.mjs");
|
|
24
|
-
return windows
|
|
25
|
-
? `& ${powershellQuote(executable)} ${powershellQuote(script)} login`
|
|
26
|
-
: `${posixQuote(executable)} ${posixQuote(script)} login`;
|
|
27
|
-
}
|
|
28
|
-
const posixQuote = (value: string) => `'${value.replaceAll("'", `'\\''`)}'`;
|
|
29
|
-
const powershellQuote = (value: string) => `'${value.replaceAll("'", "''")}'`;
|
|
30
|
-
|
|
31
16
|
export function createRuntimeSetupHandlers(
|
|
32
17
|
installer: ManagedRuntimeInstaller,
|
|
33
18
|
environment: NodeJS.ProcessEnv = process.env,
|
|
@@ -63,24 +48,14 @@ export function createRuntimeSetupHandlers(
|
|
|
63
48
|
directory: managedRuntimeRoot(environment),
|
|
64
49
|
components: [],
|
|
65
50
|
};
|
|
66
|
-
const components = [
|
|
67
|
-
await component(layout.node),
|
|
68
|
-
await component(layout.zcode),
|
|
69
|
-
];
|
|
70
51
|
return {
|
|
71
52
|
...base,
|
|
72
53
|
supported: true,
|
|
73
54
|
directory: layout.root,
|
|
74
|
-
components
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
layout.node.executable,
|
|
79
|
-
layout.zcode.directory,
|
|
80
|
-
layout.platform.startsWith("win-"),
|
|
81
|
-
),
|
|
82
|
-
}
|
|
83
|
-
: {}),
|
|
55
|
+
components: [
|
|
56
|
+
await component(layout.node),
|
|
57
|
+
await component(layout.zcode),
|
|
58
|
+
],
|
|
84
59
|
};
|
|
85
60
|
},
|
|
86
61
|
install: async () => ({ started: installer.start() }),
|