@pstdio/sdk 0.25.0 → 0.35.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/data.d.ts CHANGED
@@ -1,49 +1,27 @@
1
- export declare const applyFrontmatter: (frontmatter: string, content: string) => string;
2
-
3
- declare interface ArtifactFile {
4
- path: string;
5
- size?: number;
6
- updatedAt?: string;
7
- }
8
-
9
- declare interface ArtifactMount {
10
- exists(path: string): Promise<boolean>;
11
- readText(path: string): Promise<string>;
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>;
15
- readBytes(path: string): Promise<Uint8Array>;
16
- writeBytes(path: string, value: Uint8Array): Promise<void>;
17
- list(pattern?: string): Promise<ArtifactFile[]>;
18
- listDirs(path?: string): Promise<string[]>;
19
- delete(path: string): Promise<void>;
20
- }
21
-
22
- export declare const assertSafePathSegment: (value: string) => void;
23
-
24
- export declare const createDraftLayout: (root: string, document: string) => {
25
- directory: (name: string) => string;
26
- markdown: (name: string, suffix?: string) => string;
27
- files: (name: string, suffix?: string) => string;
28
- };
29
-
30
- export declare const findClosingFrontmatterDelimiter: (content: string) => {
31
- end: number;
32
- start: number;
33
- } | null;
34
-
35
- export declare const quoteYamlScalar: (value: string) => string;
36
-
37
- export declare const requireRepoFiles: (repoFiles: ArtifactMount | undefined) => ArtifactMount;
38
-
39
- export declare const resolveByIdOrName: <TItem extends {
40
- id: string;
41
- }>(items: TItem[], value: string, nameOf: (item: TItem) => string, label: string) => string;
42
-
43
- export declare const sameName: (a: string, b: string) => boolean;
44
-
45
- export declare const stripFrontmatter: (content: string) => string;
46
-
47
- export declare const unquoteYamlScalar: (value: string) => string;
48
-
49
- export { }
1
+ import { Lr as ArtifactMount } from "./index-x7CdJPRb.js";
2
+ //#region src/data/draft-layout.d.ts
3
+ export declare const assertSafePathSegment: (value: string) => void;
4
+ export declare const requireRepoFiles: (repoFiles: ArtifactMount | undefined) => ArtifactMount;
5
+ export declare const createDraftLayout: (root: string, document: string) => {
6
+ directory: (name: string) => string;
7
+ markdown: (name: string, suffix?: string) => string;
8
+ files: (name: string, suffix?: string) => string;
9
+ };
10
+ //#endregion
11
+ //#region src/data/frontmatter.d.ts
12
+ export declare const quoteYamlScalar: (value: string) => string;
13
+ export declare const findClosingFrontmatterDelimiter: (content: string) => {
14
+ end: number;
15
+ start: number;
16
+ } | null;
17
+ export declare const stripFrontmatter: (content: string) => string;
18
+ export declare const applyFrontmatter: (frontmatter: string, content: string) => string;
19
+ export declare const unquoteYamlScalar: (value: string) => string;
20
+ //#endregion
21
+ //#region src/data/resolve.d.ts
22
+ export declare const sameName: (a: string, b: string) => boolean;
23
+ export declare const resolveByIdOrName: <TItem extends {
24
+ id: string;
25
+ }>(items: TItem[], value: string, nameOf: (item: TItem) => string, label: string) => string;
26
+ //#endregion
27
+ export {};
@@ -1,3 +1,7 @@
1
+ // ../pstdio-api-contracts/src/extension-kernel/api-versions.ts
2
+ var numericIdentifier = "(?:0|[1-9]\\d*)";
3
+ var prereleaseIdentifier = `(?:${numericIdentifier}|\\d*[A-Za-z-][0-9A-Za-z-]*)`;
4
+ var exactVersion = new RegExp(`^${numericIdentifier}\\.${numericIdentifier}\\.${numericIdentifier}(?:-${prereleaseIdentifier}(?:\\.${prereleaseIdentifier})*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$`);
1
5
  // ../pstdio-api-contracts/src/extension-kernel/types/composition.ts
2
6
  var dockedWorkbenchRegions = ["sidenav", "main", "secondary", "side"];
3
7
  var extensionPanelRegions = ["main", "secondary", "side"];
