import {
  defineExecutorConfig
} from "./chunk-7MT7NZUQ.js";
import {
  DEFAULT_EXECUTOR_SERVER_ORIGIN,
  DEFAULT_EXECUTOR_SERVER_USERNAME,
  InternalError,
  OAUTH_POPUP_MESSAGE_TYPE,
  apiBaseUrlForServerOrigin,
  getExecutorServerAuthorizationHeader,
  isOAuthPopupResult,
  normalizeExecutorServerConnection,
  normalizeExecutorServerOrigin,
  originFromApiBaseUrl
} from "./chunk-SK3PCJHJ.js";
import {
  OAUTH2_PROVIDER_KEY,
  OAUTH2_SESSION_TTL_MS,
  ORG_SUBJECT,
  StorageError,
  TOOL_POLICY_ACTIONS,
  ToolFileJsonSchema,
  ToolFileSchema,
  ToolResult,
  UniqueViolationError,
  annotateToolResultOutcome,
  bigintColumn,
  boolColumn,
  buildToolTypeScriptPreview,
  collectTables,
  connectionAddress,
  coreSchema,
  coreTables,
  createExecutor,
  dateColumn,
  definePlugin,
  definePluginStorageCollection,
  executorOwnerPolicyName,
  executorUnscopedPolicyName,
  isStorageFailure,
  isToolFile,
  isToolPolicyAction,
  isToolResult,
  jsonColumn,
  keyColumn,
  makeFumaBlobStore,
  makeInMemoryBlobStore,
  nullableBigintColumn,
  nullableJsonColumn,
  nullableKeyColumn,
  nullableTextColumn,
  parseToolAddress,
  pluginBlobStore,
  pluginStorageId,
  sha256Hex,
  textColumn,
  tool,
  toolAddress
} from "./chunk-QEKKFEJL.js";
import {
  ConnectionNotFoundError,
  CredentialProviderNotRegisteredError,
  CredentialResolutionError,
  ElicitationAction,
  ElicitationDeclinedError,
  ElicitationResponse,
  FormElicitation,
  IntegrationAlreadyExistsError,
  IntegrationDetectionResult,
  IntegrationNotFoundError,
  IntegrationRemovalNotAllowedError,
  NoHandlerError,
  OAuthCompleteError,
  OAuthProbeError,
  OAuthRegisterDynamicError,
  OAuthSessionNotFoundError,
  OAuthStartError,
  PluginNotLoadedError,
  ToolBlockedError,
  ToolInvocationError,
  ToolNotFoundError,
  ToolPolicyActionSchema,
  ToolSchemaView,
  UrlElicitation,
  effectivePolicyFromSorted,
  isValidPattern,
  matchPattern
} from "./chunk-6EED5LAL.js";
import "./chunk-EIHWBY6T.js";
import {
  AuthTemplateSlug,
  ConnectionAddress,
  ConnectionName,
  ElicitationId,
  IntegrationSlug,
  OAuthClientSlug,
  OAuthState,
  Owner,
  PolicyId,
  ProviderItemId,
  ProviderKey,
  Subject,
  Tenant,
  ToolAddress,
  ToolName,
  connectionIdentifier,
  isConnectionIdentifier
} from "./chunk-7GJMCW76.js";
import "./chunk-7D4SUZUM.js";

// src/index.ts
import { Context, Effect as Effect3, Layer, Schema as Schema2, Data as Data2, Option as Option2 } from "effect";
import {
  HttpApi,
  HttpApiBuilder,
  HttpApiClient,
  HttpApiEndpoint,
  HttpApiGroup,
  HttpApiMiddleware,
  HttpApiSchema
} from "effect/unstable/httpapi";
import { fumadb } from "@executor-js/fumadb";
import { column, idColumn, schema, table } from "@executor-js/fumadb/schema";

// src/integration.ts
var shortId = () => Math.random().toString(36).slice(2, 8);
var freshCustomAuthSlug = (taken) => {
  let candidate = `custom_${shortId()}`;
  while (taken.has(candidate)) candidate = `custom_${shortId()}`;
  return candidate;
};
var mergeAuthTemplates = (existing, incoming) => {
  const result = existing.map((entry) => entry);
  const taken = new Set(result.map((entry) => String(entry.slug)));
  for (const entry of incoming) {
    const rawSlug = entry.slug;
    const requested = typeof rawSlug === "string" ? rawSlug.trim() : "";
    const existingIndex = result.findIndex((current) => String(current.slug) === requested);
    if (requested.length > 0 && existingIndex >= 0) {
      result[existingIndex] = entry;
      continue;
    }
    const slug = requested.length > 0 && !taken.has(requested) ? requested : freshCustomAuthSlug(taken);
    taken.add(slug);
    result.push({ ...entry, slug });
  }
  return result;
};

