@pstdio/sdk 0.39.0 → 0.41.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.
@@ -1,4 +1,4 @@
1
- import { d as WorkspaceListItem$1, s as Workspace$1 } from "./index-Dd4tqVV7.js";
1
+ import { d as WorkspaceListItem$1, s as Workspace$1 } from "./index-BvsVU-eX.js";
2
2
  //#region src/resources/workspace.d.ts
3
3
  type Workspace = Workspace$1;
4
4
  type WorkspaceListItem = WorkspaceListItem$1;
@@ -6263,6 +6263,7 @@ var agentSkillsLayoutSchema = object({
6263
6263
  });
6264
6264
  var localizableSchema = union([string2(), object({ $l10n: string2(), default: string2().optional() })]);
6265
6265
  var harnessParamBaseSchema = object({
6266
+ control: literal("command").optional(),
6266
6267
  label: localizableSchema.optional(),
6267
6268
  description: localizableSchema.optional(),
6268
6269
  required: boolean2().optional(),
@@ -6597,6 +6598,29 @@ var isNavigationHref = (href) => {
6597
6598
  }
6598
6599
  };
6599
6600
 
6601
+ // ../pstdio-api-contracts/src/extension-kernel/source-position.ts
6602
+ var isFileSourcePosition = (value) => {
6603
+ if (!value || typeof value !== "object" || Array.isArray(value))
6604
+ return false;
6605
+ const position = value;
6606
+ const positive = (number) => typeof number === "number" && Number.isSafeInteger(number) && number > 0;
6607
+ if (!positive(position.line))
6608
+ return false;
6609
+ for (const key of ["column", "endLine", "endColumn"]) {
6610
+ if (position[key] !== undefined && !positive(position[key]))
6611
+ return false;
6612
+ }
6613
+ if (position.endColumn !== undefined && position.endLine === undefined)
6614
+ return false;
6615
+ if (position.endLine !== undefined) {
6616
+ if (position.endLine < position.line)
6617
+ return false;
6618
+ if (position.endLine === position.line && (position.endColumn ?? 1) < (position.column ?? 1))
6619
+ return false;
6620
+ }
6621
+ return true;
6622
+ };
6623
+
6600
6624
  // ../pstdio-api-contracts/src/extensions/resource-ref.ts
6601
6625
  var extensionResourceRefSchema = object({
6602
6626
  shorthand: string2().optional(),
@@ -6628,6 +6652,12 @@ var commandTargetSchema = object({
6628
6652
  });
6629
6653
 
6630
6654
  // ../pstdio-api-contracts/src/extensions/navigation-target-metadata.ts
6655
+ var sourcePositionSchema = object({
6656
+ line: number2().int().positive(),
6657
+ column: number2().int().positive().optional(),
6658
+ endLine: number2().int().positive().optional(),
6659
+ endColumn: number2().int().positive().optional()
6660
+ }).refine(isFileSourcePosition, "Expected ordered source coordinates");
6631
6661
  var sectionSchema = object({
6632
6662
  anchors: array(object({ id: string2(), heading: string2(), occurrence: number2().int().nonnegative().optional() }))
6633
6663
  });
@@ -6637,8 +6667,9 @@ var pageTargetSchema = lazy(() => object({
6637
6667
  resource: extensionResourceRefSchema.optional(),
6638
6668
  open: _enum(["preview", "pin"]).optional(),
6639
6669
  section: sectionSchema.optional(),
6670
+ position: sourcePositionSchema.optional(),
6640
6671
  parent: pageTargetSchema.optional()
6641
- })).meta({ id: "WorkbenchMetadataPageTarget" });
6672
+ }).refine((value) => !(value.position && value.section), "Choose a source position or a heading section")).meta({ id: "WorkbenchMetadataPageTarget" });
6642
6673
  var navigationOperationSchema = union([
6643
6674
  pageTargetSchema,
6644
6675
  object({
@@ -6930,6 +6961,105 @@ var extensionControlsRendererRecordSchema = extensionRendererRecordBaseSchema.ex
6930
6961
  defaultValues: controlValuesSchema.optional()
6931
6962
  });
6932
6963
 
6964
+ // ../pstdio-api-contracts/src/extension-kernel/types/collection-view.ts
6965
+ var optionConditions = ["is-any-of", "is-none-of", "is-empty", "is-not-empty"];
6966
+ var VIEW_FILTER_CONDITIONS = {
6967
+ boolean: ["is", "is-not", "is-empty", "is-not-empty"],
6968
+ string: ["contains", "does-not-contain", "is", "is-not", "is-empty", "is-not-empty"],
6969
+ number: ["is", "is-not", "gt", "gte", "lt", "lte", "is-empty", "is-not-empty"],
6970
+ date: ["is", "is-before", "is-after", "is-on-or-before", "is-on-or-after", "is-empty", "is-not-empty"],
6971
+ enum: optionConditions,
6972
+ status: optionConditions,
6973
+ user: optionConditions,
6974
+ "enum-multi": ["has-any-of", "has-all-of", "has-none-of", "is-empty", "is-not-empty"]
6975
+ };
6976
+
6977
+ // ../pstdio-api-contracts/src/extensions/collection-view.ts
6978
+ var VIEW_DAY_PATTERN = /^(\d{4}-\d{2}-\d{2}|today([+-]\d+)?)$/;
6979
+ var conditionIds = [...new Set(Object.values(VIEW_FILTER_CONDITIONS).flat())];
6980
+ var viewFilterConditionSchema = _enum(conditionIds);
6981
+ var viewFilterRuleSchema = object({
6982
+ attributeId: string2().min(1),
6983
+ condition: viewFilterConditionSchema,
6984
+ value: union([boolean2(), string2(), number2(), array(string2())]).optional()
6985
+ });
6986
+ var advancedFilterGroupSchema = strictObject({
6987
+ conjunction: _enum(["and", "or"]),
6988
+ rules: array(viewFilterRuleSchema)
6989
+ });
6990
+ var viewFilterGroupSchema = advancedFilterGroupSchema.extend({
6991
+ groups: array(advancedFilterGroupSchema).optional()
6992
+ }).refine((filter) => !filter.groups?.length || filter.conjunction === "and", {
6993
+ message: "Normal rules and advanced groups combine using AND"
6994
+ });
6995
+ var viewSortSchema = object({ attributeId: string2().min(1), direction: _enum(["asc", "desc"]) });
6996
+ var viewSortsSchema = array(viewSortSchema).max(1, "A view allows only one sort");
6997
+ var viewFilterValueKind = (kind, condition) => {
6998
+ if (condition === "is-empty" || condition === "is-not-empty")
6999
+ return "none";
7000
+ if (condition === "is-any-of" || condition === "is-none-of")
7001
+ return "options";
7002
+ if (kind === "boolean")
7003
+ return "boolean";
7004
+ if (kind === "number")
7005
+ return "number";
7006
+ if (kind === "date")
7007
+ return "day";
7008
+ if (kind === "string")
7009
+ return "text";
7010
+ return "options";
7011
+ };
7012
+ var valueNeeds = {
7013
+ none: "takes no value",
7014
+ boolean: "needs a boolean",
7015
+ number: "needs a number",
7016
+ day: "needs a day such as 2026-10-02, today, or today-7",
7017
+ text: "needs text",
7018
+ options: "needs a list of option values"
7019
+ };
7020
+ var valueFits = (value, kind) => {
7021
+ if (value === undefined)
7022
+ return true;
7023
+ if (kind === "none")
7024
+ return false;
7025
+ if (kind === "boolean")
7026
+ return typeof value === "boolean";
7027
+ if (kind === "number")
7028
+ return typeof value === "number" && Number.isFinite(value);
7029
+ if (kind === "day")
7030
+ return typeof value === "string" && VIEW_DAY_PATTERN.test(value);
7031
+ if (kind === "text")
7032
+ return typeof value === "string";
7033
+ return Array.isArray(value);
7034
+ };
7035
+ var ruleProblem = (rule, fields) => {
7036
+ const filterable = fields.filter((field) => field.filterable);
7037
+ const field = filterable.find((field) => field.id === rule.attributeId);
7038
+ if (!field)
7039
+ return `Invalid filter field "${rule.attributeId}". Valid IDs: ${filterable.map((field) => field.id).join(", ")}`;
7040
+ const conditions = VIEW_FILTER_CONDITIONS[field.kind];
7041
+ const legacyList = ["is-any-of", "is-none-of"].includes(rule.condition) && ["string", "number", "date"].includes(field.kind);
7042
+ if (!conditions.includes(rule.condition) && !legacyList)
7043
+ return `Field "${field.id}" does not accept "${rule.condition}". Valid conditions: ${conditions.join(", ")}`;
7044
+ const valueKind = viewFilterValueKind(field.kind, rule.condition);
7045
+ if (!valueFits(rule.value, valueKind))
7046
+ return `Condition "${rule.condition}" on "${field.id}" ${valueNeeds[valueKind]}`;
7047
+ const options = field.options;
7048
+ const values = Array.isArray(rule.value) ? rule.value : [];
7049
+ const unknown = options ? values.find((value) => !options.some((option) => option.value === value)) : undefined;
7050
+ if (options && unknown !== undefined)
7051
+ return `Invalid filter value "${unknown}" for "${field.id}". Valid values: ${options.map((option) => option.value).join(", ")}`;
7052
+ return;
7053
+ };
7054
+ var findViewFilterProblem = (filter, fields) => {
7055
+ for (const rule of [...filter.rules, ...(filter.groups ?? []).flatMap((group) => group.rules)]) {
7056
+ const problem = ruleProblem(rule, fields);
7057
+ if (problem)
7058
+ return problem;
7059
+ }
7060
+ return;
7061
+ };
7062
+
6933
7063
  // ../pstdio-api-contracts/src/extensions/view-toolbar-action.ts
6934
7064
  var viewToolbarActionSchema = object({
6935
7065
  id: string2(),
@@ -6969,12 +7099,30 @@ var columnRendererSchema = discriminatedUnion("type", [
6969
7099
  var dataTableRendererColumnSchema = object({
6970
7100
  id: string2(),
6971
7101
  label: localizableStringSchema.optional(),
7102
+ type: _enum(["string", "number", "boolean", "date"]).optional(),
7103
+ groupable: boolean2().optional(),
7104
+ filterable: boolean2().optional(),
6972
7105
  description: localizableStringSchema.optional(),
6973
7106
  icon: string2().optional(),
6974
7107
  hidden: boolean2().optional(),
6975
7108
  stat: columnStatSchema.optional(),
6976
7109
  renderer: columnRendererSchema.optional()
6977
7110
  });
7111
+ var dataTableRendererSettingsSchema = object({
7112
+ grouping: string2(),
7113
+ rowNumbers: boolean2(),
7114
+ wrapRows: boolean2(),
7115
+ showStats: boolean2(),
7116
+ hiddenColumns: array(string2()),
7117
+ columnOrder: array(string2())
7118
+ });
7119
+ var dataTableRendererSavedViewSchema = object({
7120
+ id: string2(),
7121
+ title: localizableStringSchema,
7122
+ settings: dataTableRendererSettingsSchema.partial().optional(),
7123
+ filter: viewFilterGroupSchema.optional(),
7124
+ sorts: viewSortsSchema.optional()
7125
+ });
6978
7126
  var rowActionSchema = object({
6979
7127
  id: string2(),
6980
7128
  label: localizableStringSchema,
@@ -6998,7 +7146,12 @@ var extensionDataTableRendererRecordSchema = extensionRendererRecordBaseSchema.e
6998
7146
  rowActions: array(rowActionSchema).optional(),
6999
7147
  rowActivationHandlerId: string2().optional(),
7000
7148
  initialPageSize: number2().int().positive().optional(),
7001
- pageSizeOptions: array(number2().int().positive()).optional()
7149
+ pageSizeOptions: array(number2().int().positive()).optional(),
7150
+ defaultSettings: dataTableRendererSettingsSchema.partial().optional(),
7151
+ defaultFilter: viewFilterGroupSchema.optional(),
7152
+ defaultSorts: viewSortsSchema.optional(),
7153
+ defaultViews: array(dataTableRendererSavedViewSchema).optional(),
7154
+ defaultActiveViewId: string2().optional()
7002
7155
  });
7003
7156
 
7004
7157
  // ../pstdio-api-contracts/src/extensions/kanban-renderer.ts
@@ -7019,6 +7172,7 @@ var kanbanRendererAttributeTypeSchema = discriminatedUnion("kind", [
7019
7172
  id: string2()
7020
7173
  })
7021
7174
  }),
7175
+ object({ kind: literal("boolean"), legacyValues: record(string2(), boolean2()).optional() }),
7022
7176
  object({ kind: literal("string") }),
7023
7177
  object({ kind: literal("date") }),
7024
7178
  object({ kind: literal("number") }),
@@ -7039,21 +7193,18 @@ var kanbanRendererAttributeSchema = object({
7039
7193
  editable: boolean2().optional(),
7040
7194
  display: kanbanRendererAttributeDisplaySchema.optional()
7041
7195
  });
7042
- var kanbanRendererSettingsSchema = object({
7196
+ var kanbanViewSettingsSchema = object({
7043
7197
  viewMode: _enum(["board", "list"]),
7044
7198
  columnGrouping: string2(),
7045
7199
  rowGrouping: string2(),
7046
- ordering: object({
7047
- attributeId: string2(),
7048
- direction: _enum(["asc", "desc"])
7049
- }),
7050
7200
  displayProperties: array(string2())
7051
7201
  });
7052
7202
  var kanbanRendererSavedViewSchema = object({
7053
7203
  id: string2(),
7054
7204
  title: localizableStringSchema,
7055
- settings: kanbanRendererSettingsSchema,
7056
- filters: record(string2(), array(string2())),
7205
+ settings: kanbanViewSettingsSchema,
7206
+ filter: viewFilterGroupSchema,
7207
+ sorts: viewSortsSchema,
7057
7208
  isDefault: boolean2().optional()
7058
7209
  });
7059
7210
  var extensionKanbanRendererCreateRowSchema = object({
@@ -7093,8 +7244,9 @@ var extensionKanbanRendererRecordSchema = extensionRendererRecordBaseSchema.exte
7093
7244
  createRow: extensionKanbanRendererCreateRowSchema.optional(),
7094
7245
  rowActions: array(extensionKanbanRendererRowActionSchema).optional(),
7095
7246
  rowActivationHandlerId: string2().optional(),
7096
- defaultSettings: kanbanRendererSettingsSchema.partial().optional(),
7097
- defaultFilters: record(string2(), array(string2())).optional(),
7247
+ defaultSettings: kanbanViewSettingsSchema.partial().optional(),
7248
+ defaultFilter: viewFilterGroupSchema.optional(),
7249
+ defaultSorts: viewSortsSchema.optional(),
7098
7250
  defaultViews: array(kanbanRendererSavedViewSchema).optional(),
7099
7251
  defaultActiveViewId: string2().optional(),
7100
7252
  hideToolbar: boolean2().optional()
@@ -7190,6 +7342,7 @@ var workbenchExtensionPageRecordSchema = object({
7190
7342
  title: localizableStringSchema,
7191
7343
  icon: string2().optional(),
7192
7344
  path: string2(),
7345
+ document: object({ metadataKey: string2().refine((key) => key.trim().length > 0) }).optional(),
7193
7346
  mode: modeRefSchema,
7194
7347
  parent: pageRefSchema.optional(),
7195
7348
  resource: resourceConstraintSchema.optional(),
@@ -7212,6 +7365,12 @@ var extensionSettingsPanelRecordSchema = object({
7212
7365
  section: string2().optional(),
7213
7366
  webview: extensionWebviewContributionSchema
7214
7367
  });
7368
+ var extensionSettingOptionSourceSchema = object({
7369
+ commandId: string2(),
7370
+ valueField: string2(),
7371
+ labelField: string2(),
7372
+ params: record(string2(), unknown()).optional()
7373
+ });
7215
7374
  var extensionSettingDefinitionRecordSchema = object({
7216
7375
  key: string2(),
7217
7376
  extensionId: string2(),
@@ -7219,6 +7378,7 @@ var extensionSettingDefinitionRecordSchema = object({
7219
7378
  scope: extensionSettingScopeSchema,
7220
7379
  default: unknown().optional(),
7221
7380
  enum: array(unknown()).optional(),
7381
+ options: extensionSettingOptionSourceSchema.optional(),
7222
7382
  title: localizableStringSchema.optional(),
7223
7383
  description: localizableStringSchema.optional()
7224
7384
  });
@@ -7263,8 +7423,7 @@ var rendererBaseOmissions = {
7263
7423
  id: true,
7264
7424
  extensionId: true,
7265
7425
  title: true,
7266
- icon: true,
7267
- resourceKind: true
7426
+ icon: true
7268
7427
  };
7269
7428
  var commandActionSchema = object({
7270
7429
  id: string2(),
@@ -7535,6 +7694,15 @@ var listExtensionAppearanceResponseSchema = object({
7535
7694
  translations: array(extensionTranslationRecordSchema),
7536
7695
  diagnostics: workbenchExtensionMetadataSchema.shape.diagnostics
7537
7696
  });
7697
+ // ../pstdio-api-contracts/src/extension-kernel/types/data-table-renderer.ts
7698
+ var DEFAULT_DATA_TABLE_SETTINGS = {
7699
+ grouping: "none",
7700
+ rowNumbers: true,
7701
+ wrapRows: false,
7702
+ showStats: true,
7703
+ hiddenColumns: [],
7704
+ columnOrder: []
7705
+ };
7538
7706
  // ../pstdio-api-contracts/src/extensions/install.ts
7539
7707
  var enableInstalledExtensionRequestSchema = object({
7540
7708
  displayName: string2(),
@@ -7683,33 +7851,38 @@ var listAutomationRunEventsResponseSchema = object({ events: array(automationRun
7683
7851
  var boardFieldSchema = object({
7684
7852
  id: string2(),
7685
7853
  label: string2(),
7686
- kind: _enum(["enum", "enum-multi", "status", "string", "date", "number", "user"]),
7854
+ kind: _enum(["enum", "enum-multi", "status", "string", "date", "number", "boolean", "user"]),
7855
+ conditions: array(viewFilterConditionSchema),
7687
7856
  filterable: boolean2(),
7688
7857
  groupable: boolean2(),
7689
7858
  sortable: boolean2(),
7690
7859
  displayable: boolean2(),
7860
+ legacyValues: record(string2(), boolean2()).optional(),
7691
7861
  options: array(object({ value: string2(), label: string2() })).optional()
7692
7862
  });
7693
7863
  var boardSummarySchema = object({
7694
7864
  id: string2(),
7695
7865
  title: string2(),
7696
- extensionId: string2(),
7866
+ kind: _enum(["kanban", "dataTable"]),
7867
+ extensionId: string2().nullable(),
7697
7868
  fields: array(boardFieldSchema)
7698
7869
  });
7699
- var boardFiltersSchema = record(string2(), array(string2()));
7870
+ var boardViewSettingsSchema = union([kanbanViewSettingsSchema, dataTableRendererSettingsSchema]);
7700
7871
  var boardViewSchema = object({
7701
7872
  id: string2(),
7702
7873
  boardId: string2(),
7703
7874
  title: string2(),
7704
- settings: kanbanRendererSettingsSchema,
7705
- filters: boardFiltersSchema,
7875
+ settings: boardViewSettingsSchema,
7876
+ filter: viewFilterGroupSchema,
7877
+ sorts: viewSortsSchema,
7706
7878
  builtIn: boolean2()
7707
7879
  });
7708
7880
  var boardViewsSchema = object({ views: array(boardViewSchema), defaultViewId: string2() });
7709
7881
  var boardViewUpdateSchema = object({
7710
7882
  title: string2().trim().min(1).optional(),
7711
- settings: kanbanRendererSettingsSchema.partial().optional(),
7712
- filters: boardFiltersSchema.optional()
7883
+ settings: union([kanbanViewSettingsSchema.partial().strict(), dataTableRendererSettingsSchema.partial().strict()]).optional(),
7884
+ filter: viewFilterGroupSchema.optional(),
7885
+ sorts: viewSortsSchema.optional()
7713
7886
  }).strict();
7714
7887
  var boardViewCreateSchema = boardViewUpdateSchema.extend({
7715
7888
  title: string2().trim().min(1),
@@ -7718,6 +7891,24 @@ var boardViewCreateSchema = boardViewUpdateSchema.extend({
7718
7891
  // ../pstdio-api-contracts/src/extension-kernel/api-versions.ts
7719
7892
  var numericIdentifier = "(?:0|[1-9]\\d*)";
7720
7893
  var caretTerm = new RegExp(`^\\^(${numericIdentifier}\\.${numericIdentifier}\\.${numericIdentifier})$`);
7894
+ // ../pstdio-api-contracts/src/extension-kernel/boolean-view-filter.ts
7895
+ var normalizeBooleanViewRule = (rule, type) => {
7896
+ const mapping = type.kind === "boolean" ? type.legacyValues : undefined;
7897
+ if (!mapping || !Array.isArray(rule.value) || rule.value.length === 0)
7898
+ return rule;
7899
+ if (rule.condition !== "is-any-of" && rule.condition !== "is-none-of")
7900
+ return rule;
7901
+ if (rule.value.some((value) => !Object.hasOwn(mapping, value)))
7902
+ return rule;
7903
+ const values = new Set(rule.value.map((value) => mapping[value]));
7904
+ if (values.size === 2)
7905
+ return { attributeId: rule.attributeId, condition: rule.condition === "is-any-of" ? "is-not-empty" : "is-empty" };
7906
+ return {
7907
+ attributeId: rule.attributeId,
7908
+ condition: rule.condition === "is-any-of" ? "is" : "is-not",
7909
+ value: [...values][0]
7910
+ };
7911
+ };
7721
7912
  // ../pstdio-api-contracts/src/extension-kernel/builtin-refs.ts
7722
7913
  var hostRef = (kind, id) => ({ extensionId: "pstdio", kind, id });
7723
7914
  var workbenchModes = {
@@ -7809,6 +8000,24 @@ var workbenchSlots = {
7809
8000
  var localContributionIdPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*(?:\.[a-z0-9]+(?:-[a-z0-9]+)*)*$/;
7810
8001
  var isValidLocalContributionId = (id) => localContributionIdPattern.test(id);
7811
8002
  var localContributionIdGrammar = 'lowercase kebab-case segments separated by dots, such as "ticket-status.create"';
8003
+ // ../pstdio-api-contracts/src/extension-kernel/data-table-values.ts
8004
+ var resolveDataTableComparableValue = (value, renderer) => {
8005
+ if (typeof value !== "object" || value === null)
8006
+ return value;
8007
+ if ("display" in value)
8008
+ return "sortValue" in value ? value.sortValue : undefined;
8009
+ if (renderer?.type === "diff" && "additions" in value && "deletions" in value && typeof value.additions === "number" && typeof value.deletions === "number")
8010
+ return value.additions + value.deletions;
8011
+ return value;
8012
+ };
8013
+ var resolveDataTableFieldKind = (values, column = {}) => {
8014
+ if (column.type)
8015
+ return column.type;
8016
+ if (column.renderer?.type === "date")
8017
+ return "date";
8018
+ const comparable = values.map((value) => resolveDataTableComparableValue(value, column.renderer)).filter((value) => value !== null && value !== undefined);
8019
+ return comparable.length > 0 && comparable.every((value) => typeof value === "number") ? "number" : "string";
8020
+ };
7812
8021
  // ../pstdio-api-contracts/src/extension-kernel/refs.ts
7813
8022
  var createCommandRef = (input) => ({ ...input, kind: "command" });
7814
8023
  var commandRef = Object.assign(createCommandRef, {
@@ -7898,6 +8107,8 @@ var isPageTarget = (value, ancestors = new Set) => {
7898
8107
  return false;
7899
8108
  if (value.section !== undefined && !isRecord(value.section))
7900
8109
  return false;
8110
+ if (value.position !== undefined && (!isFileSourcePosition(value.position) || value.section !== undefined))
8111
+ return false;
7901
8112
  if (!isOpenIntent(value.open))
7902
8113
  return false;
7903
8114
  if (value.parent === undefined)
@@ -7971,7 +8182,7 @@ var packageAsset = (path, baseUrl) => ({
7971
8182
  baseUrl
7972
8183
  });
7973
8184
  // ../pstdio-api-contracts/src/extension-kernel/types/extension.ts
7974
- var EXTENSION_API_VERSION = "0.1.0";
8185
+ var EXTENSION_API_VERSION = "0.1.2";
7975
8186
  // ../pstdio-api-contracts/src/extension-kernel/types/webview-capabilities.ts
7976
8187
  var WEBVIEW_HOST_CAPABILITY_VERSION = 1;
7977
8188
  var WEBVIEW_DECLARABLE_CAPABILITIES = [
@@ -8014,6 +8225,66 @@ var fileRecordSchema = object({
8014
8225
  created_at: string2(),
8015
8226
  updated_at: string2()
8016
8227
  });
8228
+ // ../pstdio-api-contracts/src/harness-commands.ts
8229
+ var harnessCommandSchema = object({
8230
+ name: string2(),
8231
+ description: string2(),
8232
+ argumentHelp: string2().optional(),
8233
+ composer: object({
8234
+ label: string2(),
8235
+ modeId: string2().optional(),
8236
+ reservedArguments: array(string2()).optional()
8237
+ }).optional(),
8238
+ disabledReason: string2().optional()
8239
+ });
8240
+ var harnessModeActionSchema = object({
8241
+ id: string2(),
8242
+ label: string2(),
8243
+ icon: string2().optional(),
8244
+ argument: object({ label: string2(), value: string2().optional() }).optional()
8245
+ });
8246
+ var harnessModeSchema = object({
8247
+ id: string2(),
8248
+ label: string2(),
8249
+ description: string2(),
8250
+ state: string2(),
8251
+ indicator: object({ label: string2(), tone: _enum(["neutral", "info", "success", "warning", "error"]) }).optional(),
8252
+ tagText: string2().optional(),
8253
+ closeActionId: string2().optional(),
8254
+ confirmation: object({
8255
+ id: string2(),
8256
+ title: string2(),
8257
+ actionId: string2(),
8258
+ cancelLabel: string2().optional(),
8259
+ model: string2().optional()
8260
+ }).optional(),
8261
+ actions: array(harnessModeActionSchema)
8262
+ });
8263
+ var harnessCommandStateSchema = object({
8264
+ commands: array(harnessCommandSchema),
8265
+ modes: array(harnessModeSchema),
8266
+ slashCommands: boolean2()
8267
+ });
8268
+ var harnessOperationSchema = discriminatedUnion("kind", [
8269
+ object({ kind: literal("command"), text: string2().min(1) }).strict(),
8270
+ object({
8271
+ kind: literal("mode-action"),
8272
+ modeId: string2(),
8273
+ actionId: string2(),
8274
+ argument: string2().optional()
8275
+ }).strict()
8276
+ ]);
8277
+ var draftHarnessCommandInputSchema = object({
8278
+ project_id: string2().min(1),
8279
+ agent: string2().min(1),
8280
+ workspace_id: string2().optional(),
8281
+ model: string2().optional(),
8282
+ params: record(string2(), union([string2(), boolean2()])).optional()
8283
+ }).strict();
8284
+ var harnessOperationResponseSchema = object({
8285
+ status: _enum(["completed", "started"]),
8286
+ message: string2().optional()
8287
+ });
8017
8288
  // ../pstdio-api-contracts/src/history-turn-evidence.ts
8018
8289
  var historyTurnEvidence = (known, native, prompt, body) => {
8019
8290
  const signatures = (turn) => JSON.stringify([prompt(turn), body(turn)]);
@@ -8270,6 +8541,35 @@ var updateProjectInputSchema = object({
8270
8541
  }).refine((value) => Object.keys(value).length > 0, {
8271
8542
  message: "At least one field must be provided"
8272
8543
  });
8544
+ // ../pstdio-api-contracts/src/resource-anchors.ts
8545
+ var resourceLinkRefSchema = extensionResourceRefSchema.extend({
8546
+ type: string2().min(1),
8547
+ id: string2().min(1),
8548
+ projectId: string2().min(1).optional(),
8549
+ extensionId: string2().min(1).optional()
8550
+ });
8551
+ var resourceAnchorSchema = resourceLinkRefSchema.extend({
8552
+ role: _enum(["primary", "context", "source", "result"]).optional()
8553
+ });
8554
+ var addResourceAnchorsSchema = object({
8555
+ resource: resourceLinkRefSchema,
8556
+ anchors: array(resourceAnchorSchema).max(100)
8557
+ });
8558
+ var removeResourceAnchorsSchema = object({
8559
+ resource: resourceLinkRefSchema,
8560
+ refs: array(resourceLinkRefSchema).max(100)
8561
+ });
8562
+ var resourceAnchorQuerySchema = object({
8563
+ resource: resourceLinkRefSchema,
8564
+ direction: _enum(["outgoing", "incoming", "both"]).optional(),
8565
+ role: _enum(["primary", "context", "source", "result"]).optional(),
8566
+ cursor: string2().optional(),
8567
+ limit: number2().int().min(1).max(100).optional()
8568
+ });
8569
+ var resourceAnchorPageSchema = object({
8570
+ items: array(object({ source: resourceLinkRefSchema, target: resourceAnchorSchema })),
8571
+ nextCursor: string2().optional()
8572
+ });
8273
8573
  // ../pstdio-api-contracts/src/session-attachment-types.ts
8274
8574
  var sessionAttachmentMimeTypesByExtension = {
8275
8575
  c: "text/plain",
@@ -8445,6 +8745,9 @@ var sessionSchema = object({
8445
8745
  var sessionAttachmentRefSchema = object({
8446
8746
  file_id: string2().min(1)
8447
8747
  });
8748
+ var createSessionResponseSchema = sessionSchema.extend({
8749
+ operation_result: harnessOperationResponseSchema.optional()
8750
+ });
8448
8751
  var sessionAttachmentSchema = object({
8449
8752
  file_id: string2(),
8450
8753
  name: string2(),
@@ -8459,6 +8762,7 @@ var createSessionInputSchema = object({
8459
8762
  project_id: string2().min(1),
8460
8763
  title: string2().min(1),
8461
8764
  prompt: string2().min(1).optional(),
8765
+ operation: harnessOperationSchema.optional(),
8462
8766
  agent: string2().min(1).optional(),
8463
8767
  workspace_id: string2().optional(),
8464
8768
  anchors: array(extensionResourceRefSchema).optional(),
@@ -8468,7 +8772,8 @@ var createSessionInputSchema = object({
8468
8772
  original_session_id: string2().optional()
8469
8773
  });
8470
8774
  var questionResponseSchema = object({
8471
- answers: array(array(string2()))
8775
+ answers: array(array(string2())),
8776
+ callId: string2().min(1).optional()
8472
8777
  });
8473
8778
  var followUpInputSchema = object({
8474
8779
  prompt: string2().min(1).optional(),
@@ -8530,8 +8835,7 @@ var skillSourceKindSchema = _enum(["project", "extension"]);
8530
8835
  var skillAgentInstallationSchema = object({
8531
8836
  agent_id: string2(),
8532
8837
  agent_name: string2(),
8533
- installed_version: string2().nullable(),
8534
- outdated: boolean2()
8838
+ installed_version: string2().nullable()
8535
8839
  });
8536
8840
  var skillSchema = object({
8537
8841
  id: string2(),
@@ -8555,7 +8859,6 @@ var skillSchema = object({
8555
8859
  });
8556
8860
  var skillWithContentSchema = skillSchema.extend({
8557
8861
  installed_agents: array(string2()),
8558
- outdated_agents: array(string2()),
8559
8862
  agent_installations: array(skillAgentInstallationSchema)
8560
8863
  });
8561
8864
  var updateSkillInputSchema = object({
@@ -1,4 +1,4 @@
1
- import { Au as SkillFile, Gd as AgentModel, Kd as AgentSkillsLayout, Ud as AgentAvailabilityType, Vu as Session, Wd as AgentInfo, b as FileRecord, ju as SkillWithContent, ku as Skill, m as Settings, qd as harnessLocalId, qu as SessionStatus, v as Project } from "./index-Dd4tqVV7.js";
2
- import { n as WorkspaceListItem, t as Workspace } from "./index-Cq80VGQo.js";
1
+ import { Af as AgentAvailabilityType, Mf as AgentModel, Nf as AgentSkillsLayout, Pf as harnessLocalId, Xu as SkillFile, Yu as Skill, Zu as SkillWithContent, b as FileRecord, cd as Session, jf as AgentInfo, m as Settings, md as SessionStatus, v as Project } from "./index-BvsVU-eX.js";
2
+ import { n as WorkspaceListItem, t as Workspace } from "./index-CJNVNXEP.js";
3
3
  export { type AgentAvailabilityType, type AgentInfo, type AgentModel, type AgentSkillsLayout, type FileRecord, type Project, type Session, type SessionStatus, type Settings, type Skill, type SkillFile, type SkillWithContent, type Workspace, type WorkspaceListItem, harnessLocalId };
4
4
  export {};
@@ -0,0 +1,2 @@
1
+ import "./index-BvsVU-eX.js";
2
+ export {};
@@ -0,0 +1,2 @@
1
+ import "./index-BvsVU-eX.js";
2
+ export {};
@@ -1,6 +1,57 @@
1
+ // src/testing/memory-resource-links.ts
2
+ var createMemoryResourceLinks = (input) => {
3
+ const canonical = (ref) => {
4
+ if (ref.projectId && ref.projectId !== input.projectId)
5
+ throw new Error("Resource belongs to another project.");
6
+ return { ...ref, projectId: input.projectId, extensionId: ref.extensionId ?? input.extensionId };
7
+ };
8
+ const identity = (ref) => JSON.stringify([ref.projectId, ref.extensionId, ref.type, ref.id]);
9
+ const pair = (source, target) => JSON.stringify([identity(source), identity(target)]);
10
+ return {
11
+ addAnchors: async (resource, anchors) => {
12
+ const source = canonical(resource);
13
+ const targets = anchors.map((anchor) => ({ ...canonical(anchor), role: anchor.role ?? "context" }));
14
+ for (const target of targets)
15
+ input.edges.set(pair(source, target), { source, target });
16
+ },
17
+ removeAnchors: async (resource, refs) => {
18
+ const source = canonical(resource);
19
+ const targets = refs.map(canonical);
20
+ for (const target of targets)
21
+ input.edges.delete(pair(source, target));
22
+ },
23
+ listAnchors: async (query) => {
24
+ const ref = identity(canonical(query.resource));
25
+ const direction = query.direction ?? "outgoing";
26
+ const limit = query.limit ?? 50;
27
+ if (!Number.isInteger(limit) || limit < 1 || limit > 100)
28
+ throw new Error("Limit must be between 1 and 100.");
29
+ const rows = [...input.edges.entries()].filter(([key, edge]) => {
30
+ const outgoing = identity(edge.source) === ref && direction !== "incoming";
31
+ const incoming = identity(edge.target) === ref && direction !== "outgoing";
32
+ return (outgoing || incoming) && (!query.role || edge.target.role === query.role) && (!query.cursor || key > query.cursor);
33
+ }).sort(([a], [b]) => {
34
+ if (a === b)
35
+ return 0;
36
+ return a < b ? -1 : 1;
37
+ });
38
+ return {
39
+ items: rows.slice(0, limit).map(([, edge]) => edge),
40
+ ...rows.length > limit ? { nextCursor: rows[limit - 1][0] } : {}
41
+ };
42
+ },
43
+ removed: async (resource) => {
44
+ const ref = identity(canonical(resource));
45
+ for (const [key, edge] of input.edges)
46
+ if (identity(edge.source) === ref || identity(edge.target) === ref)
47
+ input.edges.delete(key);
48
+ }
49
+ };
50
+ };
51
+
1
52
  // src/testing/memory-resources.ts
2
- var createMemoryResources = (prefixes, sequences = new Map) => ({
3
- removed: async () => {},
53
+ var createMemoryResources = (prefixes, sequences = new Map, links = createMemoryResourceLinks({ projectId: "proj-1", extensionId: "test.extension", edges: new Map })) => ({
54
+ ...links,
4
55
  allocate: async ({ kind }) => {
5
56
  const prefix = prefixes[kind];
6
57
  if (!prefix)
@@ -12,6 +63,7 @@ var createMemoryResources = (prefixes, sequences = new Map) => ({
12
63
  });
13
64
 
14
65
  // src/testing/command-context.ts
66
+ var linksByStorage = new WeakMap;
15
67
  var sequencesByStorage = new WeakMap;
16
68
  var paramsByContext = new WeakMap;
17
69
  var makeCommandContext = (input) => {
@@ -21,7 +73,12 @@ var makeCommandContext = (input) => {
21
73
  sequences = new Map;
22
74
  sequencesByStorage.set(storage, sequences);
23
75
  }
24
- const resources = createMemoryResources(input.resourcePrefixes ?? {}, sequences);
76
+ let edges = linksByStorage.get(storage);
77
+ if (!edges) {
78
+ edges = new Map;
79
+ linksByStorage.set(storage, edges);
80
+ }
81
+ const resources = createMemoryResources(input.resourcePrefixes ?? {}, sequences, createMemoryResourceLinks({ projectId, extensionId: overrides?.extensionId ?? "test.extension", edges }));
25
82
  const context = {
26
83
  extensionId: "test.extension",
27
84
  name: "test-extension",