@pstdio/sdk 0.24.1 → 0.25.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/dist/api/index.js +143 -47
- package/dist/api.d.ts +1 -0
- package/dist/client.d.ts +1 -0
- package/dist/data.d.ts +2 -0
- package/dist/extensions/index.js +95 -1
- package/dist/extensions.d.ts +22 -2
- package/dist/hooks.d.ts +1 -0
- package/dist/resources/index.js +143 -47
- package/dist/testing/index.js +12 -0
- package/dist/testing.d.ts +11 -0
- package/package.json +1 -1
package/dist/api/index.js
CHANGED
|
@@ -5229,7 +5229,19 @@ var listExtensionConnectionsResponseSchema = object({
|
|
|
5229
5229
|
connections: array(extensionConnectionRecordSchema)
|
|
5230
5230
|
});
|
|
5231
5231
|
|
|
5232
|
-
// ../pstdio-api-contracts/src/
|
|
5232
|
+
// ../pstdio-api-contracts/src/extension-kernel/navigation-href.ts
|
|
5233
|
+
var isNavigationHref = (href) => {
|
|
5234
|
+
if (typeof href !== "string")
|
|
5235
|
+
return false;
|
|
5236
|
+
try {
|
|
5237
|
+
const { protocol } = new URL(href);
|
|
5238
|
+
return protocol === "https:" || protocol === "http:";
|
|
5239
|
+
} catch {
|
|
5240
|
+
return false;
|
|
5241
|
+
}
|
|
5242
|
+
};
|
|
5243
|
+
|
|
5244
|
+
// ../pstdio-api-contracts/src/extensions/resource-ref.ts
|
|
5233
5245
|
var extensionResourceRefSchema = object({
|
|
5234
5246
|
shorthand: string2().optional(),
|
|
5235
5247
|
type: string2(),
|
|
@@ -5240,6 +5252,54 @@ var extensionResourceRefSchema = object({
|
|
|
5240
5252
|
extensionId: string2().optional(),
|
|
5241
5253
|
metadata: serializableJsonObjectSchema.optional()
|
|
5242
5254
|
});
|
|
5255
|
+
|
|
5256
|
+
// ../pstdio-api-contracts/src/extensions/workbench-refs-metadata.ts
|
|
5257
|
+
var contributionRefSchema = (kind) => object({ extensionId: string2(), kind: literal(kind), id: string2() });
|
|
5258
|
+
var pageRefSchema = contributionRefSchema("page");
|
|
5259
|
+
var placementRefSchema = contributionRefSchema("placement");
|
|
5260
|
+
var modeRefSchema = contributionRefSchema("mode");
|
|
5261
|
+
var viewRefSchema = contributionRefSchema("view");
|
|
5262
|
+
var resourceKindRefSchema = contributionRefSchema("resource-kind");
|
|
5263
|
+
var pageSlotRefSchema = object({
|
|
5264
|
+
kind: literal("page-slot"),
|
|
5265
|
+
page: pageRefSchema,
|
|
5266
|
+
id: string2()
|
|
5267
|
+
});
|
|
5268
|
+
var panelRefSchema = union([placementRefSchema, pageSlotRefSchema]);
|
|
5269
|
+
var commandTargetSchema = object({
|
|
5270
|
+
command: contributionRefSchema("command"),
|
|
5271
|
+
params: serializableJsonObjectSchema.optional()
|
|
5272
|
+
});
|
|
5273
|
+
|
|
5274
|
+
// ../pstdio-api-contracts/src/extensions/navigation-target-metadata.ts
|
|
5275
|
+
var sectionSchema = object({
|
|
5276
|
+
anchors: array(object({ id: string2(), heading: string2(), occurrence: number2().int().nonnegative().optional() }))
|
|
5277
|
+
});
|
|
5278
|
+
var pageTargetSchema = lazy(() => object({
|
|
5279
|
+
kind: literal("page"),
|
|
5280
|
+
page: pageRefSchema,
|
|
5281
|
+
resource: extensionResourceRefSchema.optional(),
|
|
5282
|
+
open: _enum(["preview", "pin"]).optional(),
|
|
5283
|
+
section: sectionSchema.optional(),
|
|
5284
|
+
parent: pageTargetSchema.optional()
|
|
5285
|
+
})).meta({ id: "WorkbenchMetadataPageTarget" });
|
|
5286
|
+
var navigationOperationSchema = union([
|
|
5287
|
+
pageTargetSchema,
|
|
5288
|
+
object({
|
|
5289
|
+
kind: literal("panel"),
|
|
5290
|
+
panel: panelRefSchema,
|
|
5291
|
+
resource: extensionResourceRefSchema.optional(),
|
|
5292
|
+
open: _enum(["preview", "pin"]).optional()
|
|
5293
|
+
})
|
|
5294
|
+
]);
|
|
5295
|
+
var navigationTargetSchema = union([
|
|
5296
|
+
navigationOperationSchema,
|
|
5297
|
+
object({ kind: literal("command"), target: commandTargetSchema }),
|
|
5298
|
+
object({ kind: literal("href"), href: string2().refine(isNavigationHref, "Expected an HTTP or HTTPS URL") }),
|
|
5299
|
+
object({ kind: literal("compound"), targets: array(navigationOperationSchema).min(1) })
|
|
5300
|
+
]);
|
|
5301
|
+
|
|
5302
|
+
// ../pstdio-api-contracts/src/extensions/execute.ts
|
|
5243
5303
|
var extensionRepoContextSchema = object({
|
|
5244
5304
|
projectId: string2(),
|
|
5245
5305
|
repoId: string2(),
|
|
@@ -5309,10 +5369,12 @@ var commandDiagnosticSchema = object({
|
|
|
5309
5369
|
commandId: string2().optional(),
|
|
5310
5370
|
metadata: jsonObjectSchema.optional()
|
|
5311
5371
|
});
|
|
5372
|
+
var responseNavigationTargetSchema = navigationTargetSchema;
|
|
5312
5373
|
var commandOutcomeSchema = object({
|
|
5313
5374
|
ok: boolean2(),
|
|
5314
5375
|
status: _enum(["success", "rejected", "error"]),
|
|
5315
5376
|
value: unknown().optional(),
|
|
5377
|
+
navigationRequests: array(responseNavigationTargetSchema).optional(),
|
|
5316
5378
|
code: string2().optional(),
|
|
5317
5379
|
reason: string2().optional(),
|
|
5318
5380
|
data: jsonObjectSchema.optional(),
|
|
@@ -5682,52 +5744,6 @@ var extensionCommandPaletteResourceRecordSchema = object({
|
|
|
5682
5744
|
refreshEventIds: array(string2().min(1)).optional()
|
|
5683
5745
|
});
|
|
5684
5746
|
|
|
5685
|
-
// ../pstdio-api-contracts/src/extensions/workbench-refs-metadata.ts
|
|
5686
|
-
var contributionRefSchema = (kind) => object({ extensionId: string2(), kind: literal(kind), id: string2() });
|
|
5687
|
-
var pageRefSchema = contributionRefSchema("page");
|
|
5688
|
-
var placementRefSchema = contributionRefSchema("placement");
|
|
5689
|
-
var modeRefSchema = contributionRefSchema("mode");
|
|
5690
|
-
var viewRefSchema = contributionRefSchema("view");
|
|
5691
|
-
var resourceKindRefSchema = contributionRefSchema("resource-kind");
|
|
5692
|
-
var pageSlotRefSchema = object({
|
|
5693
|
-
kind: literal("page-slot"),
|
|
5694
|
-
page: pageRefSchema,
|
|
5695
|
-
id: string2()
|
|
5696
|
-
});
|
|
5697
|
-
var panelRefSchema = union([placementRefSchema, pageSlotRefSchema]);
|
|
5698
|
-
var commandTargetSchema = object({
|
|
5699
|
-
command: contributionRefSchema("command"),
|
|
5700
|
-
params: serializableJsonObjectSchema.optional()
|
|
5701
|
-
});
|
|
5702
|
-
|
|
5703
|
-
// ../pstdio-api-contracts/src/extensions/navigation-target-metadata.ts
|
|
5704
|
-
var sectionSchema = object({
|
|
5705
|
-
anchors: array(object({ id: string2(), heading: string2(), occurrence: number2().int().nonnegative().optional() }))
|
|
5706
|
-
});
|
|
5707
|
-
var pageTargetSchema = lazy(() => object({
|
|
5708
|
-
kind: literal("page"),
|
|
5709
|
-
page: pageRefSchema,
|
|
5710
|
-
resource: extensionResourceRefSchema.optional(),
|
|
5711
|
-
open: _enum(["preview", "pin"]).optional(),
|
|
5712
|
-
section: sectionSchema.optional(),
|
|
5713
|
-
parent: pageTargetSchema.optional()
|
|
5714
|
-
})).meta({ id: "WorkbenchMetadataPageTarget" });
|
|
5715
|
-
var navigationOperationSchema = union([
|
|
5716
|
-
pageTargetSchema,
|
|
5717
|
-
object({
|
|
5718
|
-
kind: literal("panel"),
|
|
5719
|
-
panel: panelRefSchema,
|
|
5720
|
-
resource: extensionResourceRefSchema.optional(),
|
|
5721
|
-
open: _enum(["preview", "pin"]).optional()
|
|
5722
|
-
})
|
|
5723
|
-
]);
|
|
5724
|
-
var navigationTargetSchema = union([
|
|
5725
|
-
navigationOperationSchema,
|
|
5726
|
-
object({ kind: literal("command"), target: commandTargetSchema }),
|
|
5727
|
-
object({ kind: literal("href"), href: string2() }),
|
|
5728
|
-
object({ kind: literal("compound"), targets: array(navigationOperationSchema).min(1) })
|
|
5729
|
-
]);
|
|
5730
|
-
|
|
5731
5747
|
// ../pstdio-api-contracts/src/extensions/keybindings.ts
|
|
5732
5748
|
var parsedKeybindingChordSchema = object({
|
|
5733
5749
|
key: string2(),
|
|
@@ -6453,6 +6469,86 @@ var l10n = (key, defaultValue) => ({
|
|
|
6453
6469
|
...defaultValue === undefined ? {} : { default: defaultValue }
|
|
6454
6470
|
});
|
|
6455
6471
|
var isLocalizedString = (value) => typeof value === "object" && value !== null && ("$l10n" in value) && typeof value.$l10n === "string";
|
|
6472
|
+
// ../pstdio-api-contracts/src/extension-kernel/navigation.ts
|
|
6473
|
+
var isRecord = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
6474
|
+
var isContributionRef = (value, kind) => isRecord(value) && value.kind === kind && typeof value.id === "string";
|
|
6475
|
+
var isResource = (value) => isRecord(value) && typeof value.type === "string" && typeof value.id === "string";
|
|
6476
|
+
var isOpenIntent = (value) => value === undefined || value === "preview" || value === "pin";
|
|
6477
|
+
var isPageTarget = (value, ancestors = new Set) => {
|
|
6478
|
+
if (!isRecord(value) || value.kind !== "page" || !isContributionRef(value.page, "page"))
|
|
6479
|
+
return false;
|
|
6480
|
+
if (ancestors.has(value))
|
|
6481
|
+
return false;
|
|
6482
|
+
if (value.resource !== undefined && !isResource(value.resource))
|
|
6483
|
+
return false;
|
|
6484
|
+
if (value.section !== undefined && !isRecord(value.section))
|
|
6485
|
+
return false;
|
|
6486
|
+
if (!isOpenIntent(value.open))
|
|
6487
|
+
return false;
|
|
6488
|
+
if (value.parent === undefined)
|
|
6489
|
+
return true;
|
|
6490
|
+
const next = new Set(ancestors);
|
|
6491
|
+
next.add(value);
|
|
6492
|
+
return isPageTarget(value.parent, next);
|
|
6493
|
+
};
|
|
6494
|
+
var isPanelTarget = (value) => {
|
|
6495
|
+
if (!isRecord(value) || value.kind !== "panel" || !isRecord(value.panel))
|
|
6496
|
+
return false;
|
|
6497
|
+
const panel = value.panel;
|
|
6498
|
+
const validPanel = isContributionRef(panel, "placement") || panel.kind === "page-slot" && isContributionRef(panel.page, "page") && typeof panel.id === "string";
|
|
6499
|
+
return validPanel && (value.resource === undefined || isResource(value.resource)) && isOpenIntent(value.open);
|
|
6500
|
+
};
|
|
6501
|
+
var isItemTarget = (value) => {
|
|
6502
|
+
if (!isRecord(value))
|
|
6503
|
+
return false;
|
|
6504
|
+
if (value.kind === "page")
|
|
6505
|
+
return isPageTarget(value);
|
|
6506
|
+
if (value.kind === "panel")
|
|
6507
|
+
return isPanelTarget(value);
|
|
6508
|
+
if (value.kind === "href")
|
|
6509
|
+
return isNavigationHref(value.href);
|
|
6510
|
+
return value.kind === "command" && isRecord(value.target) && isContributionRef(value.target.command, "command") && (value.target.params === undefined || isRecord(value.target.params));
|
|
6511
|
+
};
|
|
6512
|
+
var isNavigationTarget = (value) => {
|
|
6513
|
+
if (isItemTarget(value))
|
|
6514
|
+
return true;
|
|
6515
|
+
if (!isRecord(value) || value.kind !== "compound" || !Array.isArray(value.targets) || value.targets.length === 0) {
|
|
6516
|
+
return false;
|
|
6517
|
+
}
|
|
6518
|
+
return value.targets.every((target) => isPageTarget(target) || isPanelTarget(target));
|
|
6519
|
+
};
|
|
6520
|
+
var withExtensionOwner = (ref, extensionId) => ref.extensionId !== undefined || extensionId === undefined ? ref : { ...ref, extensionId };
|
|
6521
|
+
var toPageTarget = (target, extensionId, projectId) => ({
|
|
6522
|
+
...target,
|
|
6523
|
+
page: withExtensionOwner(target.page, extensionId),
|
|
6524
|
+
...target.resource ? { resource: qualifyResource(target.resource, extensionId, projectId) } : {},
|
|
6525
|
+
...target.parent ? { parent: toPageTarget(target.parent, extensionId, projectId) } : {}
|
|
6526
|
+
});
|
|
6527
|
+
var qualifyResource = (resource, extensionId, projectId) => ({
|
|
6528
|
+
...resource,
|
|
6529
|
+
extensionId: resource.extensionId ?? extensionId,
|
|
6530
|
+
projectId: resource.projectId ?? projectId
|
|
6531
|
+
});
|
|
6532
|
+
var qualifyNavigationTarget = (target, extensionId, projectId) => {
|
|
6533
|
+
if (!isNavigationTarget(target))
|
|
6534
|
+
throw new Error("Invalid navigation target.");
|
|
6535
|
+
if (target.kind === "page")
|
|
6536
|
+
return toPageTarget(target, extensionId, projectId);
|
|
6537
|
+
if (target.kind === "panel")
|
|
6538
|
+
return {
|
|
6539
|
+
...target,
|
|
6540
|
+
panel: target.panel.kind === "page-slot" ? { ...target.panel, page: withExtensionOwner(target.panel.page, extensionId) } : withExtensionOwner(target.panel, extensionId),
|
|
6541
|
+
...target.resource ? { resource: qualifyResource(target.resource, extensionId, projectId) } : {}
|
|
6542
|
+
};
|
|
6543
|
+
if (target.kind === "command")
|
|
6544
|
+
return { ...target, target: { ...target.target, command: withExtensionOwner(target.target.command, extensionId) } };
|
|
6545
|
+
if (target.kind === "href")
|
|
6546
|
+
return target;
|
|
6547
|
+
return {
|
|
6548
|
+
...target,
|
|
6549
|
+
targets: target.targets.map((item) => qualifyNavigationTarget(item, extensionId, projectId))
|
|
6550
|
+
};
|
|
6551
|
+
};
|
|
6456
6552
|
// ../pstdio-api-contracts/src/extension-kernel/package-asset.ts
|
|
6457
6553
|
var packageAsset = (path, baseUrl) => ({
|
|
6458
6554
|
kind: "package-asset",
|
package/dist/api.d.ts
CHANGED
|
@@ -180,6 +180,7 @@ declare const commandExecuteResponseSchema: z.ZodObject<{
|
|
|
180
180
|
rejected: "rejected";
|
|
181
181
|
}>;
|
|
182
182
|
value: z.ZodOptional<z.ZodUnknown>;
|
|
183
|
+
navigationRequests: z.ZodOptional<z.ZodArray<z.ZodType<NavigationTarget, unknown, z.core.$ZodTypeInternals<NavigationTarget, unknown>>>>;
|
|
183
184
|
code: z.ZodOptional<z.ZodString>;
|
|
184
185
|
reason: z.ZodOptional<z.ZodString>;
|
|
185
186
|
data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
package/dist/client.d.ts
CHANGED
|
@@ -244,6 +244,7 @@ declare const commandExecuteResponseSchema: z.ZodObject<{
|
|
|
244
244
|
rejected: "rejected";
|
|
245
245
|
}>;
|
|
246
246
|
value: z.ZodOptional<z.ZodUnknown>;
|
|
247
|
+
navigationRequests: z.ZodOptional<z.ZodArray<z.ZodType<NavigationTarget, unknown, z.core.$ZodTypeInternals<NavigationTarget, unknown>>>>;
|
|
247
248
|
code: z.ZodOptional<z.ZodString>;
|
|
248
249
|
reason: z.ZodOptional<z.ZodString>;
|
|
249
250
|
data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
package/dist/data.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ declare interface ArtifactMount {
|
|
|
10
10
|
exists(path: string): Promise<boolean>;
|
|
11
11
|
readText(path: string): Promise<string>;
|
|
12
12
|
writeText(path: string, value: string): Promise<void>;
|
|
13
|
+
/** Replace existing text. Fails if missing and never recreates a concurrently deleted file. */
|
|
14
|
+
updateText(path: string, value: string): Promise<void>;
|
|
13
15
|
readBytes(path: string): Promise<Uint8Array>;
|
|
14
16
|
writeBytes(path: string, value: Uint8Array): Promise<void>;
|
|
15
17
|
list(pattern?: string): Promise<ArtifactFile[]>;
|
package/dist/extensions/index.js
CHANGED
|
@@ -163,6 +163,98 @@ var l10n = (key, defaultValue) => ({
|
|
|
163
163
|
...defaultValue === undefined ? {} : { default: defaultValue }
|
|
164
164
|
});
|
|
165
165
|
var isLocalizedString = (value) => typeof value === "object" && value !== null && ("$l10n" in value) && typeof value.$l10n === "string";
|
|
166
|
+
// ../pstdio-api-contracts/src/extension-kernel/navigation-href.ts
|
|
167
|
+
var isNavigationHref = (href) => {
|
|
168
|
+
if (typeof href !== "string")
|
|
169
|
+
return false;
|
|
170
|
+
try {
|
|
171
|
+
const { protocol } = new URL(href);
|
|
172
|
+
return protocol === "https:" || protocol === "http:";
|
|
173
|
+
} catch {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// ../pstdio-api-contracts/src/extension-kernel/navigation.ts
|
|
179
|
+
var isRecord = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
180
|
+
var isContributionRef = (value, kind) => isRecord(value) && value.kind === kind && typeof value.id === "string";
|
|
181
|
+
var isResource = (value) => isRecord(value) && typeof value.type === "string" && typeof value.id === "string";
|
|
182
|
+
var isOpenIntent = (value) => value === undefined || value === "preview" || value === "pin";
|
|
183
|
+
var isPageTarget = (value, ancestors = new Set) => {
|
|
184
|
+
if (!isRecord(value) || value.kind !== "page" || !isContributionRef(value.page, "page"))
|
|
185
|
+
return false;
|
|
186
|
+
if (ancestors.has(value))
|
|
187
|
+
return false;
|
|
188
|
+
if (value.resource !== undefined && !isResource(value.resource))
|
|
189
|
+
return false;
|
|
190
|
+
if (value.section !== undefined && !isRecord(value.section))
|
|
191
|
+
return false;
|
|
192
|
+
if (!isOpenIntent(value.open))
|
|
193
|
+
return false;
|
|
194
|
+
if (value.parent === undefined)
|
|
195
|
+
return true;
|
|
196
|
+
const next = new Set(ancestors);
|
|
197
|
+
next.add(value);
|
|
198
|
+
return isPageTarget(value.parent, next);
|
|
199
|
+
};
|
|
200
|
+
var isPanelTarget = (value) => {
|
|
201
|
+
if (!isRecord(value) || value.kind !== "panel" || !isRecord(value.panel))
|
|
202
|
+
return false;
|
|
203
|
+
const panel = value.panel;
|
|
204
|
+
const validPanel = isContributionRef(panel, "placement") || panel.kind === "page-slot" && isContributionRef(panel.page, "page") && typeof panel.id === "string";
|
|
205
|
+
return validPanel && (value.resource === undefined || isResource(value.resource)) && isOpenIntent(value.open);
|
|
206
|
+
};
|
|
207
|
+
var isItemTarget = (value) => {
|
|
208
|
+
if (!isRecord(value))
|
|
209
|
+
return false;
|
|
210
|
+
if (value.kind === "page")
|
|
211
|
+
return isPageTarget(value);
|
|
212
|
+
if (value.kind === "panel")
|
|
213
|
+
return isPanelTarget(value);
|
|
214
|
+
if (value.kind === "href")
|
|
215
|
+
return isNavigationHref(value.href);
|
|
216
|
+
return value.kind === "command" && isRecord(value.target) && isContributionRef(value.target.command, "command") && (value.target.params === undefined || isRecord(value.target.params));
|
|
217
|
+
};
|
|
218
|
+
var isNavigationTarget = (value) => {
|
|
219
|
+
if (isItemTarget(value))
|
|
220
|
+
return true;
|
|
221
|
+
if (!isRecord(value) || value.kind !== "compound" || !Array.isArray(value.targets) || value.targets.length === 0) {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
return value.targets.every((target) => isPageTarget(target) || isPanelTarget(target));
|
|
225
|
+
};
|
|
226
|
+
var withExtensionOwner = (ref, extensionId) => ref.extensionId !== undefined || extensionId === undefined ? ref : { ...ref, extensionId };
|
|
227
|
+
var toPageTarget = (target, extensionId, projectId) => ({
|
|
228
|
+
...target,
|
|
229
|
+
page: withExtensionOwner(target.page, extensionId),
|
|
230
|
+
...target.resource ? { resource: qualifyResource(target.resource, extensionId, projectId) } : {},
|
|
231
|
+
...target.parent ? { parent: toPageTarget(target.parent, extensionId, projectId) } : {}
|
|
232
|
+
});
|
|
233
|
+
var qualifyResource = (resource, extensionId, projectId) => ({
|
|
234
|
+
...resource,
|
|
235
|
+
extensionId: resource.extensionId ?? extensionId,
|
|
236
|
+
projectId: resource.projectId ?? projectId
|
|
237
|
+
});
|
|
238
|
+
var qualifyNavigationTarget = (target, extensionId, projectId) => {
|
|
239
|
+
if (!isNavigationTarget(target))
|
|
240
|
+
throw new Error("Invalid navigation target.");
|
|
241
|
+
if (target.kind === "page")
|
|
242
|
+
return toPageTarget(target, extensionId, projectId);
|
|
243
|
+
if (target.kind === "panel")
|
|
244
|
+
return {
|
|
245
|
+
...target,
|
|
246
|
+
panel: target.panel.kind === "page-slot" ? { ...target.panel, page: withExtensionOwner(target.panel.page, extensionId) } : withExtensionOwner(target.panel, extensionId),
|
|
247
|
+
...target.resource ? { resource: qualifyResource(target.resource, extensionId, projectId) } : {}
|
|
248
|
+
};
|
|
249
|
+
if (target.kind === "command")
|
|
250
|
+
return { ...target, target: { ...target.target, command: withExtensionOwner(target.target.command, extensionId) } };
|
|
251
|
+
if (target.kind === "href")
|
|
252
|
+
return target;
|
|
253
|
+
return {
|
|
254
|
+
...target,
|
|
255
|
+
targets: target.targets.map((item) => qualifyNavigationTarget(item, extensionId, projectId))
|
|
256
|
+
};
|
|
257
|
+
};
|
|
166
258
|
// ../pstdio-api-contracts/src/extension-kernel/package-asset.ts
|
|
167
259
|
var packageAsset = (path, baseUrl) => ({
|
|
168
260
|
kind: "package-asset",
|
|
@@ -200,7 +292,7 @@ var WEBVIEW_HOST_CAPABILITIES = [
|
|
|
200
292
|
...ALWAYS_AVAILABLE_WEBVIEW_CAPABILITIES
|
|
201
293
|
];
|
|
202
294
|
// package.json
|
|
203
|
-
var version = "0.
|
|
295
|
+
var version = "0.25.0";
|
|
204
296
|
|
|
205
297
|
// src/version.ts
|
|
206
298
|
var SDK_VERSION = version;
|
|
@@ -733,6 +825,7 @@ export {
|
|
|
733
825
|
extensionPanelRegions,
|
|
734
826
|
gitEvents,
|
|
735
827
|
isLocalizedString,
|
|
828
|
+
isNavigationTarget,
|
|
736
829
|
isValidLocalContributionId,
|
|
737
830
|
isWorkbenchProjectUrl,
|
|
738
831
|
l10n,
|
|
@@ -746,6 +839,7 @@ export {
|
|
|
746
839
|
projectEvents,
|
|
747
840
|
projectPrefix,
|
|
748
841
|
projectSlots,
|
|
842
|
+
qualifyNavigationTarget,
|
|
749
843
|
qualifyRef,
|
|
750
844
|
resolveEventReferenceId,
|
|
751
845
|
resourceKey,
|
package/dist/extensions.d.ts
CHANGED
|
@@ -99,6 +99,8 @@ export declare interface ArtifactMount {
|
|
|
99
99
|
exists(path: string): Promise<boolean>;
|
|
100
100
|
readText(path: string): Promise<string>;
|
|
101
101
|
writeText(path: string, value: string): Promise<void>;
|
|
102
|
+
/** Replace existing text. Fails if missing and never recreates a concurrently deleted file. */
|
|
103
|
+
updateText(path: string, value: string): Promise<void>;
|
|
102
104
|
readBytes(path: string): Promise<Uint8Array>;
|
|
103
105
|
writeBytes(path: string, value: Uint8Array): Promise<void>;
|
|
104
106
|
list(pattern?: string): Promise<ArtifactFile[]>;
|
|
@@ -303,6 +305,7 @@ export declare type CommandOutcome<TResult = unknown> = {
|
|
|
303
305
|
ok: true;
|
|
304
306
|
status: "success";
|
|
305
307
|
value: TResult;
|
|
308
|
+
navigationRequests?: NavigationTarget[];
|
|
306
309
|
notices?: CommandNotice[];
|
|
307
310
|
diagnostics?: CommandDiagnostic[];
|
|
308
311
|
} | {
|
|
@@ -652,7 +655,7 @@ export declare interface DataTableRendererRowAction<TParams extends Struct = Str
|
|
|
652
655
|
|
|
653
656
|
export declare type DataTableRendererRowActivationHandler = RendererCallback<{
|
|
654
657
|
row: DataTableRendererRow;
|
|
655
|
-
},
|
|
658
|
+
}, void | NavigationTarget>;
|
|
656
659
|
|
|
657
660
|
export declare interface DataTableRendererSelectionAction<TParams extends Struct = Struct> {
|
|
658
661
|
id: string;
|
|
@@ -933,6 +936,10 @@ export declare interface ExtensionContextBase<TSettings extends Record<string, u
|
|
|
933
936
|
source?: CommandSource;
|
|
934
937
|
storage: ExtensionStorageApi;
|
|
935
938
|
resources: ExtensionResourcesApi;
|
|
939
|
+
/** Records navigation for the invoking UI; headless execution opens nothing. */
|
|
940
|
+
navigation: {
|
|
941
|
+
open(target: NavigationTarget): void;
|
|
942
|
+
};
|
|
936
943
|
artifacts: ExtensionArtifactApi;
|
|
937
944
|
/** Working tree of the invocation's repo, scoped to its root. Absent for non-repo (event/hook) invocations. */
|
|
938
945
|
repoFiles?: ArtifactMount;
|
|
@@ -1064,6 +1071,8 @@ export declare interface ExtensionReposApi {
|
|
|
1064
1071
|
}
|
|
1065
1072
|
|
|
1066
1073
|
export declare interface ExtensionResourcesApi {
|
|
1074
|
+
/** Publish a committed removal to clients displaying this project resource. */
|
|
1075
|
+
removed(resource: ResourceRef): Promise<void>;
|
|
1067
1076
|
allocate(input: {
|
|
1068
1077
|
kind: string;
|
|
1069
1078
|
}): Promise<{
|
|
@@ -1173,6 +1182,8 @@ export declare interface ExtensionStorageCollectionApi<TItem = unknown> {
|
|
|
1173
1182
|
get(id: string): Promise<TItem | undefined>;
|
|
1174
1183
|
list(): Promise<TItem[]>;
|
|
1175
1184
|
put(id: string, value: TItem): Promise<void>;
|
|
1185
|
+
/** Replace an existing item atomically. Throws if the item was deleted. */
|
|
1186
|
+
update(id: string, value: TItem): Promise<void>;
|
|
1176
1187
|
createIfAbsent(id: string, value: TItem): Promise<boolean>;
|
|
1177
1188
|
deleteIfValue(id: string, value: TItem): Promise<boolean>;
|
|
1178
1189
|
create(value: TItem): Promise<TItem & {
|
|
@@ -1488,6 +1499,8 @@ export declare interface HookDefinition<TPayload extends Struct = Struct> extend
|
|
|
1488
1499
|
|
|
1489
1500
|
export declare const isLocalizedString: (value: unknown) => value is LocalizedString;
|
|
1490
1501
|
|
|
1502
|
+
export declare const isNavigationTarget: (value: unknown) => value is NavigationTarget;
|
|
1503
|
+
|
|
1491
1504
|
export declare const isValidLocalContributionId: (id: string) => boolean;
|
|
1492
1505
|
|
|
1493
1506
|
export declare const isWorkbenchProjectUrl: (urlValue: string, projectId: string) => boolean;
|
|
@@ -1646,7 +1659,7 @@ export declare interface KanbanRendererRowAction<TParams extends Struct = Struct
|
|
|
1646
1659
|
|
|
1647
1660
|
export declare type KanbanRendererRowActivationHandler = RendererCallback<{
|
|
1648
1661
|
row: KanbanRendererRow;
|
|
1649
|
-
},
|
|
1662
|
+
}, void | NavigationTarget>;
|
|
1650
1663
|
|
|
1651
1664
|
export declare interface KanbanRendererSavedView {
|
|
1652
1665
|
id: string;
|
|
@@ -2332,6 +2345,8 @@ export declare type QualifiedRef<Ref extends QualifiableRef> = Ref extends PageS
|
|
|
2332
2345
|
readonly extensionId: string;
|
|
2333
2346
|
};
|
|
2334
2347
|
|
|
2348
|
+
export declare const qualifyNavigationTarget: (target: NavigationTarget, extensionId: string, projectId?: string) => NavigationTarget;
|
|
2349
|
+
|
|
2335
2350
|
/** Publish a provider-owned reference without changing the local contribution definition. */
|
|
2336
2351
|
export declare function qualifyRef<Ref extends QualifiableRef>(owner: string, ref: Ref): QualifiedRef<Ref>;
|
|
2337
2352
|
|
|
@@ -2552,6 +2567,11 @@ export declare interface ResourceRef {
|
|
|
2552
2567
|
/** A reference the host can open (e.g. another resource tab). */
|
|
2553
2568
|
export declare type ResourceRefValue = ResourceRef;
|
|
2554
2569
|
|
|
2570
|
+
export declare interface ResourceRemovedEvent {
|
|
2571
|
+
id: string;
|
|
2572
|
+
resource: ResourceRef;
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2555
2575
|
export declare type ResourceRole = "primary" | "context" | "source" | "result";
|
|
2556
2576
|
|
|
2557
2577
|
/** A reattach error is permanent unless the provider explicitly marks it retryable. */
|
package/dist/hooks.d.ts
CHANGED
|
@@ -242,6 +242,7 @@ declare const commandExecuteResponseSchema: z.ZodObject<{
|
|
|
242
242
|
rejected: "rejected";
|
|
243
243
|
}>;
|
|
244
244
|
value: z.ZodOptional<z.ZodUnknown>;
|
|
245
|
+
navigationRequests: z.ZodOptional<z.ZodArray<z.ZodType<NavigationTarget, unknown, z.core.$ZodTypeInternals<NavigationTarget, unknown>>>>;
|
|
245
246
|
code: z.ZodOptional<z.ZodString>;
|
|
246
247
|
reason: z.ZodOptional<z.ZodString>;
|
|
247
248
|
data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
package/dist/resources/index.js
CHANGED
|
@@ -5229,7 +5229,19 @@ var listExtensionConnectionsResponseSchema = object({
|
|
|
5229
5229
|
connections: array(extensionConnectionRecordSchema)
|
|
5230
5230
|
});
|
|
5231
5231
|
|
|
5232
|
-
// ../pstdio-api-contracts/src/
|
|
5232
|
+
// ../pstdio-api-contracts/src/extension-kernel/navigation-href.ts
|
|
5233
|
+
var isNavigationHref = (href) => {
|
|
5234
|
+
if (typeof href !== "string")
|
|
5235
|
+
return false;
|
|
5236
|
+
try {
|
|
5237
|
+
const { protocol } = new URL(href);
|
|
5238
|
+
return protocol === "https:" || protocol === "http:";
|
|
5239
|
+
} catch {
|
|
5240
|
+
return false;
|
|
5241
|
+
}
|
|
5242
|
+
};
|
|
5243
|
+
|
|
5244
|
+
// ../pstdio-api-contracts/src/extensions/resource-ref.ts
|
|
5233
5245
|
var extensionResourceRefSchema = object({
|
|
5234
5246
|
shorthand: string2().optional(),
|
|
5235
5247
|
type: string2(),
|
|
@@ -5240,6 +5252,54 @@ var extensionResourceRefSchema = object({
|
|
|
5240
5252
|
extensionId: string2().optional(),
|
|
5241
5253
|
metadata: serializableJsonObjectSchema.optional()
|
|
5242
5254
|
});
|
|
5255
|
+
|
|
5256
|
+
// ../pstdio-api-contracts/src/extensions/workbench-refs-metadata.ts
|
|
5257
|
+
var contributionRefSchema = (kind) => object({ extensionId: string2(), kind: literal(kind), id: string2() });
|
|
5258
|
+
var pageRefSchema = contributionRefSchema("page");
|
|
5259
|
+
var placementRefSchema = contributionRefSchema("placement");
|
|
5260
|
+
var modeRefSchema = contributionRefSchema("mode");
|
|
5261
|
+
var viewRefSchema = contributionRefSchema("view");
|
|
5262
|
+
var resourceKindRefSchema = contributionRefSchema("resource-kind");
|
|
5263
|
+
var pageSlotRefSchema = object({
|
|
5264
|
+
kind: literal("page-slot"),
|
|
5265
|
+
page: pageRefSchema,
|
|
5266
|
+
id: string2()
|
|
5267
|
+
});
|
|
5268
|
+
var panelRefSchema = union([placementRefSchema, pageSlotRefSchema]);
|
|
5269
|
+
var commandTargetSchema = object({
|
|
5270
|
+
command: contributionRefSchema("command"),
|
|
5271
|
+
params: serializableJsonObjectSchema.optional()
|
|
5272
|
+
});
|
|
5273
|
+
|
|
5274
|
+
// ../pstdio-api-contracts/src/extensions/navigation-target-metadata.ts
|
|
5275
|
+
var sectionSchema = object({
|
|
5276
|
+
anchors: array(object({ id: string2(), heading: string2(), occurrence: number2().int().nonnegative().optional() }))
|
|
5277
|
+
});
|
|
5278
|
+
var pageTargetSchema = lazy(() => object({
|
|
5279
|
+
kind: literal("page"),
|
|
5280
|
+
page: pageRefSchema,
|
|
5281
|
+
resource: extensionResourceRefSchema.optional(),
|
|
5282
|
+
open: _enum(["preview", "pin"]).optional(),
|
|
5283
|
+
section: sectionSchema.optional(),
|
|
5284
|
+
parent: pageTargetSchema.optional()
|
|
5285
|
+
})).meta({ id: "WorkbenchMetadataPageTarget" });
|
|
5286
|
+
var navigationOperationSchema = union([
|
|
5287
|
+
pageTargetSchema,
|
|
5288
|
+
object({
|
|
5289
|
+
kind: literal("panel"),
|
|
5290
|
+
panel: panelRefSchema,
|
|
5291
|
+
resource: extensionResourceRefSchema.optional(),
|
|
5292
|
+
open: _enum(["preview", "pin"]).optional()
|
|
5293
|
+
})
|
|
5294
|
+
]);
|
|
5295
|
+
var navigationTargetSchema = union([
|
|
5296
|
+
navigationOperationSchema,
|
|
5297
|
+
object({ kind: literal("command"), target: commandTargetSchema }),
|
|
5298
|
+
object({ kind: literal("href"), href: string2().refine(isNavigationHref, "Expected an HTTP or HTTPS URL") }),
|
|
5299
|
+
object({ kind: literal("compound"), targets: array(navigationOperationSchema).min(1) })
|
|
5300
|
+
]);
|
|
5301
|
+
|
|
5302
|
+
// ../pstdio-api-contracts/src/extensions/execute.ts
|
|
5243
5303
|
var extensionRepoContextSchema = object({
|
|
5244
5304
|
projectId: string2(),
|
|
5245
5305
|
repoId: string2(),
|
|
@@ -5309,10 +5369,12 @@ var commandDiagnosticSchema = object({
|
|
|
5309
5369
|
commandId: string2().optional(),
|
|
5310
5370
|
metadata: jsonObjectSchema.optional()
|
|
5311
5371
|
});
|
|
5372
|
+
var responseNavigationTargetSchema = navigationTargetSchema;
|
|
5312
5373
|
var commandOutcomeSchema = object({
|
|
5313
5374
|
ok: boolean2(),
|
|
5314
5375
|
status: _enum(["success", "rejected", "error"]),
|
|
5315
5376
|
value: unknown().optional(),
|
|
5377
|
+
navigationRequests: array(responseNavigationTargetSchema).optional(),
|
|
5316
5378
|
code: string2().optional(),
|
|
5317
5379
|
reason: string2().optional(),
|
|
5318
5380
|
data: jsonObjectSchema.optional(),
|
|
@@ -5682,52 +5744,6 @@ var extensionCommandPaletteResourceRecordSchema = object({
|
|
|
5682
5744
|
refreshEventIds: array(string2().min(1)).optional()
|
|
5683
5745
|
});
|
|
5684
5746
|
|
|
5685
|
-
// ../pstdio-api-contracts/src/extensions/workbench-refs-metadata.ts
|
|
5686
|
-
var contributionRefSchema = (kind) => object({ extensionId: string2(), kind: literal(kind), id: string2() });
|
|
5687
|
-
var pageRefSchema = contributionRefSchema("page");
|
|
5688
|
-
var placementRefSchema = contributionRefSchema("placement");
|
|
5689
|
-
var modeRefSchema = contributionRefSchema("mode");
|
|
5690
|
-
var viewRefSchema = contributionRefSchema("view");
|
|
5691
|
-
var resourceKindRefSchema = contributionRefSchema("resource-kind");
|
|
5692
|
-
var pageSlotRefSchema = object({
|
|
5693
|
-
kind: literal("page-slot"),
|
|
5694
|
-
page: pageRefSchema,
|
|
5695
|
-
id: string2()
|
|
5696
|
-
});
|
|
5697
|
-
var panelRefSchema = union([placementRefSchema, pageSlotRefSchema]);
|
|
5698
|
-
var commandTargetSchema = object({
|
|
5699
|
-
command: contributionRefSchema("command"),
|
|
5700
|
-
params: serializableJsonObjectSchema.optional()
|
|
5701
|
-
});
|
|
5702
|
-
|
|
5703
|
-
// ../pstdio-api-contracts/src/extensions/navigation-target-metadata.ts
|
|
5704
|
-
var sectionSchema = object({
|
|
5705
|
-
anchors: array(object({ id: string2(), heading: string2(), occurrence: number2().int().nonnegative().optional() }))
|
|
5706
|
-
});
|
|
5707
|
-
var pageTargetSchema = lazy(() => object({
|
|
5708
|
-
kind: literal("page"),
|
|
5709
|
-
page: pageRefSchema,
|
|
5710
|
-
resource: extensionResourceRefSchema.optional(),
|
|
5711
|
-
open: _enum(["preview", "pin"]).optional(),
|
|
5712
|
-
section: sectionSchema.optional(),
|
|
5713
|
-
parent: pageTargetSchema.optional()
|
|
5714
|
-
})).meta({ id: "WorkbenchMetadataPageTarget" });
|
|
5715
|
-
var navigationOperationSchema = union([
|
|
5716
|
-
pageTargetSchema,
|
|
5717
|
-
object({
|
|
5718
|
-
kind: literal("panel"),
|
|
5719
|
-
panel: panelRefSchema,
|
|
5720
|
-
resource: extensionResourceRefSchema.optional(),
|
|
5721
|
-
open: _enum(["preview", "pin"]).optional()
|
|
5722
|
-
})
|
|
5723
|
-
]);
|
|
5724
|
-
var navigationTargetSchema = union([
|
|
5725
|
-
navigationOperationSchema,
|
|
5726
|
-
object({ kind: literal("command"), target: commandTargetSchema }),
|
|
5727
|
-
object({ kind: literal("href"), href: string2() }),
|
|
5728
|
-
object({ kind: literal("compound"), targets: array(navigationOperationSchema).min(1) })
|
|
5729
|
-
]);
|
|
5730
|
-
|
|
5731
5747
|
// ../pstdio-api-contracts/src/extensions/keybindings.ts
|
|
5732
5748
|
var parsedKeybindingChordSchema = object({
|
|
5733
5749
|
key: string2(),
|
|
@@ -6453,6 +6469,86 @@ var l10n = (key, defaultValue) => ({
|
|
|
6453
6469
|
...defaultValue === undefined ? {} : { default: defaultValue }
|
|
6454
6470
|
});
|
|
6455
6471
|
var isLocalizedString = (value) => typeof value === "object" && value !== null && ("$l10n" in value) && typeof value.$l10n === "string";
|
|
6472
|
+
// ../pstdio-api-contracts/src/extension-kernel/navigation.ts
|
|
6473
|
+
var isRecord = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
6474
|
+
var isContributionRef = (value, kind) => isRecord(value) && value.kind === kind && typeof value.id === "string";
|
|
6475
|
+
var isResource = (value) => isRecord(value) && typeof value.type === "string" && typeof value.id === "string";
|
|
6476
|
+
var isOpenIntent = (value) => value === undefined || value === "preview" || value === "pin";
|
|
6477
|
+
var isPageTarget = (value, ancestors = new Set) => {
|
|
6478
|
+
if (!isRecord(value) || value.kind !== "page" || !isContributionRef(value.page, "page"))
|
|
6479
|
+
return false;
|
|
6480
|
+
if (ancestors.has(value))
|
|
6481
|
+
return false;
|
|
6482
|
+
if (value.resource !== undefined && !isResource(value.resource))
|
|
6483
|
+
return false;
|
|
6484
|
+
if (value.section !== undefined && !isRecord(value.section))
|
|
6485
|
+
return false;
|
|
6486
|
+
if (!isOpenIntent(value.open))
|
|
6487
|
+
return false;
|
|
6488
|
+
if (value.parent === undefined)
|
|
6489
|
+
return true;
|
|
6490
|
+
const next = new Set(ancestors);
|
|
6491
|
+
next.add(value);
|
|
6492
|
+
return isPageTarget(value.parent, next);
|
|
6493
|
+
};
|
|
6494
|
+
var isPanelTarget = (value) => {
|
|
6495
|
+
if (!isRecord(value) || value.kind !== "panel" || !isRecord(value.panel))
|
|
6496
|
+
return false;
|
|
6497
|
+
const panel = value.panel;
|
|
6498
|
+
const validPanel = isContributionRef(panel, "placement") || panel.kind === "page-slot" && isContributionRef(panel.page, "page") && typeof panel.id === "string";
|
|
6499
|
+
return validPanel && (value.resource === undefined || isResource(value.resource)) && isOpenIntent(value.open);
|
|
6500
|
+
};
|
|
6501
|
+
var isItemTarget = (value) => {
|
|
6502
|
+
if (!isRecord(value))
|
|
6503
|
+
return false;
|
|
6504
|
+
if (value.kind === "page")
|
|
6505
|
+
return isPageTarget(value);
|
|
6506
|
+
if (value.kind === "panel")
|
|
6507
|
+
return isPanelTarget(value);
|
|
6508
|
+
if (value.kind === "href")
|
|
6509
|
+
return isNavigationHref(value.href);
|
|
6510
|
+
return value.kind === "command" && isRecord(value.target) && isContributionRef(value.target.command, "command") && (value.target.params === undefined || isRecord(value.target.params));
|
|
6511
|
+
};
|
|
6512
|
+
var isNavigationTarget = (value) => {
|
|
6513
|
+
if (isItemTarget(value))
|
|
6514
|
+
return true;
|
|
6515
|
+
if (!isRecord(value) || value.kind !== "compound" || !Array.isArray(value.targets) || value.targets.length === 0) {
|
|
6516
|
+
return false;
|
|
6517
|
+
}
|
|
6518
|
+
return value.targets.every((target) => isPageTarget(target) || isPanelTarget(target));
|
|
6519
|
+
};
|
|
6520
|
+
var withExtensionOwner = (ref, extensionId) => ref.extensionId !== undefined || extensionId === undefined ? ref : { ...ref, extensionId };
|
|
6521
|
+
var toPageTarget = (target, extensionId, projectId) => ({
|
|
6522
|
+
...target,
|
|
6523
|
+
page: withExtensionOwner(target.page, extensionId),
|
|
6524
|
+
...target.resource ? { resource: qualifyResource(target.resource, extensionId, projectId) } : {},
|
|
6525
|
+
...target.parent ? { parent: toPageTarget(target.parent, extensionId, projectId) } : {}
|
|
6526
|
+
});
|
|
6527
|
+
var qualifyResource = (resource, extensionId, projectId) => ({
|
|
6528
|
+
...resource,
|
|
6529
|
+
extensionId: resource.extensionId ?? extensionId,
|
|
6530
|
+
projectId: resource.projectId ?? projectId
|
|
6531
|
+
});
|
|
6532
|
+
var qualifyNavigationTarget = (target, extensionId, projectId) => {
|
|
6533
|
+
if (!isNavigationTarget(target))
|
|
6534
|
+
throw new Error("Invalid navigation target.");
|
|
6535
|
+
if (target.kind === "page")
|
|
6536
|
+
return toPageTarget(target, extensionId, projectId);
|
|
6537
|
+
if (target.kind === "panel")
|
|
6538
|
+
return {
|
|
6539
|
+
...target,
|
|
6540
|
+
panel: target.panel.kind === "page-slot" ? { ...target.panel, page: withExtensionOwner(target.panel.page, extensionId) } : withExtensionOwner(target.panel, extensionId),
|
|
6541
|
+
...target.resource ? { resource: qualifyResource(target.resource, extensionId, projectId) } : {}
|
|
6542
|
+
};
|
|
6543
|
+
if (target.kind === "command")
|
|
6544
|
+
return { ...target, target: { ...target.target, command: withExtensionOwner(target.target.command, extensionId) } };
|
|
6545
|
+
if (target.kind === "href")
|
|
6546
|
+
return target;
|
|
6547
|
+
return {
|
|
6548
|
+
...target,
|
|
6549
|
+
targets: target.targets.map((item) => qualifyNavigationTarget(item, extensionId, projectId))
|
|
6550
|
+
};
|
|
6551
|
+
};
|
|
6456
6552
|
// ../pstdio-api-contracts/src/extension-kernel/package-asset.ts
|
|
6457
6553
|
var packageAsset = (path, baseUrl) => ({
|
|
6458
6554
|
kind: "package-asset",
|
package/dist/testing/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/testing/memory-resources.ts
|
|
2
2
|
var createMemoryResources = (prefixes, sequences = new Map) => ({
|
|
3
|
+
removed: async () => {},
|
|
3
4
|
allocate: async ({ kind }) => {
|
|
4
5
|
const prefix = prefixes[kind];
|
|
5
6
|
if (!prefix)
|
|
@@ -28,6 +29,7 @@ var makeCommandContext = (input) => {
|
|
|
28
29
|
project: { id: projectId, name: "Test Project", shorthand: "T" },
|
|
29
30
|
storage,
|
|
30
31
|
resources,
|
|
32
|
+
navigation: { open: () => {} },
|
|
31
33
|
invocation: { params },
|
|
32
34
|
events: { emit: async () => ({ delivered: 0 }) },
|
|
33
35
|
notify: { action: async () => ({}), dismiss: async () => [], resolve: async () => [], toast: async () => {} },
|
|
@@ -57,6 +59,11 @@ var createMemoryRepoFiles = () => {
|
|
|
57
59
|
writeText: async (path, value) => {
|
|
58
60
|
files.set(path, encoder.encode(value));
|
|
59
61
|
},
|
|
62
|
+
updateText: async (path, value) => {
|
|
63
|
+
if (!files.has(path))
|
|
64
|
+
throw new Error(`File not found: ${path}`);
|
|
65
|
+
files.set(path, encoder.encode(value));
|
|
66
|
+
},
|
|
60
67
|
readBytes: async (path) => {
|
|
61
68
|
const value = files.get(path);
|
|
62
69
|
if (value === undefined)
|
|
@@ -170,6 +177,11 @@ var createMemoryStorage = () => {
|
|
|
170
177
|
async put(id, value) {
|
|
171
178
|
store.set(id, value);
|
|
172
179
|
},
|
|
180
|
+
async update(id, value) {
|
|
181
|
+
if (!store.has(id))
|
|
182
|
+
throw new Error(`Item not found: ${id}`);
|
|
183
|
+
store.set(id, value);
|
|
184
|
+
},
|
|
173
185
|
async createIfAbsent(id, value) {
|
|
174
186
|
if (store.has(id))
|
|
175
187
|
return false;
|
package/dist/testing.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ declare interface ArtifactMount {
|
|
|
10
10
|
exists(path: string): Promise<boolean>;
|
|
11
11
|
readText(path: string): Promise<string>;
|
|
12
12
|
writeText(path: string, value: string): Promise<void>;
|
|
13
|
+
/** Replace existing text. Fails if missing and never recreates a concurrently deleted file. */
|
|
14
|
+
updateText(path: string, value: string): Promise<void>;
|
|
13
15
|
readBytes(path: string): Promise<Uint8Array>;
|
|
14
16
|
writeBytes(path: string, value: Uint8Array): Promise<void>;
|
|
15
17
|
list(pattern?: string): Promise<ArtifactFile[]>;
|
|
@@ -88,6 +90,7 @@ declare type CommandOutcome<TResult = unknown> = {
|
|
|
88
90
|
ok: true;
|
|
89
91
|
status: "success";
|
|
90
92
|
value: TResult;
|
|
93
|
+
navigationRequests?: NavigationTarget[];
|
|
91
94
|
notices?: CommandNotice[];
|
|
92
95
|
diagnostics?: CommandDiagnostic[];
|
|
93
96
|
} | {
|
|
@@ -283,6 +286,10 @@ declare interface ExtensionContextBase<TSettings extends Record<string, unknown>
|
|
|
283
286
|
source?: CommandSource;
|
|
284
287
|
storage: ExtensionStorageApi;
|
|
285
288
|
resources: ExtensionResourcesApi;
|
|
289
|
+
/** Records navigation for the invoking UI; headless execution opens nothing. */
|
|
290
|
+
navigation: {
|
|
291
|
+
open(target: NavigationTarget): void;
|
|
292
|
+
};
|
|
286
293
|
artifacts: ExtensionArtifactApi;
|
|
287
294
|
/** Working tree of the invocation's repo, scoped to its root. Absent for non-repo (event/hook) invocations. */
|
|
288
295
|
repoFiles?: ArtifactMount;
|
|
@@ -394,6 +401,8 @@ declare interface ExtensionReposApi {
|
|
|
394
401
|
}
|
|
395
402
|
|
|
396
403
|
declare interface ExtensionResourcesApi {
|
|
404
|
+
/** Publish a committed removal to clients displaying this project resource. */
|
|
405
|
+
removed(resource: ResourceRef): Promise<void>;
|
|
397
406
|
allocate(input: {
|
|
398
407
|
kind: string;
|
|
399
408
|
}): Promise<{
|
|
@@ -480,6 +489,8 @@ declare interface ExtensionStorageCollectionApi<TItem = unknown> {
|
|
|
480
489
|
get(id: string): Promise<TItem | undefined>;
|
|
481
490
|
list(): Promise<TItem[]>;
|
|
482
491
|
put(id: string, value: TItem): Promise<void>;
|
|
492
|
+
/** Replace an existing item atomically. Throws if the item was deleted. */
|
|
493
|
+
update(id: string, value: TItem): Promise<void>;
|
|
483
494
|
createIfAbsent(id: string, value: TItem): Promise<boolean>;
|
|
484
495
|
deleteIfValue(id: string, value: TItem): Promise<boolean>;
|
|
485
496
|
create(value: TItem): Promise<TItem & {
|