// src/sqlite-data-migrations.ts
import { Data, Effect } from "effect";
var DataMigrationError = class extends Data.TaggedError("DataMigrationError") {
};
var DuplicateDataMigrationError = class extends Data.TaggedError("DuplicateDataMigrationError") {
};
var LEDGER_TABLE = "data_migration";
var execute = (client, stmt, migration) => Effect.tryPromise({
  try: () => client.execute(stmt),
  catch: (cause) => new DataMigrationError({ migration, cause })
});
var sqliteDataMigration = (name, run) => ({
  name,
  run: (client) => Effect.tryPromise({
    try: () => run(client),
    catch: (cause) => new DataMigrationError({ migration: name, cause })
  }).pipe(Effect.asVoid)
});
var runSqliteDataMigrations = (client, migrations) => Effect.gen(function* () {
  const names = /* @__PURE__ */ new Set();
  for (const migration of migrations) {
    if (names.has(migration.name)) {
      return yield* new DuplicateDataMigrationError({ name: migration.name });
    }
    names.add(migration.name);
  }
  yield* execute(
    client,
    `CREATE TABLE IF NOT EXISTS ${LEDGER_TABLE} (name TEXT PRIMARY KEY, time_completed INTEGER NOT NULL)`,
    null
  );
  const stamped = yield* execute(client, `SELECT name FROM ${LEDGER_TABLE}`, null);
  const completed = new Set(
    stamped.rows.map((row) => row.name).filter((name) => typeof name === "string")
  );
  const applied = [];
  for (const migration of migrations) {
    if (completed.has(migration.name)) continue;
    yield* migration.run(client);
    yield* execute(
      client,
      {
        sql: `INSERT INTO ${LEDGER_TABLE} (name, time_completed) VALUES (?, ?)`,
        args: [migration.name, Date.now()]
      },
      migration.name
    );
    applied.push(migration.name);
  }
  return applied;
});

// src/sqlite-config-blob-migration.ts
import { Effect as Effect2, Option, Schema } from "effect";
var decodeJsonOption = Schema.decodeUnknownOption(Schema.UnknownFromJsonString);
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
var runSqliteConfigBlobMigration = (client, options) => Effect2.gen(function* () {
  const execute2 = (stmt) => Effect2.tryPromise({
    try: () => client.execute(stmt),
    catch: (cause) => new DataMigrationError({ migration: options.migrationName, cause })
  });
  const exists = yield* execute2(
    "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'integration'"
  );
  if (exists.rows.length === 0) return 0;
  const result = yield* execute2({
    sql: "SELECT row_id, tenant, config FROM integration WHERE plugin_id = ? AND config IS NOT NULL",
    args: [options.pluginId]
  });
  const moves = [];
  for (const row of result.rows) {
    if (typeof row.row_id !== "string" || typeof row.tenant !== "string") continue;
    if (typeof row.config !== "string") continue;
    const decoded = decodeJsonOption(row.config);
    if (Option.isNone(decoded) || !isRecord(decoded.value)) continue;
    const inline = decoded.value[options.inlineField];
    if (typeof inline !== "string") continue;
    const hash = yield* sha256Hex(inline);
    const namespace = `o:${row.tenant}/${options.pluginId}`;
    const key = `${options.blobKeyPrefix}/${hash}`;
    const { [options.inlineField]: _removed, ...rest } = decoded.value;
    moves.push({
      rowId: row.row_id,
      namespace,
      key,
      blobId: JSON.stringify([namespace, key]),
      inlineText: inline,
      nextConfig: JSON.stringify({ ...rest, [options.hashField]: hash })
    });
  }
  if (moves.length === 0) return 0;
  const applyAll = Effect2.gen(function* () {
    for (const move of moves) {
      const existing = yield* execute2({
        sql: "SELECT row_id FROM blob WHERE id = ?",
        args: [move.blobId]
      });
      if (existing.rows.length === 0) {
        yield* execute2({
          sql: "INSERT INTO blob (namespace, key, value, row_id, id) VALUES (?, ?, ?, ?, ?)",
          args: [move.namespace, move.key, move.inlineText, crypto.randomUUID(), move.blobId]
        });
      } else {
        yield* execute2({
          sql: "UPDATE blob SET value = ? WHERE id = ?",
          args: [move.inlineText, move.blobId]
        });
      }
      yield* execute2({
        sql: "UPDATE integration SET config = ? WHERE row_id = ?",
        args: [move.nextConfig, move.rowId]
      });
    }
    yield* execute2("COMMIT");
  });
  yield* execute2("BEGIN");
  yield* applyAll.pipe(Effect2.tapError(() => execute2("ROLLBACK").pipe(Effect2.ignore)));
  return moves.length;
});