@@ -133,6 +137,11 @@ var workspaceSlots = {
133
137
  var projectEvents = {
134
138
  opened: hostEventRef("project.opened")
135
139
  };
140
+ var viewDataEvents = {
141
+ sessionsChanged: hostEventRef("view.sessions.changed"),
142
+ workspacesChanged: hostEventRef("view.workspaces.changed"),
143
+ repositoriesChanged: hostEventRef("view.repositories.changed")
144
+ };
136
145
  var sessionEvents = {
137
146
  started: hostEventRef("session.started"),
138
147
  resumed: hostEventRef("session.resumed"),
@@ -291,8 +300,181 @@ var WEBVIEW_HOST_CAPABILITIES = [
291
300
  ...WEBVIEW_SCOPED_DECLARABLE_CAPABILITIES,
292
301
  ...ALWAYS_AVAILABLE_WEBVIEW_CAPABILITIES
293
302
  ];
303
+ // ../pstdio-api-contracts/src/history-turn-evidence.ts
304
+ var historyTurnEvidence = (known, native, prompt, body) => {
305
+ const signatures = (turn) => JSON.stringify([prompt(turn), body(turn)]);
306
+ if (known.length === native.length && known.every((turn, index) => signatures(turn) === signatures(native[index]))) {
307
+ return signatures;
308
+ }
309
+ const tokens = (turns) => {
310
+ const positions = new Map;
311
+ turns.forEach((turn, index) => {
312
+ for (const value of new Set(body(turn))) {
313
+ const token = JSON.stringify([prompt(turn), value]);
314
+ positions.set(token, positions.has(token) ? -1 : index);
315
+ }
316
+ });
317
+ return positions;
318
+ };
319
+ const left = tokens(known);
320
+ const right = tokens(native);
321
+ const matches = new Map;
322
+ const reverse = new Map;
323
+ for (const [token, index] of left) {
324
+ const other = right.get(token);
325
+ if (index < 0 || other === undefined || other < 0)
326
+ continue;
327
+ const targets = matches.get(index) ?? new Set;
328
+ targets.add(other);
329
+ matches.set(index, targets);
330
+ const sources = reverse.get(other) ?? new Set;
331
+ sources.add(index);
332
+ reverse.set(other, sources);
333
+ }
334
+ const keys = new Map;
335
+ known.forEach((turn, index) => {
336
+ keys.set(turn, `known:${index}`);
337
+ });
338
+ native.forEach((turn, index) => {
339
+ keys.set(turn, `native:${index}`);
340
+ });
341
+ for (const [index, targets] of matches) {
342
+ if (targets.size !== 1)
343
+ continue;
344
+ const other = [...targets][0];
345
+ if (reverse.get(other)?.size !== 1)
346
+ continue;
347
+ const key = `pair:${index}:${other}`;
348
+ keys.set(known[index], key);
349
+ keys.set(native[other], key);
350
+ }
351
+ return (turn) => keys.get(turn);
352
+ };
353
+
354
+ // ../pstdio-api-contracts/src/history-reconciliation.ts
355
+ class HistoryConflict extends Error {
356
+ }
357
+ var submittedPrompt = (message) => message.parts.filter((part) => part.type === "text").map((part) => part.text).join(`
358
+ `).replace(/\n\n<session-attachments>[\s\S]*<\/session-attachments>\s*$/, "").trim();
359
+ var historyValueKey = (value) => JSON.stringify(value, (_key, item) => {
360
+ if (!item || typeof item !== "object" || Array.isArray(item))
361
+ return item;
362
+ return Object.fromEntries(Object.entries(item).sort(([a], [b]) => a.localeCompare(b)));
363
+ });
364
+ var historyMessageKey = (message) => historyValueKey([message.role, message.parts]);
365
+ var positions = (items, key) => {
366
+ const result = new Map;
367
+ items.forEach((item, index) => {
368
+ const value = key(item);
369
+ const indices = result.get(value) ?? [];
370
+ indices.push(index);
371
+ result.set(value, indices);
372
+ });
373
+ return result;
374
+ };
375
+ var mergeOrderedHistory = (known, native, key, merge, refineKey) => {
376
+ if (!known.length)
377
+ return native;
378
+ if (!native.length)
379
+ return known;
380
+ const knownPositions = positions(known, key);
381
+ const nativePositions = positions(native, key);
382
+ const anchors = [];
383
+ for (const [value, indices] of knownPositions) {
384
+ const other = nativePositions.get(value);
385
+ if (indices.length === 1 && other?.length === 1)
386
+ anchors.push([indices[0], other[0]]);
387
+ }
388
+ if (!anchors.length) {
389
+ if (refineKey) {
390
+ const refined = mergeOrderedHistory(known, native, refineKey(known, native), merge);
391
+ return refined;
392
+ }
393
+ if (known.length === native.length && known.every((item, index) => key(item) === key(native[index]))) {
394
+ return known.map((item, index) => merge(item, native[index]));
395
+ }
396
+ throw new HistoryConflict("ambiguous_interval");
397
+ }
398
+ let left = 0;
399
+ let right = 0;
400
+ const result = [];
401
+ for (const [a, b] of anchors) {
402
+ if (b < right)
403
+ throw new HistoryConflict("conflicting_order");
404
+ result.push(...mergeOrderedHistory(known.slice(left, a), native.slice(right, b), key, merge, refineKey));
405
+ result.push(merge(known[a], native[b]));
406
+ left = a + 1;
407
+ right = b + 1;
408
+ }
409
+ result.push(...mergeOrderedHistory(known.slice(left), native.slice(right), key, merge, refineKey));
410
+ return result;
411
+ };
412
+ var splitHistoryTurns = (messages) => {
413
+ const turns = [];
414
+ for (const message of messages) {
415
+ if (message.role === "user" || !turns.length)
416
+ turns.push([]);
417
+ turns[turns.length - 1].push(message);
418
+ }
419
+ return turns;
420
+ };
421
+ var mergeHistoryMetadata = (known, native) => {
422
+ const files = native.parts.filter((part) => part.type === "file");
423
+ const fileKeys = new Set(files.map((part) => part.fileId ?? part.url));
424
+ const missing = known.parts.filter((part) => part.type === "file" && !fileKeys.has(part.fileId ?? part.url));
425
+ const parts = native.role === "user" ? [...known.parts.filter((part) => part.type === "text"), ...native.parts.filter((part) => part.type !== "text")] : native.parts;
426
+ return { ...known, ...native, parts: [...parts, ...missing] };
427
+ };
428
+ var isUsage = (message) => message.role === "system" && message.parts.length > 0 && message.parts.every((part) => part.type === "token_usage");
429
+ var combineTextRuns = (messages) => {
430
+ const runs = [];
431
+ for (const message of messages) {
432
+ const previous = runs.at(-1);
433
+ const part = message.parts[0];
434
+ const previousPart = previous?.parts[0];
435
+ if (previous && message.role === previous.role && message.parts.length === 1 && previous.parts.length === 1 && (part.type === "text" || part.type === "reasoning") && previousPart?.type === part.type) {
436
+ runs[runs.length - 1] = { ...previous, parts: [{ ...part, text: previousPart.text + part.text }] };
437
+ } else
438
+ runs.push(message);
439
+ }
440
+ return runs;
441
+ };
442
+ var reconcileMessageHistory = (input, projection = {}) => {
443
+ const key = projection.key ?? historyMessageKey;
444
+ const merge = projection.merge ?? mergeHistoryMetadata;
445
+ const generated = projection.isGenerated ?? isUsage;
446
+ const mergeTurn = (known, native) => {
447
+ const startsWithUser = known[0]?.role === "user" && native[0]?.role === "user";
448
+ const body = (turn) => combineTextRuns(turn.slice(startsWithUser ? 1 : 0).filter((message) => !generated(message)));
449
+ const messages = mergeOrderedHistory(body(known), body(native), key, merge);
450
+ const metadata = [...native.filter(generated)];
451
+ const counts = new Map;
452
+ metadata.forEach((message) => {
453
+ counts.set(historyMessageKey(message), (counts.get(historyMessageKey(message)) ?? 0) + 1);
454
+ });
455
+ for (const message of known.filter(generated)) {
456
+ const value = historyMessageKey(message);
457
+ const remaining = counts.get(value) ?? 0;
458
+ if (remaining)
459
+ counts.set(value, remaining - 1);
460
+ else
461
+ metadata.push(message);
462
+ }
463
+ return [...startsWithUser ? [mergeHistoryMetadata(known[0], native[0])] : [], ...messages, ...metadata];
464
+ };
465
+ try {
466
+ const prompt = (turn) => turn[0]?.role === "user" ? `user:${submittedPrompt(turn[0])}` : "prefix";
467
+ const turns = mergeOrderedHistory(splitHistoryTurns(input.knownMessages), splitHistoryTurns(input.nativeMessages), prompt, mergeTurn, (known, native) => historyTurnEvidence(known, native, prompt, (turn) => combineTextRuns(turn.slice(1).filter((message) => !generated(message))).map(key)));
468
+ const messages = turns.flat().map((message, index) => message.index === undefined ? message : { ...message, index });
469
+ return { kind: "recovered", messages };
470
+ } catch (error) {
471
+ if (error instanceof HistoryConflict)
472
+ return { kind: "conflict", category: error.message };
473
+ throw error;
474
+ }
475
+ };
294
476
  // package.json
295
- var version = "0.25.0";
477
+ var version = "0.35.0";
296
478
 
297
479
  // src/version.ts
298
480
  var SDK_VERSION = version;
@@ -732,7 +914,8 @@ var createWebviewClient = (host, options) => {
732
914
  const runCommand = async (commandKey, params) => {
733
915
  const response = await host.call("commands.execute", {
734
916
  commandId: `${extensionId}.command.${commandKey}`,
735
- params
917
+ params,
918
+ ...options?.workspaceId ? { workspaceId: options.workspaceId } : {}
736
919
  });
737
920
  return unwrapCommandOutcome(response);
738
921
  };
@@ -776,6 +959,7 @@ export {
776
959
  ALWAYS_AVAILABLE_WEBVIEW_CAPABILITIES,
777
960
  EXTENSION_API_VERSION,
778
961
  EXTENSION_EVENTS_SCOPE,
962
+ HistoryConflict,
779
963
  SDK_VERSION,
780
964
  WEBVIEW_DECLARABLE_CAPABILITIES,
781
965
  WEBVIEW_HOST_CAPABILITIES,
@@ -824,6 +1008,8 @@ export {
824
1008
  eventRef,
825
1009
  extensionPanelRegions,
826
1010
  gitEvents,
1011
+ historyMessageKey,
1012
+ historyValueKey,
827
1013
  isLocalizedString,
828
1014
  isNavigationTarget,
829
1015
  isValidLocalContributionId,
@@ -832,6 +1018,8 @@ export {
832
1018
  localContributionIdGrammar,
833
1019
  localContributionIdPattern,
834
1020
  matchesResourceWhen,
1021
+ mergeHistoryMetadata,
1022
+ mergeOrderedHistory,
835
1023
  packageAsset,
836
1024
  params,
837
1025
  parsePageUrl,
@@ -841,6 +1029,7 @@ export {
841
1029
  projectSlots,
842
1030
  qualifyNavigationTarget,
843
1031
  qualifyRef,
1032
+ reconcileMessageHistory,
844
1033
  resolveEventReferenceId,
845
1034
  resourceKey,
846
1035
  resourceMenuSlotRef2 as resourceMenuSlotRef,
@@ -848,7 +1037,10 @@ export {
848
1037
  serializeWorkbenchPageUrl,
849
1038
  sessionEvents,
850
1039
  sessionSlots,
1040
+ splitHistoryTurns,
1041
+ submittedPrompt,
851
1042
  unwrapCommandOutcome,
1043
+ viewDataEvents,
852
1044
  workbenchModeDefinitions,
853
1045
  workbenchModes,
854
1046
  workbenchPageDefinitions,
@@ -1,23 +1,18 @@
1
- import { QueryKey } from '@tanstack/react-query';
2
- import { UseMutationResult } from '@tanstack/react-query';
3
- import { UseQueryResult } from '@tanstack/react-query';
4
-
5
- declare interface CommandMutationInput<TParams, TResult> {
6
- command: (params: TParams) => Promise<TResult>;
7
- invalidate?: QueryKey[];
8
- }
9
-
10
- declare interface CommandQueryInput<TResult> {
11
- queryKey: QueryKey;
12
- command: () => Promise<TResult>;
13
- enabled?: boolean;
14
- staleTime?: number;
15
- }
16
-
17
- /** Writes server state via a typed client command and refreshes affected queries on success. */
18
- export declare const useCommandMutation: <TParams, TResult>(input: CommandMutationInput<TParams, TResult>) => UseMutationResult<TResult, Error, TParams, unknown>;
19
-
20
- /** Reads server state via a typed client command, cached and deduped by react-query. */
21
- export declare const useCommandQuery: <TResult>(input: CommandQueryInput<TResult>) => UseQueryResult<TResult>;
22
-
23
- export { }
1
+ import { QueryKey, UseQueryResult } from "@tanstack/react-query";
2
+ //#region src/extensions/react/index.d.ts
3
+ interface CommandQueryInput<TResult> {
4
+ queryKey: QueryKey;
5
+ command: () => Promise<TResult>;
6
+ enabled?: boolean;
7
+ staleTime?: number;
8
+ }
9
+ /** Reads server state via a typed client command, cached and deduped by react-query. */
10
+ export declare const useCommandQuery: <TResult>(input: CommandQueryInput<TResult>) => UseQueryResult<TResult>;
11
+ interface CommandMutationInput<TParams, TResult> {
12
+ command: (params: TParams) => Promise<TResult>;
13
+ invalidate?: QueryKey[];
14
+ }
15
+ /** Writes server state via a typed client command and refreshes affected queries on success. */
16
+ export declare const useCommandMutation: <TParams, TResult>(input: CommandMutationInput<TParams, TResult>) => import("@tanstack/react-query").UseMutationResult<TResult, Error, TParams, unknown>;
17
+ //#endregion
18
+ export {};