@zixt/host 0.0.103 → 0.0.105

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +447 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ import { homedir as homedir3 } from "node:os";
28
28
  // package.json
29
29
  var package_default = {
30
30
  name: "@zixt/host",
31
- version: "0.0.103",
31
+ version: "0.0.105",
32
32
  type: "module",
33
33
  exports: {
34
34
  ".": "./src/client.ts",
@@ -15592,7 +15592,8 @@ var uniqueGithubOperations = external_exports.array(GithubOperation).max(100).su
15592
15592
  var ApiToolPackOperation = external_exports.enum([
15593
15593
  "operation.search",
15594
15594
  "operation.inspect",
15595
- "operation.call"
15595
+ "operation.call",
15596
+ "configuration.read"
15596
15597
  ]);
15597
15598
  var uniqueApiOperations = external_exports.array(ApiToolPackOperation).max(10).superRefine((operations, ctx) => {
15598
15599
  if (new Set(operations).size !== operations.length) {
@@ -15829,6 +15830,124 @@ var IntegrationCategory = external_exports.enum([
15829
15830
  var ApiHttpMethod = external_exports.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
15830
15831
  var ApiOperationRisk = external_exports.enum(["read", "write", "destructive"]);
15831
15832
  var JsonSchemaFragment = external_exports.record(external_exports.string(), external_exports.unknown());
15833
+ var CONFIGURATION_FILE_MAX_BYTES = 1024 * 1024;
15834
+ var CONFIGURATION_FORM_MAX_FIELDS = 60;
15835
+ var ConfigurationFieldId = external_exports.string().min(1).max(64).regex(/^[a-z][a-z0-9_]*$/, "Use lowercase letters, numbers, and underscores.");
15836
+ var ConfigurationFieldBase = {
15837
+ id: ConfigurationFieldId,
15838
+ label: external_exports.string().trim().min(1).max(120),
15839
+ required: external_exports.boolean().default(false),
15840
+ placeholder: external_exports.string().max(300).optional(),
15841
+ hint: external_exports.string().max(1e3).optional(),
15842
+ tooltip: external_exports.string().max(2e3).optional()
15843
+ };
15844
+ var ConfigurationField = external_exports.discriminatedUnion("type", [
15845
+ external_exports.object({ ...ConfigurationFieldBase, type: external_exports.literal("text") }).strict(),
15846
+ external_exports.object({ ...ConfigurationFieldBase, type: external_exports.literal("textarea") }).strict(),
15847
+ external_exports.object({ ...ConfigurationFieldBase, type: external_exports.literal("url") }).strict(),
15848
+ external_exports.object({ ...ConfigurationFieldBase, type: external_exports.literal("email") }).strict(),
15849
+ external_exports.object({ ...ConfigurationFieldBase, type: external_exports.literal("secret") }).strict(),
15850
+ external_exports.object({
15851
+ ...ConfigurationFieldBase,
15852
+ type: external_exports.literal("number"),
15853
+ minimum: external_exports.number().finite().optional(),
15854
+ maximum: external_exports.number().finite().optional(),
15855
+ step: external_exports.number().positive().finite().optional()
15856
+ }).strict(),
15857
+ external_exports.object({ ...ConfigurationFieldBase, type: external_exports.literal("checkbox") }).strict(),
15858
+ external_exports.object({
15859
+ ...ConfigurationFieldBase,
15860
+ type: external_exports.literal("select"),
15861
+ options: external_exports.array(
15862
+ external_exports.object({
15863
+ value: external_exports.string().min(1).max(200),
15864
+ label: external_exports.string().trim().min(1).max(200)
15865
+ }).strict()
15866
+ ).min(1).max(100)
15867
+ }).strict(),
15868
+ external_exports.object({
15869
+ ...ConfigurationFieldBase,
15870
+ type: external_exports.literal("file"),
15871
+ acceptedMediaTypes: external_exports.array(external_exports.string().min(1).max(200)).max(30).default([]),
15872
+ maxBytes: external_exports.number().int().min(1).max(CONFIGURATION_FILE_MAX_BYTES).default(CONFIGURATION_FILE_MAX_BYTES)
15873
+ }).strict()
15874
+ ]);
15875
+ var ConfigurationSection = external_exports.object({
15876
+ id: ConfigurationFieldId,
15877
+ title: external_exports.string().trim().min(1).max(160),
15878
+ description: external_exports.string().max(2e3).optional(),
15879
+ showWhen: external_exports.object({ fieldId: ConfigurationFieldId, equals: external_exports.boolean() }).strict().optional(),
15880
+ fields: external_exports.array(ConfigurationField).min(1).max(CONFIGURATION_FORM_MAX_FIELDS)
15881
+ }).strict();
15882
+ var ConfigurationForm = external_exports.object({ sections: external_exports.array(ConfigurationSection).min(1).max(30) }).strict().superRefine((form, context) => {
15883
+ const sectionIds = form.sections.map(({ id }) => id);
15884
+ if (new Set(sectionIds).size !== sectionIds.length) {
15885
+ context.addIssue({
15886
+ code: "custom",
15887
+ path: ["sections"],
15888
+ message: "Section identifiers must be unique."
15889
+ });
15890
+ }
15891
+ const fields = form.sections.flatMap(({ fields: fields2 }) => fields2);
15892
+ if (fields.length > CONFIGURATION_FORM_MAX_FIELDS) {
15893
+ context.addIssue({
15894
+ code: "custom",
15895
+ path: ["sections"],
15896
+ message: `A connection form supports up to ${CONFIGURATION_FORM_MAX_FIELDS} fields.`
15897
+ });
15898
+ }
15899
+ const fieldIds = fields.map(({ id }) => id);
15900
+ if (new Set(fieldIds).size !== fieldIds.length) {
15901
+ context.addIssue({
15902
+ code: "custom",
15903
+ path: ["sections"],
15904
+ message: "Field identifiers must be unique across the form."
15905
+ });
15906
+ }
15907
+ const fieldsById = new Map(fields.map((field) => [field.id, field]));
15908
+ for (const [fieldIndex, field] of fields.entries()) {
15909
+ if (field.type === "number" && field.minimum !== void 0 && field.maximum !== void 0 && field.minimum > field.maximum) {
15910
+ context.addIssue({
15911
+ code: "custom",
15912
+ path: ["fields", fieldIndex, "maximum"],
15913
+ message: "Maximum must be greater than or equal to minimum."
15914
+ });
15915
+ }
15916
+ if (field.type === "select" && new Set(field.options.map(({ value }) => value)).size !== field.options.length) {
15917
+ context.addIssue({
15918
+ code: "custom",
15919
+ path: ["fields", fieldIndex, "options"],
15920
+ message: "Option values must be unique."
15921
+ });
15922
+ }
15923
+ }
15924
+ for (const [sectionIndex, section] of form.sections.entries()) {
15925
+ const condition = section.showWhen;
15926
+ if (!condition) continue;
15927
+ const controlling = fieldsById.get(condition.fieldId);
15928
+ if (!controlling || controlling.type !== "checkbox") {
15929
+ context.addIssue({
15930
+ code: "custom",
15931
+ path: ["sections", sectionIndex, "showWhen", "fieldId"],
15932
+ message: "Conditional sections must depend on a checkbox field."
15933
+ });
15934
+ }
15935
+ const controllingSection = form.sections.findIndex(
15936
+ ({ fields: candidates }) => candidates.some(({ id }) => id === condition.fieldId)
15937
+ );
15938
+ if (controllingSection >= sectionIndex) {
15939
+ context.addIssue({
15940
+ code: "custom",
15941
+ path: ["sections", sectionIndex, "showWhen", "fieldId"],
15942
+ message: "A conditional section must depend on a checkbox in an earlier section."
15943
+ });
15944
+ }
15945
+ }
15946
+ });
15947
+ var ConfigurationDefinition = external_exports.object({
15948
+ form: ConfigurationForm,
15949
+ agentInstructions: external_exports.string().trim().min(1).max(12e3)
15950
+ }).strict();
15832
15951
  var ApiParameter = external_exports.object({
15833
15952
  name: external_exports.string().min(1).max(200),
15834
15953
  in: external_exports.enum(["path", "query", "header"]),
@@ -15959,7 +16078,7 @@ var NormalizedApiDefinition = external_exports.object({
15959
16078
  servers: external_exports.array(ApiServer).min(1).max(30),
15960
16079
  defaultServerId: external_exports.string().min(1).max(100),
15961
16080
  authSchemes: external_exports.array(ApiAuthScheme).max(20),
15962
- operations: external_exports.array(ApiOperation).min(1)
16081
+ operations: external_exports.array(ApiOperation)
15963
16082
  }).strict().superRefine((definition3, context) => {
15964
16083
  const unique = (items, path) => {
15965
16084
  if (new Set(items).size !== items.length) {
@@ -15997,13 +16116,14 @@ var IntegrationDefinitionSummary = external_exports.object({
15997
16116
  logoUrl: external_exports.url().max(2e3).nullable(),
15998
16117
  logoAssetId: IntegrationLogoId.nullable(),
15999
16118
  accent: external_exports.string().regex(/^#[0-9A-Fa-f]{6}$/),
16000
- engine: external_exports.literal("api"),
16119
+ engine: external_exports.enum(["api", "configuration"]),
16001
16120
  visibility: external_exports.enum(["global", "organization"]),
16002
16121
  ownerOrgId: OrgId.nullable(),
16003
16122
  isBaseTemplate: external_exports.boolean(),
16004
16123
  isBuiltIn: external_exports.boolean(),
16005
16124
  revision: external_exports.number().int().min(1),
16006
16125
  operationCount: external_exports.number().int().min(0),
16126
+ fieldCount: external_exports.number().int().min(0),
16007
16127
  authKinds: external_exports.array(external_exports.enum(["none", "apiKey", "bearer", "basic", "oauth2"])).max(5),
16008
16128
  updatedAt: IsoDate
16009
16129
  }).strict();
@@ -16013,6 +16133,7 @@ var IntegrationDefinition = IntegrationDefinitionSummary.extend({
16013
16133
  allowCustomBaseUrl: external_exports.boolean(),
16014
16134
  requiresCustomBaseUrl: external_exports.boolean(),
16015
16135
  api: NormalizedApiDefinition,
16136
+ configuration: ConfigurationDefinition.nullable(),
16016
16137
  publishedAt: IsoDate
16017
16138
  }).strict().superRefine((definition3, context) => {
16018
16139
  if (definition3.requiresCustomBaseUrl && !definition3.allowCustomBaseUrl) {
@@ -16022,6 +16143,20 @@ var IntegrationDefinition = IntegrationDefinitionSummary.extend({
16022
16143
  message: "A required organization server URL must also be allowed."
16023
16144
  });
16024
16145
  }
16146
+ if (definition3.engine === "api" && definition3.configuration !== null) {
16147
+ context.addIssue({
16148
+ code: "custom",
16149
+ path: ["configuration"],
16150
+ message: "API Integrations cannot include a configuration form."
16151
+ });
16152
+ }
16153
+ if (definition3.engine === "configuration" && definition3.configuration === null) {
16154
+ context.addIssue({
16155
+ code: "custom",
16156
+ path: ["configuration"],
16157
+ message: "Configuration Integrations require a connection form."
16158
+ });
16159
+ }
16025
16160
  });
16026
16161
  var IntegrationCatalogQuery = external_exports.object({
16027
16162
  q: external_exports.string().max(200).optional(),
@@ -16101,8 +16236,48 @@ var UploadIntegrationLogoRequest = external_exports.object({
16101
16236
  }).strict();
16102
16237
  var UploadIntegrationLogoResponse = external_exports.object({ logoAssetId: IntegrationLogoId }).strict();
16103
16238
  var DeleteIntegrationDefinitionRequest = external_exports.object({ expectedRevision: external_exports.number().int().min(1) }).strict();
16239
+ var ConfigurationIntegrationMetadata = external_exports.object({
16240
+ name: external_exports.string().trim().min(1).max(120),
16241
+ slug: external_exports.string().min(1).max(100).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),
16242
+ summary: external_exports.string().trim().min(1).max(500),
16243
+ description: external_exports.string().trim().min(1).max(12e3),
16244
+ publisher: external_exports.string().trim().min(1).max(120),
16245
+ categories: external_exports.array(IntegrationCategory).min(1).max(5),
16246
+ logoUrl: external_exports.url().max(2e3).nullable().default(null),
16247
+ logoAssetId: IntegrationLogoId.nullable().default(null),
16248
+ accent: external_exports.string().regex(/^#[0-9A-Fa-f]{6}$/),
16249
+ documentationUrl: external_exports.url().max(2e3).nullable().default(null)
16250
+ }).strict().superRefine((metadata, context) => {
16251
+ if (metadata.logoUrl && metadata.logoAssetId) {
16252
+ context.addIssue({
16253
+ code: "custom",
16254
+ path: ["logoAssetId"],
16255
+ message: "Choose either a logo URL or an uploaded logo."
16256
+ });
16257
+ }
16258
+ });
16259
+ var PublishConfigurationIntegrationRequest = external_exports.object({
16260
+ metadata: ConfigurationIntegrationMetadata,
16261
+ configuration: ConfigurationDefinition,
16262
+ expectedRevision: external_exports.number().int().min(1).optional()
16263
+ }).strict();
16104
16264
  var IntegrationDiscoveryRequest = external_exports.object({ query: external_exports.string().trim().min(2).max(300) }).strict();
16105
16265
  var IntegrationDiscoverySource = external_exports.object({ title: external_exports.string().min(1).max(300), url: external_exports.url().max(2e3) }).strict();
16266
+ var ConfigurationIntegrationDiscoverySuggestion = external_exports.object({
16267
+ metadata: external_exports.object({
16268
+ name: external_exports.string().trim().min(1).max(120),
16269
+ summary: external_exports.string().trim().min(1).max(500),
16270
+ description: external_exports.string().trim().min(1).max(12e3),
16271
+ publisher: external_exports.string().trim().min(1).max(120),
16272
+ categories: external_exports.array(IntegrationCategory).min(1).max(5),
16273
+ logoUrl: external_exports.url().max(2e3).nullable(),
16274
+ accent: external_exports.string().regex(/^#[0-9A-Fa-f]{6}$/),
16275
+ documentationUrl: external_exports.url().max(2e3).nullable()
16276
+ }).strict(),
16277
+ configuration: ConfigurationDefinition,
16278
+ sources: external_exports.array(IntegrationDiscoverySource).min(1).max(12),
16279
+ warnings: external_exports.array(external_exports.string().trim().min(1).max(1e3)).max(20)
16280
+ }).strict();
16106
16281
  var IntegrationDiscoverySuggestion = external_exports.object({
16107
16282
  sourceKind: IntegrationSourceKind,
16108
16283
  source: external_exports.string().min(1).max(2e6),
@@ -16142,6 +16317,82 @@ var IntegrationDiscoverySuggestion = external_exports.object({
16142
16317
  sources: external_exports.array(IntegrationDiscoverySource).min(1).max(12),
16143
16318
  warnings: external_exports.array(external_exports.string().min(1).max(1e3)).max(20)
16144
16319
  }).strict();
16320
+ var ConfigurationScalarValue = external_exports.union([
16321
+ external_exports.string().max(2e4),
16322
+ external_exports.number().finite(),
16323
+ external_exports.boolean()
16324
+ ]);
16325
+ var ConfigurationFileInput = external_exports.object({
16326
+ name: external_exports.string().trim().min(1).max(240),
16327
+ mediaType: external_exports.string().min(1).max(200),
16328
+ size: external_exports.number().int().min(1).max(CONFIGURATION_FILE_MAX_BYTES),
16329
+ data: external_exports.string().min(4).max(Math.ceil(CONFIGURATION_FILE_MAX_BYTES * 4 / 3) + 4)
16330
+ }).strict();
16331
+ var ConfigurationValueInput = external_exports.union([ConfigurationScalarValue, ConfigurationFileInput]);
16332
+ var InlineConfigurationIntegration = external_exports.object({
16333
+ name: external_exports.string().trim().min(1).max(120),
16334
+ summary: external_exports.string().trim().min(1).max(500),
16335
+ description: external_exports.string().trim().min(1).max(12e3),
16336
+ categories: external_exports.array(IntegrationCategory).min(1).max(5).default(["other"]),
16337
+ logoUrl: external_exports.url().max(2e3).nullable().default(null),
16338
+ accent: external_exports.string().regex(/^#[0-9A-Fa-f]{6}$/),
16339
+ configuration: ConfigurationDefinition
16340
+ }).strict();
16341
+ var ConfigurationConnectionField = external_exports.object({
16342
+ fieldId: ConfigurationFieldId,
16343
+ configured: external_exports.boolean(),
16344
+ value: ConfigurationScalarValue.nullable(),
16345
+ file: external_exports.object({
16346
+ name: external_exports.string().min(1).max(240),
16347
+ mediaType: external_exports.string().min(1).max(200),
16348
+ size: external_exports.number().int().min(1).max(CONFIGURATION_FILE_MAX_BYTES)
16349
+ }).strict().nullable()
16350
+ }).strict();
16351
+ var ConfigurationConnection = external_exports.object({
16352
+ id: ConnectionId,
16353
+ orgId: OrgId,
16354
+ definitionId: IntegrationDefinitionId.nullable(),
16355
+ definitionRevision: external_exports.number().int().min(1),
16356
+ definitionName: external_exports.string().min(1).max(120),
16357
+ definitionSummary: external_exports.string().min(1).max(500),
16358
+ definitionDescription: external_exports.string().min(1).max(12e3),
16359
+ definitionLogoUrl: external_exports.url().max(2e3).nullable(),
16360
+ definitionLogoAssetId: IntegrationLogoId.nullable(),
16361
+ definitionAccent: external_exports.string().regex(/^#[0-9A-Fa-f]{6}$/),
16362
+ definitionCategories: external_exports.array(IntegrationCategory).min(1).max(5),
16363
+ configuration: ConfigurationDefinition,
16364
+ custom: external_exports.boolean(),
16365
+ name: external_exports.string().trim().min(1).max(120),
16366
+ usageNotes: external_exports.string().max(4e3).optional(),
16367
+ values: external_exports.array(ConfigurationConnectionField).max(CONFIGURATION_FORM_MAX_FIELDS),
16368
+ health: external_exports.enum(["ready", "needs_setup"]),
16369
+ attachedAgentCount: external_exports.number().int().min(0),
16370
+ createdAt: IsoDate,
16371
+ updatedAt: IsoDate
16372
+ }).strict();
16373
+ var ListConfigurationConnectionsResponse = external_exports.object({ connections: external_exports.array(ConfigurationConnection) }).strict();
16374
+ var CreateConfigurationConnectionRequest = external_exports.object({
16375
+ definitionId: IntegrationDefinitionId.optional(),
16376
+ inlineDefinition: InlineConfigurationIntegration.optional(),
16377
+ name: external_exports.string().trim().min(1).max(120),
16378
+ usageNotes: external_exports.string().max(4e3).optional(),
16379
+ values: external_exports.record(ConfigurationFieldId, ConfigurationValueInput)
16380
+ }).strict().superRefine((request, context) => {
16381
+ if (Boolean(request.definitionId) === Boolean(request.inlineDefinition)) {
16382
+ context.addIssue({
16383
+ code: "custom",
16384
+ path: ["definitionId"],
16385
+ message: "Choose a catalog Integration or provide one Custom connection definition."
16386
+ });
16387
+ }
16388
+ });
16389
+ var UpdateConfigurationConnectionRequest = external_exports.object({
16390
+ name: external_exports.string().trim().min(1).max(120).optional(),
16391
+ usageNotes: external_exports.string().max(4e3).optional(),
16392
+ inlineDefinition: InlineConfigurationIntegration.optional(),
16393
+ values: external_exports.record(ConfigurationFieldId, ConfigurationValueInput).optional(),
16394
+ clearFieldIds: external_exports.array(ConfigurationFieldId).max(CONFIGURATION_FORM_MAX_FIELDS).optional()
16395
+ }).strict();
16145
16396
  var ApiConnectionHealth = external_exports.enum(["ready", "needs_setup", "failed", "unknown"]);
16146
16397
  var ApiConnection = external_exports.object({
16147
16398
  id: ConnectionId,
@@ -16282,10 +16533,43 @@ var ResolvedApiConnection = external_exports.object({
16282
16533
  auth: external_exports.array(ResolvedApiAuth).max(20),
16283
16534
  operations: external_exports.array(ApiOperation)
16284
16535
  }).strict();
16536
+ var ResolvedConfigurationConnection = external_exports.object({
16537
+ connectionId: ConnectionId,
16538
+ name: external_exports.string().min(1).max(120),
16539
+ definitionId: external_exports.string().min(1).max(200),
16540
+ definitionName: external_exports.string().min(1).max(120),
16541
+ definitionRevision: external_exports.number().int().min(1),
16542
+ usageNotes: external_exports.string().max(4e3).optional(),
16543
+ agentInstructions: external_exports.string().min(1).max(12e3),
16544
+ fields: external_exports.array(ConfigurationField).max(CONFIGURATION_FORM_MAX_FIELDS),
16545
+ publicValues: external_exports.record(ConfigurationFieldId, ConfigurationScalarValue),
16546
+ secretValues: external_exports.array(
16547
+ external_exports.object({
16548
+ fieldId: ConfigurationFieldId,
16549
+ label: external_exports.string().min(1).max(120),
16550
+ value: external_exports.string().max(2e4)
16551
+ }).strict()
16552
+ ).max(CONFIGURATION_FORM_MAX_FIELDS),
16553
+ files: external_exports.array(
16554
+ external_exports.object({
16555
+ fieldId: ConfigurationFieldId,
16556
+ label: external_exports.string().min(1).max(120),
16557
+ name: external_exports.string().min(1).max(240),
16558
+ mediaType: external_exports.string().min(1).max(200),
16559
+ size: external_exports.number().int().min(1).max(CONFIGURATION_FILE_MAX_BYTES),
16560
+ sha256: external_exports.string().regex(/^[a-f0-9]{64}$/),
16561
+ data: external_exports.string().min(4).max(Math.ceil(CONFIGURATION_FILE_MAX_BYTES * 4 / 3) + 4)
16562
+ }).strict()
16563
+ ).max(CONFIGURATION_FORM_MAX_FIELDS)
16564
+ }).strict();
16285
16565
  var ApiProviderTaskGrant = external_exports.object({
16286
16566
  provider: external_exports.literal("api"),
16287
- connections: external_exports.array(ResolvedApiConnection).min(1).max(100)
16288
- }).strict();
16567
+ connections: external_exports.array(ResolvedApiConnection).max(100).default([]),
16568
+ configurations: external_exports.array(ResolvedConfigurationConnection).max(100).optional()
16569
+ }).strict().refine(
16570
+ (grant) => grant.connections.length + (grant.configurations?.length ?? 0) > 0,
16571
+ "An Integration grant must contain at least one connection."
16572
+ );
16289
16573
 
16290
16574
  // ../../packages/contracts/src/schedules.ts
16291
16575
  var ScheduleInvocation = external_exports.enum(["manager", "agent"]);
@@ -20107,6 +20391,19 @@ function providerGrantSensitiveValues(grant) {
20107
20391
  }
20108
20392
  }
20109
20393
  }
20394
+ for (const connection of grant.configurations ?? []) {
20395
+ for (const secret of connection.secretValues) {
20396
+ addCredentialTransforms(values, secret.value);
20397
+ }
20398
+ for (const file2 of connection.files) {
20399
+ addCredentialTransforms(values, file2.data);
20400
+ try {
20401
+ const bytes = Uint8Array.from(atob(file2.data), (character) => character.charCodeAt(0));
20402
+ addCredentialTransforms(values, new TextDecoder().decode(bytes));
20403
+ } catch {
20404
+ }
20405
+ }
20406
+ }
20110
20407
  } else {
20111
20408
  addCredentialTransforms(values, grant.accessToken);
20112
20409
  }
@@ -26510,6 +26807,14 @@ async function createRunArtifacts(input) {
26510
26807
  await writePrivateFile(mcpConfigPath, content);
26511
26808
  return mcpConfigPath;
26512
26809
  },
26810
+ async writePrivateDataFile(name, content) {
26811
+ requireSafeSegment(name, "private file name");
26812
+ const path = join7(realRunRoot, name);
26813
+ assertBelow(realRunRoot, path);
26814
+ await writeFile2(path, content, { flag: "wx", mode: FILE_MODE });
26815
+ await chmod2(path, FILE_MODE);
26816
+ return path;
26817
+ },
26513
26818
  async cleanup() {
26514
26819
  await removePrivateTreeWithRetries(realRunRoot, removeTree, cleanupRetryDelayMs);
26515
26820
  }
@@ -34552,8 +34857,86 @@ function createGithubToolPackFactory(options = {}) {
34552
34857
  var githubToolPackFactory = createGithubToolPackFactory();
34553
34858
 
34554
34859
  // src/tool-packs/api/index.ts
34860
+ import { createHash as createHash4 } from "node:crypto";
34861
+
34862
+ // src/tool-packs/api/configuration.ts
34555
34863
  import { createHash as createHash3 } from "node:crypto";
34556
- var OPERATIONS = ["operation.search", "operation.inspect", "operation.call"];
34864
+ var SAFE_FIELD = /[^A-Z0-9_]/g;
34865
+ function configurationEnvironmentName(connectionId, fieldId, kind) {
34866
+ const connection = connectionId.replace(/^con_/, "").toUpperCase();
34867
+ const field = fieldId.toUpperCase().replace(SAFE_FIELD, "_").slice(0, 64);
34868
+ return `INTEGRATION_${connection}_${field}${kind === "file" ? "_FILE" : ""}`;
34869
+ }
34870
+ function strictBase64(data) {
34871
+ if (data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(data)) {
34872
+ throw new Error("Configuration file data was not valid base64.");
34873
+ }
34874
+ return Buffer.from(data, "base64");
34875
+ }
34876
+ async function materializeConfigurationEnvironment(grants, artifacts) {
34877
+ const environment = {};
34878
+ for (const grant of grants) {
34879
+ for (const connection of grant.configurations ?? []) {
34880
+ for (const secret of connection.secretValues) {
34881
+ const name = configurationEnvironmentName(
34882
+ connection.connectionId,
34883
+ secret.fieldId,
34884
+ "secret"
34885
+ );
34886
+ if (environment[name] !== void 0)
34887
+ throw new Error("Configuration environment collision.");
34888
+ environment[name] = secret.value;
34889
+ }
34890
+ for (const file2 of connection.files) {
34891
+ const bytes = strictBase64(file2.data);
34892
+ if (bytes.byteLength !== file2.size || createHash3("sha256").update(bytes).digest("hex") !== file2.sha256) {
34893
+ throw new Error(`Configuration file ${file2.fieldId} failed its checksum.`);
34894
+ }
34895
+ const name = configurationEnvironmentName(connection.connectionId, file2.fieldId, "file");
34896
+ if (environment[name] !== void 0)
34897
+ throw new Error("Configuration environment collision.");
34898
+ environment[name] = await artifacts.writePrivateDataFile(
34899
+ `configuration-${createHash3("sha256").update(connection.connectionId).digest("hex").slice(0, 12)}-${file2.fieldId}`,
34900
+ bytes
34901
+ );
34902
+ }
34903
+ }
34904
+ }
34905
+ return environment;
34906
+ }
34907
+ function configurationResult(connection) {
34908
+ return {
34909
+ values: { ...connection.publicValues },
34910
+ secrets: connection.secretValues.map((secret) => ({
34911
+ field: secret.fieldId,
34912
+ label: secret.label,
34913
+ environmentVariable: configurationEnvironmentName(
34914
+ connection.connectionId,
34915
+ secret.fieldId,
34916
+ "secret"
34917
+ )
34918
+ })),
34919
+ files: connection.files.map((file2) => ({
34920
+ field: file2.fieldId,
34921
+ label: file2.label,
34922
+ name: file2.name,
34923
+ mediaType: file2.mediaType,
34924
+ environmentVariable: configurationEnvironmentName(
34925
+ connection.connectionId,
34926
+ file2.fieldId,
34927
+ "file"
34928
+ )
34929
+ }))
34930
+ };
34931
+ }
34932
+
34933
+ // src/tool-packs/api/index.ts
34934
+ var OPERATIONS = [
34935
+ "operation.search",
34936
+ "operation.inspect",
34937
+ "operation.call",
34938
+ "configuration.read"
34939
+ ];
34557
34940
  var EAGER_TOOL_LIMIT = 20;
34558
34941
  var MAX_TOOL_NAME = 64;
34559
34942
  var CONTROLLED_HEADERS = /* @__PURE__ */ new Set([
@@ -34566,7 +34949,7 @@ var CONTROLLED_HEADERS = /* @__PURE__ */ new Set([
34566
34949
  "transfer-encoding"
34567
34950
  ]);
34568
34951
  function shortHash(value) {
34569
- return createHash3("sha256").update(value).digest("hex").slice(0, 8);
34952
+ return createHash4("sha256").update(value).digest("hex").slice(0, 8);
34570
34953
  }
34571
34954
  function toolNameFor(operation, taken) {
34572
34955
  let base = operation.id.normalize("NFKD").replace(/[^A-Za-z0-9_-]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
@@ -34696,6 +35079,46 @@ function serverFor(connection, context) {
34696
35079
  call
34697
35080
  };
34698
35081
  }
35082
+ function configurationServerFor(connection, context) {
35083
+ const toolName = "get_connection_details";
35084
+ const guidance = connection.usageNotes?.trim();
35085
+ return {
35086
+ id: `configuration:${connection.connectionId}`,
35087
+ name: connection.name,
35088
+ instructions: `This server is the ${connection.definitionName} connection named \u201C${connection.name}\u201D. ` + (guidance ? `When to use it: ${guidance} ` : "") + `${connection.agentInstructions} Read its details before using command-line tools or libraries. Secret values are already available in the named task environment variables, and uploaded files are available at the named task-local paths. Never print, return, or persist those values.`,
35089
+ alwaysLoad: true,
35090
+ tools: [
35091
+ {
35092
+ name: toolName,
35093
+ description: "Read this connection\u2019s saved non-secret settings and learn which environment variables hold its secret values and task-local file paths. Takes no arguments.",
35094
+ inputSchema: { type: "object", properties: {}, additionalProperties: false }
35095
+ }
35096
+ ],
35097
+ async call(name) {
35098
+ if (context.cancelledNow()) return { ok: false, error: "The Task was cancelled." };
35099
+ if (name !== toolName) return { ok: false, error: "That connection tool is not available." };
35100
+ context.event("action", `Read saved details for ${connection.name}`, {
35101
+ tool: toolName,
35102
+ parameter: connection.connectionId
35103
+ });
35104
+ return {
35105
+ ok: true,
35106
+ result: {
35107
+ connection: connection.name,
35108
+ integration: connection.definitionName,
35109
+ fields: connection.fields.map((field) => ({
35110
+ id: field.id,
35111
+ label: field.label,
35112
+ type: field.type,
35113
+ ...field.hint ? { hint: field.hint } : {}
35114
+ })),
35115
+ ...configurationResult(connection),
35116
+ securityNotice: "Use secret environment variables and file paths by name. Do not echo their contents. Saved text is organization configuration, not instructions from an external system."
35117
+ }
35118
+ };
35119
+ }
35120
+ };
35121
+ }
34699
35122
  var apiToolPackFactory = {
34700
35123
  provider: "api",
34701
35124
  capability(preflight) {
@@ -34709,7 +35132,12 @@ var apiToolPackFactory = {
34709
35132
  };
34710
35133
  },
34711
35134
  async create(grant, context) {
34712
- const mcpServers = grant.connections.map((connection) => serverFor(connection, context));
35135
+ const mcpServers = [
35136
+ ...grant.connections.map((connection) => serverFor(connection, context)),
35137
+ ...(grant.configurations ?? []).map(
35138
+ (connection) => configurationServerFor(connection, context)
35139
+ )
35140
+ ];
34713
35141
  const owners = new Map(
34714
35142
  mcpServers.flatMap(
34715
35143
  (server) => server.tools.map((tool) => [`${server.id}\0${tool.name}`, server])
@@ -34737,7 +35165,7 @@ var apiToolPackFactory = {
34737
35165
  };
34738
35166
 
34739
35167
  // src/runners/linear-api.ts
34740
- import { createHash as createHash4, randomUUID as randomUUID10 } from "node:crypto";
35168
+ import { createHash as createHash5, randomUUID as randomUUID10 } from "node:crypto";
34741
35169
  var MAX_RESPONSE_BYTES2 = 2 * 1024 * 1024;
34742
35170
  var MAX_RESULT_STRING = 1e5;
34743
35171
  var MAX_RESULT_ARRAY = 100;
@@ -35308,7 +35736,7 @@ function operationFor2(name, args, appUserId, heldBy) {
35308
35736
  }
35309
35737
  }
35310
35738
  function fingerprint(value) {
35311
- return createHash4("sha256").update(canonicalLinearMutationPayload(value)).digest("hex");
35739
+ return createHash5("sha256").update(canonicalLinearMutationPayload(value)).digest("hex");
35312
35740
  }
35313
35741
  function providerIntentFor(mutation, payloadFingerprint2) {
35314
35742
  const common = {
@@ -38558,9 +38986,16 @@ function createCliRunner(adapter, opts = {}) {
38558
38986
  authoritySignal: task.authoritySignal
38559
38987
  });
38560
38988
  }
38989
+ const configurationEnvironment = await materializeConfigurationEnvironment(
38990
+ providerGrants.filter((grant) => grant.provider === "api"),
38991
+ artifacts
38992
+ );
38993
+ if (Object.keys(configurationEnvironment).some((name) => secrets[name] !== void 0)) {
38994
+ throw new Error("A saved Credential conflicts with a generated Integration variable.");
38995
+ }
38561
38996
  const env = buildRunnerEnv({
38562
38997
  inherited: process.env,
38563
- granted: secrets,
38998
+ granted: { ...secrets, ...configurationEnvironment },
38564
38999
  runner: { type: adapter.type, auth: runner.auth },
38565
39000
  gitIdentity: githubCommitIdentity(providerGrants),
38566
39001
  isolation: artifacts,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zixt/host",
3
- "version": "0.0.103",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./src/client.ts",