// src/auth-tool-failure.ts
var authRecovery = (input) => ({
  createConnectionTool: "executor.coreTools.connections.createHandoff",
  startOAuthTool: "executor.coreTools.oauth.start",
  listConnectionsTool: "executor.coreTools.connections.list",
  ...input?.configureSourceTool ? { configureSourceTool: input.configureSourceTool } : {},
  connectionInstructions: "For API keys and tokens, call createConnectionTool for the integration to get a browser URL; the user enters the credential there, which creates the bound connection. Do not ask the user to paste secrets into chat. Then call listConnectionsTool to confirm the connection exists before retrying this tool.",
  oauthInstructions: "For OAuth credentials, call startOAuthTool and give the returned authorizationUrl to the user. The completed connection binds automatically, then retry the tool."
});
var authToolFailure = (input) => {
  const error = {
    code: input.code,
    message: input.message,
    retryable: false,
    ...input.status !== void 0 ? { status: input.status } : {},
    details: {
      category: "authentication",
      ...input.source ? { source: input.source } : {},
      ...input.credential ? { credential: input.credential } : {},
      ...input.upstream ? { upstream: input.upstream } : {},
      recovery: authRecovery(input.recovery)
    }
  };
  return ToolResult.fail(error);
};
export {
  AuthTemplateSlug,
  ConnectionAddress,
  ConnectionName,
  ConnectionNotFoundError,
  Context,
  CredentialProviderNotRegisteredError,
  CredentialResolutionError,
  DEFAULT_EXECUTOR_SERVER_ORIGIN,
  DEFAULT_EXECUTOR_SERVER_USERNAME,
  Data2 as Data,
  DataMigrationError,
  DuplicateDataMigrationError,
  Effect3 as Effect,
  ElicitationAction,
  ElicitationDeclinedError,
  ElicitationId,
  ElicitationResponse,
  FormElicitation,
  HttpApi,
  HttpApiBuilder,
  HttpApiClient,
  HttpApiEndpoint,
  HttpApiGroup,
  HttpApiMiddleware,
  HttpApiSchema,
  IntegrationAlreadyExistsError,
  IntegrationDetectionResult,
  IntegrationNotFoundError,
  IntegrationRemovalNotAllowedError,
  IntegrationSlug,
  InternalError,
  Layer,
  NoHandlerError,
  OAUTH2_PROVIDER_KEY,
  OAUTH2_SESSION_TTL_MS,
  OAUTH_POPUP_MESSAGE_TYPE,
  OAuthClientSlug,
  OAuthCompleteError,
  OAuthProbeError,
  OAuthRegisterDynamicError,
  OAuthSessionNotFoundError,
  OAuthStartError,
  OAuthState,
  ORG_SUBJECT,
  Option2 as Option,
  Owner,
  PluginNotLoadedError,
  PolicyId,
  ProviderItemId,
  ProviderKey,
  Schema2 as Schema,
  StorageError,
  Subject,
  TOOL_POLICY_ACTIONS,
  Tenant,
  ToolAddress,
  ToolBlockedError,
  ToolFileJsonSchema,
  ToolFileSchema,
  ToolInvocationError,
  ToolName,
  ToolNotFoundError,
  ToolPolicyActionSchema,
  ToolResult,
  ToolSchemaView,
  UniqueViolationError,
  UrlElicitation,
  annotateToolResultOutcome,
  apiBaseUrlForServerOrigin,
  authToolFailure,
  bigintColumn,
  boolColumn,
  buildToolTypeScriptPreview,
  collectTables,
  column,
  connectionAddress,
  connectionIdentifier,
  coreSchema,
  coreTables,
  createExecutor,
  dateColumn,
  defineExecutorConfig,
  definePlugin,
  definePluginStorageCollection,
  effectivePolicyFromSorted,
  executorOwnerPolicyName,
  executorUnscopedPolicyName,
  freshCustomAuthSlug,
  schema as fumaSchema,
  fumadb,
  getExecutorServerAuthorizationHeader,
  idColumn,
  isConnectionIdentifier,
  isOAuthPopupResult,
  isStorageFailure,
  isToolFile,
  isToolPolicyAction,
  isToolResult,
  isValidPattern,
  jsonColumn,
  keyColumn,
  makeFumaBlobStore,
  makeInMemoryBlobStore,
  matchPattern,
  mergeAuthTemplates,
  normalizeExecutorServerConnection,
  normalizeExecutorServerOrigin,
  nullableBigintColumn,
  nullableJsonColumn,
  nullableKeyColumn,
  nullableTextColumn,
  originFromApiBaseUrl,
  parseToolAddress,
  pluginBlobStore,
  pluginStorageId,
  runSqliteConfigBlobMigration,
  runSqliteDataMigrations,
  sha256Hex,
  sqliteDataMigration,
  table,
  textColumn,
  tool,
  toolAddress
};
//# sourceMappingURL=core.js.map