@zixt/host 0.0.103 → 0.0.104

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 +432 -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.104",
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,6 +16236,31 @@ 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();
16106
16266
  var IntegrationDiscoverySuggestion = external_exports.object({
@@ -16142,6 +16302,82 @@ var IntegrationDiscoverySuggestion = external_exports.object({
16142
16302
  sources: external_exports.array(IntegrationDiscoverySource).min(1).max(12),
16143
16303
  warnings: external_exports.array(external_exports.string().min(1).max(1e3)).max(20)
16144
16304
  }).strict();
16305
+ var ConfigurationScalarValue = external_exports.union([
16306
+ external_exports.string().max(2e4),
16307
+ external_exports.number().finite(),
16308
+ external_exports.boolean()
16309
+ ]);
16310
+ var ConfigurationFileInput = external_exports.object({
16311
+ name: external_exports.string().trim().min(1).max(240),
16312
+ mediaType: external_exports.string().min(1).max(200),
16313
+ size: external_exports.number().int().min(1).max(CONFIGURATION_FILE_MAX_BYTES),
16314
+ data: external_exports.string().min(4).max(Math.ceil(CONFIGURATION_FILE_MAX_BYTES * 4 / 3) + 4)
16315
+ }).strict();
16316
+ var ConfigurationValueInput = external_exports.union([ConfigurationScalarValue, ConfigurationFileInput]);
16317
+ var InlineConfigurationIntegration = external_exports.object({
16318
+ name: external_exports.string().trim().min(1).max(120),
16319
+ summary: external_exports.string().trim().min(1).max(500),
16320
+ description: external_exports.string().trim().min(1).max(12e3),
16321
+ categories: external_exports.array(IntegrationCategory).min(1).max(5).default(["other"]),
16322
+ logoUrl: external_exports.url().max(2e3).nullable().default(null),
16323
+ accent: external_exports.string().regex(/^#[0-9A-Fa-f]{6}$/),
16324
+ configuration: ConfigurationDefinition
16325
+ }).strict();
16326
+ var ConfigurationConnectionField = external_exports.object({
16327
+ fieldId: ConfigurationFieldId,
16328
+ configured: external_exports.boolean(),
16329
+ value: ConfigurationScalarValue.nullable(),
16330
+ file: external_exports.object({
16331
+ name: external_exports.string().min(1).max(240),
16332
+ mediaType: external_exports.string().min(1).max(200),
16333
+ size: external_exports.number().int().min(1).max(CONFIGURATION_FILE_MAX_BYTES)
16334
+ }).strict().nullable()
16335
+ }).strict();
16336
+ var ConfigurationConnection = external_exports.object({
16337
+ id: ConnectionId,
16338
+ orgId: OrgId,
16339
+ definitionId: IntegrationDefinitionId.nullable(),
16340
+ definitionRevision: external_exports.number().int().min(1),
16341
+ definitionName: external_exports.string().min(1).max(120),
16342
+ definitionSummary: external_exports.string().min(1).max(500),
16343
+ definitionDescription: external_exports.string().min(1).max(12e3),
16344
+ definitionLogoUrl: external_exports.url().max(2e3).nullable(),
16345
+ definitionLogoAssetId: IntegrationLogoId.nullable(),
16346
+ definitionAccent: external_exports.string().regex(/^#[0-9A-Fa-f]{6}$/),
16347
+ definitionCategories: external_exports.array(IntegrationCategory).min(1).max(5),
16348
+ configuration: ConfigurationDefinition,
16349
+ custom: external_exports.boolean(),
16350
+ name: external_exports.string().trim().min(1).max(120),
16351
+ usageNotes: external_exports.string().max(4e3).optional(),
16352
+ values: external_exports.array(ConfigurationConnectionField).max(CONFIGURATION_FORM_MAX_FIELDS),
16353
+ health: external_exports.enum(["ready", "needs_setup"]),
16354
+ attachedAgentCount: external_exports.number().int().min(0),
16355
+ createdAt: IsoDate,
16356
+ updatedAt: IsoDate
16357
+ }).strict();
16358
+ var ListConfigurationConnectionsResponse = external_exports.object({ connections: external_exports.array(ConfigurationConnection) }).strict();
16359
+ var CreateConfigurationConnectionRequest = external_exports.object({
16360
+ definitionId: IntegrationDefinitionId.optional(),
16361
+ inlineDefinition: InlineConfigurationIntegration.optional(),
16362
+ name: external_exports.string().trim().min(1).max(120),
16363
+ usageNotes: external_exports.string().max(4e3).optional(),
16364
+ values: external_exports.record(ConfigurationFieldId, ConfigurationValueInput)
16365
+ }).strict().superRefine((request, context) => {
16366
+ if (Boolean(request.definitionId) === Boolean(request.inlineDefinition)) {
16367
+ context.addIssue({
16368
+ code: "custom",
16369
+ path: ["definitionId"],
16370
+ message: "Choose a catalog Integration or provide one Custom connection definition."
16371
+ });
16372
+ }
16373
+ });
16374
+ var UpdateConfigurationConnectionRequest = external_exports.object({
16375
+ name: external_exports.string().trim().min(1).max(120).optional(),
16376
+ usageNotes: external_exports.string().max(4e3).optional(),
16377
+ inlineDefinition: InlineConfigurationIntegration.optional(),
16378
+ values: external_exports.record(ConfigurationFieldId, ConfigurationValueInput).optional(),
16379
+ clearFieldIds: external_exports.array(ConfigurationFieldId).max(CONFIGURATION_FORM_MAX_FIELDS).optional()
16380
+ }).strict();
16145
16381
  var ApiConnectionHealth = external_exports.enum(["ready", "needs_setup", "failed", "unknown"]);
16146
16382
  var ApiConnection = external_exports.object({
16147
16383
  id: ConnectionId,
@@ -16282,10 +16518,43 @@ var ResolvedApiConnection = external_exports.object({
16282
16518
  auth: external_exports.array(ResolvedApiAuth).max(20),
16283
16519
  operations: external_exports.array(ApiOperation)
16284
16520
  }).strict();
16521
+ var ResolvedConfigurationConnection = external_exports.object({
16522
+ connectionId: ConnectionId,
16523
+ name: external_exports.string().min(1).max(120),
16524
+ definitionId: external_exports.string().min(1).max(200),
16525
+ definitionName: external_exports.string().min(1).max(120),
16526
+ definitionRevision: external_exports.number().int().min(1),
16527
+ usageNotes: external_exports.string().max(4e3).optional(),
16528
+ agentInstructions: external_exports.string().min(1).max(12e3),
16529
+ fields: external_exports.array(ConfigurationField).max(CONFIGURATION_FORM_MAX_FIELDS),
16530
+ publicValues: external_exports.record(ConfigurationFieldId, ConfigurationScalarValue),
16531
+ secretValues: external_exports.array(
16532
+ external_exports.object({
16533
+ fieldId: ConfigurationFieldId,
16534
+ label: external_exports.string().min(1).max(120),
16535
+ value: external_exports.string().max(2e4)
16536
+ }).strict()
16537
+ ).max(CONFIGURATION_FORM_MAX_FIELDS),
16538
+ files: external_exports.array(
16539
+ external_exports.object({
16540
+ fieldId: ConfigurationFieldId,
16541
+ label: external_exports.string().min(1).max(120),
16542
+ name: external_exports.string().min(1).max(240),
16543
+ mediaType: external_exports.string().min(1).max(200),
16544
+ size: external_exports.number().int().min(1).max(CONFIGURATION_FILE_MAX_BYTES),
16545
+ sha256: external_exports.string().regex(/^[a-f0-9]{64}$/),
16546
+ data: external_exports.string().min(4).max(Math.ceil(CONFIGURATION_FILE_MAX_BYTES * 4 / 3) + 4)
16547
+ }).strict()
16548
+ ).max(CONFIGURATION_FORM_MAX_FIELDS)
16549
+ }).strict();
16285
16550
  var ApiProviderTaskGrant = external_exports.object({
16286
16551
  provider: external_exports.literal("api"),
16287
- connections: external_exports.array(ResolvedApiConnection).min(1).max(100)
16288
- }).strict();
16552
+ connections: external_exports.array(ResolvedApiConnection).max(100).default([]),
16553
+ configurations: external_exports.array(ResolvedConfigurationConnection).max(100).optional()
16554
+ }).strict().refine(
16555
+ (grant) => grant.connections.length + (grant.configurations?.length ?? 0) > 0,
16556
+ "An Integration grant must contain at least one connection."
16557
+ );
16289
16558
 
16290
16559
  // ../../packages/contracts/src/schedules.ts
16291
16560
  var ScheduleInvocation = external_exports.enum(["manager", "agent"]);
@@ -20107,6 +20376,19 @@ function providerGrantSensitiveValues(grant) {
20107
20376
  }
20108
20377
  }
20109
20378
  }
20379
+ for (const connection of grant.configurations ?? []) {
20380
+ for (const secret of connection.secretValues) {
20381
+ addCredentialTransforms(values, secret.value);
20382
+ }
20383
+ for (const file2 of connection.files) {
20384
+ addCredentialTransforms(values, file2.data);
20385
+ try {
20386
+ const bytes = Uint8Array.from(atob(file2.data), (character) => character.charCodeAt(0));
20387
+ addCredentialTransforms(values, new TextDecoder().decode(bytes));
20388
+ } catch {
20389
+ }
20390
+ }
20391
+ }
20110
20392
  } else {
20111
20393
  addCredentialTransforms(values, grant.accessToken);
20112
20394
  }
@@ -26510,6 +26792,14 @@ async function createRunArtifacts(input) {
26510
26792
  await writePrivateFile(mcpConfigPath, content);
26511
26793
  return mcpConfigPath;
26512
26794
  },
26795
+ async writePrivateDataFile(name, content) {
26796
+ requireSafeSegment(name, "private file name");
26797
+ const path = join7(realRunRoot, name);
26798
+ assertBelow(realRunRoot, path);
26799
+ await writeFile2(path, content, { flag: "wx", mode: FILE_MODE });
26800
+ await chmod2(path, FILE_MODE);
26801
+ return path;
26802
+ },
26513
26803
  async cleanup() {
26514
26804
  await removePrivateTreeWithRetries(realRunRoot, removeTree, cleanupRetryDelayMs);
26515
26805
  }
@@ -34552,8 +34842,86 @@ function createGithubToolPackFactory(options = {}) {
34552
34842
  var githubToolPackFactory = createGithubToolPackFactory();
34553
34843
 
34554
34844
  // src/tool-packs/api/index.ts
34845
+ import { createHash as createHash4 } from "node:crypto";
34846
+
34847
+ // src/tool-packs/api/configuration.ts
34555
34848
  import { createHash as createHash3 } from "node:crypto";
34556
- var OPERATIONS = ["operation.search", "operation.inspect", "operation.call"];
34849
+ var SAFE_FIELD = /[^A-Z0-9_]/g;
34850
+ function configurationEnvironmentName(connectionId, fieldId, kind) {
34851
+ const connection = connectionId.replace(/^con_/, "").toUpperCase();
34852
+ const field = fieldId.toUpperCase().replace(SAFE_FIELD, "_").slice(0, 64);
34853
+ return `INTEGRATION_${connection}_${field}${kind === "file" ? "_FILE" : ""}`;
34854
+ }
34855
+ function strictBase64(data) {
34856
+ if (data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(data)) {
34857
+ throw new Error("Configuration file data was not valid base64.");
34858
+ }
34859
+ return Buffer.from(data, "base64");
34860
+ }
34861
+ async function materializeConfigurationEnvironment(grants, artifacts) {
34862
+ const environment = {};
34863
+ for (const grant of grants) {
34864
+ for (const connection of grant.configurations ?? []) {
34865
+ for (const secret of connection.secretValues) {
34866
+ const name = configurationEnvironmentName(
34867
+ connection.connectionId,
34868
+ secret.fieldId,
34869
+ "secret"
34870
+ );
34871
+ if (environment[name] !== void 0)
34872
+ throw new Error("Configuration environment collision.");
34873
+ environment[name] = secret.value;
34874
+ }
34875
+ for (const file2 of connection.files) {
34876
+ const bytes = strictBase64(file2.data);
34877
+ if (bytes.byteLength !== file2.size || createHash3("sha256").update(bytes).digest("hex") !== file2.sha256) {
34878
+ throw new Error(`Configuration file ${file2.fieldId} failed its checksum.`);
34879
+ }
34880
+ const name = configurationEnvironmentName(connection.connectionId, file2.fieldId, "file");
34881
+ if (environment[name] !== void 0)
34882
+ throw new Error("Configuration environment collision.");
34883
+ environment[name] = await artifacts.writePrivateDataFile(
34884
+ `configuration-${createHash3("sha256").update(connection.connectionId).digest("hex").slice(0, 12)}-${file2.fieldId}`,
34885
+ bytes
34886
+ );
34887
+ }
34888
+ }
34889
+ }
34890
+ return environment;
34891
+ }
34892
+ function configurationResult(connection) {
34893
+ return {
34894
+ values: { ...connection.publicValues },
34895
+ secrets: connection.secretValues.map((secret) => ({
34896
+ field: secret.fieldId,
34897
+ label: secret.label,
34898
+ environmentVariable: configurationEnvironmentName(
34899
+ connection.connectionId,
34900
+ secret.fieldId,
34901
+ "secret"
34902
+ )
34903
+ })),
34904
+ files: connection.files.map((file2) => ({
34905
+ field: file2.fieldId,
34906
+ label: file2.label,
34907
+ name: file2.name,
34908
+ mediaType: file2.mediaType,
34909
+ environmentVariable: configurationEnvironmentName(
34910
+ connection.connectionId,
34911
+ file2.fieldId,
34912
+ "file"
34913
+ )
34914
+ }))
34915
+ };
34916
+ }
34917
+
34918
+ // src/tool-packs/api/index.ts
34919
+ var OPERATIONS = [
34920
+ "operation.search",
34921
+ "operation.inspect",
34922
+ "operation.call",
34923
+ "configuration.read"
34924
+ ];
34557
34925
  var EAGER_TOOL_LIMIT = 20;
34558
34926
  var MAX_TOOL_NAME = 64;
34559
34927
  var CONTROLLED_HEADERS = /* @__PURE__ */ new Set([
@@ -34566,7 +34934,7 @@ var CONTROLLED_HEADERS = /* @__PURE__ */ new Set([
34566
34934
  "transfer-encoding"
34567
34935
  ]);
34568
34936
  function shortHash(value) {
34569
- return createHash3("sha256").update(value).digest("hex").slice(0, 8);
34937
+ return createHash4("sha256").update(value).digest("hex").slice(0, 8);
34570
34938
  }
34571
34939
  function toolNameFor(operation, taken) {
34572
34940
  let base = operation.id.normalize("NFKD").replace(/[^A-Za-z0-9_-]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
@@ -34696,6 +35064,46 @@ function serverFor(connection, context) {
34696
35064
  call
34697
35065
  };
34698
35066
  }
35067
+ function configurationServerFor(connection, context) {
35068
+ const toolName = "get_connection_details";
35069
+ const guidance = connection.usageNotes?.trim();
35070
+ return {
35071
+ id: `configuration:${connection.connectionId}`,
35072
+ name: connection.name,
35073
+ 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.`,
35074
+ alwaysLoad: true,
35075
+ tools: [
35076
+ {
35077
+ name: toolName,
35078
+ 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.",
35079
+ inputSchema: { type: "object", properties: {}, additionalProperties: false }
35080
+ }
35081
+ ],
35082
+ async call(name) {
35083
+ if (context.cancelledNow()) return { ok: false, error: "The Task was cancelled." };
35084
+ if (name !== toolName) return { ok: false, error: "That connection tool is not available." };
35085
+ context.event("action", `Read saved details for ${connection.name}`, {
35086
+ tool: toolName,
35087
+ parameter: connection.connectionId
35088
+ });
35089
+ return {
35090
+ ok: true,
35091
+ result: {
35092
+ connection: connection.name,
35093
+ integration: connection.definitionName,
35094
+ fields: connection.fields.map((field) => ({
35095
+ id: field.id,
35096
+ label: field.label,
35097
+ type: field.type,
35098
+ ...field.hint ? { hint: field.hint } : {}
35099
+ })),
35100
+ ...configurationResult(connection),
35101
+ 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."
35102
+ }
35103
+ };
35104
+ }
35105
+ };
35106
+ }
34699
35107
  var apiToolPackFactory = {
34700
35108
  provider: "api",
34701
35109
  capability(preflight) {
@@ -34709,7 +35117,12 @@ var apiToolPackFactory = {
34709
35117
  };
34710
35118
  },
34711
35119
  async create(grant, context) {
34712
- const mcpServers = grant.connections.map((connection) => serverFor(connection, context));
35120
+ const mcpServers = [
35121
+ ...grant.connections.map((connection) => serverFor(connection, context)),
35122
+ ...(grant.configurations ?? []).map(
35123
+ (connection) => configurationServerFor(connection, context)
35124
+ )
35125
+ ];
34713
35126
  const owners = new Map(
34714
35127
  mcpServers.flatMap(
34715
35128
  (server) => server.tools.map((tool) => [`${server.id}\0${tool.name}`, server])
@@ -34737,7 +35150,7 @@ var apiToolPackFactory = {
34737
35150
  };
34738
35151
 
34739
35152
  // src/runners/linear-api.ts
34740
- import { createHash as createHash4, randomUUID as randomUUID10 } from "node:crypto";
35153
+ import { createHash as createHash5, randomUUID as randomUUID10 } from "node:crypto";
34741
35154
  var MAX_RESPONSE_BYTES2 = 2 * 1024 * 1024;
34742
35155
  var MAX_RESULT_STRING = 1e5;
34743
35156
  var MAX_RESULT_ARRAY = 100;
@@ -35308,7 +35721,7 @@ function operationFor2(name, args, appUserId, heldBy) {
35308
35721
  }
35309
35722
  }
35310
35723
  function fingerprint(value) {
35311
- return createHash4("sha256").update(canonicalLinearMutationPayload(value)).digest("hex");
35724
+ return createHash5("sha256").update(canonicalLinearMutationPayload(value)).digest("hex");
35312
35725
  }
35313
35726
  function providerIntentFor(mutation, payloadFingerprint2) {
35314
35727
  const common = {
@@ -38558,9 +38971,16 @@ function createCliRunner(adapter, opts = {}) {
38558
38971
  authoritySignal: task.authoritySignal
38559
38972
  });
38560
38973
  }
38974
+ const configurationEnvironment = await materializeConfigurationEnvironment(
38975
+ providerGrants.filter((grant) => grant.provider === "api"),
38976
+ artifacts
38977
+ );
38978
+ if (Object.keys(configurationEnvironment).some((name) => secrets[name] !== void 0)) {
38979
+ throw new Error("A saved Credential conflicts with a generated Integration variable.");
38980
+ }
38561
38981
  const env = buildRunnerEnv({
38562
38982
  inherited: process.env,
38563
- granted: secrets,
38983
+ granted: { ...secrets, ...configurationEnvironment },
38564
38984
  runner: { type: adapter.type, auth: runner.auth },
38565
38985
  gitIdentity: githubCommitIdentity(providerGrants),
38566
38986
  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.104",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./src/client.ts",