From 35adcf72e9fc2a6fe55fc9d0a3fada4001a29fee Mon Sep 17 00:00:00 2001 From: Waleed Date: Sat, 3 Oct 2026 01:29:01 -0700 Subject: [PATCH 01/12] improvement(guidance): make every ratchet shrink-only, scope rules to their files, fix stale guidance (#8594) * improvement(guidance): make every ratchet shrink-only, scope rules to their files, fix stale guidance - check:test-patterns --update refuses new violations and fails closed on a missing baseline - check:react-query drops its unused, growable baseline: every violation fails, as it already did - check:utils drops the id.ts allowlist entry by rewording the comment that tripped it - constitution, react-performance, and url-state rules load only for the files they govern - guidance: Switch stays the boolean toggle, current chip names, @sim/utils/random, db-migrate covers the schema mock and drizzle sync, apps/sim/AGENTS.md maps common tasks to skills * chore(guidance): widen rule scopes to the changelog route, package hooks, and nuqs navigation helpers * chore(guidance): scope url-state by directory so app hooks and helpers stay covered --- .agents/skills/db-migrate/SKILL.md | 4 +- .claude/rules/constitution.md | 10 +++ .claude/rules/emcn-components.md | 2 +- .claude/rules/sim-queries.md | 2 +- .claude/rules/sim-react-performance.md | 5 ++ .claude/rules/sim-settings-pages.md | 5 +- .claude/rules/sim-styling.md | 2 +- .claude/rules/sim-url-state.md | 12 ++- .cursor/rules/constitution.mdc | 2 +- .cursor/rules/emcn-components.mdc | 2 +- .cursor/rules/sim-queries.mdc | 2 +- .cursor/rules/sim-react-performance.mdc | 2 +- .cursor/rules/sim-settings-pages.mdc | 5 +- .cursor/rules/sim-styling.mdc | 2 +- .cursor/rules/sim-url-state.mdc | 2 +- CLAUDE.md | 6 +- apps/sim/AGENTS.md | 7 ++ package.json | 2 +- packages/testing/src/factories/id.ts | 3 +- .../check-react-query-patterns.baseline.json | 4 - scripts/check-react-query-patterns.ts | 88 +++---------------- scripts/check-test-patterns.ts | 33 +++++-- scripts/check-utils-enforcement.ts | 2 - scripts/run-audits.ts | 2 +- 24 files changed, 92 insertions(+), 114 deletions(-) delete mode 100644 scripts/check-react-query-patterns.baseline.json diff --git a/.agents/skills/db-migrate/SKILL.md b/.agents/skills/db-migrate/SKILL.md index 0ff4581a2b1..a2c05a96a86 100644 --- a/.agents/skills/db-migrate/SKILL.md +++ b/.agents/skills/db-migrate/SKILL.md @@ -83,7 +83,9 @@ The lint flags risky *shapes*; it cannot know whether a given drop is *safe righ ``` The reason must be specific and name the PR/version that removed the dependency. An empty reason fails the lint. - **Warnings** (`data-backfill`): non-blocking, but confirm the batching/idempotency before merging. -4. Verify locally: `cd packages/db && bun run db:migrate` against a dev DB. +4. Regenerate the test schema mock: `bun run scripts/generate-schema-mock.ts` (`check:schema-mock` in `check:audits` fails after any `schema.ts` change until you do). +5. Re-run `(cd packages/db && bunx drizzle-kit generate)` once your migration is written: it must report no schema changes and write no new file, or CI fails on the schema and migrations disagreeing. +6. Verify locally: `cd packages/db && bun run db:migrate` against a dev DB. ## Hard rule diff --git a/.claude/rules/constitution.md b/.claude/rules/constitution.md index 565dee4b877..3bd45448d59 100644 --- a/.claude/rules/constitution.md +++ b/.claude/rules/constitution.md @@ -1,5 +1,15 @@ --- description: Sim product language, positioning, and tone guidelines +paths: + - "apps/sim/app/(landing)/**" + - "apps/sim/lib/landing/**" + - "apps/sim/content/**" + - "apps/sim/emails/broadcasts/**" + - "apps/sim/app/layout.tsx" + - "apps/sim/app/manifest.ts" + - "apps/sim/app/llms*.txt/**" + - "apps/sim/app/changelog.xml/**" + - "apps/docs/**" --- # Sim — Language & Positioning diff --git a/.claude/rules/emcn-components.md b/.claude/rules/emcn-components.md index d4c697869d0..c21cad945cd 100644 --- a/.claude/rules/emcn-components.md +++ b/.claude/rules/emcn-components.md @@ -6,7 +6,7 @@ paths: # EMCN Components -Import components, `cn`, and tokens from the `@sim/emcn` barrel; icons come from the `@sim/emcn/icons` subpath, and CSS modules from their file path. Never deep-import other component subpaths. The **chip family** is the platform's primary chrome — always reach for it over the legacy primitives it is progressively replacing (`Input`→`ChipInput`, `Textarea`→`ChipTextarea`, `Modal`→`ChipModal`, `Select`/`Combobox`→`ChipSelect`/`ChipCombobox`/`ChipDropdown`, `Switch`→`ChipSwitch`, date field→`ChipDatePicker`). For context/action menus the canonical control is `DropdownMenu` — the standard menu (not a chip, and never a hand-rolled popover). +Import components, `cn`, and tokens from the `@sim/emcn` barrel; icons come from the `@sim/emcn/icons` subpath, and CSS modules from their file path. Never deep-import other component subpaths. The **chip family** is the platform's primary chrome — always reach for it over the legacy primitives it is progressively replacing (`Input`→`ChipInput`, `Textarea`→`ChipTextarea`, `Modal`→`ChipModal`, `Select`/`Combobox`→`ChipSelect`/`ChipCombobox`/`ChipDropdown`, date field→`ChipDatePicker`). `ChipSwitch` is a segmented choice between options, not a replacement for `Switch`: a boolean on/off toggle stays `Switch`. For context/action menus the canonical control is `DropdownMenu` — the standard menu (not a chip, and never a hand-rolled popover). ## Chip chrome — single source of truth diff --git a/.claude/rules/sim-queries.md b/.claude/rules/sim-queries.md index f09036b315c..3cf27da59e4 100644 --- a/.claude/rules/sim-queries.md +++ b/.claude/rules/sim-queries.md @@ -172,4 +172,4 @@ Hooks import named type aliases from `@/lib/api/contracts/**` and never import ` ## Enforcement -`scripts/check-react-query-patterns.ts` (`bun run check:react-query`, run in CI) statically enforces these conventions: every `useQuery`/`useInfiniteQuery`/`useSuspenseQuery` declares an explicit `staleTime`, inline `queryFn`s destructure `signal`, `queryKey`s reference a colocated factory rather than an inline literal, every `*Keys` factory in `hooks/queries/**` exposes an `all` root key, and every identifier the `queryFn` forwards into the fetch also appears in the `queryKey` (`key-fetch-arg-drift`). `hooks/queries/**` is a zero-tolerance zone; the rest of `apps/sim/**` is ratcheted against `scripts/check-react-query-patterns.baseline.json`. For a genuine exception, put `// rq-lint-allow: ` on the line directly above the flagged construct. +`scripts/check-react-query-patterns.ts` (`bun run check:react-query`, run in CI) statically enforces these conventions: every `useQuery`/`useInfiniteQuery`/`useSuspenseQuery` declares an explicit `staleTime`, inline `queryFn`s destructure `signal`, `queryKey`s reference a colocated factory rather than an inline literal, every `*Keys` factory in `hooks/queries/**` exposes an `all` root key, and every identifier the `queryFn` forwards into the fetch also appears in the `queryKey` (`key-fetch-arg-drift`). Any violation under `apps/sim/**` fails. For a genuine exception, put `// rq-lint-allow: ` on the line directly above the flagged construct. diff --git a/.claude/rules/sim-react-performance.md b/.claude/rules/sim-react-performance.md index f37fb447299..516cd46fc6a 100644 --- a/.claude/rules/sim-react-performance.md +++ b/.claude/rules/sim-react-performance.md @@ -1,5 +1,10 @@ --- description: Behavior-preserving React render-performance idioms +paths: + - "apps/sim/**/*.ts" + - "apps/sim/**/*.tsx" + - "packages/emcn/**" + - "packages/workflow-renderer/**" --- # React & Render Performance diff --git a/.claude/rules/sim-settings-pages.md b/.claude/rules/sim-settings-pages.md index 09393d6ef3b..40a6b5dcfba 100644 --- a/.claude/rules/sim-settings-pages.md +++ b/.claude/rules/sim-settings-pages.md @@ -224,8 +224,9 @@ and — on activatable rows only — the hover band. Never hand-roll any of it, divider, body. Also carries `headerAccessory` and `action` slots. Never re-derive the label/divider chrome; `sim-styling.md` owns those tokens. - **`SettingsField`** (`…/components/settings-field`) — a read-only label/value - pair in a detail body: muted caption over the value. Pair it with - `SETTINGS_FIELD_VALUE_CLASSES` for the value text. + pair in a detail body: muted caption over the value. Pass the value as text and it + renders the value paragraph itself; pass a node when the value needs its own + presentation (a control, an icon beside the value, status styling). - **`SettingsEmptyState`** (`…/components/settings-empty-state`) — the canonical muted status message, for empty lists, "no results", loading gates, **and failed loads** (`tone='error'`). `variant='fill'` (default) centers in the diff --git a/.claude/rules/sim-styling.md b/.claude/rules/sim-styling.md index f146e7a547c..e3cc5541e23 100644 --- a/.claude/rules/sim-styling.md +++ b/.claude/rules/sim-styling.md @@ -108,7 +108,7 @@ Layout/sizing ONLY: `flex-1`, `w-full`, `w-[Npx]`, `min-w-0`, `max-w-*`, margins - **Modal body** (`ChipModalBody`): `gap-4` between fields, padding `px-2 pt-4 pb-4.5`. - **Header/footer**: horizontal gutter `px-4` (header `pt-3`; footer `px-4 pt-2 pb-2`, tinted bar). - **Every body field MUST be a `ChipModalField`** — NEVER hand-roll a field row (raw `
` + hand-rolled `

`/`

`. -- **Uncovered controls** (`ChipCombobox`, `ChipSelect`, `DatePicker`, `TimePicker`, `ButtonGroup`, arbitrary JSX) → `ChipModalField type='custom'` with a `title`. It still applies the `px-2` gutter and renders the canonical `Label`, so it stays aligned. Never drop such a control into a raw `

`, and never add a body-level wrapper `
` with a custom `gap-*` that fights `gap-4`. +- **Uncovered controls** (`ChipCombobox`, `ChipSelect`, `ChipDatePicker`, `ChipTimePicker`, `ChipButtonGroup`, arbitrary JSX) → `ChipModalField type='custom'` with a `title`. It still applies the `px-2` gutter and renders the canonical `Label`, so it stays aligned. Never drop such a control into a raw `
`, and never add a body-level wrapper `
` with a custom `gap-*` that fights `gap-4`. - **Page section rhythm** (integrations/skills/settings): muted `text-small` label + `mt-[9px] mb-3 h-px bg-[var(--border)]` divider, sections stacked `gap-7`. Reuse `SettingsSection` (`app/workspace/[workspaceId]/settings/components/settings-section/settings-section.tsx`) rather than re-deriving it. When a standalone labeled field outside a `ChipModal` needs the same look (e.g. `SkillImport`), match the field rhythm by hand: `flex flex-col gap-[9px]`, muted label, `ChipInput`/`ChipTextarea` control, `text-caption` error below. diff --git a/.claude/rules/sim-url-state.md b/.claude/rules/sim-url-state.md index 6114efc83bc..914bb12403c 100644 --- a/.claude/rules/sim-url-state.md +++ b/.claude/rules/sim-url-state.md @@ -2,10 +2,14 @@ description: Shareable client view-state lives in the URL via nuqs paths: - "apps/sim/app/**/*.tsx" - - "apps/sim/app/**/*.ts" - - "apps/sim/app/**/search-params.ts" - - "apps/sim/ee/**/*.tsx" - - "apps/sim/ee/**/*.ts" + - "apps/sim/app/workspace/**/*.ts" + - "apps/sim/app/o/**/*.ts" + - "apps/sim/ee/**" + - "apps/sim/hooks/**" + - "apps/sim/stores/**" + - "apps/sim/lib/url-state/**" + - "apps/sim/**/search-params.ts" + - "apps/sim/**/*navigation.ts" --- # URL / Query-Param State (nuqs) diff --git a/.cursor/rules/constitution.mdc b/.cursor/rules/constitution.mdc index 9e9a50d2b2b..f97878570ab 100644 --- a/.cursor/rules/constitution.mdc +++ b/.cursor/rules/constitution.mdc @@ -1,6 +1,6 @@ --- description: "Sim product language, positioning, and tone guidelines" -alwaysApply: true +globs: ["apps/sim/app/(landing)/**","apps/sim/lib/landing/**","apps/sim/content/**","apps/sim/emails/broadcasts/**","apps/sim/app/layout.tsx","apps/sim/app/manifest.ts","apps/sim/app/llms*.txt/**","apps/sim/app/changelog.xml/**","apps/docs/**"] --- diff --git a/.cursor/rules/emcn-components.mdc b/.cursor/rules/emcn-components.mdc index b4743462057..d77a4082838 100644 --- a/.cursor/rules/emcn-components.mdc +++ b/.cursor/rules/emcn-components.mdc @@ -7,7 +7,7 @@ globs: ["packages/emcn/**"] # EMCN Components -Import components, `cn`, and tokens from the `@sim/emcn` barrel; icons come from the `@sim/emcn/icons` subpath, and CSS modules from their file path. Never deep-import other component subpaths. The **chip family** is the platform's primary chrome — always reach for it over the legacy primitives it is progressively replacing (`Input`→`ChipInput`, `Textarea`→`ChipTextarea`, `Modal`→`ChipModal`, `Select`/`Combobox`→`ChipSelect`/`ChipCombobox`/`ChipDropdown`, `Switch`→`ChipSwitch`, date field→`ChipDatePicker`). For context/action menus the canonical control is `DropdownMenu` — the standard menu (not a chip, and never a hand-rolled popover). +Import components, `cn`, and tokens from the `@sim/emcn` barrel; icons come from the `@sim/emcn/icons` subpath, and CSS modules from their file path. Never deep-import other component subpaths. The **chip family** is the platform's primary chrome — always reach for it over the legacy primitives it is progressively replacing (`Input`→`ChipInput`, `Textarea`→`ChipTextarea`, `Modal`→`ChipModal`, `Select`/`Combobox`→`ChipSelect`/`ChipCombobox`/`ChipDropdown`, date field→`ChipDatePicker`). `ChipSwitch` is a segmented choice between options, not a replacement for `Switch`: a boolean on/off toggle stays `Switch`. For context/action menus the canonical control is `DropdownMenu` — the standard menu (not a chip, and never a hand-rolled popover). ## Chip chrome — single source of truth diff --git a/.cursor/rules/sim-queries.mdc b/.cursor/rules/sim-queries.mdc index 82f695bc66b..e068cc48182 100644 --- a/.cursor/rules/sim-queries.mdc +++ b/.cursor/rules/sim-queries.mdc @@ -173,4 +173,4 @@ Hooks import named type aliases from `@/lib/api/contracts/**` and never import ` ## Enforcement -`scripts/check-react-query-patterns.ts` (`bun run check:react-query`, run in CI) statically enforces these conventions: every `useQuery`/`useInfiniteQuery`/`useSuspenseQuery` declares an explicit `staleTime`, inline `queryFn`s destructure `signal`, `queryKey`s reference a colocated factory rather than an inline literal, every `*Keys` factory in `hooks/queries/**` exposes an `all` root key, and every identifier the `queryFn` forwards into the fetch also appears in the `queryKey` (`key-fetch-arg-drift`). `hooks/queries/**` is a zero-tolerance zone; the rest of `apps/sim/**` is ratcheted against `scripts/check-react-query-patterns.baseline.json`. For a genuine exception, put `// rq-lint-allow: ` on the line directly above the flagged construct. +`scripts/check-react-query-patterns.ts` (`bun run check:react-query`, run in CI) statically enforces these conventions: every `useQuery`/`useInfiniteQuery`/`useSuspenseQuery` declares an explicit `staleTime`, inline `queryFn`s destructure `signal`, `queryKey`s reference a colocated factory rather than an inline literal, every `*Keys` factory in `hooks/queries/**` exposes an `all` root key, and every identifier the `queryFn` forwards into the fetch also appears in the `queryKey` (`key-fetch-arg-drift`). Any violation under `apps/sim/**` fails. For a genuine exception, put `// rq-lint-allow: ` on the line directly above the flagged construct. diff --git a/.cursor/rules/sim-react-performance.mdc b/.cursor/rules/sim-react-performance.mdc index 4ad3ca74971..98920fa7d2d 100644 --- a/.cursor/rules/sim-react-performance.mdc +++ b/.cursor/rules/sim-react-performance.mdc @@ -1,6 +1,6 @@ --- description: "Behavior-preserving React render-performance idioms" -alwaysApply: true +globs: ["apps/sim/**/*.ts","apps/sim/**/*.tsx","packages/emcn/**","packages/workflow-renderer/**"] --- diff --git a/.cursor/rules/sim-settings-pages.mdc b/.cursor/rules/sim-settings-pages.mdc index 98b9a684370..9f6959a04eb 100644 --- a/.cursor/rules/sim-settings-pages.mdc +++ b/.cursor/rules/sim-settings-pages.mdc @@ -221,8 +221,9 @@ and — on activatable rows only — the hover band. Never hand-roll any of it, divider, body. Also carries `headerAccessory` and `action` slots. Never re-derive the label/divider chrome; `sim-styling.md` owns those tokens. - **`SettingsField`** (`…/components/settings-field`) — a read-only label/value - pair in a detail body: muted caption over the value. Pair it with - `SETTINGS_FIELD_VALUE_CLASSES` for the value text. + pair in a detail body: muted caption over the value. Pass the value as text and it + renders the value paragraph itself; pass a node when the value needs its own + presentation (a control, an icon beside the value, status styling). - **`SettingsEmptyState`** (`…/components/settings-empty-state`) — the canonical muted status message, for empty lists, "no results", loading gates, **and failed loads** (`tone='error'`). `variant='fill'` (default) centers in the diff --git a/.cursor/rules/sim-styling.mdc b/.cursor/rules/sim-styling.mdc index 3cc6ebcd23b..359412b40c4 100644 --- a/.cursor/rules/sim-styling.mdc +++ b/.cursor/rules/sim-styling.mdc @@ -108,7 +108,7 @@ Layout/sizing ONLY: `flex-1`, `w-full`, `w-[Npx]`, `min-w-0`, `max-w-*`, margins - **Modal body** (`ChipModalBody`): `gap-4` between fields, padding `px-2 pt-4 pb-4.5`. - **Header/footer**: horizontal gutter `px-4` (header `pt-3`; footer `px-4 pt-2 pb-2`, tinted bar). - **Every body field MUST be a `ChipModalField`** — NEVER hand-roll a field row (raw `
` + hand-rolled `

`/`

`. -- **Uncovered controls** (`ChipCombobox`, `ChipSelect`, `DatePicker`, `TimePicker`, `ButtonGroup`, arbitrary JSX) → `ChipModalField type='custom'` with a `title`. It still applies the `px-2` gutter and renders the canonical `Label`, so it stays aligned. Never drop such a control into a raw `

`, and never add a body-level wrapper `
` with a custom `gap-*` that fights `gap-4`. +- **Uncovered controls** (`ChipCombobox`, `ChipSelect`, `ChipDatePicker`, `ChipTimePicker`, `ChipButtonGroup`, arbitrary JSX) → `ChipModalField type='custom'` with a `title`. It still applies the `px-2` gutter and renders the canonical `Label`, so it stays aligned. Never drop such a control into a raw `
`, and never add a body-level wrapper `
` with a custom `gap-*` that fights `gap-4`. - **Page section rhythm** (integrations/skills/settings): muted `text-small` label + `mt-[9px] mb-3 h-px bg-[var(--border)]` divider, sections stacked `gap-7`. Reuse `SettingsSection` (`app/workspace/[workspaceId]/settings/components/settings-section/settings-section.tsx`) rather than re-deriving it. When a standalone labeled field outside a `ChipModal` needs the same look (e.g. `SkillImport`), match the field rhythm by hand: `flex flex-col gap-[9px]`, muted label, `ChipInput`/`ChipTextarea` control, `text-caption` error below. diff --git a/.cursor/rules/sim-url-state.mdc b/.cursor/rules/sim-url-state.mdc index 1aa10918c8e..cb1d05fa410 100644 --- a/.cursor/rules/sim-url-state.mdc +++ b/.cursor/rules/sim-url-state.mdc @@ -1,6 +1,6 @@ --- description: "Shareable client view-state lives in the URL via nuqs" -globs: ["apps/sim/app/**/*.tsx","apps/sim/app/**/*.ts","apps/sim/app/**/search-params.ts","apps/sim/ee/**/*.tsx","apps/sim/ee/**/*.ts"] +globs: ["apps/sim/app/**/*.tsx","apps/sim/app/workspace/**/*.ts","apps/sim/app/o/**/*.ts","apps/sim/ee/**","apps/sim/hooks/**","apps/sim/stores/**","apps/sim/lib/url-state/**","apps/sim/**/search-params.ts","apps/sim/**/*navigation.ts"] --- diff --git a/CLAUDE.md b/CLAUDE.md index a3f7da54018..c04bd72e209 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,7 +7,7 @@ This file (also `AGENTS.md`) holds the repo-wide rules. Area detail lives in `.c - **Package manager**: `bun` and `bunx`, never `npm` and `npx`. - **Logging**: `createLogger` from `@sim/logger`; `logger.info` / `logger.warn` / `logger.error`, never `console.log`. Inside `withRouteHandler` the logger already carries the request ID — no manual `withMetadata({ requestId })`. - **Comments**: name things so the code explains itself. TSDoc documents exported APIs and non-obvious modules. An inline `//` is only for a terse, non-obvious *why*, or for a script-enforced `// : ` annotation (`boundary-raw-fetch`, `double-cast-allowed`, `boundary-raw-json`, `untyped-response`, `rq-lint-allow`, `client-boundary-allow`, `utils-lint-allow`, …). History belongs in the commit message. No `====` separators or commented-out code (`check:comment-hygiene` enforces this). The `/you-might-not-need-a-comment` skill applies this to a diff. -- **ID generation**: `generateId()` (UUID v4, the default) or `generateShortId(size?)` (URL-safe, 21 chars by default) from `@sim/utils/id` — never `crypto.randomUUID()`, `nanoid`, or `uuid`. Both use `crypto.getRandomValues()`, so they also work in non-secure (HTTP) browsers. +- **ID generation**: `generateId()` (UUID v4, the default) or `generateShortId(size?)` (URL-safe, 21 chars by default) from `@sim/utils/id` — never `crypto.randomUUID()`, `nanoid`, or `uuid`. Both use `crypto.getRandomValues()`, so they also work in non-secure (HTTP) browsers. For other randomness, `@sim/utils/random` (`randomInt`, `randomFloat`, `randomItem`, `generateRandomBytes`, `generateRandomHex`) — never `Math.random()` or `crypto.randomBytes()`. - **Common utilities**: use the shared helpers from `@sim/utils` instead of inline implementations (`check:utils` bans most of the inline forms below): - `sleep(ms)` from `@sim/utils/helpers` — never `new Promise(resolve => setTimeout(resolve, ms))` - `toError(e)` from `@sim/utils/errors` — normalize caught values to `Error`; never `e instanceof Error ? e : new Error(String(e))` @@ -104,7 +104,7 @@ The `'use client'` server boundary, the app/worker runtime env split, and featur - Tailwind only. Inline `style` only for a genuinely dynamic value or a CSS variable. Never update global styles; keep styling local to the component. `cn()` from `@sim/emcn` for conditional classes. `size-*` for equal height and width (icons default `size-[14px]`), never `h-N w-N`. - Import components, `cn`, and tokens from the `@sim/emcn` barrel; icons from `@sim/emcn/icons`; CSS modules by file path. Never deep-import other component subpaths. -- The chip family is the canonical chrome: `ChipInput`, `ChipTextarea`, `ChipModal`/`ChipModalField`, `ChipSelect`/`ChipCombobox`/`ChipDropdown`, `ChipSwitch`, `ChipDatePicker`, `Chip`/`ChipLink`, `ChipTag`; `DropdownMenu` for context/action menus. Components own their chrome: consumers pass props (`error`, `icon`, `endAdornment`, `inputClassName`) and `className` carries only layout/sizing. Every labeled field inside a `ChipModalBody` is a `ChipModalField`. +- The chip family is the canonical chrome: `ChipInput`, `ChipTextarea`, `ChipModal`/`ChipModalField`, `ChipSelect`/`ChipCombobox`/`ChipDropdown`, `ChipSwitch` (a segmented choice; a boolean toggle stays `Switch`), `ChipDatePicker`, `Chip`/`ChipLink`, `ChipTag`; `DropdownMenu` for context/action menus. Components own their chrome: consumers pass props (`error`, `icon`, `endAdornment`, `inputClassName`) and `className` carries only layout/sizing. Every labeled field inside a `ChipModalBody` is a `ChipModalField`. - Consumer rules, tokens, text scale, and modal rhythm: `.claude/rules/sim-styling.md`. Authoring components in `packages/emcn`: `.claude/rules/emcn-components.md`. Product UI copy: `.claude/rules/sim-ui-copy.md`. Marketing copy and positioning: `.claude/rules/constitution.md`. ## Testing @@ -149,4 +149,4 @@ git fetch origin staging # the block-registry check diffs against it bun run apps/sim/scripts/check-block-registry.ts origin/staging ``` -CI also runs `bun run check:migrations ` (it needs a base ref, so it is not in `check:audits`; run it with `origin/staging` when you touch `packages/db/migrations/**`), checks that `drizzle-kit generate` in `packages/db` produces no new migration, and runs a non-blocking `bun audit`. When an audit fails, its output and its script's header say what the rule protects; fix the code, never the check. Ratchet baselines (`scripts/*baseline.json`) only shrink: regenerate one with the update flag its failure output names (`--update` or `--update-baseline`) after removing violations, never to admit new debt. The one exception is `check:tool-registry-boundary`, whose module-count baseline is re-recorded when growth is deliberate (see its skill). +CI also runs `bun run check:migrations` (it diffs against a base ref, `origin/staging` by default, so it is not in `check:audits`; run it when you touch `packages/db/migrations/**`), checks that `drizzle-kit generate` in `packages/db` produces no new migration, and runs a non-blocking `bun audit`. When an audit fails, its output and its script's header say what the rule protects; fix the code, never the check. Ratchet baselines (`scripts/*baseline.json`) only shrink: regenerate one with `--update` after removing violations; it refuses to admit new debt. The one exception is `check:tool-registry-boundary`, whose module-count baseline is re-recorded with `--update-baseline` when growth is deliberate (see its skill). diff --git a/apps/sim/AGENTS.md b/apps/sim/AGENTS.md index 27a844ddf7e..84feeac85ce 100644 --- a/apps/sim/AGENTS.md +++ b/apps/sim/AGENTS.md @@ -12,6 +12,13 @@ Applies to `apps/sim/**` on top of the root [AGENTS.md](/AGENTS.md), which holds - Tests: `sim-testing.md` and the `test-audit` skill - Landing pages: `app/(landing)/CLAUDE.md`, `landing-seo-geo.md`, `constitution.md` (product language) +For a common task, start from its skill (`.agents/skills//SKILL.md`): + +- New or migrated API route, tool command, or protected operation: `migrate-application-operation`, then `sim-api-contracts.md`; a `/api/v2` route also follows `v2-api-conventions` +- Schema change or migration: `db-migrate` +- Integration (tools, block, trigger): `add-integration`; a knowledge connector: `add-connector` +- Feature flag: `add-feature-flag`; settings page: `add-settings-page`; table column type: `add-column-type`; model: `add-model` + # This is NOT the Next.js you know diff --git a/package.json b/package.json index 4d76f4c6e37..99443cc674e 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "check:sql-date-binding": "bun run scripts/check-sql-date-binding.ts", "check:pending-drop-tables": "bun run scripts/check-pending-drop-tables.ts", "check:zustand-v5": "bun run scripts/check-zustand-v5-selectors.ts", - "check:react-query": "bun run scripts/check-react-query-patterns.ts --check", + "check:react-query": "bun run scripts/check-react-query-patterns.ts", "check:client-boundary": "bun run scripts/check-client-boundary-imports.ts --check", "check:utils": "bun run scripts/check-utils-enforcement.ts", "check:canvas-sentences": "bun run apps/sim/scripts/check-canvas-sentences.ts --require-coverage", diff --git a/packages/testing/src/factories/id.ts b/packages/testing/src/factories/id.ts index 858963f6058..08c95f8c86d 100644 --- a/packages/testing/src/factories/id.ts +++ b/packages/testing/src/factories/id.ts @@ -3,8 +3,7 @@ const URL_SAFE_ALPHABET = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghj /** * Generates a short, URL-safe random ID for test fixtures. * - * Uses `crypto.getRandomValues()` instead of `crypto.randomUUID()` for - * consistency with the app-level `generateShortId` utility. + * Mirrors the app-level `generateShortId` utility, which is built on `crypto.getRandomValues()`. */ export function shortId(size = 8): string { const bytes = new Uint8Array(size) diff --git a/scripts/check-react-query-patterns.baseline.json b/scripts/check-react-query-patterns.baseline.json deleted file mode 100644 index f0815addbe0..00000000000 --- a/scripts/check-react-query-patterns.baseline.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "generatedFrom": "apps/sim (non-strict zone)", - "counts": {} -} diff --git a/scripts/check-react-query-patterns.ts b/scripts/check-react-query-patterns.ts index 86f8525b6b6..97755a7dc08 100644 --- a/scripts/check-react-query-patterns.ts +++ b/scripts/check-react-query-patterns.ts @@ -21,29 +21,23 @@ * pageParam machinery) are checked, and only when both a queryKey and an * inline-arrow queryFn with a recognizable call are present. * - * Enforcement model (mirrors check-api-validation-contracts.ts): - * - STRICT ZONE (apps/sim/hooks/queries/**): zero tolerance — any violation fails. - * - Elsewhere under apps/sim/**: ratcheted against scripts/check-react-query-patterns.baseline.json - * (fails only when a category's count rises above the recorded baseline). + * Zero tolerance across apps/sim/**: any violation fails. * * Escape hatch: put `// rq-lint-allow: ` on the line directly above the * flagged construct (up to 3 preceding comment lines tolerated). The reason must * be non-empty. * - * Usage: - * bun run scripts/check-react-query-patterns.ts # report - * bun run scripts/check-react-query-patterns.ts --check # CI gate (strict zone + ratchet) - * bun run scripts/check-react-query-patterns.ts --update-baseline + * Usage: bun run scripts/check-react-query-patterns.ts */ -import { readdir, readFile, writeFile } from 'node:fs/promises' +import { readdir, readFile } from 'node:fs/promises' import path from 'node:path' const ROOT = path.resolve(import.meta.dir, '..') const APP_DIR = path.join(ROOT, 'apps/sim') -const BASELINE_PATH = path.join(ROOT, 'scripts/check-react-query-patterns.baseline.json') +/** The shared query-hook layer, where every `*Keys` factory must expose an `all` root key. */ +const QUERY_HOOKS_PREFIX = 'apps/sim/hooks/queries/' const SKIP_DIRS = new Set(['node_modules', '.next', '.turbo', 'coverage', 'dist', 'build']) -const STRICT_PREFIX = 'apps/sim/hooks/queries/' const ALLOW = 'rq-lint-allow:' type Category = @@ -143,7 +137,7 @@ function hasAllow(lines: string[], line: number): boolean { * The optional explicit type argument on a query call — `useQuery({ ... })`. * * Matched rather than ignored because a call carrying one is still a query call: without this - * the scan skipped every generically-typed query, including ten in the strict zone, which then + * the scan skipped every generically-typed query, including ten in `hooks/queries`, which then * reported zero violations while never having looked at them. One level of nesting is enough * for the shapes that occur here (`useQuery>`). */ @@ -429,7 +423,7 @@ function scanFile(rel: string, content: string): Violation[] { } // 4: key factory must have an `all` root (hooks/queries/** only, excluding util key files that compose others) - if (rel.startsWith(STRICT_PREFIX)) { + if (rel.startsWith(QUERY_HOOKS_PREFIX)) { KEYS_FACTORY.lastIndex = 0 let k: RegExpExecArray | null = KEYS_FACTORY.exec(content) for (; k !== null; k = KEYS_FACTORY.exec(content)) { @@ -445,23 +439,7 @@ function scanFile(rel: string, content: string): Violation[] { return violations } -interface Baseline { - generatedFrom: string - counts: Record -} - -async function loadBaseline(): Promise { - try { - return JSON.parse(await readFile(BASELINE_PATH, 'utf8')) - } catch { - return { generatedFrom: 'none', counts: {} } - } -} - async function main() { - const update = process.argv.includes('--update-baseline') - const check = process.argv.includes('--check') - const files = await walk(APP_DIR) const all: Violation[] = [] for (const file of files) { @@ -474,60 +452,16 @@ async function main() { all.push(...scanFile(rel, content)) } - const strict = all.filter((v) => v.file.startsWith(STRICT_PREFIX)) - const ratchet = all.filter((v) => !v.file.startsWith(STRICT_PREFIX)) - - const counts: Record = {} - for (const v of ratchet) counts[v.category] = (counts[v.category] ?? 0) + 1 - - if (update) { - const baseline: Baseline = { generatedFrom: 'apps/sim (non-strict zone)', counts } - await writeFile(BASELINE_PATH, `${JSON.stringify(baseline, null, 2)}\n`) - console.log(`✓ Baseline written: ${JSON.stringify(counts)}`) - process.exit(0) - } - console.log(`React Query pattern audit — scanned ${files.length} files`) - console.log(` strict zone (${STRICT_PREFIX}**) violations: ${strict.length}`) - console.log(` ratchet zone violations: ${ratchet.length} ${JSON.stringify(counts)}`) - - let failed = false - - if (strict.length > 0) { - failed = true - console.error(`\n✗ ${strict.length} violation(s) in the strict zone (${STRICT_PREFIX}**):\n`) - for (const v of strict) { + if (all.length > 0) { + console.error(`\n✗ ${all.length} violation(s):\n`) + for (const v of all) { console.error(` ${v.file}:${v.line} [${v.category}]`) console.error(` ${v.snippet}`) console.error(` → ${v.message}\n`) } + process.exit(1) } - - if (!check && ratchet.length > 0) { - console.error(`\nRatchet-zone occurrences (not failing without --check):`) - for (const v of ratchet) { - console.error(` ${v.file}:${v.line} [${v.category}] ${v.snippet}`) - } - } - - if (check) { - const baseline = await loadBaseline() - for (const [category, count] of Object.entries(counts)) { - const base = baseline.counts[category] ?? 0 - if (count > base) { - failed = true - console.error( - `\n✗ ratchet regression: ${category} rose to ${count} (baseline ${base}). ` + - `Fix the new occurrence(s) or annotate with // ${ALLOW} .` - ) - for (const v of ratchet.filter((x) => x.category === category)) { - console.error(` ${v.file}:${v.line} ${v.snippet}`) - } - } - } - } - - if (failed) process.exit(1) console.log('\n✓ React Query pattern audit passed.') process.exit(0) } diff --git a/scripts/check-test-patterns.ts b/scripts/check-test-patterns.ts index 1d810e6e663..afaa9dd82b7 100644 --- a/scripts/check-test-patterns.ts +++ b/scripts/check-test-patterns.ts @@ -19,7 +19,7 @@ * Run: `bun run check:test-patterns` */ import { execFileSync } from 'node:child_process' -import { readdirSync, readFileSync, writeFileSync } from 'node:fs' +import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs' import path from 'node:path' import { parse } from '@babel/parser' @@ -285,14 +285,35 @@ function key(violation: Violation): string { const violations = collect() const current = [...new Set(violations.map(key))].sort() -if (process.argv.includes('--update')) { - writeFileSync(BASELINE, `${JSON.stringify(current, null, 2)}\n`) - console.log(`Wrote ${current.length} baseline entries to ${path.relative(ROOT, BASELINE)}`) - process.exit(0) +/** + * The committed baseline. A missing file fails closed: restore it from git. `--update --init` + * is the only way to create one, and it accepts every current violation. + */ +function readBaseline(): string[] { + if (existsSync(BASELINE)) return JSON.parse(readFileSync(BASELINE, 'utf8')) + if (process.argv.includes('--update') && process.argv.includes('--init')) return current + console.error( + `✗ ${path.relative(ROOT, BASELINE)} is missing. Restore it from git; ` + + 'create a new one only with --update --init.' + ) + process.exit(1) } -const baseline = new Set(JSON.parse(readFileSync(BASELINE, 'utf8'))) +const baseline = new Set(readBaseline()) const added = current.filter((entry) => !baseline.has(entry)) + +if (process.argv.includes('--update')) { + // Shrink-only: drop fixed entries, never admit a new one, and write nothing if refusing. + for (const entry of added) { + const [rule, file, detail] = entry.split('\t') + console.error(`✗ not baselined — fix it: ${rule}: ${file} (${detail})`) + } + if (added.length) process.exit(1) + const kept = current.filter((entry) => baseline.has(entry)) + writeFileSync(BASELINE, `${JSON.stringify(kept, null, 2)}\n`) + console.log(`Wrote ${kept.length} baseline entries to ${path.relative(ROOT, BASELINE)}`) + process.exit(0) +} const currentSet = new Set(current) const stale = [...baseline].filter((entry) => !currentSet.has(entry)) diff --git a/scripts/check-utils-enforcement.ts b/scripts/check-utils-enforcement.ts index 8facefb0075..63da16ffbb7 100644 --- a/scripts/check-utils-enforcement.ts +++ b/scripts/check-utils-enforcement.ts @@ -46,8 +46,6 @@ const ALLOWLISTED_FILES = new Set([ 'apps/sim/lib/execution/isolated-vm-worker.cjs', // Emits the sandbox-side event filter as plain JS source, which cannot import @sim/utils 'apps/sim/executor/handlers/pi/cloud/event-filter-source.ts', - // Uses crypto.getRandomValues() directly (not crypto.randomUUID) — TSDoc comment triggers false positive - 'packages/testing/src/factories/id.ts', ]) /** `s.slice(0, n)` plus a suffix, by `+` or in a template literal; `\1` is `s` and `\2` is `n`. */ diff --git a/scripts/run-audits.ts b/scripts/run-audits.ts index 1c44bddc26f..b06890355cd 100644 --- a/scripts/run-audits.ts +++ b/scripts/run-audits.ts @@ -16,7 +16,7 @@ import path from 'node:path' /** `check:*` scripts this runner deliberately does not own, and why. */ const EXCLUDED: Record = { 'check:audits': 'this runner', - 'check:migrations': 'needs a git base ref argument', + 'check:migrations': 'diffs against a git base ref (origin/staging by default)', 'check:api-validation': 'superseded by the :strict variant, which this runner does run', 'check:dead-code': 'check:unused-exports gates the same issues in its single knip pass', } From 81a425625fec1399a03da734d3eadec306e581b3 Mon Sep 17 00:00:00 2001 From: Waleed Date: Sat, 3 Oct 2026 01:31:39 -0700 Subject: [PATCH 02/12] improvement(tools): delete unreferenced tool response types and the dead generic resource data path (#8596) * improvement(tools): delete unreferenced tool response types and the dead generic resource data path - delete 168 exported tool *Response types nothing references (mostly umbrella unions) and the 24 local types only they used - add-integration and add-tools templates declare one response type per tool and no umbrella union - drop the never-set genericResourceData chat field; the generic resource panel renders its empty state directly * chore(skills): name InternalToolConfig beside ToolConfig in the response-type guidance --- .agents/skills/add-integration/SKILL.md | 4 +- .agents/skills/add-tools/SKILL.md | 2 + .../home/components/chat-resource-panel.tsx | 2 - .../generic-resource-content.tsx | 73 +------- .../resource-content/resource-content.tsx | 11 +- .../mothership-view/mothership-view.tsx | 7 +- .../[workspaceId]/home/hooks/use-chat.ts | 3 - .../app/workspace/[workspaceId]/home/types.ts | 14 -- apps/sim/blocks/blocks/airtable.ts | 1 - apps/sim/tools/ahrefs/types.ts | 25 --- apps/sim/tools/airtable/types.ts | 13 -- apps/sim/tools/apollo/types.ts | 28 --- apps/sim/tools/arxiv/types.ts | 5 - apps/sim/tools/asana/types.ts | 14 -- apps/sim/tools/attio/types.ts | 47 ----- apps/sim/tools/azure_devops/types.ts | 18 -- apps/sim/tools/brex/types.ts | 33 ---- apps/sim/tools/brightdata/types.ts | 10 -- apps/sim/tools/browser_use/types.ts | 4 - apps/sim/tools/cbinsights/types.ts | 95 ---------- apps/sim/tools/clerk/types.ts | 37 ---- apps/sim/tools/clickhouse/types.ts | 2 - apps/sim/tools/clickup/types.ts | 25 --- apps/sim/tools/cloudflare/types.ts | 37 ---- apps/sim/tools/coda/types.ts | 51 ------ apps/sim/tools/confluence/types.ts | 110 ------------ apps/sim/tools/convex/types.ts | 14 -- apps/sim/tools/crowdstrike/types.ts | 23 --- apps/sim/tools/crunchbase/types.ts | 5 - apps/sim/tools/cursor/types.ts | 15 -- apps/sim/tools/dagster/types.ts | 19 -- apps/sim/tools/databricks/types.ts | 25 --- apps/sim/tools/datadog/types.ts | 43 ----- apps/sim/tools/datagma/types.ts | 7 - apps/sim/tools/discord/types.ts | 41 ----- apps/sim/tools/docusign/types.ts | 10 -- apps/sim/tools/downdetector/types.ts | 16 -- apps/sim/tools/dropbox/types.ts | 23 --- apps/sim/tools/dropcontact/types.ts | 3 - apps/sim/tools/dub/types.ts | 19 -- apps/sim/tools/duckduckgo/types.ts | 2 - apps/sim/tools/dynamodb/types.ts | 2 - apps/sim/tools/dynatrace/types.ts | 48 ----- apps/sim/tools/elasticsearch/types.ts | 56 ------ apps/sim/tools/elevenlabs/types.ts | 10 -- apps/sim/tools/emailbison/types.ts | 10 -- apps/sim/tools/enrow/types.ts | 2 - apps/sim/tools/exa/types.ts | 7 - apps/sim/tools/fathom/types.ts | 8 - apps/sim/tools/findymail/types.ts | 13 -- apps/sim/tools/firecrawl/types.ts | 15 -- apps/sim/tools/fireflies/types.ts | 12 -- apps/sim/tools/gamma/types.ts | 7 - apps/sim/tools/github/types.ts | 36 ---- apps/sim/tools/gitlab/types.ts | 58 ------ apps/sim/tools/gong/types.ts | 32 ---- apps/sim/tools/google_appsheet/types.ts | 6 - apps/sim/tools/google_calendar/types.ts | 77 -------- apps/sim/tools/google_contacts/types.ts | 8 - apps/sim/tools/google_docs/types.ts | 17 -- apps/sim/tools/google_drive/types.ts | 6 - apps/sim/tools/google_meet/types.ts | 8 - apps/sim/tools/google_sheets/types.ts | 25 --- apps/sim/tools/google_slides/types.ts | 5 - apps/sim/tools/grafana/types.ts | 46 ----- apps/sim/tools/greenhouse/types.ts | 16 -- apps/sim/tools/greptile/types.ts | 9 - apps/sim/tools/hex/types.ts | 23 --- apps/sim/tools/hubspot/types.ts | 65 ------- apps/sim/tools/hunter/types.ts | 8 - apps/sim/tools/iam/types.ts | 5 - apps/sim/tools/icypeas/types.ts | 2 - apps/sim/tools/identity_center/types.ts | 5 - apps/sim/tools/incidentio/types.ts | 67 ------- apps/sim/tools/infisical/types.ts | 7 - apps/sim/tools/instagram/types.ts | 22 --- apps/sim/tools/instantly/types.ts | 13 -- apps/sim/tools/jira/types.ts | 32 ---- apps/sim/tools/jsm/types.ts | 46 ----- apps/sim/tools/ketch/types.ts | 7 - apps/sim/tools/lambda/types.ts | 52 ------ apps/sim/tools/langsmith/types.ts | 7 - apps/sim/tools/latex/types.ts | 6 - apps/sim/tools/leadmagic/types.ts | 11 -- apps/sim/tools/lemlist/types.ts | 5 - apps/sim/tools/linear/types.ts | 80 --------- apps/sim/tools/linkedin/types.ts | 14 -- apps/sim/tools/logfire/types.ts | 5 - apps/sim/tools/loops/types.ts | 15 -- apps/sim/tools/microsoft_ad/types.ts | 36 ---- apps/sim/tools/microsoft_dataverse/types.ts | 20 --- apps/sim/tools/microsoft_excel/types.ts | 13 -- apps/sim/tools/microsoft_planner/types.ts | 20 --- apps/sim/tools/microsoft_teams/types.ts | 16 -- apps/sim/tools/microsoft_word/types.ts | 9 - apps/sim/tools/millionverifier/types.ts | 4 - apps/sim/tools/mssql/types.ts | 2 - apps/sim/tools/neverbounce/types.ts | 2 - apps/sim/tools/new_relic/types.ts | 6 - apps/sim/tools/okta/types.ts | 46 ----- apps/sim/tools/onedrive/types.ts | 12 -- apps/sim/tools/openai/types.ts | 12 -- apps/sim/tools/outlook/types.ts | 19 -- apps/sim/tools/persona/types.ts | 17 -- apps/sim/tools/pipedrive/types.ts | 21 --- apps/sim/tools/postgresql/types.ts | 2 - apps/sim/tools/prospeo/types.ts | 10 -- apps/sim/tools/quickbooks/types.ts | 21 --- apps/sim/tools/rabbitmq/types.ts | 27 --- apps/sim/tools/railway/types.ts | 22 --- apps/sim/tools/rb2b/types.ts | 16 -- apps/sim/tools/rds/types.ts | 2 - apps/sim/tools/reddit/types.ts | 9 - apps/sim/tools/revenuecat/types.ts | 12 -- apps/sim/tools/rootly/types.ts | 38 ---- apps/sim/tools/sailpoint/types.ts | 53 ------ apps/sim/tools/salesforce/types.ts | 42 ----- apps/sim/tools/secrets_manager/types.ts | 5 - apps/sim/tools/semrush/types.ts | 46 ----- apps/sim/tools/sentry/types.ts | 18 -- apps/sim/tools/servicenow/types.ts | 19 -- apps/sim/tools/sharepoint/types.ts | 26 --- apps/sim/tools/slack/types.ts | 47 ----- apps/sim/tools/smartlead/types.ts | 29 --- apps/sim/tools/splunk/types.ts | 14 -- apps/sim/tools/sqs/types.ts | 7 - apps/sim/tools/square/types.ts | 20 --- apps/sim/tools/stripe/types.ts | 21 --- apps/sim/tools/sts/types.ts | 4 - apps/sim/tools/stt/types.ts | 13 -- apps/sim/tools/supabase/types.ts | 2 - apps/sim/tools/tavily/types.ts | 2 - apps/sim/tools/telegram/types.ts | 12 -- apps/sim/tools/temporal/types.ts | 18 -- apps/sim/tools/tiktok/types.ts | 10 -- apps/sim/tools/tinybird/types.ts | 12 -- apps/sim/tools/trello/types.ts | 23 --- apps/sim/tools/trigger_dev/types.ts | 33 ---- apps/sim/tools/typeform/types.ts | 7 - apps/sim/tools/vanta/types.ts | 28 --- apps/sim/tools/video/types.ts | 12 -- apps/sim/tools/wealthbox/types.ts | 2 - apps/sim/tools/webflow/types.ts | 7 - apps/sim/tools/wikipedia/types.ts | 6 - apps/sim/tools/wiza/types.ts | 6 - apps/sim/tools/wordpress/types.ts | 50 ------ apps/sim/tools/x/types.ts | 2 - apps/sim/tools/youtube/types.ts | 11 -- apps/sim/tools/zendesk/types.ts | 15 -- apps/sim/tools/zerobounce/types.ts | 2 - apps/sim/tools/zoom/types.ts | 13 -- apps/sim/tools/zoominfo/types.ts | 8 - scripts/check-unused-exports.baseline.json | 165 ------------------ 153 files changed, 12 insertions(+), 3184 deletions(-) diff --git a/.agents/skills/add-integration/SKILL.md b/.agents/skills/add-integration/SKILL.md index 07c33c130b7..74289debc60 100644 --- a/.agents/skills/add-integration/SKILL.md +++ b/.agents/skills/add-integration/SKILL.md @@ -85,13 +85,15 @@ export interface {Service}{Action}Params { optionalParam?: string } -export interface {Service}Response extends ToolResponse { +export interface {Service}{Action}Response extends ToolResponse { output: { // Define output structure } } ``` +Declare one response interface per tool, imported by that tool's `ToolConfig` (or `InternalToolConfig` for in-process work). Never add an umbrella `{Service}Response` union: nothing imports it. + **Tool file pattern:** an external provider API uses `ToolConfig` with `request` (absolute `https://` URL, headers, body, `transformResponse`); same-process Sim work uses `InternalToolConfig` with `operation`. Both full templates, param visibility rules, and output typing live in `.agents/skills/add-tools/SKILL.md` — read it before writing the first tool. ### Critical Rules diff --git a/.agents/skills/add-tools/SKILL.md b/.agents/skills/add-tools/SKILL.md index e488f4c9469..d54af50dd0f 100644 --- a/.agents/skills/add-tools/SKILL.md +++ b/.agents/skills/add-tools/SKILL.md @@ -423,6 +423,8 @@ export interface {Service}{Action}Response extends ToolResponse { } ``` +Each response interface is imported by its tool's config: `ToolConfig` for an external API, `InternalToolConfig` for in-process work. Never add an umbrella `{Service}Response` union of them: nothing imports it. + ## Index.ts Barrel Export Pattern ```typescript diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/chat-resource-panel.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/chat-resource-panel.tsx index 1b67be0a675..0b93d1793e3 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/chat-resource-panel.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/chat-resource-panel.tsx @@ -47,7 +47,6 @@ export function ChatResourcePanel({ setTableViewContext, previewSession, isSending, - genericResourceData, } = chat const { isResourceCollapsed, @@ -102,7 +101,6 @@ export function ChatResourcePanel({ isCollapsed={isResourceCollapsed} previewSession={previewSession} isAgentResponding={isSending} - genericResourceData={genericResourceData ?? undefined} onSummarize={summarize} onUserInteraction={handleResourceInteraction} className={skipResourceTransition ? 'transition-none!' : undefined} diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/components/generic-resource-content/generic-resource-content.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/components/generic-resource-content/generic-resource-content.tsx index d763ae269f7..e939eb48a75 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/components/generic-resource-content/generic-resource-content.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/components/generic-resource-content/generic-resource-content.tsx @@ -1,73 +1,8 @@ -'use client' - -import { useEffect, useRef } from 'react' -import { PillsRing } from '@sim/emcn' -import { getToolStatusDisplayTitle } from '@/lib/mothership/tools/tool-display' -import type { GenericResourceData } from '@/app/workspace/[workspaceId]/home/types' - -interface GenericResourceContentProps { - data: GenericResourceData -} - -// TODO: Emir — replace with rich UI (status icons, collapsible result cards, copy-to-clipboard, etc.) -export function GenericResourceContent({ data }: GenericResourceContentProps) { - const bottomRef = useRef(null) - - useEffect(() => { - const el = bottomRef.current - const container = el?.parentElement - if (container) { - container.scrollTop = container.scrollHeight - } - }, [data.entries.length]) - - if (data.entries.length === 0) { - return ( -
-

No results yet

-
- ) - } - +/** The panel for a `generic` resource, which carries no content of its own. */ +export function GenericResourceContent() { return ( -
- {data.entries.map((entry) => ( -
-
- {entry.status === 'executing' && ( - - )} - - {getToolStatusDisplayTitle(entry.displayTitle, entry.status, entry.toolName)} - - {entry.status === 'error' && ( - Error - )} - {entry.status === 'skipped' && ( - Skipped - )} - {entry.status === 'rejected' && ( - Rejected - )} -
- {entry.streamingArgs && ( -
-              {entry.streamingArgs}
-            
- )} - {!entry.streamingArgs && entry.result?.output != null && ( -
-              {typeof entry.result.output === 'string'
-                ? entry.result.output
-                : JSON.stringify(entry.result.output, null, 2)}
-            
- )} - {entry.result?.error && ( -

{entry.result.error}

- )} -
- ))} -
+
+

No results yet

) } diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/resource-content.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/resource-content.tsx index 0685009d447..2329d717c9a 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/resource-content.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/resource-content.tsx @@ -45,10 +45,7 @@ import { GenericResourceContent } from '@/app/workspace/[workspaceId]/home/compo import { TerminalSession } from '@/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/components/terminal-session/terminal-session' import { RESOURCE_TAB_ICON_CLASS } from '@/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-tabs/resource-tab-controls' import { hasRenderableFilePreviewContent } from '@/app/workspace/[workspaceId]/home/hooks/preview' -import type { - GenericResourceData, - MothershipResource, -} from '@/app/workspace/[workspaceId]/home/types' +import type { MothershipResource } from '@/app/workspace/[workspaceId]/home/types' import { KnowledgeBase } from '@/app/workspace/[workspaceId]/knowledge/[id]/base' import { LogDetailsContent } from '@/app/workspace/[workspaceId]/logs/components' import { useFeatureFlag } from '@/app/workspace/[workspaceId]/providers/feature-flags-provider' @@ -113,7 +110,6 @@ interface ResourceContentProps { previewMode?: PreviewMode previewSession?: FilePreviewSession | null isAgentResponding?: boolean - genericResourceData?: GenericResourceData previewContextKey?: string onNotFound?: (resourceId: string) => void /** @@ -187,7 +183,6 @@ export const ResourceContent = memo(function ResourceContent({ previewMode, previewSession, isAgentResponding, - genericResourceData, previewContextKey, onNotFound, visible = true, @@ -351,9 +346,7 @@ export const ResourceContent = memo(function ResourceContent({ ) case 'generic': - return ( - - ) + return case 'browser': // One panel serves every browser tab of the chat: the desktop app diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/mothership-view.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/mothership-view.tsx index 75ded534ef2..9fb538d0330 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/mothership-view.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/mothership-view.tsx @@ -27,7 +27,6 @@ import { TerminalSession } from '@/app/workspace/[workspaceId]/home/components/m import { ResourceWorkspaceHost } from '@/app/workspace/[workspaceId]/home/components/resource-workspace-host' import { hasRenderableFilePreviewContent } from '@/app/workspace/[workspaceId]/home/hooks/preview' import type { - GenericResourceData, MothershipResource, MothershipResourceType, } from '@/app/workspace/[workspaceId]/home/types' @@ -105,7 +104,6 @@ interface MothershipViewProps { previewSession?: FilePreviewSession | null isAgentResponding?: boolean onSummarize: (message: string, filters: WorkspaceSearchFilters) => void - genericResourceData?: GenericResourceData /** Claims the current resource selection after direct panel interaction. */ onUserInteraction?: () => void } @@ -126,7 +124,6 @@ export const MothershipView = memo( className, previewSession, isAgentResponding, - genericResourceData, onSummarize, onUserInteraction, }: MothershipViewProps, @@ -316,7 +313,6 @@ export const MothershipView = memo( previewMode={isActivePreviewable ? previewMode : undefined} previewSession={previewForActive} isAgentResponding={isAgentResponding} - genericResourceData={active.type === 'generic' ? genericResourceData : undefined} previewContextKey={chatId} onNotFound={(resourceId) => removeResource('log', resourceId, active.workspaceId)} /> @@ -348,8 +344,7 @@ function ScopedResourceContent({ if (props.resource.type === 'search') return if (!workspaceId) { - if (props.resource.type === 'generic') - return + if (props.resource.type === 'generic') return if (props.resource.type === 'browser') return ( string | undefined } @@ -4981,7 +4979,6 @@ export function useChat( editingQueuedId, dispatchingHeadId, previewSession, - genericResourceData: null, getCurrentRequestId, } } diff --git a/apps/sim/app/workspace/[workspaceId]/home/types.ts b/apps/sim/app/workspace/[workspaceId]/home/types.ts index 9aaaa4a83b2..ac11d5c981d 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/types.ts +++ b/apps/sim/app/workspace/[workspaceId]/home/types.ts @@ -55,20 +55,6 @@ interface ToolCallResult { error?: string } -interface GenericResourceEntry { - toolCallId: string - toolName: string - displayTitle: string - status: ToolCallStatus - params?: Record - streamingArgs?: string - result?: ToolCallResult -} - -export interface GenericResourceData { - entries: GenericResourceEntry[] -} - export interface ToolCallData { id: string toolName: string diff --git a/apps/sim/blocks/blocks/airtable.ts b/apps/sim/blocks/blocks/airtable.ts index bbf0ed9c8e6..6cfdec23592 100644 --- a/apps/sim/blocks/blocks/airtable.ts +++ b/apps/sim/blocks/blocks/airtable.ts @@ -457,7 +457,6 @@ Return ONLY the valid JSON array of record ID strings - no explanations, no mark typecast: { type: 'boolean', description: 'Auto-convert string values to field types' }, recordIds: { type: 'json', description: 'Record IDs to delete' }, // Required for delete }, - // Output structure depends on the operation, covered by AirtableResponse union type outputs: { bases: { type: 'json', description: 'List of accessible Airtable bases' }, tables: { type: 'json', description: 'Table schemas with fields and views' }, diff --git a/apps/sim/tools/ahrefs/types.ts b/apps/sim/tools/ahrefs/types.ts index 79b27125c02..26b02ca71ae 100644 --- a/apps/sim/tools/ahrefs/types.ts +++ b/apps/sim/tools/ahrefs/types.ts @@ -569,28 +569,3 @@ export interface AhrefsPaidPagesResponse extends ToolResponse { paidPages: AhrefsPaidPage[] } } - -export type AhrefsResponse = - | AhrefsDomainRatingResponse - | AhrefsBacklinksResponse - | AhrefsBacklinksStatsResponse - | AhrefsReferringDomainsResponse - | AhrefsOrganicKeywordsResponse - | AhrefsTopPagesResponse - | AhrefsKeywordOverviewResponse - | AhrefsBrokenBacklinksResponse - | AhrefsMetricsResponse - | AhrefsOrganicCompetitorsResponse - | AhrefsRankTrackerOverviewResponse - | AhrefsRankTrackerSerpOverviewResponse - | AhrefsRankTrackerCompetitorsOverviewResponse - | AhrefsRankTrackerCompetitorsStatsResponse - | AhrefsBatchAnalysisResponse - | AhrefsSiteAuditPageExplorerResponse - | AhrefsDomainRatingHistoryResponse - | AhrefsMetricsHistoryResponse - | AhrefsRefdomainsHistoryResponse - | AhrefsKeywordsHistoryResponse - | AhrefsRelatedTermsResponse - | AhrefsAnchorsResponse - | AhrefsPaidPagesResponse diff --git a/apps/sim/tools/airtable/types.ts b/apps/sim/tools/airtable/types.ts index 10246ed1292..fd220989d55 100644 --- a/apps/sim/tools/airtable/types.ts +++ b/apps/sim/tools/airtable/types.ts @@ -1,4 +1,3 @@ -import type { AirtableGetBaseSchemaResponse } from '@/tools/airtable/get_base_schema' import type { ToolResponse } from '@/tools/types' // Common types @@ -198,15 +197,3 @@ export interface AirtableUpsertResponse extends ToolResponse { } } } - -export type AirtableResponse = - | AirtableListBasesResponse - | AirtableListTablesResponse - | AirtableListResponse - | AirtableGetResponse - | AirtableCreateResponse - | AirtableUpdateResponse - | AirtableUpdateMultipleResponse - | AirtableDeleteResponse - | AirtableUpsertResponse - | AirtableGetBaseSchemaResponse diff --git a/apps/sim/tools/apollo/types.ts b/apps/sim/tools/apollo/types.ts index 1c68e180ea0..480b82abb04 100644 --- a/apps/sim/tools/apollo/types.ts +++ b/apps/sim/tools/apollo/types.ts @@ -675,31 +675,3 @@ export interface ApolloSequenceSearchResponse extends ToolResponse { total_entries: number } } - -// Union type for all Apollo responses -export type ApolloResponse = - | ApolloPeopleSearchResponse - | ApolloPeopleEnrichResponse - | ApolloPeopleBulkEnrichResponse - | ApolloOrganizationSearchResponse - | ApolloOrganizationEnrichResponse - | ApolloOrganizationBulkEnrichResponse - | ApolloContactCreateResponse - | ApolloContactUpdateResponse - | ApolloContactBulkCreateResponse - | ApolloContactBulkUpdateResponse - | ApolloContactSearchResponse - | ApolloAccountCreateResponse - | ApolloAccountUpdateResponse - | ApolloAccountSearchResponse - | ApolloAccountBulkCreateResponse - | ApolloAccountBulkUpdateResponse - | ApolloSequenceAddContactsResponse - | ApolloTaskCreateResponse - | ApolloTaskSearchResponse - | ApolloEmailAccountsResponse - | ApolloSequenceSearchResponse - | ApolloOpportunityCreateResponse - | ApolloOpportunitySearchResponse - | ApolloOpportunityGetResponse - | ApolloOpportunityUpdateResponse diff --git a/apps/sim/tools/arxiv/types.ts b/apps/sim/tools/arxiv/types.ts index 7cf8062b4bc..d330a7af42e 100644 --- a/apps/sim/tools/arxiv/types.ts +++ b/apps/sim/tools/arxiv/types.ts @@ -58,8 +58,3 @@ export interface ArxivGetAuthorPapersResponse extends ToolResponse { authorName: string } } - -export type ArxivResponse = - | ArxivSearchResponse - | ArxivGetPaperResponse - | ArxivGetAuthorPapersResponse diff --git a/apps/sim/tools/asana/types.ts b/apps/sim/tools/asana/types.ts index 5bf7d09e1c6..78ab9a5bf4f 100644 --- a/apps/sim/tools/asana/types.ts +++ b/apps/sim/tools/asana/types.ts @@ -285,17 +285,3 @@ export interface AsanaListSectionsResponse extends ToolResponse { }> } } - -export type AsanaResponse = - | AsanaGetTaskResponse - | AsanaCreateTaskResponse - | AsanaUpdateTaskResponse - | AsanaGetProjectsResponse - | AsanaSearchTasksResponse - | AsanaAddCommentResponse - | AsanaProjectRecordResponse - | AsanaListWorkspacesResponse - | AsanaDeleteTaskResponse - | AsanaAddFollowersResponse - | AsanaSectionResponse - | AsanaListSectionsResponse diff --git a/apps/sim/tools/attio/types.ts b/apps/sim/tools/attio/types.ts index 56a10e13486..acb1e5c206f 100644 --- a/apps/sim/tools/attio/types.ts +++ b/apps/sim/tools/attio/types.ts @@ -1246,50 +1246,3 @@ export interface AttioUpdateAttributeParams { export interface AttioUpdateAttributeResponse extends ToolResponse { output: AttioAttributeOutput } - -export type AttioResponse = - | AttioListRecordsResponse - | AttioGetRecordResponse - | AttioCreateRecordResponse - | AttioUpdateRecordResponse - | AttioDeleteRecordResponse - | AttioSearchRecordsResponse - | AttioAssertRecordResponse - | AttioListNotesResponse - | AttioGetNoteResponse - | AttioCreateNoteResponse - | AttioDeleteNoteResponse - | AttioListTasksResponse - | AttioCreateTaskResponse - | AttioUpdateTaskResponse - | AttioGetTaskResponse - | AttioDeleteTaskResponse - | AttioListObjectsResponse - | AttioGetObjectResponse - | AttioCreateObjectResponse - | AttioUpdateObjectResponse - | AttioListListsResponse - | AttioGetListResponse - | AttioCreateListResponse - | AttioUpdateListResponse - | AttioQueryListEntriesResponse - | AttioGetListEntryResponse - | AttioCreateListEntryResponse - | AttioUpdateListEntryResponse - | AttioDeleteListEntryResponse - | AttioListMembersResponse - | AttioGetMemberResponse - | AttioCreateCommentResponse - | AttioGetCommentResponse - | AttioDeleteCommentResponse - | AttioListThreadsResponse - | AttioGetThreadResponse - | AttioListWebhooksResponse - | AttioGetWebhookResponse - | AttioCreateWebhookResponse - | AttioUpdateWebhookResponse - | AttioDeleteWebhookResponse - | AttioListAttributesResponse - | AttioGetAttributeResponse - | AttioCreateAttributeResponse - | AttioUpdateAttributeResponse diff --git a/apps/sim/tools/azure_devops/types.ts b/apps/sim/tools/azure_devops/types.ts index 048409985ff..2f20f9237be 100644 --- a/apps/sim/tools/azure_devops/types.ts +++ b/apps/sim/tools/azure_devops/types.ts @@ -414,24 +414,6 @@ export interface AddCommentResponse extends ToolResponse { // ── Response Union ──────────────────────────────────────────────────────────── -export type AzureDevOpsResponse = - | ListPipelinesResponse - | GetPipelineResponse - | ListPipelineRunsResponse - | GetPipelineRunResponse - | ListBuildsResponse - | ListBuildLogsResponse - | GetBuildLogResponse - | GetBuildTimelineResponse - | GetWorkItemsBetweenBuildsResponse - | QueryWorkItemsResponse - | GetWorkItemResponse - | GetWorkItemsBatchResponse - | CreateWorkItemResponse - | UpdateWorkItemResponse - | AddCommentResponse - | GetCommentsResponse - // ── Get Comments ────────────────────────────────────────────────────────────── export interface GetCommentsParams extends AzureDevOpsBaseParams { diff --git a/apps/sim/tools/brex/types.ts b/apps/sim/tools/brex/types.ts index a79211afc85..4ec35be19ae 100644 --- a/apps/sim/tools/brex/types.ts +++ b/apps/sim/tools/brex/types.ts @@ -712,39 +712,6 @@ export interface BrexUpdateVendorResponse extends ToolResponse { } } -export type BrexResponse = - | BrexListExpensesResponse - | BrexGetExpenseResponse - | BrexUpdateExpenseResponse - | BrexUploadReceiptResponse - | BrexListCardTransactionsResponse - | BrexListCashTransactionsResponse - | BrexListCardAccountsResponse - | BrexListCashAccountsResponse - | BrexListUsersResponse - | BrexGetUserResponse - | BrexListDepartmentsResponse - | BrexListLocationsResponse - | BrexListBudgetsResponse - | BrexListSpendLimitsResponse - | BrexListVendorsResponse - | BrexListTransfersResponse - | BrexGetCompanyResponse - | BrexListCardsResponse - | BrexListTitlesResponse - | BrexGetCashAccountResponse - | BrexListStatementsResponse - | BrexGetBudgetResponse - | BrexGetSpendLimitResponse - | BrexGetVendorResponse - | BrexGetTransferResponse - | BrexCreateTransferResponse - | BrexCreateBudgetResponse - | BrexArchiveBudgetResponse - | BrexCreateSpendLimitResponse - | BrexCreateVendorResponse - | BrexUpdateVendorResponse - export const BREX_MONEY_PROPERTIES: Record = { amount: { type: 'number', diff --git a/apps/sim/tools/brightdata/types.ts b/apps/sim/tools/brightdata/types.ts index 8df36c38267..06a1bf4f8b6 100644 --- a/apps/sim/tools/brightdata/types.ts +++ b/apps/sim/tools/brightdata/types.ts @@ -137,13 +137,3 @@ export interface BrightDataDiscoverResponse extends ToolResponse { taskId?: string | null } } - -export type BrightDataResponse = - | BrightDataScrapeUrlResponse - | BrightDataSerpSearchResponse - | BrightDataScrapeDatasetResponse - | BrightDataSyncScrapeResponse - | BrightDataSnapshotStatusResponse - | BrightDataDownloadSnapshotResponse - | BrightDataCancelSnapshotResponse - | BrightDataDiscoverResponse diff --git a/apps/sim/tools/browser_use/types.ts b/apps/sim/tools/browser_use/types.ts index 1316bf41a14..cd1beade932 100644 --- a/apps/sim/tools/browser_use/types.ts +++ b/apps/sim/tools/browser_use/types.ts @@ -42,7 +42,3 @@ interface BrowserUseTaskOutput { export interface BrowserUseRunTaskResponse extends ToolResponse { output: BrowserUseTaskOutput } - -export interface BrowserUseResponse extends ToolResponse { - output: BrowserUseTaskOutput -} diff --git a/apps/sim/tools/cbinsights/types.ts b/apps/sim/tools/cbinsights/types.ts index 1dae7f163ca..57d72602b64 100644 --- a/apps/sim/tools/cbinsights/types.ts +++ b/apps/sim/tools/cbinsights/types.ts @@ -58,24 +58,6 @@ export interface CbInsightsPagedOrgListResponse extends ToolResponse { } } -export interface CbInsightsPagedItemsResponse extends ToolResponse { - output: CbInsightsPageInfo & { - items: CbInsightsRecord[] - } -} - -export interface CbInsightsItemsResponse extends ToolResponse { - output: { - items: CbInsightsRecord[] - } -} - -export interface CbInsightsObjectResponse extends ToolResponse { - output: { - data: CbInsightsRecord - } -} - export interface CbInsightsChatResponse extends ToolResponse { output: { chatId: string | null @@ -93,80 +75,3 @@ export interface CbInsightsRagResponse extends ToolResponse { guidance: string[] } } - -export interface CbInsightsScoutingReportResponse extends ToolResponse { - output: { - orgInfo: CbInsightsRecord | null - reportMarkdown: string | null - reportJson: string | null - } -} - -export interface CbInsightsStrategyMapResponse extends ToolResponse { - output: { - orgName: string | null - logoUrl: string | null - categories: CbInsightsRecord[] - } -} - -export interface CbInsightsMosaicHistoryResponse extends ToolResponse { - output: { - overall: CbInsightsRecord[] - management: CbInsightsRecord[] - market: CbInsightsRecord[] - momentum: CbInsightsRecord[] - money: CbInsightsRecord[] - } -} - -export interface CbInsightsExitProbabilityHistoryResponse extends ToolResponse { - output: { - ipo: CbInsightsRecord[] - mna: CbInsightsRecord[] - incompleteRoundType: string | null - } -} - -export interface CbInsightsFundingWindowResponse extends ToolResponse { - output: { - windowStart: string | null - windowEnd: string | null - cohortNextRoundRate: number | null - cohortCriteria: CbInsightsRecord | null - latestFunding: CbInsightsRecord | null - } -} - -export interface CbInsightsRevenueResponse extends ToolResponse { - output: { - orgId: number | null - orgName: string | null - orgUrl: string | null - revenue: CbInsightsRecord[] - } -} - -export interface CbInsightsFundingsResponse extends ToolResponse { - output: CbInsightsPageInfo & { - fundings: CbInsightsRecord[] - capTableHistory: CbInsightsRecord[] - } -} - -export type CbInsightsResponse = - | CbInsightsListResponse - | CbInsightsOrgListResponse - | CbInsightsPagedOrgListResponse - | CbInsightsPagedItemsResponse - | CbInsightsItemsResponse - | CbInsightsObjectResponse - | CbInsightsChatResponse - | CbInsightsRagResponse - | CbInsightsScoutingReportResponse - | CbInsightsStrategyMapResponse - | CbInsightsMosaicHistoryResponse - | CbInsightsExitProbabilityHistoryResponse - | CbInsightsFundingWindowResponse - | CbInsightsRevenueResponse - | CbInsightsFundingsResponse diff --git a/apps/sim/tools/clerk/types.ts b/apps/sim/tools/clerk/types.ts index 1f6d04abe5d..073508ce5be 100644 --- a/apps/sim/tools/clerk/types.ts +++ b/apps/sim/tools/clerk/types.ts @@ -1040,40 +1040,3 @@ export interface ClerkRevokeActorTokenParams { export interface ClerkRevokeActorTokenResponse extends ToolResponse { output: ClerkActorTokenOutput & { success: boolean } } - -/** Union of every Clerk tool response, used by the block. */ -export type ClerkResponse = - | ClerkListUsersResponse - | ClerkGetUserResponse - | ClerkCreateUserResponse - | ClerkUpdateUserResponse - | ClerkDeleteUserResponse - | ClerkListOrganizationsResponse - | ClerkGetOrganizationResponse - | ClerkCreateOrganizationResponse - | ClerkUpdateOrganizationResponse - | ClerkDeleteOrganizationResponse - | ClerkListSessionsResponse - | ClerkGetSessionResponse - | ClerkRevokeSessionResponse - | ClerkListOrganizationMembershipsResponse - | ClerkAddOrganizationMemberResponse - | ClerkUpdateOrganizationMembershipResponse - | ClerkRemoveOrganizationMemberResponse - | ClerkCreateOrganizationInvitationResponse - | ClerkListOrganizationInvitationsResponse - | ClerkBanUserResponse - | ClerkUnbanUserResponse - | ClerkLockUserResponse - | ClerkUnlockUserResponse - | ClerkGetUserOauthTokenResponse - | ClerkListAllowlistIdentifiersResponse - | ClerkCreateAllowlistIdentifierResponse - | ClerkDeleteAllowlistIdentifierResponse - | ClerkListBlocklistIdentifiersResponse - | ClerkCreateBlocklistIdentifierResponse - | ClerkDeleteBlocklistIdentifierResponse - | ClerkListJwtTemplatesResponse - | ClerkGetJwtTemplateResponse - | ClerkCreateActorTokenResponse - | ClerkRevokeActorTokenResponse diff --git a/apps/sim/tools/clickhouse/types.ts b/apps/sim/tools/clickhouse/types.ts index 99258d04f7e..063cf3d5155 100644 --- a/apps/sim/tools/clickhouse/types.ts +++ b/apps/sim/tools/clickhouse/types.ts @@ -209,5 +209,3 @@ export interface ClickHouseIntrospectResponse extends ToolResponse { } error?: string } - -export interface ClickHouseResponse extends ClickHouseRowsResponse {} diff --git a/apps/sim/tools/clickup/types.ts b/apps/sim/tools/clickup/types.ts index 57b980cc2aa..1960b8e70f6 100644 --- a/apps/sim/tools/clickup/types.ts +++ b/apps/sim/tools/clickup/types.ts @@ -648,28 +648,3 @@ export interface ClickUpGetRunningTimerParams { workspaceId: string assignee?: number } - -export type ClickUpResponse = - | ClickUpTaskResponse - | ClickUpTaskListResponse - | ClickUpDeleteResponse - | ClickUpCreateCommentResponse - | ClickUpCommentListResponse - | ClickUpUpdateCommentResponse - | ClickUpUploadAttachmentResponse - | ClickUpWorkspaceListResponse - | ClickUpSpaceListResponse - | ClickUpFolderListResponse - | ClickUpFolderResponse - | ClickUpListListResponse - | ClickUpListResponse - | ClickUpTagListResponse - | ClickUpTaskTagResponse - | ClickUpMemberListResponse - | ClickUpCustomFieldListResponse - | ClickUpCustomFieldValueResponse - | ClickUpChecklistResponse - | ClickUpUpdateChecklistResponse - | ClickUpTimeEntryListResponse - | ClickUpTimeEntryResponse - | ClickUpUpdateTimeEntryResponse diff --git a/apps/sim/tools/cloudflare/types.ts b/apps/sim/tools/cloudflare/types.ts index fe6cd87349b..62f837dca1e 100644 --- a/apps/sim/tools/cloudflare/types.ts +++ b/apps/sim/tools/cloudflare/types.ts @@ -1349,40 +1349,3 @@ export interface CloudflareGetTunnelConfigurationResponse extends ToolResponse { config: Record | null } } - -export type CloudflareResponse = - | CloudflareListRulesetsResponse - | CloudflareRulesetResponse - | CloudflareListManagedRulesetOverridesResponse - | CloudflareListAccessApplicationsResponse - | CloudflareAccessApplicationResponse - | CloudflareListAccessPoliciesResponse - | CloudflareAccessPolicyResponse - | CloudflareListAccessGroupsResponse - | CloudflareListAccessIdentityProvidersResponse - | CloudflareListAccessServiceTokensResponse - | CloudflareCreateAccessServiceTokenResponse - | CloudflareAccessServiceTokenResponse - | CloudflareDeletedIdResponse - | CloudflareListR2BucketsResponse - | CloudflareR2BucketResponse - | CloudflareDeleteR2BucketResponse - | CloudflareListWorkerScriptsResponse - | CloudflareGetWorkerScriptSettingsResponse - | CloudflareListWorkerRoutesResponse - | CloudflareListTunnelsResponse - | CloudflareTunnelResponse - | CloudflareGetTunnelConfigurationResponse - | CloudflareListZonesResponse - | CloudflareGetZoneResponse - | CloudflareCreateZoneResponse - | CloudflareDeleteZoneResponse - | CloudflareListDnsRecordsResponse - | CloudflareCreateDnsRecordResponse - | CloudflareUpdateDnsRecordResponse - | CloudflareDeleteDnsRecordResponse - | CloudflareListCertificatesResponse - | CloudflarePurgeCacheResponse - | CloudflareDnsAnalyticsResponse - | CloudflareGetZoneSettingsResponse - | CloudflareUpdateZoneSettingResponse diff --git a/apps/sim/tools/coda/types.ts b/apps/sim/tools/coda/types.ts index b32167c0b5a..c96b67c057a 100644 --- a/apps/sim/tools/coda/types.ts +++ b/apps/sim/tools/coda/types.ts @@ -727,54 +727,3 @@ export interface CodaTriggerAutomationParams extends CodaDocParams { ruleId: string payload?: unknown } - -export type CodaResponse = - | CodaWhoamiResponse - | CodaListDocsResponse - | CodaDocResponse - | CodaCreateDocResponse - | CodaDocIdResponse - | CodaListCategoriesResponse - | CodaRequestIdResponse - | CodaSharingMetadataResponse - | CodaAclSettingsResponse - | CodaSearchPrincipalsResponse - | CodaListPermissionsResponse - | CodaAddPermissionResponse - | CodaDeletePermissionResponse - | CodaListPagesResponse - | CodaPageResponse - | CodaPageMutationResponse - | CodaGetPageContentResponse - | CodaExportPageResponse - | CodaPageExportStatusResponse - | CodaListTablesResponse - | CodaTableResponse - | CodaListColumnsResponse - | CodaColumnResponse - | CodaListRowsResponse - | CodaRowResponse - | CodaUpsertRowsResponse - | CodaRowMutationResponse - | CodaDeleteRowsResponse - | CodaPushButtonResponse - | CodaListFormulasResponse - | CodaFormulaResponse - | CodaListControlsResponse - | CodaControlResponse - | CodaListFoldersResponse - | CodaFolderResponse - | CodaDeleteFolderResponse - | CodaListFolderChildrenResponse - | CodaListWorkspaceMembersResponse - | CodaChangeUserRoleResponse - | CodaListWorkspaceRolesResponse - | CodaListDocAnalyticsResponse - | CodaListPageAnalyticsResponse - | CodaDocAnalyticsSummaryResponse - | CodaAnalyticsLastUpdatedResponse - | CodaListCustomDomainsResponse - | CodaCustomDomainResponse - | CodaGetCustomDomainProviderResponse - | CodaResolveBrowserLinkResponse - | CodaGetMutationStatusResponse diff --git a/apps/sim/tools/confluence/types.ts b/apps/sim/tools/confluence/types.ts index 416d4bd258d..2e9e092a1d0 100644 --- a/apps/sim/tools/confluence/types.ts +++ b/apps/sim/tools/confluence/types.ts @@ -447,113 +447,3 @@ export interface ConfluenceUpdateResponse extends ToolResponse { success: boolean } } - -interface ConfluenceCreatePageResponse extends ToolResponse { - output: { - ts: string - pageId: string - title: string - url: string - } -} - -interface ConfluenceDeletePageResponse extends ToolResponse { - output: { - ts: string - pageId: string - deleted: boolean - } -} - -interface ConfluenceSearchResponse extends ToolResponse { - output: { - ts: string - results: Array<{ - id: string - title: string - type: string - url: string - excerpt: string - }> - } -} - -interface ConfluenceCommentResponse extends ToolResponse { - output: { - ts: string - commentId: string - pageId: string - } -} - -interface ConfluenceAttachmentResponse extends ToolResponse { - output: { - ts: string - attachments?: Array<{ - id: string - title: string - fileSize: number - mediaType: string - downloadUrl: string - }> - attachmentId?: string - deleted?: boolean - } -} - -interface ConfluenceUploadAttachmentResponse extends ToolResponse { - output: { - ts: string - attachmentId: string - title: string - fileSize: number - mediaType: string - downloadUrl: string - pageId: string - } -} - -interface ConfluenceLabelResponse extends ToolResponse { - output: { - ts: string - labels?: Array<{ - id: string - name: string - prefix: string - }> - pageId?: string - labelName?: string - added?: boolean - removed?: boolean - } -} - -interface ConfluenceSpaceResponse extends ToolResponse { - output: { - ts: string - spaces?: Array<{ - id: string - name: string - key: string - type: string - status: string - }> - spaceId?: string - name?: string - key?: string - type?: string - status?: string - } -} - -export type ConfluenceResponse = - | ConfluenceRetrieveResponse - | ConfluenceUpdateResponse - | ConfluenceCreatePageResponse - | ConfluenceDeletePageResponse - | ConfluenceSearchResponse - | ConfluenceCommentResponse - | ConfluenceAttachmentResponse - | ConfluenceUploadAttachmentResponse - | ConfluenceLabelResponse - | ConfluenceSpaceResponse diff --git a/apps/sim/tools/convex/types.ts b/apps/sim/tools/convex/types.ts index 4f474a9c596..96e6cd2b5b1 100644 --- a/apps/sim/tools/convex/types.ts +++ b/apps/sim/tools/convex/types.ts @@ -87,17 +87,3 @@ export interface ConvexDocumentDeltasApiResponse { hasMore?: boolean cursor?: number | string | null } - -export interface ConvexResponse extends ToolResponse { - output: { - value?: unknown - logLines?: string[] - tables?: string[] - schemas?: Record - documents?: unknown[] - hasMore?: boolean - snapshot?: string | null - pageCursor?: string | null - cursor?: string | null - } -} diff --git a/apps/sim/tools/crowdstrike/types.ts b/apps/sim/tools/crowdstrike/types.ts index 4dc0a753c58..43a3ff33e41 100644 --- a/apps/sim/tools/crowdstrike/types.ts +++ b/apps/sim/tools/crowdstrike/types.ts @@ -657,26 +657,3 @@ export interface CrowdStrikeGetCaseDetailsResponse extends ToolResponse { errors: CrowdStrikeApiError[] } } - -export type CrowdStrikeResponse = - | CrowdStrikeQuerySensorsResponse - | CrowdStrikeGetSensorDetailsResponse - | CrowdStrikeGetSensorAggregatesResponse - | CrowdStrikeQueryAlertsResponse - | CrowdStrikeGetAlertDetailsResponse - | CrowdStrikeUpdateAlertsResponse - | CrowdStrikePerformHostActionResponse - | CrowdStrikeQueryHostGroupsResponse - | CrowdStrikeGetHostGroupDetailsResponse - | CrowdStrikePerformHostGroupActionResponse - | CrowdStrikeQueryIndicatorsResponse - | CrowdStrikeIndicatorListResponse - | CrowdStrikeDeleteIndicatorsResponse - | CrowdStrikeQueryVulnerabilitiesResponse - | CrowdStrikeGetVulnerabilityDetailsResponse - | CrowdStrikeInitRtrSessionResponse - | CrowdStrikeExecuteRtrCommandResponse - | CrowdStrikeGetRtrCommandStatusResponse - | CrowdStrikeDeleteRtrSessionResponse - | CrowdStrikeQueryCasesResponse - | CrowdStrikeGetCaseDetailsResponse diff --git a/apps/sim/tools/crunchbase/types.ts b/apps/sim/tools/crunchbase/types.ts index 13f97dac917..0c9925ec7c4 100644 --- a/apps/sim/tools/crunchbase/types.ts +++ b/apps/sim/tools/crunchbase/types.ts @@ -118,8 +118,3 @@ export interface CrunchbaseAutocompleteResponse extends ToolResponse { entities: CrunchbaseAutocompleteEntity[] } } - -export type CrunchbaseResponse = - | CrunchbaseSearchResponse - | CrunchbaseEntityResponse - | CrunchbaseAutocompleteResponse diff --git a/apps/sim/tools/cursor/types.ts b/apps/sim/tools/cursor/types.ts index 31159e509bd..44ae5ff3aa6 100644 --- a/apps/sim/tools/cursor/types.ts +++ b/apps/sim/tools/cursor/types.ts @@ -222,18 +222,3 @@ export interface DownloadArtifactV2Response extends ToolResponse { file: UserFile } } - -export type CursorResponse = - | ListAgentsResponse - | GetAgentResponse - | GetConversationResponse - | LaunchAgentResponse - | AddFollowupResponse - | StopAgentResponse - | DeleteAgentResponse - | GetApiKeyInfoResponse - | ListModelsResponse - | ListRepositoriesResponse - | ListArtifactsResponse - | DownloadArtifactResponse - | DownloadArtifactV2Response diff --git a/apps/sim/tools/dagster/types.ts b/apps/sim/tools/dagster/types.ts index 1ed08af3186..2f0e347ec28 100644 --- a/apps/sim/tools/dagster/types.ts +++ b/apps/sim/tools/dagster/types.ts @@ -275,22 +275,3 @@ export interface DagsterWipeAssetResponse extends ToolResponse { assetKey: string } } - -export type DagsterResponse = - | DagsterLaunchRunResponse - | DagsterGetRunResponse - | DagsterListRunsResponse - | DagsterListJobsResponse - | DagsterTerminateRunResponse - | DagsterGetRunLogsResponse - | DagsterReexecuteRunResponse - | DagsterDeleteRunResponse - | DagsterListSchedulesResponse - | DagsterScheduleMutationResponse - | DagsterListSensorsResponse - | DagsterSensorMutationResponse - | DagsterListAssetsResponse - | DagsterGetAssetResponse - | DagsterMaterializeAssetsResponse - | DagsterReportAssetMaterializationResponse - | DagsterWipeAssetResponse diff --git a/apps/sim/tools/databricks/types.ts b/apps/sim/tools/databricks/types.ts index 83fea47fc35..56f53125582 100644 --- a/apps/sim/tools/databricks/types.ts +++ b/apps/sim/tools/databricks/types.ts @@ -651,28 +651,3 @@ export const GENIE_AGENT_ITEM_OUTPUT_PROPERTIES = { nullable: true, }, } as const satisfies Record - -/** Union type for all Databricks responses */ -export type DatabricksResponse = - | DatabricksExecuteSqlResponse - | DatabricksListJobsResponse - | DatabricksRunJobResponse - | DatabricksGetJobResponse - | DatabricksGetRunResponse - | DatabricksListRunsResponse - | DatabricksCancelRunResponse - | DatabricksGetRunOutputResponse - | DatabricksListClustersResponse - | DatabricksGetClusterResponse - | DatabricksListWarehousesResponse - | DatabricksGenieAskResponse - | DatabricksGenieGetMessageResponse - | DatabricksGenieListMessagesResponse - | DatabricksGenieQueryResultResponse - | DatabricksGenieDownloadVisualizationResponse - | DatabricksGenieListConversationsResponse - | DatabricksGenieSuccessResponse - | DatabricksGenieListSpacesResponse - | DatabricksGenieGetSpaceResponse - | DatabricksGenieAgentAskResponse - | DatabricksGenieAgentListItemsResponse diff --git a/apps/sim/tools/datadog/types.ts b/apps/sim/tools/datadog/types.ts index 97883919bd5..279594c2e5e 100644 --- a/apps/sim/tools/datadog/types.ts +++ b/apps/sim/tools/datadog/types.ts @@ -1163,46 +1163,3 @@ interface AddIncidentTodoOutput { export interface AddIncidentTodoResponse extends ToolResponse { output: AddIncidentTodoOutput } - -export type DatadogResponse = - | SubmitMetricsResponse - | QueryTimeseriesResponse - | CreateEventResponse - | CreateMonitorResponse - | GetMonitorResponse - | ListMonitorsResponse - | MuteMonitorResponse - | UnmuteMonitorResponse - | SendLogsResponse - | QueryLogsResponse - | CreateDowntimeResponse - | ListDowntimesResponse - | CancelDowntimeResponse - | ListSlosResponse - | GetSloResponse - | CreateSloResponse - | UpdateSloResponse - | DeleteSloResponse - | GetSloHistoryResponse - | ListDashboardsResponse - | GetDashboardResponse - | CreateDashboardResponse - | DeleteDashboardResponse - | ListSyntheticsTestsResponse - | GetSyntheticsTestResponse - | GetSyntheticsResultsResponse - | GetBrowserSyntheticsResultsResponse - | TriggerSyntheticsTestsResponse - | UpdateSyntheticsStatusResponse - | ListSecuritySignalsResponse - | GetSecuritySignalResponse - | UpdateSecuritySignalStateResponse - | UpdateSecuritySignalAssigneeResponse - | ListSecurityRulesResponse - | SearchSpansResponse - | ListServicesResponse - | ListIncidentsResponse - | GetIncidentResponse - | CreateIncidentResponse - | UpdateIncidentResponse - | AddIncidentTodoResponse diff --git a/apps/sim/tools/datagma/types.ts b/apps/sim/tools/datagma/types.ts index 33af052c1d8..9e6242115d3 100644 --- a/apps/sim/tools/datagma/types.ts +++ b/apps/sim/tools/datagma/types.ts @@ -130,10 +130,3 @@ export interface DatagmaGetCreditsResponse extends ToolResponse { } // Union of all response types - -export type DatagmaResponse = - | DatagmaFindEmailResponse - | DatagmaEnrichPersonResponse - | DatagmaEnrichCompanyResponse - | DatagmaFindPhoneResponse - | DatagmaGetCreditsResponse diff --git a/apps/sim/tools/discord/types.ts b/apps/sim/tools/discord/types.ts index cb968aa916b..4a446937e0e 100644 --- a/apps/sim/tools/discord/types.ts +++ b/apps/sim/tools/discord/types.ts @@ -528,44 +528,3 @@ export interface DiscordBulkDeleteMessagesResponse extends BaseDiscordResponse { message: string } } - -export type DiscordResponse = - | DiscordSendMessageResponse - | DiscordGetMessagesResponse - | DiscordGetServerResponse - | DiscordGetUserResponse - | DiscordEditMessageResponse - | DiscordDeleteMessageResponse - | DiscordAddReactionResponse - | DiscordRemoveReactionResponse - | DiscordPinMessageResponse - | DiscordUnpinMessageResponse - | DiscordCreateThreadResponse - | DiscordJoinThreadResponse - | DiscordLeaveThreadResponse - | DiscordArchiveThreadResponse - | DiscordCreateChannelResponse - | DiscordUpdateChannelResponse - | DiscordDeleteChannelResponse - | DiscordGetChannelResponse - | DiscordCreateRoleResponse - | DiscordUpdateRoleResponse - | DiscordDeleteRoleResponse - | DiscordAssignRoleResponse - | DiscordRemoveRoleResponse - | DiscordKickMemberResponse - | DiscordBanMemberResponse - | DiscordUnbanMemberResponse - | DiscordGetMemberResponse - | DiscordUpdateMemberResponse - | DiscordCreateInviteResponse - | DiscordGetInviteResponse - | DiscordDeleteInviteResponse - | DiscordCreateWebhookResponse - | DiscordExecuteWebhookResponse - | DiscordGetWebhookResponse - | DiscordDeleteWebhookResponse - | DiscordListChannelsResponse - | DiscordListRolesResponse - | DiscordGetPinnedMessagesResponse - | DiscordBulkDeleteMessagesResponse diff --git a/apps/sim/tools/docusign/types.ts b/apps/sim/tools/docusign/types.ts index 730d342faea..5eb11690e4e 100644 --- a/apps/sim/tools/docusign/types.ts +++ b/apps/sim/tools/docusign/types.ts @@ -237,13 +237,3 @@ export interface DocuSignListRecipientsResponse extends ToolResponse { }> } } - -export type DocuSignResponse = - | DocuSignSendEnvelopeResponse - | DocuSignCreateFromTemplateResponse - | DocuSignGetEnvelopeResponse - | DocuSignListEnvelopesResponse - | DocuSignVoidEnvelopeResponse - | DocuSignDownloadDocumentResponse - | DocuSignListTemplatesResponse - | DocuSignListRecipientsResponse diff --git a/apps/sim/tools/downdetector/types.ts b/apps/sim/tools/downdetector/types.ts index 9dce8a177dc..16c909a498c 100644 --- a/apps/sim/tools/downdetector/types.ts +++ b/apps/sim/tools/downdetector/types.ts @@ -300,19 +300,3 @@ export interface DowndetectorGetProviderResponse extends ToolResponse { provider: DowndetectorProvider } } - -export type DowndetectorResponse = - | DowndetectorSearchCompaniesResponse - | DowndetectorGetCompanyResponse - | DowndetectorGetCompanyStatusResponse - | DowndetectorGetCompanyBaselineResponse - | DowndetectorGetCompanyIndicatorsResponse - | DowndetectorGetReportsResponse - | DowndetectorIncidentsResponse - | DowndetectorListCategoriesResponse - | DowndetectorListSitesResponse - | DowndetectorGetCompanyLast15Response - | DowndetectorGetCompanyEventsResponse - | DowndetectorGetCompanyAttributionResponse - | DowndetectorGetSiteCompaniesResponse - | DowndetectorGetProviderResponse diff --git a/apps/sim/tools/dropbox/types.ts b/apps/sim/tools/dropbox/types.ts index 2955f472386..a104bde0b51 100644 --- a/apps/sim/tools/dropbox/types.ts +++ b/apps/sim/tools/dropbox/types.ts @@ -202,13 +202,6 @@ export interface DropboxSearchResponse extends ToolResponse { } } -interface DropboxGetTemporaryLinkResponse extends ToolResponse { - output: { - metadata?: DropboxFileMetadata - link?: string - } -} - export interface DropboxListSharedLinksParams extends DropboxBaseParams { path?: string directOnly?: boolean @@ -258,19 +251,3 @@ export interface DropboxRestoreResponse extends ToolResponse { metadata?: DropboxFileMetadata } } - -export type DropboxResponse = - | DropboxUploadResponse - | DropboxDownloadResponse - | DropboxListFolderResponse - | DropboxCreateFolderResponse - | DropboxDeleteResponse - | DropboxCopyResponse - | DropboxMoveResponse - | DropboxGetMetadataResponse - | DropboxCreateSharedLinkResponse - | DropboxSearchResponse - | DropboxGetTemporaryLinkResponse - | DropboxListSharedLinksResponse - | DropboxListRevisionsResponse - | DropboxRestoreResponse diff --git a/apps/sim/tools/dropcontact/types.ts b/apps/sim/tools/dropcontact/types.ts index be385cb9793..96e63ee501d 100644 --- a/apps/sim/tools/dropcontact/types.ts +++ b/apps/sim/tools/dropcontact/types.ts @@ -122,6 +122,3 @@ export interface DropcontactEnrichContactResponse extends ToolResponse { company_results: string | null } } - -/** Discriminated union of all Dropcontact tool responses */ -export type DropcontactResponse = DropcontactEnrichContactResponse diff --git a/apps/sim/tools/dub/types.ts b/apps/sim/tools/dub/types.ts index 9fea3443f39..224a2a5ca6d 100644 --- a/apps/sim/tools/dub/types.ts +++ b/apps/sim/tools/dub/types.ts @@ -338,22 +338,3 @@ export interface DubListFoldersResponse extends ToolResponse { count: number } } - -export type DubResponse = - | DubCreateLinkResponse - | DubGetLinkResponse - | DubUpdateLinkResponse - | DubUpsertLinkResponse - | DubDeleteLinkResponse - | DubListLinksResponse - | DubGetAnalyticsResponse - | DubGetLinksCountResponse - | DubGetEventsResponse - | DubBulkCreateLinksResponse - | DubBulkUpdateLinksResponse - | DubBulkDeleteLinksResponse - | DubGetQrCodeResponse - | DubListDomainsResponse - | DubListTagsResponse - | DubCreateTagResponse - | DubListFoldersResponse diff --git a/apps/sim/tools/duckduckgo/types.ts b/apps/sim/tools/duckduckgo/types.ts index a8a1c12c60e..3626cd5bb2f 100644 --- a/apps/sim/tools/duckduckgo/types.ts +++ b/apps/sim/tools/duckduckgo/types.ts @@ -51,5 +51,3 @@ interface DuckDuckGoSearchOutput { export interface DuckDuckGoSearchResponse extends ToolResponse { output: DuckDuckGoSearchOutput } - -export type DuckDuckGoResponse = DuckDuckGoSearchResponse diff --git a/apps/sim/tools/dynamodb/types.ts b/apps/sim/tools/dynamodb/types.ts index 0149fd5c165..47e470d3e94 100644 --- a/apps/sim/tools/dynamodb/types.ts +++ b/apps/sim/tools/dynamodb/types.ts @@ -75,8 +75,6 @@ export type DynamoDBQueryResponse = DynamoDBBaseResponse export type DynamoDBScanResponse = DynamoDBBaseResponse export type DynamoDBUpdateResponse = DynamoDBBaseResponse export type DynamoDBDeleteResponse = DynamoDBBaseResponse -export type DynamoDBResponse = DynamoDBBaseResponse - export interface DynamoDBIntrospectParams extends DynamoDBConnectionConfig { tableName?: string } diff --git a/apps/sim/tools/dynatrace/types.ts b/apps/sim/tools/dynatrace/types.ts index 45a85803707..9b4dba8817c 100644 --- a/apps/sim/tools/dynatrace/types.ts +++ b/apps/sim/tools/dynatrace/types.ts @@ -1020,51 +1020,3 @@ export interface DynatraceDeleteSloResponse extends ToolResponse { deleted: boolean } } - -/** Union of every Dynatrace tool response, used as the block's response type. */ -export type DynatraceResponse = - | DynatraceAddProblemCommentResponse - | DynatraceAddTagsResponse - | DynatraceCloseProblemResponse - | DynatraceCreateSettingsObjectResponse - | DynatraceCreateSloResponse - | DynatraceDeleteProblemCommentResponse - | DynatraceDeleteSettingsObjectResponse - | DynatraceDeleteSloResponse - | DynatraceDeleteTagResponse - | DynatraceExecuteSyntheticMonitorsResponse - | DynatraceGetAttackResponse - | DynatraceGetAuditLogsResponse - | DynatraceGetEntityResponse - | DynatraceGetEventResponse - | DynatraceGetMetricResponse - | DynatraceGetProblemCommentResponse - | DynatraceGetProblemResponse - | DynatraceGetSecurityProblemResponse - | DynatraceGetSettingsObjectResponse - | DynatraceGetSloResponse - | DynatraceGetSyntheticBatchResponse - | DynatraceIngestEventResponse - | DynatraceIngestLogsResponse - | DynatraceIngestMetricsResponse - | DynatraceListAttacksResponse - | DynatraceListEntitiesResponse - | DynatraceListEntityTypesResponse - | DynatraceListEventsResponse - | DynatraceListMetricsResponse - | DynatraceListProblemCommentsResponse - | DynatraceListProblemsResponse - | DynatraceListRemediationItemsResponse - | DynatraceListSecurityProblemsResponse - | DynatraceListSettingsObjectsResponse - | DynatraceListSettingsSchemasResponse - | DynatraceListSlosResponse - | DynatraceListSyntheticMonitorsResponse - | DynatraceListTagsResponse - | DynatraceMuteSecurityProblemResponse - | DynatraceMuteSecurityProblemsResponse - | DynatraceQueryMetricsResponse - | DynatraceSearchLogsResponse - | DynatraceUpdateProblemCommentResponse - | DynatraceUpdateSettingsObjectResponse - | DynatraceUpdateSloResponse diff --git a/apps/sim/tools/elasticsearch/types.ts b/apps/sim/tools/elasticsearch/types.ts index 741ce5457a5..ab6ca4c6123 100644 --- a/apps/sim/tools/elasticsearch/types.ts +++ b/apps/sim/tools/elasticsearch/types.ts @@ -192,16 +192,6 @@ export interface ElasticsearchIndexInfoResponse extends ToolResponse { } } -interface ElasticsearchIndexExistsResponse extends ToolResponse { - output: { - exists: boolean - } -} - -interface ElasticsearchMappingResponse extends ToolResponse { - output: Record }> -} - export interface ElasticsearchClusterHealthResponse extends ToolResponse { output: { cluster_name: string @@ -240,36 +230,6 @@ export interface ElasticsearchClusterStatsResponse extends ToolResponse { } } -interface ElasticsearchRefreshResponse extends ToolResponse { - output: { - _shards: { - total: number - successful: number - failed: number - } - } -} - -interface ElasticsearchIndexStatsResponse extends ToolResponse { - output: { - _all: { - primaries: { - docs: { count: number; deleted: number } - store: { size_in_bytes: number } - indexing: { index_total: number } - search: { query_total: number } - } - total: { - docs: { count: number; deleted: number } - store: { size_in_bytes: number } - indexing: { index_total: number } - search: { query_total: number } - } - } - indices: Record - } -} - export interface ElasticsearchListIndicesResponse extends ToolResponse { output: { message: string @@ -277,19 +237,3 @@ export interface ElasticsearchListIndicesResponse extends ToolResponse { } error?: string } - -// Union type for all Elasticsearch responses -export type ElasticsearchResponse = - | ElasticsearchDocumentResponse - | ElasticsearchSearchResponse - | ElasticsearchCountResponse - | ElasticsearchBulkResponse - | ElasticsearchIndexResponse - | ElasticsearchIndexInfoResponse - | ElasticsearchIndexExistsResponse - | ElasticsearchMappingResponse - | ElasticsearchClusterHealthResponse - | ElasticsearchClusterStatsResponse - | ElasticsearchRefreshResponse - | ElasticsearchIndexStatsResponse - | ElasticsearchListIndicesResponse diff --git a/apps/sim/tools/elevenlabs/types.ts b/apps/sim/tools/elevenlabs/types.ts index 7eb312c705f..f9d7d16842e 100644 --- a/apps/sim/tools/elevenlabs/types.ts +++ b/apps/sim/tools/elevenlabs/types.ts @@ -170,13 +170,3 @@ export interface ElevenLabsAudioResponse extends ToolResponse { audioFile?: UserFile } } - -export type ElevenLabsBlockResponse = - | ElevenLabsTtsResponse - | ElevenLabsListVoicesResponse - | ElevenLabsGetVoiceResponse - | ElevenLabsGetVoiceSettingsResponse - | ElevenLabsEditVoiceSettingsResponse - | ElevenLabsListModelsResponse - | ElevenLabsGetUserResponse - | ElevenLabsAudioResponse diff --git a/apps/sim/tools/emailbison/types.ts b/apps/sim/tools/emailbison/types.ts index de7a007f4d6..727a9bfeef1 100644 --- a/apps/sim/tools/emailbison/types.ts +++ b/apps/sim/tools/emailbison/types.ts @@ -242,13 +242,3 @@ export interface EmailBisonListTagsResponse extends ToolResponse { export interface EmailBisonTagResponse extends ToolResponse { output: EmailBisonTag } - -export type EmailBisonResponse = - | EmailBisonListLeadsResponse - | EmailBisonLeadResponse - | EmailBisonListCampaignsResponse - | EmailBisonCampaignResponse - | EmailBisonActionResponse - | EmailBisonListRepliesResponse - | EmailBisonListTagsResponse - | EmailBisonTagResponse diff --git a/apps/sim/tools/enrow/types.ts b/apps/sim/tools/enrow/types.ts index 522b2b1136c..ad8f620bde3 100644 --- a/apps/sim/tools/enrow/types.ts +++ b/apps/sim/tools/enrow/types.ts @@ -50,8 +50,6 @@ export interface EnrowVerifyEmailResponse extends ToolResponse { // Union response type (used in BlockConfig generic) -export type EnrowResponse = EnrowFindEmailResponse | EnrowVerifyEmailResponse - // Shared output property constants /** Reusable output-property definition for the Enrow job ID. */ diff --git a/apps/sim/tools/exa/types.ts b/apps/sim/tools/exa/types.ts index 7f7e79c4cd7..d5afb07181d 100644 --- a/apps/sim/tools/exa/types.ts +++ b/apps/sim/tools/exa/types.ts @@ -242,10 +242,3 @@ export interface ExaAgentResponse extends ToolResponse { __costDollars?: ExaCostDollars } } - -export type ExaResponse = - | ExaSearchResponse - | ExaGetContentsResponse - | ExaFindSimilarLinksResponse - | ExaAnswerResponse - | ExaAgentResponse diff --git a/apps/sim/tools/fathom/types.ts b/apps/sim/tools/fathom/types.ts index 5a550b9f277..c269fc8366d 100644 --- a/apps/sim/tools/fathom/types.ts +++ b/apps/sim/tools/fathom/types.ts @@ -147,11 +147,3 @@ export interface FathomListMeetingTypesResponse extends ToolResponse { next_cursor: string | null } } - -export type FathomResponse = - | FathomListMeetingsResponse - | FathomGetSummaryResponse - | FathomGetTranscriptResponse - | FathomListTeamMembersResponse - | FathomListTeamsResponse - | FathomListMeetingTypesResponse diff --git a/apps/sim/tools/findymail/types.ts b/apps/sim/tools/findymail/types.ts index 72ceab1c79a..1150c4cb340 100644 --- a/apps/sim/tools/findymail/types.ts +++ b/apps/sim/tools/findymail/types.ts @@ -226,16 +226,3 @@ export interface FindymailGetCreditsResponse extends ToolResponse { verifier_credits: number } } - -export type FindymailResponse = - | FindymailVerifyEmailResponse - | FindymailFindEmailFromNameResponse - | FindymailFindEmailsByDomainResponse - | FindymailFindEmailFromLinkedInResponse - | FindymailReverseEmailLookupResponse - | FindymailGetCompanyResponse - | FindymailFindEmployeesResponse - | FindymailFindPhoneResponse - | FindymailSearchTechnologiesResponse - | FindymailLookupTechnologiesResponse - | FindymailGetCreditsResponse diff --git a/apps/sim/tools/firecrawl/types.ts b/apps/sim/tools/firecrawl/types.ts index 283b8dfd786..cf2aad3d780 100644 --- a/apps/sim/tools/firecrawl/types.ts +++ b/apps/sim/tools/firecrawl/types.ts @@ -569,18 +569,3 @@ export interface FirecrawlCreditUsageResponse extends ToolResponse { billingPeriodEnd?: string | null } } - -export type FirecrawlResponse = - | ScrapeResponse - | SearchResponse - | FirecrawlCrawlResponse - | MapResponse - | ExtractResponse - | AgentResponse - | ParseResponse - | FirecrawlCrawlStatusResponse - | FirecrawlCancelCrawlResponse - | FirecrawlBatchScrapeResponse - | FirecrawlBatchScrapeStatusResponse - | FirecrawlExtractStatusResponse - | FirecrawlCreditUsageResponse diff --git a/apps/sim/tools/fireflies/types.ts b/apps/sim/tools/fireflies/types.ts index 147aa807260..5c53a272833 100644 --- a/apps/sim/tools/fireflies/types.ts +++ b/apps/sim/tools/fireflies/types.ts @@ -295,15 +295,3 @@ export interface FirefliesListContactsResponse extends ToolResponse { contacts?: FirefliesContact[] } } - -export type FirefliesResponse = - | FirefliesListTranscriptsResponse - | FirefliesGetTranscriptResponse - | FirefliesGetUserResponse - | FirefliesUploadAudioResponse - | FirefliesDeleteTranscriptResponse - | FirefliesAddToLiveMeetingResponse - | FirefliesListUsersResponse - | FirefliesCreateBiteResponse - | FirefliesListBitesResponse - | FirefliesListContactsResponse diff --git a/apps/sim/tools/gamma/types.ts b/apps/sim/tools/gamma/types.ts index d007d903a57..4dbeb129c85 100644 --- a/apps/sim/tools/gamma/types.ts +++ b/apps/sim/tools/gamma/types.ts @@ -154,10 +154,3 @@ export interface GammaListFoldersResponse extends ToolResponse { nextCursor: string | null } } - -export type GammaResponse = - | GammaGenerateResponse - | GammaGenerateFromTemplateResponse - | GammaCheckStatusResponse - | GammaListThemesResponse - | GammaListFoldersResponse diff --git a/apps/sim/tools/github/types.ts b/apps/sim/tools/github/types.ts index df90bbec62c..65d6a7a816e 100644 --- a/apps/sim/tools/github/types.ts +++ b/apps/sim/tools/github/types.ts @@ -1675,42 +1675,6 @@ export interface ReadmeResponse extends ToolResponse { } } -export type GitHubResponse = - | PullRequestResponse - | PullRequestV2Response - | PRReviewResponse - | TagsListResponse - | ReadmeResponse - | ReleaseResponse - | CreateCommentResponse - | LatestCommitResponse - | RepoInfoResponse - | IssueCommentResponse - | CommentsListResponse - | DeleteCommentResponse - | PRResponse - | MergeResultResponse - | PRListResponse - | PRFilesListResponse - | ReviewersResponse - | ListProjectsResponse - | ProjectResponse - | BranchResponse - | BranchListResponse - | BranchProtectionResponse - | RefResponse - | DeleteBranchResponse - | WorkflowResponse - | WorkflowRunResponse - | ListWorkflowsResponse - | ListWorkflowRunsResponse - | TriggerWorkflowResponse - | CancelWorkflowRunResponse - | RerunWorkflowResponse - | IssueResponse - | IssuesListResponse - | LabelsResponse - export interface CreateReleaseParams extends BaseGitHubParams { tag_name: string target_commitish?: string diff --git a/apps/sim/tools/gitlab/types.ts b/apps/sim/tools/gitlab/types.ts index 2e4f17f7ec4..69f4e77ef45 100644 --- a/apps/sim/tools/gitlab/types.ts +++ b/apps/sim/tools/gitlab/types.ts @@ -1182,61 +1182,3 @@ export interface GitLabDeleteUserIdentityResponse extends ToolResponse { success?: boolean } } - -export type GitLabResponse = - | GitLabListProjectsResponse - | GitLabGetProjectResponse - | GitLabListGroupsResponse - | GitLabGetGroupResponse - | GitLabListUserMembershipsResponse - | GitLabListIssuesResponse - | GitLabGetIssueResponse - | GitLabCreateIssueResponse - | GitLabUpdateIssueResponse - | GitLabDeleteIssueResponse - | GitLabListMergeRequestsResponse - | GitLabGetMergeRequestResponse - | GitLabCreateMergeRequestResponse - | GitLabUpdateMergeRequestResponse - | GitLabMergeMergeRequestResponse - | GitLabListPipelinesResponse - | GitLabGetPipelineResponse - | GitLabCreatePipelineResponse - | GitLabRetryPipelineResponse - | GitLabCancelPipelineResponse - | GitLabListBranchesResponse - | GitLabCreateBranchResponse - | GitLabDeleteBranchResponse - | GitLabCompareBranchesResponse - | GitLabCreateNoteResponse - | GitLabListReleasesResponse - | GitLabCreateReleaseResponse - | GitLabListRepositoryTreeResponse - | GitLabGetFileResponse - | GitLabCreateFileResponse - | GitLabUpdateFileResponse - | GitLabListCommitsResponse - | GitLabGetMergeRequestChangesResponse - | GitLabApproveMergeRequestResponse - | GitLabListPipelineJobsResponse - | GitLabGetJobLogResponse - | GitLabPlayJobResponse - | GitLabListMembersResponse - | GitLabAddMemberResponse - | GitLabUpdateMemberResponse - | GitLabRemoveMemberResponse - | GitLabInviteMemberResponse - | GitLabListInvitationsResponse - | GitLabUpdateInvitationResponse - | GitLabRevokeInvitationResponse - | GitLabListAccessRequestsResponse - | GitLabApproveAccessRequestResponse - | GitLabDenyAccessRequestResponse - | GitLabListSamlGroupLinksResponse - | GitLabSamlGroupLinkResponse - | GitLabDeleteSamlGroupLinkResponse - | GitLabSearchUsersResponse - | GitLabUserResponse - | GitLabDeleteUserResponse - | GitLabUserActionResponse - | GitLabDeleteUserIdentityResponse diff --git a/apps/sim/tools/gong/types.ts b/apps/sim/tools/gong/types.ts index 5895d0d7168..45d29605923 100644 --- a/apps/sim/tools/gong/types.ts +++ b/apps/sim/tools/gong/types.ts @@ -873,35 +873,3 @@ export interface GongGetLogsResponse extends ToolResponse { currentPageNumber: number | null } } - -/** Union type for all Gong responses */ -export type GongResponse = - | GongListCallsResponse - | GongCreateCallResponse - | GongGetCallResponse - | GongGetCallTranscriptResponse - | GongGetExtensiveCallsResponse - | GongListUsersResponse - | GongGetUserResponse - | GongAggregateActivityResponse - | GongDayByDayActivityResponse - | GongAggregateByPeriodResponse - | GongInteractionStatsResponse - | GongAnsweredScorecardsResponse - | GongListLibraryFoldersResponse - | GongGetFolderContentResponse - | GongListScorecardsResponse - | GongListTrackersResponse - | GongListWorkspacesResponse - | GongListFlowsResponse - | GongGetCoachingResponse - | GongLookupEmailResponse - | GongLookupPhoneResponse - | GongPurgeEmailAddressResponse - | GongPurgePhoneNumberResponse - | GongAssignFlowProspectsResponse - | GongGetProspectFlowsResponse - | GongAskAnythingResponse - | GongGetBriefResponse - | GongUnassignFlowProspectsResponse - | GongGetLogsResponse diff --git a/apps/sim/tools/google_appsheet/types.ts b/apps/sim/tools/google_appsheet/types.ts index fcb523dd527..ea35e05ffca 100644 --- a/apps/sim/tools/google_appsheet/types.ts +++ b/apps/sim/tools/google_appsheet/types.ts @@ -64,9 +64,3 @@ export interface GoogleAppsheetDeleteResponse extends ToolResponse { } } } - -export type GoogleAppsheetResponse = - | GoogleAppsheetFindResponse - | GoogleAppsheetAddResponse - | GoogleAppsheetEditResponse - | GoogleAppsheetDeleteResponse diff --git a/apps/sim/tools/google_calendar/types.ts b/apps/sim/tools/google_calendar/types.ts index 5d4302d6ae4..b0adef6fc71 100644 --- a/apps/sim/tools/google_calendar/types.ts +++ b/apps/sim/tools/google_calendar/types.ts @@ -369,43 +369,6 @@ export interface GoogleCalendarApiListResponse { items: GoogleCalendarApiEventResponse[] } -interface GoogleCalendarDeleteResponse extends ToolResponse { - output: { - content: string - metadata: { - eventId: string - deleted: boolean - } - } -} - -interface GoogleCalendarMoveResponse extends ToolResponse { - output: { - content: string - metadata: EventMetadata - } -} - -interface GoogleCalendarInstancesResponse extends ToolResponse { - output: { - content: string - metadata: { - nextPageToken?: string - timeZone: string - instances: Array< - EventMetadata & { - recurringEventId: string - originalStartTime: { - dateTime?: string - date?: string - timeZone?: string - } - } - > - } - } -} - export interface GoogleCalendarFreeBusyResponse extends ToolResponse { output: { content: string @@ -436,28 +399,6 @@ export interface GoogleCalendarApiFreeBusyResponse { > } -interface GoogleCalendarListCalendarsResponse extends ToolResponse { - output: { - content: string - metadata: { - nextPageToken?: string - calendars: Array<{ - id: string - summary: string - description?: string - location?: string - timeZone: string - accessRole: string - backgroundColor: string - foregroundColor: string - primary?: boolean - hidden?: boolean - selected?: boolean - }> - } - } -} - export interface GoogleCalendarCreateCalendarResponse extends ToolResponse { output: { content: string @@ -501,21 +442,3 @@ export interface GoogleCalendarUnshareCalendarResponse extends ToolResponse { } } } - -export type GoogleCalendarResponse = - | GoogleCalendarCreateResponse - | GoogleCalendarListResponse - | GoogleCalendarGetResponse - | GoogleCalendarQuickAddResponse - | GoogleCalendarInviteResponse - | GoogleCalendarRespondResponse - | GoogleCalendarUpdateResponse - | GoogleCalendarDeleteResponse - | GoogleCalendarMoveResponse - | GoogleCalendarInstancesResponse - | GoogleCalendarFreeBusyResponse - | GoogleCalendarListCalendarsResponse - | GoogleCalendarCreateCalendarResponse - | GoogleCalendarShareCalendarResponse - | GoogleCalendarListAclResponse - | GoogleCalendarUnshareCalendarResponse diff --git a/apps/sim/tools/google_contacts/types.ts b/apps/sim/tools/google_contacts/types.ts index fc4dfe75b5f..03240756fe5 100644 --- a/apps/sim/tools/google_contacts/types.ts +++ b/apps/sim/tools/google_contacts/types.ts @@ -132,14 +132,6 @@ export interface GoogleContactsSearchResponse extends ToolResponse { } } -export type GoogleContactsResponse = - | GoogleContactsCreateResponse - | GoogleContactsGetResponse - | GoogleContactsListResponse - | GoogleContactsUpdateResponse - | GoogleContactsDeleteResponse - | GoogleContactsSearchResponse - /** Transforms a raw Google People API person object into a ContactMetadata */ export function transformPerson(person: Record): ContactMetadata { return { diff --git a/apps/sim/tools/google_docs/types.ts b/apps/sim/tools/google_docs/types.ts index 112ad681dd6..e4f3558815f 100644 --- a/apps/sim/tools/google_docs/types.ts +++ b/apps/sim/tools/google_docs/types.ts @@ -145,20 +145,3 @@ export interface GoogleDocsToolParams { namedRangeId?: string namedRangeName?: string } - -export type GoogleDocsResponse = - | GoogleDocsReadResponse - | GoogleDocsWriteResponse - | GoogleDocsCreateResponse - | GoogleDocsInsertTextResponse - | GoogleDocsReplaceTextResponse - | GoogleDocsInsertTableResponse - | GoogleDocsInsertImageResponse - | GoogleDocsInsertPageBreakResponse - | GoogleDocsUpdateTextStyleResponse - | GoogleDocsDeleteContentRangeResponse - | GoogleDocsUpdateParagraphStyleResponse - | GoogleDocsCreateParagraphBulletsResponse - | GoogleDocsDeleteParagraphBulletsResponse - | GoogleDocsCreateNamedRangeResponse - | GoogleDocsDeleteNamedRangeResponse diff --git a/apps/sim/tools/google_drive/types.ts b/apps/sim/tools/google_drive/types.ts index 3a8304adea6..efd7b497e53 100644 --- a/apps/sim/tools/google_drive/types.ts +++ b/apps/sim/tools/google_drive/types.ts @@ -359,9 +359,3 @@ export interface GoogleDriveToolParams { exportMimeType?: string includeRevisions?: boolean } - -export type GoogleDriveResponse = - | GoogleDriveUploadResponse - | GoogleDriveGetContentResponse - | GoogleDriveDownloadResponse - | GoogleDriveListResponse diff --git a/apps/sim/tools/google_meet/types.ts b/apps/sim/tools/google_meet/types.ts index 4f7630c2614..bab3bf5b7d1 100644 --- a/apps/sim/tools/google_meet/types.ts +++ b/apps/sim/tools/google_meet/types.ts @@ -155,11 +155,3 @@ export interface GoogleMeetListParticipantsResponse extends ToolResponse { totalSize: number | null } } - -export type GoogleMeetResponse = - | GoogleMeetCreateSpaceResponse - | GoogleMeetGetSpaceResponse - | GoogleMeetEndConferenceResponse - | GoogleMeetListConferenceRecordsResponse - | GoogleMeetGetConferenceRecordResponse - | GoogleMeetListParticipantsResponse diff --git a/apps/sim/tools/google_sheets/types.ts b/apps/sim/tools/google_sheets/types.ts index 119a71e305d..5357c0c7e8c 100644 --- a/apps/sim/tools/google_sheets/types.ts +++ b/apps/sim/tools/google_sheets/types.ts @@ -1,6 +1,3 @@ -import type { GoogleSheetsV2DeleteRowsResponse } from '@/tools/google_sheets/delete_rows' -import type { GoogleSheetsV2DeleteSheetResponse } from '@/tools/google_sheets/delete_sheet' -import type { GoogleSheetsV2DeleteSpreadsheetResponse } from '@/tools/google_sheets/delete_spreadsheet' import type { SheetFilterMatchType } from '@/tools/google_sheets/filter' import type { ToolResponse } from '@/tools/types' @@ -74,12 +71,6 @@ export interface GoogleSheetsToolParams { majorDimension?: 'ROWS' | 'COLUMNS' } -export type GoogleSheetsResponse = - | GoogleSheetsReadResponse - | GoogleSheetsWriteResponse - | GoogleSheetsUpdateResponse - | GoogleSheetsAppendResponse - // V2 Types - with explicit sheetName parameter export interface GoogleSheetsFilterInfo { @@ -154,22 +145,6 @@ export interface GoogleSheetsV2ToolParams { filterMatchType?: SheetFilterMatchType } -export type GoogleSheetsV2Response = - | GoogleSheetsV2ReadResponse - | GoogleSheetsV2WriteResponse - | GoogleSheetsV2UpdateResponse - | GoogleSheetsV2AppendResponse - | GoogleSheetsV2ClearResponse - | GoogleSheetsV2GetSpreadsheetResponse - | GoogleSheetsV2CreateSpreadsheetResponse - | GoogleSheetsV2BatchGetResponse - | GoogleSheetsV2BatchUpdateResponse - | GoogleSheetsV2BatchClearResponse - | GoogleSheetsV2CopySheetResponse - | GoogleSheetsV2DeleteRowsResponse - | GoogleSheetsV2DeleteSheetResponse - | GoogleSheetsV2DeleteSpreadsheetResponse - // V2 Clear Types export interface GoogleSheetsV2ClearParams { accessToken: string diff --git a/apps/sim/tools/google_slides/types.ts b/apps/sim/tools/google_slides/types.ts index 6f26a7b36ec..371744d4b2c 100644 --- a/apps/sim/tools/google_slides/types.ts +++ b/apps/sim/tools/google_slides/types.ts @@ -43,8 +43,3 @@ export interface GoogleSlidesToolParams { folderId?: string folderSelector?: string } - -export type GoogleSlidesResponse = - | GoogleSlidesReadResponse - | GoogleSlidesWriteResponse - | GoogleSlidesCreateResponse diff --git a/apps/sim/tools/grafana/types.ts b/apps/sim/tools/grafana/types.ts index 1a09a27ec2b..3ac27ee43dd 100644 --- a/apps/sim/tools/grafana/types.ts +++ b/apps/sim/tools/grafana/types.ts @@ -193,17 +193,6 @@ export interface GrafanaUpdateDashboardParams extends GrafanaBaseParams { message?: string } -interface GrafanaUpdateDashboardResponse extends ToolResponse { - output: { - id: number - uid: string - url: string - status: string - version: number - slug: string - } -} - export interface GrafanaDeleteDashboardParams extends GrafanaBaseParams { dashboardUid: string } @@ -299,10 +288,6 @@ export interface GrafanaUpdateAlertRuleParams extends GrafanaBaseParams { disableProvenance?: boolean } -interface GrafanaUpdateAlertRuleResponse extends ToolResponse { - output: GrafanaAlertRule -} - export interface GrafanaDeleteAlertRuleParams extends GrafanaBaseParams { alertRuleUid: string } @@ -488,10 +473,6 @@ export interface GrafanaUpdateFolderParams extends GrafanaBaseParams { title?: string } -export interface GrafanaUpdateFolderResponse extends ToolResponse { - output: GrafanaFolder -} - export interface GrafanaDeleteFolderParams extends GrafanaBaseParams { folderUid: string forceDeleteRules?: boolean @@ -545,33 +526,6 @@ export interface GrafanaCreateContactPointResponse extends ToolResponse { } } -export type GrafanaResponse = - | GrafanaHealthCheckResponse - | GrafanaDataSourceHealthResponse - | GrafanaGetDashboardResponse - | GrafanaListDashboardsResponse - | GrafanaCreateDashboardResponse - | GrafanaUpdateDashboardResponse - | GrafanaDeleteDashboardResponse - | GrafanaListAlertRulesResponse - | GrafanaGetAlertRuleResponse - | GrafanaCreateAlertRuleResponse - | GrafanaUpdateAlertRuleResponse - | GrafanaDeleteAlertRuleResponse - | GrafanaCreateAnnotationResponse - | GrafanaListAnnotationsResponse - | GrafanaUpdateAnnotationResponse - | GrafanaDeleteAnnotationResponse - | GrafanaListDataSourcesResponse - | GrafanaGetDataSourceResponse - | GrafanaListFoldersResponse - | GrafanaCreateFolderResponse - | GrafanaGetFolderResponse - | GrafanaUpdateFolderResponse - | GrafanaDeleteFolderResponse - | GrafanaListContactPointsResponse - | GrafanaCreateContactPointResponse - export interface GrafanaUpdateContactPointParams extends GrafanaBaseParams { contactPointUid: string name: string diff --git a/apps/sim/tools/greenhouse/types.ts b/apps/sim/tools/greenhouse/types.ts index ef82d049e82..774d85cd828 100644 --- a/apps/sim/tools/greenhouse/types.ts +++ b/apps/sim/tools/greenhouse/types.ts @@ -392,19 +392,3 @@ interface GreenhouseOpening { application_id: number | null close_reason: { id: number; name: string } | null } - -/** - * Union type of all Greenhouse responses - */ -export type GreenhouseResponse = - | GreenhouseListCandidatesResponse - | GreenhouseGetCandidateResponse - | GreenhouseListJobsResponse - | GreenhouseGetJobResponse - | GreenhouseListApplicationsResponse - | GreenhouseGetApplicationResponse - | GreenhouseListUsersResponse - | GreenhouseGetUserResponse - | GreenhouseListDepartmentsResponse - | GreenhouseListOfficesResponse - | GreenhouseListJobStagesResponse diff --git a/apps/sim/tools/greptile/types.ts b/apps/sim/tools/greptile/types.ts index bc72161cef3..f1b84321b6d 100644 --- a/apps/sim/tools/greptile/types.ts +++ b/apps/sim/tools/greptile/types.ts @@ -109,12 +109,3 @@ export interface GreptileStatusResponse extends ToolResponse { sha?: string } } - -/** - * Union type for all Greptile responses - */ -export type GreptileResponse = - | GreptileQueryResponse - | GreptileSearchResponse - | GreptileIndexResponse - | GreptileStatusResponse diff --git a/apps/sim/tools/hex/types.ts b/apps/sim/tools/hex/types.ts index c8fc52b2295..49c3c3e666d 100644 --- a/apps/sim/tools/hex/types.ts +++ b/apps/sim/tools/hex/types.ts @@ -514,26 +514,3 @@ export interface HexDeactivateUserResponse extends ToolResponse { userId: string } } - -export type HexResponse = - | HexListProjectsResponse - | HexGetProjectResponse - | HexRunProjectResponse - | HexGetRunStatusResponse - | HexCancelRunResponse - | HexGetProjectRunsResponse - | HexUpdateProjectResponse - | HexListUsersResponse - | HexListCollectionsResponse - | HexListDataConnectionsResponse - | HexGetQueriedTablesResponse - | HexListGroupsResponse - | HexGetGroupResponse - | HexGetDataConnectionResponse - | HexGetCollectionResponse - | HexCreateCollectionResponse - | HexUpdateCollectionResponse - | HexCreateGroupResponse - | HexUpdateGroupResponse - | HexDeleteGroupResponse - | HexDeactivateUserResponse diff --git a/apps/sim/tools/hubspot/types.ts b/apps/sim/tools/hubspot/types.ts index 8a8cc502dda..9cfa26c70c6 100644 --- a/apps/sim/tools/hubspot/types.ts +++ b/apps/sim/tools/hubspot/types.ts @@ -1691,68 +1691,3 @@ export interface HubSpotSearchQuotesResponse extends ToolResponse { success: boolean } } - -// Generic HubSpot response type for the block -export type HubSpotResponse = - | HubSpotGetUsersResponse - | HubSpotListContactsResponse - | HubSpotGetContactResponse - | HubSpotCreateContactResponse - | HubSpotUpdateContactResponse - | HubSpotSearchContactsResponse - | HubSpotListCompaniesResponse - | HubSpotGetCompanyResponse - | HubSpotCreateCompanyResponse - | HubSpotUpdateCompanyResponse - | HubSpotSearchCompaniesResponse - | HubSpotListDealsResponse - | HubSpotGetDealResponse - | HubSpotCreateDealResponse - | HubSpotUpdateDealResponse - | HubSpotSearchDealsResponse - | HubSpotListTicketsResponse - | HubSpotGetTicketResponse - | HubSpotCreateTicketResponse - | HubSpotUpdateTicketResponse - | HubSpotSearchTicketsResponse - | HubSpotListLineItemsResponse - | HubSpotGetLineItemResponse - | HubSpotCreateLineItemResponse - | HubSpotUpdateLineItemResponse - | HubSpotListQuotesResponse - | HubSpotGetQuoteResponse - | HubSpotListAppointmentsResponse - | HubSpotGetAppointmentResponse - | HubSpotCreateAppointmentResponse - | HubSpotUpdateAppointmentResponse - | HubSpotListCartsResponse - | HubSpotGetCartResponse - | HubSpotListOwnersResponse - | HubSpotListMarketingEventsResponse - | HubSpotGetMarketingEventResponse - | HubSpotListListsResponse - | HubSpotGetListResponse - | HubSpotCreateListResponse - | HubSpotCreateNoteResponse - | HubSpotGetNoteResponse - | HubSpotListNotesResponse - | HubSpotSearchNotesResponse - | HubSpotCreateEmailResponse - | HubSpotGetEmailResponse - | HubSpotListEmailsResponse - | HubSpotSearchEmailsResponse - | HubSpotGetPropertiesResponse - | HubSpotListAssociationsResponse - | HubSpotCreateAssociationResponse - | HubSpotDeleteAssociationResponse - | HubSpotGetAssociationLabelsResponse - | HubSpotDeleteContactResponse - | HubSpotDeleteCompanyResponse - | HubSpotDeleteDealResponse - | HubSpotDeleteTicketResponse - | HubSpotDeleteLineItemResponse - | HubSpotAddListMembershipsResponse - | HubSpotRemoveListMembershipsResponse - | HubSpotGetListMembershipsResponse - | HubSpotSearchLineItemsResponse - | HubSpotSearchQuotesResponse diff --git a/apps/sim/tools/hunter/types.ts b/apps/sim/tools/hunter/types.ts index b77c1162f79..ad9b55ed4a2 100644 --- a/apps/sim/tools/hunter/types.ts +++ b/apps/sim/tools/hunter/types.ts @@ -403,11 +403,3 @@ export interface HunterEmailCountResponse extends ToolResponse { } } } - -export type HunterResponse = - | HunterDiscoverResponse - | HunterDomainSearchResponse - | HunterEmailFinderResponse - | HunterEmailVerifierResponse - | HunterEnrichmentResponse - | HunterEmailCountResponse diff --git a/apps/sim/tools/iam/types.ts b/apps/sim/tools/iam/types.ts index dc5f9c15f80..018a9e3ed52 100644 --- a/apps/sim/tools/iam/types.ts +++ b/apps/sim/tools/iam/types.ts @@ -121,11 +121,6 @@ export interface IAMRemoveUserFromGroupParams extends IAMConnectionConfig { groupName: string } -export interface IAMBaseResponse extends ToolResponse { - output: { message: string } - error?: string -} - export interface IAMListUsersResponse extends ToolResponse { output: { users: Array<{ diff --git a/apps/sim/tools/icypeas/types.ts b/apps/sim/tools/icypeas/types.ts index 6c89d43daf6..aab946e7559 100644 --- a/apps/sim/tools/icypeas/types.ts +++ b/apps/sim/tools/icypeas/types.ts @@ -51,8 +51,6 @@ export interface IcypeasVerifyEmailResponse extends ToolResponse { // Union response type used by the block -export type IcypeasResponse = IcypeasFindEmailResponse | IcypeasVerifyEmailResponse - // Shared output property constants export const ICYPEAS_SEARCH_ID_OUTPUT: OutputProperty = { diff --git a/apps/sim/tools/identity_center/types.ts b/apps/sim/tools/identity_center/types.ts index 4a851d0f3ca..4acfc92555c 100644 --- a/apps/sim/tools/identity_center/types.ts +++ b/apps/sim/tools/identity_center/types.ts @@ -99,11 +99,6 @@ export interface IdentityCenterDescribeAccountParams extends IdentityCenterConne accountId: string } -export interface IdentityCenterBaseResponse extends ToolResponse { - output: { message: string } - error?: string -} - export interface IdentityCenterListInstancesResponse extends ToolResponse { output: { instances: Array<{ diff --git a/apps/sim/tools/incidentio/types.ts b/apps/sim/tools/incidentio/types.ts index 87c6e4913d5..9f317ea8111 100644 --- a/apps/sim/tools/incidentio/types.ts +++ b/apps/sim/tools/incidentio/types.ts @@ -868,73 +868,6 @@ export interface IncidentioIncidentTypesListResponse extends ToolResponse { } } -export type IncidentioResponse = - | IncidentioIncidentsListResponse - | IncidentioIncidentsCreateResponse - | IncidentioIncidentsShowResponse - | IncidentioIncidentsUpdateResponse - | IncidentioActionsListResponse - | IncidentioActionsShowResponse - | IncidentioFollowUpsListResponse - | IncidentioFollowUpsShowResponse - | WorkflowsListResponse - | WorkflowsCreateResponse - | WorkflowsShowResponse - | WorkflowsUpdateResponse - | WorkflowsDeleteResponse - | CustomFieldsListResponse - | CustomFieldsCreateResponse - | CustomFieldsShowResponse - | CustomFieldsUpdateResponse - | CustomFieldsDeleteResponse - | IncidentioUsersListResponse - | IncidentioUsersShowResponse - | IncidentioSeveritiesListResponse - | IncidentioIncidentStatusesListResponse - | IncidentioIncidentTypesListResponse - | IncidentioEscalationsListResponse - | IncidentioEscalationsCreateResponse - | IncidentioEscalationsShowResponse - | IncidentioSchedulesListResponse - | IncidentioSchedulesCreateResponse - | IncidentioSchedulesShowResponse - | IncidentioSchedulesUpdateResponse - | IncidentioSchedulesDeleteResponse - | IncidentioIncidentRolesListResponse - | IncidentioIncidentRolesCreateResponse - | IncidentioIncidentRolesShowResponse - | IncidentioIncidentRolesUpdateResponse - | IncidentioIncidentRolesDeleteResponse - | IncidentioIncidentTimestampsListResponse - | IncidentioIncidentTimestampsShowResponse - | IncidentioIncidentUpdatesListResponse - | IncidentioScheduleEntriesListResponse - | IncidentioScheduleOverridesCreateResponse - | IncidentioEscalationPathsListResponse - | IncidentioEscalationPathsCreateResponse - | IncidentioEscalationPathsShowResponse - | IncidentioEscalationPathsUpdateResponse - | IncidentioEscalationPathsDeleteResponse - | IncidentioOnCallNowResponse - | IncidentioScheduleOverridesListResponse - | IncidentioAlertsListResponse - | IncidentioAlertsShowResponse - | IncidentioAlertsResolveResponse - | IncidentioAlertEventsCreateResponse - | IncidentioIncidentAlertsListResponse - | IncidentioEscalationsCancelResponse - | IncidentioCatalogTypesListResponse - | IncidentioCatalogEntriesListResponse - | IncidentioTeamsListResponse - | IncidentioTeamsShowResponse - | IncidentioFollowUpsCreateResponse - | IncidentioFollowUpsUpdateResponse - | IncidentioActionsCreateResponse - | IncidentioActionsUpdateResponse - | IncidentioIncidentParticipantsListResponse - | IncidentioIncidentMembershipsCreateResponse - | IncidentioIncidentMembershipsRevokeResponse - // Escalations types export interface IncidentioEscalationsListParams extends IncidentioBaseParams { page_size?: number diff --git a/apps/sim/tools/infisical/types.ts b/apps/sim/tools/infisical/types.ts index e1fe2d0fbc6..9c2c3655868 100644 --- a/apps/sim/tools/infisical/types.ts +++ b/apps/sim/tools/infisical/types.ts @@ -137,10 +137,3 @@ export interface InfisicalDeleteSecretResponse extends ToolResponse { secret: InfisicalSecret } } - -export type InfisicalResponse = - | InfisicalListSecretsResponse - | InfisicalGetSecretResponse - | InfisicalCreateSecretResponse - | InfisicalUpdateSecretResponse - | InfisicalDeleteSecretResponse diff --git a/apps/sim/tools/instagram/types.ts b/apps/sim/tools/instagram/types.ts index 6f4478289fc..78a53928436 100644 --- a/apps/sim/tools/instagram/types.ts +++ b/apps/sim/tools/instagram/types.ts @@ -360,25 +360,3 @@ export interface InstagramGetMediaInsightsResponse extends ToolResponse { }> } } - -export type InstagramResponse = - | InstagramGetProfileResponse - | InstagramListMediaResponse - | InstagramGetMediaResponse - | InstagramDownloadMediaResponse - | InstagramListStoriesResponse - | InstagramPublishResponse - | InstagramGetContainerStatusResponse - | InstagramGetPublishingLimitResponse - | InstagramListCommentsResponse - | InstagramReplyToCommentResponse - | InstagramHideCommentResponse - | InstagramDeleteCommentResponse - | InstagramSetCommentsEnabledResponse - | InstagramPrivateReplyResponse - | InstagramListConversationsResponse - | InstagramGetConversationMessagesResponse - | InstagramGetMessageResponse - | InstagramSendTextMessageResponse - | InstagramGetAccountInsightsResponse - | InstagramGetMediaInsightsResponse diff --git a/apps/sim/tools/instantly/types.ts b/apps/sim/tools/instantly/types.ts index 6b30bb67401..5ea23e2cfce 100644 --- a/apps/sim/tools/instantly/types.ts +++ b/apps/sim/tools/instantly/types.ts @@ -333,16 +333,3 @@ export interface InstantlyLeadListResponse extends ToolResponse { name: string | null } } - -export type InstantlyResponse = - | InstantlyListLeadsResponse - | InstantlyLeadResponse - | InstantlyDeleteLeadsResponse - | InstantlyUpdateLeadInterestStatusResponse - | InstantlyListCampaignsResponse - | InstantlyCampaignResponse - | InstantlyCampaignActionResponse - | InstantlyListEmailsResponse - | InstantlyEmailResponse - | InstantlyListLeadListsResponse - | InstantlyLeadListResponse diff --git a/apps/sim/tools/jira/types.ts b/apps/sim/tools/jira/types.ts index fab5e3bc910..c12faca736c 100644 --- a/apps/sim/tools/jira/types.ts +++ b/apps/sim/tools/jira/types.ts @@ -1614,35 +1614,3 @@ export interface JiraGetFieldsResponse extends ToolResponse { total: number } } - -export type JiraResponse = - | JiraRetrieveResponse - | JiraUpdateResponse - | JiraWriteResponse - | JiraRetrieveResponseBulk - | JiraDeleteIssueResponse - | JiraAssignIssueResponse - | JiraTransitionIssueResponse - | JiraSearchIssuesResponse - | JiraAddCommentResponse - | JiraGetCommentsResponse - | JiraUpdateCommentResponse - | JiraDeleteCommentResponse - | JiraGetAttachmentsResponse - | JiraAddAttachmentResponse - | JiraDeleteAttachmentResponse - | JiraAddWorklogResponse - | JiraGetWorklogsResponse - | JiraUpdateWorklogResponse - | JiraDeleteWorklogResponse - | JiraCreateIssueLinkResponse - | JiraDeleteIssueLinkResponse - | JiraAddWatcherResponse - | JiraRemoveWatcherResponse - | JiraGetUsersResponse - | JiraSearchUsersResponse - | JiraListProjectsResponse - | JiraGetProjectResponse - | JiraGetTransitionsResponse - | JiraListIssueTypesResponse - | JiraGetFieldsResponse diff --git a/apps/sim/tools/jsm/types.ts b/apps/sim/tools/jsm/types.ts index 104a2eb0ecb..2e984f45422 100644 --- a/apps/sim/tools/jsm/types.ts +++ b/apps/sim/tools/jsm/types.ts @@ -1037,52 +1037,6 @@ export interface JsmReopenFormResponse extends ToolResponse { } } -/** Union type for all JSM responses */ -export type JsmResponse = - | JsmGetServiceDesksResponse - | JsmGetRequestTypesResponse - | JsmCreateRequestResponse - | JsmGetRequestResponse - | JsmGetRequestsResponse - | JsmAddCommentResponse - | JsmGetCommentsResponse - | JsmGetCustomersResponse - | JsmAddCustomerResponse - | JsmGetOrganizationsResponse - | JsmGetQueuesResponse - | JsmGetSlaResponse - | JsmTransitionRequestResponse - | JsmGetTransitionsResponse - | JsmCreateOrganizationResponse - | JsmAddOrganizationResponse - | JsmGetParticipantsResponse - | JsmAddParticipantsResponse - | JsmGetApprovalsResponse - | JsmAnswerApprovalResponse - | JsmGetRequestTypeFieldsResponse - | JsmGetFormTemplatesResponse - | JsmGetFormStructureResponse - | JsmGetIssueFormsResponse - | JsmAttachFormResponse - | JsmSaveFormAnswersResponse - | JsmSubmitFormResponse - | JsmGetFormResponse - | JsmDeleteFormResponse - | JsmExternaliseFormResponse - | JsmInternaliseFormResponse - | JsmCopyFormsResponse - | JsmGetFormAnswersResponse - | JsmReopenFormResponse - | JsmListObjectSchemasResponse - | JsmGetObjectSchemaResponse - | JsmListObjectTypesResponse - | JsmGetObjectTypeAttributesResponse - | JsmSearchObjectsAqlResponse - | JsmGetObjectResponse - | JsmCreateObjectResponse - | JsmUpdateObjectResponse - | JsmDeleteObjectResponse - /** * JSM Assets (Insight / CMDB) tool types. * diff --git a/apps/sim/tools/ketch/types.ts b/apps/sim/tools/ketch/types.ts index 9f7aa2c2b06..e195e1b414d 100644 --- a/apps/sim/tools/ketch/types.ts +++ b/apps/sim/tools/ketch/types.ts @@ -108,10 +108,3 @@ export interface KetchSetSubscriptionsResponse extends ToolResponse { success: boolean } } - -export type KetchResponse = - | KetchGetConsentResponse - | KetchSetConsentResponse - | KetchInvokeRightResponse - | KetchGetSubscriptionsResponse - | KetchSetSubscriptionsResponse diff --git a/apps/sim/tools/lambda/types.ts b/apps/sim/tools/lambda/types.ts index 1bea6cbb048..24372263d7f 100644 --- a/apps/sim/tools/lambda/types.ts +++ b/apps/sim/tools/lambda/types.ts @@ -648,55 +648,3 @@ export interface LambdaPutRuntimeManagementConfigParams export interface LambdaPutRuntimeManagementConfigResponse extends ToolResponse { output: AwsLambdaPutRuntimeManagementConfigResponse['output'] } - -export type LambdaResponse = - | LambdaInvokeResponse - | LambdaListFunctionsResponse - | LambdaGetFunctionResponse - | LambdaGetFunctionConfigurationResponse - | LambdaCreateFunctionResponse - | LambdaUpdateFunctionCodeResponse - | LambdaUpdateFunctionConfigurationResponse - | LambdaDeleteFunctionResponse - | LambdaPublishVersionResponse - | LambdaListVersionsByFunctionResponse - | LambdaCreateAliasResponse - | LambdaGetAliasResponse - | LambdaUpdateAliasResponse - | LambdaDeleteAliasResponse - | LambdaListAliasesResponse - | LambdaAddPermissionResponse - | LambdaRemovePermissionResponse - | LambdaGetPolicyResponse - | LambdaCreateEventSourceMappingResponse - | LambdaGetEventSourceMappingResponse - | LambdaUpdateEventSourceMappingResponse - | LambdaDeleteEventSourceMappingResponse - | LambdaListEventSourceMappingsResponse - | LambdaGetFunctionConcurrencyResponse - | LambdaPutFunctionConcurrencyResponse - | LambdaDeleteFunctionConcurrencyResponse - | LambdaGetProvisionedConcurrencyConfigResponse - | LambdaPutProvisionedConcurrencyConfigResponse - | LambdaDeleteProvisionedConcurrencyConfigResponse - | LambdaListProvisionedConcurrencyConfigsResponse - | LambdaCreateFunctionUrlConfigResponse - | LambdaGetFunctionUrlConfigResponse - | LambdaUpdateFunctionUrlConfigResponse - | LambdaDeleteFunctionUrlConfigResponse - | LambdaListFunctionUrlConfigsResponse - | LambdaGetFunctionEventInvokeConfigResponse - | LambdaPutFunctionEventInvokeConfigResponse - | LambdaDeleteFunctionEventInvokeConfigResponse - | LambdaListFunctionEventInvokeConfigsResponse - | LambdaListLayersResponse - | LambdaListLayerVersionsResponse - | LambdaGetLayerVersionResponse - | LambdaListTagsResponse - | LambdaTagResourceResponse - | LambdaUntagResourceResponse - | LambdaGetAccountSettingsResponse - | LambdaGetFunctionRecursionConfigResponse - | LambdaPutFunctionRecursionConfigResponse - | LambdaGetRuntimeManagementConfigResponse - | LambdaPutRuntimeManagementConfigResponse diff --git a/apps/sim/tools/langsmith/types.ts b/apps/sim/tools/langsmith/types.ts index ff289163391..d6fd70d27ea 100644 --- a/apps/sim/tools/langsmith/types.ts +++ b/apps/sim/tools/langsmith/types.ts @@ -128,10 +128,3 @@ export interface LangsmithCreateFeedbackResponse extends ToolResponse { createdAt: string | null } } - -export type LangsmithResponse = - | LangsmithCreateRunResponse - | LangsmithCreateRunsBatchResponse - | LangsmithUpdateRunResponse - | LangsmithGetRunResponse - | LangsmithCreateFeedbackResponse diff --git a/apps/sim/tools/latex/types.ts b/apps/sim/tools/latex/types.ts index c9b536e2f6f..f84e6dc07b8 100644 --- a/apps/sim/tools/latex/types.ts +++ b/apps/sim/tools/latex/types.ts @@ -98,9 +98,3 @@ export interface LatexListFontsResponse extends ToolResponse { totalMatches: number } } - -export type LatexResponse = - | LatexCompileResponse - | LatexSearchPackagesResponse - | LatexGetPackageResponse - | LatexListFontsResponse diff --git a/apps/sim/tools/leadmagic/types.ts b/apps/sim/tools/leadmagic/types.ts index 90543fe91cd..4e63280bca1 100644 --- a/apps/sim/tools/leadmagic/types.ts +++ b/apps/sim/tools/leadmagic/types.ts @@ -198,14 +198,3 @@ export interface LeadMagicGetCreditsResponse extends ToolResponse { } // Union response type - -export type LeadMagicResponse = - | LeadMagicValidateEmailResponse - | LeadMagicFindEmailResponse - | LeadMagicFindMobileResponse - | LeadMagicProfileSearchResponse - | LeadMagicProfileToEmailResponse - | LeadMagicEmailToProfileResponse - | LeadMagicCompanySearchResponse - | LeadMagicRoleFinderResponse - | LeadMagicGetCreditsResponse diff --git a/apps/sim/tools/lemlist/types.ts b/apps/sim/tools/lemlist/types.ts index 7ee7beb610b..3f2360529fa 100644 --- a/apps/sim/tools/lemlist/types.ts +++ b/apps/sim/tools/lemlist/types.ts @@ -68,8 +68,3 @@ export interface LemlistSendEmailResponse extends ToolResponse { ok: boolean } } - -export type LemlistResponse = - | LemlistGetActivitiesResponse - | LemlistGetLeadResponse - | LemlistSendEmailResponse diff --git a/apps/sim/tools/linear/types.ts b/apps/sim/tools/linear/types.ts index eef623776ed..b941502ddce 100644 --- a/apps/sim/tools/linear/types.ts +++ b/apps/sim/tools/linear/types.ts @@ -1876,83 +1876,3 @@ export interface LinearDeleteProjectResponse extends ToolResponse { success?: boolean } } - -export type LinearResponse = - | LinearReadIssuesResponse - | LinearGetIssueResponse - | LinearCreateIssueResponse - | LinearUpdateIssueResponse - | LinearArchiveIssueResponse - | LinearUnarchiveIssueResponse - | LinearDeleteIssueResponse - | LinearAddLabelResponse - | LinearRemoveLabelResponse - | LinearSearchIssuesResponse - | LinearCreateCommentResponse - | LinearUpdateCommentResponse - | LinearDeleteCommentResponse - | LinearListCommentsResponse - | LinearListProjectsResponse - | LinearGetProjectResponse - | LinearCreateProjectResponse - | LinearUpdateProjectResponse - | LinearArchiveProjectResponse - | LinearListUsersResponse - | LinearListTeamsResponse - | LinearGetViewerResponse - | LinearListLabelsResponse - | LinearCreateLabelResponse - | LinearUpdateLabelResponse - | LinearArchiveLabelResponse - | LinearListWorkflowStatesResponse - | LinearCreateWorkflowStateResponse - | LinearUpdateWorkflowStateResponse - | LinearListCyclesResponse - | LinearGetCycleResponse - | LinearCreateCycleResponse - | LinearGetActiveCycleResponse - | LinearCreateAttachmentResponse - | LinearListAttachmentsResponse - | LinearUpdateAttachmentResponse - | LinearDeleteAttachmentResponse - | LinearCreateIssueRelationResponse - | LinearListIssueRelationsResponse - | LinearDeleteIssueRelationResponse - | LinearCreateFavoriteResponse - | LinearListFavoritesResponse - | LinearCreateProjectUpdateResponse - | LinearListProjectUpdatesResponse - | LinearListNotificationsResponse - | LinearUpdateNotificationResponse - | LinearCreateCustomerResponse - | LinearListCustomersResponse - | LinearGetCustomerResponse - | LinearUpdateCustomerResponse - | LinearDeleteCustomerResponse - | LinearMergeCustomersResponse - | LinearCreateCustomerRequestResponse - | LinearUpdateCustomerRequestResponse - | LinearListCustomerRequestsResponse - | LinearCreateCustomerStatusResponse - | LinearUpdateCustomerStatusResponse - | LinearDeleteCustomerStatusResponse - | LinearListCustomerStatusesResponse - | LinearCreateCustomerTierResponse - | LinearUpdateCustomerTierResponse - | LinearDeleteCustomerTierResponse - | LinearListCustomerTiersResponse - | LinearDeleteProjectResponse - | LinearCreateProjectLabelResponse - | LinearUpdateProjectLabelResponse - | LinearDeleteProjectLabelResponse - | LinearListProjectLabelsResponse - | LinearAddLabelToProjectResponse - | LinearRemoveLabelFromProjectResponse - | LinearCreateProjectMilestoneResponse - | LinearUpdateProjectMilestoneResponse - | LinearDeleteProjectMilestoneResponse - | LinearListProjectMilestonesResponse - | LinearCreateProjectStatusResponse - | LinearUpdateProjectStatusResponse - | LinearDeleteProjectStatusResponse - | LinearListProjectStatusesResponse diff --git a/apps/sim/tools/linkedin/types.ts b/apps/sim/tools/linkedin/types.ts index 7b0397b43cb..2cb6026da27 100644 --- a/apps/sim/tools/linkedin/types.ts +++ b/apps/sim/tools/linkedin/types.ts @@ -1,19 +1,5 @@ import type { ToolResponse } from '@/tools/types' -export type LinkedInResponse = { - success: boolean - output: { - postId?: string - profile?: { - id: string - name: string - email?: string - picture?: string - } - } - error?: string -} - // Tool-specific type definitions export interface LinkedInProfileOutput { profile?: { diff --git a/apps/sim/tools/logfire/types.ts b/apps/sim/tools/logfire/types.ts index 6010db1897d..e4fa96798b8 100644 --- a/apps/sim/tools/logfire/types.ts +++ b/apps/sim/tools/logfire/types.ts @@ -195,8 +195,3 @@ export interface LogfireGetTokenInfoResponse extends ToolResponse { spendingCapReachedAt: string | null } } - -export type LogfireResponse = - | LogfireQueryResponse - | LogfireRecordsResponse - | LogfireGetTokenInfoResponse diff --git a/apps/sim/tools/loops/types.ts b/apps/sim/tools/loops/types.ts index 79b0e3626b6..b80dad00961 100644 --- a/apps/sim/tools/loops/types.ts +++ b/apps/sim/tools/loops/types.ts @@ -218,21 +218,6 @@ export interface LoopsGetTransactionalEmailResponse extends ToolResponse { } } -export type LoopsResponse = - | LoopsCreateContactResponse - | LoopsUpdateContactResponse - | LoopsFindContactResponse - | LoopsDeleteContactResponse - | LoopsSendTransactionalEmailResponse - | LoopsSendEventResponse - | LoopsListMailingListsResponse - | LoopsListTransactionalEmailsResponse - | LoopsCreateContactPropertyResponse - | LoopsListContactPropertiesResponse - | LoopsCheckContactSuppressionResponse - | LoopsRemoveContactSuppressionResponse - | LoopsGetTransactionalEmailResponse - export const LOOPS_CONTACT_OUTPUT_PROPERTIES = { id: { type: 'string' as const, description: 'Loops-assigned contact ID' }, email: { type: 'string' as const, description: 'Contact email address' }, diff --git a/apps/sim/tools/microsoft_ad/types.ts b/apps/sim/tools/microsoft_ad/types.ts index 92d488f34cd..ccb5a986658 100644 --- a/apps/sim/tools/microsoft_ad/types.ts +++ b/apps/sim/tools/microsoft_ad/types.ts @@ -792,39 +792,3 @@ export interface MicrosoftAdRemoveGroupMemberResponse extends ToolResponse { memberId: string } } - -export type MicrosoftAdResponse = - | MicrosoftAdListUsersResponse - | MicrosoftAdGetUserResponse - | MicrosoftAdCreateUserResponse - | MicrosoftAdUpdateUserResponse - | MicrosoftAdDeleteUserResponse - | MicrosoftAdListGroupsResponse - | MicrosoftAdGetGroupResponse - | MicrosoftAdCreateGroupResponse - | MicrosoftAdUpdateGroupResponse - | MicrosoftAdDeleteGroupResponse - | MicrosoftAdListGroupMembersResponse - | MicrosoftAdAddGroupMemberResponse - | MicrosoftAdRemoveGroupMemberResponse - | MicrosoftAdAssignLicenseResponse - | MicrosoftAdListUserLicensesResponse - | MicrosoftAdListSubscribedSkusResponse - | MicrosoftAdRevokeSignInSessionsResponse - | MicrosoftAdSetPasswordResponse - | MicrosoftAdResetPasswordResponse - | MicrosoftAdListAuthenticationMethodsResponse - | MicrosoftAdListSignInsResponse - | MicrosoftAdListDirectoryAuditsResponse - | MicrosoftAdListAppRoleAssignmentsResponse - | MicrosoftAdAddUserAppRoleAssignmentResponse - | MicrosoftAdRemoveUserAppRoleAssignmentResponse - | MicrosoftAdListServicePrincipalsResponse - | MicrosoftAdListDirectoryRolesResponse - | MicrosoftAdListDirectoryRoleMembersResponse - | MicrosoftAdAddDirectoryRoleMemberResponse - | MicrosoftAdRemoveDirectoryRoleMemberResponse - | MicrosoftAdListDevicesResponse - | MicrosoftAdGetDeviceResponse - | MicrosoftAdListConditionalAccessPoliciesResponse - | MicrosoftAdGetConditionalAccessPolicyResponse diff --git a/apps/sim/tools/microsoft_dataverse/types.ts b/apps/sim/tools/microsoft_dataverse/types.ts index 9fbc642c0b5..8264962e614 100644 --- a/apps/sim/tools/microsoft_dataverse/types.ts +++ b/apps/sim/tools/microsoft_dataverse/types.ts @@ -382,23 +382,3 @@ export interface DataverseGetEntityMetadataResponse extends ToolResponse { success: boolean } } - -export type DataverseResponse = - | DataverseCreateRecordResponse - | DataverseGetRecordResponse - | DataverseUpdateRecordResponse - | DataverseDeleteRecordResponse - | DataverseListRecordsResponse - | DataverseUpsertRecordResponse - | DataverseWhoAmIResponse - | DataverseAssociateResponse - | DataverseDisassociateResponse - | DataverseFetchXmlQueryResponse - | DataverseExecuteActionResponse - | DataverseExecuteFunctionResponse - | DataverseCreateMultipleResponse - | DataverseUpdateMultipleResponse - | DataverseUploadFileResponse - | DataverseDownloadFileResponse - | DataverseSearchResponse - | DataverseGetEntityMetadataResponse diff --git a/apps/sim/tools/microsoft_excel/types.ts b/apps/sim/tools/microsoft_excel/types.ts index ed5a3123587..d8755074af6 100644 --- a/apps/sim/tools/microsoft_excel/types.ts +++ b/apps/sim/tools/microsoft_excel/types.ts @@ -182,17 +182,6 @@ export interface MicrosoftExcelSortRangeResponse extends ToolResponse { } } -export type MicrosoftExcelResponse = - | MicrosoftExcelReadResponse - | MicrosoftExcelWriteResponse - | MicrosoftExcelTableAddResponse - | MicrosoftExcelWorksheetAddResponse - | MicrosoftExcelClearRangeResponse - | MicrosoftExcelFormatRangeResponse - | MicrosoftExcelCreateTableResponse - | MicrosoftExcelDeleteWorksheetResponse - | MicrosoftExcelSortRangeResponse - // V2 Types - with separate sheetName param export interface MicrosoftExcelV2ToolParams { accessToken: string @@ -229,5 +218,3 @@ export interface MicrosoftExcelV2WriteResponse extends ToolResponse { } } } - -export type MicrosoftExcelV2Response = MicrosoftExcelV2ReadResponse | MicrosoftExcelV2WriteResponse diff --git a/apps/sim/tools/microsoft_planner/types.ts b/apps/sim/tools/microsoft_planner/types.ts index 6b30db41eea..0a3c034ae49 100644 --- a/apps/sim/tools/microsoft_planner/types.ts +++ b/apps/sim/tools/microsoft_planner/types.ts @@ -273,23 +273,3 @@ export interface MicrosoftPlannerToolParams { categoryDescriptions?: Record sharedWith?: Record } - -export type MicrosoftPlannerResponse = - | MicrosoftPlannerReadResponse - | MicrosoftPlannerCreateResponse - | MicrosoftPlannerUpdateTaskResponse - | MicrosoftPlannerDeleteTaskResponse - | MicrosoftPlannerListPlansResponse - | MicrosoftPlannerReadPlanResponse - | MicrosoftPlannerCreatePlanResponse - | MicrosoftPlannerDeletePlanResponse - | MicrosoftPlannerGetPlanDetailsResponse - | MicrosoftPlannerListBucketsResponse - | MicrosoftPlannerReadBucketResponse - | MicrosoftPlannerCreateBucketResponse - | MicrosoftPlannerUpdateBucketResponse - | MicrosoftPlannerDeleteBucketResponse - | MicrosoftPlannerGetTaskDetailsResponse - | MicrosoftPlannerUpdateTaskDetailsResponse - | MicrosoftPlannerUpdatePlanResponse - | MicrosoftPlannerUpdatePlanDetailsResponse diff --git a/apps/sim/tools/microsoft_teams/types.ts b/apps/sim/tools/microsoft_teams/types.ts index 33061ac92e0..21fb112fe3e 100644 --- a/apps/sim/tools/microsoft_teams/types.ts +++ b/apps/sim/tools/microsoft_teams/types.ts @@ -1,12 +1,6 @@ import type { UserFile } from '@/executor/types' import type { ToolFileData, ToolResponse } from '@/tools/types' -export interface GraphApiErrorResponse { - error?: { - message?: string - } -} - export interface GraphDriveItem { id: string webUrl?: string @@ -211,13 +205,3 @@ export interface MicrosoftTeamsReactionResponse extends ToolResponse { metadata: MicrosoftTeamsMetadata } } - -export type MicrosoftTeamsResponse = - | MicrosoftTeamsReadResponse - | MicrosoftTeamsWriteResponse - | MicrosoftTeamsDeleteResponse - | MicrosoftTeamsListMembersResponse - | MicrosoftTeamsReactionResponse - | MicrosoftTeamsListTeamsResponse - | MicrosoftTeamsListChatsResponse - | MicrosoftTeamsListChannelsResponse diff --git a/apps/sim/tools/microsoft_word/types.ts b/apps/sim/tools/microsoft_word/types.ts index bb703a5b52b..a6200ade77f 100644 --- a/apps/sim/tools/microsoft_word/types.ts +++ b/apps/sim/tools/microsoft_word/types.ts @@ -85,12 +85,3 @@ export interface MicrosoftWordExportPdfResponse extends ToolResponse { } } } - -export type MicrosoftWordResponse = - | MicrosoftWordCreateResponse - | MicrosoftWordReadResponse - | MicrosoftWordUpdateResponse - | MicrosoftWordListResponse - | MicrosoftWordCreateFromTemplateResponse - | MicrosoftWordReplaceTextResponse - | MicrosoftWordExportPdfResponse diff --git a/apps/sim/tools/millionverifier/types.ts b/apps/sim/tools/millionverifier/types.ts index 1e3dbda9c02..866c547384c 100644 --- a/apps/sim/tools/millionverifier/types.ts +++ b/apps/sim/tools/millionverifier/types.ts @@ -26,7 +26,3 @@ export interface MillionVerifierGetCreditsResponse extends ToolResponse { credits: number } } - -export type MillionVerifierResponse = - | MillionVerifierVerifyEmailResponse - | MillionVerifierGetCreditsResponse diff --git a/apps/sim/tools/mssql/types.ts b/apps/sim/tools/mssql/types.ts index ef597772a02..9443596fe5a 100644 --- a/apps/sim/tools/mssql/types.ts +++ b/apps/sim/tools/mssql/types.ts @@ -65,8 +65,6 @@ export interface MSSQLExecuteResponse extends MSSQLBaseResponse {} export interface MSSQLInsertResponse extends MSSQLBaseResponse {} export interface MSSQLUpdateResponse extends MSSQLBaseResponse {} export interface MSSQLDeleteResponse extends MSSQLBaseResponse {} -export interface MSSQLResponse extends MSSQLBaseResponse {} - interface MSSQLTableColumn { name: string type: string diff --git a/apps/sim/tools/neverbounce/types.ts b/apps/sim/tools/neverbounce/types.ts index a57caa6bd46..b0947bcf56b 100644 --- a/apps/sim/tools/neverbounce/types.ts +++ b/apps/sim/tools/neverbounce/types.ts @@ -27,5 +27,3 @@ export interface NeverBounceGetCreditsResponse extends ToolResponse { freeCredits: number } } - -export type NeverBounceResponse = NeverBounceVerifyEmailResponse | NeverBounceGetCreditsResponse diff --git a/apps/sim/tools/new_relic/types.ts b/apps/sim/tools/new_relic/types.ts index 2f6db073018..605801e4786 100644 --- a/apps/sim/tools/new_relic/types.ts +++ b/apps/sim/tools/new_relic/types.ts @@ -101,9 +101,3 @@ export interface NewRelicCreateDeploymentEventResponse extends ToolResponse { messages: string[] } } - -export type NewRelicResponse = - | NewRelicNrqlQueryResponse - | NewRelicSearchEntitiesResponse - | NewRelicGetEntityResponse - | NewRelicCreateDeploymentEventResponse diff --git a/apps/sim/tools/okta/types.ts b/apps/sim/tools/okta/types.ts index f572459936a..f5cc624120b 100644 --- a/apps/sim/tools/okta/types.ts +++ b/apps/sim/tools/okta/types.ts @@ -1096,49 +1096,3 @@ export interface OktaDeleteGroupRuleResponse extends ToolResponse { success: boolean } } - -export type OktaResponse = - | OktaListUsersResponse - | OktaGetUserResponse - | OktaCreateUserResponse - | OktaUpdateUserResponse - | OktaDeactivateUserResponse - | OktaSuspendUserResponse - | OktaUnsuspendUserResponse - | OktaActivateUserResponse - | OktaResetPasswordResponse - | OktaDeleteUserResponse - | OktaListGroupsResponse - | OktaGetGroupResponse - | OktaCreateGroupResponse - | OktaUpdateGroupResponse - | OktaDeleteGroupResponse - | OktaAddUserToGroupResponse - | OktaRemoveUserFromGroupResponse - | OktaListGroupMembersResponse - | OktaGetLogsResponse - | OktaClearUserSessionsResponse - | OktaGetSessionResponse - | OktaRevokeSessionResponse - | OktaListFactorsResponse - | OktaGetFactorResponse - | OktaResetFactorResponse - | OktaResetAllFactorsResponse - | OktaEnrollFactorResponse - | OktaListAppsResponse - | OktaGetAppResponse - | OktaListAppUsersResponse - | OktaAssignUserToAppResponse - | OktaRemoveUserFromAppResponse - | OktaListAppGroupsResponse - | OktaAssignGroupToAppResponse - | OktaRemoveGroupFromAppResponse - | OktaListUserRolesResponse - | OktaAssignUserRoleResponse - | OktaRemoveUserRoleResponse - | OktaListGroupRulesResponse - | OktaGetGroupRuleResponse - | OktaCreateGroupRuleResponse - | OktaActivateGroupRuleResponse - | OktaDeactivateGroupRuleResponse - | OktaDeleteGroupRuleResponse diff --git a/apps/sim/tools/onedrive/types.ts b/apps/sim/tools/onedrive/types.ts index dd3d3e4d464..b0f14c2b899 100644 --- a/apps/sim/tools/onedrive/types.ts +++ b/apps/sim/tools/onedrive/types.ts @@ -165,15 +165,3 @@ export interface OneDriveToolParams { linkType?: 'view' | 'edit' | 'embed' linkScope?: 'anonymous' | 'organization' | 'users' } - -export type OneDriveResponse = - | OneDriveUploadResponse - | OneDriveDownloadResponse - | OneDriveListResponse - | OneDriveDeleteResponse - | OneDriveSearchResponse - | OneDriveMoveResponse - | OneDriveCopyResponse - | OneDriveShareLinkResponse - | OneDriveGetItemResponse - | OneDriveGetDriveInfoResponse diff --git a/apps/sim/tools/openai/types.ts b/apps/sim/tools/openai/types.ts index e2386b9620b..0c701932560 100644 --- a/apps/sim/tools/openai/types.ts +++ b/apps/sim/tools/openai/types.ts @@ -1,5 +1,3 @@ -import type { ToolResponse } from '@/tools/types' - export interface BaseImageRequestBody { model: string prompt: string @@ -7,13 +5,3 @@ export interface BaseImageRequestBody { n: number [key: string]: unknown } - -export interface DalleResponse extends ToolResponse { - output: { - content: string // This will now be the image URL - image: string // This will be the base64 image data - metadata: { - model: string // Only contains model name now - } - } -} diff --git a/apps/sim/tools/outlook/types.ts b/apps/sim/tools/outlook/types.ts index e65afb86b52..b03ede4ae25 100644 --- a/apps/sim/tools/outlook/types.ts +++ b/apps/sim/tools/outlook/types.ts @@ -245,8 +245,6 @@ export interface CleanedOutlookMessage { importance?: string } -export type OutlookResponse = OutlookReadResponse | OutlookSendResponse | OutlookDraftResponse - export interface OutlookForwardParams { accessToken: string messageId: string @@ -324,15 +322,6 @@ export interface OutlookCopyResponse extends ToolResponse { } } -export type OutlookExtendedResponse = - | OutlookResponse - | OutlookForwardResponse - | OutlookMoveResponse - | OutlookMarkReadResponse - | OutlookDeleteResponse - | OutlookCopyResponse - | OutlookCalendarResponse - /** * Output definition for mail folder objects. * @see https://learn.microsoft.com/en-us/graph/api/resources/mailfolder @@ -813,11 +802,3 @@ export interface OutlookCalendarRespondResponse extends ToolResponse { } } } - -export type OutlookCalendarResponse = - | OutlookCalendarListEventsResponse - | OutlookCalendarGetEventResponse - | OutlookCalendarCreateEventResponse - | OutlookCalendarUpdateEventResponse - | OutlookCalendarDeleteEventResponse - | OutlookCalendarRespondResponse diff --git a/apps/sim/tools/persona/types.ts b/apps/sim/tools/persona/types.ts index 460c402ebae..6c917d04628 100644 --- a/apps/sim/tools/persona/types.ts +++ b/apps/sim/tools/persona/types.ts @@ -369,20 +369,3 @@ export interface PersonaDocumentResponse extends ToolResponse { document: PersonaDocument } } - -export type PersonaResponse = - | PersonaInquiryResponse - | PersonaListInquiriesResponse - | PersonaResumeInquiryResponse - | PersonaGenerateInquiryLinkResponse - | PersonaListReportsResponse - | PersonaListInquiryTemplatesResponse - | PersonaPrintInquiryPdfResponse - | PersonaAccountResponse - | PersonaListAccountsResponse - | PersonaImportAccountsResponse - | PersonaCaseResponse - | PersonaListCasesResponse - | PersonaReportResponse - | PersonaVerificationResponse - | PersonaDocumentResponse diff --git a/apps/sim/tools/pipedrive/types.ts b/apps/sim/tools/pipedrive/types.ts index fcfa944c5a6..ed4842643cb 100644 --- a/apps/sim/tools/pipedrive/types.ts +++ b/apps/sim/tools/pipedrive/types.ts @@ -665,24 +665,3 @@ interface PipedriveDeleteLeadOutput { export interface PipedriveDeleteLeadResponse extends ToolResponse { output: PipedriveDeleteLeadOutput } - -// Union type of all responses -export type PipedriveResponse = - | PipedriveGetAllDealsResponse - | PipedriveGetDealResponse - | PipedriveCreateDealResponse - | PipedriveUpdateDealResponse - | PipedriveGetFilesResponse - | PipedriveGetMailMessagesResponse - | PipedriveGetMailThreadResponse - | PipedriveGetPipelinesResponse - | PipedriveGetPipelineDealsResponse - | PipedriveGetProjectsResponse - | PipedriveCreateProjectResponse - | PipedriveGetActivitiesResponse - | PipedriveCreateActivityResponse - | PipedriveUpdateActivityResponse - | PipedriveGetLeadsResponse - | PipedriveCreateLeadResponse - | PipedriveUpdateLeadResponse - | PipedriveDeleteLeadResponse diff --git a/apps/sim/tools/postgresql/types.ts b/apps/sim/tools/postgresql/types.ts index bb0811e4473..12c359e793d 100644 --- a/apps/sim/tools/postgresql/types.ts +++ b/apps/sim/tools/postgresql/types.ts @@ -177,5 +177,3 @@ export interface PostgresIntrospectResponse extends ToolResponse { } error?: string } - -export interface PostgresResponse extends PostgresBaseResponse {} diff --git a/apps/sim/tools/prospeo/types.ts b/apps/sim/tools/prospeo/types.ts index c44ec03f83c..e6a6dc0c3fb 100644 --- a/apps/sim/tools/prospeo/types.ts +++ b/apps/sim/tools/prospeo/types.ts @@ -165,16 +165,6 @@ export interface ProspeoSearchSuggestionsResponse extends ToolResponse { } } -export type ProspeoResponse = - | ProspeoAccountInformationResponse - | ProspeoEnrichPersonResponse - | ProspeoEnrichCompanyResponse - | ProspeoBulkEnrichPersonResponse - | ProspeoBulkEnrichCompanyResponse - | ProspeoSearchPersonResponse - | ProspeoSearchCompanyResponse - | ProspeoSearchSuggestionsResponse - /** * Build a Prospeo API error message from a non-OK response payload. */ diff --git a/apps/sim/tools/quickbooks/types.ts b/apps/sim/tools/quickbooks/types.ts index 29a1faf7261..7c4f54ac43c 100644 --- a/apps/sim/tools/quickbooks/types.ts +++ b/apps/sim/tools/quickbooks/types.ts @@ -1281,27 +1281,6 @@ export interface QuickBooksVoidResponse extends ToolResponse { } } -export type QuickBooksResponse = - | QuickBooksCompanyInfoResponse - | QuickBooksListResponse - | QuickBooksReadMasterDataResponse - | QuickBooksReadSalesTransactionsResponse - | QuickBooksReadPurchasingTransactionsResponse - | QuickBooksReadAccountingTransactionsResponse - | QuickBooksRunFinancialReportResponse - | QuickBooksEmailTransactionResponse - | QuickBooksReadAttachmentsResponse - | QuickBooksAddAttachmentResponse - | QuickBooksFileResponse - | QuickBooksMutationResponse< - QuickBooksCustomer | QuickBooksEmployee | QuickBooksVendor | QuickBooksItem - > - | QuickBooksMutationResponse - | QuickBooksMutationResponse - | QuickBooksCreateBillResponse - | QuickBooksMutationResponse - | QuickBooksVoidResponse - export const QUICKBOOKS_REFERENCE_PROPERTIES: Record = { value: { type: 'string', description: 'QuickBooks entity ID', optional: true }, name: { type: 'string', description: 'QuickBooks entity display name', optional: true }, diff --git a/apps/sim/tools/rabbitmq/types.ts b/apps/sim/tools/rabbitmq/types.ts index 974851b47d3..b919ac90aca 100644 --- a/apps/sim/tools/rabbitmq/types.ts +++ b/apps/sim/tools/rabbitmq/types.ts @@ -518,30 +518,3 @@ export interface RabbitmqGetOverviewResponse extends ToolResponse { messageStats: Record } } - -export type RabbitmqResponse = - | RabbitmqPublishMessageResponse - | RabbitmqGetMessagesResponse - | RabbitmqListQueuesResponse - | RabbitmqGetQueueResponse - | RabbitmqCreateQueueResponse - | RabbitmqDeleteQueueResponse - | RabbitmqPurgeQueueResponse - | RabbitmqListExchangesResponse - | RabbitmqListBindingsResponse - | RabbitmqCreateBindingResponse - | RabbitmqGetOverviewResponse - | RabbitmqGetExchangeResponse - | RabbitmqCreateExchangeResponse - | RabbitmqDeleteExchangeResponse - | RabbitmqListExchangeBindingsResponse - | RabbitmqDeleteBindingResponse - | RabbitmqListVhostsResponse - | RabbitmqListConnectionsResponse - | RabbitmqListChannelsResponse - | RabbitmqListConsumersResponse - | RabbitmqListNodesResponse - | RabbitmqHealthCheckResponse - | RabbitmqListPoliciesResponse - | RabbitmqCreatePolicyResponse - | RabbitmqDeletePolicyResponse diff --git a/apps/sim/tools/railway/types.ts b/apps/sim/tools/railway/types.ts index 77c76fb6a72..150dc66a5f3 100644 --- a/apps/sim/tools/railway/types.ts +++ b/apps/sim/tools/railway/types.ts @@ -323,25 +323,3 @@ export interface RailwayUpsertVariableResponse extends ToolResponse { success: boolean } } - -export type RailwayResponse = - | RailwayListProjectsResponse - | RailwayGetProjectResponse - | RailwayCreateProjectResponse - | RailwayUpdateProjectResponse - | RailwayDeleteProjectResponse - | RailwayTransferProjectResponse - | RailwayListProjectMembersResponse - | RailwayCreateEnvironmentResponse - | RailwayDeleteEnvironmentResponse - | RailwayListDeploymentsResponse - | RailwayDeployServiceResponse - | RailwayCreateServiceResponse - | RailwayDeleteServiceResponse - | RailwayGetDeploymentResponse - | RailwayRestartDeploymentResponse - | RailwayRollbackDeploymentResponse - | RailwayGetDeploymentLogsResponse - | RailwayListVariablesResponse - | RailwayUpsertVariableResponse - | RailwayDeleteVariableResponse diff --git a/apps/sim/tools/rb2b/types.ts b/apps/sim/tools/rb2b/types.ts index 3dc39232965..a6f6f4ed706 100644 --- a/apps/sim/tools/rb2b/types.ts +++ b/apps/sim/tools/rb2b/types.ts @@ -307,19 +307,3 @@ export interface Rb2bLinkedinSlugSearchResponse extends ToolResponse { linkedin_url: string | null } } - -export type Rb2bResponse = - | Rb2bCreditCheckResponse - | Rb2bIpToHemResponse - | Rb2bIpToCompanyResponse - | Rb2bMaidResponse - | Rb2bLinkedinUrlResponse - | Rb2bLinkedinSlugResponse - | Rb2bBusinessProfileResponse - | Rb2bEmailActivityResponse - | Rb2bBestPersonalEmailResponse - | Rb2bPersonalEmailsResponse - | Rb2bHashedEmailsResponse - | Rb2bMobilePhoneResponse - | Rb2bLinkedinProfileResponse - | Rb2bLinkedinSlugSearchResponse diff --git a/apps/sim/tools/rds/types.ts b/apps/sim/tools/rds/types.ts index 077852e3186..bd5e300b1bd 100644 --- a/apps/sim/tools/rds/types.ts +++ b/apps/sim/tools/rds/types.ts @@ -52,8 +52,6 @@ export interface RdsInsertResponse extends RdsBaseResponse {} export interface RdsUpdateResponse extends RdsBaseResponse {} export interface RdsDeleteResponse extends RdsBaseResponse {} export interface RdsExecuteResponse extends RdsBaseResponse {} -export interface RdsResponse extends RdsBaseResponse {} - interface RdsTableColumn { name: string type: string diff --git a/apps/sim/tools/reddit/types.ts b/apps/sim/tools/reddit/types.ts index e4552c1be4a..7f242645011 100644 --- a/apps/sim/tools/reddit/types.ts +++ b/apps/sim/tools/reddit/types.ts @@ -439,12 +439,3 @@ export interface RedditSubredditInfoResponse extends ToolResponse { banner_img: string | null } } - -export type RedditResponse = - | RedditHotPostsResponse - | RedditPostsResponse - | RedditCommentsResponse - | RedditWriteResponse - | RedditUserResponse - | RedditMessagesResponse - | RedditSubredditInfoResponse diff --git a/apps/sim/tools/revenuecat/types.ts b/apps/sim/tools/revenuecat/types.ts index d3ceac6b99c..81ef0a889ee 100644 --- a/apps/sim/tools/revenuecat/types.ts +++ b/apps/sim/tools/revenuecat/types.ts @@ -419,15 +419,3 @@ export interface RevokeGoogleSubscriptionResponse extends ToolResponse { subscriber: RevenueCatSubscriber } } - -export type RevenueCatResponse = - | CustomerResponse - | DeleteCustomerResponse - | GrantEntitlementResponse - | RevokeEntitlementResponse - | ListOfferingsResponse - | CreatePurchaseResponse - | UpdateSubscriberAttributesResponse - | DeferGoogleSubscriptionResponse - | RefundGoogleSubscriptionResponse - | RevokeGoogleSubscriptionResponse diff --git a/apps/sim/tools/rootly/types.ts b/apps/sim/tools/rootly/types.ts index 42a403a9c51..62c5c5c8234 100644 --- a/apps/sim/tools/rootly/types.ts +++ b/apps/sim/tools/rootly/types.ts @@ -809,41 +809,3 @@ export interface RootlyListIncidentRolesResponse extends ToolResponse { totalCount: number } } - -/** Union of all responses */ -export type RootlyResponse = - | RootlyCreateIncidentResponse - | RootlyGetIncidentResponse - | RootlyUpdateIncidentResponse - | RootlyDeleteIncidentResponse - | RootlyListIncidentsResponse - | RootlyCreateAlertResponse - | RootlyGetAlertResponse - | RootlyUpdateAlertResponse - | RootlyAcknowledgeAlertResponse - | RootlyResolveAlertResponse - | RootlyListAlertsResponse - | RootlyAddIncidentEventResponse - | RootlyCreateActionItemResponse - | RootlyListActionItemsResponse - | RootlyListServicesResponse - | RootlyListSeveritiesResponse - | RootlyListRetrospectivesResponse - | RootlyListTeamsResponse - | RootlyListEnvironmentsResponse - | RootlyListIncidentTypesResponse - | RootlyListFunctionalitiesResponse - | RootlyListCausesResponse - | RootlyListPlaybooksResponse - | RootlyListUsersResponse - | RootlyListOnCallsResponse - | RootlyListSchedulesResponse - | RootlyListEscalationPoliciesResponse - | RootlyIncidentActionResponse - | RootlyAlertActionResponse - | RootlyCreateStatusPageEventResponse - | RootlyUpdateActionItemResponse - | RootlyDeleteActionItemResponse - | RootlyListIncidentEventsResponse - | RootlyRunWorkflowResponse - | RootlyListIncidentRolesResponse diff --git a/apps/sim/tools/sailpoint/types.ts b/apps/sim/tools/sailpoint/types.ts index 8f5539147a8..315f0a947d0 100644 --- a/apps/sim/tools/sailpoint/types.ts +++ b/apps/sim/tools/sailpoint/types.ts @@ -1,5 +1,3 @@ -import type { ToolResponse } from '@/tools/types' - export interface SailPointCredentials { clientId: string clientSecret: string @@ -27,20 +25,6 @@ export interface SailPointListOutput> { totalCount: number | null } -export interface SailPointListResponse> extends ToolResponse { - output: SailPointListOutput -} - -export interface SailPointResourceResponse< - T extends Record = Record, -> extends ToolResponse { - output: T -} - -export interface SailPointAcceptedResponse extends ToolResponse { - output: { accepted: boolean; status: number } -} - export interface SailPointListIdentitiesParams extends SailPointListParams { defaultFilter?: 'CORRELATED_ONLY' | 'NONE' } @@ -170,22 +154,6 @@ export interface SailPointSearchAggregateParams extends SailPointSearchBodyParams, SailPointPaginationParams {} -export interface SailPointSearchResponse extends ToolResponse { - output: { results: Record[]; count: number; totalCount: number | null } -} - -export interface SailPointSearchCountResponse extends ToolResponse { - output: { total: number } -} - -export interface SailPointSearchAggregateResponse extends ToolResponse { - output: { - aggregations: Record - hits: Record[] - totalCount: number | null - } -} - export type SailPointAccessRequestType = 'GRANT_ACCESS' | 'REVOKE_ACCESS' | 'MODIFY_ACCESS' export type SailPointRequestedItemType = 'ACCESS_PROFILE' | 'ROLE' | 'ENTITLEMENT' @@ -236,15 +204,6 @@ export interface SailPointAccessRequestTracking { accessRequestIds?: string[] } -export interface SailPointAccessRequestResponse extends ToolResponse { - output: { - accepted: boolean - status: number - newRequests: SailPointAccessRequestTracking[] - existingRequests: SailPointAccessRequestTracking[] - } -} - export interface SailPointCancelAccessRequestParams extends SailPointCredentials { accountActivityId: string comment: string @@ -288,18 +247,6 @@ export interface SailPointTask { returns?: Record[] } -export interface SailPointTaskResponse extends ToolResponse { - output: { task: SailPointTask } -} - -export interface SailPointLoadAccountsResponse extends ToolResponse { - output: { success: boolean; task: SailPointTask } -} - -export interface SailPointLoadEntitlementsResponse extends ToolResponse { - output: { task: SailPointTask } -} - export interface SailPointReviewRecommendation { recommendation?: string | null reasons?: string[] diff --git a/apps/sim/tools/salesforce/types.ts b/apps/sim/tools/salesforce/types.ts index 66efbe53d7e..2f1f063259f 100644 --- a/apps/sim/tools/salesforce/types.ts +++ b/apps/sim/tools/salesforce/types.ts @@ -1889,45 +1889,3 @@ export interface SalesforceToolingQueryResponse extends ToolResponse { success: boolean } } - -export type SalesforceResponse = - | SalesforceGetAccountsResponse - | SalesforceCreateAccountResponse - | SalesforceUpdateAccountResponse - | SalesforceDeleteAccountResponse - | SalesforceGetContactsResponse - | SalesforceCreateContactResponse - | SalesforceUpdateContactResponse - | SalesforceDeleteContactResponse - | SalesforceGetLeadsResponse - | SalesforceCreateLeadResponse - | SalesforceUpdateLeadResponse - | SalesforceDeleteLeadResponse - | SalesforceGetOpportunitiesResponse - | SalesforceCreateOpportunityResponse - | SalesforceUpdateOpportunityResponse - | SalesforceDeleteOpportunityResponse - | SalesforceGetCasesResponse - | SalesforceCreateCaseResponse - | SalesforceUpdateCaseResponse - | SalesforceDeleteCaseResponse - | SalesforceGetTasksResponse - | SalesforceCreateTaskResponse - | SalesforceUpdateTaskResponse - | SalesforceDeleteTaskResponse - | SalesforceListReportsResponse - | SalesforceGetReportResponse - | SalesforceRunReportResponse - | SalesforceListReportTypesResponse - | SalesforceListDashboardsResponse - | SalesforceGetDashboardResponse - | SalesforceRefreshDashboardResponse - | SalesforceQueryResponse - | SalesforceQueryMoreResponse - | SalesforceDescribeObjectResponse - | SalesforceListObjectsResponse - | SalesforceCreateCustomFieldResponse - | SalesforceUpdateCustomFieldResponse - | SalesforceDeleteCustomFieldResponse - | SalesforceCreateCustomObjectResponse - | SalesforceToolingQueryResponse diff --git a/apps/sim/tools/secrets_manager/types.ts b/apps/sim/tools/secrets_manager/types.ts index 9b3475dfa7a..2ed4ae281da 100644 --- a/apps/sim/tools/secrets_manager/types.ts +++ b/apps/sim/tools/secrets_manager/types.ts @@ -35,11 +35,6 @@ export interface SecretsManagerDeleteSecretParams extends SecretsManagerConnecti forceDelete?: boolean | null } -export interface SecretsManagerBaseResponse extends ToolResponse { - output: { message: string } - error?: string -} - export interface SecretsManagerGetSecretResponse extends ToolResponse { output: { name: string diff --git a/apps/sim/tools/semrush/types.ts b/apps/sim/tools/semrush/types.ts index b486b9801b2..a1359b0ce24 100644 --- a/apps/sim/tools/semrush/types.ts +++ b/apps/sim/tools/semrush/types.ts @@ -1182,49 +1182,3 @@ export interface SemrushDomainVsDomainResponse extends ToolResponse { keywords: SemrushDomainVsDomainRow[] } } - -export type SemrushResponse = - | SemrushDomainOverviewResponse - | SemrushDomainOverviewAllResponse - | SemrushDomainOverviewHistoryResponse - | SemrushWinnersAndLosersResponse - | SemrushTopDomainsResponse - | SemrushDomainOrganicKeywordsResponse - | SemrushDomainPaidKeywordsResponse - | SemrushDomainAdCopiesResponse - | SemrushDomainAdHistoryResponse - | SemrushDomainOrganicCompetitorsResponse - | SemrushDomainPaidCompetitorsResponse - | SemrushDomainPlaKeywordsResponse - | SemrushDomainPlaCopiesResponse - | SemrushSubdomainOverviewResponse - | SemrushSubdomainOverviewAllResponse - | SemrushSubdomainOverviewHistoryResponse - | SemrushSubdomainOrganicKeywordsResponse - | SemrushSubdomainPaidKeywordsResponse - | SemrushSubdomainAdCopiesResponse - | SemrushUrlOverviewResponse - | SemrushUrlOverviewAllResponse - | SemrushUrlOverviewHistoryResponse - | SemrushUrlOrganicKeywordsResponse - | SemrushUrlPaidKeywordsResponse - | SemrushKeywordOverviewResponse - | SemrushKeywordOverviewAllResponse - | SemrushBatchKeywordOverviewResponse - | SemrushKeywordDifficultyResponse - | SemrushRelatedKeywordsResponse - | SemrushBroadMatchKeywordsResponse - | SemrushKeywordQuestionsResponse - | SemrushOrganicResultsResponse - | SemrushPaidResultsResponse - | SemrushKeywordAdHistoryResponse - | SemrushBacklinksOverviewResponse - | SemrushBacklinksResponse - | SemrushReferringDomainsResponse - | SemrushReferringIpsResponse - | SemrushBacklinksTldDistributionResponse - | SemrushBacklinksGeoDistributionResponse - | SemrushBacklinksAnchorsResponse - | SemrushBacklinksIndexedPagesResponse - | SemrushBacklinksCompetitorsResponse - | SemrushDomainVsDomainResponse diff --git a/apps/sim/tools/sentry/types.ts b/apps/sim/tools/sentry/types.ts index 7ecfc217c5a..50f2b57cce2 100644 --- a/apps/sim/tools/sentry/types.ts +++ b/apps/sim/tools/sentry/types.ts @@ -424,21 +424,3 @@ export interface SentryCreateDeployResponse extends ToolResponse { } } } - -/** - * Union response type for all Sentry operations - */ -export type SentryResponse = - | SentryListTeamsResponse - | SentryListIssuesResponse - | SentryGetIssueResponse - | SentryUpdateIssueResponse - | SentryListProjectsResponse - | SentryGetProjectResponse - | SentryCreateProjectResponse - | SentryUpdateProjectResponse - | SentryListEventsResponse - | SentryGetEventResponse - | SentryListReleasesResponse - | SentryCreateReleaseResponse - | SentryCreateDeployResponse diff --git a/apps/sim/tools/servicenow/types.ts b/apps/sim/tools/servicenow/types.ts index ef2a04ec622..272756b96f2 100644 --- a/apps/sim/tools/servicenow/types.ts +++ b/apps/sim/tools/servicenow/types.ts @@ -580,22 +580,3 @@ export interface ServiceNowUploadAttachmentResponse extends ToolResponse { } } } - -export type ServiceNowResponse = - | ServiceNowCreateResponse - | ServiceNowReadResponse - | ServiceNowUpdateResponse - | ServiceNowDeleteResponse - | ServiceNowAggregateResponse - | ServiceNowListAttachmentsResponse - | ServiceNowDownloadAttachmentResponse - | ServiceNowUploadAttachmentResponse - | ServiceNowRecordListResponse - | ServiceNowSingleRecordResponse - | ServiceNowChangeTaskListResponse - | ServiceNowGetChangeNextStatesResponse - | ServiceNowListCatalogItemsResponse - | ServiceNowOrderCatalogItemResponse - | ServiceNowGetCiResponse - | ServiceNowSearchKnowledgeResponse - | ServiceNowGetKnowledgeArticleResponse diff --git a/apps/sim/tools/sharepoint/types.ts b/apps/sim/tools/sharepoint/types.ts index 7449c2ef473..47b8dd90bbb 100644 --- a/apps/sim/tools/sharepoint/types.ts +++ b/apps/sim/tools/sharepoint/types.ts @@ -65,13 +65,6 @@ export interface SharepointList { items?: SharepointListItem[] } -interface SharepointListSitesResponse extends ToolResponse { - output: { - sites: SharepointSite[] - nextPageUrl?: string - } -} - export interface SharepointCreatePageResponse extends ToolResponse { output: { page: SharepointPage @@ -206,25 +199,6 @@ export interface CanvasLayout { }> } -export type SharepointResponse = - | SharepointListSitesResponse - | SharepointCreatePageResponse - | SharepointReadPageResponse - | SharepointReadSiteResponse - | SharepointGetListResponse - | SharepointCreateListResponse - | SharepointUpdateListItemResponse - | SharepointAddListItemResponse - | SharepointUploadFileResponse - | SharepointDeleteListItemResponse - | SharepointGetListItemResponse - | SharepointDeletePageResponse - | SharepointUpdatePageResponse - | SharepointPublishPageResponse - | SharepointDownloadFileResponse - | SharepointDeleteFileResponse - | SharepointGetDriveItemResponse - export interface SharepointGetListResponse extends ToolResponse { output: { list?: SharepointList diff --git a/apps/sim/tools/slack/types.ts b/apps/sim/tools/slack/types.ts index 172c8b72441..bebc1159c26 100644 --- a/apps/sim/tools/slack/types.ts +++ b/apps/sim/tools/slack/types.ts @@ -1529,50 +1529,3 @@ export interface SlackSetConversationPurposeResponse extends ToolResponse { purpose: string } } - -export type SlackResponse = - | SlackCanvasResponse - | SlackMessageReaderResponse - | SlackMessageResponse - | SlackDownloadResponse - | SlackUpdateMessageResponse - | SlackDeleteMessageResponse - | SlackAddReactionResponse - | SlackRemoveReactionResponse - | SlackListChannelsResponse - | SlackListMembersResponse - | SlackListUsersResponse - | SlackGetUserResponse - | SlackEphemeralMessageResponse - | SlackGetMessageResponse - | SlackGetThreadResponse - | SlackSetStatusResponse - | SlackSetTitleResponse - | SlackSetSuggestedPromptsResponse - | SlackSetAgentSessionStatusV2Response - | SlackRenameAgentSessionV2Response - | SlackSetSuggestedPromptsV2Response - | SlackGetPermalinkResponse - | SlackGetChannelHistoryResponse - | SlackGetThreadRepliesResponse - | SlackGetChannelInfoResponse - | SlackGetUserPresenceResponse - | SlackEditCanvasResponse - | SlackCreateChannelCanvasResponse - | SlackGetCanvasResponse - | SlackListCanvasesResponse - | SlackLookupCanvasSectionsResponse - | SlackDeleteCanvasResponse - | SlackCreateConversationResponse - | SlackInviteToConversationResponse - | SlackOpenViewResponse - | SlackUpdateViewResponse - | SlackPushViewResponse - | SlackPublishViewResponse - | SlackScheduleMessageResponse - | SlackListScheduledMessagesResponse - | SlackDeleteScheduledMessageResponse - | SlackArchiveConversationResponse - | SlackRenameConversationResponse - | SlackSetConversationTopicResponse - | SlackSetConversationPurposeResponse diff --git a/apps/sim/tools/smartlead/types.ts b/apps/sim/tools/smartlead/types.ts index af2253c2333..05ea324bca3 100644 --- a/apps/sim/tools/smartlead/types.ts +++ b/apps/sim/tools/smartlead/types.ts @@ -441,32 +441,3 @@ export interface SmartleadLeadListsResponse extends ToolResponse { export interface SmartleadLeadListResponse extends ToolResponse { output: SmartleadLeadList } - -export type SmartleadResponse = - | SmartleadListCampaignsResponse - | SmartleadCampaignResponse - | SmartleadCreateCampaignResponse - | SmartleadActionResponse - | SmartleadCampaignAnalyticsResponse - | SmartleadCampaignAnalyticsByDateResponse - | SmartleadSequencesResponse - | SmartleadSaveSequencesResponse - | SmartleadCampaignStatisticsResponse - | SmartleadAddLeadsResponse - | SmartleadListCampaignLeadsResponse - | SmartleadLeadDetailResponse - | SmartleadLeadCategoriesResponse - | SmartleadMessageHistoryResponse - | SmartleadListWebhooksResponse - | SmartleadUpsertWebhookResponse - | SmartleadDuplicateCampaignResponse - | SmartleadExportLeadsResponse - | SmartleadOpaqueListResponse - | SmartleadPaginatedRowsResponse - | SmartleadTopLevelAnalyticsResponse - | SmartleadLeadByIdResponse - | SmartleadMarkCompleteResponse - | SmartleadWebhookSummaryResponse - | SmartleadLeadListsResponse - | SmartleadLeadListResponse - | SmartleadEmailAccountsResponse diff --git a/apps/sim/tools/splunk/types.ts b/apps/sim/tools/splunk/types.ts index db2af99ce7d..bce070df963 100644 --- a/apps/sim/tools/splunk/types.ts +++ b/apps/sim/tools/splunk/types.ts @@ -275,20 +275,6 @@ export interface SplunkListAppsResponse extends ToolResponse { } } -/** Union of every Splunk tool response, used by the block's generic output typing. */ -export type SplunkResponse = - | SplunkSearchResultsResponse - | SplunkCreateSearchJobResponse - | SplunkGetSearchJobResponse - | SplunkCancelSearchJobResponse - | SplunkListSavedSearchesResponse - | SplunkGetSavedSearchResponse - | SplunkDispatchSavedSearchResponse - | SplunkListFiredAlertsResponse - | SplunkGetFiredAlertsResponse - | SplunkListIndexesResponse - | SplunkListAppsResponse - /** Output schema shared by the two tools that project a saved search. */ export const SAVED_SEARCH_OUTPUT_FIELDS: Record = { name: { type: 'string', description: 'Saved search name' }, diff --git a/apps/sim/tools/sqs/types.ts b/apps/sim/tools/sqs/types.ts index de15df306f7..4c9bc60d1bc 100644 --- a/apps/sim/tools/sqs/types.ts +++ b/apps/sim/tools/sqs/types.ts @@ -151,11 +151,6 @@ export interface SqsCancelMessageMoveTaskParams extends SqsConnectionConfig { taskHandle: string } -interface SqsBaseResponse extends ToolResponse { - output: { message: string; id?: string } - error?: string -} - export interface SqsSendMessageResponse extends ToolResponse { output: { message: string @@ -272,5 +267,3 @@ export interface SqsCancelMessageMoveTaskResponse extends ToolResponse { output: { message: string; approximateNumberOfMessagesMoved: number | null } error?: string } - -export interface SqsResponse extends SqsBaseResponse {} diff --git a/apps/sim/tools/square/types.ts b/apps/sim/tools/square/types.ts index ff230d76766..a86e8081c7f 100644 --- a/apps/sim/tools/square/types.ts +++ b/apps/sim/tools/square/types.ts @@ -1055,23 +1055,3 @@ export interface InventoryCountListResponse extends ToolResponse { metadata: SquareListMetadata } } - -export type SquareResponse = - | PaymentResponse - | PaymentListResponse - | RefundResponse - | RefundListResponse - | CustomerResponse - | CustomerListResponse - | CustomerDeleteResponse - | LocationListResponse - | LocationResponse - | OrderResponse - | OrderListResponse - | InvoiceResponse - | InvoiceListResponse - | InvoiceDeleteResponse - | CatalogObjectResponse - | CatalogListResponse - | CatalogDeleteResponse - | InventoryCountListResponse diff --git a/apps/sim/tools/stripe/types.ts b/apps/sim/tools/stripe/types.ts index 3e966dd658e..4b5cd1a0fe1 100644 --- a/apps/sim/tools/stripe/types.ts +++ b/apps/sim/tools/stripe/types.ts @@ -1907,24 +1907,3 @@ export interface EventListResponse extends ToolResponse { } } } - -export type StripeResponse = - | PaymentIntentResponse - | PaymentIntentListResponse - | CustomerResponse - | CustomerListResponse - | CustomerDeleteResponse - | SubscriptionResponse - | SubscriptionListResponse - | InvoiceResponse - | InvoiceListResponse - | InvoiceDeleteResponse - | ChargeResponse - | ChargeListResponse - | ProductResponse - | ProductListResponse - | ProductDeleteResponse - | PriceResponse - | PriceListResponse - | EventResponse - | EventListResponse diff --git a/apps/sim/tools/sts/types.ts b/apps/sim/tools/sts/types.ts index de0a1afa89c..5983efa6ddd 100644 --- a/apps/sim/tools/sts/types.ts +++ b/apps/sim/tools/sts/types.ts @@ -121,7 +121,3 @@ export interface STSGetAccessKeyInfoResponse extends ToolResponse { account: string } } - -export interface STSBaseResponse extends ToolResponse { - output: { message: string } -} diff --git a/apps/sim/tools/stt/types.ts b/apps/sim/tools/stt/types.ts index fa5e647dd7f..af2a9a28b58 100644 --- a/apps/sim/tools/stt/types.ts +++ b/apps/sim/tools/stt/types.ts @@ -89,16 +89,3 @@ export interface SttResponse extends ToolResponse { summary?: string } } - -export interface SttBlockResponse extends ToolResponse { - output: { - transcript: string - segments?: TranscriptSegment[] - language?: string - duration?: number - confidence?: number - sentiment?: Record[] - entities?: Record[] - summary?: string - } -} diff --git a/apps/sim/tools/supabase/types.ts b/apps/sim/tools/supabase/types.ts index b48f2d981a5..2f045e870fb 100644 --- a/apps/sim/tools/supabase/types.ts +++ b/apps/sim/tools/supabase/types.ts @@ -324,8 +324,6 @@ export interface SupabaseUpsertResponse extends SupabaseBaseResponse {} export interface SupabaseVectorSearchResponse extends SupabaseBaseResponse {} -export interface SupabaseResponse extends SupabaseBaseResponse {} - export interface SupabaseRpcParams { apiKey: string projectId: string diff --git a/apps/sim/tools/tavily/types.ts b/apps/sim/tools/tavily/types.ts index 090f23bf420..a26875fd7d6 100644 --- a/apps/sim/tools/tavily/types.ts +++ b/apps/sim/tools/tavily/types.ts @@ -148,8 +148,6 @@ export interface TavilySearchParams { auto_parameters?: boolean } -export type TavilyResponse = TavilySearchResponse | TavilyExtractResponse - /** * Parameters for the Tavily Crawl tool. */ diff --git a/apps/sim/tools/telegram/types.ts b/apps/sim/tools/telegram/types.ts index 9be17369e54..e61084ceddd 100644 --- a/apps/sim/tools/telegram/types.ts +++ b/apps/sim/tools/telegram/types.ts @@ -290,16 +290,4 @@ export interface TelegramGetChatMemberResponse extends ToolResponse { } } -export type TelegramResponse = - | TelegramSendMessageResponse - | TelegramSendPhotoResponse - | TelegramSendAudioResponse - | TelegramSendMediaResponse - | TelegramSendDocumentResponse - | TelegramDeleteMessageResponse - | TelegramCopyMessageResponse - | TelegramBooleanResponse - | TelegramGetChatResponse - | TelegramGetChatMemberResponse - // Legacy type for backwards compatibility diff --git a/apps/sim/tools/temporal/types.ts b/apps/sim/tools/temporal/types.ts index 385ff6cd573..6bab71b9503 100644 --- a/apps/sim/tools/temporal/types.ts +++ b/apps/sim/tools/temporal/types.ts @@ -306,21 +306,3 @@ export interface TemporalTerminateWorkflowResponse extends ToolResponse { workflowId: string } } - -export type TemporalResponse = - | TemporalStartWorkflowResponse - | TemporalSignalWorkflowResponse - | TemporalSignalWithStartResponse - | TemporalQueryWorkflowResponse - | TemporalUpdateWorkflowResponse - | TemporalDescribeWorkflowResponse - | TemporalListWorkflowsResponse - | TemporalCountWorkflowsResponse - | TemporalGetWorkflowHistoryResponse - | TemporalCancelWorkflowResponse - | TemporalTerminateWorkflowResponse - | TemporalResetWorkflowResponse - | TemporalListSchedulesResponse - | TemporalDescribeScheduleResponse - | TemporalScheduleMutationResponse - | TemporalDescribeTaskQueueResponse diff --git a/apps/sim/tools/tiktok/types.ts b/apps/sim/tools/tiktok/types.ts index c1172179f31..bb099691ba1 100644 --- a/apps/sim/tools/tiktok/types.ts +++ b/apps/sim/tools/tiktok/types.ts @@ -153,13 +153,3 @@ export interface TikTokGetPostStatusResponse extends ToolResponse { downloadedBytes: number | null } } - -/** - * Union type of all TikTok responses - */ -export type TikTokResponse = - | TikTokGetUserResponse - | TikTokListVideosResponse - | TikTokQueryVideosResponse - | TikTokUploadVideoDraftResponse - | TikTokGetPostStatusResponse diff --git a/apps/sim/tools/tinybird/types.ts b/apps/sim/tools/tinybird/types.ts index 3d4392eee51..4214f52f02b 100644 --- a/apps/sim/tools/tinybird/types.ts +++ b/apps/sim/tools/tinybird/types.ts @@ -176,15 +176,3 @@ export interface TinybirdGetJobResponse extends ToolResponse { job: Record | null } } - -/** - * Union type for all possible Tinybird responses - */ -export type TinybirdResponse = - | TinybirdEventsResponse - | TinybirdQueryResponse - | TinybirdQueryPipeResponse - | TinybirdAppendDatasourceResponse - | TinybirdTruncateDatasourceResponse - | TinybirdDeleteDatasourceRowsResponse - | TinybirdGetJobResponse diff --git a/apps/sim/tools/trello/types.ts b/apps/sim/tools/trello/types.ts index de253a083e4..948ca3fa5ee 100644 --- a/apps/sim/tools/trello/types.ts +++ b/apps/sim/tools/trello/types.ts @@ -396,26 +396,3 @@ export interface TrelloSearchResponse extends ToolResponse { error?: string } } - -export type TrelloResponse = - | TrelloListListsResponse - | TrelloListCardsResponse - | TrelloCreateCardResponse - | TrelloUpdateCardResponse - | TrelloDeleteCardResponse - | TrelloGetActionsResponse - | TrelloAddCommentResponse - | TrelloCreateBoardResponse - | TrelloGetBoardResponse - | TrelloCreateListResponse - | TrelloUpdateListResponse - | TrelloGetCardResponse - | TrelloAddChecklistResponse - | TrelloAddChecklistItemResponse - | TrelloUpdateChecklistItemResponse - | TrelloAddLabelResponse - | TrelloRemoveLabelResponse - | TrelloAddMemberResponse - | TrelloRemoveMemberResponse - | TrelloListMembersResponse - | TrelloSearchResponse diff --git a/apps/sim/tools/trigger_dev/types.ts b/apps/sim/tools/trigger_dev/types.ts index 852584e7edf..b50c072925f 100644 --- a/apps/sim/tools/trigger_dev/types.ts +++ b/apps/sim/tools/trigger_dev/types.ts @@ -753,36 +753,3 @@ export interface TriggerDevDeleteScheduleResponse extends ToolResponse { scheduleId: string } } - -export type TriggerDevResponse = - | TriggerDevTriggerTaskResponse - | TriggerDevBatchTriggerTaskResponse - | TriggerDevGetBatchResponse - | TriggerDevBatchResultsResponse - | TriggerDevRunResponse - | TriggerDevRunResultResponse - | TriggerDevListRunsResponse - | TriggerDevRunActionResponse - | TriggerDevAddRunTagsResponse - | TriggerDevRunEventsResponse - | TriggerDevRunTraceResponse - | TriggerDevUpdateRunMetadataResponse - | TriggerDevScheduleResponse - | TriggerDevListSchedulesResponse - | TriggerDevDeleteScheduleResponse - | TriggerDevListEnvVarsResponse - | TriggerDevEnvVarResponse - | TriggerDevEnvVarActionResponse - | TriggerDevImportEnvVarsResponse - | TriggerDevQueueResponse - | TriggerDevListQueuesResponse - | TriggerDevDeploymentResponse - | TriggerDevListDeploymentsResponse - | TriggerDevPromoteDeploymentResponse - | TriggerDevExecuteQueryResponse - | TriggerDevQuerySchemaResponse - | TriggerDevCreateWaitpointTokenResponse - | TriggerDevCompleteWaitpointTokenResponse - | TriggerDevWaitpointTokenResponse - | TriggerDevListWaitpointTokensResponse - | TriggerDevListTimezonesResponse diff --git a/apps/sim/tools/typeform/types.ts b/apps/sim/tools/typeform/types.ts index 03972c66cd4..3841aea5e81 100644 --- a/apps/sim/tools/typeform/types.ts +++ b/apps/sim/tools/typeform/types.ts @@ -240,10 +240,3 @@ export interface TypeformDeleteFormResponse extends ToolResponse { message: string } } - -export interface TypeformResponse extends ToolResponse { - output: - | TypeformResponsesResponse['output'] - | TypeformFilesResponse['output'] - | TypeformInsightsData -} diff --git a/apps/sim/tools/vanta/types.ts b/apps/sim/tools/vanta/types.ts index 1688ef10e08..6a0609ced5d 100644 --- a/apps/sim/tools/vanta/types.ts +++ b/apps/sim/tools/vanta/types.ts @@ -744,31 +744,3 @@ export interface VantaListVulnerabilitiesResponse extends ToolResponse { pageInfo: VantaPageInfo | null } } - -export type VantaResponse = - | VantaListFrameworksResponse - | VantaGetFrameworkResponse - | VantaListControlsResponse - | VantaGetControlResponse - | VantaListTestsResponse - | VantaGetTestResponse - | VantaListTestEntitiesResponse - | VantaListDocumentsResponse - | VantaGetDocumentResponse - | VantaListDocumentUploadsResponse - | VantaUploadDocumentFileResponse - | VantaDownloadDocumentFileResponse - | VantaSubmitDocumentResponse - | VantaListPeopleResponse - | VantaGetPersonResponse - | VantaListPoliciesResponse - | VantaGetPolicyResponse - | VantaListVendorsResponse - | VantaGetVendorResponse - | VantaListMonitoredComputersResponse - | VantaListVulnerabilitiesResponse - | VantaListVulnerabilityRemediationsResponse - | VantaListVulnerableAssetsResponse - | VantaGetVulnerableAssetResponse - | VantaListRiskScenariosResponse - | VantaGetRiskScenarioResponse diff --git a/apps/sim/tools/video/types.ts b/apps/sim/tools/video/types.ts index b5bff168f94..9be54e425b5 100644 --- a/apps/sim/tools/video/types.ts +++ b/apps/sim/tools/video/types.ts @@ -46,15 +46,3 @@ export interface VideoResponse extends ToolResponse { } } } - -export interface VideoBlockResponse extends ToolResponse { - output: { - videoUrl: string - videoFile?: UserFile - duration?: number - width?: number - height?: number - provider?: string - model?: string - } -} diff --git a/apps/sim/tools/wealthbox/types.ts b/apps/sim/tools/wealthbox/types.ts index 53ef69e53db..f4e5c14f6f8 100644 --- a/apps/sim/tools/wealthbox/types.ts +++ b/apps/sim/tools/wealthbox/types.ts @@ -146,5 +146,3 @@ export interface WealthboxTaskRequestBody { type: string }> } - -export type WealthboxResponse = WealthboxReadResponse | WealthboxWriteResponse diff --git a/apps/sim/tools/webflow/types.ts b/apps/sim/tools/webflow/types.ts index cf6205d1977..1692105c207 100644 --- a/apps/sim/tools/webflow/types.ts +++ b/apps/sim/tools/webflow/types.ts @@ -125,10 +125,3 @@ export interface WebflowDeleteItemResponse { success: boolean output: WebflowDeleteItemOutput } - -export type WebflowResponse = - | WebflowListItemsResponse - | WebflowGetItemResponse - | WebflowCreateItemResponse - | WebflowUpdateItemResponse - | WebflowDeleteItemResponse diff --git a/apps/sim/tools/wikipedia/types.ts b/apps/sim/tools/wikipedia/types.ts index f09b8e97ce9..a084994c391 100644 --- a/apps/sim/tools/wikipedia/types.ts +++ b/apps/sim/tools/wikipedia/types.ts @@ -302,9 +302,3 @@ export interface WikipediaRandomPageResponse extends ToolResponse { randomPage: WikipediaRandomPage } } - -export type WikipediaResponse = - | WikipediaPageSummaryResponse - | WikipediaSearchResponse - | WikipediaPageContentResponse - | WikipediaRandomPageResponse diff --git a/apps/sim/tools/wiza/types.ts b/apps/sim/tools/wiza/types.ts index 603a3fa933f..afe75b04d25 100644 --- a/apps/sim/tools/wiza/types.ts +++ b/apps/sim/tools/wiza/types.ts @@ -166,9 +166,3 @@ export interface WizaIndividualRevealData { export interface WizaIndividualRevealResponse extends ToolResponse { output: WizaIndividualRevealData } - -export type WizaResponse = - | WizaGetCreditsResponse - | WizaProspectSearchResponse - | WizaCompanyEnrichmentResponse - | WizaIndividualRevealResponse diff --git a/apps/sim/tools/wordpress/types.ts b/apps/sim/tools/wordpress/types.ts index e3b41d78c74..6c855c6d2aa 100644 --- a/apps/sim/tools/wordpress/types.ts +++ b/apps/sim/tools/wordpress/types.ts @@ -121,14 +121,6 @@ export interface WordPressListPostsResponse extends ToolResponse { } } -interface WordPressSearchPostsResponse extends ToolResponse { - output: { - posts: WordPressPost[] - total: number - totalPages: number - } -} - export interface WordPressCreatePageParams extends WordPressBaseParams { title: string content?: string @@ -336,12 +328,6 @@ export interface WordPressCreateCommentResponse extends ToolResponse { } } -interface WordPressGetCommentResponse extends ToolResponse { - output: { - comment: WordPressComment - } -} - export interface WordPressListCommentsParams extends WordPressBaseParams { perPage?: number page?: number @@ -601,39 +587,3 @@ export interface WordPressSearchContentResponse extends ToolResponse { totalPages: number } } - -export type WordPressResponse = - | WordPressCreatePostResponse - | WordPressUpdatePostResponse - | WordPressDeletePostResponse - | WordPressGetPostResponse - | WordPressListPostsResponse - | WordPressSearchPostsResponse - | WordPressCreatePageResponse - | WordPressUpdatePageResponse - | WordPressDeletePageResponse - | WordPressGetPageResponse - | WordPressListPagesResponse - | WordPressUploadMediaResponse - | WordPressGetMediaResponse - | WordPressListMediaResponse - | WordPressDeleteMediaResponse - | WordPressCreateCommentResponse - | WordPressGetCommentResponse - | WordPressListCommentsResponse - | WordPressUpdateCommentResponse - | WordPressDeleteCommentResponse - | WordPressCreateCategoryResponse - | WordPressListCategoriesResponse - | WordPressGetCategoryResponse - | WordPressUpdateCategoryResponse - | WordPressDeleteCategoryResponse - | WordPressCreateTagResponse - | WordPressListTagsResponse - | WordPressGetTagResponse - | WordPressUpdateTagResponse - | WordPressDeleteTagResponse - | WordPressGetCurrentUserResponse - | WordPressListUsersResponse - | WordPressGetUserResponse - | WordPressSearchContentResponse diff --git a/apps/sim/tools/x/types.ts b/apps/sim/tools/x/types.ts index 51c6a94ca91..9105d0772f6 100644 --- a/apps/sim/tools/x/types.ts +++ b/apps/sim/tools/x/types.ts @@ -141,8 +141,6 @@ export interface XUserResponse extends ToolResponse { } } -export type XResponse = XWriteResponse | XReadResponse | XSearchResponse | XUserResponse - /** * Transforms raw X API tweet data (snake_case) into the XTweet format (camelCase) */ diff --git a/apps/sim/tools/youtube/types.ts b/apps/sim/tools/youtube/types.ts index d33195dc39c..575da7c07e9 100644 --- a/apps/sim/tools/youtube/types.ts +++ b/apps/sim/tools/youtube/types.ts @@ -240,14 +240,3 @@ export interface YouTubeVideoCategoriesResponse extends ToolResponse { totalResults: number } } - -export type YouTubeResponse = - | YouTubeSearchResponse - | YouTubeVideoDetailsResponse - | YouTubeChannelInfoResponse - | YouTubePlaylistItemsResponse - | YouTubeCommentsResponse - | YouTubeChannelVideosResponse - | YouTubeChannelPlaylistsResponse - | YouTubeTrendingResponse - | YouTubeVideoCategoriesResponse diff --git a/apps/sim/tools/zendesk/types.ts b/apps/sim/tools/zendesk/types.ts index a24661e54ae..8c87bb798c7 100644 --- a/apps/sim/tools/zendesk/types.ts +++ b/apps/sim/tools/zendesk/types.ts @@ -16,21 +16,6 @@ export interface ZendeskPagingInfo { next_page?: string | null } -interface ZendeskListMetadata { - total_returned: number - has_more: boolean -} - -export interface ZendeskResponse { - success: boolean - output: { - data?: T - paging?: ZendeskPagingInfo - metadata?: ZendeskListMetadata - success: boolean - } -} - // Helper function to build Zendesk API URLs // Subdomain is always provided by user as a parameter export function buildZendeskUrl(subdomain: string, path: string): string { diff --git a/apps/sim/tools/zerobounce/types.ts b/apps/sim/tools/zerobounce/types.ts index e04dcd59c16..4846aa0e952 100644 --- a/apps/sim/tools/zerobounce/types.ts +++ b/apps/sim/tools/zerobounce/types.ts @@ -25,5 +25,3 @@ export interface ZeroBounceGetCreditsResponse extends ToolResponse { credits: number } } - -export type ZeroBounceResponse = ZeroBounceVerifyEmailResponse | ZeroBounceGetCreditsResponse diff --git a/apps/sim/tools/zoom/types.ts b/apps/sim/tools/zoom/types.ts index 0a3911ac8b9..e7818856ca0 100644 --- a/apps/sim/tools/zoom/types.ts +++ b/apps/sim/tools/zoom/types.ts @@ -520,16 +520,3 @@ export interface ZoomListPastParticipantsResponse extends ToolResponse { } } } - -// Combined response type for block -export type ZoomResponse = - | ZoomCreateMeetingResponse - | ZoomListMeetingsResponse - | ZoomGetMeetingResponse - | ZoomUpdateMeetingResponse - | ZoomDeleteMeetingResponse - | ZoomGetMeetingInvitationResponse - | ZoomListRecordingsResponse - | ZoomGetMeetingRecordingsResponse - | ZoomDeleteRecordingResponse - | ZoomListPastParticipantsResponse diff --git a/apps/sim/tools/zoominfo/types.ts b/apps/sim/tools/zoominfo/types.ts index 57a867a4f06..b1693cad039 100644 --- a/apps/sim/tools/zoominfo/types.ts +++ b/apps/sim/tools/zoominfo/types.ts @@ -126,11 +126,3 @@ export interface ZoomInfoSearchNewsResponse extends ToolResponse { totalPages: number | null } } - -export type ZoomInfoResponse = - | ZoomInfoSearchCompaniesResponse - | ZoomInfoSearchContactsResponse - | ZoomInfoEnrichCompaniesResponse - | ZoomInfoEnrichContactsResponse - | ZoomInfoSearchIntentResponse - | ZoomInfoSearchNewsResponse diff --git a/scripts/check-unused-exports.baseline.json b/scripts/check-unused-exports.baseline.json index 16bb8898a49..fa47270c80d 100644 --- a/scripts/check-unused-exports.baseline.json +++ b/scripts/check-unused-exports.baseline.json @@ -5527,11 +5527,8 @@ "apps/sim/tools/agiloft/types.ts#AgiloftDeleteRule", "apps/sim/tools/ahrefs/types.ts#AhrefsHistory", "apps/sim/tools/ahrefs/types.ts#AhrefsRankTrackerDevice", - "apps/sim/tools/ahrefs/types.ts#AhrefsResponse", "apps/sim/tools/ahrefs/types.ts#AhrefsTargetMode", "apps/sim/tools/ahrefs/types.ts#AhrefsVolumeMode", - "apps/sim/tools/airtable/types.ts#AirtableResponse", - "apps/sim/tools/apollo/types.ts#ApolloResponse", "apps/sim/tools/appconfig/types.ts#AppConfigApplication", "apps/sim/tools/appconfig/types.ts#AppConfigConfigurationProfile", "apps/sim/tools/appconfig/types.ts#AppConfigDeploymentDetail", @@ -5539,14 +5536,12 @@ "apps/sim/tools/appconfig/types.ts#AppConfigDeploymentSummary", "apps/sim/tools/appconfig/types.ts#AppConfigEnvironment", "apps/sim/tools/appconfig/types.ts#AppConfigHostedConfigurationVersionSummary", - "apps/sim/tools/arxiv/types.ts#ArxivResponse", "apps/sim/tools/arxiv/utils.ts#cleanText", "apps/sim/tools/arxiv/utils.ts#extractAuthors", "apps/sim/tools/arxiv/utils.ts#extractCategories", "apps/sim/tools/arxiv/utils.ts#extractPdfLink", "apps/sim/tools/arxiv/utils.ts#extractXmlAttribute", "apps/sim/tools/arxiv/utils.ts#extractXmlValue", - "apps/sim/tools/asana/types.ts#AsanaResponse", "apps/sim/tools/ashby/utils.ts#CONTACT_INFO_OUTPUT", "apps/sim/tools/ashby/utils.ts#FILE_HANDLES_OUTPUT", "apps/sim/tools/ashby/utils.ts#FILE_HANDLE_OUTPUT", @@ -5563,7 +5558,6 @@ "apps/sim/tools/attio/types.ts#ACTOR_OUTPUT_PROPERTIES", "apps/sim/tools/attio/types.ts#ASSIGNEE_OUTPUT_PROPERTIES", "apps/sim/tools/attio/types.ts#AttioNoteTag", - "apps/sim/tools/attio/types.ts#AttioResponse", "apps/sim/tools/attio/types.ts#LINKED_RECORD_OUTPUT_PROPERTIES", "apps/sim/tools/attio/types.ts#RECORD_ID_OUTPUT_PROPERTIES", "apps/sim/tools/azure_data_explorer/types.ts#AzureDataExplorerColumn", @@ -5576,7 +5570,6 @@ "apps/sim/tools/azure_devops/types.ts#AzureDevOpsPipelineDetail", "apps/sim/tools/azure_devops/types.ts#AzureDevOpsPipelineRun", "apps/sim/tools/azure_devops/types.ts#AzureDevOpsPipelineRunDetail", - "apps/sim/tools/azure_devops/types.ts#AzureDevOpsResponse", "apps/sim/tools/bitbucket/types.ts#BITBUCKET_COMMENT_RESOLUTION_OUTPUT_PROPERTIES", "apps/sim/tools/bitbucket/types.ts#BITBUCKET_PAGE_OUTPUT_PROPERTIES", "apps/sim/tools/bitbucket/types.ts#BITBUCKET_PIPELINE_COMMAND_OUTPUT_PROPERTIES", @@ -5608,7 +5601,6 @@ "apps/sim/tools/brex/types.ts#BrexExpenseReceipt", "apps/sim/tools/brex/types.ts#BrexLocation", "apps/sim/tools/brex/types.ts#BrexMoney", - "apps/sim/tools/brex/types.ts#BrexResponse", "apps/sim/tools/brex/types.ts#BrexSpendLimit", "apps/sim/tools/brex/types.ts#BrexSpendLimitPeriodBalance", "apps/sim/tools/brex/types.ts#BrexStatement", @@ -5616,8 +5608,6 @@ "apps/sim/tools/brex/types.ts#BrexTransfer", "apps/sim/tools/brex/types.ts#BrexUser", "apps/sim/tools/brex/types.ts#BrexVendor", - "apps/sim/tools/brightdata/types.ts#BrightDataResponse", - "apps/sim/tools/browser_use/types.ts#BrowserUseResponse", "apps/sim/tools/buffer/types.ts#BUFFER_SCHEDULING_TYPES", "apps/sim/tools/buffer/types.ts#BUFFER_SHARE_MODES", "apps/sim/tools/buffer/types.ts#BufferAccount", @@ -5641,18 +5631,7 @@ "apps/sim/tools/calendly/types.ts#CalendlyInviteeResource", "apps/sim/tools/calendly/types.ts#CalendlyPagination", "apps/sim/tools/calendly/types.ts#CalendlyUserResource", - "apps/sim/tools/cbinsights/types.ts#CbInsightsExitProbabilityHistoryResponse", - "apps/sim/tools/cbinsights/types.ts#CbInsightsFundingWindowResponse", - "apps/sim/tools/cbinsights/types.ts#CbInsightsFundingsResponse", - "apps/sim/tools/cbinsights/types.ts#CbInsightsItemsResponse", - "apps/sim/tools/cbinsights/types.ts#CbInsightsMosaicHistoryResponse", - "apps/sim/tools/cbinsights/types.ts#CbInsightsObjectResponse", - "apps/sim/tools/cbinsights/types.ts#CbInsightsPagedItemsResponse", "apps/sim/tools/cbinsights/types.ts#CbInsightsPagedParams", - "apps/sim/tools/cbinsights/types.ts#CbInsightsResponse", - "apps/sim/tools/cbinsights/types.ts#CbInsightsRevenueResponse", - "apps/sim/tools/cbinsights/types.ts#CbInsightsScoutingReportResponse", - "apps/sim/tools/cbinsights/types.ts#CbInsightsStrategyMapResponse", "apps/sim/tools/cbinsights/utils.ts#CBINSIGHTS_API_BASE", "apps/sim/tools/cbinsights/utils.ts#LIMIT_MAX", "apps/sim/tools/cbinsights/utils.ts#LIMIT_MIN", @@ -5671,18 +5650,14 @@ "apps/sim/tools/circleback/utils.ts#RawCirclebackMeetingActionItem", "apps/sim/tools/clerk/types.ts#ClerkOrganizationInvitationPublicUserData", "apps/sim/tools/clerk/types.ts#ClerkOrganizationMembershipPublicUserData", - "apps/sim/tools/clerk/types.ts#ClerkResponse", "apps/sim/tools/clickhouse/types.ts#CLICKHOUSE_COLUMN_OUTPUT_PROPERTIES", "apps/sim/tools/clickhouse/types.ts#ClickHouseConnectionConfig", - "apps/sim/tools/clickhouse/types.ts#ClickHouseResponse", "apps/sim/tools/clickup/shared.ts#mapClickUpUser", - "apps/sim/tools/clickup/types.ts#ClickUpResponse", "apps/sim/tools/clickup/types.ts#ClickUpTimeEntryLocation", "apps/sim/tools/cloudflare/types.ts#CloudflareRawCertificate", "apps/sim/tools/cloudflare/types.ts#CloudflareRawDnsAnalyticsAggregate", "apps/sim/tools/cloudflare/types.ts#CloudflareRawRule", "apps/sim/tools/cloudflare/types.ts#CloudflareRawValidationRecord", - "apps/sim/tools/cloudflare/types.ts#CloudflareResponse", "apps/sim/tools/cloudflare/types.ts#CloudflareResultInfo", "apps/sim/tools/cloudflare/utils.ts#parseJsonParam", "apps/sim/tools/cloudtrail/types.ts#CloudTrailAdvancedEventSelector", @@ -5701,7 +5676,6 @@ "apps/sim/tools/coda/types.ts#CodaPaginationParams", "apps/sim/tools/coda/types.ts#CodaPerson", "apps/sim/tools/coda/types.ts#CodaPrincipalType", - "apps/sim/tools/coda/types.ts#CodaResponse", "apps/sim/tools/coda/types.ts#CodaTableParams", "apps/sim/tools/coda/types.ts#CodaTableRef", "apps/sim/tools/coda/types.ts#CodaWorkspaceRef", @@ -5718,7 +5692,6 @@ "apps/sim/tools/confluence/types.ts#COMMENT_BODY_OUTPUT_PROPERTIES", "apps/sim/tools/confluence/types.ts#COMMENT_ITEM_PROPERTIES", "apps/sim/tools/confluence/types.ts#COMMENT_OUTPUT", - "apps/sim/tools/confluence/types.ts#ConfluenceResponse", "apps/sim/tools/confluence/types.ts#LABELS_OUTPUT", "apps/sim/tools/confluence/types.ts#LABEL_OUTPUT", "apps/sim/tools/confluence/types.ts#PAGE_OUTPUT", @@ -5729,12 +5702,10 @@ "apps/sim/tools/confluence/types.ts#SUCCESS_OUTPUT", "apps/sim/tools/context_dev/hosting.ts#CONTEXT_DEV_API_KEY_PREFIX", "apps/sim/tools/convex/types.ts#ConvexBaseParams", - "apps/sim/tools/convex/types.ts#ConvexResponse", "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeAggregateFiltersSpec", "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeApiError", "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeIndicatorListResponse", "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeIndicatorMetadata", - "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeResponse", "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeVulnerabilityApp", "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeVulnerabilityCve", "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeVulnerabilityHostInfo", @@ -5743,7 +5714,6 @@ "apps/sim/tools/crunchbase/types.ts#CrunchbaseLink", "apps/sim/tools/crunchbase/types.ts#CrunchbaseLocationIdentifier", "apps/sim/tools/crunchbase/types.ts#CrunchbaseMoney", - "apps/sim/tools/crunchbase/types.ts#CrunchbaseResponse", "apps/sim/tools/crunchbase/utils.ts#CRUNCHBASE_AUTOCOMPLETE_COLLECTIONS=CRUNCHBASE_COLLECTIONS=CRUNCHBASE_METADATA_COLLECTIONS", "apps/sim/tools/crunchbase/utils.ts#MAX_PREDICATES", "apps/sim/tools/crunchbase/utils.ts#MAX_PREDICATE_VALUES", @@ -5754,12 +5724,8 @@ "apps/sim/tools/crunchbase/utils.ts#normalizeOrder", "apps/sim/tools/crunchbase/utils.ts#normalizePredicates", "apps/sim/tools/crunchbase/utils.ts#parseArrayParam", - "apps/sim/tools/cursor/types.ts#CursorResponse", - "apps/sim/tools/dagster/types.ts#DagsterResponse", "apps/sim/tools/databricks/types.ts#DatabricksCluster", - "apps/sim/tools/databricks/types.ts#DatabricksResponse", "apps/sim/tools/datadog/types.ts#DashboardLayoutType", - "apps/sim/tools/datadog/types.ts#DatadogResponse", "apps/sim/tools/datadog/types.ts#EventData", "apps/sim/tools/datadog/types.ts#IncidentSeverity", "apps/sim/tools/datadog/types.ts#MetricPoint", @@ -5770,12 +5736,9 @@ "apps/sim/tools/datadog/types.ts#SloType", "apps/sim/tools/datadog/types.ts#SyntheticsTestPauseStatus", "apps/sim/tools/datagma/hosting.ts#DATAGMA_API_KEY_PREFIX", - "apps/sim/tools/datagma/types.ts#DatagmaResponse", "apps/sim/tools/daytona/types.ts#DaytonaFileInfo", "apps/sim/tools/daytona/utils.ts#DAYTONA_TOOLBOX_BASE_URL", "apps/sim/tools/deployments/types.ts#DeploymentVersionSummary", - "apps/sim/tools/discord/types.ts#DiscordResponse", - "apps/sim/tools/docusign/types.ts#DocuSignResponse", "apps/sim/tools/docusign/types.ts#ENVELOPE_OUTPUT_PROPERTIES", "apps/sim/tools/docusign/types.ts#RECIPIENT_OUTPUT_PROPERTIES", "apps/sim/tools/docusign/types.ts#TEMPLATE_OUTPUT_PROPERTIES", @@ -5787,60 +5750,43 @@ "apps/sim/tools/downdetector/types.ts#DowndetectorIndicator", "apps/sim/tools/downdetector/types.ts#DowndetectorProvider", "apps/sim/tools/downdetector/types.ts#DowndetectorReportBucket", - "apps/sim/tools/downdetector/types.ts#DowndetectorResponse", "apps/sim/tools/downdetector/types.ts#DowndetectorSite", "apps/sim/tools/downdetector/types.ts#DowndetectorSiteCompany", "apps/sim/tools/dropbox/types.ts#DropboxMetadata", - "apps/sim/tools/dropbox/types.ts#DropboxResponse", "apps/sim/tools/dropcontact/hosting.ts#DROPCONTACT_API_KEY_PREFIX", "apps/sim/tools/dropcontact/types.ts#DROPCONTACT_EMAIL_ITEM_OUTPUT_PROPERTIES", "apps/sim/tools/dropcontact/types.ts#DropcontactBaseParams", - "apps/sim/tools/dropcontact/types.ts#DropcontactResponse", - "apps/sim/tools/dub/types.ts#DubResponse", - "apps/sim/tools/duckduckgo/types.ts#DuckDuckGoResponse", - "apps/sim/tools/dynamodb/types.ts#DynamoDBResponse", "apps/sim/tools/dynatrace/outputs.ts#entityStubProperties", "apps/sim/tools/dynatrace/outputs.ts#managementZoneProperties", "apps/sim/tools/dynatrace/types.ts#DynatraceBaseParams", "apps/sim/tools/dynatrace/types.ts#DynatraceMetricSeries", - "apps/sim/tools/dynatrace/types.ts#DynatraceResponse", "apps/sim/tools/dynatrace/utils.ts#mapEntityStub", "apps/sim/tools/dynatrace/utils.ts#mapManagementZones", - "apps/sim/tools/elasticsearch/types.ts#ElasticsearchResponse", - "apps/sim/tools/elevenlabs/types.ts#ElevenLabsBlockResponse", "apps/sim/tools/elevenlabs/types.ts#ElevenLabsModelLanguage", "apps/sim/tools/elevenlabs/types.ts#ElevenLabsVoiceSettings", - "apps/sim/tools/emailbison/types.ts#EmailBisonResponse", "apps/sim/tools/embeddings/index.ts#EmbeddingsParams", "apps/sim/tools/embeddings/index.ts#EmbeddingsResponse", "apps/sim/tools/embeddings/index.ts#createEmbeddingTool", "apps/sim/tools/enrow/hosting.ts#ENROW_API_KEY_PREFIX", "apps/sim/tools/enrow/types.ts#EnrowBaseParams", - "apps/sim/tools/enrow/types.ts#EnrowResponse", "apps/sim/tools/error-extractors.ts#ErrorExtractor", "apps/sim/tools/exa/types.ts#ExaAgentEffort", - "apps/sim/tools/exa/types.ts#ExaResponse", "apps/sim/tools/exa/types.ts#ExaSearchType", - "apps/sim/tools/fathom/types.ts#FathomResponse", "apps/sim/tools/findymail/hosting.ts#FINDYMAIL_API_KEY_PREFIX", "apps/sim/tools/findymail/types.ts#FINDYMAIL_CONTACT_OUTPUT_PROPERTIES", "apps/sim/tools/findymail/types.ts#FINDYMAIL_EMPLOYEE_OUTPUT_PROPERTIES", "apps/sim/tools/findymail/types.ts#FINDYMAIL_TECHNOLOGY_OUTPUT_PROPERTIES", "apps/sim/tools/findymail/types.ts#FindymailContact", "apps/sim/tools/findymail/types.ts#FindymailEmployee", - "apps/sim/tools/findymail/types.ts#FindymailResponse", "apps/sim/tools/findymail/types.ts#FindymailTechnology", "apps/sim/tools/firecrawl/hosting.ts#FIRECRAWL_API_KEY_PREFIX", "apps/sim/tools/firecrawl/types.ts#CRAWL_METADATA_OUTPUT", "apps/sim/tools/firecrawl/types.ts#CRAWL_METADATA_OUTPUT_PROPERTIES", - "apps/sim/tools/firecrawl/types.ts#FirecrawlResponse", "apps/sim/tools/firecrawl/types.ts#PAGE_METADATA_OUTPUT", "apps/sim/tools/firecrawl/types.ts#SEARCH_METADATA_OUTPUT", "apps/sim/tools/firecrawl/types.ts#SEARCH_METADATA_OUTPUT_PROPERTIES", "apps/sim/tools/firecrawl/types.ts#SEARCH_RESULT_OUTPUT", - "apps/sim/tools/fireflies/types.ts#FirefliesResponse", "apps/sim/tools/flint/types.ts#FlintTaskCreatedOutput", - "apps/sim/tools/gamma/types.ts#GammaResponse", "apps/sim/tools/github/types.ts#BRANCH_REF_OUTPUT_PROPERTIES", "apps/sim/tools/github/types.ts#COMMIT_DATA_OUTPUT_PROPERTIES", "apps/sim/tools/github/types.ts#COMMIT_REF_OUTPUT", @@ -5854,7 +5800,6 @@ "apps/sim/tools/github/types.ts#GIST_OWNER_OUTPUT_PROPERTIES", "apps/sim/tools/github/types.ts#GIT_ACTOR_OUTPUT", "apps/sim/tools/github/types.ts#GIT_ACTOR_OUTPUT_PROPERTIES", - "apps/sim/tools/github/types.ts#GitHubResponse", "apps/sim/tools/github/types.ts#HEAD_COMMIT_OUTPUT_PROPERTIES", "apps/sim/tools/github/types.ts#LABEL_OUTPUT_PROPERTIES", "apps/sim/tools/github/types.ts#MILESTONE_CREATOR_OUTPUT_PROPERTIES", @@ -5866,40 +5811,25 @@ "apps/sim/tools/github/types.ts#SEARCH_REPO_OUTPUT_PROPERTIES", "apps/sim/tools/github/types.ts#USER_OUTPUT_PROPERTIES", "apps/sim/tools/github/utils.server.ts#GITHUB_MAX_RESPONSE_BYTES", - "apps/sim/tools/gitlab/types.ts#GitLabResponse", "apps/sim/tools/gitlab/utils.ts#GITLAB_ACCESS_LEVELS", "apps/sim/tools/gmail/types.ts#GmailToolParams", "apps/sim/tools/gmail/utils.ts#buildBodyAlternatives", "apps/sim/tools/gmail/utils.ts#extractMessageBody", "apps/sim/tools/gmail/utils.ts#fetchThreadingHeaders", - "apps/sim/tools/gong/types.ts#GongResponse", "apps/sim/tools/gong/utils.ts#parseGongJsonField", - "apps/sim/tools/google_appsheet/types.ts#GoogleAppsheetResponse", "apps/sim/tools/google_appsheet/types.ts#GoogleAppsheetRow", - "apps/sim/tools/google_calendar/types.ts#GoogleCalendarResponse", "apps/sim/tools/google_calendar/types.ts#GoogleCalendarToolParams", - "apps/sim/tools/google_contacts/types.ts#GoogleContactsResponse", "apps/sim/tools/google_contacts/types.ts#GoogleContactsToolParams", - "apps/sim/tools/google_docs/types.ts#GoogleDocsResponse", "apps/sim/tools/google_drive/types.ts#GoogleDriveCommentReply", - "apps/sim/tools/google_drive/types.ts#GoogleDriveResponse", "apps/sim/tools/google_forms/utils.ts#FORMS_API_BASE", - "apps/sim/tools/google_meet/types.ts#GoogleMeetResponse", "apps/sim/tools/google_meet/types.ts#GoogleMeetToolParams", "apps/sim/tools/google_sheets/types.ts#GoogleSheetsFilterInfo", - "apps/sim/tools/google_sheets/types.ts#GoogleSheetsResponse", - "apps/sim/tools/google_sheets/types.ts#GoogleSheetsV2Response", - "apps/sim/tools/google_slides/types.ts#GoogleSlidesResponse", "apps/sim/tools/google_slides/utils.ts#ptToEmuDimension", "apps/sim/tools/google_vault/types.ts#GoogleVaultCorpus", "apps/sim/tools/google_vault/types.ts#GoogleVaultHoldView", - "apps/sim/tools/grafana/types.ts#GrafanaResponse", - "apps/sim/tools/grafana/types.ts#GrafanaUpdateFolderResponse", "apps/sim/tools/grain/types.ts#GRAIN_HOOK_TYPES", "apps/sim/tools/grain/types.ts#GrainHookType", "apps/sim/tools/granola/types.ts#GranolaWebhookEndpointOutput", - "apps/sim/tools/greenhouse/types.ts#GreenhouseResponse", - "apps/sim/tools/greptile/types.ts#GreptileResponse", "apps/sim/tools/harmonic/types.ts#HarmonicContactMetadata", "apps/sim/tools/harmonic/types.ts#HarmonicSocialMetadata", "apps/sim/tools/harmonic/utils.ts#HARMONIC_BATCH_PEOPLE_MAX", @@ -5914,7 +5844,6 @@ "apps/sim/tools/harmonic/utils.ts#clampPageSize", "apps/sim/tools/harmonic/utils.ts#normalizeNewResultsSince", "apps/sim/tools/harmonic/utils.ts#normalizePerson", - "apps/sim/tools/hex/types.ts#HexResponse", "apps/sim/tools/http/utils.ts#canonicalizeFirstPartyApiUrl", "apps/sim/tools/hubspot/types.ts#APPOINTMENT_PROPERTIES_OUTPUT", "apps/sim/tools/hubspot/types.ts#COMPANY_PROPERTIES_OUTPUT", @@ -5933,7 +5862,6 @@ "apps/sim/tools/hubspot/types.ts#HubSpotListMembership", "apps/sim/tools/hubspot/types.ts#HubSpotNote", "apps/sim/tools/hubspot/types.ts#HubSpotQuote", - "apps/sim/tools/hubspot/types.ts#HubSpotResponse", "apps/sim/tools/hubspot/types.ts#HubSpotTicket", "apps/sim/tools/hubspot/types.ts#LINE_ITEM_PROPERTIES_OUTPUT", "apps/sim/tools/hubspot/types.ts#MARKETING_EVENT_OUTPUT_PROPERTIES", @@ -5946,12 +5874,10 @@ "apps/sim/tools/hunter/types.ts#DEPARTMENT_OUTPUT_PROPERTIES", "apps/sim/tools/hunter/types.ts#DISCOVER_RESULT_OUTPUT_PROPERTIES", "apps/sim/tools/hunter/types.ts#EMAIL_OUTPUT_PROPERTIES", - "apps/sim/tools/hunter/types.ts#HunterResponse", "apps/sim/tools/hunter/types.ts#SENIORITY_OUTPUT_PROPERTIES", "apps/sim/tools/hunter/types.ts#SOURCE_OUTPUT_PROPERTIES", "apps/sim/tools/hunter/types.ts#VERIFICATION_OUTPUT_PROPERTIES", "apps/sim/tools/iam/types.ts#IAMAccessKeyStatus", - "apps/sim/tools/iam/types.ts#IAMBaseResponse", "apps/sim/tools/iam/types.ts#IAMContextKeyType", "apps/sim/tools/iam/types.ts#IAMPolicyScope", "apps/sim/tools/iam/types.ts#IAMSimulateEvaluationResult", @@ -5959,8 +5885,6 @@ "apps/sim/tools/iam/types.ts#IAMSimulateResourceSpecificResult", "apps/sim/tools/icypeas/hosting.ts#ICYPEAS_API_KEY_PREFIX", "apps/sim/tools/icypeas/types.ts#IcypeasBaseParams", - "apps/sim/tools/icypeas/types.ts#IcypeasResponse", - "apps/sim/tools/identity_center/types.ts#IdentityCenterBaseResponse", "apps/sim/tools/identity_center/types.ts#IdentityCenterConnectionConfig", "apps/sim/tools/incidentio/types.ts#CustomFieldType", "apps/sim/tools/incidentio/types.ts#INCIDENTIO_ACTION_OUTPUT_PROPERTIES", @@ -5986,22 +5910,18 @@ "apps/sim/tools/incidentio/types.ts#IncidentioIncidentAlert", "apps/sim/tools/incidentio/types.ts#IncidentioIncidentParticipant", "apps/sim/tools/incidentio/types.ts#IncidentioPaginationMeta", - "apps/sim/tools/incidentio/types.ts#IncidentioResponse", "apps/sim/tools/incidentio/types.ts#IncidentioScheduleOverrideRecord", "apps/sim/tools/incidentio/types.ts#IncidentioSlimUser", "apps/sim/tools/incidentio/types.ts#IncidentioTeam", "apps/sim/tools/index.ts#ToolEnvReferenceMode", - "apps/sim/tools/infisical/types.ts#InfisicalResponse", "apps/sim/tools/instagram/constants.ts#INSTAGRAM_GRAPH_VERSION", "apps/sim/tools/instagram/types.ts#InstagramAccessParams", "apps/sim/tools/instagram/types.ts#InstagramAccountInsightsMetricType", "apps/sim/tools/instagram/types.ts#InstagramAccountInsightsPeriod", "apps/sim/tools/instagram/types.ts#InstagramAccountInsightsTimeframe", "apps/sim/tools/instagram/types.ts#InstagramMediaInput", - "apps/sim/tools/instagram/types.ts#InstagramResponse", "apps/sim/tools/instagram/utils.ts#InstagramGraphPaging", "apps/sim/tools/instantly/types.ts#InstantlyBaseParams", - "apps/sim/tools/instantly/types.ts#InstantlyResponse", "apps/sim/tools/instantly/types.ts#InstantlyScalar", "apps/sim/tools/intercom/types.ts#INTERCOM_ADMIN_OUTPUT_PROPERTIES", "apps/sim/tools/intercom/types.ts#INTERCOM_AVATAR_OUTPUT_PROPERTIES", @@ -6045,7 +5965,6 @@ "apps/sim/tools/jira/types.ts#COMPONENT_OUTPUT_PROPERTIES", "apps/sim/tools/jira/types.ts#ISSUE_LINK_ITEM_PROPERTIES", "apps/sim/tools/jira/types.ts#ISSUE_TYPE_OUTPUT_PROPERTIES", - "apps/sim/tools/jira/types.ts#JiraResponse", "apps/sim/tools/jira/types.ts#PRIORITY_OUTPUT_PROPERTIES", "apps/sim/tools/jira/types.ts#PROJECT_OUTPUT", "apps/sim/tools/jira/types.ts#PROJECT_OUTPUT_PROPERTIES", @@ -6067,7 +5986,6 @@ "apps/sim/tools/jsm/types.ts#AssetObjectAttributeInput", "apps/sim/tools/jsm/types.ts#AssetObjectAttributeValue", "apps/sim/tools/jsm/types.ts#JsmAssetsBaseParams", - "apps/sim/tools/jsm/types.ts#JsmResponse", "apps/sim/tools/jsm/types.ts#RawAssetObjectAttribute", "apps/sim/tools/jsm/types.ts#RawAssetObjectAttributeValue", "apps/sim/tools/jsm/utils.ts#getAssetsApiBaseUrl", @@ -6083,26 +6001,19 @@ "apps/sim/tools/kalshi/types.ts#KALSHI_CANDLESTICK_OUTPUT_PROPERTIES", "apps/sim/tools/kalshi/types.ts#KALSHI_ORDERBOOK_LEVEL_OUTPUT_PROPERTIES", "apps/sim/tools/kalshi/types.ts#generateKalshiSignature", - "apps/sim/tools/ketch/types.ts#KetchResponse", "apps/sim/tools/lambda/types.ts#LambdaConnectionParams", - "apps/sim/tools/lambda/types.ts#LambdaResponse", "apps/sim/tools/langsmith/types.ts#LangsmithFeedbackSourceType", - "apps/sim/tools/langsmith/types.ts#LangsmithResponse", "apps/sim/tools/langsmith/types.ts#LangsmithRunType", "apps/sim/tools/latex/types.ts#LatexCompiler", "apps/sim/tools/latex/types.ts#LatexPdfReference", "apps/sim/tools/latex/types.ts#LatexResource", - "apps/sim/tools/latex/types.ts#LatexResponse", "apps/sim/tools/leadmagic/hosting.ts#LEADMAGIC_API_KEY_PREFIX", - "apps/sim/tools/leadmagic/types.ts#LeadMagicResponse", - "apps/sim/tools/lemlist/types.ts#LemlistResponse", "apps/sim/tools/linear/types.ts#CYCLE_OUTPUT", "apps/sim/tools/linear/types.ts#CYCLE_OUTPUT_PROPERTIES", "apps/sim/tools/linear/types.ts#ISSUE_MINIMAL_OUTPUT", "apps/sim/tools/linear/types.ts#ISSUE_MINIMAL_OUTPUT_PROPERTIES", "apps/sim/tools/linear/types.ts#LABELS_OUTPUT", "apps/sim/tools/linear/types.ts#LABEL_OUTPUT_PROPERTIES", - "apps/sim/tools/linear/types.ts#LinearResponse", "apps/sim/tools/linear/types.ts#PROJECT_OUTPUT", "apps/sim/tools/linear/types.ts#PROJECT_OUTPUT_PROPERTIES", "apps/sim/tools/linear/types.ts#STATE_OUTPUT", @@ -6111,15 +6022,12 @@ "apps/sim/tools/linear/types.ts#TEAM_OUTPUT_PROPERTIES", "apps/sim/tools/linear/types.ts#USER_OUTPUT", "apps/sim/tools/linear/types.ts#USER_OUTPUT_PROPERTIES", - "apps/sim/tools/linkedin/types.ts#LinkedInResponse", "apps/sim/tools/linq/types.ts#LinqChatHandle", "apps/sim/tools/linq/types.ts#LinqReactionType", "apps/sim/tools/logfire/types.ts#LogfireApiField", "apps/sim/tools/logfire/types.ts#LogfireLevel", "apps/sim/tools/logfire/types.ts#LogfireQueryWindowParams", - "apps/sim/tools/logfire/types.ts#LogfireResponse", "apps/sim/tools/logs/types.ts#LogsComparisonOperator", - "apps/sim/tools/loops/types.ts#LoopsResponse", "apps/sim/tools/mailchimp/types.ts#extractServerPrefix", "apps/sim/tools/manageengine_sdp/data-centers.ts#DEFAULT_SDP_DATA_CENTER", "apps/sim/tools/manageengine_sdp/data-centers.ts#SdpDataCenter", @@ -6131,11 +6039,9 @@ "apps/sim/tools/mcp/index.ts#McpRunOperationResponse", "apps/sim/tools/mem0/types.ts#SEARCH_RESULT_OUTPUT", "apps/sim/tools/microsoft_ad/types.ts#DIRECTORY_AUDIT_TARGET_RESOURCE_PROPERTIES", - "apps/sim/tools/microsoft_ad/types.ts#MicrosoftAdResponse", "apps/sim/tools/microsoft_ad/types.ts#PREPAID_UNITS_OUTPUT_PROPERTIES", "apps/sim/tools/microsoft_ad/types.ts#SERVICE_PLAN_OUTPUT_PROPERTIES", "apps/sim/tools/microsoft_ad/utils.ts#isGraphObjectId", - "apps/sim/tools/microsoft_dataverse/types.ts#DataverseResponse", "apps/sim/tools/microsoft_dynamics_365/index.ts#DataverseCloseCaseParams", "apps/sim/tools/microsoft_dynamics_365/index.ts#DataverseCloseCaseResponse", "apps/sim/tools/microsoft_dynamics_365/index.ts#DataverseCloseOpportunityParams", @@ -6155,24 +6061,17 @@ "apps/sim/tools/microsoft_dynamics_365/index.ts#DataverseUpdateRecordParams", "apps/sim/tools/microsoft_dynamics_365/index.ts#DataverseUpdateRecordResponse", "apps/sim/tools/microsoft_dynamics_365/types.ts#DataverseResponse", - "apps/sim/tools/microsoft_excel/types.ts#MicrosoftExcelResponse", - "apps/sim/tools/microsoft_excel/types.ts#MicrosoftExcelV2Response", "apps/sim/tools/microsoft_excel/utils.ts#extractGraphError", "apps/sim/tools/microsoft_excel/utils.ts#resolveSheetAndAddress", - "apps/sim/tools/microsoft_planner/types.ts#MicrosoftPlannerResponse", - "apps/sim/tools/microsoft_teams/types.ts#GraphApiErrorResponse", "apps/sim/tools/microsoft_teams/types.ts#GraphChatMessage", "apps/sim/tools/microsoft_teams/types.ts#GraphDriveItem", - "apps/sim/tools/microsoft_teams/types.ts#MicrosoftTeamsResponse", "apps/sim/tools/microsoft_teams/utils.ts#TeamsMention", "apps/sim/tools/microsoft_teams/utils.ts#resolveMentionsForChannel", "apps/sim/tools/microsoft_teams/utils.ts#resolveMentionsForChat", - "apps/sim/tools/microsoft_word/types.ts#MicrosoftWordResponse", "apps/sim/tools/microsoft_word/utils.ts#GRAPH_BASE_URL", "apps/sim/tools/microsoft_word/utils.ts#getItemBasePath", "apps/sim/tools/millionverifier/hosting.ts#MILLIONVERIFIER_API_KEY_PREFIX", "apps/sim/tools/millionverifier/hosting.ts#MILLIONVERIFIER_CREDIT_USD", - "apps/sim/tools/millionverifier/types.ts#MillionVerifierResponse", "apps/sim/tools/mintlify/types.ts#MintlifyAssistantContextItem", "apps/sim/tools/mintlify/types.ts#MintlifyConversationSource", "apps/sim/tools/mistral/types.ts#MISTRAL_OCR_DIMENSIONS_OUTPUT", @@ -6185,7 +6084,6 @@ "apps/sim/tools/mongodb/types.ts#MongoDBCollectionInfo", "apps/sim/tools/mongodb/types.ts#MongoDBConnectionConfig", "apps/sim/tools/mssql/types.ts#MSSQLConnectionConfig", - "apps/sim/tools/mssql/types.ts#MSSQLResponse", "apps/sim/tools/mssql/types.ts#MSSQL_COLUMN_OUTPUT_PROPERTIES", "apps/sim/tools/mssql/types.ts#MSSQL_FOREIGN_KEY_OUTPUT_PROPERTIES", "apps/sim/tools/mssql/types.ts#MSSQL_INDEX_OUTPUT_PROPERTIES", @@ -6194,10 +6092,8 @@ "apps/sim/tools/netsuite/types.ts#NetSuiteRecordQueryParams", "apps/sim/tools/neverbounce/hosting.ts#NEVERBOUNCE_API_KEY_PREFIX", "apps/sim/tools/neverbounce/hosting.ts#NEVERBOUNCE_CREDIT_USD", - "apps/sim/tools/neverbounce/types.ts#NeverBounceResponse", "apps/sim/tools/new_relic/types.ts#NewRelicBaseParams", "apps/sim/tools/new_relic/types.ts#NewRelicEntityTag", - "apps/sim/tools/new_relic/types.ts#NewRelicResponse", "apps/sim/tools/notion/types.ts#ANNOTATIONS_OUTPUT_PROPERTIES", "apps/sim/tools/notion/types.ts#COMMENT_OUTPUT_PROPERTIES", "apps/sim/tools/notion/types.ts#COVER_OUTPUT", @@ -6213,12 +6109,9 @@ "apps/sim/tools/notion/types.ts#PARTIAL_USER_OUTPUT_PROPERTIES", "apps/sim/tools/notion/types.ts#RICH_TEXT_OUTPUT_PROPERTIES", "apps/sim/tools/notion/types.ts#USER_OUTPUT", - "apps/sim/tools/okta/types.ts#OktaResponse", - "apps/sim/tools/onedrive/types.ts#OneDriveResponse", "apps/sim/tools/onedrive/utils.ts#ExcelArrayValues", "apps/sim/tools/onedrive/utils.ts#ExcelCell", "apps/sim/tools/onedrive/utils.ts#ExcelObjectValues", - "apps/sim/tools/openai/types.ts#DalleResponse", "apps/sim/tools/otter/types.ts#OtterActionItemStatus", "apps/sim/tools/otter/types.ts#OtterProcessStatus", "apps/sim/tools/otter/utils.ts#OTTER_CONVERSATION_INCLUDE_OPTIONS", @@ -6232,15 +6125,10 @@ "apps/sim/tools/outlook/types.ts#OUTLOOK_EVENT_DATETIME_OUTPUT_PROPERTIES", "apps/sim/tools/outlook/types.ts#OUTLOOK_EVENT_ONLINE_MEETING_OUTPUT_PROPERTIES", "apps/sim/tools/outlook/types.ts#OUTLOOK_MESSAGE_BODY_OUTPUT_PROPERTIES", - "apps/sim/tools/outlook/types.ts#OutlookCalendarResponse", - "apps/sim/tools/outlook/types.ts#OutlookExtendedResponse", - "apps/sim/tools/outlook/types.ts#OutlookResponse", "apps/sim/tools/params.ts#resolveToolParamVisibility", - "apps/sim/tools/persona/types.ts#PersonaResponse", "apps/sim/tools/pipedrive/types.ts#PIPEDRIVE_LEAD_VALUE_OUTPUT_PROPERTIES", "apps/sim/tools/pipedrive/types.ts#PIPEDRIVE_MAIL_MESSAGE_OUTPUT_PROPERTIES", "apps/sim/tools/pipedrive/types.ts#PIPEDRIVE_PROJECT_OUTPUT_PROPERTIES", - "apps/sim/tools/pipedrive/types.ts#PipedriveResponse", "apps/sim/tools/pitchbook/utils.ts#appendFilters", "apps/sim/tools/pitchbook/utils.ts#pitchbookErrorMessage", "apps/sim/tools/planetscale/utils.ts#PLANETSCALE_API_ORIGIN", @@ -6249,13 +6137,11 @@ "apps/sim/tools/postgresql/types.ts#POSTGRES_COLUMN_OUTPUT_PROPERTIES", "apps/sim/tools/postgresql/types.ts#POSTGRES_FOREIGN_KEY_OUTPUT_PROPERTIES", "apps/sim/tools/postgresql/types.ts#POSTGRES_INDEX_OUTPUT_PROPERTIES", - "apps/sim/tools/postgresql/types.ts#PostgresResponse", "apps/sim/tools/prospeo/hosting.ts#PROSPEO_API_KEY_PREFIX", "apps/sim/tools/prospeo/types.ts#ProspeoBaseParams", "apps/sim/tools/prospeo/types.ts#ProspeoCompanyData", "apps/sim/tools/prospeo/types.ts#ProspeoPaginationOutput", "apps/sim/tools/prospeo/types.ts#ProspeoPersonData", - "apps/sim/tools/prospeo/types.ts#ProspeoResponse", "apps/sim/tools/quartr/types.ts#QUARTR_AUDIO_METADATA_OUTPUT_PROPERTIES", "apps/sim/tools/quartr/types.ts#QUARTR_EXPANDED_EVENT_OUTPUT_PROPERTIES", "apps/sim/tools/quartr/types.ts#QUARTR_TICKER_OUTPUT_PROPERTIES", @@ -6287,12 +6173,8 @@ "apps/sim/tools/quickbooks/utils.ts#QUICKBOOKS_PURCHASING_ENTITIES", "apps/sim/tools/quickbooks/utils.ts#QUICKBOOKS_SALES_ENTITIES", "apps/sim/tools/quickbooks/values.ts#QUICKBOOKS_GLOBAL_TAX_CALCULATIONS", - "apps/sim/tools/rabbitmq/types.ts#RabbitmqResponse", "apps/sim/tools/railway/types.ts#RailwayAuthParams", - "apps/sim/tools/railway/types.ts#RailwayResponse", "apps/sim/tools/rb2b/types.ts#RB2B_LINKEDIN_COMPANY_OUTPUT_PROPERTIES", - "apps/sim/tools/rb2b/types.ts#Rb2bResponse", - "apps/sim/tools/rds/types.ts#RdsResponse", "apps/sim/tools/reddit/types.ts#COMMENT_OUTPUT_PROPERTIES", "apps/sim/tools/reddit/types.ts#COMMENT_WITH_REPLIES_OUTPUT_PROPERTIES", "apps/sim/tools/reddit/types.ts#EDIT_DATA_OUTPUT_PROPERTIES", @@ -6300,12 +6182,10 @@ "apps/sim/tools/reddit/types.ts#POST_OUTPUT_PROPERTIES", "apps/sim/tools/reddit/types.ts#REPLY_DATA_OUTPUT_PROPERTIES", "apps/sim/tools/reddit/types.ts#RedditMessage", - "apps/sim/tools/reddit/types.ts#RedditResponse", "apps/sim/tools/reddit/types.ts#SUBMIT_POST_DATA_OUTPUT_PROPERTIES", "apps/sim/tools/reducto/types.ts#ReductoBlockType", "apps/sim/tools/revenuecat/types.ts#ENTITLEMENT_OUTPUT_PROPERTIES", "apps/sim/tools/revenuecat/types.ts#OFFERING_PACKAGE_OUTPUT_PROPERTIES", - "apps/sim/tools/revenuecat/types.ts#RevenueCatResponse", "apps/sim/tools/revenuecat/types.ts#SUBSCRIBER_OUTPUT_PROPERTIES", "apps/sim/tools/revenuecat/types.ts#SUBSCRIPTION_OUTPUT_PROPERTIES", "apps/sim/tools/rocketlane/types.ts#PROJECT_COMPANY_OUTPUT_PROPERTIES", @@ -6381,33 +6261,22 @@ "apps/sim/tools/rocketlane/types.ts#mapProjectStatus", "apps/sim/tools/rocketlane/types.ts#mapProjectTeamMembers", "apps/sim/tools/rocketlane/types.ts#mapUserSummary", - "apps/sim/tools/rootly/types.ts#RootlyResponse", "apps/sim/tools/sailpoint/common.ts#assertMutuallyExclusive", - "apps/sim/tools/sailpoint/types.ts#SailPointAcceptedResponse", - "apps/sim/tools/sailpoint/types.ts#SailPointAccessRequestResponse", "apps/sim/tools/sailpoint/types.ts#SailPointAccessRequestTracking", "apps/sim/tools/sailpoint/types.ts#SailPointAccessRequestType", "apps/sim/tools/sailpoint/types.ts#SailPointAccountItemRef", "apps/sim/tools/sailpoint/types.ts#SailPointListOutput", - "apps/sim/tools/sailpoint/types.ts#SailPointListResponse", - "apps/sim/tools/sailpoint/types.ts#SailPointLoadAccountsResponse", - "apps/sim/tools/sailpoint/types.ts#SailPointLoadEntitlementsResponse", "apps/sim/tools/sailpoint/types.ts#SailPointNestedRequestedItem", "apps/sim/tools/sailpoint/types.ts#SailPointPaginationParams", "apps/sim/tools/sailpoint/types.ts#SailPointQueryResultFilter", "apps/sim/tools/sailpoint/types.ts#SailPointRequestedForWithItems", "apps/sim/tools/sailpoint/types.ts#SailPointRequestedItem", "apps/sim/tools/sailpoint/types.ts#SailPointRequestedItemType", - "apps/sim/tools/sailpoint/types.ts#SailPointResourceResponse", "apps/sim/tools/sailpoint/types.ts#SailPointReviewRecommendation", - "apps/sim/tools/sailpoint/types.ts#SailPointSearchAggregateResponse", - "apps/sim/tools/sailpoint/types.ts#SailPointSearchCountResponse", "apps/sim/tools/sailpoint/types.ts#SailPointSearchFilter", "apps/sim/tools/sailpoint/types.ts#SailPointSearchIndex", "apps/sim/tools/sailpoint/types.ts#SailPointSearchQuery", - "apps/sim/tools/sailpoint/types.ts#SailPointSearchResponse", "apps/sim/tools/sailpoint/types.ts#SailPointTask", - "apps/sim/tools/sailpoint/types.ts#SailPointTaskResponse", "apps/sim/tools/sailpoint/types.ts#SailPointTextQuery", "apps/sim/tools/sailpoint/types.ts#SailPointTypeAheadQuery", "apps/sim/tools/salesforce/types.ts#ACCOUNT_OUTPUT_PROPERTIES", @@ -6424,7 +6293,6 @@ "apps/sim/tools/salesforce/types.ts#RESPONSE_METADATA_OUTPUT_PROPERTIES", "apps/sim/tools/salesforce/types.ts#SOBJECTS_OUTPUT", "apps/sim/tools/salesforce/types.ts#SOBJECT_LIST_ITEM_OUTPUT_PROPERTIES", - "apps/sim/tools/salesforce/types.ts#SalesforceResponse", "apps/sim/tools/salesforce/types.ts#TASK_OUTPUT_PROPERTIES", "apps/sim/tools/salesforce/utils.ts#normalizeBoolean", "apps/sim/tools/salesforce/utils.ts#parseDelimitedList", @@ -6433,7 +6301,6 @@ "apps/sim/tools/sap_s4hana/types.ts#ODataMethod", "apps/sim/tools/sap_s4hana/types.ts#SapAuthType", "apps/sim/tools/sap_s4hana/types.ts#SapDeploymentType", - "apps/sim/tools/secrets_manager/types.ts#SecretsManagerBaseResponse", "apps/sim/tools/secrets_manager/types.ts#SecretsManagerConnectionConfig", "apps/sim/tools/secrets_manager/types.ts#SecretsManagerReplicationStatus", "apps/sim/tools/secrets_manager/types.ts#SecretsManagerRotationRules", @@ -6441,7 +6308,6 @@ "apps/sim/tools/semrush/utils.ts#getColumnDef", "apps/sim/tools/sendblue/types.ts#SendblueMessageOutput", "apps/sim/tools/sendblue/types.ts#SendblueSendStyle", - "apps/sim/tools/sentry/types.ts#SentryResponse", "apps/sim/tools/serper/types.ts#ANSWER_BOX_OUTPUT_PROPERTIES", "apps/sim/tools/serper/types.ts#IMAGE_RESULT_OUTPUT_PROPERTIES", "apps/sim/tools/serper/types.ts#KNOWLEDGE_GRAPH_OUTPUT_PROPERTIES", @@ -6458,8 +6324,6 @@ "apps/sim/tools/serper/types.ts#VIDEO_RESULT_OUTPUT_PROPERTIES", "apps/sim/tools/servicenow/constants.ts#CHANGE_STATE", "apps/sim/tools/servicenow/params.ts#inputDisplayValueParam", - "apps/sim/tools/servicenow/types.ts#ServiceNowResponse", - "apps/sim/tools/sharepoint/types.ts#SharepointResponse", "apps/sim/tools/sharepoint/utils.ts#READ_ONLY_LIST_ITEM_FIELDS", "apps/sim/tools/slack/types.ts#ATTACHMENTS_OUTPUT", "apps/sim/tools/slack/types.ts#ATTACHMENT_OUTPUT_PROPERTIES", @@ -6475,7 +6339,6 @@ "apps/sim/tools/slack/types.ts#MESSAGE_THREAD_OUTPUT_PROPERTIES", "apps/sim/tools/slack/types.ts#REACTIONS_OUTPUT", "apps/sim/tools/slack/types.ts#REACTION_OUTPUT_PROPERTIES", - "apps/sim/tools/slack/types.ts#SlackResponse", "apps/sim/tools/slack/types.ts#SlackScheduledMessage", "apps/sim/tools/slack/types.ts#USER_OUTPUT", "apps/sim/tools/slack/utils.ts#mapSlackMessage", @@ -6487,12 +6350,10 @@ "apps/sim/tools/slack_lists/types.ts#SlackListItem", "apps/sim/tools/slack_lists/types.ts#SlackListResponseColumn", "apps/sim/tools/slack_lists/types.ts#SlackListSummary", - "apps/sim/tools/smartlead/types.ts#SmartleadResponse", "apps/sim/tools/snowflake/selector-kinds.ts#SNOWFLAKE_SELECTOR_KINDS", "apps/sim/tools/snowflake/utils.ts#DEFAULT_MAX_ROWS", "apps/sim/tools/snowflake/utils.ts#SIM_MAX_RESULT_ROWS", "apps/sim/tools/snowflake/utils.ts#normalizeStatementTimeout", - "apps/sim/tools/splunk/types.ts#SplunkResponse", "apps/sim/tools/splunk/utils.ts#SPLUNK_JSON_OUTPUT_MODE", "apps/sim/tools/splunk/utils.ts#getEntryAuthor", "apps/sim/tools/sportmonks/types.ts#SPORTMONKS_PAGINATION_PROPERTIES", @@ -6502,7 +6363,6 @@ "apps/sim/tools/sqs/types.ts#SqsBatchErrorEntry", "apps/sim/tools/sqs/types.ts#SqsMessageAttributeInput", "apps/sim/tools/sqs/types.ts#SqsMessageAttributeOutput", - "apps/sim/tools/sqs/types.ts#SqsResponse", "apps/sim/tools/sqs/types.ts#SqsSendMessageBatchEntry", "apps/sim/tools/square/idempotency.ts#SQUARE_IDEMPOTENCY_WINDOW_SECONDS", "apps/sim/tools/square/types.ts#ADDRESS_OUTPUT", @@ -6518,7 +6378,6 @@ "apps/sim/tools/square/types.ts#ORDER_OUTPUT_PROPERTIES", "apps/sim/tools/square/types.ts#PAYMENT_OUTPUT_PROPERTIES", "apps/sim/tools/square/types.ts#REFUND_OUTPUT_PROPERTIES", - "apps/sim/tools/square/types.ts#SquareResponse", "apps/sim/tools/ssh/types.ts#SSHParams", "apps/sim/tools/stagehand/types.ts#STAGEHAND_ACTIONS_OUTPUT", "apps/sim/tools/stagehand/types.ts#STAGEHAND_ACTION_OUTPUT_PROPERTIES", @@ -6526,23 +6385,17 @@ "apps/sim/tools/stagehand/types.ts#STAGEHAND_USAGE_OUTPUT_PROPERTIES", "apps/sim/tools/stripe/idempotency.ts#STRIPE_IDEMPOTENCY_WINDOW_SECONDS", "apps/sim/tools/stripe/idempotency.ts#resolveStripeIdempotencyKey", - "apps/sim/tools/sts/types.ts#STSBaseResponse", - "apps/sim/tools/stt/types.ts#SttBlockResponse", "apps/sim/tools/supabase/types.ts#INTROSPECT_COLUMN_OUTPUT_PROPERTIES", "apps/sim/tools/supabase/types.ts#INTROSPECT_FOREIGN_KEY_OUTPUT_PROPERTIES", "apps/sim/tools/supabase/types.ts#INTROSPECT_INDEX_OUTPUT_PROPERTIES", "apps/sim/tools/supabase/types.ts#INTROSPECT_REFERENCE_OUTPUT_PROPERTIES", "apps/sim/tools/supabase/types.ts#STORAGE_FILE_METADATA_OUTPUT_PROPERTIES", - "apps/sim/tools/supabase/types.ts#SupabaseResponse", "apps/sim/tools/tavily/types.ts#TAVILY_USAGE_OUTPUT_PROPERTIES", - "apps/sim/tools/tavily/types.ts#TavilyResponse", - "apps/sim/tools/telegram/types.ts#TelegramResponse", "apps/sim/tools/telegram/types.ts#TelegramUser", "apps/sim/tools/temporal/types.ts#TemporalBaseParams", "apps/sim/tools/temporal/types.ts#TemporalExecutionSummary", "apps/sim/tools/temporal/types.ts#TemporalHistoryEventSummary", "apps/sim/tools/temporal/types.ts#TemporalPendingActivity", - "apps/sim/tools/temporal/types.ts#TemporalResponse", "apps/sim/tools/temporal/types.ts#TemporalScheduleSummary", "apps/sim/tools/temporal/utils.ts#TemporalRawExecution", "apps/sim/tools/temporal/utils.ts#encodePayload", @@ -6556,8 +6409,6 @@ "apps/sim/tools/tiktok/api-schemas.ts#tiktokApiUserSchema", "apps/sim/tools/tiktok/api-schemas.ts#tiktokApiVideoSchema", "apps/sim/tools/tiktok/types.ts#TikTokBaseParams", - "apps/sim/tools/tiktok/types.ts#TikTokResponse", - "apps/sim/tools/tinybird/types.ts#TinybirdResponse", "apps/sim/tools/tinyfish/hosting.ts#TINYFISH_API_KEY_PREFIX", "apps/sim/tools/tinyfish/types.ts#TinyFishAgentMode", "apps/sim/tools/tinyfish/types.ts#TinyFishBrowserProfile", @@ -6565,15 +6416,12 @@ "apps/sim/tools/tinyfish/types.ts#TinyFishFetchFormat", "apps/sim/tools/tinyfish/types.ts#TinyFishRunStatus", "apps/sim/tools/tinyfish/utils.ts#TINYFISH_API_INTEGRATION", - "apps/sim/tools/trello/types.ts#TrelloResponse", "apps/sim/tools/trigger_dev/types.ts#TriggerDevBatch", "apps/sim/tools/trigger_dev/types.ts#TriggerDevEnvVar", - "apps/sim/tools/trigger_dev/types.ts#TriggerDevResponse", "apps/sim/tools/trigger_dev/types.ts#TriggerDevRunEvent", "apps/sim/tools/trigger_dev/types.ts#TriggerDevSpanEvent", "apps/sim/tools/trigger_dev/utils.ts#mapTriggerDevAttempt", "apps/sim/tools/trigger_dev/utils.ts#parseSerializedOutput", - "apps/sim/tools/typeform/types.ts#TypeformResponse", "apps/sim/tools/types.ts#InternalToolOperationConfig", "apps/sim/tools/uptimerobot/types.ts#UptimeRobotAssignedAlertContact", "apps/sim/tools/uptimerobot/types.ts#UptimeRobotIncidentRootCause", @@ -6591,7 +6439,6 @@ "apps/sim/tools/vanta/types.ts#VantaPersonName", "apps/sim/tools/vanta/types.ts#VantaPersonTasksSummary", "apps/sim/tools/vanta/types.ts#VantaPolicyLatestApprovedVersion", - "apps/sim/tools/vanta/types.ts#VantaResponse", "apps/sim/tools/vanta/types.ts#VantaTestDeactivatedStatusInfo", "apps/sim/tools/vanta/types.ts#VantaTestRemediationStatusInfo", "apps/sim/tools/vanta/types.ts#VantaTestVersion", @@ -6601,9 +6448,6 @@ "apps/sim/tools/vanta/types.ts#VantaVendorDecision", "apps/sim/tools/vanta/types.ts#VantaVendorProcurementRequest", "apps/sim/tools/vanta/types.ts#VantaVulnerabilityDeactivateMetadata", - "apps/sim/tools/video/types.ts#VideoBlockResponse", - "apps/sim/tools/wealthbox/types.ts#WealthboxResponse", - "apps/sim/tools/webflow/types.ts#WebflowResponse", "apps/sim/tools/whatsapp/utils.ts#WHATSAPP_GRAPH_VERSION", "apps/sim/tools/whatsapp/utils.ts#WHATSAPP_MEDIA_TYPES", "apps/sim/tools/wikipedia/types.ts#WIKIPEDIA_CONTENT_URLS_OUTPUT", @@ -6611,7 +6455,6 @@ "apps/sim/tools/wikipedia/types.ts#WIKIPEDIA_CONTENT_URL_OUTPUT_PROPERTIES", "apps/sim/tools/wikipedia/types.ts#WIKIPEDIA_THUMBNAIL_OUTPUT", "apps/sim/tools/wikipedia/types.ts#WIKIPEDIA_THUMBNAIL_OUTPUT_PROPERTIES", - "apps/sim/tools/wikipedia/types.ts#WikipediaResponse", "apps/sim/tools/windchill/types.ts#WINDCHILL_CONTENT_PROPERTIES", "apps/sim/tools/windchill/types.ts#WINDCHILL_DOCUMENT_PROPERTIES", "apps/sim/tools/windchill/types.ts#WINDCHILL_OPERATIONS", @@ -6627,12 +6470,8 @@ "apps/sim/tools/wiza/hosting.ts#WIZA_API_KEY_PREFIX", "apps/sim/tools/wiza/types.ts#WizaIncludeExcludeFilter", "apps/sim/tools/wiza/types.ts#WizaLocationFilter", - "apps/sim/tools/wiza/types.ts#WizaResponse", "apps/sim/tools/wordpress/types.ts#CommentStatus", "apps/sim/tools/wordpress/types.ts#PostStatus", - "apps/sim/tools/wordpress/types.ts#WordPressResponse", - "apps/sim/tools/x/types.ts#XResponse", - "apps/sim/tools/youtube/types.ts#YouTubeResponse", "apps/sim/tools/zendesk/types.ts#CUSTOM_FIELD_OUTPUT_PROPERTIES", "apps/sim/tools/zendesk/types.ts#JOB_RESULT_OUTPUT_PROPERTIES", "apps/sim/tools/zendesk/types.ts#JOB_STATUS_OUTPUT_PROPERTIES", @@ -6641,13 +6480,11 @@ "apps/sim/tools/zendesk/types.ts#SATISFACTION_RATING_OUTPUT_PROPERTIES", "apps/sim/tools/zendesk/types.ts#USER_PHOTO_OUTPUT_PROPERTIES", "apps/sim/tools/zendesk/types.ts#VIA_OUTPUT_PROPERTIES", - "apps/sim/tools/zendesk/types.ts#ZendeskResponse", "apps/sim/tools/zep/types.ts#MESSAGE_OUTPUT", "apps/sim/tools/zep/types.ts#MESSAGE_OUTPUT_PROPERTIES", "apps/sim/tools/zep/types.ts#USER_OUTPUT", "apps/sim/tools/zerobounce/hosting.ts#ZEROBOUNCE_API_KEY_PREFIX", "apps/sim/tools/zerobounce/hosting.ts#ZEROBOUNCE_CREDIT_USD", - "apps/sim/tools/zerobounce/types.ts#ZeroBounceResponse", "apps/sim/tools/zoho_desk/types.ts#ZOHO_DESK_ATTACHMENT_PROPERTIES", "apps/sim/tools/zoom/types.ts#MEETING_SETTINGS_OUTPUT", "apps/sim/tools/zoom/types.ts#MEETING_SETTINGS_OUTPUT_PROPERTIES", @@ -6658,9 +6495,7 @@ "apps/sim/tools/zoom/types.ts#RECURRENCE_OUTPUT", "apps/sim/tools/zoom/types.ts#RECURRENCE_OUTPUT_PROPERTIES", "apps/sim/tools/zoom/types.ts#ZoomMeetingType", - "apps/sim/tools/zoom/types.ts#ZoomResponse", "apps/sim/tools/zoominfo/types.ts#ZoomInfoBaseParams", - "apps/sim/tools/zoominfo/types.ts#ZoomInfoResponse", "apps/sim/triggers/ashby/utils.ts#ashbySetupInstructions", "apps/sim/triggers/ashby/utils.ts#ashbyTriggerOptions", "apps/sim/triggers/ashby/utils.ts#buildApplicationSubmitOutputs=buildApplicationUpdateOutputs", From 55de8765d56648220f2cd618baa2d7e8bebe3e23 Mon Sep 17 00:00:00 2001 From: Waleed Date: Sat, 3 Oct 2026 01:53:38 -0700 Subject: [PATCH 03/12] improvement(tools): stop exporting tool types used only in their own file (#8597) - Drop `export` from 406 tool types referenced only inside their own types.ts - Delete 27 tool types used nowhere, plus 5 private param types only they referenced - Remove the dead `DataverseResponse` re-export from microsoft_dynamics_365/index.ts - Shrink check-unused-exports baseline by 434 entries; `export const` output schemas untouched --- apps/sim/tools/a2a/types.ts | 2 +- apps/sim/tools/affinity/types.ts | 8 +- apps/sim/tools/agentphone/types.ts | 8 +- apps/sim/tools/agiloft/types.ts | 2 +- apps/sim/tools/ahrefs/types.ts | 8 +- apps/sim/tools/appconfig/types.ts | 14 +- apps/sim/tools/athena/types.ts | 16 +- apps/sim/tools/attio/types.ts | 2 +- apps/sim/tools/azure_data_explorer/types.ts | 2 +- apps/sim/tools/azure_devops/types.ts | 16 +- apps/sim/tools/bitbucket/types.ts | 19 +- apps/sim/tools/brex/types.ts | 36 +- apps/sim/tools/buffer/types.ts | 17 +- apps/sim/tools/calendly/types.ts | 6 +- apps/sim/tools/cbinsights/types.ts | 6 - apps/sim/tools/circleback/types.ts | 14 +- apps/sim/tools/clerk/types.ts | 4 +- apps/sim/tools/clickhouse/types.ts | 2 +- apps/sim/tools/clickup/types.ts | 2 +- apps/sim/tools/cloudflare/types.ts | 10 +- apps/sim/tools/cloudtrail/types.ts | 10 +- apps/sim/tools/cloudwatch/types.ts | 6 +- apps/sim/tools/coda/types.ts | 22 +- apps/sim/tools/codepipeline/types.ts | 16 +- apps/sim/tools/convex/types.ts | 2 +- apps/sim/tools/crowdstrike/types.ts | 16 +- apps/sim/tools/crunchbase/types.ts | 24 - apps/sim/tools/databricks/types.ts | 2 +- apps/sim/tools/datadog/types.ts | 20 +- apps/sim/tools/daytona/types.ts | 2 +- apps/sim/tools/deployments/types.ts | 2 +- apps/sim/tools/downdetector/types.ts | 20 +- apps/sim/tools/dropbox/types.ts | 2 +- apps/sim/tools/dropcontact/types.ts | 2 +- apps/sim/tools/dynatrace/types.ts | 4 +- apps/sim/tools/elevenlabs/types.ts | 4 +- apps/sim/tools/enrow/types.ts | 2 +- apps/sim/tools/exa/types.ts | 4 +- apps/sim/tools/findymail/types.ts | 6 +- apps/sim/tools/flint/types.ts | 2 +- apps/sim/tools/gmail/types.ts | 9 - apps/sim/tools/google_appsheet/types.ts | 2 +- apps/sim/tools/google_calendar/types.ts | 42 -- apps/sim/tools/google_contacts/types.ts | 8 - apps/sim/tools/google_drive/types.ts | 2 +- apps/sim/tools/google_meet/types.ts | 8 - apps/sim/tools/google_sheets/types.ts | 2 +- apps/sim/tools/google_vault/types.ts | 4 +- apps/sim/tools/grain/types.ts | 2 +- apps/sim/tools/granola/types.ts | 2 +- apps/sim/tools/harmonic/types.ts | 4 +- apps/sim/tools/hubspot/types.ts | 24 +- apps/sim/tools/iam/types.ts | 12 +- apps/sim/tools/icypeas/types.ts | 2 +- apps/sim/tools/identity_center/types.ts | 2 +- apps/sim/tools/incidentio/types.ts | 36 +- apps/sim/tools/instagram/types.ts | 10 +- apps/sim/tools/instantly/types.ts | 4 +- apps/sim/tools/jotform/types.ts | 8 +- apps/sim/tools/jsm/types.ts | 12 +- apps/sim/tools/jupyter/types.ts | 10 +- apps/sim/tools/lambda/types.ts | 2 +- apps/sim/tools/langsmith/types.ts | 11 +- apps/sim/tools/latex/types.ts | 6 +- apps/sim/tools/linq/types.ts | 4 +- apps/sim/tools/logfire/types.ts | 6 +- apps/sim/tools/logs/types.ts | 2 +- .../sim/tools/microsoft_dynamics_365/index.ts | 1 - .../sim/tools/microsoft_dynamics_365/types.ts | 10 - apps/sim/tools/microsoft_teams/types.ts | 18 - apps/sim/tools/mintlify/types.ts | 4 +- apps/sim/tools/mongodb/types.ts | 4 +- apps/sim/tools/mssql/types.ts | 2 +- apps/sim/tools/netsuite/types.ts | 6 +- apps/sim/tools/new_relic/types.ts | 4 +- apps/sim/tools/otter/types.ts | 4 +- apps/sim/tools/outlook/types.ts | 4 +- apps/sim/tools/prospeo/types.ts | 8 +- apps/sim/tools/quartr/types.ts | 8 +- apps/sim/tools/railway/types.ts | 2 +- apps/sim/tools/reddit/types.ts | 2 +- apps/sim/tools/reducto/types.ts | 2 +- apps/sim/tools/rocketlane/types.ts | 114 ++--- apps/sim/tools/sailpoint/types.ts | 60 +-- apps/sim/tools/sap_concur/types.ts | 4 +- apps/sim/tools/sap_s4hana/types.ts | 6 +- apps/sim/tools/secrets_manager/types.ts | 6 +- apps/sim/tools/sendblue/types.ts | 4 +- apps/sim/tools/slack/types.ts | 2 +- apps/sim/tools/slack_lists/types.ts | 12 +- apps/sim/tools/sportmonks_core/types.ts | 4 +- apps/sim/tools/sqs/types.ts | 8 +- apps/sim/tools/ssh/types.ts | 32 -- apps/sim/tools/telegram/types.ts | 2 +- apps/sim/tools/temporal/types.ts | 10 +- apps/sim/tools/textract/types.ts | 24 +- apps/sim/tools/thrive/types.ts | 4 +- apps/sim/tools/tiktok/types.ts | 2 +- apps/sim/tools/tinyfish/types.ts | 14 +- apps/sim/tools/trigger_dev/types.ts | 8 +- apps/sim/tools/uptimerobot/types.ts | 8 +- apps/sim/tools/vanta/types.ts | 38 +- apps/sim/tools/windchill/types.ts | 10 +- apps/sim/tools/wiza/types.ts | 4 +- apps/sim/tools/wordpress/types.ts | 4 +- apps/sim/tools/zoom/types.ts | 2 +- apps/sim/tools/zoominfo/types.ts | 2 +- scripts/check-unused-exports.baseline.json | 434 ------------------ 108 files changed, 406 insertions(+), 1089 deletions(-) diff --git a/apps/sim/tools/a2a/types.ts b/apps/sim/tools/a2a/types.ts index e2e63be67e5..ed8ed2d1f9a 100644 --- a/apps/sim/tools/a2a/types.ts +++ b/apps/sim/tools/a2a/types.ts @@ -2,7 +2,7 @@ import type { A2AAgentCardOutput, A2ATaskOutput } from '@/lib/a2a/client' import type { UserFile } from '@/executor/types' import type { OutputProperty, ToolResponse } from '@/tools/types' -export interface A2ABaseParams { +interface A2ABaseParams { agentUrl: string apiKey?: string } diff --git a/apps/sim/tools/affinity/types.ts b/apps/sim/tools/affinity/types.ts index 9be1ac34a99..9310991477d 100644 --- a/apps/sim/tools/affinity/types.ts +++ b/apps/sim/tools/affinity/types.ts @@ -8,7 +8,7 @@ export interface AffinityPagination { } /** Cursor outputs every collection tool declares alongside its rows. */ -export interface AffinityCollectionMeta { +interface AffinityCollectionMeta { count: number nextCursor: string | null prevCursor: string | null @@ -26,7 +26,7 @@ export interface AffinityEntityResponse> exten } /** Every tool authenticates with a workspace API key sent as a bearer token. */ -export interface AffinityAuthParams { +interface AffinityAuthParams { apiKey: string } @@ -42,7 +42,7 @@ export interface AffinityFilterParams extends AffinityCursorParams { } /** Collections that can be asked for the total size of the match. */ -export interface AffinityTotalCountParams { +interface AffinityTotalCountParams { totalCount?: boolean } @@ -261,7 +261,7 @@ export interface AffinitySearchByKeywordParams extends AffinityAuthParams { ids?: string | number[] } -export interface AffinityNoteIdParams extends AffinityAuthParams { +interface AffinityNoteIdParams extends AffinityAuthParams { noteId: string } diff --git a/apps/sim/tools/agentphone/types.ts b/apps/sim/tools/agentphone/types.ts index ae034a8a688..487f383d28f 100644 --- a/apps/sim/tools/agentphone/types.ts +++ b/apps/sim/tools/agentphone/types.ts @@ -285,13 +285,7 @@ export interface AgentPhoneSendMessageResult extends ToolResponse { } } -export type AgentPhoneReactionType = - | 'love' - | 'like' - | 'dislike' - | 'laugh' - | 'emphasize' - | 'question' +type AgentPhoneReactionType = 'love' | 'like' | 'dislike' | 'laugh' | 'emphasize' | 'question' export interface AgentPhoneReactToMessageParams { apiKey: string diff --git a/apps/sim/tools/agiloft/types.ts b/apps/sim/tools/agiloft/types.ts index 2ef86af87e6..e260886caba 100644 --- a/apps/sim/tools/agiloft/types.ts +++ b/apps/sim/tools/agiloft/types.ts @@ -34,7 +34,7 @@ export interface AgiloftUpdateRecordParams extends AgiloftBaseParams { } /** Strategies EWDelete accepts for records that depend on the one being deleted. */ -export type AgiloftDeleteRule = +type AgiloftDeleteRule = | 'ERROR_IF_DEPENDANTS' | 'APPLY_DELETE_WHERE_POSSIBLE' | 'DELETE_WHERE_POSSIBLE_OTHERWISE_UNLINK' diff --git a/apps/sim/tools/ahrefs/types.ts b/apps/sim/tools/ahrefs/types.ts index 26b02ca71ae..a2e64f4f569 100644 --- a/apps/sim/tools/ahrefs/types.ts +++ b/apps/sim/tools/ahrefs/types.ts @@ -4,13 +4,13 @@ interface AhrefsBaseParams { apiKey: string } -export type AhrefsTargetMode = 'domain' | 'prefix' | 'subdomains' | 'exact' +type AhrefsTargetMode = 'domain' | 'prefix' | 'subdomains' | 'exact' /** * Historical scope for backlink-profile endpoints (no `date` param on these endpoints). * `since:YYYY-MM-DD` is also valid. */ -export type AhrefsHistory = 'live' | 'all_time' | string +type AhrefsHistory = 'live' | 'all_time' | string export interface AhrefsDomainRatingParams extends AhrefsBaseParams { target: string @@ -239,10 +239,10 @@ export interface AhrefsOrganicCompetitorsResponse extends ToolResponse { } } -export type AhrefsRankTrackerDevice = 'desktop' | 'mobile' +type AhrefsRankTrackerDevice = 'desktop' | 'mobile' /** Rank Tracker search volume calculation mode */ -export type AhrefsVolumeMode = 'monthly' | 'average' +type AhrefsVolumeMode = 'monthly' | 'average' export interface AhrefsRankTrackerOverviewParams extends AhrefsBaseParams { projectId: number diff --git a/apps/sim/tools/appconfig/types.ts b/apps/sim/tools/appconfig/types.ts index 79e10dab1dd..d30d30f5b91 100644 --- a/apps/sim/tools/appconfig/types.ts +++ b/apps/sim/tools/appconfig/types.ts @@ -6,13 +6,13 @@ export interface AppConfigConnectionConfig { secretAccessKey: string } -export interface AppConfigApplication { +interface AppConfigApplication { id: string name: string description: string | null } -export interface AppConfigEnvironment { +interface AppConfigEnvironment { applicationId: string id: string name: string @@ -20,7 +20,7 @@ export interface AppConfigEnvironment { state: string | null } -export interface AppConfigConfigurationProfile { +interface AppConfigConfigurationProfile { applicationId: string id: string name: string @@ -31,7 +31,7 @@ export interface AppConfigConfigurationProfile { validatorTypes: string[] } -export interface AppConfigDeploymentSummary { +interface AppConfigDeploymentSummary { deploymentNumber: number | null configurationName: string | null configurationVersion: string | null @@ -46,7 +46,7 @@ export interface AppConfigDeploymentSummary { versionLabel: string | null } -export interface AppConfigDeploymentDetail { +interface AppConfigDeploymentDetail { applicationId: string environmentId: string deploymentStrategyId: string @@ -61,7 +61,7 @@ export interface AppConfigDeploymentDetail { completedAt: string | null } -export interface AppConfigDeploymentStrategy { +interface AppConfigDeploymentStrategy { id: string name: string description: string | null @@ -72,7 +72,7 @@ export interface AppConfigDeploymentStrategy { replicateTo: string | null } -export interface AppConfigHostedConfigurationVersionSummary { +interface AppConfigHostedConfigurationVersionSummary { applicationId: string | null configurationProfileId: string | null versionNumber: number | null diff --git a/apps/sim/tools/athena/types.ts b/apps/sim/tools/athena/types.ts index 39c46f45948..52fa6dab145 100644 --- a/apps/sim/tools/athena/types.ts +++ b/apps/sim/tools/athena/types.ts @@ -142,7 +142,7 @@ export interface AthenaBatchGetQueryExecutionParams extends AthenaConnectionConf queryExecutionIds: string } -export interface AthenaQueryExecutionSummary { +interface AthenaQueryExecutionSummary { queryExecutionId: string query: string | null state: string | null @@ -161,7 +161,7 @@ export interface AthenaQueryExecutionSummary { outputLocation: string | null } -export interface AthenaUnprocessedQueryExecutionId { +interface AthenaUnprocessedQueryExecutionId { queryExecutionId: string | null errorCode: string | null errorMessage: string | null @@ -181,7 +181,7 @@ export interface AthenaListDatabasesParams extends AthenaConnectionConfig { nextToken?: string } -export interface AthenaDatabase { +interface AthenaDatabase { name: string description: string | null parameters: Record @@ -203,13 +203,13 @@ export interface AthenaListTableMetadataParams extends AthenaConnectionConfig { nextToken?: string } -export interface AthenaColumn { +interface AthenaColumn { name: string type: string | null comment: string | null } -export interface AthenaTableMetadata { +interface AthenaTableMetadata { name: string tableType: string | null createTime: number | null @@ -226,7 +226,7 @@ export interface AthenaListTableMetadataResponse extends ToolResponse { } } -export interface AthenaNamedQuery { +interface AthenaNamedQuery { namedQueryId: string name: string description: string | null @@ -235,7 +235,7 @@ export interface AthenaNamedQuery { workGroup: string | null } -export interface AthenaPreparedStatement { +interface AthenaPreparedStatement { statementName: string queryStatement: string workGroupName: string | null @@ -243,7 +243,7 @@ export interface AthenaPreparedStatement { lastModifiedTime: number | null } -export interface AthenaEngineVersion { +interface AthenaEngineVersion { selectedEngineVersion: string | null effectiveEngineVersion: string | null } diff --git a/apps/sim/tools/attio/types.ts b/apps/sim/tools/attio/types.ts index acb1e5c206f..faa1dc55c60 100644 --- a/apps/sim/tools/attio/types.ts +++ b/apps/sim/tools/attio/types.ts @@ -1,7 +1,7 @@ import type { OutputProperty, ToolResponse } from '@/tools/types' /** Raw Attio note tag shape (workspace-member or record variant) */ -export interface AttioNoteTag { +interface AttioNoteTag { type?: string workspace_member_id?: string object?: string diff --git a/apps/sim/tools/azure_data_explorer/types.ts b/apps/sim/tools/azure_data_explorer/types.ts index 76a86084492..53fb7efa6ab 100644 --- a/apps/sim/tools/azure_data_explorer/types.ts +++ b/apps/sim/tools/azure_data_explorer/types.ts @@ -8,7 +8,7 @@ export interface AzureDataExplorerBaseParams { resource?: string } -export interface AzureDataExplorerColumn { +interface AzureDataExplorerColumn { name: string type: string | null dataType: string | null diff --git a/apps/sim/tools/azure_devops/types.ts b/apps/sim/tools/azure_devops/types.ts index 2f20f9237be..0ea8f0c2305 100644 --- a/apps/sim/tools/azure_devops/types.ts +++ b/apps/sim/tools/azure_devops/types.ts @@ -1,6 +1,6 @@ import type { ToolResponse } from '@/tools/types' -export interface AzureDevOpsBaseParams { +interface AzureDevOpsBaseParams { /** Azure DevOps organization name */ organization: string /** Azure DevOps project name */ @@ -17,7 +17,7 @@ export interface ListPipelinesParams extends AzureDevOpsBaseParams { continuationToken?: string } -export interface AzureDevOpsPipeline { +interface AzureDevOpsPipeline { id: number name: string folder: string @@ -42,7 +42,7 @@ export interface GetPipelineParams extends AzureDevOpsBaseParams { pipelineVersion?: number } -export interface AzureDevOpsPipelineConfiguration { +interface AzureDevOpsPipelineConfiguration { type: string path?: string repository?: { @@ -51,7 +51,7 @@ export interface AzureDevOpsPipelineConfiguration { } } -export interface AzureDevOpsPipelineDetail extends AzureDevOpsPipeline { +interface AzureDevOpsPipelineDetail extends AzureDevOpsPipeline { configuration: AzureDevOpsPipelineConfiguration links: { self: string @@ -74,7 +74,7 @@ export interface ListPipelineRunsParams extends AzureDevOpsBaseParams { pipelineId: number } -export interface AzureDevOpsPipelineRun { +interface AzureDevOpsPipelineRun { id: number name: string state: string @@ -102,7 +102,7 @@ export interface GetPipelineRunParams extends AzureDevOpsBaseParams { runId: number } -export interface AzureDevOpsPipelineRunDetail extends AzureDevOpsPipelineRun { +interface AzureDevOpsPipelineRunDetail extends AzureDevOpsPipelineRun { pipeline: { id: number name: string @@ -131,7 +131,7 @@ export interface ListBuildsParams extends AzureDevOpsBaseParams { branchName?: string } -export interface AzureDevOpsBuild { +interface AzureDevOpsBuild { id: number buildNumber: string status: string @@ -164,7 +164,7 @@ export interface ListBuildLogsParams extends AzureDevOpsBaseParams { buildId: number } -export interface AzureDevOpsBuildLog { +interface AzureDevOpsBuildLog { id: number type: string url: string diff --git a/apps/sim/tools/bitbucket/types.ts b/apps/sim/tools/bitbucket/types.ts index 67edcc8e206..583029a7304 100644 --- a/apps/sim/tools/bitbucket/types.ts +++ b/apps/sim/tools/bitbucket/types.ts @@ -1,10 +1,10 @@ import type { ToolOutputProperty } from '@/tools/types' -export interface BitbucketAuthParams { +interface BitbucketAuthParams { accessToken: string } -export interface BitbucketPaginationParams { +interface BitbucketPaginationParams { nextUrl?: string pageLen?: number } @@ -94,7 +94,7 @@ export interface BitbucketCreatePullRequestParams extends BitbucketRepositoryPar reviewerUuids?: string[] } -export type BitbucketMergeStrategy = +type BitbucketMergeStrategy = | 'merge_commit' | 'squash' | 'fast_forward' @@ -138,15 +138,10 @@ export interface BitbucketListPullRequestCommitStatusesParams sort?: string } -export type BitbucketPipelineListRefType = 'BRANCH' | 'TAG' | 'ANNOTATED_TAG' -export type BitbucketPipelineListSelectorType = - | 'BRANCH' - | 'TAG' - | 'CUSTOM' - | 'PULLREQUESTS' - | 'DEFAULT' -export type BitbucketPipelineTriggerType = 'PUSH' | 'MANUAL' | 'SCHEDULED' | 'PARENT_STEP' -export type BitbucketPipelineStatus = +type BitbucketPipelineListRefType = 'BRANCH' | 'TAG' | 'ANNOTATED_TAG' +type BitbucketPipelineListSelectorType = 'BRANCH' | 'TAG' | 'CUSTOM' | 'PULLREQUESTS' | 'DEFAULT' +type BitbucketPipelineTriggerType = 'PUSH' | 'MANUAL' | 'SCHEDULED' | 'PARENT_STEP' +type BitbucketPipelineStatus = | 'PARSING' | 'PENDING' | 'PAUSED' diff --git a/apps/sim/tools/brex/types.ts b/apps/sim/tools/brex/types.ts index 4ec35be19ae..e1cbdd9342d 100644 --- a/apps/sim/tools/brex/types.ts +++ b/apps/sim/tools/brex/types.ts @@ -6,17 +6,17 @@ export interface BrexPaginationParams { limit?: string } -export interface BrexMoney { +interface BrexMoney { amount: number currency: string | null } -export interface BrexExpenseReceipt { +interface BrexExpenseReceipt { id: string download_uris?: string[] } -export interface BrexExpense { +interface BrexExpense { id: string memo: string | null status: string | null @@ -44,7 +44,7 @@ export interface BrexExpense { dashboard_url: string } -export interface BrexCardTransaction { +interface BrexCardTransaction { id: string card_id: string | null description: string @@ -56,7 +56,7 @@ export interface BrexCardTransaction { expense_id: string | null } -export interface BrexCashTransaction { +interface BrexCashTransaction { id: string description: string amount: BrexMoney | null @@ -66,7 +66,7 @@ export interface BrexCashTransaction { transfer_id: string | null } -export interface BrexCardAccount { +interface BrexCardAccount { id: string status: string | null current_balance: BrexMoney | null @@ -75,7 +75,7 @@ export interface BrexCardAccount { current_statement_period: { start_date: string; end_date: string } } -export interface BrexCashAccount { +interface BrexCashAccount { id: string name: string status: string | null @@ -86,7 +86,7 @@ export interface BrexCashAccount { primary: boolean } -export interface BrexSpendLimitPeriodBalance { +interface BrexSpendLimitPeriodBalance { start_date: string | null end_date: string | null start_time: string | null @@ -95,7 +95,7 @@ export interface BrexSpendLimitPeriodBalance { rollover_amount: BrexMoney | null } -export interface BrexUser { +interface BrexUser { id: string first_name: string last_name: string @@ -107,19 +107,19 @@ export interface BrexUser { title_id: string | null } -export interface BrexDepartment { +interface BrexDepartment { id: string name: string description: string | null } -export interface BrexLocation { +interface BrexLocation { id: string name: string description: string | null } -export interface BrexBudget { +interface BrexBudget { budget_id: string account_id: string name: string @@ -134,7 +134,7 @@ export interface BrexBudget { limit_type: string | null } -export interface BrexSpendLimit { +interface BrexSpendLimit { id: string account_id: string name: string @@ -151,7 +151,7 @@ export interface BrexSpendLimit { authorization_settings: Record | null } -export interface BrexVendor { +interface BrexVendor { id: string company_name: string | null email: string | null @@ -159,7 +159,7 @@ export interface BrexVendor { payment_accounts: unknown[] } -export interface BrexTransfer { +interface BrexTransfer { id: string counterparty: Record | null description: string | null @@ -177,7 +177,7 @@ export interface BrexTransfer { is_ppro_enabled: boolean | null } -export interface BrexCard { +interface BrexCard { id: string owner: Record status: string | null @@ -191,14 +191,14 @@ export interface BrexCard { budget_id: string | null } -export interface BrexStatement { +interface BrexStatement { id: string start_balance: BrexMoney | null end_balance: BrexMoney | null period: { start_date: string; end_date: string } } -export interface BrexTitle { +interface BrexTitle { id: string name: string } diff --git a/apps/sim/tools/buffer/types.ts b/apps/sim/tools/buffer/types.ts index 71d19c81469..834cf9b14f4 100644 --- a/apps/sim/tools/buffer/types.ts +++ b/apps/sim/tools/buffer/types.ts @@ -24,9 +24,8 @@ export const BUFFER_POST_STATUSES = [ 'error', ] as const -export type BufferShareMode = (typeof BUFFER_SHARE_MODES)[number] -export type BufferSchedulingType = (typeof BUFFER_SCHEDULING_TYPES)[number] -export type BufferPostStatus = (typeof BUFFER_POST_STATUSES)[number] +type BufferShareMode = (typeof BUFFER_SHARE_MODES)[number] +type BufferSchedulingType = (typeof BUFFER_SCHEDULING_TYPES)[number] /** Every Buffer tool authenticates with the account API key as a Bearer token. */ interface BufferBaseParams { @@ -97,7 +96,7 @@ export const BUFFER_POST_SELECTION = ` // region Shared object shapes -export interface BufferAsset { +interface BufferAsset { id: string | null type: string mimeType: string @@ -105,7 +104,7 @@ export interface BufferAsset { thumbnail: string } -export interface BufferPostError { +interface BufferPostError { message: string supportUrl: string | null rawError: string | null @@ -145,14 +144,14 @@ export interface BufferChannel { organizationId: string } -export interface BufferOrganization { +interface BufferOrganization { id: string name: string channelCount: number ownerEmail: string } -export interface BufferAccount { +interface BufferAccount { id: string email: string name: string | null @@ -168,13 +167,13 @@ export interface BufferIdea { text: string | null } -export interface BufferIdeaGroup { +interface BufferIdeaGroup { id: string name: string isLocked: boolean } -export interface BufferPageInfo { +interface BufferPageInfo { hasNextPage: boolean endCursor: string | null } diff --git a/apps/sim/tools/calendly/types.ts b/apps/sim/tools/calendly/types.ts index 49f92ec1e61..f6158447456 100644 --- a/apps/sim/tools/calendly/types.ts +++ b/apps/sim/tools/calendly/types.ts @@ -1,7 +1,7 @@ import type { ToolResponse } from '@/tools/types' /** Shared pagination envelope returned by every Calendly list endpoint. */ -export interface CalendlyPagination { +interface CalendlyPagination { count: number next_page: string | null previous_page: string | null @@ -10,7 +10,7 @@ export interface CalendlyPagination { } /** The User resource, returned by both `/users/me` and `/users/{uuid}`. */ -export interface CalendlyUserResource { +interface CalendlyUserResource { uri: string name: string slug: string @@ -409,7 +409,7 @@ export interface CalendlyDeleteWebhookResponse extends ToolResponse { } /** The Invitee resource, returned by the single-invitee read and by the booking endpoint. */ -export interface CalendlyInviteeResource { +interface CalendlyInviteeResource { uri: string email: string name: string diff --git a/apps/sim/tools/cbinsights/types.ts b/apps/sim/tools/cbinsights/types.ts index 57d72602b64..c7887907455 100644 --- a/apps/sim/tools/cbinsights/types.ts +++ b/apps/sim/tools/cbinsights/types.ts @@ -19,12 +19,6 @@ export interface CbInsightsOrgListParams extends CbInsightsAuthParams { orgIds: number[] | string } -/** Every paged list endpoint carries the same opaque continuation token. */ -export interface CbInsightsPagedParams { - limit?: number | string - nextPageToken?: string -} - /** A response page shared by the endpoints that report a total. */ export interface CbInsightsPageInfo { nextPageToken: string | null diff --git a/apps/sim/tools/circleback/types.ts b/apps/sim/tools/circleback/types.ts index ca278a6bdfc..ca89c83c4f9 100644 --- a/apps/sim/tools/circleback/types.ts +++ b/apps/sim/tools/circleback/types.ts @@ -286,7 +286,7 @@ export const CALENDAR_EVENT_OUTPUT_PROPERTIES = { } as const satisfies Record /** A meeting attendee mapped to Sim's output shape. */ -export interface CirclebackAttendee { +interface CirclebackAttendee { profileId: number name: string | null title: string | null @@ -297,14 +297,14 @@ export interface CirclebackAttendee { } /** A mapped tag. */ -export interface CirclebackTag { +interface CirclebackTag { id: number name: string description: string | null } /** An assignee reference on an action item. */ -export interface CirclebackAssignee { +interface CirclebackAssignee { profileId: number name: string | null title: string | null @@ -313,7 +313,7 @@ export interface CirclebackAssignee { } /** A full meeting mapped to Sim's output shape. */ -export interface CirclebackMeeting { +interface CirclebackMeeting { id: string name: string | null createdAt: string @@ -339,7 +339,7 @@ export interface CirclebackMeeting { } /** A standalone action item mapped to Sim's output shape. */ -export interface CirclebackActionItem { +interface CirclebackActionItem { id: number title: string description: string @@ -351,7 +351,7 @@ export interface CirclebackActionItem { } /** A person mapped to Sim's output shape. */ -export interface CirclebackPerson { +interface CirclebackPerson { id: number title: string | null companyId: number | null @@ -362,7 +362,7 @@ export interface CirclebackPerson { } /** An external link mapped to Sim's output shape. */ -export interface CirclebackExternalLink { +interface CirclebackExternalLink { url: string objectType: string type: string diff --git a/apps/sim/tools/clerk/types.ts b/apps/sim/tools/clerk/types.ts index 073508ce5be..72d41e6c59e 100644 --- a/apps/sim/tools/clerk/types.ts +++ b/apps/sim/tools/clerk/types.ts @@ -573,7 +573,7 @@ export interface ClerkDeleteOrganizationResponse extends ToolResponse { * `public_user_data` mirrors the OpenAPI spec (richer than the @clerk/backend SDK's * resource class, which omits `username`/`banned`/the deprecated `profile_image_url`). */ -export interface ClerkOrganizationMembershipPublicUserData { +interface ClerkOrganizationMembershipPublicUserData { user_id: string first_name: string | null last_name: string | null @@ -668,7 +668,7 @@ export interface ClerkRemoveOrganizationMemberResponse extends ToolResponse { /** * Clerk Organization Invitation object. */ -export interface ClerkOrganizationInvitationPublicUserData { +interface ClerkOrganizationInvitationPublicUserData { user_id: string first_name: string | null last_name: string | null diff --git a/apps/sim/tools/clickhouse/types.ts b/apps/sim/tools/clickhouse/types.ts index 063cf3d5155..f8a52802fb4 100644 --- a/apps/sim/tools/clickhouse/types.ts +++ b/apps/sim/tools/clickhouse/types.ts @@ -49,7 +49,7 @@ export const CLICKHOUSE_TABLE_OUTPUT_PROPERTIES = { }, } as const satisfies Record -export interface ClickHouseConnectionConfig { +interface ClickHouseConnectionConfig { host: string port: number database: string diff --git a/apps/sim/tools/clickup/types.ts b/apps/sim/tools/clickup/types.ts index 1960b8e70f6..d485a7d94a4 100644 --- a/apps/sim/tools/clickup/types.ts +++ b/apps/sim/tools/clickup/types.ts @@ -149,7 +149,7 @@ export interface ClickUpChecklist { items: ClickUpChecklistItem[] } -export interface ClickUpTimeEntryLocation { +interface ClickUpTimeEntryLocation { listId: string | null folderId: string | null spaceId: string | null diff --git a/apps/sim/tools/cloudflare/types.ts b/apps/sim/tools/cloudflare/types.ts index 62f837dca1e..88824b2cf80 100644 --- a/apps/sim/tools/cloudflare/types.ts +++ b/apps/sim/tools/cloudflare/types.ts @@ -9,7 +9,7 @@ interface CloudflareBaseParams { * endpoints populate `page`/`per_page`/`total_count`; the Rulesets engine and * R2 use cursors instead, so every field is optional. */ -export interface CloudflareResultInfo { +interface CloudflareResultInfo { page?: number per_page?: number count?: number @@ -35,7 +35,7 @@ export interface CloudflareEnvelope { } /** Raw rule payload inside a ruleset, as returned by the Rulesets API. */ -export interface CloudflareRawRule { +interface CloudflareRawRule { id?: string version?: string action?: string @@ -251,7 +251,7 @@ export interface CloudflareRawDnsRecord { } /** Raw hostname-validation record shared by certificate pack validation fields. */ -export interface CloudflareRawValidationRecord { +interface CloudflareRawValidationRecord { cname?: string cname_target?: string emails?: string[] @@ -263,7 +263,7 @@ export interface CloudflareRawValidationRecord { } /** Raw certificate inside a certificate pack. */ -export interface CloudflareRawCertificate { +interface CloudflareRawCertificate { id?: string hosts?: string[] issuer?: string @@ -296,7 +296,7 @@ export interface CloudflareRawCertificatePack { } /** Raw DNS analytics aggregate block (`totals`, `min`, and `max` share this shape). */ -export interface CloudflareRawDnsAnalyticsAggregate { +interface CloudflareRawDnsAnalyticsAggregate { queryCount?: number uncachedCount?: number staleCount?: number diff --git a/apps/sim/tools/cloudtrail/types.ts b/apps/sim/tools/cloudtrail/types.ts index 1bfa127026a..0746afab2d7 100644 --- a/apps/sim/tools/cloudtrail/types.ts +++ b/apps/sim/tools/cloudtrail/types.ts @@ -6,7 +6,7 @@ interface CloudTrailConnectionConfig { awsSecretAccessKey: string } -export interface CloudTrailAdvancedEventSelector { +interface CloudTrailAdvancedEventSelector { name: string | null fieldSelectors: { field: string @@ -19,7 +19,7 @@ export interface CloudTrailAdvancedEventSelector { }[] } -export interface CloudTrailTrail { +interface CloudTrailTrail { name: string s3BucketName: string | null s3KeyPrefix: string | null @@ -38,7 +38,7 @@ export interface CloudTrailTrail { isOrganizationTrail: boolean | null } -export type CloudTrailLookupAttributeKey = +type CloudTrailLookupAttributeKey = | 'AccessKeyId' | 'EventId' | 'EventName' @@ -58,7 +58,7 @@ export interface CloudTrailLookupEventsParams extends CloudTrailConnectionConfig nextToken?: string } -export interface CloudTrailEvent { +interface CloudTrailEvent { eventId: string | null eventName: string | null readOnly: string | null @@ -231,7 +231,7 @@ export interface CloudTrailCancelQueryResponse extends ToolResponse { } } -export interface CloudTrailEventDataStoreSummary { +interface CloudTrailEventDataStoreSummary { eventDataStoreArn: string | null name: string | null status: string | null diff --git a/apps/sim/tools/cloudwatch/types.ts b/apps/sim/tools/cloudwatch/types.ts index 59e8700cda8..9efd98f8de3 100644 --- a/apps/sim/tools/cloudwatch/types.ts +++ b/apps/sim/tools/cloudwatch/types.ts @@ -164,7 +164,7 @@ export interface CloudWatchPutMetricDataResponse extends ToolResponse { } } -export type CloudWatchMuteDurationUnit = 'minutes' | 'hours' | 'days' +type CloudWatchMuteDurationUnit = 'minutes' | 'hours' | 'days' export interface CloudWatchMuteAlarmParams extends CloudWatchConnectionConfig { muteRuleName: string @@ -196,14 +196,14 @@ export interface CloudWatchUnmuteAlarmResponse extends ToolResponse { } } -export type CloudWatchAlarmHistoryItemType = +type CloudWatchAlarmHistoryItemType = | 'ConfigurationUpdate' | 'StateUpdate' | 'Action' | 'AlarmContributorStateUpdate' | 'AlarmContributorAction' -export type CloudWatchAlarmHistoryScanBy = 'TimestampDescending' | 'TimestampAscending' +type CloudWatchAlarmHistoryScanBy = 'TimestampDescending' | 'TimestampAscending' export interface CloudWatchDescribeAlarmHistoryParams extends CloudWatchConnectionConfig { alarmName?: string diff --git a/apps/sim/tools/coda/types.ts b/apps/sim/tools/coda/types.ts index c96b67c057a..de7a010b7e8 100644 --- a/apps/sim/tools/coda/types.ts +++ b/apps/sim/tools/coda/types.ts @@ -4,7 +4,7 @@ export interface CodaAuthParams { accessToken: string } -export interface CodaPaginationParams { +interface CodaPaginationParams { limit?: number pageToken?: string } @@ -17,7 +17,7 @@ export interface CodaPageParams extends CodaDocParams { pageId: string } -export interface CodaTableParams extends CodaDocParams { +interface CodaTableParams extends CodaDocParams { tableId: string } @@ -25,25 +25,25 @@ export interface CodaRowParams extends CodaTableParams { rowId: string } -export interface CodaIcon { +interface CodaIcon { name: string | null type: string | null browserLink: string | null } -export interface CodaPerson { +interface CodaPerson { name: string | null email: string | null } -export interface CodaPageRef { +interface CodaPageRef { id: string name: string | null href: string | null browserLink: string | null } -export interface CodaTableRef { +interface CodaTableRef { id: string name: string | null tableType: string | null @@ -51,7 +51,7 @@ export interface CodaTableRef { browserLink: string | null } -export interface CodaWorkspaceRef { +interface CodaWorkspaceRef { id: string name: string | null organizationId: string | null @@ -206,7 +206,7 @@ export interface CodaPermission { } } -export type CodaListResponse = ToolResponse & { +type CodaListResponse = ToolResponse & { output: Record & { nextPageToken: string | null } } @@ -242,7 +242,7 @@ export interface CodaDocResponse extends ToolResponse { output: { doc: CodaDoc } } -export interface CodaPageContentParams { +interface CodaPageContentParams { pageType?: string contentFormat?: string content?: string @@ -327,7 +327,7 @@ export interface CodaListPermissionsParams extends CodaDocParams, CodaPagination export type CodaListPermissionsResponse = CodaListResponse<'permissions', CodaPermission> -export type CodaPrincipalType = 'email' | 'group' | 'domain' | 'workspace' | 'anyone' +type CodaPrincipalType = 'email' | 'group' | 'domain' | 'workspace' | 'anyone' export interface CodaAddPermissionParams extends CodaDocParams { access: 'readonly' | 'write' | 'comment' @@ -562,7 +562,7 @@ export interface CodaDeleteFolderResponse extends ToolResponse { export interface CodaListFolderChildrenParams extends CodaFolderParams, CodaPaginationParams {} -export type CodaFolderChild = Omit & { visibility: string } +type CodaFolderChild = Omit & { visibility: string } export type CodaListFolderChildrenResponse = CodaListResponse<'children', CodaFolderChild> diff --git a/apps/sim/tools/codepipeline/types.ts b/apps/sim/tools/codepipeline/types.ts index 6b9bc935146..09ef58e95c4 100644 --- a/apps/sim/tools/codepipeline/types.ts +++ b/apps/sim/tools/codepipeline/types.ts @@ -29,7 +29,7 @@ export interface CodePipelineGetPipelineStateParams extends CodePipelineConnecti pipelineName: string } -export interface CodePipelineActionState { +interface CodePipelineActionState { actionName: string status: string | undefined summary: string | undefined @@ -44,7 +44,7 @@ export interface CodePipelineActionState { entityUrl: string | undefined } -export interface CodePipelineStageState { +interface CodePipelineStageState { stageName: string status: string | undefined pipelineExecutionId: string | undefined @@ -149,7 +149,7 @@ export interface CodePipelineStopExecutionResponse extends ToolResponse { } } -export type CodePipelineRetryMode = 'FAILED_ACTIONS' | 'ALL_ACTIONS' +type CodePipelineRetryMode = 'FAILED_ACTIONS' | 'ALL_ACTIONS' export interface CodePipelineRetryStageExecutionParams extends CodePipelineConnectionConfig { pipelineName: string @@ -164,7 +164,7 @@ export interface CodePipelineRetryStageExecutionResponse extends ToolResponse { } } -export type CodePipelineApprovalStatus = 'Approved' | 'Rejected' +type CodePipelineApprovalStatus = 'Approved' | 'Rejected' export interface CodePipelinePutApprovalResultParams extends CodePipelineConnectionConfig { pipelineName: string @@ -187,7 +187,7 @@ export interface CodePipelineGetPipelineParams extends CodePipelineConnectionCon version?: number } -export interface CodePipelineActionDeclaration { +interface CodePipelineActionDeclaration { name: string category: string owner: string @@ -199,7 +199,7 @@ export interface CodePipelineActionDeclaration { outputArtifacts: string[] } -export interface CodePipelineStageDeclaration { +interface CodePipelineStageDeclaration { stageName: string actions: CodePipelineActionDeclaration[] } @@ -232,7 +232,7 @@ export interface CodePipelineListActionExecutionsParams extends CodePipelineConn nextToken?: string } -export interface CodePipelineActionExecutionDetail { +interface CodePipelineActionExecutionDetail { pipelineExecutionId: string | undefined actionExecutionId: string | undefined pipelineVersion: number | undefined @@ -256,7 +256,7 @@ export interface CodePipelineListActionExecutionsResponse extends ToolResponse { } } -export type CodePipelineTransitionType = 'Inbound' | 'Outbound' +type CodePipelineTransitionType = 'Inbound' | 'Outbound' export interface CodePipelineDisableStageTransitionParams extends CodePipelineConnectionConfig { pipelineName: string diff --git a/apps/sim/tools/convex/types.ts b/apps/sim/tools/convex/types.ts index 96e6cd2b5b1..f1b2d516def 100644 --- a/apps/sim/tools/convex/types.ts +++ b/apps/sim/tools/convex/types.ts @@ -6,7 +6,7 @@ import type { ToolResponse } from '@/tools/types' * @see https://docs.convex.dev/http-api/ */ -export interface ConvexBaseParams { +interface ConvexBaseParams { deploymentUrl: string deployKey: string } diff --git a/apps/sim/tools/crowdstrike/types.ts b/apps/sim/tools/crowdstrike/types.ts index 43a3ff33e41..133532b3982 100644 --- a/apps/sim/tools/crowdstrike/types.ts +++ b/apps/sim/tools/crowdstrike/types.ts @@ -36,7 +36,7 @@ interface CrowdStrikeAggregateRangeSpec { } /** CrowdStrike's `MsaAPIFiltersSpec`: an FQL-per-bucket map plus the catch-all bucket controls. */ -export interface CrowdStrikeAggregateFiltersSpec { +interface CrowdStrikeAggregateFiltersSpec { filters: Record other_bucket?: boolean other_bucket_key?: string @@ -144,7 +144,7 @@ export interface CrowdStrikeGetSensorAggregatesResponse extends ToolResponse { } } -export interface CrowdStrikeApiError { +interface CrowdStrikeApiError { code: number | null id: string | null message: string | null @@ -378,7 +378,7 @@ export interface CrowdStrikeDeleteIndicatorsParams extends CrowdStrikeBaseParams comment?: string } -export interface CrowdStrikeIndicatorMetadata { +interface CrowdStrikeIndicatorMetadata { avHits: number | null companyName: string | null fileDescription: string | null @@ -423,7 +423,7 @@ export interface CrowdStrikeQueryIndicatorsResponse extends ToolResponse { } } -export interface CrowdStrikeIndicatorListResponse extends ToolResponse { +interface CrowdStrikeIndicatorListResponse extends ToolResponse { output: { indicators: CrowdStrikeIndicator[] count: number @@ -454,7 +454,7 @@ export interface CrowdStrikeGetVulnerabilityDetailsParams extends CrowdStrikeBas vulnerabilityIds: string[] } -export interface CrowdStrikeVulnerabilityCve { +interface CrowdStrikeVulnerabilityCve { id: string | null baseScore: number | null severity: string | null @@ -471,13 +471,13 @@ export interface CrowdStrikeVulnerabilityCve { cisaDueDate: string | null } -export interface CrowdStrikeVulnerabilityApp { +interface CrowdStrikeVulnerabilityApp { productNameNormalized: string | null productNameVersion: string | null vendorNormalized: string | null } -export interface CrowdStrikeVulnerabilityHostInfo { +interface CrowdStrikeVulnerabilityHostInfo { hostname: string | null localIp: string | null machineDomain: string | null @@ -490,7 +490,7 @@ export interface CrowdStrikeVulnerabilityHostInfo { groups: string[] } -export interface CrowdStrikeVulnerabilityRemediation { +interface CrowdStrikeVulnerabilityRemediation { id: string | null title: string | null action: string | null diff --git a/apps/sim/tools/crunchbase/types.ts b/apps/sim/tools/crunchbase/types.ts index 0c9925ec7c4..3ae21e044e8 100644 --- a/apps/sim/tools/crunchbase/types.ts +++ b/apps/sim/tools/crunchbase/types.ts @@ -12,30 +12,6 @@ export interface CrunchbaseEntityIdentifier { image_id?: string } -/** Location identifiers add a `location_type` on top of the entity identifier. */ -export interface CrunchbaseLocationIdentifier extends CrunchbaseEntityIdentifier { - location_type?: string -} - -/** A date whose known precision may be coarser than a day. */ -export interface CrunchbaseDateWithPrecision { - precision: 'none' | 'year' | 'month' | 'day' - value?: string -} - -/** A monetary amount, normalized to USD alongside its native currency. */ -export interface CrunchbaseMoney { - currency: string - value: number - value_usd?: number -} - -/** A url paired with optional display text. */ -export interface CrunchbaseLink { - value?: string - label?: string -} - /** * Entity properties are shaped by the requested `field_ids`, so the payload is * a dynamic bag rather than a fixed record. diff --git a/apps/sim/tools/databricks/types.ts b/apps/sim/tools/databricks/types.ts index 56f53125582..daba6a94526 100644 --- a/apps/sim/tools/databricks/types.ts +++ b/apps/sim/tools/databricks/types.ts @@ -185,7 +185,7 @@ export interface DatabricksGetRunOutputResponse extends ToolResponse { } /** Shared cluster shape returned by list_clusters and get_cluster */ -export interface DatabricksCluster { +interface DatabricksCluster { clusterId: string clusterName: string state: string diff --git a/apps/sim/tools/datadog/types.ts b/apps/sim/tools/datadog/types.ts index 279594c2e5e..587f0c8674b 100644 --- a/apps/sim/tools/datadog/types.ts +++ b/apps/sim/tools/datadog/types.ts @@ -43,9 +43,9 @@ export interface DatadogV2Resource { attributes?: TAttributes } -export type MetricType = 'gauge' | 'rate' | 'count' | 'distribution' +type MetricType = 'gauge' | 'rate' | 'count' | 'distribution' -export interface MetricPoint { +interface MetricPoint { timestamp: number value: number } @@ -140,7 +140,7 @@ export interface CreateEventParams extends DatadogWriteOnlyParams { dateHappened?: number } -export interface EventData { +interface EventData { id?: number title?: string text?: string @@ -443,9 +443,9 @@ export interface CancelDowntimeResponse extends ToolResponse { output: CancelDowntimeOutput } -export type SloType = 'metric' | 'monitor' | 'time_slice' +type SloType = 'metric' | 'monitor' | 'time_slice' -export type SloTimeframe = '7d' | '30d' | '90d' | 'custom' +type SloTimeframe = '7d' | '30d' | '90d' | 'custom' interface SloThreshold { timeframe: SloTimeframe @@ -604,7 +604,7 @@ export interface GetSloHistoryResponse extends ToolResponse { output: GetSloHistoryOutput } -export type DashboardLayoutType = 'ordered' | 'free' +type DashboardLayoutType = 'ordered' | 'free' interface DashboardData { id?: string @@ -696,7 +696,7 @@ export interface DeleteDashboardResponse extends ToolResponse { output: DeleteDashboardOutput } -export type SyntheticsTestPauseStatus = 'live' | 'paused' +type SyntheticsTestPauseStatus = 'live' | 'paused' export interface SyntheticsTestData { public_id?: string @@ -830,9 +830,9 @@ export interface UpdateSyntheticsStatusResponse extends ToolResponse { output: UpdateSyntheticsStatusOutput } -export type SecuritySignalState = 'open' | 'archived' | 'under_review' +type SecuritySignalState = 'open' | 'archived' | 'under_review' -export type SecuritySignalArchiveReason = +type SecuritySignalArchiveReason = | 'none' | 'false_positive' | 'testing_or_maintenance' @@ -1027,7 +1027,7 @@ export interface ListServicesResponse extends ToolResponse { output: ListServicesOutput } -export type IncidentSeverity = 'UNKNOWN' | 'SEV-0' | 'SEV-1' | 'SEV-2' | 'SEV-3' | 'SEV-4' | 'SEV-5' +type IncidentSeverity = 'UNKNOWN' | 'SEV-0' | 'SEV-1' | 'SEV-2' | 'SEV-3' | 'SEV-4' | 'SEV-5' interface IncidentFieldValue { type?: string diff --git a/apps/sim/tools/daytona/types.ts b/apps/sim/tools/daytona/types.ts index 491c7dfbfff..045c6cff0d0 100644 --- a/apps/sim/tools/daytona/types.ts +++ b/apps/sim/tools/daytona/types.ts @@ -18,7 +18,7 @@ export interface DaytonaSandboxSummary { updatedAt: string | null } -export interface DaytonaFileInfo { +interface DaytonaFileInfo { name: string isDir: boolean size: number diff --git a/apps/sim/tools/deployments/types.ts b/apps/sim/tools/deployments/types.ts index 46b120d02bf..b4f861313dd 100644 --- a/apps/sim/tools/deployments/types.ts +++ b/apps/sim/tools/deployments/types.ts @@ -24,7 +24,7 @@ export interface DeploymentsGetVersionParams { version: number } -export interface DeploymentVersionSummary { +interface DeploymentVersionSummary { id: string version: number name: string | null diff --git a/apps/sim/tools/downdetector/types.ts b/apps/sim/tools/downdetector/types.ts index 16c909a498c..6f877ecd4aa 100644 --- a/apps/sim/tools/downdetector/types.ts +++ b/apps/sim/tools/downdetector/types.ts @@ -9,7 +9,7 @@ interface DowndetectorBaseParams { } /** Company summary returned by the search endpoint (restricted field set). */ -export interface DowndetectorCompanySummary { +interface DowndetectorCompanySummary { id: number | null name: string | null slug: string | null @@ -19,7 +19,7 @@ export interface DowndetectorCompanySummary { } /** Full company detail returned by the company endpoint. */ -export interface DowndetectorCompany { +interface DowndetectorCompany { id: number | null name: string | null slug: string | null @@ -36,7 +36,7 @@ export interface DowndetectorCompany { } /** A single reported indicator (e.g. "App crashing", "Login") for a company. */ -export interface DowndetectorIndicator { +interface DowndetectorIndicator { slug: string | null indicator: string | null key: string | null @@ -45,7 +45,7 @@ export interface DowndetectorIndicator { } /** A time bucket of report counts. */ -export interface DowndetectorReportBucket { +interface DowndetectorReportBucket { pointInTime: string | null total: number | null indicators: number | null @@ -67,14 +67,14 @@ export interface DowndetectorIncident { } /** A Downdetector category (e.g. "Telecom", "Gaming"). */ -export interface DowndetectorCategory { +interface DowndetectorCategory { id: number | null name: string | null slug: string | null } /** A Downdetector site (regional status page domain). */ -export interface DowndetectorSite { +interface DowndetectorSite { id: number | null name: string | null domain: string | null @@ -82,7 +82,7 @@ export interface DowndetectorSite { } /** Company summary including current status (returned by the site companies endpoint). */ -export interface DowndetectorSiteCompany { +interface DowndetectorSiteCompany { id: number | null name: string | null slug: string | null @@ -93,7 +93,7 @@ export interface DowndetectorSiteCompany { } /** An event (e.g. a detected outage) published for a company. */ -export interface DowndetectorEvent { +interface DowndetectorEvent { id: number | null title: string | null body: string | null @@ -110,7 +110,7 @@ export interface DowndetectorEvent { } /** Incident attribution detail for a company. */ -export interface DowndetectorAttribution { +interface DowndetectorAttribution { attribution: number | null attributionCalculatedAt: string | null userImpact: number | null @@ -122,7 +122,7 @@ export interface DowndetectorAttribution { } /** A Downdetector provider (ISP / network operator). */ -export interface DowndetectorProvider { +interface DowndetectorProvider { id: number | null name: string | null downdetectorId: number | null diff --git a/apps/sim/tools/dropbox/types.ts b/apps/sim/tools/dropbox/types.ts index a104bde0b51..a3ec6f34b68 100644 --- a/apps/sim/tools/dropbox/types.ts +++ b/apps/sim/tools/dropbox/types.ts @@ -31,7 +31,7 @@ interface DropboxDeletedMetadata { path_lower?: string } -export type DropboxMetadata = DropboxFileMetadata | DropboxFolderMetadata | DropboxDeletedMetadata +type DropboxMetadata = DropboxFileMetadata | DropboxFolderMetadata | DropboxDeletedMetadata interface DropboxSharedLinkMetadata { url: string diff --git a/apps/sim/tools/dropcontact/types.ts b/apps/sim/tools/dropcontact/types.ts index 96e63ee501d..0f74d7266ba 100644 --- a/apps/sim/tools/dropcontact/types.ts +++ b/apps/sim/tools/dropcontact/types.ts @@ -1,6 +1,6 @@ import type { OutputProperty, ToolResponse } from '@/tools/types' -export interface DropcontactBaseParams { +interface DropcontactBaseParams { apiKey: string } diff --git a/apps/sim/tools/dynatrace/types.ts b/apps/sim/tools/dynatrace/types.ts index 9b4dba8817c..ddd9b13674c 100644 --- a/apps/sim/tools/dynatrace/types.ts +++ b/apps/sim/tools/dynatrace/types.ts @@ -1,7 +1,7 @@ import type { ToolResponse } from '@/tools/types' /** Credentials every Dynatrace Environment API v2 call needs. */ -export interface DynatraceBaseParams { +interface DynatraceBaseParams { environmentUrl: string apiToken: string } @@ -110,7 +110,7 @@ export interface DynatraceEvent { } /** One series of a metric query result. */ -export interface DynatraceMetricSeries { +interface DynatraceMetricSeries { dimensions: string[] dimensionMap: Record timestamps: number[] diff --git a/apps/sim/tools/elevenlabs/types.ts b/apps/sim/tools/elevenlabs/types.ts index f9d7d16842e..c681d71e78e 100644 --- a/apps/sim/tools/elevenlabs/types.ts +++ b/apps/sim/tools/elevenlabs/types.ts @@ -18,7 +18,7 @@ export interface ElevenLabsTtsResponse extends ToolResponse { } /** Voice settings shared by get/edit settings and embedded voice objects. */ -export interface ElevenLabsVoiceSettings { +interface ElevenLabsVoiceSettings { stability?: number | null similarity_boost?: number | null style?: number | null @@ -97,7 +97,7 @@ export interface ElevenLabsEditVoiceSettingsResponse extends ToolResponse { } } -export interface ElevenLabsModelLanguage { +interface ElevenLabsModelLanguage { languageId: string | null name: string | null } diff --git a/apps/sim/tools/enrow/types.ts b/apps/sim/tools/enrow/types.ts index ad8f620bde3..828ea75b14a 100644 --- a/apps/sim/tools/enrow/types.ts +++ b/apps/sim/tools/enrow/types.ts @@ -1,7 +1,7 @@ import type { OutputProperty, ToolResponse } from '@/tools/types' /** Common params shared by all Enrow tool operations. */ -export interface EnrowBaseParams { +interface EnrowBaseParams { apiKey: string } diff --git a/apps/sim/tools/exa/types.ts b/apps/sim/tools/exa/types.ts index d5afb07181d..36168245026 100644 --- a/apps/sim/tools/exa/types.ts +++ b/apps/sim/tools/exa/types.ts @@ -26,7 +26,7 @@ export interface ExaFreshnessParams { * documented set; `neural`, `keyword`, and `hybrid` are legacy values the API * still honors, kept so workflows saved against the old dropdown keep running. */ -export type ExaSearchType = +type ExaSearchType = | 'instant' | 'fast' | 'auto' @@ -213,7 +213,7 @@ export interface ExaAnswerResponse extends ToolResponse { } /** Effort levels the Agent API accepts, trading cost against depth. */ -export type ExaAgentEffort = 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'auto' +type ExaAgentEffort = 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'auto' export interface ExaAgentParams extends ExaBaseParams { query: string diff --git a/apps/sim/tools/findymail/types.ts b/apps/sim/tools/findymail/types.ts index 1150c4cb340..27a4d4ada90 100644 --- a/apps/sim/tools/findymail/types.ts +++ b/apps/sim/tools/findymail/types.ts @@ -62,7 +62,7 @@ export const FINDYMAIL_EMPLOYEES_OUTPUT: OutputProperty = { }, } -export interface FindymailContact { +interface FindymailContact { name: string email: string domain: string @@ -164,7 +164,7 @@ export interface FindymailFindEmployeesParams extends FindymailBaseParams { count?: number } -export interface FindymailEmployee { +interface FindymailEmployee { name: string linkedinUrl: string | null companyWebsite: string | null @@ -193,7 +193,7 @@ export interface FindymailSearchTechnologiesParams extends FindymailBaseParams { q: string } -export interface FindymailTechnology { +interface FindymailTechnology { name: string category: string | null subcategory: string | null diff --git a/apps/sim/tools/flint/types.ts b/apps/sim/tools/flint/types.ts index f6fa7320df6..26d7a941ba5 100644 --- a/apps/sim/tools/flint/types.ts +++ b/apps/sim/tools/flint/types.ts @@ -44,7 +44,7 @@ export interface FlintTaskPage { /** * Shared output shape of the two task-creation endpoints. */ -export interface FlintTaskCreatedOutput { +interface FlintTaskCreatedOutput { taskId: string | null status: string | null createdAt: string | null diff --git a/apps/sim/tools/gmail/types.ts b/apps/sim/tools/gmail/types.ts index 9843c7aa626..25396a7ff80 100644 --- a/apps/sim/tools/gmail/types.ts +++ b/apps/sim/tools/gmail/types.ts @@ -52,15 +52,6 @@ export interface GmailLabelParams extends BaseGmailParams { labelIds: string } -// Union type for all Gmail tool parameters -export type GmailToolParams = - | GmailSendParams - | GmailReadParams - | GmailSearchParams - | GmailMoveParams - | GmailMarkReadParams - | GmailLabelParams - // Response metadata interface BaseGmailMetadata { id?: string diff --git a/apps/sim/tools/google_appsheet/types.ts b/apps/sim/tools/google_appsheet/types.ts index ea35e05ffca..c56e62b22f6 100644 --- a/apps/sim/tools/google_appsheet/types.ts +++ b/apps/sim/tools/google_appsheet/types.ts @@ -7,7 +7,7 @@ interface GoogleAppsheetBaseParams { region?: string } -export type GoogleAppsheetRow = Record +type GoogleAppsheetRow = Record // Find Rows Types export interface GoogleAppsheetFindParams extends GoogleAppsheetBaseParams { diff --git a/apps/sim/tools/google_calendar/types.ts b/apps/sim/tools/google_calendar/types.ts index b0adef6fc71..62e59b2ef66 100644 --- a/apps/sim/tools/google_calendar/types.ts +++ b/apps/sim/tools/google_calendar/types.ts @@ -87,21 +87,6 @@ export interface GoogleCalendarRespondParams extends BaseGoogleCalendarParams { sendUpdates?: 'all' | 'externalOnly' | 'none' } -interface GoogleCalendarMoveParams extends BaseGoogleCalendarParams { - eventId: string - destinationCalendarId: string - sendUpdates?: 'all' | 'externalOnly' | 'none' -} - -interface GoogleCalendarInstancesParams extends BaseGoogleCalendarParams { - eventId: string - timeMin?: string - timeMax?: string - maxResults?: number - pageToken?: string - showDeleted?: boolean -} - export interface GoogleCalendarFreeBusyParams { accessToken: string calendarIds: string @@ -110,15 +95,6 @@ export interface GoogleCalendarFreeBusyParams { timeZone?: string } -interface GoogleCalendarListCalendarsParams { - accessToken: string - minAccessRole?: 'freeBusyReader' | 'reader' | 'writer' | 'owner' - maxResults?: number - pageToken?: string - showDeleted?: boolean - showHidden?: boolean -} - export interface GoogleCalendarCreateCalendarParams { accessToken: string summary: string @@ -153,24 +129,6 @@ export interface GoogleCalendarUnshareCalendarParams { ruleId: string } -export type GoogleCalendarToolParams = - | GoogleCalendarCreateParams - | GoogleCalendarListParams - | GoogleCalendarGetParams - | GoogleCalendarUpdateParams - | GoogleCalendarDeleteParams - | GoogleCalendarQuickAddParams - | GoogleCalendarInviteParams - | GoogleCalendarRespondParams - | GoogleCalendarMoveParams - | GoogleCalendarInstancesParams - | GoogleCalendarFreeBusyParams - | GoogleCalendarListCalendarsParams - | GoogleCalendarCreateCalendarParams - | GoogleCalendarShareCalendarParams - | GoogleCalendarListAclParams - | GoogleCalendarUnshareCalendarParams - interface EventMetadata { id: string htmlLink: string diff --git a/apps/sim/tools/google_contacts/types.ts b/apps/sim/tools/google_contacts/types.ts index 03240756fe5..e6b4fd9bac9 100644 --- a/apps/sim/tools/google_contacts/types.ts +++ b/apps/sim/tools/google_contacts/types.ts @@ -58,14 +58,6 @@ export interface GoogleContactsSearchParams extends BaseGoogleContactsParams { pageSize?: number } -export type GoogleContactsToolParams = - | GoogleContactsCreateParams - | GoogleContactsGetParams - | GoogleContactsListParams - | GoogleContactsUpdateParams - | GoogleContactsDeleteParams - | GoogleContactsSearchParams - interface ContactMetadata { resourceName: string etag: string diff --git a/apps/sim/tools/google_drive/types.ts b/apps/sim/tools/google_drive/types.ts index efd7b497e53..e7f5248498d 100644 --- a/apps/sim/tools/google_drive/types.ts +++ b/apps/sim/tools/google_drive/types.ts @@ -185,7 +185,7 @@ export interface GoogleDriveRevision { } /** A threaded reply attached to a comment. */ -export interface GoogleDriveCommentReply { +interface GoogleDriveCommentReply { id?: string kind?: string createdTime?: string diff --git a/apps/sim/tools/google_meet/types.ts b/apps/sim/tools/google_meet/types.ts index bab3bf5b7d1..791115d2f84 100644 --- a/apps/sim/tools/google_meet/types.ts +++ b/apps/sim/tools/google_meet/types.ts @@ -36,14 +36,6 @@ export interface GoogleMeetListParticipantsParams extends BaseGoogleMeetParams { pageToken?: string } -export type GoogleMeetToolParams = - | GoogleMeetCreateSpaceParams - | GoogleMeetGetSpaceParams - | GoogleMeetEndConferenceParams - | GoogleMeetListConferenceRecordsParams - | GoogleMeetGetConferenceRecordParams - | GoogleMeetListParticipantsParams - export interface GoogleMeetApiSpaceResponse { name: string meetingUri: string diff --git a/apps/sim/tools/google_sheets/types.ts b/apps/sim/tools/google_sheets/types.ts index 5357c0c7e8c..8bc3731334f 100644 --- a/apps/sim/tools/google_sheets/types.ts +++ b/apps/sim/tools/google_sheets/types.ts @@ -73,7 +73,7 @@ export interface GoogleSheetsToolParams { // V2 Types - with explicit sheetName parameter -export interface GoogleSheetsFilterInfo { +interface GoogleSheetsFilterInfo { /** Whether row filtering was actually applied to the data rows. */ applied: boolean /** The column header the filter targeted. */ diff --git a/apps/sim/tools/google_vault/types.ts b/apps/sim/tools/google_vault/types.ts index daf8207ca21..f79bd5e1e59 100644 --- a/apps/sim/tools/google_vault/types.ts +++ b/apps/sim/tools/google_vault/types.ts @@ -41,9 +41,7 @@ export interface GoogleVaultListMattersExportParams extends GoogleVaultCommonPar exportId?: string } -export type GoogleVaultHoldView = 'BASIC_HOLD' | 'FULL_HOLD' - -export type GoogleVaultCorpus = 'MAIL' | 'DRIVE' | 'GROUPS' | 'HANGOUTS_CHAT' | 'VOICE' +type GoogleVaultCorpus = 'MAIL' | 'DRIVE' | 'GROUPS' | 'HANGOUTS_CHAT' | 'VOICE' export interface GoogleVaultCreateMattersHoldsParams extends GoogleVaultCommonParams { holdName: string diff --git a/apps/sim/tools/grain/types.ts b/apps/sim/tools/grain/types.ts index d89ac1282c1..c396701a1b3 100644 --- a/apps/sim/tools/grain/types.ts +++ b/apps/sim/tools/grain/types.ts @@ -249,7 +249,7 @@ export const GRAIN_HOOK_TYPES = [ 'upload_status', ] as const -export type GrainHookType = (typeof GRAIN_HOOK_TYPES)[number] +type GrainHookType = (typeof GRAIN_HOOK_TYPES)[number] /** Hook object returned by the Grain v2 hooks endpoints. */ interface GrainHookV2 { diff --git a/apps/sim/tools/granola/types.ts b/apps/sim/tools/granola/types.ts index c995ad57613..c2ff70e9dd2 100644 --- a/apps/sim/tools/granola/types.ts +++ b/apps/sim/tools/granola/types.ts @@ -162,7 +162,7 @@ export interface GranolaListAuditEventsResponse extends ToolResponse { } /** The webhook endpoint shape shared by the create, list, and update tools. */ -export interface GranolaWebhookEndpointOutput { +interface GranolaWebhookEndpointOutput { id: string url: string urlRedacted: boolean diff --git a/apps/sim/tools/harmonic/types.ts b/apps/sim/tools/harmonic/types.ts index 0a4a82b27f7..55c4301cad5 100644 --- a/apps/sim/tools/harmonic/types.ts +++ b/apps/sim/tools/harmonic/types.ts @@ -41,7 +41,7 @@ export interface HarmonicSavedSearch { updatedAt: string } -export interface HarmonicContactMetadata { +interface HarmonicContactMetadata { emails?: unknown phone_numbers?: unknown exec_emails?: unknown @@ -56,7 +56,7 @@ export interface HarmonicLocationMetadata { country?: unknown } -export interface HarmonicSocialMetadata { +interface HarmonicSocialMetadata { url?: unknown } diff --git a/apps/sim/tools/hubspot/types.ts b/apps/sim/tools/hubspot/types.ts index 9cfa26c70c6..ffb95fd5d5c 100644 --- a/apps/sim/tools/hubspot/types.ts +++ b/apps/sim/tools/hubspot/types.ts @@ -900,7 +900,7 @@ interface HubSpotCrmObject { } /** @deprecated Use HubSpotCrmObject instead */ -export type HubSpotContact = HubSpotCrmObject +type HubSpotContact = HubSpotCrmObject interface HubSpotPaging { next?: { @@ -1034,8 +1034,6 @@ export interface HubSpotSearchContactsParams { after?: string } -// Companies (same structure as contacts) -export type HubSpotCompany = HubSpotCrmObject export type HubSpotListCompaniesParams = HubSpotListContactsParams export type HubSpotListCompaniesResponse = Omit & { output: { @@ -1090,8 +1088,6 @@ export interface HubSpotSearchCompaniesResponse extends ToolResponse { } } -// Deals -export type HubSpotDeal = HubSpotCrmObject export type HubSpotListDealsParams = HubSpotListContactsParams export type HubSpotListDealsResponse = Omit & { output: { @@ -1126,8 +1122,6 @@ export interface HubSpotSearchDealsResponse extends ToolResponse { } } -// Tickets -export type HubSpotTicket = HubSpotCrmObject export type HubSpotListTicketsParams = HubSpotListContactsParams export type HubSpotListTicketsResponse = ToolResponse & { output: { @@ -1165,7 +1159,7 @@ export interface HubSpotSearchTicketsResponse extends ToolResponse { } // Line Items -export type HubSpotLineItem = HubSpotCrmObject +type HubSpotLineItem = HubSpotCrmObject export type HubSpotListLineItemsParams = HubSpotListContactsParams export type HubSpotListLineItemsResponse = ToolResponse & { output: { @@ -1193,7 +1187,7 @@ export type HubSpotUpdateLineItemResponse = ToolResponse & { } // Quotes -export type HubSpotQuote = HubSpotCrmObject +type HubSpotQuote = HubSpotCrmObject export type HubSpotListQuotesParams = HubSpotListContactsParams export type HubSpotListQuotesResponse = ToolResponse & { output: { @@ -1210,8 +1204,6 @@ export type HubSpotGetQuoteResponse = ToolResponse & { output: { quote: HubSpotContact; quoteId: string; success: boolean } } -// Appointments -export type HubSpotAppointment = HubSpotCrmObject export type HubSpotListAppointmentsParams = HubSpotListContactsParams export type HubSpotListAppointmentsResponse = ToolResponse & { output: { @@ -1238,8 +1230,6 @@ export type HubSpotUpdateAppointmentResponse = ToolResponse & { output: { appointment: HubSpotContact; appointmentId: string; success: boolean } } -// Carts -export type HubSpotCart = HubSpotCrmObject export type HubSpotListCartsParams = HubSpotListContactsParams export type HubSpotListCartsResponse = ToolResponse & { output: { @@ -1389,8 +1379,6 @@ export interface HubSpotCreateListResponse extends ToolResponse { } } -// Notes -export type HubSpotNote = HubSpotCrmObject export type HubSpotCreateNoteParams = HubSpotCreateContactParams export type HubSpotCreateNoteResponse = ToolResponse & { output: { note: HubSpotContact; noteId: string; success: boolean } @@ -1419,8 +1407,6 @@ export interface HubSpotSearchNotesResponse extends ToolResponse { } } -// Emails -export type HubSpotEmail = HubSpotCrmObject export type HubSpotCreateEmailParams = HubSpotCreateContactParams export type HubSpotCreateEmailResponse = ToolResponse & { output: { email: HubSpotContact; emailId: string; success: boolean } @@ -1552,7 +1538,7 @@ export interface HubSpotDeleteAssociationResponse extends ToolResponse { } } -export interface HubSpotAssociationLabel { +interface HubSpotAssociationLabel { category: string typeId: number label: string | null @@ -1618,7 +1604,7 @@ export interface HubSpotDeleteLineItemResponse extends ToolResponse { } // List memberships -export interface HubSpotListMembership { +interface HubSpotListMembership { recordId: string membershipTimestamp?: string } diff --git a/apps/sim/tools/iam/types.ts b/apps/sim/tools/iam/types.ts index 018a9e3ed52..873ff5f20da 100644 --- a/apps/sim/tools/iam/types.ts +++ b/apps/sim/tools/iam/types.ts @@ -67,7 +67,7 @@ export interface IAMDetachRolePolicyParams extends IAMConnectionConfig { policyArn: string } -export type IAMPolicyScope = 'All' | 'AWS' | 'Local' +type IAMPolicyScope = 'All' | 'AWS' | 'Local' export interface IAMListPoliciesParams extends IAMConnectionConfig { scope?: IAMPolicyScope | null @@ -97,7 +97,7 @@ export interface IAMListAccessKeysParams extends IAMConnectionConfig { } /** AWS accepts `Expired` on the wire, but only `Active`/`Inactive` are settable. */ -export type IAMAccessKeyStatus = 'Active' | 'Inactive' +type IAMAccessKeyStatus = 'Active' | 'Inactive' export interface IAMUpdateAccessKeyParams extends IAMConnectionConfig { accessKeyIdToUpdate: string @@ -303,7 +303,7 @@ export interface IAMListAttachedUserPoliciesParams extends IAMConnectionConfig { marker?: string | null } -export type IAMContextKeyType = +type IAMContextKeyType = | 'binary' | 'binaryList' | 'boolean' @@ -346,7 +346,7 @@ export interface IAMListAttachedPoliciesResponse extends ToolResponse { error?: string } -export interface IAMSimulateMatchedStatement { +interface IAMSimulateMatchedStatement { sourcePolicyId: string sourcePolicyType: string } @@ -356,7 +356,7 @@ export interface IAMSimulateMatchedStatement { * action regardless of how many resource ARNs were simulated, so this is the only place * a per-ARN decision is reported. */ -export interface IAMSimulateResourceSpecificResult { +interface IAMSimulateResourceSpecificResult { evalResourceName: string evalResourceDecision: string matchedStatements: IAMSimulateMatchedStatement[] @@ -364,7 +364,7 @@ export interface IAMSimulateResourceSpecificResult { permissionsBoundaryAllowed: boolean | null } -export interface IAMSimulateEvaluationResult { +interface IAMSimulateEvaluationResult { evalActionName: string /** The resource-type ARN template AWS echoes back, not a customer resource ARN. */ evalResourceName: string diff --git a/apps/sim/tools/icypeas/types.ts b/apps/sim/tools/icypeas/types.ts index aab946e7559..1756595947f 100644 --- a/apps/sim/tools/icypeas/types.ts +++ b/apps/sim/tools/icypeas/types.ts @@ -1,7 +1,7 @@ import type { OutputProperty, ToolResponse } from '@/tools/types' /** Base params shared by every Icypeas operation. */ -export interface IcypeasBaseParams { +interface IcypeasBaseParams { apiKey: string } diff --git a/apps/sim/tools/identity_center/types.ts b/apps/sim/tools/identity_center/types.ts index 4acfc92555c..4d315b67b76 100644 --- a/apps/sim/tools/identity_center/types.ts +++ b/apps/sim/tools/identity_center/types.ts @@ -1,6 +1,6 @@ import type { ToolResponse } from '@/tools/types' -export interface IdentityCenterConnectionConfig { +interface IdentityCenterConnectionConfig { region: string accessKeyId: string secretAccessKey: string diff --git a/apps/sim/tools/incidentio/types.ts b/apps/sim/tools/incidentio/types.ts index 9f317ea8111..d505ddb9a90 100644 --- a/apps/sim/tools/incidentio/types.ts +++ b/apps/sim/tools/incidentio/types.ts @@ -374,7 +374,7 @@ export const INCIDENTIO_TEAM_OUTPUT_PROPERTIES = { } as const satisfies Record // Common parameters for all incident.io tools -export interface IncidentioBaseParams { +interface IncidentioBaseParams { apiKey: string } @@ -708,7 +708,7 @@ export interface WorkflowsDeleteResponse extends ToolResponse { } // Custom field types -export type CustomFieldType = 'text' | 'single_select' | 'multi_select' | 'numeric' | 'link' +type CustomFieldType = 'text' | 'single_select' | 'multi_select' | 'numeric' | 'link' interface CustomField { id: string @@ -1306,7 +1306,7 @@ export interface IncidentioEscalationPathsDeleteResponse extends ToolResponse { * documents `email`, `role`, and `slack_user_id` as optional. * @see https://docs.incident.io/api-reference */ -export interface IncidentioSlimUser { +interface IncidentioSlimUser { id: string name: string email?: string @@ -1315,7 +1315,7 @@ export interface IncidentioSlimUser { } /** Pagination envelope returned by incident.io list endpoints. */ -export interface IncidentioPaginationMeta { +interface IncidentioPaginationMeta { after?: string page_size: number total_record_count?: number @@ -1356,7 +1356,7 @@ export interface IncidentioOnCallNowResponse extends ToolResponse { } /** A one-off change layered over a schedule's rotations, as the list endpoint returns it. */ -export interface IncidentioScheduleOverrideRecord { +interface IncidentioScheduleOverrideRecord { id: string schedule_id: string rotation_id: string @@ -1384,7 +1384,7 @@ export interface IncidentioScheduleOverridesListResponse extends ToolResponse { } /** A single value on an alert attribute, either a literal or a catalog entry reference. */ -export interface IncidentioAlertAttributeValue { +interface IncidentioAlertAttributeValue { literal?: string label?: string catalog_entry?: { @@ -1395,7 +1395,7 @@ export interface IncidentioAlertAttributeValue { } /** An attribute value parsed from an alert's payload by its alert source config. */ -export interface IncidentioAlertAttributeEntry { +interface IncidentioAlertAttributeEntry { attribute: { id: string name: string @@ -1408,7 +1408,7 @@ export interface IncidentioAlertAttributeEntry { array_value?: IncidentioAlertAttributeValue[] } -export interface IncidentioAlert { +interface IncidentioAlert { id: string title: string status: string @@ -1424,7 +1424,7 @@ export interface IncidentioAlert { } /** The alert shape returned on incident-alert connections, which omits `attributes`. */ -export type IncidentioAlertSlim = Omit +type IncidentioAlertSlim = Omit export interface IncidentioAlertsListParams extends IncidentioBaseParams { page_size?: number @@ -1491,7 +1491,7 @@ export interface IncidentioAlertEventsCreateResponse extends ToolResponse { } /** The connection between an alert and the incident it was attached to. */ -export interface IncidentioIncidentAlert { +interface IncidentioIncidentAlert { id: string alert: IncidentioAlertSlim incident: { @@ -1531,7 +1531,7 @@ export interface IncidentioEscalationsCancelResponse extends ToolResponse { } /** A catalog type, describing the schema shared by all entries of that type. */ -export interface IncidentioCatalogType { +interface IncidentioCatalogType { id: string name: string description: string @@ -1575,7 +1575,7 @@ export interface IncidentioCatalogTypesListResponse extends ToolResponse { } /** A single entry of a catalog type, such as one service or one team. */ -export interface IncidentioCatalogEntry { +interface IncidentioCatalogEntry { id: string name: string catalog_type_id: string @@ -1603,7 +1603,7 @@ export interface IncidentioCatalogEntriesListResponse extends ToolResponse { } } -export interface IncidentioTeam { +interface IncidentioTeam { id: string name: string members: IncidentioSlimUser[] @@ -1788,7 +1788,7 @@ export const INCIDENTIO_ACTION_RECORD_OUTPUT_PROPERTIES = { * Whoever caused something to happen. Exactly one of these is populated, so consumers should * check each in turn rather than assuming a user. */ -export interface IncidentioActor { +interface IncidentioActor { user?: IncidentioSlimUser api_key?: { id: string; name: string } workflow?: { id: string; name: string } @@ -1796,14 +1796,14 @@ export interface IncidentioActor { } /** A reference to the issue an action or follow-up was exported to. */ -export interface IncidentioExternalIssueReference { +interface IncidentioExternalIssueReference { provider: string issue_name: string issue_permalink: string } /** A follow-up exactly as the incident.io API returns it. */ -export interface IncidentioFollowUpRecord { +interface IncidentioFollowUpRecord { id: string incident_id: string title: string @@ -1826,7 +1826,7 @@ export interface IncidentioFollowUpRecord { } /** An action exactly as the incident.io API returns it. */ -export interface IncidentioActionRecord { +interface IncidentioActionRecord { id: string incident_id: string description: string @@ -1901,7 +1901,7 @@ export interface IncidentioActionsUpdateResponse extends ToolResponse { } /** A person who took part in an incident, annotated with how they participated. */ -export interface IncidentioIncidentParticipant { +interface IncidentioIncidentParticipant { participant_type: string user: IncidentioSlimUser } diff --git a/apps/sim/tools/instagram/types.ts b/apps/sim/tools/instagram/types.ts index 78a53928436..9a55b938298 100644 --- a/apps/sim/tools/instagram/types.ts +++ b/apps/sim/tools/instagram/types.ts @@ -9,7 +9,7 @@ export const PUBLISH_OUTPUTS = { statusCode: { type: 'string', description: 'Final container status', optional: true }, } satisfies Record -export interface InstagramAccessParams { +interface InstagramAccessParams { accessToken: string igUserId?: string } @@ -108,7 +108,7 @@ export interface InstagramListStoriesResponse extends ToolResponse { } /** Canonical Sim file uploaded in basic mode or referenced from a prior block. */ -export type InstagramMediaInput = RawFileInput +type InstagramMediaInput = RawFileInput export interface InstagramPublishImageParams extends InstagramAccessParams { image: InstagramMediaInput @@ -315,9 +315,9 @@ export interface InstagramSendTextMessageResponse extends ToolResponse { } } -export type InstagramAccountInsightsPeriod = 'day' | 'lifetime' -export type InstagramAccountInsightsMetricType = 'time_series' | 'total_value' -export type InstagramAccountInsightsTimeframe = 'this_week' | 'this_month' +type InstagramAccountInsightsPeriod = 'day' | 'lifetime' +type InstagramAccountInsightsMetricType = 'time_series' | 'total_value' +type InstagramAccountInsightsTimeframe = 'this_week' | 'this_month' export interface InstagramGetAccountInsightsParams extends InstagramAccessParams { metrics: string diff --git a/apps/sim/tools/instantly/types.ts b/apps/sim/tools/instantly/types.ts index 5ea23e2cfce..6e5ffafe353 100644 --- a/apps/sim/tools/instantly/types.ts +++ b/apps/sim/tools/instantly/types.ts @@ -1,8 +1,8 @@ import type { ToolResponse } from '@/tools/types' -export type InstantlyScalar = string | number | boolean | null +type InstantlyScalar = string | number | boolean | null -export interface InstantlyBaseParams { +interface InstantlyBaseParams { apiKey: string } diff --git a/apps/sim/tools/jotform/types.ts b/apps/sim/tools/jotform/types.ts index 1bd91cbad83..6e57b582145 100644 --- a/apps/sim/tools/jotform/types.ts +++ b/apps/sim/tools/jotform/types.ts @@ -7,7 +7,7 @@ import type { ToolResponse } from '@/tools/types' */ /** Credentials and host selection every Jotform tool takes. */ -export interface JotformAuthParams { +interface JotformAuthParams { apiKey: string region?: string } @@ -89,7 +89,7 @@ export interface JotformFile { url: string | null } -export interface JotformPagination { +interface JotformPagination { offset: number | null limit: number | null count: number | null @@ -370,7 +370,7 @@ export interface JotformGetHistoryParams extends JotformAuthParams { endDate?: string } -export interface JotformHistoryEntry { +interface JotformHistoryEntry { type: string | null formID: string | null username: string | null @@ -403,7 +403,7 @@ export interface JotformCreateQuestionsParams extends JotformAuthParams { questions: unknown[] | string } -export interface JotformSubUserPermission { +interface JotformSubUserPermission { type: string | null resource_id: string | null access_type: string | null diff --git a/apps/sim/tools/jsm/types.ts b/apps/sim/tools/jsm/types.ts index 2e984f45422..894add04469 100644 --- a/apps/sim/tools/jsm/types.ts +++ b/apps/sim/tools/jsm/types.ts @@ -1045,7 +1045,7 @@ export interface JsmReopenFormResponse extends ToolResponse { */ /** Base params shared by every JSM Assets tool */ -export interface JsmAssetsBaseParams { +interface JsmAssetsBaseParams { accessToken: string domain: string /** Jira Cloud ID (resolved server-side from the domain when omitted) */ @@ -1055,7 +1055,7 @@ export interface JsmAssetsBaseParams { } /** A single attribute value entry on an Assets object */ -export interface AssetObjectAttributeValue { +interface AssetObjectAttributeValue { value: string | null displayValue: string | null searchValue?: string | null @@ -1064,7 +1064,7 @@ export interface AssetObjectAttributeValue { } /** A resolved attribute on an Assets object (read shape) */ -export interface AssetObjectAttribute { +interface AssetObjectAttribute { id: string objectTypeAttributeId: string objectAttributeValues: AssetObjectAttributeValue[] @@ -1085,13 +1085,13 @@ export interface AssetObject { } /** Attribute payload for creating/updating an Assets object */ -export interface AssetObjectAttributeInput { +interface AssetObjectAttributeInput { objectTypeAttributeId: string objectAttributeValues: Array<{ value: unknown }> } /** Raw attribute value as returned by the Assets API (before normalization) */ -export interface RawAssetObjectAttributeValue { +interface RawAssetObjectAttributeValue { value?: string | null displayValue?: string | null searchValue?: string | null @@ -1100,7 +1100,7 @@ export interface RawAssetObjectAttributeValue { } /** Raw attribute as returned by the Assets API (before normalization) */ -export interface RawAssetObjectAttribute { +interface RawAssetObjectAttribute { id?: string objectTypeAttributeId?: string objectAttributeValues?: RawAssetObjectAttributeValue[] diff --git a/apps/sim/tools/jupyter/types.ts b/apps/sim/tools/jupyter/types.ts index a3813072191..7f97a43951f 100644 --- a/apps/sim/tools/jupyter/types.ts +++ b/apps/sim/tools/jupyter/types.ts @@ -1,12 +1,12 @@ import type { UserFile } from '@/executor/types' import type { ToolResponse } from '@/tools/types' -export interface JupyterAuthParams { +interface JupyterAuthParams { serverUrl: string token: string } -export interface JupyterContentItem { +interface JupyterContentItem { name: string path: string type: 'directory' | 'file' | 'notebook' @@ -18,7 +18,7 @@ export interface JupyterContentItem { format: 'json' | 'text' | 'base64' | null } -export interface JupyterKernel { +interface JupyterKernel { id: string name: string lastActivity: string | null @@ -26,7 +26,7 @@ export interface JupyterKernel { connections: number | null } -export interface JupyterKernelSpec { +interface JupyterKernelSpec { name: string displayName: string language: string | null @@ -34,7 +34,7 @@ export interface JupyterKernelSpec { interruptMode: string | null } -export interface JupyterSession { +interface JupyterSession { id: string path: string name: string diff --git a/apps/sim/tools/lambda/types.ts b/apps/sim/tools/lambda/types.ts index 24372263d7f..64a59b0ff76 100644 --- a/apps/sim/tools/lambda/types.ts +++ b/apps/sim/tools/lambda/types.ts @@ -204,7 +204,7 @@ import type { ToolResponse } from '@/tools/types' * Credential params every Lambda tool declares. The tool's `operation.input` renames * these onto the `region`/`accessKeyId`/`secretAccessKey` fields the contract expects. */ -export interface LambdaConnectionParams { +interface LambdaConnectionParams { awsRegion: string awsAccessKeyId: string awsSecretAccessKey: string diff --git a/apps/sim/tools/langsmith/types.ts b/apps/sim/tools/langsmith/types.ts index d6fd70d27ea..deb0ca5ac82 100644 --- a/apps/sim/tools/langsmith/types.ts +++ b/apps/sim/tools/langsmith/types.ts @@ -1,13 +1,6 @@ import type { ToolResponse } from '@/tools/types' -export type LangsmithRunType = - | 'tool' - | 'chain' - | 'llm' - | 'retriever' - | 'embedding' - | 'prompt' - | 'parser' +type LangsmithRunType = 'tool' | 'chain' | 'llm' | 'retriever' | 'embedding' | 'prompt' | 'parser' export interface LangsmithRunPayload { id?: string @@ -104,7 +97,7 @@ export interface LangsmithGetRunResponse extends ToolResponse { } } -export type LangsmithFeedbackSourceType = 'api' | 'app' | 'model' +type LangsmithFeedbackSourceType = 'api' | 'app' | 'model' export interface LangsmithCreateFeedbackParams { apiKey: string diff --git a/apps/sim/tools/latex/types.ts b/apps/sim/tools/latex/types.ts index f84e6dc07b8..1d50fcf68da 100644 --- a/apps/sim/tools/latex/types.ts +++ b/apps/sim/tools/latex/types.ts @@ -1,14 +1,14 @@ import type { UserFile } from '@/executor/types' import type { ToolResponse } from '@/tools/types' -export type LatexCompiler = 'pdflatex' | 'xelatex' | 'lualatex' | 'platex' | 'uplatex' | 'context' +type LatexCompiler = 'pdflatex' | 'xelatex' | 'lualatex' | 'platex' | 'uplatex' | 'context' /** * Supporting file made available to the compiler alongside the main document. * Exactly one of `content` (plain text), `file` (base64), or `url` (remote * file) must be provided. */ -export interface LatexResource { +interface LatexResource { path: string content?: string file?: string @@ -26,7 +26,7 @@ export interface LatexCompileParams { * Reference to the compiled PDF when no execution-file context is available; * with execution context the output is a full {@link UserFile}. */ -export interface LatexPdfReference { +interface LatexPdfReference { name: string url: string mimeType: string diff --git a/apps/sim/tools/linq/types.ts b/apps/sim/tools/linq/types.ts index 6ed19dc3c5a..9615556bb7c 100644 --- a/apps/sim/tools/linq/types.ts +++ b/apps/sim/tools/linq/types.ts @@ -4,7 +4,7 @@ import type { ToolResponse } from '@/tools/types' export type LinqServiceType = 'iMessage' | 'SMS' | 'RCS' /** Tapback / reaction types supported by the Linq API. */ -export type LinqReactionType = +type LinqReactionType = | 'love' | 'like' | 'dislike' @@ -15,7 +15,7 @@ export type LinqReactionType = | 'sticker' /** A participant handle within a chat. */ -export interface LinqChatHandle { +interface LinqChatHandle { id: string handle: string joined_at: string diff --git a/apps/sim/tools/logfire/types.ts b/apps/sim/tools/logfire/types.ts index e4fa96798b8..44fc1f696e6 100644 --- a/apps/sim/tools/logfire/types.ts +++ b/apps/sim/tools/logfire/types.ts @@ -11,7 +11,7 @@ export type LogfireRegion = 'auto' | 'us' | 'eu' * level as an OpenTelemetry severity number but rewrites string comparisons, * so `level >= 'error'` works directly in SQL. */ -export type LogfireLevel = 'trace' | 'debug' | 'info' | 'notice' | 'warn' | 'error' | 'fatal' +type LogfireLevel = 'trace' | 'debug' | 'info' | 'notice' | 'warn' | 'error' | 'fatal' export interface LogfireBaseParams { apiKey: string @@ -24,7 +24,7 @@ export interface LogfireBaseParams { } /** Time-window and paging controls accepted by every `/v2/query` request. */ -export interface LogfireQueryWindowParams { +interface LogfireQueryWindowParams { minTimestamp?: string maxTimestamp?: string limit?: number @@ -42,7 +42,7 @@ export interface LogfireColumn { * the official SDK renames it to `datatype` before handing results to callers, * and {@link LogfireColumn} keeps that friendlier name. */ -export interface LogfireApiField { +interface LogfireApiField { name?: string | null data_type?: unknown nullable?: boolean | null diff --git a/apps/sim/tools/logs/types.ts b/apps/sim/tools/logs/types.ts index b8c6f8f074a..3c6e3a36360 100644 --- a/apps/sim/tools/logs/types.ts +++ b/apps/sim/tools/logs/types.ts @@ -30,7 +30,7 @@ export interface LogsGetExecutionParams { _context?: WorkflowToolExecutionContext } -export type LogsComparisonOperator = '=' | '>' | '<' | '>=' | '<=' | '!=' +type LogsComparisonOperator = '=' | '>' | '<' | '>=' | '<=' | '!=' export interface LogsQueryRunsParams { workflowIds?: string diff --git a/apps/sim/tools/microsoft_dynamics_365/index.ts b/apps/sim/tools/microsoft_dynamics_365/index.ts index f28bd129cf9..e21cb443fec 100644 --- a/apps/sim/tools/microsoft_dynamics_365/index.ts +++ b/apps/sim/tools/microsoft_dynamics_365/index.ts @@ -19,7 +19,6 @@ export type { DataverseOpportunityOutcome, DataverseQualifyLeadParams, DataverseQualifyLeadResponse, - DataverseResponse, DataverseSearchParams, DataverseSearchResponse, DataverseUpdateRecordParams, diff --git a/apps/sim/tools/microsoft_dynamics_365/types.ts b/apps/sim/tools/microsoft_dynamics_365/types.ts index 74a2cce29bd..d0a5d211fa1 100644 --- a/apps/sim/tools/microsoft_dynamics_365/types.ts +++ b/apps/sim/tools/microsoft_dynamics_365/types.ts @@ -210,13 +210,3 @@ export interface DataverseCloseCaseResponse extends ToolResponse { success: boolean } } - -export type DataverseResponse = - | DataverseListRecordsResponse - | DataverseGetRecordResponse - | DataverseCreateRecordResponse - | DataverseUpdateRecordResponse - | DataverseSearchResponse - | DataverseQualifyLeadResponse - | DataverseCloseOpportunityResponse - | DataverseCloseCaseResponse diff --git a/apps/sim/tools/microsoft_teams/types.ts b/apps/sim/tools/microsoft_teams/types.ts index 21fb112fe3e..a38bdfd95c5 100644 --- a/apps/sim/tools/microsoft_teams/types.ts +++ b/apps/sim/tools/microsoft_teams/types.ts @@ -1,24 +1,6 @@ import type { UserFile } from '@/executor/types' import type { ToolFileData, ToolResponse } from '@/tools/types' -export interface GraphDriveItem { - id: string - webUrl?: string - webDavUrl?: string - eTag?: string - name?: string - size?: number -} - -export interface GraphChatMessage { - id?: string - chatId?: string - channelIdentity?: { teamId?: string; channelId?: string } - body?: { content?: string } - createdDateTime?: string - webUrl?: string -} - export interface MicrosoftTeamsAttachment { id: string contentType: string diff --git a/apps/sim/tools/mintlify/types.ts b/apps/sim/tools/mintlify/types.ts index 10b56debb3a..a1d8d42fdf3 100644 --- a/apps/sim/tools/mintlify/types.ts +++ b/apps/sim/tools/mintlify/types.ts @@ -191,7 +191,7 @@ export interface MintlifyGetPageContentResponse extends ToolResponse { } } -export interface MintlifyAssistantContextItem { +interface MintlifyAssistantContextItem { type: string value: string path?: string @@ -280,7 +280,7 @@ export interface MintlifyGetAssistantConversationsParams extends MintlifyAnalyti cursor?: string } -export interface MintlifyConversationSource { +interface MintlifyConversationSource { title: string | null url: string | null } diff --git a/apps/sim/tools/mongodb/types.ts b/apps/sim/tools/mongodb/types.ts index 862b583a0dd..b20a59aa9fc 100644 --- a/apps/sim/tools/mongodb/types.ts +++ b/apps/sim/tools/mongodb/types.ts @@ -1,6 +1,6 @@ import type { ToolResponse } from '@/tools/types' -export interface MongoDBConnectionConfig { +interface MongoDBConnectionConfig { host: string port: number database: string @@ -51,7 +51,7 @@ export interface MongoDBIntrospectParams { ssl?: 'disabled' | 'required' | 'preferred' } -export interface MongoDBCollectionInfo { +interface MongoDBCollectionInfo { name: string type: string documentCount: number diff --git a/apps/sim/tools/mssql/types.ts b/apps/sim/tools/mssql/types.ts index 9443596fe5a..e3a5cf79168 100644 --- a/apps/sim/tools/mssql/types.ts +++ b/apps/sim/tools/mssql/types.ts @@ -6,7 +6,7 @@ import type { OutputProperty, ToolResponse } from '@/tools/types' * `options.encrypt` / `options.trustServerCertificate` booleans. * @see https://github.com/tediousjs/node-mssql#tedious */ -export interface MSSQLConnectionConfig { +interface MSSQLConnectionConfig { host: string port: number database: string diff --git a/apps/sim/tools/netsuite/types.ts b/apps/sim/tools/netsuite/types.ts index c46c13b1d83..334d446dea0 100644 --- a/apps/sim/tools/netsuite/types.ts +++ b/apps/sim/tools/netsuite/types.ts @@ -9,12 +9,12 @@ export interface NetSuiteAuthParams { instanceUrl?: string } -export interface NetSuitePaginationParams { +interface NetSuitePaginationParams { limit?: number offset?: number } -export interface NetSuiteRecordQueryParams { +interface NetSuiteRecordQueryParams { fields?: string expand?: string expandSubResources?: boolean @@ -143,7 +143,7 @@ export interface NetSuiteExecuteDatasetParams extends NetSuiteAuthParams, NetSui export interface NetSuiteListRecordTypesParams extends NetSuiteAuthParams {} -export type NetSuiteMetadataFormat = 'default' | 'openapi' | 'json_schema' +type NetSuiteMetadataFormat = 'default' | 'openapi' | 'json_schema' export interface NetSuiteGetRecordMetadataParams extends NetSuiteAuthParams { recordType: string diff --git a/apps/sim/tools/new_relic/types.ts b/apps/sim/tools/new_relic/types.ts index 605801e4786..e41a0ca8155 100644 --- a/apps/sim/tools/new_relic/types.ts +++ b/apps/sim/tools/new_relic/types.ts @@ -2,7 +2,7 @@ import type { ToolResponse } from '@/tools/types' export type NewRelicRegion = 'us' | 'eu' -export interface NewRelicBaseParams { +interface NewRelicBaseParams { apiKey: string region?: NewRelicRegion } @@ -25,7 +25,7 @@ export interface NewRelicSearchEntitiesParams extends NewRelicBaseParams { cursor?: string } -export interface NewRelicEntityTag { +interface NewRelicEntityTag { key: string | null values: string[] } diff --git a/apps/sim/tools/otter/types.ts b/apps/sim/tools/otter/types.ts index ca5b4e6031e..647e25aaaff 100644 --- a/apps/sim/tools/otter/types.ts +++ b/apps/sim/tools/otter/types.ts @@ -34,7 +34,7 @@ export interface OtterSharedChannel { permission: string | null } -export interface OtterProcessStatus { +interface OtterProcessStatus { abstractSummary: string | null actionItem: string | null outline: string | null @@ -54,7 +54,7 @@ export interface OtterConversation { confJoinUrl: string | null } -export interface OtterActionItemStatus { +interface OtterActionItemStatus { completed: boolean | null createdAt: string | null lastModifiedAt: string | null diff --git a/apps/sim/tools/outlook/types.ts b/apps/sim/tools/outlook/types.ts index b03ede4ae25..cc0bad04d72 100644 --- a/apps/sim/tools/outlook/types.ts +++ b/apps/sim/tools/outlook/types.ts @@ -597,7 +597,7 @@ export const OUTLOOK_EVENT_OUTPUT_PROPERTIES = { } as const satisfies Record /** Cleaned dateTimeTimeZone value returned by our tools. */ -export interface CleanedOutlookEventDateTime { +interface CleanedOutlookEventDateTime { dateTime?: string timeZone?: string } @@ -637,7 +637,7 @@ export interface GraphDateTimeTimeZone { } /** Raw Microsoft Graph emailAddress value. */ -export interface GraphEmailAddress { +interface GraphEmailAddress { name?: string address?: string } diff --git a/apps/sim/tools/prospeo/types.ts b/apps/sim/tools/prospeo/types.ts index e6a6dc0c3fb..7317fcf56ca 100644 --- a/apps/sim/tools/prospeo/types.ts +++ b/apps/sim/tools/prospeo/types.ts @@ -1,10 +1,10 @@ import type { OutputProperty, ToolResponse } from '@/tools/types' -export interface ProspeoBaseParams { +interface ProspeoBaseParams { apiKey: string } -export interface ProspeoPersonData { +interface ProspeoPersonData { first_name?: string last_name?: string full_name?: string @@ -16,14 +16,14 @@ export interface ProspeoPersonData { person_id?: string } -export interface ProspeoCompanyData { +interface ProspeoCompanyData { company_name?: string company_website?: string company_linkedin_url?: string company_id?: string } -export interface ProspeoPaginationOutput { +interface ProspeoPaginationOutput { current_page: number per_page: number total_page: number diff --git a/apps/sim/tools/quartr/types.ts b/apps/sim/tools/quartr/types.ts index 2641f300775..0618d1b4193 100644 --- a/apps/sim/tools/quartr/types.ts +++ b/apps/sim/tools/quartr/types.ts @@ -1,7 +1,7 @@ import type { OutputProperty, ToolFileData, ToolResponse } from '@/tools/types' /** Raw ticker entry as returned by the Quartr API. */ -export interface QuartrTicker { +interface QuartrTicker { ticker: string exchange: string } @@ -77,7 +77,7 @@ export interface QuartrSummaryDto { } /** Raw audio metadata as returned by the Quartr API (`AudioMetadataDto`). */ -export interface QuartrAudioMetadataDto { +interface QuartrAudioMetadataDto { size?: string duration?: number encoding?: string @@ -134,7 +134,7 @@ export interface QuartrDocumentTypeDto { } /** Cursor pagination envelope returned by Quartr list endpoints. */ -export interface QuartrPaginationDto { +interface QuartrPaginationDto { nextCursor: number | null } @@ -211,7 +211,7 @@ export interface QuartrSummarySource { } /** Audio metadata with nullable optional fields, as emitted in tool outputs. */ -export interface QuartrAudioMetadata { +interface QuartrAudioMetadata { size: string | null duration: number | null encoding: string | null diff --git a/apps/sim/tools/railway/types.ts b/apps/sim/tools/railway/types.ts index 150dc66a5f3..f2792cc5321 100644 --- a/apps/sim/tools/railway/types.ts +++ b/apps/sim/tools/railway/types.ts @@ -2,7 +2,7 @@ import type { ToolResponse } from '@/tools/types' export type RailwayTokenType = 'account' | 'workspace' | 'project' | 'oauth' -export interface RailwayAuthParams { +interface RailwayAuthParams { apiKey: string tokenType?: RailwayTokenType } diff --git a/apps/sim/tools/reddit/types.ts b/apps/sim/tools/reddit/types.ts index 7f242645011..0e34a7adb51 100644 --- a/apps/sim/tools/reddit/types.ts +++ b/apps/sim/tools/reddit/types.ts @@ -201,7 +201,7 @@ export interface RedditComment { replies: RedditComment[] } -export interface RedditMessage { +interface RedditMessage { id: string name: string author: string diff --git a/apps/sim/tools/reducto/types.ts b/apps/sim/tools/reducto/types.ts index e82f298722d..81e46516813 100644 --- a/apps/sim/tools/reducto/types.ts +++ b/apps/sim/tools/reducto/types.ts @@ -61,7 +61,7 @@ interface ReductoGranularConfidence { /** * Block type classification */ -export type ReductoBlockType = +type ReductoBlockType = | 'Header' | 'Footer' | 'Title' diff --git a/apps/sim/tools/rocketlane/types.ts b/apps/sim/tools/rocketlane/types.ts index 5c2867c94ed..fb92a3e9f5d 100644 --- a/apps/sim/tools/rocketlane/types.ts +++ b/apps/sim/tools/rocketlane/types.ts @@ -6,7 +6,7 @@ import type { OutputProperty, ToolResponse } from '@/tools/types' export const ROCKETLANE_API_BASE = 'https://api.rocketlane.com/api/1.0' /** Every Rocketlane tool authenticates with the account API key via the `api-key` header. */ -export interface RocketlaneBaseParams { +interface RocketlaneBaseParams { apiKey: string } @@ -48,7 +48,7 @@ export async function rocketlaneError(response: Response): Promise { // region Shared object shapes /** Compact user reference returned inside most Rocketlane resources. */ -export interface RocketlaneUserSummary { +interface RocketlaneUserSummary { userId: number | null firstName: string | null lastName: string | null @@ -115,55 +115,55 @@ export const PAGINATION_OUTPUT_PROPERTIES = { // region Tasks /** Compact project reference returned inside a Rocketlane task. */ -export interface RocketlaneTaskProjectRef { +interface RocketlaneTaskProjectRef { projectId: number | null projectName: string | null } /** Compact phase reference returned inside a Rocketlane task. */ -export interface RocketlaneTaskPhaseRef { +interface RocketlaneTaskPhaseRef { phaseId: number | null phaseName: string | null } /** Value/label pair used for task status and priority fields. */ -export interface RocketlaneTaskChoice { +interface RocketlaneTaskChoice { value: number | null label: string | null } /** Role associated with a placeholder assignee. */ -export interface RocketlaneTaskRole { +interface RocketlaneTaskRole { roleId: number | null roleName: string | null } /** Placeholder assignee on a task, associated with a role. */ -export interface RocketlaneTaskPlaceholder { +interface RocketlaneTaskPlaceholder { placeholderId: number | null placeholderName: string | null role: RocketlaneTaskRole | null } /** Assignees of a task: members (team members or customers) and placeholders. */ -export interface RocketlaneTaskAssignees { +interface RocketlaneTaskAssignees { members: RocketlaneUserSummary[] placeholders: RocketlaneTaskPlaceholder[] } /** Followers of a task (members only). */ -export interface RocketlaneTaskFollowers { +interface RocketlaneTaskFollowers { members: RocketlaneUserSummary[] } /** Lite task reference used for dependencies and the parent task. */ -export interface RocketlaneTaskLite { +interface RocketlaneTaskLite { taskId: number | null taskName: string | null } /** Custom field value attached to a task. */ -export interface RocketlaneTaskField { +interface RocketlaneTaskField { fieldId: number | null fieldLabel: string | null fieldValue: unknown @@ -171,13 +171,13 @@ export interface RocketlaneTaskField { } /** Time entry category associated with a task. */ -export interface RocketlaneTaskTimeEntryCategory { +interface RocketlaneTaskTimeEntryCategory { categoryId: number | null categoryName: string | null } /** Financials budget in which the task's time entry is added. */ -export interface RocketlaneTaskBudget { +interface RocketlaneTaskBudget { budgetId: number | null budgetName: string | null } @@ -738,7 +738,7 @@ export interface RocketlaneTaskDeleteResponse extends ToolResponse { // region Projects /** Company reference (customer or partner) returned on Rocketlane projects. */ -export interface RocketlaneProjectCompany { +interface RocketlaneProjectCompany { companyId: number | null companyName: string | null companyUrl: string | null @@ -761,7 +761,7 @@ export const PROJECT_COMPANY_OUTPUT_PROPERTIES = { } satisfies Record /** Project status value/label pair. */ -export interface RocketlaneProjectStatus { +interface RocketlaneProjectStatus { value: number | null label: string | null } @@ -781,7 +781,7 @@ export const PROJECT_STATUS_OUTPUT_PROPERTIES = { } satisfies Record /** Custom project field value returned on Rocketlane projects. */ -export interface RocketlaneProjectField { +interface RocketlaneProjectField { fieldId: number | null fieldLabel: string | null fieldValue: string | null @@ -810,7 +810,7 @@ export const PROJECT_FIELD_OUTPUT_PROPERTIES = { } satisfies Record /** In-progress phase reference returned on Rocketlane projects. */ -export interface RocketlaneProjectPhase { +interface RocketlaneProjectPhase { phaseId: number | null phaseName: string | null } @@ -829,7 +829,7 @@ export const PROJECT_PHASE_OUTPUT_PROPERTIES = { } satisfies Record /** Template source imported into a Rocketlane project. */ -export interface RocketlaneProjectSource { +interface RocketlaneProjectSource { prefix: string | null startDate: string | null templateId: number | null @@ -862,7 +862,7 @@ export const PROJECT_SOURCE_OUTPUT_PROPERTIES = { } satisfies Record /** Project members, customers, and customer champion. */ -export interface RocketlaneProjectTeamMembers { +interface RocketlaneProjectTeamMembers { members: RocketlaneUserSummary[] customers: RocketlaneUserSummary[] customerChampion: RocketlaneUserSummary | null @@ -904,7 +904,7 @@ export const PROJECT_TEAM_MEMBERS_OUTPUT_PROPERTIES = { * Flattened project financials (contract type plus the per-contract-type fields * from fixedFeeContract, timeAndMaterialContract, and subscriptionContract). */ -export interface RocketlaneProjectFinancials { +interface RocketlaneProjectFinancials { contractType: string | null revenueRecognitionType: string | null fixedFee: number | null @@ -1328,13 +1328,13 @@ export interface RocketlanePlaceholder { } /** Project reference attached to a placeholder. */ -export interface RocketlanePlaceholderProjectRef { +interface RocketlanePlaceholderProjectRef { projectId: number | null projectName: string | null } /** Role reference attached to a placeholder. */ -export interface RocketlanePlaceholderRole { +interface RocketlanePlaceholderRole { roleId: number | null roleName: string | null } @@ -1408,7 +1408,7 @@ export const PLACEHOLDER_OUTPUT_PROPERTIES = { } satisfies Record /** User assigned to a placeholder mapping (user summary plus role name). */ -export interface RocketlanePlaceholderMappingUser { +interface RocketlanePlaceholderMappingUser { userId: number | null firstName: string | null lastName: string | null @@ -1428,7 +1428,7 @@ export interface RocketlanePlaceholderMapping { } /** Compact placeholder reference inside a placeholder mapping. */ -export interface RocketlanePlaceholderRef { +interface RocketlanePlaceholderRef { placeholderId: number | null placeholderName: string | null } @@ -1515,20 +1515,20 @@ export const PLACEHOLDER_MAPPING_OUTPUT_PROPERTIES = { } satisfies Record /** Custom field assignment sent when creating or updating a project. */ -export interface RocketlaneProjectFieldInput { +interface RocketlaneProjectFieldInput { fieldId: number fieldValue: string | number | number[] } /** Template source sent when creating a project. */ -export interface RocketlaneProjectSourceInput { +interface RocketlaneProjectSourceInput { templateId: number startDate: string prefix?: string } /** Placeholder-to-user mapping sent when creating a project or assigning placeholders. */ -export interface RocketlaneProjectPlaceholderInput { +interface RocketlaneProjectPlaceholderInput { placeholderId: number user: { userId?: number @@ -1830,7 +1830,7 @@ export const FIELD_OUTPUT_PROPERTIES = { } satisfies Record /** Option payload accepted when creating a field. */ -export interface RocketlaneFieldOptionInput { +interface RocketlaneFieldOptionInput { optionLabel: string optionColor: string } @@ -1926,13 +1926,13 @@ export interface RocketlaneFieldOptionResponse extends ToolResponse { // region Phases /** Compact project reference returned inside a phase. */ -export interface RocketlanePhaseProject { +interface RocketlanePhaseProject { projectId: number | null projectName: string | null } /** Status of a phase, as a numeric value with a display label. */ -export interface RocketlanePhaseStatus { +interface RocketlanePhaseStatus { value: number | null label: string | null } @@ -2121,19 +2121,19 @@ export interface RocketlanePhaseDeleteResponse extends ToolResponse { // region Time Entries /** Project reference embedded in a time entry. */ -export interface RocketlaneTimeEntryProject { +interface RocketlaneTimeEntryProject { projectId: number | null projectName: string | null } /** Task reference embedded in a time entry. */ -export interface RocketlaneTimeEntryTask { +interface RocketlaneTimeEntryTask { taskId: number | null taskName: string | null } /** Project phase reference embedded in a time entry. */ -export interface RocketlaneTimeEntryPhase { +interface RocketlaneTimeEntryPhase { phaseId: number | null phaseName: string | null } @@ -2145,13 +2145,13 @@ export interface RocketlaneTimeEntryCategory { } /** Hourly cost/bill rate attached to a time entry. */ -export interface RocketlaneTimeEntryRate { +interface RocketlaneTimeEntryRate { rate: number | null currency: string | null } /** Custom field value attached to a time entry. */ -export interface RocketlaneTimeEntryField { +interface RocketlaneTimeEntryField { fieldId: number | null fieldLabel: string | null fieldValue: unknown @@ -2507,7 +2507,7 @@ export interface RocketlaneDeleteTimeEntryParams extends RocketlaneBaseParams { } /** Filter/sort/pagination params shared by the list and search time entry tools. */ -export interface RocketlaneTimeEntryFilterParams extends RocketlaneBaseParams { +interface RocketlaneTimeEntryFilterParams extends RocketlaneBaseParams { sortBy?: string sortOrder?: string match?: string @@ -2595,7 +2595,7 @@ export interface RocketlaneTimeEntryCategoryListResponse extends ToolResponse { // region Spaces /** The project a space belongs to. */ -export interface RocketlaneSpaceProject { +interface RocketlaneSpaceProject { projectId: number | null projectName: string | null } @@ -2743,13 +2743,13 @@ export interface RocketlaneListSpacesResponse extends ToolResponse { // region Space Documents /** The space a space document belongs to. */ -export interface RocketlaneSpaceDocumentSpaceRef { +interface RocketlaneSpaceDocumentSpaceRef { spaceId: number | null spaceName: string | null } /** The document template a space document was created from. */ -export interface RocketlaneSpaceDocumentSource { +interface RocketlaneSpaceDocumentSource { templateId: number | null templateName: string | null } @@ -2940,31 +2940,31 @@ export interface RocketlaneListSpaceDocumentsResponse extends ToolResponse { // region Users /** The role assigned to a user. */ -export interface RocketlaneUserRole { +interface RocketlaneUserRole { roleId: number | null roleName: string | null } /** The company a user belongs to. */ -export interface RocketlaneUserCompany { +interface RocketlaneUserCompany { companyId: number | null companyName: string | null } /** The permission level of a user. */ -export interface RocketlaneUserPermission { +interface RocketlaneUserPermission { permissionId: number | null permissionName: string | null } /** The holiday calendar assigned to a user. Field names use the API's `calender` spelling. */ -export interface RocketlaneUserHolidayCalendar { +interface RocketlaneUserHolidayCalendar { calenderId: number | null calenderName: string | null } /** A custom user field value. */ -export interface RocketlaneUserField { +interface RocketlaneUserField { fieldId: number | null fieldLabel: string | null fieldValue: string | null @@ -3300,7 +3300,7 @@ export interface RocketlaneTimeOffListParams extends RocketlaneBaseParams { } /** The notify-users preferences attached to a time-off. */ -export interface RocketlaneTimeOffNotifyUsers { +interface RocketlaneTimeOffNotifyUsers { projectOwners: boolean | null others: RocketlaneUserSummary[] } @@ -3454,37 +3454,37 @@ export interface RocketlaneResourceAllocationListParams extends RocketlaneBasePa } /** A role attached to an allocation member or placeholder. */ -export interface RocketlaneResourceAllocationRole { +interface RocketlaneResourceAllocationRole { roleId: number | null roleName: string | null } /** The team member an allocation is made for, including their role. */ -export interface RocketlaneResourceAllocationMember extends RocketlaneUserSummary { +interface RocketlaneResourceAllocationMember extends RocketlaneUserSummary { role: RocketlaneResourceAllocationRole | null } /** The placeholder an allocation is made for. */ -export interface RocketlaneResourceAllocationPlaceholder { +interface RocketlaneResourceAllocationPlaceholder { placeholderId: number | null placeholderName: string | null role: RocketlaneResourceAllocationRole | null } /** The project associated with an allocation. */ -export interface RocketlaneResourceAllocationProject { +interface RocketlaneResourceAllocationProject { projectId: number | null projectName: string | null } /** A task associated with an allocation. */ -export interface RocketlaneResourceAllocationTask { +interface RocketlaneResourceAllocationTask { taskId: number | null taskName: string | null } /** Total duration figures for an allocation between its start and end dates. */ -export interface RocketlaneResourceAllocationDuration { +interface RocketlaneResourceAllocationDuration { daysConsider: number | null seconds: number | null minutes: number | null @@ -3813,20 +3813,20 @@ export interface RocketlaneInvoiceLineItemsParams extends RocketlaneBaseParams { } /** Customer company details on an invoice. */ -export interface RocketlaneInvoiceCompany { +interface RocketlaneInvoiceCompany { companyId: number | null companyName: string | null companyUrl: string | null } /** A project mapped to an invoice. */ -export interface RocketlaneInvoiceProject { +interface RocketlaneInvoiceProject { projectId: number | null projectName: string | null } /** A custom field value attached to an invoice. */ -export interface RocketlaneInvoiceField { +interface RocketlaneInvoiceField { fieldId: number | null fieldLabel: string | null fieldValue: unknown @@ -3834,7 +3834,7 @@ export interface RocketlaneInvoiceField { } /** An attachment associated with an invoice. */ -export interface RocketlaneInvoiceAttachment { +interface RocketlaneInvoiceAttachment { attachmentId: number | null attachmentName: string | null createdAt: number | null @@ -3879,7 +3879,7 @@ export interface RocketlaneInvoicePayment { } /** Tax code information for an invoice line item. */ -export interface RocketlaneInvoiceLineItemTaxCode { +interface RocketlaneInvoiceLineItemTaxCode { taxCodeId: number | null taxCodeName: string | null taxCodeRate: number | null @@ -3887,7 +3887,7 @@ export interface RocketlaneInvoiceLineItemTaxCode { } /** A tax component that makes up a line item's tax code. */ -export interface RocketlaneInvoiceLineItemTaxComponent { +interface RocketlaneInvoiceLineItemTaxComponent { taxComponentId: number | null taxComponentName: string | null taxComponentRate: number | null diff --git a/apps/sim/tools/sailpoint/types.ts b/apps/sim/tools/sailpoint/types.ts index 315f0a947d0..d671c3798ee 100644 --- a/apps/sim/tools/sailpoint/types.ts +++ b/apps/sim/tools/sailpoint/types.ts @@ -4,7 +4,7 @@ export interface SailPointCredentials { tenant: string } -export interface SailPointPaginationParams { +interface SailPointPaginationParams { limit?: number offset?: number count?: boolean @@ -19,12 +19,6 @@ export interface SailPointGetByIdParams extends SailPointCredentials { id: string } -export interface SailPointListOutput> { - items: T[] - count: number - totalCount: number | null -} - export interface SailPointListIdentitiesParams extends SailPointListParams { defaultFilter?: 'CORRELATED_ONLY' | 'NONE' } @@ -80,7 +74,7 @@ export interface SailPointListReviewItemsParams extends SailPointListParams { roles?: string } -export type SailPointSearchIndex = +type SailPointSearchIndex = | 'accessprofiles' | 'accountactivities' | 'entitlements' @@ -89,21 +83,21 @@ export type SailPointSearchIndex = | 'roles' | '*' -export interface SailPointSearchQuery { +interface SailPointSearchQuery { query?: string fields?: string timeZone?: string innerHit?: Record } -export interface SailPointTextQuery { +interface SailPointTextQuery { terms: string[] fields: string[] matchAny?: boolean contains?: boolean } -export interface SailPointTypeAheadQuery { +interface SailPointTypeAheadQuery { query: string field: string nestedType?: string @@ -113,12 +107,12 @@ export interface SailPointTypeAheadQuery { sortByValue?: boolean } -export interface SailPointQueryResultFilter { +interface SailPointQueryResultFilter { includes?: string[] excludes?: string[] } -export interface SailPointSearchFilter { +interface SailPointSearchFilter { type?: string range?: Record terms?: string[] @@ -154,10 +148,10 @@ export interface SailPointSearchAggregateParams extends SailPointSearchBodyParams, SailPointPaginationParams {} -export type SailPointAccessRequestType = 'GRANT_ACCESS' | 'REVOKE_ACCESS' | 'MODIFY_ACCESS' -export type SailPointRequestedItemType = 'ACCESS_PROFILE' | 'ROLE' | 'ENTITLEMENT' +type SailPointAccessRequestType = 'GRANT_ACCESS' | 'REVOKE_ACCESS' | 'MODIFY_ACCESS' +type SailPointRequestedItemType = 'ACCESS_PROFILE' | 'ROLE' | 'ENTITLEMENT' -export interface SailPointRequestedItem { +interface SailPointRequestedItem { type: SailPointRequestedItemType id: string comment?: string @@ -169,11 +163,11 @@ export interface SailPointRequestedItem { formInstanceId?: string | null } -export type SailPointNestedRequestedItem = Omit & { +type SailPointNestedRequestedItem = Omit & { accountSelection?: SailPointSourceItemRef[] | null } -export interface SailPointAccountItemRef { +interface SailPointAccountItemRef { accountUuid?: string | null nativeIdentity?: string } @@ -183,7 +177,7 @@ export interface SailPointSourceItemRef { accounts?: SailPointAccountItemRef[] | null } -export interface SailPointRequestedForWithItems { +interface SailPointRequestedForWithItems { identityId: string identityType?: 'HUMAN' | 'MACHINE' requestedItems: SailPointNestedRequestedItem[] @@ -197,13 +191,6 @@ export interface SailPointRequestAccessParams extends SailPointCredentials { clientMetadata?: Record | string } -export interface SailPointAccessRequestTracking { - requestedFor?: string - requestedItemsDetails?: Array<{ type?: SailPointRequestedItemType; id?: string }> - attributesHash?: number - accessRequestIds?: string[] -} - export interface SailPointCancelAccessRequestParams extends SailPointCredentials { accountActivityId: string comment: string @@ -228,26 +215,7 @@ export interface SailPointLoadEntitlementsParams extends SailPointCredentials { file?: unknown } -export interface SailPointTask { - id?: string - type?: string - name?: string - uniqueName?: string - description?: string - launcher?: string - created?: string - launched?: string | null - completed?: string | null - completionStatus?: string | null - parentName?: string | null - messages?: Record[] - progress?: string | null - percentComplete?: number - attributes?: Record - returns?: Record[] -} - -export interface SailPointReviewRecommendation { +interface SailPointReviewRecommendation { recommendation?: string | null reasons?: string[] timestamp?: string diff --git a/apps/sim/tools/sap_concur/types.ts b/apps/sim/tools/sap_concur/types.ts index 6b0a70d8118..e2f0d4f9b92 100644 --- a/apps/sim/tools/sap_concur/types.ts +++ b/apps/sim/tools/sap_concur/types.ts @@ -5,7 +5,7 @@ import type { ToolResponse } from '@/tools/types' * operation schema. Every datacenter is published twice — the bare host and its `www-` * twin — except GLZ, which has no twin. */ -export type SapConcurDatacenter = +type SapConcurDatacenter = | 'us.api.concursolutions.com' | 'www-us.api.concursolutions.com' | 'us2.api.concursolutions.com' @@ -25,7 +25,7 @@ export type SapConcurDatacenter = | 'emea-impl.api.concursolutions.com' | 'www-emea-impl.api.concursolutions.com' -export type SapConcurGrantType = 'client_credentials' | 'password' +type SapConcurGrantType = 'client_credentials' | 'password' export interface SapConcurBaseParams { datacenter?: SapConcurDatacenter diff --git a/apps/sim/tools/sap_s4hana/types.ts b/apps/sim/tools/sap_s4hana/types.ts index 4bb1c28de8f..8ea1bc8228a 100644 --- a/apps/sim/tools/sap_s4hana/types.ts +++ b/apps/sim/tools/sap_s4hana/types.ts @@ -1,7 +1,7 @@ import type { ToolResponse } from '@/tools/types' -export type SapDeploymentType = 'cloud_public' | 'cloud_private' | 'on_premise' -export type SapAuthType = 'oauth_client_credentials' | 'basic' +type SapDeploymentType = 'cloud_public' | 'cloud_private' | 'on_premise' +type SapAuthType = 'oauth_client_credentials' | 'basic' export interface SapBaseParams { deploymentType?: SapDeploymentType @@ -297,7 +297,7 @@ export interface CreatePurchaseRequisitionParams extends SapBaseParams { body?: Record | string } -export type ODataMethod = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE' | 'MERGE' +type ODataMethod = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE' | 'MERGE' export interface ODataQueryParams extends SapBaseParams { service: string diff --git a/apps/sim/tools/secrets_manager/types.ts b/apps/sim/tools/secrets_manager/types.ts index 2ed4ae281da..1d7edb3cfa5 100644 --- a/apps/sim/tools/secrets_manager/types.ts +++ b/apps/sim/tools/secrets_manager/types.ts @@ -1,6 +1,6 @@ import type { ToolResponse } from '@/tools/types' -export interface SecretsManagerConnectionConfig { +interface SecretsManagerConnectionConfig { region: string accessKeyId: string secretAccessKey: string @@ -47,7 +47,7 @@ export interface SecretsManagerGetSecretResponse extends ToolResponse { error?: string } -export interface SecretsManagerRotationRules { +interface SecretsManagerRotationRules { automaticallyAfterDays: number | null duration: string | null scheduleExpression: string | null @@ -110,7 +110,7 @@ export interface SecretsManagerDescribeSecretParams extends SecretsManagerConnec secretId: string } -export interface SecretsManagerReplicationStatus { +interface SecretsManagerReplicationStatus { region: string kmsKeyId: string | null status: string | null diff --git a/apps/sim/tools/sendblue/types.ts b/apps/sim/tools/sendblue/types.ts index d7c1fe41f5b..60036c48280 100644 --- a/apps/sim/tools/sendblue/types.ts +++ b/apps/sim/tools/sendblue/types.ts @@ -3,7 +3,7 @@ import type { ToolResponse } from '@/tools/types' /** * iMessage expressive styles supported by Sendblue. */ -export type SendblueSendStyle = +type SendblueSendStyle = | 'celebration' | 'shooting_star' | 'fireworks' @@ -62,7 +62,7 @@ export interface SendblueGetMessageParams extends SendblueBaseParams { /** * Shared shape of a Sendblue message resource returned by the send endpoints. */ -export interface SendblueMessageOutput { +interface SendblueMessageOutput { status: string | null message_handle: string | null account_email: string | null diff --git a/apps/sim/tools/slack/types.ts b/apps/sim/tools/slack/types.ts index bebc1159c26..b947d65c992 100644 --- a/apps/sim/tools/slack/types.ts +++ b/apps/sim/tools/slack/types.ts @@ -1476,7 +1476,7 @@ export interface SlackGetThreadRepliesResponse extends ToolResponse { } } -export interface SlackScheduledMessage { +interface SlackScheduledMessage { id: string channel_id: string post_at: number diff --git a/apps/sim/tools/slack_lists/types.ts b/apps/sim/tools/slack_lists/types.ts index a506194ce13..a8541fefe59 100644 --- a/apps/sim/tools/slack_lists/types.ts +++ b/apps/sim/tools/slack_lists/types.ts @@ -3,10 +3,10 @@ import type { listColumnResponseSchema, listFieldResponseSchema } from '@/tools/ import type { columnSchema, fieldSchema, updateCellSchema } from '@/tools/slack_lists/validation' import type { OutputProperty, ToolResponse } from '@/tools/types' -export type SlackListColumn = z.infer -export type SlackListResponseColumn = z.infer -export type SlackListField = z.infer -export type SlackListCell = z.infer +type SlackListColumn = z.infer +type SlackListResponseColumn = z.infer +type SlackListField = z.infer +type SlackListCell = z.infer export interface SlackListsAuthParams { accessToken: string @@ -58,7 +58,7 @@ export interface SlackListsItemsUpdateParams extends SlackListsAuthParams { cells: SlackListCell[] | string } -export interface SlackListItem { +interface SlackListItem { id: string list_id: string date_created: number @@ -69,7 +69,7 @@ export interface SlackListItem { parent_record_id: string | null } -export interface SlackListSummary { +interface SlackListSummary { id: string title: string schema: SlackListResponseColumn[] diff --git a/apps/sim/tools/sportmonks_core/types.ts b/apps/sim/tools/sportmonks_core/types.ts index 2852a80d8ea..3a249e5f20c 100644 --- a/apps/sim/tools/sportmonks_core/types.ts +++ b/apps/sim/tools/sportmonks_core/types.ts @@ -218,7 +218,7 @@ export interface SportmonksUsage { } /** A single type entry as returned by the "Type by Entity" endpoint. */ -export interface SportmonksTypeEntityEntry { +interface SportmonksTypeEntityEntry { id: number name: string code?: string | null @@ -228,7 +228,7 @@ export interface SportmonksTypeEntityEntry { } /** The per-entity grouping returned by the "Type by Entity" endpoint. */ -export interface SportmonksTypeEntityGroup { +interface SportmonksTypeEntityGroup { updated_at: string types: SportmonksTypeEntityEntry[] } diff --git a/apps/sim/tools/sqs/types.ts b/apps/sim/tools/sqs/types.ts index 4c9bc60d1bc..2c8c62c52e0 100644 --- a/apps/sim/tools/sqs/types.ts +++ b/apps/sim/tools/sqs/types.ts @@ -7,20 +7,20 @@ export interface SqsConnectionConfig { } /** A message attribute in the JSON-safe form Sim tools accept. */ -export interface SqsMessageAttributeInput { +interface SqsMessageAttributeInput { dataType: string stringValue: string } /** A message attribute as projected from a received message. */ -export interface SqsMessageAttributeOutput { +interface SqsMessageAttributeOutput { dataType: string | null stringValue: string | null stringListValues: string[] } /** One entry of the `Failed` list every SQS batch action returns. */ -export interface SqsBatchErrorEntry { +interface SqsBatchErrorEntry { id: string | null senderFault: boolean | null code: string | null @@ -36,7 +36,7 @@ export interface SqsSendMessageParams extends SqsConnectionConfig { messageDeduplicationId?: string | null } -export interface SqsSendMessageBatchEntry { +interface SqsSendMessageBatchEntry { id: string data: Record delaySeconds?: number | null diff --git a/apps/sim/tools/ssh/types.ts b/apps/sim/tools/ssh/types.ts index b64d8d73d61..694e20ba4c1 100644 --- a/apps/sim/tools/ssh/types.ts +++ b/apps/sim/tools/ssh/types.ts @@ -48,25 +48,11 @@ export interface SSHUploadFileParams extends SSHConnectionConfig { overwrite?: boolean } -// Upload Directory parameters -interface SSHUploadDirectoryParams extends SSHConnectionConfig { - localDirectory: string - remoteDirectory: string - recursive?: boolean - concurrency?: number -} - // Download File parameters export interface SSHDownloadFileParams extends SSHConnectionConfig { remotePath: string } -// Download Directory parameters -interface SSHDownloadDirectoryParams extends SSHConnectionConfig { - remotePath: string - recursive?: boolean -} - // List Directory parameters export interface SSHListDirectoryParams extends SSHConnectionConfig { path: string @@ -191,21 +177,3 @@ export interface SSHResponse extends ToolResponse { metadata?: Record } } - -// Union type for all SSH parameters -export type SSHParams = - | SSHExecuteCommandParams - | SSHExecuteScriptParams - | SSHCheckCommandExistsParams - | SSHUploadFileParams - | SSHUploadDirectoryParams - | SSHDownloadFileParams - | SSHDownloadDirectoryParams - | SSHListDirectoryParams - | SSHCheckFileExistsParams - | SSHCreateDirectoryParams - | SSHDeleteFileParams - | SSHMoveRenameParams - | SSHGetSystemInfoParams - | SSHReadFileContentParams - | SSHWriteFileContentParams diff --git a/apps/sim/tools/telegram/types.ts b/apps/sim/tools/telegram/types.ts index e61084ceddd..63a3cba6699 100644 --- a/apps/sim/tools/telegram/types.ts +++ b/apps/sim/tools/telegram/types.ts @@ -198,7 +198,7 @@ export interface TelegramChatFullInfo { linked_chat_id?: number } -export interface TelegramUser { +interface TelegramUser { id: number is_bot: boolean first_name?: string diff --git a/apps/sim/tools/temporal/types.ts b/apps/sim/tools/temporal/types.ts index 6bab71b9503..55134a35f37 100644 --- a/apps/sim/tools/temporal/types.ts +++ b/apps/sim/tools/temporal/types.ts @@ -1,12 +1,12 @@ import type { ToolResponse } from '@/tools/types' -export interface TemporalBaseParams { +interface TemporalBaseParams { serverUrl: string namespace: string apiKey?: string } -export interface TemporalExecutionSummary { +interface TemporalExecutionSummary { workflowId: string | null runId: string | null workflowType: string | null @@ -18,7 +18,7 @@ export interface TemporalExecutionSummary { taskQueue: string | null } -export interface TemporalPendingActivity { +interface TemporalPendingActivity { activityId: string | null activityType: string | null state: string | null @@ -26,7 +26,7 @@ export interface TemporalPendingActivity { lastFailureMessage: string | null } -export interface TemporalHistoryEventSummary { +interface TemporalHistoryEventSummary { eventId: number | null eventTime: string | null eventType: string | null @@ -189,7 +189,7 @@ export interface TemporalResetWorkflowResponse extends ToolResponse { } } -export interface TemporalScheduleSummary { +interface TemporalScheduleSummary { scheduleId: string | null workflowType: string | null paused: boolean diff --git a/apps/sim/tools/textract/types.ts b/apps/sim/tools/textract/types.ts index aea61f8b660..cbe603c6883 100644 --- a/apps/sim/tools/textract/types.ts +++ b/apps/sim/tools/textract/types.ts @@ -2,7 +2,7 @@ import type { RawFileInput } from '@/lib/uploads/utils/file-utils' import type { UserFile } from '@/executor/types' import type { ToolResponse } from '@/tools/types' -export type TextractProcessingMode = 'sync' | 'async' +type TextractProcessingMode = 'sync' | 'async' export interface TextractParserInput { accessKeyId: string @@ -28,7 +28,7 @@ export interface TextractParserV2Input { queries?: TextractQuery[] } -export type TextractFeatureType = 'TABLES' | 'FORMS' | 'QUERIES' | 'SIGNATURES' | 'LAYOUT' +type TextractFeatureType = 'TABLES' | 'FORMS' | 'QUERIES' | 'SIGNATURES' | 'LAYOUT' interface TextractQuery { Text: string @@ -95,16 +95,6 @@ export interface TextractParserOutput extends ToolResponse { output: TextractNormalizedOutput } -export interface TextractAnalyzeExpenseInput { - accessKeyId: string - secretAccessKey: string - region: string - processingMode?: TextractProcessingMode - filePath?: string - file?: RawFileInput - s3Uri?: string -} - export interface TextractAnalyzeExpenseV2Input { accessKeyId: string secretAccessKey: string @@ -157,16 +147,6 @@ export interface TextractAnalyzeExpenseOutput extends ToolResponse { } } -export interface TextractAnalyzeIdInput { - accessKeyId: string - secretAccessKey: string - region: string - filePath?: string - file?: RawFileInput - filePathBack?: string - fileBack?: RawFileInput -} - export interface TextractAnalyzeIdV2Input { accessKeyId: string secretAccessKey: string diff --git a/apps/sim/tools/thrive/types.ts b/apps/sim/tools/thrive/types.ts index 0ae43ce097e..1dc04aeeb52 100644 --- a/apps/sim/tools/thrive/types.ts +++ b/apps/sim/tools/thrive/types.ts @@ -4,14 +4,14 @@ import type { OutputProperty, ToolResponse } from '@/tools/types' * Credentials and region shared by every Thrive tool. * Thrive uses HTTP Basic auth (Tenant ID as username, API key as password). */ -export interface ThriveBaseParams { +interface ThriveBaseParams { tenantId: string apiKey: string /** Region-specific API host, e.g. `public.api.learn.link`. Defaults to Production. */ host?: string } -export interface ThrivePagination { +interface ThrivePagination { totalResults: number totalPages: number page: number diff --git a/apps/sim/tools/tiktok/types.ts b/apps/sim/tools/tiktok/types.ts index bb099691ba1..ff31aa9ccf2 100644 --- a/apps/sim/tools/tiktok/types.ts +++ b/apps/sim/tools/tiktok/types.ts @@ -4,7 +4,7 @@ import type { OutputProperty, ToolFileData, ToolResponse } from '@/tools/types' /** * Base params that include OAuth access token */ -export interface TikTokBaseParams { +interface TikTokBaseParams { accessToken: string } diff --git a/apps/sim/tools/tinyfish/types.ts b/apps/sim/tools/tinyfish/types.ts index 493d86c304d..94c921ce9aa 100644 --- a/apps/sim/tools/tinyfish/types.ts +++ b/apps/sim/tools/tinyfish/types.ts @@ -7,23 +7,19 @@ import type { ToolResponse } from '@/tools/types' * Context Profile, which is saved logged-in state selected with `use_profile` * and `profile_id`. */ -export type TinyFishBrowserProfile = 'lite' | 'stealth' +type TinyFishBrowserProfile = 'lite' | 'stealth' /** Agent behavior mode. `strict` fails fast, which suits test automation. */ -export type TinyFishAgentMode = 'default' | 'strict' +type TinyFishAgentMode = 'default' | 'strict' /** Lifecycle states a TinyFish run can be in. */ -export type TinyFishRunStatus = 'PENDING' | 'RUNNING' | 'COMPLETED' | 'FAILED' | 'CANCELLED' +type TinyFishRunStatus = 'PENDING' | 'RUNNING' | 'COMPLETED' | 'FAILED' | 'CANCELLED' /** Classification TinyFish attaches to a failed run. */ -export type TinyFishErrorCategory = - | 'SYSTEM_FAILURE' - | 'AGENT_FAILURE' - | 'BILLING_FAILURE' - | 'UNKNOWN' +type TinyFishErrorCategory = 'SYSTEM_FAILURE' | 'AGENT_FAILURE' | 'BILLING_FAILURE' | 'UNKNOWN' /** Output format the Fetch API extracts page content into. */ -export type TinyFishFetchFormat = 'markdown' | 'html' | 'json' +type TinyFishFetchFormat = 'markdown' | 'html' | 'json' interface TinyFishApiKeyParams { apiKey: string diff --git a/apps/sim/tools/trigger_dev/types.ts b/apps/sim/tools/trigger_dev/types.ts index b50c072925f..7d277693d17 100644 --- a/apps/sim/tools/trigger_dev/types.ts +++ b/apps/sim/tools/trigger_dev/types.ts @@ -218,7 +218,7 @@ export interface TriggerDevQueue { } /** Normalized environment variable returned by the env var tools */ -export interface TriggerDevEnvVar { +interface TriggerDevEnvVar { name: string value: string } @@ -248,14 +248,14 @@ export interface TriggerDevRunResult { } /** Span event entry attached to a run event or trace span */ -export interface TriggerDevSpanEvent { +interface TriggerDevSpanEvent { name: string | null time: string | null properties: Record | null } /** Normalized run event returned by the run events tool */ -export interface TriggerDevRunEvent { +interface TriggerDevRunEvent { spanId: string | null parentId: string | null runId: string | null @@ -533,7 +533,7 @@ export interface TriggerDevBatchTriggerTaskResponse extends ToolResponse { } /** Normalized batch returned by the get batch tool */ -export interface TriggerDevBatch { +interface TriggerDevBatch { id: string status: string idempotencyKey: string | null diff --git a/apps/sim/tools/uptimerobot/types.ts b/apps/sim/tools/uptimerobot/types.ts index 57e15e0f82c..3beb425e19b 100644 --- a/apps/sim/tools/uptimerobot/types.ts +++ b/apps/sim/tools/uptimerobot/types.ts @@ -38,19 +38,19 @@ export async function uptimeRobotError(response: Response): Promise { // region Shared object shapes -export interface UptimeRobotTag { +interface UptimeRobotTag { id: number name: string color: string | null } -export interface UptimeRobotAssignedAlertContact { +interface UptimeRobotAssignedAlertContact { alertContactId: number threshold: number recurrence: number } -export interface UptimeRobotLastIncident { +interface UptimeRobotLastIncident { id: string status: string | null cause: number | null @@ -147,7 +147,7 @@ export interface UptimeRobotIncidentSummary { includeInReports: boolean | null } -export interface UptimeRobotIncidentRootCause { +interface UptimeRobotIncidentRootCause { url: string | null httpResponseCode: number | null responseDownloadUrl: string | null diff --git a/apps/sim/tools/vanta/types.ts b/apps/sim/tools/vanta/types.ts index 6a0609ced5d..33c56be705a 100644 --- a/apps/sim/tools/vanta/types.ts +++ b/apps/sim/tools/vanta/types.ts @@ -3,13 +3,13 @@ import type { ToolResponse } from '@/tools/types' export type VantaRegion = 'us' | 'gov' -export interface VantaBaseParams { +interface VantaBaseParams { clientId: string clientSecret: string region?: VantaRegion } -export interface VantaPaginationParams { +interface VantaPaginationParams { pageSize?: number pageCursor?: string } @@ -256,18 +256,18 @@ export interface VantaControlDetail extends VantaControl { numTestsTotal: number | null } -export interface VantaTestVersion { +interface VantaTestVersion { major: number | null minor: number | null } -export interface VantaTestDeactivatedStatusInfo { +interface VantaTestDeactivatedStatusInfo { isDeactivated: boolean | null deactivatedReason: string | null lastUpdatedDate: string | null } -export interface VantaTestRemediationStatusInfo { +interface VantaTestRemediationStatusInfo { status: string | null soonestRemediateByDate: string | null itemCount: number | null @@ -312,7 +312,7 @@ export interface VantaDocument { url: string | null } -export interface VantaDocumentDeactivatedStatus { +interface VantaDocumentDeactivatedStatus { isDeactivated: boolean | null reason: string | null creationDate: string | null @@ -328,7 +328,7 @@ export interface VantaDocumentDetail extends VantaDocument { deactivatedStatus: VantaDocumentDeactivatedStatus | null } -export interface VantaUploadedByActor { +interface VantaUploadedByActor { id: string | null type: string | null } @@ -347,26 +347,26 @@ export interface VantaUploadedFile { url: string | null } -export interface VantaPersonName { +interface VantaPersonName { first: string | null last: string | null display: string | null } -export interface VantaPersonEmployment { +interface VantaPersonEmployment { status: string | null startDate: string | null endDate: string | null jobTitle: string | null } -export interface VantaPersonLeaveInfo { +interface VantaPersonLeaveInfo { status: string | null startDate: string | null endDate: string | null } -export interface VantaPersonTasksSummary { +interface VantaPersonTasksSummary { status: string | null dueDate: string | null completionDate: string | null @@ -389,7 +389,7 @@ export interface VantaPolicyDocument { url: string | null } -export interface VantaPolicyLatestApprovedVersion { +interface VantaPolicyLatestApprovedVersion { versionId: string | null documents: VantaPolicyDocument[] } @@ -404,7 +404,7 @@ export interface VantaPolicy { latestApprovedVersion: VantaPolicyLatestApprovedVersion | null } -export interface VantaVendorAuthDetails { +interface VantaVendorAuthDetails { method: string | null passwordMFA: boolean | null passwordMinimumLength: number | null @@ -412,17 +412,17 @@ export interface VantaVendorAuthDetails { passwordRequiresSymbol: boolean | null } -export interface VantaVendorContractAmount { +interface VantaVendorContractAmount { amount: number | null currency: string | null } -export interface VantaVendorDecision { +interface VantaVendorDecision { status: string | null lastUpdatedAt: string | null } -export interface VantaVendorProcurementRequest { +interface VantaVendorProcurementRequest { url: string | null service: string | null } @@ -457,7 +457,7 @@ export interface VantaVendor { linkedTaskTrackerTaskProcurementRequest: VantaVendorProcurementRequest | null } -export interface VantaVulnerabilityDeactivateMetadata { +interface VantaVulnerabilityDeactivateMetadata { isVulnDeactivatedIndefinitely: boolean | null deactivatedUntilDate: string | null deactivationReason: string | null @@ -489,7 +489,7 @@ export interface VantaVulnerability { deactivateMetadata: VantaVulnerabilityDeactivateMetadata | null } -export interface VantaOperatingSystem { +interface VantaOperatingSystem { type: string | null version: string | null } @@ -539,7 +539,7 @@ export interface VantaVulnerabilityRemediation { remediationDate: string | null } -export interface VantaAssetTag { +interface VantaAssetTag { key: string | null value: string | null } diff --git a/apps/sim/tools/windchill/types.ts b/apps/sim/tools/windchill/types.ts index 075fb5f645f..8ae67795c0f 100644 --- a/apps/sim/tools/windchill/types.ts +++ b/apps/sim/tools/windchill/types.ts @@ -287,13 +287,13 @@ export interface WindchillDocumentUsageLink { children: WindchillDocumentUsageLink[] } -export interface WindchillPageInfo { +interface WindchillPageInfo { count: number totalCount: number | null nextLink: string | null } -export type WindchillAttributeValue = +type WindchillAttributeValue = | string | number | boolean @@ -301,7 +301,7 @@ export type WindchillAttributeValue = | WindchillAttributeValue[] | { [key: string]: WindchillAttributeValue } -export interface WindchillCreateDocumentInput { +interface WindchillCreateDocumentInput { name: string containerOid: string number?: string @@ -311,12 +311,12 @@ export interface WindchillCreateDocumentInput { attributes?: Record } -export interface WindchillUpdateDocumentInput { +interface WindchillUpdateDocumentInput { id: string attributes: Record } -export interface WindchillSecurityLabelInput { +interface WindchillSecurityLabelInput { id: string labels: Record } diff --git a/apps/sim/tools/wiza/types.ts b/apps/sim/tools/wiza/types.ts index afe75b04d25..704fb4cd8c9 100644 --- a/apps/sim/tools/wiza/types.ts +++ b/apps/sim/tools/wiza/types.ts @@ -13,12 +13,12 @@ export interface WizaGetCreditsResponse extends ToolResponse { } } -export interface WizaIncludeExcludeFilter { +interface WizaIncludeExcludeFilter { v: string s: 'i' | 'e' } -export interface WizaLocationFilter { +interface WizaLocationFilter { v: string | { country?: string; state?: string; city?: string } b: 'country' | 'state' | 'city' s: 'i' | 'e' diff --git a/apps/sim/tools/wordpress/types.ts b/apps/sim/tools/wordpress/types.ts index 6c855c6d2aa..038865e09d4 100644 --- a/apps/sim/tools/wordpress/types.ts +++ b/apps/sim/tools/wordpress/types.ts @@ -14,9 +14,9 @@ interface WordPressBaseParams { export const WORDPRESS_COM_API_BASE = 'https://public-api.wordpress.com/wp/v2/sites' -export type PostStatus = 'publish' | 'draft' | 'pending' | 'private' | 'future' +type PostStatus = 'publish' | 'draft' | 'pending' | 'private' | 'future' -export type CommentStatus = 'approved' | 'hold' | 'spam' | 'trash' +type CommentStatus = 'approved' | 'hold' | 'spam' | 'trash' export interface WordPressCreatePostParams extends WordPressBaseParams { title: string diff --git a/apps/sim/tools/zoom/types.ts b/apps/sim/tools/zoom/types.ts index e7818856ca0..0b595b11222 100644 --- a/apps/sim/tools/zoom/types.ts +++ b/apps/sim/tools/zoom/types.ts @@ -247,7 +247,7 @@ interface ZoomBaseParams { } // Meeting types -export type ZoomMeetingType = 1 | 2 | 3 | 8 // 1=instant, 2=scheduled, 3=recurring no fixed time, 8=recurring fixed time +type ZoomMeetingType = 1 | 2 | 3 | 8 // 1=instant, 2=scheduled, 3=recurring no fixed time, 8=recurring fixed time interface ZoomMeetingSettings { host_video?: boolean diff --git a/apps/sim/tools/zoominfo/types.ts b/apps/sim/tools/zoominfo/types.ts index b1693cad039..83cc88819fd 100644 --- a/apps/sim/tools/zoominfo/types.ts +++ b/apps/sim/tools/zoominfo/types.ts @@ -1,6 +1,6 @@ import type { ToolResponse } from '@/tools/types' -export interface ZoomInfoBaseParams { +interface ZoomInfoBaseParams { clientId: string clientSecret: string } diff --git a/scripts/check-unused-exports.baseline.json b/scripts/check-unused-exports.baseline.json index fa47270c80d..ceaac73e6ae 100644 --- a/scripts/check-unused-exports.baseline.json +++ b/scripts/check-unused-exports.baseline.json @@ -5516,26 +5516,8 @@ "apps/sim/stores/workflows/workflow/types.ts#Subflow", "apps/sim/stores/workflows/workflow/types.ts#WorkflowActions", "apps/sim/stores/workflows/workflow/types.ts#isValidSubflowType", - "apps/sim/tools/a2a/types.ts#A2ABaseParams", - "apps/sim/tools/affinity/types.ts#AffinityAuthParams", - "apps/sim/tools/affinity/types.ts#AffinityCollectionMeta", - "apps/sim/tools/affinity/types.ts#AffinityNoteIdParams", - "apps/sim/tools/affinity/types.ts#AffinityTotalCountParams", "apps/sim/tools/affinity/utils.ts#AFFINITY_MAX_BATCH_FIELD_UPDATES", "apps/sim/tools/affinity/utils.ts#parseOptionalJsonArray", - "apps/sim/tools/agentphone/types.ts#AgentPhoneReactionType", - "apps/sim/tools/agiloft/types.ts#AgiloftDeleteRule", - "apps/sim/tools/ahrefs/types.ts#AhrefsHistory", - "apps/sim/tools/ahrefs/types.ts#AhrefsRankTrackerDevice", - "apps/sim/tools/ahrefs/types.ts#AhrefsTargetMode", - "apps/sim/tools/ahrefs/types.ts#AhrefsVolumeMode", - "apps/sim/tools/appconfig/types.ts#AppConfigApplication", - "apps/sim/tools/appconfig/types.ts#AppConfigConfigurationProfile", - "apps/sim/tools/appconfig/types.ts#AppConfigDeploymentDetail", - "apps/sim/tools/appconfig/types.ts#AppConfigDeploymentStrategy", - "apps/sim/tools/appconfig/types.ts#AppConfigDeploymentSummary", - "apps/sim/tools/appconfig/types.ts#AppConfigEnvironment", - "apps/sim/tools/appconfig/types.ts#AppConfigHostedConfigurationVersionSummary", "apps/sim/tools/arxiv/utils.ts#cleanText", "apps/sim/tools/arxiv/utils.ts#extractAuthors", "apps/sim/tools/arxiv/utils.ts#extractCategories", @@ -5547,41 +5529,16 @@ "apps/sim/tools/ashby/utils.ts#FILE_HANDLE_OUTPUT", "apps/sim/tools/ashby/utils.ts#HIRING_TEAM_OUTPUT", "apps/sim/tools/ashby/utils.ts#SOURCE_SUMMARY_OUTPUT", - "apps/sim/tools/athena/types.ts#AthenaColumn", - "apps/sim/tools/athena/types.ts#AthenaDatabase", - "apps/sim/tools/athena/types.ts#AthenaEngineVersion", - "apps/sim/tools/athena/types.ts#AthenaNamedQuery", - "apps/sim/tools/athena/types.ts#AthenaPreparedStatement", - "apps/sim/tools/athena/types.ts#AthenaQueryExecutionSummary", - "apps/sim/tools/athena/types.ts#AthenaTableMetadata", - "apps/sim/tools/athena/types.ts#AthenaUnprocessedQueryExecutionId", "apps/sim/tools/attio/types.ts#ACTOR_OUTPUT_PROPERTIES", "apps/sim/tools/attio/types.ts#ASSIGNEE_OUTPUT_PROPERTIES", - "apps/sim/tools/attio/types.ts#AttioNoteTag", "apps/sim/tools/attio/types.ts#LINKED_RECORD_OUTPUT_PROPERTIES", "apps/sim/tools/attio/types.ts#RECORD_ID_OUTPUT_PROPERTIES", - "apps/sim/tools/azure_data_explorer/types.ts#AzureDataExplorerColumn", "apps/sim/tools/azure_data_explorer/utils.ts#AzureDataExplorerIngestMode", - "apps/sim/tools/azure_devops/types.ts#AzureDevOpsBaseParams", - "apps/sim/tools/azure_devops/types.ts#AzureDevOpsBuild", - "apps/sim/tools/azure_devops/types.ts#AzureDevOpsBuildLog", - "apps/sim/tools/azure_devops/types.ts#AzureDevOpsPipeline", - "apps/sim/tools/azure_devops/types.ts#AzureDevOpsPipelineConfiguration", - "apps/sim/tools/azure_devops/types.ts#AzureDevOpsPipelineDetail", - "apps/sim/tools/azure_devops/types.ts#AzureDevOpsPipelineRun", - "apps/sim/tools/azure_devops/types.ts#AzureDevOpsPipelineRunDetail", "apps/sim/tools/bitbucket/types.ts#BITBUCKET_COMMENT_RESOLUTION_OUTPUT_PROPERTIES", "apps/sim/tools/bitbucket/types.ts#BITBUCKET_PAGE_OUTPUT_PROPERTIES", "apps/sim/tools/bitbucket/types.ts#BITBUCKET_PIPELINE_COMMAND_OUTPUT_PROPERTIES", "apps/sim/tools/bitbucket/types.ts#BITBUCKET_PR_ENDPOINT_OUTPUT_PROPERTIES", "apps/sim/tools/bitbucket/types.ts#BITBUCKET_USER_OUTPUT_PROPERTIES", - "apps/sim/tools/bitbucket/types.ts#BitbucketAuthParams", - "apps/sim/tools/bitbucket/types.ts#BitbucketMergeStrategy", - "apps/sim/tools/bitbucket/types.ts#BitbucketPaginationParams", - "apps/sim/tools/bitbucket/types.ts#BitbucketPipelineListRefType", - "apps/sim/tools/bitbucket/types.ts#BitbucketPipelineListSelectorType", - "apps/sim/tools/bitbucket/types.ts#BitbucketPipelineStatus", - "apps/sim/tools/bitbucket/types.ts#BitbucketPipelineTriggerType", "apps/sim/tools/bitbucket/utils.ts#BITBUCKET_MAX_CHARACTERS", "apps/sim/tools/bitbucket/utils.ts#BITBUCKET_MAX_LOG_CHARACTERS", "apps/sim/tools/bitbucket/utils.ts#BITBUCKET_MIN_LOG_RANGE_BYTES", @@ -5590,35 +5547,8 @@ "apps/sim/tools/bitbucket/utils.ts#positiveBitbucketInteger", "apps/sim/tools/brex/idempotency.ts#BREX_IDEMPOTENCY_WINDOW_SECONDS", "apps/sim/tools/brex/idempotency.ts#resolveBrexIdempotencyKey", - "apps/sim/tools/brex/types.ts#BrexBudget", - "apps/sim/tools/brex/types.ts#BrexCard", - "apps/sim/tools/brex/types.ts#BrexCardAccount", - "apps/sim/tools/brex/types.ts#BrexCardTransaction", - "apps/sim/tools/brex/types.ts#BrexCashAccount", - "apps/sim/tools/brex/types.ts#BrexCashTransaction", - "apps/sim/tools/brex/types.ts#BrexDepartment", - "apps/sim/tools/brex/types.ts#BrexExpense", - "apps/sim/tools/brex/types.ts#BrexExpenseReceipt", - "apps/sim/tools/brex/types.ts#BrexLocation", - "apps/sim/tools/brex/types.ts#BrexMoney", - "apps/sim/tools/brex/types.ts#BrexSpendLimit", - "apps/sim/tools/brex/types.ts#BrexSpendLimitPeriodBalance", - "apps/sim/tools/brex/types.ts#BrexStatement", - "apps/sim/tools/brex/types.ts#BrexTitle", - "apps/sim/tools/brex/types.ts#BrexTransfer", - "apps/sim/tools/brex/types.ts#BrexUser", - "apps/sim/tools/brex/types.ts#BrexVendor", "apps/sim/tools/buffer/types.ts#BUFFER_SCHEDULING_TYPES", "apps/sim/tools/buffer/types.ts#BUFFER_SHARE_MODES", - "apps/sim/tools/buffer/types.ts#BufferAccount", - "apps/sim/tools/buffer/types.ts#BufferAsset", - "apps/sim/tools/buffer/types.ts#BufferIdeaGroup", - "apps/sim/tools/buffer/types.ts#BufferOrganization", - "apps/sim/tools/buffer/types.ts#BufferPageInfo", - "apps/sim/tools/buffer/types.ts#BufferPostError", - "apps/sim/tools/buffer/types.ts#BufferPostStatus", - "apps/sim/tools/buffer/types.ts#BufferSchedulingType", - "apps/sim/tools/buffer/types.ts#BufferShareMode", "apps/sim/tools/calcom/types.ts#ATTENDEE_OUTPUT_PROPERTIES", "apps/sim/tools/calcom/types.ts#AVAILABILITY_OUTPUT", "apps/sim/tools/calcom/types.ts#AVAILABILITY_OUTPUT_PROPERTIES", @@ -5628,65 +5558,18 @@ "apps/sim/tools/calcom/types.ts#OVERRIDE_OUTPUT_PROPERTIES", "apps/sim/tools/calcom/types.ts#PAGINATION_OUTPUT", "apps/sim/tools/calcom/types.ts#PAGINATION_OUTPUT_PROPERTIES", - "apps/sim/tools/calendly/types.ts#CalendlyInviteeResource", - "apps/sim/tools/calendly/types.ts#CalendlyPagination", - "apps/sim/tools/calendly/types.ts#CalendlyUserResource", - "apps/sim/tools/cbinsights/types.ts#CbInsightsPagedParams", "apps/sim/tools/cbinsights/utils.ts#CBINSIGHTS_API_BASE", "apps/sim/tools/cbinsights/utils.ts#LIMIT_MAX", "apps/sim/tools/cbinsights/utils.ts#LIMIT_MIN", "apps/sim/tools/cbinsights/utils.ts#MAX_ORG_IDS", "apps/sim/tools/cbinsights/utils.ts#parseListParam", "apps/sim/tools/circleback/types.ts#ATTENDEE_OUTPUT_PROPERTIES", - "apps/sim/tools/circleback/types.ts#CirclebackActionItem", - "apps/sim/tools/circleback/types.ts#CirclebackAssignee", - "apps/sim/tools/circleback/types.ts#CirclebackAttendee", - "apps/sim/tools/circleback/types.ts#CirclebackExternalLink", - "apps/sim/tools/circleback/types.ts#CirclebackMeeting", - "apps/sim/tools/circleback/types.ts#CirclebackPerson", - "apps/sim/tools/circleback/types.ts#CirclebackTag", "apps/sim/tools/circleback/types.ts#MEETING_ACTION_ITEM_OUTPUT_PROPERTIES", "apps/sim/tools/circleback/utils.ts#RawCirclebackAttendee", "apps/sim/tools/circleback/utils.ts#RawCirclebackMeetingActionItem", - "apps/sim/tools/clerk/types.ts#ClerkOrganizationInvitationPublicUserData", - "apps/sim/tools/clerk/types.ts#ClerkOrganizationMembershipPublicUserData", "apps/sim/tools/clickhouse/types.ts#CLICKHOUSE_COLUMN_OUTPUT_PROPERTIES", - "apps/sim/tools/clickhouse/types.ts#ClickHouseConnectionConfig", "apps/sim/tools/clickup/shared.ts#mapClickUpUser", - "apps/sim/tools/clickup/types.ts#ClickUpTimeEntryLocation", - "apps/sim/tools/cloudflare/types.ts#CloudflareRawCertificate", - "apps/sim/tools/cloudflare/types.ts#CloudflareRawDnsAnalyticsAggregate", - "apps/sim/tools/cloudflare/types.ts#CloudflareRawRule", - "apps/sim/tools/cloudflare/types.ts#CloudflareRawValidationRecord", - "apps/sim/tools/cloudflare/types.ts#CloudflareResultInfo", "apps/sim/tools/cloudflare/utils.ts#parseJsonParam", - "apps/sim/tools/cloudtrail/types.ts#CloudTrailAdvancedEventSelector", - "apps/sim/tools/cloudtrail/types.ts#CloudTrailEvent", - "apps/sim/tools/cloudtrail/types.ts#CloudTrailEventDataStoreSummary", - "apps/sim/tools/cloudtrail/types.ts#CloudTrailLookupAttributeKey", - "apps/sim/tools/cloudtrail/types.ts#CloudTrailTrail", - "apps/sim/tools/cloudwatch/types.ts#CloudWatchAlarmHistoryItemType", - "apps/sim/tools/cloudwatch/types.ts#CloudWatchAlarmHistoryScanBy", - "apps/sim/tools/cloudwatch/types.ts#CloudWatchMuteDurationUnit", - "apps/sim/tools/coda/types.ts#CodaFolderChild", - "apps/sim/tools/coda/types.ts#CodaIcon", - "apps/sim/tools/coda/types.ts#CodaListResponse", - "apps/sim/tools/coda/types.ts#CodaPageContentParams", - "apps/sim/tools/coda/types.ts#CodaPageRef", - "apps/sim/tools/coda/types.ts#CodaPaginationParams", - "apps/sim/tools/coda/types.ts#CodaPerson", - "apps/sim/tools/coda/types.ts#CodaPrincipalType", - "apps/sim/tools/coda/types.ts#CodaTableParams", - "apps/sim/tools/coda/types.ts#CodaTableRef", - "apps/sim/tools/coda/types.ts#CodaWorkspaceRef", - "apps/sim/tools/codepipeline/types.ts#CodePipelineActionDeclaration", - "apps/sim/tools/codepipeline/types.ts#CodePipelineActionExecutionDetail", - "apps/sim/tools/codepipeline/types.ts#CodePipelineActionState", - "apps/sim/tools/codepipeline/types.ts#CodePipelineApprovalStatus", - "apps/sim/tools/codepipeline/types.ts#CodePipelineRetryMode", - "apps/sim/tools/codepipeline/types.ts#CodePipelineStageDeclaration", - "apps/sim/tools/codepipeline/types.ts#CodePipelineStageState", - "apps/sim/tools/codepipeline/types.ts#CodePipelineTransitionType", "apps/sim/tools/confluence/types.ts#ATTACHMENT_ITEM_PROPERTIES", "apps/sim/tools/confluence/types.ts#ATTACHMENT_OUTPUT", "apps/sim/tools/confluence/types.ts#COMMENT_BODY_OUTPUT_PROPERTIES", @@ -5701,19 +5584,6 @@ "apps/sim/tools/confluence/types.ts#SPACE_ITEM_PROPERTIES", "apps/sim/tools/confluence/types.ts#SUCCESS_OUTPUT", "apps/sim/tools/context_dev/hosting.ts#CONTEXT_DEV_API_KEY_PREFIX", - "apps/sim/tools/convex/types.ts#ConvexBaseParams", - "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeAggregateFiltersSpec", - "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeApiError", - "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeIndicatorListResponse", - "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeIndicatorMetadata", - "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeVulnerabilityApp", - "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeVulnerabilityCve", - "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeVulnerabilityHostInfo", - "apps/sim/tools/crowdstrike/types.ts#CrowdStrikeVulnerabilityRemediation", - "apps/sim/tools/crunchbase/types.ts#CrunchbaseDateWithPrecision", - "apps/sim/tools/crunchbase/types.ts#CrunchbaseLink", - "apps/sim/tools/crunchbase/types.ts#CrunchbaseLocationIdentifier", - "apps/sim/tools/crunchbase/types.ts#CrunchbaseMoney", "apps/sim/tools/crunchbase/utils.ts#CRUNCHBASE_AUTOCOMPLETE_COLLECTIONS=CRUNCHBASE_COLLECTIONS=CRUNCHBASE_METADATA_COLLECTIONS", "apps/sim/tools/crunchbase/utils.ts#MAX_PREDICATES", "apps/sim/tools/crunchbase/utils.ts#MAX_PREDICATE_VALUES", @@ -5724,61 +5594,26 @@ "apps/sim/tools/crunchbase/utils.ts#normalizeOrder", "apps/sim/tools/crunchbase/utils.ts#normalizePredicates", "apps/sim/tools/crunchbase/utils.ts#parseArrayParam", - "apps/sim/tools/databricks/types.ts#DatabricksCluster", - "apps/sim/tools/datadog/types.ts#DashboardLayoutType", - "apps/sim/tools/datadog/types.ts#EventData", - "apps/sim/tools/datadog/types.ts#IncidentSeverity", - "apps/sim/tools/datadog/types.ts#MetricPoint", - "apps/sim/tools/datadog/types.ts#MetricType", - "apps/sim/tools/datadog/types.ts#SecuritySignalArchiveReason", - "apps/sim/tools/datadog/types.ts#SecuritySignalState", - "apps/sim/tools/datadog/types.ts#SloTimeframe", - "apps/sim/tools/datadog/types.ts#SloType", - "apps/sim/tools/datadog/types.ts#SyntheticsTestPauseStatus", "apps/sim/tools/datagma/hosting.ts#DATAGMA_API_KEY_PREFIX", - "apps/sim/tools/daytona/types.ts#DaytonaFileInfo", "apps/sim/tools/daytona/utils.ts#DAYTONA_TOOLBOX_BASE_URL", - "apps/sim/tools/deployments/types.ts#DeploymentVersionSummary", "apps/sim/tools/docusign/types.ts#ENVELOPE_OUTPUT_PROPERTIES", "apps/sim/tools/docusign/types.ts#RECIPIENT_OUTPUT_PROPERTIES", "apps/sim/tools/docusign/types.ts#TEMPLATE_OUTPUT_PROPERTIES", - "apps/sim/tools/downdetector/types.ts#DowndetectorAttribution", - "apps/sim/tools/downdetector/types.ts#DowndetectorCategory", - "apps/sim/tools/downdetector/types.ts#DowndetectorCompany", - "apps/sim/tools/downdetector/types.ts#DowndetectorCompanySummary", - "apps/sim/tools/downdetector/types.ts#DowndetectorEvent", - "apps/sim/tools/downdetector/types.ts#DowndetectorIndicator", - "apps/sim/tools/downdetector/types.ts#DowndetectorProvider", - "apps/sim/tools/downdetector/types.ts#DowndetectorReportBucket", - "apps/sim/tools/downdetector/types.ts#DowndetectorSite", - "apps/sim/tools/downdetector/types.ts#DowndetectorSiteCompany", - "apps/sim/tools/dropbox/types.ts#DropboxMetadata", "apps/sim/tools/dropcontact/hosting.ts#DROPCONTACT_API_KEY_PREFIX", "apps/sim/tools/dropcontact/types.ts#DROPCONTACT_EMAIL_ITEM_OUTPUT_PROPERTIES", - "apps/sim/tools/dropcontact/types.ts#DropcontactBaseParams", "apps/sim/tools/dynatrace/outputs.ts#entityStubProperties", "apps/sim/tools/dynatrace/outputs.ts#managementZoneProperties", - "apps/sim/tools/dynatrace/types.ts#DynatraceBaseParams", - "apps/sim/tools/dynatrace/types.ts#DynatraceMetricSeries", "apps/sim/tools/dynatrace/utils.ts#mapEntityStub", "apps/sim/tools/dynatrace/utils.ts#mapManagementZones", - "apps/sim/tools/elevenlabs/types.ts#ElevenLabsModelLanguage", - "apps/sim/tools/elevenlabs/types.ts#ElevenLabsVoiceSettings", "apps/sim/tools/embeddings/index.ts#EmbeddingsParams", "apps/sim/tools/embeddings/index.ts#EmbeddingsResponse", "apps/sim/tools/embeddings/index.ts#createEmbeddingTool", "apps/sim/tools/enrow/hosting.ts#ENROW_API_KEY_PREFIX", - "apps/sim/tools/enrow/types.ts#EnrowBaseParams", "apps/sim/tools/error-extractors.ts#ErrorExtractor", - "apps/sim/tools/exa/types.ts#ExaAgentEffort", - "apps/sim/tools/exa/types.ts#ExaSearchType", "apps/sim/tools/findymail/hosting.ts#FINDYMAIL_API_KEY_PREFIX", "apps/sim/tools/findymail/types.ts#FINDYMAIL_CONTACT_OUTPUT_PROPERTIES", "apps/sim/tools/findymail/types.ts#FINDYMAIL_EMPLOYEE_OUTPUT_PROPERTIES", "apps/sim/tools/findymail/types.ts#FINDYMAIL_TECHNOLOGY_OUTPUT_PROPERTIES", - "apps/sim/tools/findymail/types.ts#FindymailContact", - "apps/sim/tools/findymail/types.ts#FindymailEmployee", - "apps/sim/tools/findymail/types.ts#FindymailTechnology", "apps/sim/tools/firecrawl/hosting.ts#FIRECRAWL_API_KEY_PREFIX", "apps/sim/tools/firecrawl/types.ts#CRAWL_METADATA_OUTPUT", "apps/sim/tools/firecrawl/types.ts#CRAWL_METADATA_OUTPUT_PROPERTIES", @@ -5786,7 +5621,6 @@ "apps/sim/tools/firecrawl/types.ts#SEARCH_METADATA_OUTPUT", "apps/sim/tools/firecrawl/types.ts#SEARCH_METADATA_OUTPUT_PROPERTIES", "apps/sim/tools/firecrawl/types.ts#SEARCH_RESULT_OUTPUT", - "apps/sim/tools/flint/types.ts#FlintTaskCreatedOutput", "apps/sim/tools/github/types.ts#BRANCH_REF_OUTPUT_PROPERTIES", "apps/sim/tools/github/types.ts#COMMIT_DATA_OUTPUT_PROPERTIES", "apps/sim/tools/github/types.ts#COMMIT_REF_OUTPUT", @@ -5812,26 +5646,13 @@ "apps/sim/tools/github/types.ts#USER_OUTPUT_PROPERTIES", "apps/sim/tools/github/utils.server.ts#GITHUB_MAX_RESPONSE_BYTES", "apps/sim/tools/gitlab/utils.ts#GITLAB_ACCESS_LEVELS", - "apps/sim/tools/gmail/types.ts#GmailToolParams", "apps/sim/tools/gmail/utils.ts#buildBodyAlternatives", "apps/sim/tools/gmail/utils.ts#extractMessageBody", "apps/sim/tools/gmail/utils.ts#fetchThreadingHeaders", "apps/sim/tools/gong/utils.ts#parseGongJsonField", - "apps/sim/tools/google_appsheet/types.ts#GoogleAppsheetRow", - "apps/sim/tools/google_calendar/types.ts#GoogleCalendarToolParams", - "apps/sim/tools/google_contacts/types.ts#GoogleContactsToolParams", - "apps/sim/tools/google_drive/types.ts#GoogleDriveCommentReply", "apps/sim/tools/google_forms/utils.ts#FORMS_API_BASE", - "apps/sim/tools/google_meet/types.ts#GoogleMeetToolParams", - "apps/sim/tools/google_sheets/types.ts#GoogleSheetsFilterInfo", "apps/sim/tools/google_slides/utils.ts#ptToEmuDimension", - "apps/sim/tools/google_vault/types.ts#GoogleVaultCorpus", - "apps/sim/tools/google_vault/types.ts#GoogleVaultHoldView", "apps/sim/tools/grain/types.ts#GRAIN_HOOK_TYPES", - "apps/sim/tools/grain/types.ts#GrainHookType", - "apps/sim/tools/granola/types.ts#GranolaWebhookEndpointOutput", - "apps/sim/tools/harmonic/types.ts#HarmonicContactMetadata", - "apps/sim/tools/harmonic/types.ts#HarmonicSocialMetadata", "apps/sim/tools/harmonic/utils.ts#HARMONIC_BATCH_PEOPLE_MAX", "apps/sim/tools/harmonic/utils.ts#HARMONIC_CLEAR_NET_NEW_MAX", "apps/sim/tools/harmonic/utils.ts#HARMONIC_EMAIL_ENRICHMENT_MAX", @@ -5851,18 +5672,6 @@ "apps/sim/tools/hubspot/types.ts#CRM_RECORD_BASE_OUTPUT_PROPERTIES", "apps/sim/tools/hubspot/types.ts#DEAL_PROPERTIES_OUTPUT", "apps/sim/tools/hubspot/types.ts#EMAIL_PROPERTIES_OUTPUT", - "apps/sim/tools/hubspot/types.ts#HubSpotAppointment", - "apps/sim/tools/hubspot/types.ts#HubSpotAssociationLabel", - "apps/sim/tools/hubspot/types.ts#HubSpotCart", - "apps/sim/tools/hubspot/types.ts#HubSpotCompany", - "apps/sim/tools/hubspot/types.ts#HubSpotContact", - "apps/sim/tools/hubspot/types.ts#HubSpotDeal", - "apps/sim/tools/hubspot/types.ts#HubSpotEmail", - "apps/sim/tools/hubspot/types.ts#HubSpotLineItem", - "apps/sim/tools/hubspot/types.ts#HubSpotListMembership", - "apps/sim/tools/hubspot/types.ts#HubSpotNote", - "apps/sim/tools/hubspot/types.ts#HubSpotQuote", - "apps/sim/tools/hubspot/types.ts#HubSpotTicket", "apps/sim/tools/hubspot/types.ts#LINE_ITEM_PROPERTIES_OUTPUT", "apps/sim/tools/hubspot/types.ts#MARKETING_EVENT_OUTPUT_PROPERTIES", "apps/sim/tools/hubspot/types.ts#NOTE_PROPERTIES_OUTPUT", @@ -5877,16 +5686,7 @@ "apps/sim/tools/hunter/types.ts#SENIORITY_OUTPUT_PROPERTIES", "apps/sim/tools/hunter/types.ts#SOURCE_OUTPUT_PROPERTIES", "apps/sim/tools/hunter/types.ts#VERIFICATION_OUTPUT_PROPERTIES", - "apps/sim/tools/iam/types.ts#IAMAccessKeyStatus", - "apps/sim/tools/iam/types.ts#IAMContextKeyType", - "apps/sim/tools/iam/types.ts#IAMPolicyScope", - "apps/sim/tools/iam/types.ts#IAMSimulateEvaluationResult", - "apps/sim/tools/iam/types.ts#IAMSimulateMatchedStatement", - "apps/sim/tools/iam/types.ts#IAMSimulateResourceSpecificResult", "apps/sim/tools/icypeas/hosting.ts#ICYPEAS_API_KEY_PREFIX", - "apps/sim/tools/icypeas/types.ts#IcypeasBaseParams", - "apps/sim/tools/identity_center/types.ts#IdentityCenterConnectionConfig", - "apps/sim/tools/incidentio/types.ts#CustomFieldType", "apps/sim/tools/incidentio/types.ts#INCIDENTIO_ACTION_OUTPUT_PROPERTIES", "apps/sim/tools/incidentio/types.ts#INCIDENTIO_CUSTOM_FIELD_OUTPUT_PROPERTIES", "apps/sim/tools/incidentio/types.ts#INCIDENTIO_FOLLOW_UP_OUTPUT_PROPERTIES", @@ -5896,33 +5696,9 @@ "apps/sim/tools/incidentio/types.ts#INCIDENTIO_SEVERITY_OUTPUT_PROPERTIES", "apps/sim/tools/incidentio/types.ts#INCIDENTIO_STATUS_OUTPUT_PROPERTIES", "apps/sim/tools/incidentio/types.ts#INCIDENTIO_USER_OUTPUT_PROPERTIES", - "apps/sim/tools/incidentio/types.ts#IncidentioActionRecord", - "apps/sim/tools/incidentio/types.ts#IncidentioActor", - "apps/sim/tools/incidentio/types.ts#IncidentioAlert", - "apps/sim/tools/incidentio/types.ts#IncidentioAlertAttributeEntry", - "apps/sim/tools/incidentio/types.ts#IncidentioAlertAttributeValue", - "apps/sim/tools/incidentio/types.ts#IncidentioAlertSlim", - "apps/sim/tools/incidentio/types.ts#IncidentioBaseParams", - "apps/sim/tools/incidentio/types.ts#IncidentioCatalogEntry", - "apps/sim/tools/incidentio/types.ts#IncidentioCatalogType", - "apps/sim/tools/incidentio/types.ts#IncidentioExternalIssueReference", - "apps/sim/tools/incidentio/types.ts#IncidentioFollowUpRecord", - "apps/sim/tools/incidentio/types.ts#IncidentioIncidentAlert", - "apps/sim/tools/incidentio/types.ts#IncidentioIncidentParticipant", - "apps/sim/tools/incidentio/types.ts#IncidentioPaginationMeta", - "apps/sim/tools/incidentio/types.ts#IncidentioScheduleOverrideRecord", - "apps/sim/tools/incidentio/types.ts#IncidentioSlimUser", - "apps/sim/tools/incidentio/types.ts#IncidentioTeam", "apps/sim/tools/index.ts#ToolEnvReferenceMode", "apps/sim/tools/instagram/constants.ts#INSTAGRAM_GRAPH_VERSION", - "apps/sim/tools/instagram/types.ts#InstagramAccessParams", - "apps/sim/tools/instagram/types.ts#InstagramAccountInsightsMetricType", - "apps/sim/tools/instagram/types.ts#InstagramAccountInsightsPeriod", - "apps/sim/tools/instagram/types.ts#InstagramAccountInsightsTimeframe", - "apps/sim/tools/instagram/types.ts#InstagramMediaInput", "apps/sim/tools/instagram/utils.ts#InstagramGraphPaging", - "apps/sim/tools/instantly/types.ts#InstantlyBaseParams", - "apps/sim/tools/instantly/types.ts#InstantlyScalar", "apps/sim/tools/intercom/types.ts#INTERCOM_ADMIN_OUTPUT_PROPERTIES", "apps/sim/tools/intercom/types.ts#INTERCOM_AVATAR_OUTPUT_PROPERTIES", "apps/sim/tools/intercom/types.ts#INTERCOM_COMPANY_CORE_OUTPUT_PROPERTIES", @@ -5976,37 +5752,16 @@ "apps/sim/tools/jira/types.ts#TRANSITION_ITEM_PROPERTIES", "apps/sim/tools/jira/types.ts#USER_OUTPUT", "apps/sim/tools/jira/types.ts#VERSION_OUTPUT_PROPERTIES", - "apps/sim/tools/jotform/types.ts#JotformAuthParams", - "apps/sim/tools/jotform/types.ts#JotformHistoryEntry", - "apps/sim/tools/jotform/types.ts#JotformPagination", - "apps/sim/tools/jotform/types.ts#JotformSubUserPermission", "apps/sim/tools/jotform/utils.ts#JotformResultSet", "apps/sim/tools/jsm/types.ts#APPROVER_ITEM_PROPERTIES", - "apps/sim/tools/jsm/types.ts#AssetObjectAttribute", - "apps/sim/tools/jsm/types.ts#AssetObjectAttributeInput", - "apps/sim/tools/jsm/types.ts#AssetObjectAttributeValue", - "apps/sim/tools/jsm/types.ts#JsmAssetsBaseParams", - "apps/sim/tools/jsm/types.ts#RawAssetObjectAttribute", - "apps/sim/tools/jsm/types.ts#RawAssetObjectAttributeValue", "apps/sim/tools/jsm/utils.ts#getAssetsApiBaseUrl", "apps/sim/tools/jsm/utils.ts#getAssetsWorkspaceId", "apps/sim/tools/jsm/utils.ts#getJsmFormsApiBaseUrl", - "apps/sim/tools/jupyter/types.ts#JupyterAuthParams", - "apps/sim/tools/jupyter/types.ts#JupyterContentItem", - "apps/sim/tools/jupyter/types.ts#JupyterKernel", - "apps/sim/tools/jupyter/types.ts#JupyterKernelSpec", - "apps/sim/tools/jupyter/types.ts#JupyterSession", "apps/sim/tools/kalshi/types.ts#KALSHI_BALANCE_OUTPUT_PROPERTIES", "apps/sim/tools/kalshi/types.ts#KALSHI_BASE_URL", "apps/sim/tools/kalshi/types.ts#KALSHI_CANDLESTICK_OUTPUT_PROPERTIES", "apps/sim/tools/kalshi/types.ts#KALSHI_ORDERBOOK_LEVEL_OUTPUT_PROPERTIES", "apps/sim/tools/kalshi/types.ts#generateKalshiSignature", - "apps/sim/tools/lambda/types.ts#LambdaConnectionParams", - "apps/sim/tools/langsmith/types.ts#LangsmithFeedbackSourceType", - "apps/sim/tools/langsmith/types.ts#LangsmithRunType", - "apps/sim/tools/latex/types.ts#LatexCompiler", - "apps/sim/tools/latex/types.ts#LatexPdfReference", - "apps/sim/tools/latex/types.ts#LatexResource", "apps/sim/tools/leadmagic/hosting.ts#LEADMAGIC_API_KEY_PREFIX", "apps/sim/tools/linear/types.ts#CYCLE_OUTPUT", "apps/sim/tools/linear/types.ts#CYCLE_OUTPUT_PROPERTIES", @@ -6022,12 +5777,6 @@ "apps/sim/tools/linear/types.ts#TEAM_OUTPUT_PROPERTIES", "apps/sim/tools/linear/types.ts#USER_OUTPUT", "apps/sim/tools/linear/types.ts#USER_OUTPUT_PROPERTIES", - "apps/sim/tools/linq/types.ts#LinqChatHandle", - "apps/sim/tools/linq/types.ts#LinqReactionType", - "apps/sim/tools/logfire/types.ts#LogfireApiField", - "apps/sim/tools/logfire/types.ts#LogfireLevel", - "apps/sim/tools/logfire/types.ts#LogfireQueryWindowParams", - "apps/sim/tools/logs/types.ts#LogsComparisonOperator", "apps/sim/tools/mailchimp/types.ts#extractServerPrefix", "apps/sim/tools/manageengine_sdp/data-centers.ts#DEFAULT_SDP_DATA_CENTER", "apps/sim/tools/manageengine_sdp/data-centers.ts#SdpDataCenter", @@ -6055,16 +5804,12 @@ "apps/sim/tools/microsoft_dynamics_365/index.ts#DataverseOpportunityOutcome", "apps/sim/tools/microsoft_dynamics_365/index.ts#DataverseQualifyLeadParams", "apps/sim/tools/microsoft_dynamics_365/index.ts#DataverseQualifyLeadResponse", - "apps/sim/tools/microsoft_dynamics_365/index.ts#DataverseResponse", "apps/sim/tools/microsoft_dynamics_365/index.ts#DataverseSearchParams", "apps/sim/tools/microsoft_dynamics_365/index.ts#DataverseSearchResponse", "apps/sim/tools/microsoft_dynamics_365/index.ts#DataverseUpdateRecordParams", "apps/sim/tools/microsoft_dynamics_365/index.ts#DataverseUpdateRecordResponse", - "apps/sim/tools/microsoft_dynamics_365/types.ts#DataverseResponse", "apps/sim/tools/microsoft_excel/utils.ts#extractGraphError", "apps/sim/tools/microsoft_excel/utils.ts#resolveSheetAndAddress", - "apps/sim/tools/microsoft_teams/types.ts#GraphChatMessage", - "apps/sim/tools/microsoft_teams/types.ts#GraphDriveItem", "apps/sim/tools/microsoft_teams/utils.ts#TeamsMention", "apps/sim/tools/microsoft_teams/utils.ts#resolveMentionsForChannel", "apps/sim/tools/microsoft_teams/utils.ts#resolveMentionsForChat", @@ -6072,8 +5817,6 @@ "apps/sim/tools/microsoft_word/utils.ts#getItemBasePath", "apps/sim/tools/millionverifier/hosting.ts#MILLIONVERIFIER_API_KEY_PREFIX", "apps/sim/tools/millionverifier/hosting.ts#MILLIONVERIFIER_CREDIT_USD", - "apps/sim/tools/mintlify/types.ts#MintlifyAssistantContextItem", - "apps/sim/tools/mintlify/types.ts#MintlifyConversationSource", "apps/sim/tools/mistral/types.ts#MISTRAL_OCR_DIMENSIONS_OUTPUT", "apps/sim/tools/mistral/types.ts#MISTRAL_OCR_DIMENSIONS_OUTPUT_PROPERTIES", "apps/sim/tools/mistral/types.ts#MISTRAL_OCR_IMAGE_OUTPUT_PROPERTIES", @@ -6081,19 +5824,11 @@ "apps/sim/tools/mistral/types.ts#MISTRAL_OCR_USAGE_OUTPUT", "apps/sim/tools/mistral/types.ts#MISTRAL_OCR_USAGE_OUTPUT_PROPERTIES", "apps/sim/tools/mistral/types.ts#MISTRAL_PARSER_METADATA_OUTPUT_PROPERTIES", - "apps/sim/tools/mongodb/types.ts#MongoDBCollectionInfo", - "apps/sim/tools/mongodb/types.ts#MongoDBConnectionConfig", - "apps/sim/tools/mssql/types.ts#MSSQLConnectionConfig", "apps/sim/tools/mssql/types.ts#MSSQL_COLUMN_OUTPUT_PROPERTIES", "apps/sim/tools/mssql/types.ts#MSSQL_FOREIGN_KEY_OUTPUT_PROPERTIES", "apps/sim/tools/mssql/types.ts#MSSQL_INDEX_OUTPUT_PROPERTIES", - "apps/sim/tools/netsuite/types.ts#NetSuiteMetadataFormat", - "apps/sim/tools/netsuite/types.ts#NetSuitePaginationParams", - "apps/sim/tools/netsuite/types.ts#NetSuiteRecordQueryParams", "apps/sim/tools/neverbounce/hosting.ts#NEVERBOUNCE_API_KEY_PREFIX", "apps/sim/tools/neverbounce/hosting.ts#NEVERBOUNCE_CREDIT_USD", - "apps/sim/tools/new_relic/types.ts#NewRelicBaseParams", - "apps/sim/tools/new_relic/types.ts#NewRelicEntityTag", "apps/sim/tools/notion/types.ts#ANNOTATIONS_OUTPUT_PROPERTIES", "apps/sim/tools/notion/types.ts#COMMENT_OUTPUT_PROPERTIES", "apps/sim/tools/notion/types.ts#COVER_OUTPUT", @@ -6112,13 +5847,9 @@ "apps/sim/tools/onedrive/utils.ts#ExcelArrayValues", "apps/sim/tools/onedrive/utils.ts#ExcelCell", "apps/sim/tools/onedrive/utils.ts#ExcelObjectValues", - "apps/sim/tools/otter/types.ts#OtterActionItemStatus", - "apps/sim/tools/otter/types.ts#OtterProcessStatus", "apps/sim/tools/otter/utils.ts#OTTER_CONVERSATION_INCLUDE_OPTIONS", "apps/sim/tools/outlook/calendar-idempotency.ts#OUTLOOK_CALENDAR_TRANSACTION_WINDOW_SECONDS", "apps/sim/tools/outlook/calendar-idempotency.ts#resolveOutlookCalendarTransactionId", - "apps/sim/tools/outlook/types.ts#CleanedOutlookEventDateTime", - "apps/sim/tools/outlook/types.ts#GraphEmailAddress", "apps/sim/tools/outlook/types.ts#OUTLOOK_ATTACHMENT_OUTPUT_PROPERTIES", "apps/sim/tools/outlook/types.ts#OUTLOOK_EMAIL_ADDRESS_OUTPUT_PROPERTIES", "apps/sim/tools/outlook/types.ts#OUTLOOK_EVENT_ATTENDEE_OUTPUT_PROPERTIES", @@ -6138,17 +5869,9 @@ "apps/sim/tools/postgresql/types.ts#POSTGRES_FOREIGN_KEY_OUTPUT_PROPERTIES", "apps/sim/tools/postgresql/types.ts#POSTGRES_INDEX_OUTPUT_PROPERTIES", "apps/sim/tools/prospeo/hosting.ts#PROSPEO_API_KEY_PREFIX", - "apps/sim/tools/prospeo/types.ts#ProspeoBaseParams", - "apps/sim/tools/prospeo/types.ts#ProspeoCompanyData", - "apps/sim/tools/prospeo/types.ts#ProspeoPaginationOutput", - "apps/sim/tools/prospeo/types.ts#ProspeoPersonData", "apps/sim/tools/quartr/types.ts#QUARTR_AUDIO_METADATA_OUTPUT_PROPERTIES", "apps/sim/tools/quartr/types.ts#QUARTR_EXPANDED_EVENT_OUTPUT_PROPERTIES", "apps/sim/tools/quartr/types.ts#QUARTR_TICKER_OUTPUT_PROPERTIES", - "apps/sim/tools/quartr/types.ts#QuartrAudioMetadata", - "apps/sim/tools/quartr/types.ts#QuartrAudioMetadataDto", - "apps/sim/tools/quartr/types.ts#QuartrPaginationDto", - "apps/sim/tools/quartr/types.ts#QuartrTicker", "apps/sim/tools/quartr/utils.ts#QUARTR_API_BASE_URL", "apps/sim/tools/quartr/utils.ts#mapQuartrExpandedEvent", "apps/sim/tools/quickbooks/accounting_utils.ts#buildQuickBooksDepositLines", @@ -6173,7 +5896,6 @@ "apps/sim/tools/quickbooks/utils.ts#QUICKBOOKS_PURCHASING_ENTITIES", "apps/sim/tools/quickbooks/utils.ts#QUICKBOOKS_SALES_ENTITIES", "apps/sim/tools/quickbooks/values.ts#QUICKBOOKS_GLOBAL_TAX_CALCULATIONS", - "apps/sim/tools/railway/types.ts#RailwayAuthParams", "apps/sim/tools/rb2b/types.ts#RB2B_LINKEDIN_COMPANY_OUTPUT_PROPERTIES", "apps/sim/tools/reddit/types.ts#COMMENT_OUTPUT_PROPERTIES", "apps/sim/tools/reddit/types.ts#COMMENT_WITH_REPLIES_OUTPUT_PROPERTIES", @@ -6181,9 +5903,7 @@ "apps/sim/tools/reddit/types.ts#POST_METADATA_OUTPUT_PROPERTIES", "apps/sim/tools/reddit/types.ts#POST_OUTPUT_PROPERTIES", "apps/sim/tools/reddit/types.ts#REPLY_DATA_OUTPUT_PROPERTIES", - "apps/sim/tools/reddit/types.ts#RedditMessage", "apps/sim/tools/reddit/types.ts#SUBMIT_POST_DATA_OUTPUT_PROPERTIES", - "apps/sim/tools/reducto/types.ts#ReductoBlockType", "apps/sim/tools/revenuecat/types.ts#ENTITLEMENT_OUTPUT_PROPERTIES", "apps/sim/tools/revenuecat/types.ts#OFFERING_PACKAGE_OUTPUT_PROPERTIES", "apps/sim/tools/revenuecat/types.ts#SUBSCRIBER_OUTPUT_PROPERTIES", @@ -6195,63 +5915,6 @@ "apps/sim/tools/rocketlane/types.ts#PROJECT_SOURCE_OUTPUT_PROPERTIES", "apps/sim/tools/rocketlane/types.ts#PROJECT_STATUS_OUTPUT_PROPERTIES", "apps/sim/tools/rocketlane/types.ts#PROJECT_TEAM_MEMBERS_OUTPUT_PROPERTIES", - "apps/sim/tools/rocketlane/types.ts#RocketlaneBaseParams", - "apps/sim/tools/rocketlane/types.ts#RocketlaneFieldOptionInput", - "apps/sim/tools/rocketlane/types.ts#RocketlaneInvoiceAttachment", - "apps/sim/tools/rocketlane/types.ts#RocketlaneInvoiceCompany", - "apps/sim/tools/rocketlane/types.ts#RocketlaneInvoiceField", - "apps/sim/tools/rocketlane/types.ts#RocketlaneInvoiceLineItemTaxCode", - "apps/sim/tools/rocketlane/types.ts#RocketlaneInvoiceLineItemTaxComponent", - "apps/sim/tools/rocketlane/types.ts#RocketlaneInvoiceProject", - "apps/sim/tools/rocketlane/types.ts#RocketlanePhaseProject", - "apps/sim/tools/rocketlane/types.ts#RocketlanePhaseStatus", - "apps/sim/tools/rocketlane/types.ts#RocketlanePlaceholderMappingUser", - "apps/sim/tools/rocketlane/types.ts#RocketlanePlaceholderProjectRef", - "apps/sim/tools/rocketlane/types.ts#RocketlanePlaceholderRef", - "apps/sim/tools/rocketlane/types.ts#RocketlanePlaceholderRole", - "apps/sim/tools/rocketlane/types.ts#RocketlaneProjectCompany", - "apps/sim/tools/rocketlane/types.ts#RocketlaneProjectField", - "apps/sim/tools/rocketlane/types.ts#RocketlaneProjectFieldInput", - "apps/sim/tools/rocketlane/types.ts#RocketlaneProjectFinancials", - "apps/sim/tools/rocketlane/types.ts#RocketlaneProjectPhase", - "apps/sim/tools/rocketlane/types.ts#RocketlaneProjectPlaceholderInput", - "apps/sim/tools/rocketlane/types.ts#RocketlaneProjectSource", - "apps/sim/tools/rocketlane/types.ts#RocketlaneProjectSourceInput", - "apps/sim/tools/rocketlane/types.ts#RocketlaneProjectStatus", - "apps/sim/tools/rocketlane/types.ts#RocketlaneProjectTeamMembers", - "apps/sim/tools/rocketlane/types.ts#RocketlaneResourceAllocationDuration", - "apps/sim/tools/rocketlane/types.ts#RocketlaneResourceAllocationMember", - "apps/sim/tools/rocketlane/types.ts#RocketlaneResourceAllocationPlaceholder", - "apps/sim/tools/rocketlane/types.ts#RocketlaneResourceAllocationProject", - "apps/sim/tools/rocketlane/types.ts#RocketlaneResourceAllocationRole", - "apps/sim/tools/rocketlane/types.ts#RocketlaneResourceAllocationTask", - "apps/sim/tools/rocketlane/types.ts#RocketlaneSpaceDocumentSource", - "apps/sim/tools/rocketlane/types.ts#RocketlaneSpaceDocumentSpaceRef", - "apps/sim/tools/rocketlane/types.ts#RocketlaneSpaceProject", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTaskAssignees", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTaskBudget", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTaskChoice", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTaskField", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTaskFollowers", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTaskLite", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTaskPhaseRef", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTaskPlaceholder", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTaskProjectRef", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTaskRole", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTaskTimeEntryCategory", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTimeEntryField", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTimeEntryFilterParams", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTimeEntryPhase", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTimeEntryProject", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTimeEntryRate", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTimeEntryTask", - "apps/sim/tools/rocketlane/types.ts#RocketlaneTimeOffNotifyUsers", - "apps/sim/tools/rocketlane/types.ts#RocketlaneUserCompany", - "apps/sim/tools/rocketlane/types.ts#RocketlaneUserField", - "apps/sim/tools/rocketlane/types.ts#RocketlaneUserHolidayCalendar", - "apps/sim/tools/rocketlane/types.ts#RocketlaneUserPermission", - "apps/sim/tools/rocketlane/types.ts#RocketlaneUserRole", - "apps/sim/tools/rocketlane/types.ts#RocketlaneUserSummary", "apps/sim/tools/rocketlane/types.ts#USER_SUMMARY_OUTPUT_PROPERTIES", "apps/sim/tools/rocketlane/types.ts#mapProjectCompany", "apps/sim/tools/rocketlane/types.ts#mapProjectField", @@ -6262,23 +5925,6 @@ "apps/sim/tools/rocketlane/types.ts#mapProjectTeamMembers", "apps/sim/tools/rocketlane/types.ts#mapUserSummary", "apps/sim/tools/sailpoint/common.ts#assertMutuallyExclusive", - "apps/sim/tools/sailpoint/types.ts#SailPointAccessRequestTracking", - "apps/sim/tools/sailpoint/types.ts#SailPointAccessRequestType", - "apps/sim/tools/sailpoint/types.ts#SailPointAccountItemRef", - "apps/sim/tools/sailpoint/types.ts#SailPointListOutput", - "apps/sim/tools/sailpoint/types.ts#SailPointNestedRequestedItem", - "apps/sim/tools/sailpoint/types.ts#SailPointPaginationParams", - "apps/sim/tools/sailpoint/types.ts#SailPointQueryResultFilter", - "apps/sim/tools/sailpoint/types.ts#SailPointRequestedForWithItems", - "apps/sim/tools/sailpoint/types.ts#SailPointRequestedItem", - "apps/sim/tools/sailpoint/types.ts#SailPointRequestedItemType", - "apps/sim/tools/sailpoint/types.ts#SailPointReviewRecommendation", - "apps/sim/tools/sailpoint/types.ts#SailPointSearchFilter", - "apps/sim/tools/sailpoint/types.ts#SailPointSearchIndex", - "apps/sim/tools/sailpoint/types.ts#SailPointSearchQuery", - "apps/sim/tools/sailpoint/types.ts#SailPointTask", - "apps/sim/tools/sailpoint/types.ts#SailPointTextQuery", - "apps/sim/tools/sailpoint/types.ts#SailPointTypeAheadQuery", "apps/sim/tools/salesforce/types.ts#ACCOUNT_OUTPUT_PROPERTIES", "apps/sim/tools/salesforce/types.ts#CASE_OUTPUT_PROPERTIES", "apps/sim/tools/salesforce/types.ts#CONTACT_OUTPUT_PROPERTIES", @@ -6296,18 +5942,8 @@ "apps/sim/tools/salesforce/types.ts#TASK_OUTPUT_PROPERTIES", "apps/sim/tools/salesforce/utils.ts#normalizeBoolean", "apps/sim/tools/salesforce/utils.ts#parseDelimitedList", - "apps/sim/tools/sap_concur/types.ts#SapConcurDatacenter", - "apps/sim/tools/sap_concur/types.ts#SapConcurGrantType", - "apps/sim/tools/sap_s4hana/types.ts#ODataMethod", - "apps/sim/tools/sap_s4hana/types.ts#SapAuthType", - "apps/sim/tools/sap_s4hana/types.ts#SapDeploymentType", - "apps/sim/tools/secrets_manager/types.ts#SecretsManagerConnectionConfig", - "apps/sim/tools/secrets_manager/types.ts#SecretsManagerReplicationStatus", - "apps/sim/tools/secrets_manager/types.ts#SecretsManagerRotationRules", "apps/sim/tools/semrush/utils.ts#SEMRUSH_MAX_ROWS", "apps/sim/tools/semrush/utils.ts#getColumnDef", - "apps/sim/tools/sendblue/types.ts#SendblueMessageOutput", - "apps/sim/tools/sendblue/types.ts#SendblueSendStyle", "apps/sim/tools/serper/types.ts#ANSWER_BOX_OUTPUT_PROPERTIES", "apps/sim/tools/serper/types.ts#IMAGE_RESULT_OUTPUT_PROPERTIES", "apps/sim/tools/serper/types.ts#KNOWLEDGE_GRAPH_OUTPUT_PROPERTIES", @@ -6339,17 +5975,10 @@ "apps/sim/tools/slack/types.ts#MESSAGE_THREAD_OUTPUT_PROPERTIES", "apps/sim/tools/slack/types.ts#REACTIONS_OUTPUT", "apps/sim/tools/slack/types.ts#REACTION_OUTPUT_PROPERTIES", - "apps/sim/tools/slack/types.ts#SlackScheduledMessage", "apps/sim/tools/slack/types.ts#USER_OUTPUT", "apps/sim/tools/slack/utils.ts#mapSlackMessage", "apps/sim/tools/slack/web-api-responses.ts#dndOutput", "apps/sim/tools/slack_lists/types.ts#LIST_COLUMNS_OUTPUT", - "apps/sim/tools/slack_lists/types.ts#SlackListCell", - "apps/sim/tools/slack_lists/types.ts#SlackListColumn", - "apps/sim/tools/slack_lists/types.ts#SlackListField", - "apps/sim/tools/slack_lists/types.ts#SlackListItem", - "apps/sim/tools/slack_lists/types.ts#SlackListResponseColumn", - "apps/sim/tools/slack_lists/types.ts#SlackListSummary", "apps/sim/tools/snowflake/selector-kinds.ts#SNOWFLAKE_SELECTOR_KINDS", "apps/sim/tools/snowflake/utils.ts#DEFAULT_MAX_ROWS", "apps/sim/tools/snowflake/utils.ts#SIM_MAX_RESULT_ROWS", @@ -6357,13 +5986,7 @@ "apps/sim/tools/splunk/utils.ts#SPLUNK_JSON_OUTPUT_MODE", "apps/sim/tools/splunk/utils.ts#getEntryAuthor", "apps/sim/tools/sportmonks/types.ts#SPORTMONKS_PAGINATION_PROPERTIES", - "apps/sim/tools/sportmonks_core/types.ts#SportmonksTypeEntityEntry", - "apps/sim/tools/sportmonks_core/types.ts#SportmonksTypeEntityGroup", "apps/sim/tools/spotify/types.ts#ALBUM_LIST_OUTPUT_PROPERTIES", - "apps/sim/tools/sqs/types.ts#SqsBatchErrorEntry", - "apps/sim/tools/sqs/types.ts#SqsMessageAttributeInput", - "apps/sim/tools/sqs/types.ts#SqsMessageAttributeOutput", - "apps/sim/tools/sqs/types.ts#SqsSendMessageBatchEntry", "apps/sim/tools/square/idempotency.ts#SQUARE_IDEMPOTENCY_WINDOW_SECONDS", "apps/sim/tools/square/types.ts#ADDRESS_OUTPUT", "apps/sim/tools/square/types.ts#ADDRESS_OUTPUT_PROPERTIES", @@ -6378,7 +6001,6 @@ "apps/sim/tools/square/types.ts#ORDER_OUTPUT_PROPERTIES", "apps/sim/tools/square/types.ts#PAYMENT_OUTPUT_PROPERTIES", "apps/sim/tools/square/types.ts#REFUND_OUTPUT_PROPERTIES", - "apps/sim/tools/ssh/types.ts#SSHParams", "apps/sim/tools/stagehand/types.ts#STAGEHAND_ACTIONS_OUTPUT", "apps/sim/tools/stagehand/types.ts#STAGEHAND_ACTION_OUTPUT_PROPERTIES", "apps/sim/tools/stagehand/types.ts#STAGEHAND_ACT_ACTION_OUTPUT_PROPERTIES", @@ -6391,63 +6013,18 @@ "apps/sim/tools/supabase/types.ts#INTROSPECT_REFERENCE_OUTPUT_PROPERTIES", "apps/sim/tools/supabase/types.ts#STORAGE_FILE_METADATA_OUTPUT_PROPERTIES", "apps/sim/tools/tavily/types.ts#TAVILY_USAGE_OUTPUT_PROPERTIES", - "apps/sim/tools/telegram/types.ts#TelegramUser", - "apps/sim/tools/temporal/types.ts#TemporalBaseParams", - "apps/sim/tools/temporal/types.ts#TemporalExecutionSummary", - "apps/sim/tools/temporal/types.ts#TemporalHistoryEventSummary", - "apps/sim/tools/temporal/types.ts#TemporalPendingActivity", - "apps/sim/tools/temporal/types.ts#TemporalScheduleSummary", "apps/sim/tools/temporal/utils.ts#TemporalRawExecution", "apps/sim/tools/temporal/utils.ts#encodePayload", - "apps/sim/tools/textract/types.ts#TextractAnalyzeExpenseInput", - "apps/sim/tools/textract/types.ts#TextractAnalyzeIdInput", - "apps/sim/tools/textract/types.ts#TextractFeatureType", - "apps/sim/tools/textract/types.ts#TextractProcessingMode", - "apps/sim/tools/thrive/types.ts#ThriveBaseParams", - "apps/sim/tools/thrive/types.ts#ThrivePagination", "apps/sim/tools/thrive/utils.ts#THRIVE_DEFAULT_HOST", "apps/sim/tools/tiktok/api-schemas.ts#tiktokApiUserSchema", "apps/sim/tools/tiktok/api-schemas.ts#tiktokApiVideoSchema", - "apps/sim/tools/tiktok/types.ts#TikTokBaseParams", "apps/sim/tools/tinyfish/hosting.ts#TINYFISH_API_KEY_PREFIX", - "apps/sim/tools/tinyfish/types.ts#TinyFishAgentMode", - "apps/sim/tools/tinyfish/types.ts#TinyFishBrowserProfile", - "apps/sim/tools/tinyfish/types.ts#TinyFishErrorCategory", - "apps/sim/tools/tinyfish/types.ts#TinyFishFetchFormat", - "apps/sim/tools/tinyfish/types.ts#TinyFishRunStatus", "apps/sim/tools/tinyfish/utils.ts#TINYFISH_API_INTEGRATION", - "apps/sim/tools/trigger_dev/types.ts#TriggerDevBatch", - "apps/sim/tools/trigger_dev/types.ts#TriggerDevEnvVar", - "apps/sim/tools/trigger_dev/types.ts#TriggerDevRunEvent", - "apps/sim/tools/trigger_dev/types.ts#TriggerDevSpanEvent", "apps/sim/tools/trigger_dev/utils.ts#mapTriggerDevAttempt", "apps/sim/tools/trigger_dev/utils.ts#parseSerializedOutput", "apps/sim/tools/types.ts#InternalToolOperationConfig", - "apps/sim/tools/uptimerobot/types.ts#UptimeRobotAssignedAlertContact", - "apps/sim/tools/uptimerobot/types.ts#UptimeRobotIncidentRootCause", - "apps/sim/tools/uptimerobot/types.ts#UptimeRobotLastIncident", - "apps/sim/tools/uptimerobot/types.ts#UptimeRobotTag", "apps/sim/tools/utils.ts#RequestParams", "apps/sim/tools/utils.ts#getClientEnvVars", - "apps/sim/tools/vanta/types.ts#VantaAssetTag", - "apps/sim/tools/vanta/types.ts#VantaBaseParams", - "apps/sim/tools/vanta/types.ts#VantaDocumentDeactivatedStatus", - "apps/sim/tools/vanta/types.ts#VantaOperatingSystem", - "apps/sim/tools/vanta/types.ts#VantaPaginationParams", - "apps/sim/tools/vanta/types.ts#VantaPersonEmployment", - "apps/sim/tools/vanta/types.ts#VantaPersonLeaveInfo", - "apps/sim/tools/vanta/types.ts#VantaPersonName", - "apps/sim/tools/vanta/types.ts#VantaPersonTasksSummary", - "apps/sim/tools/vanta/types.ts#VantaPolicyLatestApprovedVersion", - "apps/sim/tools/vanta/types.ts#VantaTestDeactivatedStatusInfo", - "apps/sim/tools/vanta/types.ts#VantaTestRemediationStatusInfo", - "apps/sim/tools/vanta/types.ts#VantaTestVersion", - "apps/sim/tools/vanta/types.ts#VantaUploadedByActor", - "apps/sim/tools/vanta/types.ts#VantaVendorAuthDetails", - "apps/sim/tools/vanta/types.ts#VantaVendorContractAmount", - "apps/sim/tools/vanta/types.ts#VantaVendorDecision", - "apps/sim/tools/vanta/types.ts#VantaVendorProcurementRequest", - "apps/sim/tools/vanta/types.ts#VantaVulnerabilityDeactivateMetadata", "apps/sim/tools/whatsapp/utils.ts#WHATSAPP_GRAPH_VERSION", "apps/sim/tools/whatsapp/utils.ts#WHATSAPP_MEDIA_TYPES", "apps/sim/tools/wikipedia/types.ts#WIKIPEDIA_CONTENT_URLS_OUTPUT", @@ -6460,18 +6037,9 @@ "apps/sim/tools/windchill/types.ts#WINDCHILL_OPERATIONS", "apps/sim/tools/windchill/types.ts#WINDCHILL_USAGE_LINK_OUTPUT", "apps/sim/tools/windchill/types.ts#WINDCHILL_USAGE_LINK_PROPERTIES", - "apps/sim/tools/windchill/types.ts#WindchillAttributeValue", - "apps/sim/tools/windchill/types.ts#WindchillCreateDocumentInput", - "apps/sim/tools/windchill/types.ts#WindchillPageInfo", - "apps/sim/tools/windchill/types.ts#WindchillSecurityLabelInput", - "apps/sim/tools/windchill/types.ts#WindchillUpdateDocumentInput", "apps/sim/tools/windchill/utils.ts#normalizeWindchillContent", "apps/sim/tools/windchill/utils.ts#windchillPageInfo", "apps/sim/tools/wiza/hosting.ts#WIZA_API_KEY_PREFIX", - "apps/sim/tools/wiza/types.ts#WizaIncludeExcludeFilter", - "apps/sim/tools/wiza/types.ts#WizaLocationFilter", - "apps/sim/tools/wordpress/types.ts#CommentStatus", - "apps/sim/tools/wordpress/types.ts#PostStatus", "apps/sim/tools/zendesk/types.ts#CUSTOM_FIELD_OUTPUT_PROPERTIES", "apps/sim/tools/zendesk/types.ts#JOB_RESULT_OUTPUT_PROPERTIES", "apps/sim/tools/zendesk/types.ts#JOB_STATUS_OUTPUT_PROPERTIES", @@ -6494,8 +6062,6 @@ "apps/sim/tools/zoom/types.ts#RECORDING_FILE_OUTPUT_PROPERTIES", "apps/sim/tools/zoom/types.ts#RECURRENCE_OUTPUT", "apps/sim/tools/zoom/types.ts#RECURRENCE_OUTPUT_PROPERTIES", - "apps/sim/tools/zoom/types.ts#ZoomMeetingType", - "apps/sim/tools/zoominfo/types.ts#ZoomInfoBaseParams", "apps/sim/triggers/ashby/utils.ts#ashbySetupInstructions", "apps/sim/triggers/ashby/utils.ts#ashbyTriggerOptions", "apps/sim/triggers/ashby/utils.ts#buildApplicationSubmitOutputs=buildApplicationUpdateOutputs", From 1f5001c30f05ac00e15fb3252d03ff63e648aa08 Mon Sep 17 00:00:00 2001 From: Waleed Date: Sat, 3 Oct 2026 02:12:41 -0700 Subject: [PATCH 04/12] improvement(knip): check entry exports of private packages and delete their dead barrels (#8595) * improvement(knip): check entry exports of private packages and delete their dead barrels - knip.jsonc: includeEntryExports on for every private package except db - delete the bare @sim/utils and @sim/workflow-persistence barrels and their "." exports - drop unused re-exports from the workflow-renderer and desktop-bridge barrels; un-export symbols only used in-file - delete 7 unreferenced emcn icons - baseline the remaining 262 entry-export findings (one-time rule expansion via --update --init) * improvement(packages): resolve the private-package exports the entry-export check exposed - Delete exports nothing uses: RadarChart, ChipModalPromptBody, InputOTPSeparator, DropdownMenuGroup/Portal, legacy terminal tool names, and dead types and helpers - Drop `export` from declarations used only in their own file, and remove barrel re-exports no consumer imports - Tag getOAuthClientCapabilityFields and generateRandomBytes `@public`: generate-docs loads the first by file path, and check:utils names the second - Trim the workflow-authz mock to the module's remaining exports - The unused-exports baseline gains no entries and drops one * fix(emcn): keep ChipTimePicker in the barrel as documented chip-family API * chore(emcn): export CVA variants only once another module composes them * chore(emcn): delete the PillsRing icon, unused since the generic resource panel lost its entry list * chore(knip): shrink the unused-exports baseline after rebasing onto staging --- .claude/rules/emcn-components.md | 4 +- .cursor/rules/emcn-components.mdc | 4 +- CLAUDE.md | 2 +- .../discover-managed-mcp-tools.test.ts | 2 +- .../application/execute-managed-tool.test.ts | 2 +- .../lib/mcp/application/execute-tool.test.ts | 2 +- .../mcp/application/operation-access.test.ts | 4 +- .../lib/mcp/application/operation-access.ts | 2 +- apps/sim/stores/workflows/workflow/types.ts | 2 +- knip.jsonc | 30 ++- packages/auth/src/principal.ts | 13 +- packages/auth/src/verify.ts | 2 +- packages/browser-protocol/src/index.ts | 17 +- .../deployment-config/src/env-capabilities.ts | 28 +- packages/desktop-bridge/src/index.ts | 33 +-- packages/desktop-bridge/src/title-bar.ts | 2 +- .../emcn/src/components/avatar/avatar.tsx | 9 +- .../bulk-action-button/bulk-action-button.tsx | 2 +- .../emcn/src/components/button/button.tsx | 2 +- .../emcn/src/components/calendar/calendar.tsx | 2 +- .../emcn/src/components/charts/bar-chart.tsx | 2 +- .../src/components/charts/chart-geometry.ts | 2 +- .../src/components/charts/chart-legend.tsx | 2 +- .../src/components/charts/chart-tooltip.tsx | 2 +- .../components/charts/dashboard-metric.tsx | 2 +- packages/emcn/src/components/charts/index.ts | 9 +- .../emcn/src/components/charts/line-chart.tsx | 4 +- .../src/components/charts/radar-chart.tsx | 239 ------------------ .../chip-button-group/chip-button-group.tsx | 12 +- .../chip-date-picker/chip-date-picker.tsx | 2 +- .../src/components/chip-modal/chip-modal.tsx | 93 ++----- .../components/chip-switch/chip-switch.tsx | 2 +- .../chip-time-picker/chip-time-picker.tsx | 2 +- .../emcn/src/components/chip/chip-chrome.ts | 2 +- .../emcn/src/components/combobox/combobox.tsx | 2 +- .../composer-action-button.tsx | 2 +- .../dropdown-menu/dropdown-menu.tsx | 16 +- packages/emcn/src/components/index.ts | 117 ++------- .../src/components/info-card/info-card.tsx | 6 +- .../src/components/input-otp/input-otp.tsx | 17 +- packages/emcn/src/components/input/input.tsx | 2 +- packages/emcn/src/components/label/label.tsx | 2 +- packages/emcn/src/components/modal/modal.tsx | 6 +- .../emcn/src/components/popover/popover.tsx | 2 +- .../progress-item/progress-item.tsx | 4 +- .../src/components/tab-strip/tab-strip.tsx | 4 +- packages/emcn/src/components/table/table.tsx | 2 +- .../src/components/tag-input/tag-input.tsx | 4 +- .../components/time-picker/time-picker.tsx | 2 +- .../emcn/src/components/tooltip/tooltip.tsx | 4 +- .../emcn/src/hooks/use-copy-to-clipboard.ts | 2 +- .../src/icons/animate/pills-ring.module.css | 28 -- packages/emcn/src/icons/fingerprint.tsx | 33 --- packages/emcn/src/icons/index.ts | 8 - packages/emcn/src/icons/infinity.tsx | 25 -- packages/emcn/src/icons/layout.tsx | 2 +- packages/emcn/src/icons/mic-off.tsx | 28 -- packages/emcn/src/icons/panel-right.tsx | 26 -- packages/emcn/src/icons/pause.tsx | 26 -- packages/emcn/src/icons/pills-ring.tsx | 52 ---- packages/emcn/src/icons/sim.tsx | 44 ---- packages/emcn/src/icons/user.tsx | 26 -- packages/emcn/src/index.ts | 7 +- packages/emcn/src/lib/keyboard.ts | 2 +- packages/platform-authz/src/rooms.ts | 6 +- packages/platform-authz/src/workflow.ts | 18 +- packages/realtime-protocol/src/constants.ts | 14 - packages/realtime-protocol/src/rooms.ts | 4 +- packages/realtime-protocol/src/schemas.ts | 32 +-- packages/security/src/ip.ts | 2 +- packages/terminal-protocol/src/index.ts | 38 +-- .../testing/src/mocks/billing-plan-logic.ts | 2 +- .../testing/src/mocks/workflow-authz.mock.ts | 14 - packages/utils/package.json | 4 - packages/utils/src/client-info.ts | 12 +- packages/utils/src/formatting.ts | 13 - packages/utils/src/index.ts | 60 ----- packages/utils/src/paste.ts | 2 +- packages/utils/src/random.ts | 4 +- packages/utils/src/sandbox-references.ts | 5 +- packages/utils/src/workflow-references.ts | 2 +- packages/workflow-persistence/package.json | 4 - packages/workflow-persistence/src/index.ts | 19 -- .../src/subflow-helpers.ts | 4 +- packages/workflow-renderer/src/dimensions.ts | 4 +- .../src/edge/workflow-edge-view.tsx | 2 +- packages/workflow-renderer/src/index.ts | 44 +--- .../src/note/note-block-view.tsx | 2 +- .../src/subflow/subflow-node-view.tsx | 2 +- .../src/workflow-block/source-handle.ts | 2 +- .../workflow-block/workflow-block-border.tsx | 7 +- .../workflow-block/workflow-block-view.tsx | 8 +- .../workflow-renderer/src/workflow-type.tsx | 2 +- packages/workflow-types/src/workflow.ts | 10 +- scripts/check-unused-exports.baseline.json | 1 - scripts/check-unused-exports.ts | 16 +- 96 files changed, 236 insertions(+), 1163 deletions(-) delete mode 100644 packages/emcn/src/components/charts/radar-chart.tsx delete mode 100644 packages/emcn/src/icons/animate/pills-ring.module.css delete mode 100644 packages/emcn/src/icons/fingerprint.tsx delete mode 100644 packages/emcn/src/icons/infinity.tsx delete mode 100644 packages/emcn/src/icons/mic-off.tsx delete mode 100644 packages/emcn/src/icons/panel-right.tsx delete mode 100644 packages/emcn/src/icons/pause.tsx delete mode 100644 packages/emcn/src/icons/pills-ring.tsx delete mode 100644 packages/emcn/src/icons/sim.tsx delete mode 100644 packages/emcn/src/icons/user.tsx delete mode 100644 packages/utils/src/index.ts delete mode 100644 packages/workflow-persistence/src/index.ts diff --git a/.claude/rules/emcn-components.md b/.claude/rules/emcn-components.md index c21cad945cd..f302a07fa85 100644 --- a/.claude/rules/emcn-components.md +++ b/.claude/rules/emcn-components.md @@ -12,7 +12,7 @@ Import components, `cn`, and tokens from the `@sim/emcn` barrel; icons come from Never hand-roll the chip pill from raw class strings (they go stale). Compose from the canonical sources: -- **Surface, typography + content tokens:** `chip/chip-chrome.ts` — `chipFilledSurfaceTokens`, `chipFieldSurfaceClass`, `chipFieldTextClass` (text fields and the dropdown search box build on these), plus the chip-content chrome `chipContentGap`, `chipGeometryClass`, `chipContentIconClass`, `chipContentLabelClass`, `cellIconNodeClass` (non-chip surfaces that must visually match chip content, e.g. resource table cells), and the row-state pair `chipHoverSurfaceClass` / `chipActiveSurfaceClass` (hover vs. selected — mutually exclusive, so a selected row holds its surface through hover; every hand-rolled row imports these rather than restating the literals). All are re-exported from the `@sim/emcn` barrel — no subpath import needed. +- **Surface, typography + content tokens:** `chip/chip-chrome.ts` — `chipFieldSurfaceClass`, `chipFieldTextClass` (text fields and the dropdown search box build on these), plus the chip-content chrome `chipContentGap`, `chipGeometryClass`, `chipContentIconClass`, `chipContentLabelClass`, `cellIconNodeClass` (non-chip surfaces that must visually match chip content, e.g. resource table cells), and the row-state pair `chipHoverSurfaceClass` / `chipActiveSurfaceClass` (hover vs. selected — mutually exclusive, so a selected row holds its surface through hover; every hand-rolled row imports these rather than restating the literals). All are re-exported from the `@sim/emcn` barrel — no subpath import needed. - **Pill geometry:** `chip/chip.tsx` — `chipVariants` (30px tall, `rounded-lg`, `px-2`, icon↔text `gap-1.5`). Every pill-shaped trigger (`ChipDropdown`, `ChipSelect`, `ChipSwitch`) reuses it for visual parity. Canonical look: normal font-weight (never `font-medium`/`font-semibold`), value text `--text-body`, icons `--text-icon` at `size-[14px]`, placeholder `--text-muted`, `transition-colors`, **no focus ring** (the caret marks focus). Filled surface is `--surface-5` light / `--surface-4` dark with a `--border` border (`chip-chrome.ts` still spells it through the legacy alias `--border-1`; new code writes `--border`). @@ -54,6 +54,6 @@ Declare keyboard intent on the action-owning primitive; never add document-level - **Discriminated-union props for modes** (e.g. `multiple`, the modal field `type`) instead of near-duplicate components. - **Delete legacy variants after migration** — leave no dead paths. - **Verify CSS vars exist.** An undefined var resolves to `currentColor`, which draws black borders. Align to the canonical tokens: normal weight, `--text-body`, `--text-icon`. -- Use Radix UI primitives for accessibility. Export the component and its `variants` (when using CVA). Document with TSDoc + a usage example. +- Use Radix UI primitives for accessibility. Export the component; export its CVA `variants` once another module composes them (`check:unused-exports` flags an export nothing imports). Document with TSDoc + a usage example. Color tokens and icon-size conventions are canonical in `.claude/rules/sim-styling.md` — follow it rather than restating. diff --git a/.cursor/rules/emcn-components.mdc b/.cursor/rules/emcn-components.mdc index d77a4082838..3ed219f6479 100644 --- a/.cursor/rules/emcn-components.mdc +++ b/.cursor/rules/emcn-components.mdc @@ -13,7 +13,7 @@ Import components, `cn`, and tokens from the `@sim/emcn` barrel; icons come from Never hand-roll the chip pill from raw class strings (they go stale). Compose from the canonical sources: -- **Surface, typography + content tokens:** `chip/chip-chrome.ts` — `chipFilledSurfaceTokens`, `chipFieldSurfaceClass`, `chipFieldTextClass` (text fields and the dropdown search box build on these), plus the chip-content chrome `chipContentGap`, `chipGeometryClass`, `chipContentIconClass`, `chipContentLabelClass`, `cellIconNodeClass` (non-chip surfaces that must visually match chip content, e.g. resource table cells), and the row-state pair `chipHoverSurfaceClass` / `chipActiveSurfaceClass` (hover vs. selected — mutually exclusive, so a selected row holds its surface through hover; every hand-rolled row imports these rather than restating the literals). All are re-exported from the `@sim/emcn` barrel — no subpath import needed. +- **Surface, typography + content tokens:** `chip/chip-chrome.ts` — `chipFieldSurfaceClass`, `chipFieldTextClass` (text fields and the dropdown search box build on these), plus the chip-content chrome `chipContentGap`, `chipGeometryClass`, `chipContentIconClass`, `chipContentLabelClass`, `cellIconNodeClass` (non-chip surfaces that must visually match chip content, e.g. resource table cells), and the row-state pair `chipHoverSurfaceClass` / `chipActiveSurfaceClass` (hover vs. selected — mutually exclusive, so a selected row holds its surface through hover; every hand-rolled row imports these rather than restating the literals). All are re-exported from the `@sim/emcn` barrel — no subpath import needed. - **Pill geometry:** `chip/chip.tsx` — `chipVariants` (30px tall, `rounded-lg`, `px-2`, icon↔text `gap-1.5`). Every pill-shaped trigger (`ChipDropdown`, `ChipSelect`, `ChipSwitch`) reuses it for visual parity. Canonical look: normal font-weight (never `font-medium`/`font-semibold`), value text `--text-body`, icons `--text-icon` at `size-[14px]`, placeholder `--text-muted`, `transition-colors`, **no focus ring** (the caret marks focus). Filled surface is `--surface-5` light / `--surface-4` dark with a `--border` border (`chip-chrome.ts` still spells it through the legacy alias `--border-1`; new code writes `--border`). @@ -55,6 +55,6 @@ Declare keyboard intent on the action-owning primitive; never add document-level - **Discriminated-union props for modes** (e.g. `multiple`, the modal field `type`) instead of near-duplicate components. - **Delete legacy variants after migration** — leave no dead paths. - **Verify CSS vars exist.** An undefined var resolves to `currentColor`, which draws black borders. Align to the canonical tokens: normal weight, `--text-body`, `--text-icon`. -- Use Radix UI primitives for accessibility. Export the component and its `variants` (when using CVA). Document with TSDoc + a usage example. +- Use Radix UI primitives for accessibility. Export the component; export its CVA `variants` once another module composes them (`check:unused-exports` flags an export nothing imports). Document with TSDoc + a usage example. Color tokens and icon-size conventions are canonical in `.claude/rules/sim-styling.md` — follow it rather than restating. diff --git a/CLAUDE.md b/CLAUDE.md index c04bd72e209..0b70bd052b8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,7 @@ This file (also `AGENTS.md`) holds the repo-wide rules. Area detail lives in `.c - **Logging**: `createLogger` from `@sim/logger`; `logger.info` / `logger.warn` / `logger.error`, never `console.log`. Inside `withRouteHandler` the logger already carries the request ID — no manual `withMetadata({ requestId })`. - **Comments**: name things so the code explains itself. TSDoc documents exported APIs and non-obvious modules. An inline `//` is only for a terse, non-obvious *why*, or for a script-enforced `// : ` annotation (`boundary-raw-fetch`, `double-cast-allowed`, `boundary-raw-json`, `untyped-response`, `rq-lint-allow`, `client-boundary-allow`, `utils-lint-allow`, …). History belongs in the commit message. No `====` separators or commented-out code (`check:comment-hygiene` enforces this). The `/you-might-not-need-a-comment` skill applies this to a diff. - **ID generation**: `generateId()` (UUID v4, the default) or `generateShortId(size?)` (URL-safe, 21 chars by default) from `@sim/utils/id` — never `crypto.randomUUID()`, `nanoid`, or `uuid`. Both use `crypto.getRandomValues()`, so they also work in non-secure (HTTP) browsers. For other randomness, `@sim/utils/random` (`randomInt`, `randomFloat`, `randomItem`, `generateRandomBytes`, `generateRandomHex`) — never `Math.random()` or `crypto.randomBytes()`. -- **Common utilities**: use the shared helpers from `@sim/utils` instead of inline implementations (`check:utils` bans most of the inline forms below): +- **Common utilities**: use the shared helpers from the `@sim/utils/` subpaths instead of inline implementations (`check:utils` bans most of the inline forms below): - `sleep(ms)` from `@sim/utils/helpers` — never `new Promise(resolve => setTimeout(resolve, ms))` - `toError(e)` from `@sim/utils/errors` — normalize caught values to `Error`; never `e instanceof Error ? e : new Error(String(e))` - `getErrorMessage(e, fallback?)` from `@sim/utils/errors` — never `e instanceof Error ? e.message : 'fallback'` diff --git a/apps/sim/lib/credentials/application/discover-managed-mcp-tools.test.ts b/apps/sim/lib/credentials/application/discover-managed-mcp-tools.test.ts index 88ea6e613a0..85d9f375e0f 100644 --- a/apps/sim/lib/credentials/application/discover-managed-mcp-tools.test.ts +++ b/apps/sim/lib/credentials/application/discover-managed-mcp-tools.test.ts @@ -42,7 +42,7 @@ vi.mock('@/lib/mcp/application/use-cases', () => mcpUseCasesMock) vi.mock('@/lib/workspaces/application/workspace-context', () => workspaceContextMock) vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/lib/workflows/application/context', () => workflowContextMock) -vi.mock('@sim/workflow-persistence', () => ({ +vi.mock('@sim/workflow-persistence/load', () => ({ loadWorkflowFromNormalizedTablesRaw: hoisted.loadWorkflow, })) diff --git a/apps/sim/lib/mcp/application/execute-managed-tool.test.ts b/apps/sim/lib/mcp/application/execute-managed-tool.test.ts index 3ab913fadc5..5ba7deeb835 100644 --- a/apps/sim/lib/mcp/application/execute-managed-tool.test.ts +++ b/apps/sim/lib/mcp/application/execute-managed-tool.test.ts @@ -18,7 +18,7 @@ const hoisted = vi.hoisted(() => ({ saveToolSnapshot: vi.fn(), })) -vi.mock('@sim/workflow-persistence', () => ({ +vi.mock('@sim/workflow-persistence/load', () => ({ loadWorkflowFromNormalizedTablesRaw: hoisted.loadWorkflow, })) diff --git a/apps/sim/lib/mcp/application/execute-tool.test.ts b/apps/sim/lib/mcp/application/execute-tool.test.ts index a7c829ebca8..4de6ad29275 100644 --- a/apps/sim/lib/mcp/application/execute-tool.test.ts +++ b/apps/sim/lib/mcp/application/execute-tool.test.ts @@ -25,7 +25,7 @@ const hoisted = vi.hoisted(() => ({ getServer: vi.fn(), })) -vi.mock('@sim/workflow-persistence', () => ({ +vi.mock('@sim/workflow-persistence/load', () => ({ loadWorkflowFromNormalizedTablesRaw: hoisted.loadWorkflow, })) diff --git a/apps/sim/lib/mcp/application/operation-access.test.ts b/apps/sim/lib/mcp/application/operation-access.test.ts index 682d4127257..f3511058883 100644 --- a/apps/sim/lib/mcp/application/operation-access.test.ts +++ b/apps/sim/lib/mcp/application/operation-access.test.ts @@ -3,7 +3,9 @@ import { queueTableRows, resetDbChainMock, schemaMock } from '@sim/testing' import { beforeEach, describe, expect, it, vi } from 'vitest' const { loadWorkflow } = vi.hoisted(() => ({ loadWorkflow: vi.fn() })) -vi.mock('@sim/workflow-persistence', () => ({ loadWorkflowFromNormalizedTablesRaw: loadWorkflow })) +vi.mock('@sim/workflow-persistence/load', () => ({ + loadWorkflowFromNormalizedTablesRaw: loadWorkflow, +})) import { loadMcpOperationAccess, diff --git a/apps/sim/lib/mcp/application/operation-access.ts b/apps/sim/lib/mcp/application/operation-access.ts index b04a397cd4c..c495724468c 100644 --- a/apps/sim/lib/mcp/application/operation-access.ts +++ b/apps/sim/lib/mcp/application/operation-access.ts @@ -2,7 +2,7 @@ import type { Principal } from '@sim/auth/principal' import { db } from '@sim/db' import { workflowDeploymentVersion } from '@sim/db/schema' import { isPlainRecord } from '@sim/utils/object' -import { loadWorkflowFromNormalizedTablesRaw } from '@sim/workflow-persistence' +import { loadWorkflowFromNormalizedTablesRaw } from '@sim/workflow-persistence/load' import { and, eq } from 'drizzle-orm' import { OrchestrationError } from '@/lib/core/orchestration/types' import { diff --git a/apps/sim/stores/workflows/workflow/types.ts b/apps/sim/stores/workflows/workflow/types.ts index 3dbb7d8ffd6..3c602455450 100644 --- a/apps/sim/stores/workflows/workflow/types.ts +++ b/apps/sim/stores/workflows/workflow/types.ts @@ -38,7 +38,7 @@ export type { Variable, WorkflowState, } -export { isValidSubflowType, SUBFLOW_TYPES } from '@sim/workflow-types/workflow' +export { SUBFLOW_TYPES } from '@sim/workflow-types/workflow' export interface WorkflowActions { updateNodeDimensions: (id: string, dimensions: { width: number; height: number }) => void diff --git a/knip.jsonc b/knip.jsonc index 4ab2873da7a..68c63368a0e 100644 --- a/knip.jsonc +++ b/knip.jsonc @@ -4,19 +4,22 @@ // Unused exports, types, and duplicates are ratcheted by check:unused-exports, // which reuses this config in the same knip pass. "include": ["files", "dependencies", "unlisted", "unresolved"], - // knip's default, stated so it is a decision: no entry file's exports are reported. - // That keeps package `exports`/`main`/`bin` contracts (ts-sdk, emcn, cli, …) and framework - // entries (Next routes, Trigger tasks) public, and also exempts the other configured entries - // (scripts, `*.integration.ts`, `background/**`, desktop and SDK examples). - "includeEntryExports": false, + // On by default: every workspace's `exports` map serves only this monorepo, so an entry export + // no workspace imports is dead. The workspaces below turn it off because their entries are + // public or standalone: the apps (framework entries such as Next routes and Trigger tasks), the + // published packages (cli, sim-cli, sim-setup, ts-sdk), db (standalone scripts), and the root + // (scripts). A new private package is checked without opting in. + "includeEntryExports": true, "workspaces": { ".": { + "includeEntryExports": false, "entry": ["scripts/**/*.{ts,tsx}", "vitest.shared.ts"], "paths": { "@/*": ["./apps/sim/*"] }, // This alias selects the native tsc binary; see check-native-typecheck.ts. "ignoreDependencies": ["@typescript/native"] }, "apps/sim": { + "includeEntryExports": false, "entry": [ // Container bootstrap and Trigger's directory-discovered task graph. "bootstrap.ts", @@ -69,8 +72,9 @@ // Live test spawns this path with cwd=MSHIP_WORKER_ROOT (a sibling repo). "ignoreUnresolved": ["tools/probes/src/controller-run-read.ts"] }, - "apps/realtime": { "entry": ["src/bootstrap.ts"] }, + "apps/realtime": { "includeEntryExports": false, "entry": ["src/bootstrap.ts"] }, "apps/desktop": { + "includeEntryExports": false, // scripts/build.ts and e2e/updater.spec.ts supply these to esbuild by path. "entry": [ "src/main/index.ts", @@ -83,7 +87,11 @@ // ensure-pty-prebuilds.ts assembles these package names for universal builds. "ignoreDependencies": ["@lydell/node-pty-darwin-arm64", "@lydell/node-pty-darwin-x64"] }, + "apps/docs": { "includeEntryExports": false }, + "apps/pii": { "includeEntryExports": false }, + "packages/cli": { "includeEntryExports": false }, "packages/db": { + "includeEntryExports": false, "entry": [ "scripts/*.ts", "script-migrations/*.ts", @@ -91,16 +99,18 @@ "vitest.integration.setup.ts" ] }, - "packages/sim-cli": { - "entry": ["src/index.ts", "src/runtime.ts", "scripts/*.ts"] - }, - "packages/ts-sdk": { "entry": ["examples/*.ts"] }, // The contract audit reads this snapshot by filename. // Generated, so its export surface is not ratcheted either. "packages/desktop-bridge": { "entry": ["contract-snapshot.ts"], "ignoreIssues": { "contract-snapshot.ts": ["exports", "types", "duplicates"] } }, + "packages/sim-cli": { + "includeEntryExports": false, + "entry": ["src/index.ts", "src/runtime.ts", "scripts/*.ts"] + }, + "packages/sim-setup": { "includeEntryExports": false }, + "packages/ts-sdk": { "includeEntryExports": false, "entry": ["examples/*.ts"] }, // This shared config is consumed by apps that own the Next dependency. "packages/tsconfig": { "ignoreUnresolved": ["next"] } } diff --git a/packages/auth/src/principal.ts b/packages/auth/src/principal.ts index 7f0f7cb1ce7..700f541819f 100644 --- a/packages/auth/src/principal.ts +++ b/packages/auth/src/principal.ts @@ -12,7 +12,7 @@ export type Principal = | SlackAppPrincipal /** Verified app-wide ingress authority; installation lookup grants no human access. */ -export interface SlackAppPrincipal { +interface SlackAppPrincipal { kind: 'slack_app' appId: string appRevision: string @@ -94,7 +94,7 @@ export interface ExternalUserSubject { } /** Email address proven by a deployment's OTP or SSO authentication gate. */ -export interface AuthenticatedEmailSubject { +interface AuthenticatedEmailSubject { kind: 'authenticated_email' email: string } @@ -106,7 +106,7 @@ interface ActorlessSystemPrincipal { workflowId: string } -export interface ChatSystemPrincipal { +interface ChatSystemPrincipal { kind: 'system' serviceId: 'chat' workspaceId: string @@ -124,10 +124,7 @@ export interface WebhookSystemPrincipal { subject?: ExternalUserSubject } -export type SystemPrincipal = - | ActorlessSystemPrincipal - | ChatSystemPrincipal - | WebhookSystemPrincipal +type SystemPrincipal = ActorlessSystemPrincipal | ChatSystemPrincipal | WebhookSystemPrincipal interface DelegatedPrincipalBase { kind: 'delegated' @@ -153,7 +150,7 @@ export interface SubjectDelegatedPrincipal extends DelegatedPrincipalBase { subjectUserId: string } -export interface WorkflowExecutionDelegationContext { +interface WorkflowExecutionDelegationContext { kind: 'workflow_execution' workflowId: string executionId?: string diff --git a/packages/auth/src/verify.ts b/packages/auth/src/verify.ts index 432d25d4cda..62db3b08858 100644 --- a/packages/auth/src/verify.ts +++ b/packages/auth/src/verify.ts @@ -16,7 +16,7 @@ export interface VerifyAuthOptions { * created by `apps/sim`'s full auth config, so it can carry plugin fields * (e.g. `activeOrganizationId`) this minimal instance does not configure. */ -export interface VerifiedOneTimeTokenSession { +interface VerifiedOneTimeTokenSession { user: { id: string name: string | null diff --git a/packages/browser-protocol/src/index.ts b/packages/browser-protocol/src/index.ts index aae31c887e3..4aab432ff1c 100644 --- a/packages/browser-protocol/src/index.ts +++ b/packages/browser-protocol/src/index.ts @@ -57,23 +57,20 @@ export const CURRENT_BROWSER_TOOL_NAMES = [ export type CurrentBrowserToolName = (typeof CURRENT_BROWSER_TOOL_NAMES)[number] -export const RETIRED_BROWSER_TOOL_NAMES = ['browser_request_takeover'] as const +const RETIRED_BROWSER_TOOL_NAMES = ['browser_request_takeover'] as const -export const BROWSER_TOOL_NAMES = [ - ...CURRENT_BROWSER_TOOL_NAMES, - ...RETIRED_BROWSER_TOOL_NAMES, -] as const +const BROWSER_TOOL_NAMES = [...CURRENT_BROWSER_TOOL_NAMES, ...RETIRED_BROWSER_TOOL_NAMES] as const export type BrowserToolName = (typeof BROWSER_TOOL_NAMES)[number] -export const BROWSER_WAIT_FOR_DEFAULT_TIMEOUT_MS = 10_000 -export const BROWSER_WAIT_FOR_MAX_TIMEOUT_MS = 120_000 -export const BROWSER_WAIT_FOR_RENDERER_GRACE_MS = 15_000 +const BROWSER_WAIT_FOR_DEFAULT_TIMEOUT_MS = 10_000 +const BROWSER_WAIT_FOR_MAX_TIMEOUT_MS = 120_000 +const BROWSER_WAIT_FOR_RENDERER_GRACE_MS = 15_000 export const BROWSER_TOOL_AUTHORIZATION_TIMEOUT_MS = 8_000 export const BROWSER_NAVIGATION_NATIVE_WATCHDOG_MS = 60_000 export const BROWSER_TOOL_QUEUE_WAIT_TIMEOUT_MS = BROWSER_NAVIGATION_NATIVE_WATCHDOG_MS const BROWSER_RENDERER_TRANSPORT_GRACE_MS = 2_000 -export const BROWSER_NAVIGATION_RENDERER_TIMEOUT_MS = +const BROWSER_NAVIGATION_RENDERER_TIMEOUT_MS = BROWSER_TOOL_AUTHORIZATION_TIMEOUT_MS + BROWSER_TOOL_QUEUE_WAIT_TIMEOUT_MS + BROWSER_NAVIGATION_NATIVE_WATCHDOG_MS + @@ -132,7 +129,7 @@ export function browserToolRendererTimeoutMs( } } -export const BROWSER_THEMES = ['system', 'light', 'dark'] as const +const BROWSER_THEMES = ['system', 'light', 'dark'] as const /** Sim appearance preference mirrored into browser-tab media queries. */ export type BrowserTheme = (typeof BROWSER_THEMES)[number] diff --git a/packages/deployment-config/src/env-capabilities.ts b/packages/deployment-config/src/env-capabilities.ts index 27e09d0f3d6..66443facd41 100644 --- a/packages/deployment-config/src/env-capabilities.ts +++ b/packages/deployment-config/src/env-capabilities.ts @@ -28,7 +28,7 @@ export type EnvCapabilityValues = | ReadonlyMap | Readonly> -export type EnvValueValidation = +type EnvValueValidation = | { kind: 'integer' min?: number @@ -79,13 +79,13 @@ export interface AnyOfRequirement { requirements: readonly EnvRequirement[] } -export type EnvRequirement = EnvFieldRequirement | AllOfRequirement | AnyOfRequirement +type EnvRequirement = EnvFieldRequirement | AllOfRequirement | AnyOfRequirement -export type EnvProviderActivation = +type EnvProviderActivation = | { mode: 'any-present'; keys: readonly string[] } | { mode: 'enabled'; key: string } -export interface EnvProviderValidationIssue { +interface EnvProviderValidationIssue { kind: 'missing' | 'invalid' fields: readonly string[] message: string @@ -119,7 +119,7 @@ export interface FallbackCapabilityDefinition< providers: readonly TProvider[] } -export type EnvDefaultProviderDefinition = +type EnvDefaultProviderDefinition = | { id: string; kind: 'built-in'; label: string } | { id: string; kind: 'provider' } @@ -180,11 +180,6 @@ export interface SelectedCapabilityInspection< error: EnvCapabilityConfigurationError | null } -export type CapabilityInspection = - TDefinition extends SelectedCapabilityDefinition - ? SelectedCapabilityInspection, DeclaredProviderId> - : FallbackCapabilityInspection> - export class EnvCapabilityConfigurationError extends Error { constructor( readonly capabilityId: string, @@ -237,11 +232,11 @@ export function envField( return { type: 'field', key, ...options } } -export function allOf(...requirements: readonly EnvRequirement[]): AllOfRequirement { +function allOf(...requirements: readonly EnvRequirement[]): AllOfRequirement { return { type: 'allOf', requirements } } -export function anyOf(...requirements: readonly EnvRequirement[]): AnyOfRequirement { +function anyOf(...requirements: readonly EnvRequirement[]): AnyOfRequirement { return { type: 'anyOf', requirements } } @@ -352,7 +347,7 @@ export function defineCapability } /** Returns the canonical command for configuring a runtime capability. */ -export function getCapabilitySetupCommand(definition: CapabilityDefinition): string { +function getCapabilitySetupCommand(definition: CapabilityDefinition): string { return `npx sim-setup add ${definition.id}` } @@ -540,7 +535,7 @@ function inspectRequiredProvider( } } -export function inspectProvider( +function inspectProvider( provider: TProvider, values: EnvCapabilityValues ): ProviderInspection { @@ -1637,6 +1632,11 @@ export function resolveOAuthClientCapabilityId(serviceId: string): OAuthClientCa return normalized in OAUTH_CLIENT_CAPABILITIES ? (normalized as OAuthClientCapabilityId) : null } +/** + * Env fields that configure a service's OAuth client. + * + * @public scripts/generate-docs.ts loads this module by file path, which knip cannot trace. + */ export function getOAuthClientCapabilityFields(serviceId: string): readonly string[] | null { const providerId = resolveOAuthClientCapabilityId(serviceId) return providerId ? OAUTH_CLIENT_CAPABILITIES[providerId] : null diff --git a/packages/desktop-bridge/src/index.ts b/packages/desktop-bridge/src/index.ts index efc6853efc6..5a922d7a698 100644 --- a/packages/desktop-bridge/src/index.ts +++ b/packages/desktop-bridge/src/index.ts @@ -33,7 +33,7 @@ import type { TerminalToolResponse, } from '@sim/terminal-protocol' -export const PENDING_DESKTOP_SCOPE_PREFIX = 'pending:' as const +const PENDING_DESKTOP_SCOPE_PREFIX = 'pending:' as const /** Boolean results preserve compatibility with older installed desktop shells. */ export type TerminalPasteResult = boolean | 'too-large' @@ -305,7 +305,7 @@ export interface SimDesktopBrowserAgentApi { onScopeSuspended(callback: (scopeId: string) => void): () => void } -export type BrowserDownloadState = 'progressing' | 'completed' | 'interrupted' | 'cancelled' +type BrowserDownloadState = 'progressing' | 'completed' | 'interrupted' | 'cancelled' /** Safe renderer metadata for a native browser download; host paths never cross the bridge. */ export interface BrowserDownloadInfo { @@ -409,7 +409,7 @@ export interface BrowserSiteInfo { importedAt?: string } -export interface SimDesktopBrowserImportApi { +interface SimDesktopBrowserImportApi { /** Chrome profiles detected on this device; empty when none are readable. */ listChromeProfiles(): Promise /** @@ -507,7 +507,7 @@ export interface BrowserFillAvailability { * management calls require the Sim app origin, filling additionally requires * a real user gesture, and no browser tool maps to these channels. */ -export interface SimDesktopBrowserCredentialsApi { +interface SimDesktopBrowserCredentialsApi { /** False when OS-backed encryption is unavailable and passwords are disabled. */ isAvailable(): Promise /** Saved credentials, without passwords. */ @@ -575,7 +575,7 @@ export interface LocalFilesystemEntry { modifiedAt?: string } -export interface LocalFilesystemStat { +interface LocalFilesystemStat { name: string uri: string kind: LocalFilesystemEntryKind @@ -583,7 +583,7 @@ export interface LocalFilesystemStat { modifiedAt: string } -export interface LocalFilesystemReadResult { +interface LocalFilesystemReadResult { uri: string content: string startLine: number @@ -785,7 +785,7 @@ export const TERMINAL_DARK_THEME = { brightWhite: '#f0f6fc', } as const satisfies TerminalThemePalette -export type TerminalThemeSource = 'terminal' | 'iterm2' +type TerminalThemeSource = 'terminal' | 'iterm2' export interface TerminalSelectedProfile { /** Stable source profile id used to restore this selection. */ @@ -928,7 +928,7 @@ export function resolveDesktopZoom( return Math.min(bounds.max, Math.max(bounds.min, next)) } -export const DESKTOP_APPEARANCE_THEMES = ['app', 'light', 'dark'] as const +const DESKTOP_APPEARANCE_THEMES = ['app', 'light', 'dark'] as const export type DesktopAppearanceTheme = (typeof DESKTOP_APPEARANCE_THEMES)[number] @@ -957,7 +957,7 @@ export interface DesktopNotificationPayload { } /** Device-level settings owned by the desktop shell. */ -export interface SimDesktopSettingsApi { +interface SimDesktopSettingsApi { getPreferences(): Promise setPreference( key: K, @@ -981,7 +981,7 @@ export interface SimDesktopSettingsApi { setTerminalDefaultZoom(zoom: DesktopZoomPercent): Promise } -export interface SimDesktopTerminalThemesApi { +interface SimDesktopTerminalThemesApi { listProfiles(): Promise selectProfile(profileId: string): Promise } @@ -991,13 +991,7 @@ export interface SimDesktopTerminalThemesApi { * automatic downloads are disabled or the shell requires a manual installer; * self-updating shells with automatic downloads enabled move to `downloading`. */ -export type DesktopUpdateStatus = - | 'idle' - | 'checking' - | 'available' - | 'downloading' - | 'ready' - | 'error' +type DesktopUpdateStatus = 'idle' | 'checking' | 'available' | 'downloading' | 'ready' | 'error' export interface DesktopUpdateState { status: DesktopUpdateStatus @@ -1014,7 +1008,7 @@ export interface DesktopUpdateState { } /** The shell updater surface. */ -export interface SimDesktopUpdatesApi { +interface SimDesktopUpdatesApi { getState(): Promise /** * Advances the pipeline: checks for an update, downloads an available @@ -1067,7 +1061,7 @@ export type DesktopServerChangeResult = * to must stay reachable when that server cannot be reached at all, and must * never be drivable by a page the current server serves. */ -export interface SimDesktopServerApi { +interface SimDesktopServerApi { /** Opens the shell's native server-selection window. */ open(): void getConfiguration(): Promise @@ -1132,5 +1126,4 @@ export { DESKTOP_TITLE_BAR_ATTRIBUTE, type DesktopTitleBarMode, observeDesktopTitleBar, - supportsDesktopTitleBar, } from './title-bar' diff --git a/packages/desktop-bridge/src/title-bar.ts b/packages/desktop-bridge/src/title-bar.ts index 50371a40005..36ff3f0dd5c 100644 --- a/packages/desktop-bridge/src/title-bar.ts +++ b/packages/desktop-bridge/src/title-bar.ts @@ -3,7 +3,7 @@ import type { SimDesktopWindowStateApi } from '@sim/desktop-bridge' export type DesktopTitleBarMode = 'fullscreen' | 'inset' | null export const DESKTOP_TITLE_BAR_ATTRIBUTE = 'data-sim-desktop-title-bar' -export function supportsDesktopTitleBar(userAgent: string, hasDesktopBridge: boolean): boolean { +function supportsDesktopTitleBar(userAgent: string, hasDesktopBridge: boolean): boolean { return hasDesktopBridge && /Mac/i.test(userAgent) } diff --git a/packages/emcn/src/components/avatar/avatar.tsx b/packages/emcn/src/components/avatar/avatar.tsx index d3040921d74..cbb6a268d48 100644 --- a/packages/emcn/src/components/avatar/avatar.tsx +++ b/packages/emcn/src/components/avatar/avatar.tsx @@ -213,11 +213,4 @@ const AvatarFallback = React.forwardRef< }) AvatarFallback.displayName = 'AvatarFallback' -export { - Avatar, - AvatarImage, - AvatarFallback, - avatarVariants, - avatarStatusVariants, - avatarFallbackVariants, -} +export { Avatar, AvatarImage, AvatarFallback } diff --git a/packages/emcn/src/components/bulk-action-button/bulk-action-button.tsx b/packages/emcn/src/components/bulk-action-button/bulk-action-button.tsx index b24e402e274..5ca771fa464 100644 --- a/packages/emcn/src/components/bulk-action-button/bulk-action-button.tsx +++ b/packages/emcn/src/components/bulk-action-button/bulk-action-button.tsx @@ -5,7 +5,7 @@ import { Button, type ButtonProps } from '../button/button' import { chipFilledFillTokens, chipRadiusClass } from '../chip/chip-chrome' /** The shared 28px geometry and brand-hover treatment of selection action bars. */ -export const bulkActionButtonVariants = cva( +const bulkActionButtonVariants = cva( `${chipRadiusClass} size-[28px] p-0 hover-hover:bg-[var(--brand-secondary)] hover-hover:text-[var(--text-inverse)]!`, { variants: { diff --git a/packages/emcn/src/components/button/button.tsx b/packages/emcn/src/components/button/button.tsx index 4ad21bc4a37..928a4f7a61f 100644 --- a/packages/emcn/src/components/button/button.tsx +++ b/packages/emcn/src/components/button/button.tsx @@ -98,4 +98,4 @@ const Button = forwardRef( Button.displayName = 'Button' -export { Button, buttonVariants } +export { Button } diff --git a/packages/emcn/src/components/calendar/calendar.tsx b/packages/emcn/src/components/calendar/calendar.tsx index 14869f40df8..471ad120a12 100644 --- a/packages/emcn/src/components/calendar/calendar.tsx +++ b/packages/emcn/src/components/calendar/calendar.tsx @@ -55,7 +55,7 @@ function toDateString(year: number, month: number, day: number): string { * is parsed as local time to avoid the off-by-one day that `new Date('2026-05-08')` * (UTC midnight) produces in negative-offset timezones. */ -export function parseDateValue(value: string | Date | undefined): Date | null { +function parseDateValue(value: string | Date | undefined): Date | null { if (!value) return null if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value if (/^\d{4}-\d{2}-\d{2}/.test(value)) { diff --git a/packages/emcn/src/components/charts/bar-chart.tsx b/packages/emcn/src/components/charts/bar-chart.tsx index 60b0e72d90f..9f48f67c92a 100644 --- a/packages/emcn/src/components/charts/bar-chart.tsx +++ b/packages/emcn/src/components/charts/bar-chart.tsx @@ -27,7 +27,7 @@ import { useIsDarkTheme, } from '@sim/emcn' -export interface BarChartPoint { +interface BarChartPoint { timestamp: string value: number } diff --git a/packages/emcn/src/components/charts/chart-geometry.ts b/packages/emcn/src/components/charts/chart-geometry.ts index 3d6ee534d0a..fab6a5cda76 100644 --- a/packages/emcn/src/components/charts/chart-geometry.ts +++ b/packages/emcn/src/components/charts/chart-geometry.ts @@ -21,7 +21,7 @@ export const CHART_AXIS_LABEL_GAP = 8 const CHART_AXIS_GUTTER_STEP = 8 /** Estimate SVG label width before layout, allowing extra space to prevent clipping. */ -export function estimateAxisLabelWidth(text: string): number { +function estimateAxisLabelWidth(text: string): number { let width = 0 for (const character of text) { width += NARROW_GLYPH.test(character) ? 0.3 : 0.58 diff --git a/packages/emcn/src/components/charts/chart-legend.tsx b/packages/emcn/src/components/charts/chart-legend.tsx index 4beeef6fd1a..9c74c95f308 100644 --- a/packages/emcn/src/components/charts/chart-legend.tsx +++ b/packages/emcn/src/components/charts/chart-legend.tsx @@ -3,7 +3,7 @@ import { Chip, cn } from '@sim/emcn' import { cva, type VariantProps } from 'class-variance-authority' -export const chartLegendVariants = cva('flex min-w-0 flex-1 gap-0.5', { +const chartLegendVariants = cva('flex min-w-0 flex-1 gap-0.5', { variants: { layout: { column: 'flex-col', row: 'flex-wrap items-center' }, }, diff --git a/packages/emcn/src/components/charts/chart-tooltip.tsx b/packages/emcn/src/components/charts/chart-tooltip.tsx index 9350bc8d97a..432f636068b 100644 --- a/packages/emcn/src/components/charts/chart-tooltip.tsx +++ b/packages/emcn/src/components/charts/chart-tooltip.tsx @@ -3,7 +3,7 @@ import type { ReactNode } from 'react' import { CHART_PADDING, type ChartPadding } from '@sim/emcn' -export const CHART_TOOLTIP_CLASSES = +const CHART_TOOLTIP_CLASSES = 'pointer-events-none absolute rounded-lg border border-[var(--border)] bg-[var(--surface-1)] px-2 py-1.5 text-xs shadow-overlay' interface PositionChartTooltipArgs { diff --git a/packages/emcn/src/components/charts/dashboard-metric.tsx b/packages/emcn/src/components/charts/dashboard-metric.tsx index 26d8914f3a1..04b0d2ebfae 100644 --- a/packages/emcn/src/components/charts/dashboard-metric.tsx +++ b/packages/emcn/src/components/charts/dashboard-metric.tsx @@ -4,7 +4,7 @@ import type { CSSProperties } from 'react' import { AnimatedNumber, cn, Tooltip } from '@sim/emcn' import { cva, type VariantProps } from 'class-variance-authority' -export const dashboardMetricValueVariants = cva( +const dashboardMetricValueVariants = cva( 'flex min-w-0 items-baseline gap-1 whitespace-nowrap text-[var(--text-body)] tabular-nums', { variants: { diff --git a/packages/emcn/src/components/charts/index.ts b/packages/emcn/src/components/charts/index.ts index e8b18a5a6a8..194c656c0cd 100644 --- a/packages/emcn/src/components/charts/index.ts +++ b/packages/emcn/src/components/charts/index.ts @@ -1,12 +1,11 @@ export { AnimatedNumber } from './animated-number' -export { BarChart, type BarChartPoint, type BarChartProps, type BarChartSeries } from './bar-chart' +export { BarChart, type BarChartSeries } from './bar-chart' export { ChartDataTable } from './chart-data-table' export * from './chart-format' export { ChartFrame } from './chart-frame' export * from './chart-geometry' -export { ChartLegend, type ChartLegendItem, chartLegendVariants } from './chart-legend' +export { ChartLegend, type ChartLegendItem } from './chart-legend' export * from './chart-tooltip' -export { DashboardMetric, dashboardMetricValueVariants } from './dashboard-metric' -export { LineChart, type LineChartMultiSeries, type LineChartPoint } from './line-chart' -export { RadarChart, type RadarChartAxis } from './radar-chart' +export { DashboardMetric } from './dashboard-metric' +export { LineChart } from './line-chart' export { useChartWidth, useIsDarkTheme } from './use-chart-theme' diff --git a/packages/emcn/src/components/charts/line-chart.tsx b/packages/emcn/src/components/charts/line-chart.tsx index 29f7ef2d673..ecf85764afc 100644 --- a/packages/emcn/src/components/charts/line-chart.tsx +++ b/packages/emcn/src/components/charts/line-chart.tsx @@ -27,12 +27,12 @@ import { useIsDarkTheme, } from '@sim/emcn' -export interface LineChartPoint { +interface LineChartPoint { timestamp: string value: number } -export interface LineChartMultiSeries { +interface LineChartMultiSeries { id: string label: string color: string diff --git a/packages/emcn/src/components/charts/radar-chart.tsx b/packages/emcn/src/components/charts/radar-chart.tsx deleted file mode 100644 index c4285306476..00000000000 --- a/packages/emcn/src/components/charts/radar-chart.tsx +++ /dev/null @@ -1,239 +0,0 @@ -'use client' - -import { memo, useId, useMemo, useState } from 'react' -import { - CHART_GRID_FRACTIONS, - CHART_TICK_FILL, - CHART_TICK_FONT_SIZE, - ChartTooltip, - ChartTooltipRow, - estimateAxisLabelWidth, - estimateTooltipHeight, - estimateTooltipWidth, - positionChartTooltip, - useChartWidth, - useIsDarkTheme, -} from '@sim/emcn' -import { truncate } from '@sim/utils/string' - -export interface RadarChartAxis { - label: string - value: number - /** Text shown for `value` in the hover row. Defaults to the raw number. */ - display?: string -} - -interface RadarChartProps { - axes: RadarChartAxis[] - color: string - height?: number -} - -/** Room above and below the web for the captions on the vertical centreline. */ -const LABEL_GUTTER = 52 - -/** Gap between the outer ring and a caption anchored beyond it. */ -const LABEL_GAP = 12 - -/** Cap captions to prevent overflow; tooltips retain the full label. */ -const MAX_LABEL_LENGTH = 16 - -/** Start at twelve o’clock so categories follow clockwise in list order. */ -function axisPoint(index: number, count: number, radius: number, cx: number, cy: number) { - const angle = (index / count) * Math.PI * 2 - Math.PI / 2 - return { x: cx + Math.cos(angle) * radius, y: cy + Math.sin(angle) * radius } -} - -function polygon(points: ReadonlyArray<{ x: number; y: number }>): string { - return points.map((p) => `${p.x.toFixed(2)},${p.y.toFixed(2)}`).join(' ') -} - -/** Compares category values on a shared radial scale normalized to the largest value. */ -function RadarChartComponent({ axes, color, height = 200 }: RadarChartProps) { - const uniqueId = useId().replace(/:/g, '') - const [containerRef, containerWidth] = useChartWidth() - const isDark = useIsDarkTheme() - const [hoverIndex, setHoverIndex] = useState(null) - - const width = containerWidth ?? 0 - const cx = width / 2 - const cy = height / 2 - /** Reserve caption width and reuse geometry during hover updates. */ - const { maxValue, radius, points } = useMemo(() => { - const labelWidth = axes.reduce( - (max, axis) => Math.max(max, estimateAxisLabelWidth(truncate(axis.label, MAX_LABEL_LENGTH))), - 0 - ) - const webRadius = Math.max( - 0, - Math.min(width / 2 - labelWidth - LABEL_GAP, height / 2 - LABEL_GUTTER / 2) - ) - const peak = Math.max(...axes.map((axis) => axis.value), 0) - return { - maxValue: peak, - radius: webRadius, - points: axes.map((axis, index) => { - const fraction = peak > 0 ? axis.value / peak : 0 - return { - axis, - outer: axisPoint(index, axes.length, webRadius, cx, cy), - value: axisPoint(index, axes.length, webRadius * fraction, cx, cy), - label: axisPoint(index, axes.length, webRadius + LABEL_GAP, cx, cy), - } - }), - } - }, [axes, width, height, cx, cy]) - - if (containerWidth === null) { - return
- } - - /** - Three axes are the fewest that enclose an area; below that the "polygon" is a - line or a point and reads as a rendering fault rather than as a distribution. - */ - if (axes.length < 3 || maxValue <= 0) { - return ( -
-

No data

-
- ) - } - - const hovered = hoverIndex !== null ? points[hoverIndex] : null - - return ( - /** Anchor tooltips to the plot so they scroll with it. */ -
-
- - - - - - - - - {[...CHART_GRID_FRACTIONS, 1].map((fraction) => ( - axisPoint(index, axes.length, radius * fraction, cx, cy)) - )} - fill='none' - stroke='var(--border)' - strokeOpacity={fraction === 1 ? 1 : 0.35} - strokeWidth='1' - /> - ))} - {points.map((point, index) => ( - - ))} - - - point.value))} - fill={`url(#radar-${uniqueId})`} - stroke={color} - strokeWidth={isDark ? 1.7 : 2} - strokeLinejoin='round' - /> - {points.map((point, index) => ( - - ))} - - - {points.map((point) => ( - cx ? 'start' : 'end' - } - dominantBaseline={ - Math.abs(point.label.x - cx) >= 1 - ? 'middle' - : point.label.y > cy - ? 'hanging' - : 'auto' - } - fontSize={CHART_TICK_FONT_SIZE} - fill={CHART_TICK_FILL} - > - {truncate(point.axis.label, MAX_LABEL_LENGTH)} - - ))} - - {/** Arc sectors cover the outer vertices; triangular targets leave gaps at low axis counts. */} - {points.map((point, index) => { - const half = Math.PI / axes.length - const angle = (index / axes.length) * Math.PI * 2 - Math.PI / 2 - const reach = radius + LABEL_GUTTER / 2 - const a = { - x: cx + Math.cos(angle - half) * reach, - y: cy + Math.sin(angle - half) * reach, - } - const b = { - x: cx + Math.cos(angle + half) * reach, - y: cy + Math.sin(angle + half) * reach, - } - return ( - setHoverIndex(index)} - onMouseLeave={() => setHoverIndex(null)} - /> - ) - })} - - - {hovered && - (() => { - const value = hovered.axis.display ?? String(hovered.axis.value) - /** Place tooltips beside the vertex, using caption clearance instead of axis gutters. */ - const { left, top } = positionChartTooltip({ - anchorX: hovered.value.x, - anchorY: hovered.value.y, - width, - height, - tooltipMaxWidth: estimateTooltipWidth( - Math.max(hovered.axis.label.length, value.length) - ), - tooltipHeight: estimateTooltipHeight(1, true), - padding: { top: 0, right: LABEL_GAP, bottom: 0, left: LABEL_GAP }, - }) - return ( - - - - ) - })()} -
-
- ) -} - -export const RadarChart = memo(RadarChartComponent) diff --git a/packages/emcn/src/components/chip-button-group/chip-button-group.tsx b/packages/emcn/src/components/chip-button-group/chip-button-group.tsx index 5b779537ff6..8e7aa465f03 100644 --- a/packages/emcn/src/components/chip-button-group/chip-button-group.tsx +++ b/packages/emcn/src/components/chip-button-group/chip-button-group.tsx @@ -30,7 +30,7 @@ function useChipButtonGroupContext() { return context } -export interface ChipButtonGroupProps +interface ChipButtonGroupProps extends Omit, 'onChange'>, VariantProps { /** Currently selected value */ @@ -91,8 +91,7 @@ function ChipButtonGroup({ const chipButtonGroupItemVariants = segmentedControlItemVariants -export interface ChipButtonGroupItemProps - extends Omit, 'onClick'> { +interface ChipButtonGroupItemProps extends Omit, 'onClick'> { /** Value associated with this item */ value: string /** Disables this specific item */ @@ -130,9 +129,4 @@ function ChipButtonGroupItem({ ChipButtonGroup.displayName = 'ChipButtonGroup' ChipButtonGroupItem.displayName = 'ChipButtonGroupItem' -export { - ChipButtonGroup, - ChipButtonGroupItem, - chipButtonGroupVariants, - chipButtonGroupItemVariants, -} +export { ChipButtonGroup, ChipButtonGroupItem } diff --git a/packages/emcn/src/components/chip-date-picker/chip-date-picker.tsx b/packages/emcn/src/components/chip-date-picker/chip-date-picker.tsx index ca65061ab31..74b6a45b7f3 100644 --- a/packages/emcn/src/components/chip-date-picker/chip-date-picker.tsx +++ b/packages/emcn/src/components/chip-date-picker/chip-date-picker.tsx @@ -66,7 +66,7 @@ interface ChipDatePickerRangeProps extends ChipDatePickerBaseProps { onClear?: () => void } -export type ChipDatePickerProps = ChipDatePickerSingleProps | ChipDatePickerRangeProps +type ChipDatePickerProps = ChipDatePickerSingleProps | ChipDatePickerRangeProps /** * Date counterpart to {@link ChipDropdown} — a chip-styled trigger that opens a diff --git a/packages/emcn/src/components/chip-modal/chip-modal.tsx b/packages/emcn/src/components/chip-modal/chip-modal.tsx index fe0f428bbfa..5527ea3720d 100644 --- a/packages/emcn/src/components/chip-modal/chip-modal.tsx +++ b/packages/emcn/src/components/chip-modal/chip-modal.tsx @@ -190,7 +190,7 @@ function handleChipModalEnter(event: React.KeyboardEvent): void action.click() } -export interface ChipModalProps { +interface ChipModalProps { /** Controlled open state. */ open: boolean /** Open-state change handler. */ @@ -298,7 +298,7 @@ function ChipModal({ ChipModal.displayName = 'ChipModal' -export interface ChipModalHeaderProps extends React.HTMLAttributes { +interface ChipModalHeaderProps extends React.HTMLAttributes { /** Optional leading icon. Pass `null`/omit for a title-only header. */ icon?: React.ComponentType<{ className?: string }> | null /** Invoked when the trailing close button is activated. Always rendered. */ @@ -362,7 +362,7 @@ const ChipModalHeader = React.forwardRef( ChipModalHeader.displayName = 'ChipModalHeader' /** Tab entry for {@link ChipModalTabs}. */ -export interface ChipModalTab { +interface ChipModalTab { /** Stable value used to track the active tab. */ value: string /** Visible tab label. */ @@ -371,7 +371,7 @@ export interface ChipModalTab { icon?: React.ComponentType<{ className?: string }> } -export interface ChipModalTabsProps { +interface ChipModalTabsProps { /** Tab definitions in display order. */ tabs: ReadonlyArray /** Currently-active tab value. */ @@ -433,7 +433,7 @@ ChipModalTabs.displayName = 'ChipModalTabs' * content exceeds the viewport cap (`max-h-[84vh]` on `ModalContent`), so * header and footer stay pinned. */ -export interface ChipModalBodyProps extends React.HTMLAttributes { +interface ChipModalBodyProps extends React.HTMLAttributes { /** Removes the field gutter and scrolling chrome for one edge-to-edge surface. */ fullBleed?: boolean } @@ -455,70 +455,12 @@ const ChipModalBody = React.forwardRef( ChipModalBody.displayName = 'ChipModalBody' -export interface ChipModalPromptBodyProps extends React.HTMLAttributes { - /** - * Minimum body height in pixels, so the prompt surface presents as an open - * canvas rather than collapsing to a single line. - * @default 140 - */ - minHeight?: number -} - -/** - * Body variant whose ENTIRE content is a single borderless multi-line text - * surface — an Attio-style prompt modal. Compose it exactly like - * {@link ChipModalBody} (same header above, same footer below); only the body - * differs: instead of labeled `ChipModalField` rows, the one child is a - * full-bleed prompt editor (canonically the home `PromptEditor`, which brings - * `@`-mention and `/`-skill chips, caret-anchored menus, and the overlay chip - * rendering of the chat input). - * - * Gutter math: the editor's mirror field carries its own `px-1 py-1` text - * padding, so this container pads `px-3 pt-3 pb-3.5` — text lands at the same - * effective `px-4 pt-4 pb-4.5` as `ChipModalBody` + `ChipModalField`, aligned - * with the `px-4` header/footer. The first child (the editor) is stretched so - * the whole body acts as one clickable text surface; any trailing sibling - * (e.g. a `ChipModalError`) keeps its natural height. - * - * @example - * ```tsx - * const editor = usePromptEditor({ workspaceId }) - * - * New task - * - * - * - * - * - * ``` - */ -const ChipModalPromptBody = React.forwardRef( - ({ className, style, minHeight = 140, children, ...props }, ref) => ( -
:first-child]:flex-1', - className - )} - style={{ ...style, minHeight }} - {...props} - > - {children} -
- ) -) - -ChipModalPromptBody.displayName = 'ChipModalPromptBody' - /** * Option entry for the `dropdown` branch of {@link ChipModalField}. Aliases the * canonical {@link ChipDropdownOption} so the modal dropdown stays in lockstep * with `ChipDropdown` (gains the optional leading `icon`). */ -export type ChipModalDropdownOption = ChipDropdownOption +type ChipModalDropdownOption = ChipDropdownOption /** * Props shared by every {@link ChipModalField} branch. @@ -710,7 +652,7 @@ interface ChipModalFileFieldProps extends ChipModalFieldBaseProps { * `variant` is not forwarded: the field always uses the tall `block` chip * surface so it stacks as a peer with `textarea` fields. */ -export interface ChipModalEmailsFieldProps +interface ChipModalEmailsFieldProps extends ChipModalFieldBaseProps, Omit { type: 'emails' @@ -753,7 +695,7 @@ interface ChipModalCustomFieldProps extends ChipModalFieldBaseProps { children: React.ReactNode | ((aria: ChipModalFieldAria) => React.ReactNode) } -export type ChipModalFieldProps = +type ChipModalFieldProps = | ChipModalInputFieldProps | ChipModalEmailFieldProps | ChipModalTextareaFieldProps @@ -1235,15 +1177,15 @@ export type ChipModalFooterAction = ChipModalFooterActionBase & * margin. The primary action stays declarative by design; only * `secondaryActions` accepts custom controls. */ -export interface ChipModalFooterCustomAction { +interface ChipModalFooterCustomAction { /** Chip-chrome control rendered verbatim in the slot. */ custom: React.ReactNode } /** One entry of the footer's left-docked `secondaryActions` cluster. */ -export type ChipModalFooterSlotAction = ChipModalFooterAction | ChipModalFooterCustomAction +type ChipModalFooterSlotAction = ChipModalFooterAction | ChipModalFooterCustomAction -export type ChipModalFooterDefaultAction = 'primary' | 'dismiss' | 'none' +type ChipModalFooterDefaultAction = 'primary' | 'dismiss' | 'none' interface ChipModalFooterCommonProps { /** Label for the dismiss action, such as Cancel, Later, or Stay. */ @@ -1307,7 +1249,7 @@ type ChipModalFooterCancelProps = hideCancel: true } -export type ChipModalFooterProps = ChipModalFooterCommonProps & +type ChipModalFooterProps = ChipModalFooterCommonProps & ChipModalFooterCancelProps & ( | { @@ -1459,7 +1401,7 @@ ChipModalFooter.displayName = 'ChipModalFooter' * while the async action runs and the primitive disables BOTH buttons (so the * dismiss can't be clicked mid-mutation) and swaps in `pendingLabel`. */ -export interface ChipConfirmAction { +interface ChipConfirmAction { /** Resting button label (e.g. `'Delete'`). */ label: string /** Invoked when the user confirms. */ @@ -1525,9 +1467,9 @@ export type ChipConfirmTextSegment = * single-style sentences, or an ordered run of {@link ChipConfirmTextSegment}s * when parts need emphasis or error coloring. */ -export type ChipConfirmText = string | readonly ChipConfirmTextSegment[] +type ChipConfirmText = string | readonly ChipConfirmTextSegment[] -export type ChipConfirmDefaultAction = 'confirm' | 'dismiss' | 'none' +type ChipConfirmDefaultAction = 'confirm' | 'dismiss' | 'none' /** True when `text` resolves to at least one non-empty run. */ function hasChipConfirmText(text: ChipConfirmText | undefined): text is ChipConfirmText { @@ -1568,7 +1510,7 @@ function renderChipConfirmText(text: ChipConfirmText): React.ReactNode { }) } -export interface ChipConfirmModalProps { +interface ChipConfirmModalProps { /** Controlled open state. */ open: boolean /** @@ -1765,7 +1707,7 @@ function ChipConfirmModal({ ChipConfirmModal.displayName = 'ChipConfirmModal' -export interface ChipModalErrorProps extends React.HTMLAttributes { +interface ChipModalErrorProps extends React.HTMLAttributes { /** Error message. When falsy the component renders nothing. */ children?: React.ReactNode } @@ -1809,6 +1751,5 @@ export { ChipModalField, ChipModalFooter, ChipModalHeader, - ChipModalPromptBody, ChipModalTabs, } diff --git a/packages/emcn/src/components/chip-switch/chip-switch.tsx b/packages/emcn/src/components/chip-switch/chip-switch.tsx index f3001005d1d..a8a6d75e7af 100644 --- a/packages/emcn/src/components/chip-switch/chip-switch.tsx +++ b/packages/emcn/src/components/chip-switch/chip-switch.tsx @@ -11,7 +11,7 @@ import { scrollFadeAttributes, scrollFadeXClass } from '../scroll-fade/scroll-fa * One segment in a {@link ChipSwitch}. `label` accepts a `ReactNode` so callers * can render colored accents (e.g. a discount badge) inline. */ -export interface ChipSwitchOption { +interface ChipSwitchOption { /** The value associated with this option — passed to `onChange` on select. */ value: T /** Visible label content; `ReactNode` allows inline badges or colored spans. */ diff --git a/packages/emcn/src/components/chip-time-picker/chip-time-picker.tsx b/packages/emcn/src/components/chip-time-picker/chip-time-picker.tsx index 6bebb61d419..917b69df89d 100644 --- a/packages/emcn/src/components/chip-time-picker/chip-time-picker.tsx +++ b/packages/emcn/src/components/chip-time-picker/chip-time-picker.tsx @@ -41,7 +41,7 @@ function parseTimeInput(raw: string): string | null { return `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}` } -export interface ChipTimePickerProps { +interface ChipTimePickerProps { /** Selected time as an `HH:mm` (24h) string. */ value?: string /** Called with the committed time in `HH:mm` format. */ diff --git a/packages/emcn/src/components/chip/chip-chrome.ts b/packages/emcn/src/components/chip/chip-chrome.ts index b4c5d63c52c..6b4f811d682 100644 --- a/packages/emcn/src/components/chip/chip-chrome.ts +++ b/packages/emcn/src/components/chip/chip-chrome.ts @@ -6,7 +6,7 @@ export const chipFilledFillTokens = 'bg-[var(--surface-5)] dark:bg-[var(--surfac * ({@link chipFilledFillTokens}); pill triggers (`ChipDropdown`/`ChipSelect`/ * `ChipDatePicker`) opt into the border via `TRIGGER_BORDER_CLASS`. */ -export const chipFilledSurfaceTokens = `border border-[var(--border-1)] ${chipFilledFillTokens}` +const chipFilledSurfaceTokens = `border border-[var(--border-1)] ${chipFilledFillTokens}` /** * The primary (inverse) chip fill at rest — dark fill, inverse text, mirrored in * dark mode. `chipVariants`' `primary` variant composes this with its hover diff --git a/packages/emcn/src/components/combobox/combobox.tsx b/packages/emcn/src/components/combobox/combobox.tsx index e77eeda0007..fcffa3492ac 100644 --- a/packages/emcn/src/components/combobox/combobox.tsx +++ b/packages/emcn/src/components/combobox/combobox.tsx @@ -1145,4 +1145,4 @@ const Combobox = memo( Combobox.displayName = 'Combobox' -export { Combobox, comboboxVariants } +export { Combobox } diff --git a/packages/emcn/src/components/composer-action-button/composer-action-button.tsx b/packages/emcn/src/components/composer-action-button/composer-action-button.tsx index 806f128a179..e69940ed00f 100644 --- a/packages/emcn/src/components/composer-action-button/composer-action-button.tsx +++ b/packages/emcn/src/components/composer-action-button/composer-action-button.tsx @@ -4,7 +4,7 @@ import { cn } from '../../lib/cn' import { Button, type ButtonProps } from '../button/button' /** Shared circular send, stop and search appearance, including the compact chat treatment. */ -export const composerActionButtonVariants = cva('rounded-full p-0', { +const composerActionButtonVariants = cva('rounded-full p-0', { variants: { size: { sm: 'size-[22px]', diff --git a/packages/emcn/src/components/dropdown-menu/dropdown-menu.tsx b/packages/emcn/src/components/dropdown-menu/dropdown-menu.tsx index ae0f078db0b..8b763065770 100644 --- a/packages/emcn/src/components/dropdown-menu/dropdown-menu.tsx +++ b/packages/emcn/src/components/dropdown-menu/dropdown-menu.tsx @@ -85,7 +85,7 @@ const MENU_ROW_SELECTED_CLASS = const MENU_ROW_SINGLE_LINE_CLASS = 'whitespace-nowrap [&>span]:min-w-0 [&>span:not([data-overflow-text])]:overflow-hidden [&>span:not([data-overflow-text])]:text-clip' -export type DropdownMenuItemLabelProps = Omit +type DropdownMenuItemLabelProps = Omit /** Canonical fade-only label for a menu row with icons, checks, or actions. */ const DropdownMenuItemLabel = React.memo(function DropdownMenuItemLabel({ @@ -192,16 +192,6 @@ function DropdownMenu({ const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger -const DropdownMenuGroup = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -DropdownMenuGroup.displayName = DropdownMenuPrimitive.Group.displayName - -const DropdownMenuPortal = DropdownMenuPrimitive.Portal - const DropdownMenuSub = DropdownMenuPrimitive.Sub const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup @@ -320,7 +310,7 @@ DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName export const dropdownMenuRowClass = `relative flex ${MENU_ROW_HEIGHT_CLASS} min-w-0 cursor-pointer select-none items-center ${chipContentGap} ${MENU_ROW_RADIUS_CLASS} px-2 text-[var(--text-body)] text-small outline-hidden ${MENU_ROW_TRANSITION_CLASS} data-[disabled]:pointer-events-none data-[disabled]:opacity-50 ${MENU_ROW_SINGLE_LINE_CLASS} [&_svg]:pointer-events-none [&_svg]:size-[14px] [&_svg]:shrink-0 [&_svg]:text-[var(--text-icon)]` /** Large rows match the sidebar's chip geometry without changing menu behavior. */ -export const dropdownMenuItemVariants = cva(dropdownMenuRowClass, { +const dropdownMenuItemVariants = cva(dropdownMenuRowClass, { variants: { size: { default: '', lg: chipGeometryClass }, }, @@ -644,8 +634,6 @@ export { DropdownMenuSeparator, DropdownMenuSearchInput, DropdownMenuShortcut, - DropdownMenuGroup, - DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, diff --git a/packages/emcn/src/components/index.ts b/packages/emcn/src/components/index.ts index 975d060b136..da21429fe6d 100644 --- a/packages/emcn/src/components/index.ts +++ b/packages/emcn/src/components/index.ts @@ -1,16 +1,8 @@ export { Avatar, AvatarFallback, AvatarImage } from './avatar/avatar' export { Badge, type BadgeProps, badgeVariants } from './badge/badge' export { Banner } from './banner/banner' -export { - BulkActionButton, - type BulkActionButtonProps, - bulkActionButtonVariants, -} from './bulk-action-button/bulk-action-button' -export { Button, buttonVariants } from './button/button' -export { - CalendarDayCell, - type CalendarDayCellProps, -} from './calendar/calendar-day-cell' +export { BulkActionButton } from './bulk-action-button/bulk-action-button' +export { Button } from './button/button' export { Checkbox, checkboxIconVariants, checkboxVariants } from './checkbox/checkbox' export { Chip, @@ -32,9 +24,7 @@ export { chipFieldSurfaceClass, chipFieldTextClass, chipFilledFillTokens, - chipFilledSurfaceTokens, chipGeometryClass, - chipGeometryUnroundedClass, chipHoverSurfaceClass, chipIconSlotClass, chipPrimaryFillTokens, @@ -44,73 +34,40 @@ export { export { ChipButtonGroup, ChipButtonGroupItem, - type ChipButtonGroupItemProps, - type ChipButtonGroupProps, - chipButtonGroupItemVariants, - chipButtonGroupVariants, } from './chip-button-group/chip-button-group' export { ChipCombobox } from './chip-combobox/chip-combobox' -export { - ChipCopyInput, - type ChipCopyInputProps, -} from './chip-copy-input/chip-copy-input' +export { ChipCopyInput } from './chip-copy-input/chip-copy-input' export { ChipDatePicker } from './chip-date-picker/chip-date-picker' export { ChipDropdown, type ChipDropdownOption, type ChipDropdownProps, } from './chip-dropdown/chip-dropdown' -export { - ChipEmailsInput, - type ChipEmailsInputProps, -} from './chip-emails-input/chip-emails-input' +export { ChipEmailsInput } from './chip-emails-input/chip-emails-input' export { ChipInput, type ChipInputProps } from './chip-input/chip-input' export { - type ChipConfirmAction, - type ChipConfirmDefaultAction, ChipConfirmModal, - type ChipConfirmModalProps, - type ChipConfirmText, type ChipConfirmTextSegment, ChipModal, ChipModalBody, - type ChipModalBodyProps, ChipModalDescription, - type ChipModalDescriptionProps, - type ChipModalDropdownOption, - type ChipModalEmailsFieldProps, ChipModalError, - type ChipModalErrorProps, ChipModalField, type ChipModalFieldAria, - type ChipModalFieldProps, ChipModalFooter, type ChipModalFooterAction, - type ChipModalFooterCustomAction, - type ChipModalFooterDefaultAction, - type ChipModalFooterProps, - type ChipModalFooterSlotAction, ChipModalHeader, - type ChipModalHeaderProps, - ChipModalPromptBody, - type ChipModalPromptBodyProps, - type ChipModalProps, ChipModalSeparator, ChipModalSurface, - type ChipModalTab, ChipModalTabs, - type ChipModalTabsProps, focusChipModalContent, } from './chip-modal/chip-modal' -export { ChipSelect, type ChipSelectOption, type ChipSelectProps } from './chip-select/chip-select' -export { - ChipSwitch, - type ChipSwitchOption, - type ChipSwitchProps, -} from './chip-switch/chip-switch' -export { ChipTag, type ChipTagProps, chipTagVariants } from './chip-tag/chip-tag' -export { ChipTextarea, type ChipTextareaProps } from './chip-textarea/chip-textarea' -export { ChipTimePicker, type ChipTimePickerProps } from './chip-time-picker/chip-time-picker' +export { ChipSelect, type ChipSelectOption } from './chip-select/chip-select' +export { ChipSwitch } from './chip-switch/chip-switch' +export { ChipTag, chipTagVariants } from './chip-tag/chip-tag' +export { ChipTextarea } from './chip-textarea/chip-textarea' +/** @public The documented time sibling of `ChipDatePicker`; consumers import it from the barrel. */ +export { ChipTimePicker } from './chip-time-picker/chip-time-picker' export { CODE_LINE_HEIGHT_PX, Code, @@ -119,29 +76,21 @@ export { } from './code/code' export { CopyCodeButton } from './code/copy-code-button' export { highlight, languages } from './code/prism' -export { CollapsibleCard, type CollapsibleCardProps } from './collapsible-card/collapsible-card' +export { CollapsibleCard } from './collapsible-card/collapsible-card' export { Combobox, type ComboboxOption, type ComboboxOptionGroup, } from './combobox/combobox' -export { - ComposerActionButton, - type ComposerActionButtonProps, - composerActionButtonVariants, -} from './composer-action-button/composer-action-button' -export { DetailsPanel, type DetailsPanelProps } from './details-panel/details-panel' +export { ComposerActionButton } from './composer-action-button/composer-action-button' +export { DetailsPanel } from './details-panel/details-panel' export { DropdownMenu, - DropdownMenuCheckboxItem, DropdownMenuContent, - DropdownMenuGroup, DropdownMenuItem, DropdownMenuItemAction, DropdownMenuItemLabel, - type DropdownMenuItemLabelProps, DropdownMenuLabel, - DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSearchInput, @@ -159,18 +108,13 @@ export { Info } from './info/info' export { InfoCard, InfoCardItem, - type InfoCardItemProps, InfoCardList, - type InfoCardListProps, - type InfoCardProps, } from './info-card/info-card' -export { Input, type InputProps } from './input/input' -export { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from './input-otp/input-otp' +export { Input } from './input/input' +export { InputOTP, InputOTPGroup, InputOTPSlot } from './input-otp/input-otp' export { Label } from './label/label' -export { Lightbox, type LightboxProps } from './lightbox/lightbox' -export { focusFirstTextInput, focusFirstTextInputIn } from './modal/auto-focus' +export { Lightbox } from './lightbox/lightbox' export { - MODAL_SIZES, Modal, ModalBody, ModalClose, @@ -178,8 +122,6 @@ export { ModalDescription, ModalFooter, ModalHeader, - ModalOverlay, - ModalPortal, ModalTabs, ModalTabsContent, ModalTabsList, @@ -188,12 +130,10 @@ export { ModalTrigger, NATIVE_SURFACE_OCCLUSION_PREPARE_EVENT, type NativeSurfaceOcclusionPrepareDetail, - useModalDismissDisabled, useNativeSurfaceOcclusionReady, } from './modal/modal' export { OverflowText, - type OverflowTextProps, overflowFadeSizeClass, overflowTextClipClass, overflowTextFadeClass, @@ -215,16 +155,15 @@ export { } from './popover/popover' export { POPOVER_ANIMATION_CLASSES } from './popover/popover-animation' export { ProgressItem } from './progress-item/progress-item' -export { RowActions, type RowActionsProps, rowActionsGroupClass } from './row-actions/row-actions' +export { RowActions, rowActionsGroupClass } from './row-actions/row-actions' export { SecretInput } from './secret-input/secret-input' export { SecretReveal } from './secret-reveal/secret-reveal' export { WORDMARK_PATHS, WORDMARK_VIEW_BOX } from './sim-wordmark/paths' -export { SimWordmark, type SimWordmarkProps } from './sim-wordmark/sim-wordmark' +export { SimWordmark } from './sim-wordmark/sim-wordmark' export { Skeleton } from './skeleton/skeleton' export { Slider } from './slider/slider' export { LogoPage, - type LogoPageProps, PAGE_CONTENT_WIDTH, PAGE_GUTTER, StatusPageContent, @@ -235,14 +174,10 @@ export { TabStrip, type TabStripDragContext, type TabStripItem, - type TabStripProps, type TabStripSelectionSource, - type TabStripVariant, - tabDropIndex, tabStripItemSelector, - tabStripWheelPosition, } from './tab-strip/tab-strip' -export { TabStripAction, type TabStripActionProps } from './tab-strip/tab-strip-action' +export { TabStripAction } from './tab-strip/tab-strip-action' export { Table, TableBody, @@ -253,24 +188,16 @@ export { TableHeader, TableRow, } from './table/table' -export { type FileInputOptions, TagInput, type TagItem } from './tag-input/tag-input' +export { TagInput, type TagItem } from './tag-input/tag-input' export { Textarea } from './textarea/textarea' -export { TimePicker, timePickerVariants } from './time-picker/time-picker' +export { TimePicker } from './time-picker/time-picker' export { ToastProvider, toast, useToast } from './toast/toast' export { - clamp, FloatingTooltip, - type FloatingTooltipHandlers, - type FloatingTooltipState, - isFocusVisible, isTextClipped, Tooltip, - type UseFloatingTooltipOptions, useFloatingTooltip, useIsOverflowing, } from './tooltip/tooltip' -export { - UploadPreviewButton, - type UploadPreviewButtonProps, -} from './upload-preview-button/upload-preview-button' +export { UploadPreviewButton } from './upload-preview-button/upload-preview-button' export { Wizard } from './wizard/wizard' diff --git a/packages/emcn/src/components/info-card/info-card.tsx b/packages/emcn/src/components/info-card/info-card.tsx index 11fd521792c..2913ce6054e 100644 --- a/packages/emcn/src/components/info-card/info-card.tsx +++ b/packages/emcn/src/components/info-card/info-card.tsx @@ -23,7 +23,7 @@ import * as React from 'react' import { Check } from '../../icons' import { cn } from '../../lib/cn' -export interface InfoCardProps extends React.HTMLAttributes {} +interface InfoCardProps extends React.HTMLAttributes {} /** * Root container. Owns the chip-input chrome — same tokens as `Input` and @@ -43,7 +43,7 @@ const InfoCard = React.forwardRef(({ className, . InfoCard.displayName = 'InfoCard' -export interface InfoCardListProps extends React.HTMLAttributes { +interface InfoCardListProps extends React.HTMLAttributes { /** * Tailwind class controlling the scrollable region's max height. * @default 'max-h-[200px]' @@ -69,7 +69,7 @@ const InfoCardList = React.forwardRef( InfoCardList.displayName = 'InfoCardList' -export interface InfoCardItemProps extends React.LiHTMLAttributes { +interface InfoCardItemProps extends React.LiHTMLAttributes { /** * Leading glyph. Defaults to `Check`. Pass `null` to omit. */ diff --git a/packages/emcn/src/components/input-otp/input-otp.tsx b/packages/emcn/src/components/input-otp/input-otp.tsx index cf5da3a0569..128d9b5abbd 100644 --- a/packages/emcn/src/components/input-otp/input-otp.tsx +++ b/packages/emcn/src/components/input-otp/input-otp.tsx @@ -22,13 +22,11 @@ * @see InputOTP - Root component wrapping OTPInput * @see InputOTPGroup - Groups slots together * @see InputOTPSlot - Individual digit slot - * @see InputOTPSeparator - Visual separator between groups */ 'use client' import * as React from 'react' import { OTPInput, OTPInputContext } from 'input-otp' -import { Minus } from '../../icons' import { cn } from '../../lib/cn' /** @@ -94,17 +92,4 @@ const InputOTPSlot = React.forwardRef< }) InputOTPSlot.displayName = 'InputOTPSlot' -/** - * Visual separator between OTP slot groups. - */ -const InputOTPSeparator = React.forwardRef< - React.ElementRef<'div'>, - React.ComponentPropsWithoutRef<'div'> ->(({ ...props }, ref) => ( -
- -
-)) -InputOTPSeparator.displayName = 'InputOTPSeparator' - -export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } +export { InputOTP, InputOTPGroup, InputOTPSlot } diff --git a/packages/emcn/src/components/input/input.tsx b/packages/emcn/src/components/input/input.tsx index fe0a4c1806a..2382fd777b7 100644 --- a/packages/emcn/src/components/input/input.tsx +++ b/packages/emcn/src/components/input/input.tsx @@ -31,7 +31,7 @@ import { cn } from '../../lib/cn' const INPUT_CLASS = 'flex w-full touch-manipulation rounded-sm border border-[var(--border-1)] bg-[var(--surface-5)] px-2 py-1.5 font-sans text-sm text-[var(--text-primary)] [letter-spacing:inherit] transition-colors placeholder:text-[var(--text-muted)] outline-hidden disabled:cursor-not-allowed disabled:opacity-50 scroll-pr-1' -export type InputProps = React.InputHTMLAttributes +type InputProps = React.InputHTMLAttributes /** Minimal input component matching the textarea styling. */ const Input = React.forwardRef( diff --git a/packages/emcn/src/components/label/label.tsx b/packages/emcn/src/components/label/label.tsx index 412f12e8dc7..0b8f651cc7d 100644 --- a/packages/emcn/src/components/label/label.tsx +++ b/packages/emcn/src/components/label/label.tsx @@ -3,7 +3,7 @@ import * as LabelPrimitive from '@radix-ui/react-label' import { cn } from '../../lib/cn' -export interface LabelProps extends React.ComponentPropsWithoutRef {} +interface LabelProps extends React.ComponentPropsWithoutRef {} /** * EMCN Label component built on Radix UI Label primitive. diff --git a/packages/emcn/src/components/modal/modal.tsx b/packages/emcn/src/components/modal/modal.tsx index bbf47f5e36e..833d4fabb62 100644 --- a/packages/emcn/src/components/modal/modal.tsx +++ b/packages/emcn/src/components/modal/modal.tsx @@ -424,8 +424,7 @@ const MODAL_SIZES = { export type ModalSize = keyof typeof MODAL_SIZES -export interface ModalContentProps - extends React.ComponentPropsWithoutRef { +interface ModalContentProps extends React.ComponentPropsWithoutRef { /** Backdrop styling for specialized surfaces such as media viewers. */ overlayClassName?: string /** @@ -893,8 +892,5 @@ export { ModalTabsTrigger, ModalTabsContent, ModalFooter, - ModalPortal, - ModalOverlay, ModalClose, - MODAL_SIZES, } diff --git a/packages/emcn/src/components/popover/popover.tsx b/packages/emcn/src/components/popover/popover.tsx index a81f0c02686..a0024cc5885 100644 --- a/packages/emcn/src/components/popover/popover.tsx +++ b/packages/emcn/src/components/popover/popover.tsx @@ -184,7 +184,7 @@ const usePopoverContext = () => { return context } -export interface PopoverProps extends PopoverPrimitive.PopoverProps { +interface PopoverProps extends PopoverPrimitive.PopoverProps { /** * Size variant of the popover * - sm: 11px text, compact spacing (for logs, notifications, context menus) diff --git a/packages/emcn/src/components/progress-item/progress-item.tsx b/packages/emcn/src/components/progress-item/progress-item.tsx index fe08f64dde3..165cbbb4792 100644 --- a/packages/emcn/src/components/progress-item/progress-item.tsx +++ b/packages/emcn/src/components/progress-item/progress-item.tsx @@ -26,7 +26,7 @@ function StatusIcon({ status }: { status: ProgressStatus }) { return } -export interface ProgressItemProps +interface ProgressItemProps extends Omit, 'title'>, VariantProps { status: ProgressStatus @@ -100,4 +100,4 @@ const ProgressItem = forwardRef(function Prog }) ProgressItem.displayName = 'ProgressItem' -export { ProgressItem, progressItemVariants } +export { ProgressItem } diff --git a/packages/emcn/src/components/tab-strip/tab-strip.tsx b/packages/emcn/src/components/tab-strip/tab-strip.tsx index c79c29d9e8e..3c0d08497f3 100644 --- a/packages/emcn/src/components/tab-strip/tab-strip.tsx +++ b/packages/emcn/src/components/tab-strip/tab-strip.tsx @@ -166,7 +166,7 @@ export interface TabStripDragContext { * it suits a panel header that sits above content it does not own. */ /** Underline tabs use an active bottom indicator without a filled tab surface. */ -export type TabStripVariant = 'attached' | 'floating' | 'underline' +type TabStripVariant = 'attached' | 'floating' | 'underline' /** How a tab selection was initiated. */ export type TabStripSelectionSource = 'pointer' | 'keyboard' @@ -268,7 +268,7 @@ export function tabStripItemSelector(id: string): string { } /** Final horizontal position for a wheel gesture, or null when it cannot move the strip. */ -export function tabStripWheelPosition( +function tabStripWheelPosition( scrollLeft: number, scrollWidth: number, clientWidth: number, diff --git a/packages/emcn/src/components/table/table.tsx b/packages/emcn/src/components/table/table.tsx index 6717785bc2e..daa661774d9 100644 --- a/packages/emcn/src/components/table/table.tsx +++ b/packages/emcn/src/components/table/table.tsx @@ -2,7 +2,7 @@ import * as React from 'react' import { cva, type VariantProps } from 'class-variance-authority' import { cn } from '../../lib/cn' -export const tableVariants = cva('w-full caption-bottom text-small', { +const tableVariants = cva('w-full caption-bottom text-small', { variants: { variant: { default: '', diff --git a/packages/emcn/src/components/tag-input/tag-input.tsx b/packages/emcn/src/components/tag-input/tag-input.tsx index aee34b89725..7dee9855621 100644 --- a/packages/emcn/src/components/tag-input/tag-input.tsx +++ b/packages/emcn/src/components/tag-input/tag-input.tsx @@ -93,7 +93,7 @@ export interface TagItem { /** * Options for enabling file input functionality. */ -export interface FileInputOptions { +interface FileInputOptions { /** Whether file input is enabled */ enabled: boolean /** Accepted file types (default: '.csv,.txt,text/csv,text/plain') */ @@ -517,4 +517,4 @@ const TagInput = React.forwardRef( TagInput.displayName = 'TagInput' -export { TagInput, tagInputVariants } +export { TagInput } diff --git a/packages/emcn/src/components/time-picker/time-picker.tsx b/packages/emcn/src/components/time-picker/time-picker.tsx index 009f2815beb..2494a3d707e 100644 --- a/packages/emcn/src/components/time-picker/time-picker.tsx +++ b/packages/emcn/src/components/time-picker/time-picker.tsx @@ -308,4 +308,4 @@ const TimePicker = React.forwardRef( TimePicker.displayName = 'TimePicker' -export { TimePicker, timePickerVariants } +export { TimePicker } diff --git a/packages/emcn/src/components/tooltip/tooltip.tsx b/packages/emcn/src/components/tooltip/tooltip.tsx index 6a7195b8c78..e314be8dc00 100644 --- a/packages/emcn/src/components/tooltip/tooltip.tsx +++ b/packages/emcn/src/components/tooltip/tooltip.tsx @@ -389,7 +389,7 @@ function isVisiblyRendered(element: HTMLElement): boolean { } /** Clamps `value` to the inclusive `[min, max]` range. */ -export function clamp(value: number, min: number, max: number): number { +function clamp(value: number, min: number, max: number): number { return Math.max(min, Math.min(max, value)) } @@ -406,7 +406,7 @@ function quantize(value: number): number { * mouse click). Used to keep the tooltip from re-appearing/repositioning when the trigger is * clicked. Falls back to `true` where the selector can't be queried. */ -export function isFocusVisible(element: Element): boolean { +function isFocusVisible(element: Element): boolean { try { return element.matches(':focus-visible') } catch { diff --git a/packages/emcn/src/hooks/use-copy-to-clipboard.ts b/packages/emcn/src/hooks/use-copy-to-clipboard.ts index d8fc0397ae9..b5eb0dae282 100644 --- a/packages/emcn/src/hooks/use-copy-to-clipboard.ts +++ b/packages/emcn/src/hooks/use-copy-to-clipboard.ts @@ -7,7 +7,7 @@ interface UseCopyToClipboardOptions { resetMs?: number } -export interface DeferredClipboardContent { +interface DeferredClipboardContent { /** Safe text that can be written immediately when promise-backed writes are unavailable. */ fallback: string /** Produces the preferred text when the browser supports promise-backed clipboard items. */ diff --git a/packages/emcn/src/icons/animate/pills-ring.module.css b/packages/emcn/src/icons/animate/pills-ring.module.css deleted file mode 100644 index 5ba88317291..00000000000 --- a/packages/emcn/src/icons/animate/pills-ring.module.css +++ /dev/null @@ -1,28 +0,0 @@ -/** - * PillsRing icon animation - * Pills arranged in a ring fade in/out sequentially, - * creating a chasing spinner effect. - * Individual pill delays are set via inline style. - */ - -@keyframes pill-fade { - 0%, - 50%, - 100% { - opacity: 0.15; - } - 25% { - opacity: 1; - } -} - -.animated-pills-ring-svg .pill { - animation: pill-fade 1.2s ease-in-out infinite; - will-change: opacity; -} - -@media (prefers-reduced-motion: reduce) { - .animated-pills-ring-svg .pill { - animation: none; - } -} diff --git a/packages/emcn/src/icons/fingerprint.tsx b/packages/emcn/src/icons/fingerprint.tsx deleted file mode 100644 index d801a4c3609..00000000000 --- a/packages/emcn/src/icons/fingerprint.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import type { SVGProps } from 'react' - -/** - * Fingerprint icon component — unique constraint indicator - * @param props - SVG properties including className, fill, etc. - */ -export function Fingerprint(props: SVGProps) { - return ( - - ) -} diff --git a/packages/emcn/src/icons/index.ts b/packages/emcn/src/icons/index.ts index f6234788e00..ec59f6d3006 100644 --- a/packages/emcn/src/icons/index.ts +++ b/packages/emcn/src/icons/index.ts @@ -65,7 +65,6 @@ export { File } from './file' export { FileText } from './file-text' export { FileX } from './file-x' export { Files } from './files' -export { Fingerprint } from './fingerprint' export { Folder } from './folder' export { FolderCode } from './folder-code' export { FolderInput } from './folder-input' @@ -85,7 +84,6 @@ export { Highlighter } from './highlighter' export { Home } from './home' export { HtmlIcon } from './html-icon' export { ImageUp } from './image-up' -export { InfinityIcon, InfinityIcon as Infinity } from './infinity' export { Integration } from './integration' export { Italic } from './italic' export { JsonIcon } from './json-icon' @@ -109,7 +107,6 @@ export { MarkdownIcon } from './markdown-icon' export { Menu } from './menu' export { MessageSquareText } from './message-square-text' export { Mic } from './mic' -export { MicOff } from './mic-off' export { Minus } from './minus' export { Moon } from './moon' export { MoreHorizontal } from './more-horizontal' @@ -118,14 +115,11 @@ export { Music } from './music' export { NoWrap } from './no-wrap' export { Palette } from './palette' export { PanelLeft } from './panel-left' -export { PanelRight } from './panel-right' export { Paperclip } from './paperclip' -export { Pause } from './pause' export { PdfIcon } from './pdf-icon' export { Pencil } from './pencil' export { Phone } from './phone' export { Pilcrow } from './pilcrow' -export { PillsRing } from './pills-ring' export { Pin } from './pin' export { PinOff } from './pin-off' export { Play, PlayOutline } from './play' @@ -147,7 +141,6 @@ export { Settings } from './settings' export { Share } from './share' export { ShieldCheck } from './shield-check' export { Shuffle } from './shuffle' -export { Sim } from './sim' export { SkipForward } from './skip-forward' export { Slash } from './slash' export { SlidersHorizontal } from './sliders-horizontal' @@ -181,7 +174,6 @@ export { Undo } from './undo' export { Unlink } from './unlink' export { Unlock } from './unlock' export { Upload } from './upload' -export { User } from './user' export { Users } from './users' export { VideoIcon } from './video-icon' export { Wand } from './wand' diff --git a/packages/emcn/src/icons/infinity.tsx b/packages/emcn/src/icons/infinity.tsx deleted file mode 100644 index 8a0bd923eff..00000000000 --- a/packages/emcn/src/icons/infinity.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import type { SVGProps } from 'react' - -/** - * Infinity icon component - lemniscate drawn as one continuous stroke - * @param props - SVG properties including className, fill, etc. - */ -export function InfinityIcon(props: SVGProps) { - return ( - - ) -} diff --git a/packages/emcn/src/icons/layout.tsx b/packages/emcn/src/icons/layout.tsx index c2eea996ffe..6ea0e9d188f 100644 --- a/packages/emcn/src/icons/layout.tsx +++ b/packages/emcn/src/icons/layout.tsx @@ -2,7 +2,7 @@ import type { SVGProps } from 'react' import { cn } from '../lib/cn' import styles from './animate/layout.module.css' -export type LayoutAnimationVariant = 'clockwise' | 'counterclockwise' +type LayoutAnimationVariant = 'clockwise' | 'counterclockwise' export interface LayoutProps extends SVGProps { /** diff --git a/packages/emcn/src/icons/mic-off.tsx b/packages/emcn/src/icons/mic-off.tsx deleted file mode 100644 index a434155ad7d..00000000000 --- a/packages/emcn/src/icons/mic-off.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import type { SVGProps } from 'react' - -/** - * MicOff icon component - microphone with diagonal strike-through for the muted state - * @param props - SVG properties including className, fill, etc. - */ -export function MicOff(props: SVGProps) { - return ( - - ) -} diff --git a/packages/emcn/src/icons/panel-right.tsx b/packages/emcn/src/icons/panel-right.tsx deleted file mode 100644 index b862215be85..00000000000 --- a/packages/emcn/src/icons/panel-right.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import type { SVGProps } from 'react' - -/** - * PanelRight icon component - sidebar panel docked to the right edge - * @param props - SVG properties including className, fill, etc. - */ -export function PanelRight(props: SVGProps) { - return ( - - ) -} diff --git a/packages/emcn/src/icons/pause.tsx b/packages/emcn/src/icons/pause.tsx deleted file mode 100644 index abb83672a77..00000000000 --- a/packages/emcn/src/icons/pause.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import type { SVGProps } from 'react' - -/** - * Pause icon component - two vertical bars - * @param props - SVG properties including className, fill, etc. - */ -export function Pause(props: SVGProps) { - return ( - - ) -} diff --git a/packages/emcn/src/icons/pills-ring.tsx b/packages/emcn/src/icons/pills-ring.tsx deleted file mode 100644 index c1ba467ad2b..00000000000 --- a/packages/emcn/src/icons/pills-ring.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import type { SVGProps } from 'react' -import { cn } from '../lib/cn' -import styles from './animate/pills-ring.module.css' - -export interface PillsRingProps extends SVGProps { - /** - * Enable the chasing fade animation - * @default false - */ - animate?: boolean -} - -const PILL_COUNT = 8 -const DURATION_S = 1.2 - -/** - * Ring of pill-shaped elements with optional chasing fade animation. - * Static render shows pills at graded opacities; animated render - * fades them sequentially around the ring via CSS module keyframes. - * @param props - SVG properties including className, animate, etc. - */ -export function PillsRing({ animate = false, className, ...props }: PillsRingProps) { - const svgClassName = cn(animate && styles['animated-pills-ring-svg'], className) - - return ( - - ) -} diff --git a/packages/emcn/src/icons/sim.tsx b/packages/emcn/src/icons/sim.tsx deleted file mode 100644 index c43b45e0b6b..00000000000 --- a/packages/emcn/src/icons/sim.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import type { SVGProps } from 'react' - -/** - * Sim brand logo icon component - * @param props - SVG properties including className, fill, etc. - */ -export function Sim(props: SVGProps) { - return ( - - ) -} diff --git a/packages/emcn/src/icons/user.tsx b/packages/emcn/src/icons/user.tsx deleted file mode 100644 index 3241e182688..00000000000 --- a/packages/emcn/src/icons/user.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import type { SVGProps } from 'react' - -/** - * User icon component - single person silhouette - * @param props - SVG properties including className, fill, etc. - */ -export function User(props: SVGProps) { - return ( - - ) -} diff --git a/packages/emcn/src/index.ts b/packages/emcn/src/index.ts index f89fbb7afd2..57ad244f26f 100644 --- a/packages/emcn/src/index.ts +++ b/packages/emcn/src/index.ts @@ -4,7 +4,7 @@ export * from './components' * glyph). Like `Table` above, this explicit re-export resolves the barrel to * the COMPONENT; the icon stays available from `@sim/emcn/icons`. */ -export { Calendar, type CalendarProps } from './components/calendar/calendar' +export { Calendar } from './components/calendar/calendar' export * from './components/charts' /** * `Code` exists in BOTH `./components` (the code editor) and `./icons` (a @@ -19,8 +19,6 @@ export { } from './components/code/code' export { SCROLL_FADE_BAND_PX, - type ScrollEdges, - type ScrollEdgesX, scrollFadeAttributes, scrollFadeClass, scrollFadeXClass, @@ -41,7 +39,6 @@ export { TableHead, TableHeader, TableRow, - tableVariants, } from './components/table/table' export { type ClipboardContent, @@ -52,5 +49,5 @@ export { usePrefersReducedMotion } from './hooks/use-prefers-reduced-motion' export { useScrollEdges } from './hooks/use-scroll-edges' export * from './icons' export { cn } from './lib/cn' -export { handleKeyboardActivation, isKeyboardActivation } from './lib/keyboard' +export { handleKeyboardActivation } from './lib/keyboard' export { bindPreviewHorizontalWheel, bindPreviewWheelZoom } from './lib/preview-wheel-zoom' diff --git a/packages/emcn/src/lib/keyboard.ts b/packages/emcn/src/lib/keyboard.ts index 1d91eda8a3a..4b52c0d7fd5 100644 --- a/packages/emcn/src/lib/keyboard.ts +++ b/packages/emcn/src/lib/keyboard.ts @@ -4,7 +4,7 @@ interface KeyboardActivationOptions { stopPropagation?: boolean } -export function isKeyboardActivation(event: KeyboardEvent) { +function isKeyboardActivation(event: KeyboardEvent) { return event.key === 'Enter' || event.key === ' ' } diff --git a/packages/platform-authz/src/rooms.ts b/packages/platform-authz/src/rooms.ts index f2e86ff3bbd..cc779ff8202 100644 --- a/packages/platform-authz/src/rooms.ts +++ b/packages/platform-authz/src/rooms.ts @@ -7,13 +7,13 @@ import { resolveEffectiveWorkspacePermission, } from './workspace' -export type { PermissionType, RoomRef, RoomType } +export type { PermissionType, RoomRef } /** * The owning workspace of a room, plus the org that owns that workspace — the * exact inputs {@link resolveEffectiveWorkspacePermission} needs. */ -export interface RoomWorkspace { +interface RoomWorkspace { workspaceId: string workspaceOrganizationId: string | null } @@ -24,7 +24,7 @@ export interface RoomWorkspace { * result). One resolver per workspace-scoped {@link RoomType}; this is the single * place a new such room type declares its resource→workspace lookup. */ -export type RoomWorkspaceResolver = (roomId: string) => Promise +type RoomWorkspaceResolver = (roomId: string) => Promise async function resolveWorkspaceRoomWorkspace(workspaceId: string): Promise { const [row] = await db diff --git a/packages/platform-authz/src/workflow.ts b/packages/platform-authz/src/workflow.ts index 7e50f880a2c..18b253e838a 100644 --- a/packages/platform-authz/src/workflow.ts +++ b/packages/platform-authz/src/workflow.ts @@ -6,8 +6,6 @@ import { resolveEffectiveWorkspacePermission, } from './workspace' -export type { PermissionType } - export type ActiveWorkflowRecord = typeof workflow.$inferSelect export interface ActiveWorkflowContext { @@ -50,16 +48,6 @@ export async function getActiveWorkflowRecord( return context?.workflow ?? null } -export async function assertActiveWorkflowContext( - workflowId: string -): Promise { - const context = await getActiveWorkflowContext(workflowId) - if (!context) { - throw new Error(`Active workflow not found: ${workflowId}`) - } - return context -} - type WorkflowRecord = typeof workflow.$inferSelect export class WorkflowLockedError extends Error { @@ -80,7 +68,7 @@ export class FolderLockedError extends Error { } } -export interface LockStatus { +interface LockStatus { locked: boolean directLocked: boolean inheritedLocked: boolean @@ -88,7 +76,7 @@ export interface LockStatus { lockedFolderId: string | null } -export async function getFolderLockStatus(folderId: string | null): Promise { +async function getFolderLockStatus(folderId: string | null): Promise { if (!folderId) { return { locked: false, @@ -145,7 +133,7 @@ export async function getFolderLockStatus(folderId: string | null): Promise { +async function getWorkflowLockStatus(workflowId: string): Promise { const [wf] = await db .select({ locked: workflow.locked, diff --git a/packages/realtime-protocol/src/constants.ts b/packages/realtime-protocol/src/constants.ts index 1bae03b498c..d342834cda0 100644 --- a/packages/realtime-protocol/src/constants.ts +++ b/packages/realtime-protocol/src/constants.ts @@ -16,8 +16,6 @@ export const BLOCK_OPERATIONS = { TOGGLE_HANDLES: 'toggle-handles', } as const -export type BlockOperation = (typeof BLOCK_OPERATIONS)[keyof typeof BLOCK_OPERATIONS] - export const BLOCKS_OPERATIONS = { BATCH_UPDATE_POSITIONS: 'batch-update-positions', BATCH_ADD_BLOCKS: 'batch-add-blocks', @@ -28,28 +26,20 @@ export const BLOCKS_OPERATIONS = { BATCH_TOGGLE_LOCKED: 'batch-toggle-locked', } as const -export type BlocksOperation = (typeof BLOCKS_OPERATIONS)[keyof typeof BLOCKS_OPERATIONS] - export const EDGE_OPERATIONS = { ADD: 'add', REMOVE: 'remove', } as const -export type EdgeOperation = (typeof EDGE_OPERATIONS)[keyof typeof EDGE_OPERATIONS] - export const EDGES_OPERATIONS = { BATCH_ADD_EDGES: 'batch-add-edges', BATCH_REMOVE_EDGES: 'batch-remove-edges', } as const -export type EdgesOperation = (typeof EDGES_OPERATIONS)[keyof typeof EDGES_OPERATIONS] - export const SUBFLOW_OPERATIONS = { UPDATE: 'update', } as const -export type SubflowOperation = (typeof SUBFLOW_OPERATIONS)[keyof typeof SUBFLOW_OPERATIONS] - export const VARIABLE_OPERATIONS = { ADD: 'add', REMOVE: 'remove', @@ -62,16 +52,12 @@ export const WORKFLOW_OPERATIONS = { REPLACE_STATE: 'replace-state', } as const -export type WorkflowOperation = (typeof WORKFLOW_OPERATIONS)[keyof typeof WORKFLOW_OPERATIONS] - export const SUBBLOCK_OPERATIONS = { UPDATE: 'subblock-update', BATCH_UPDATE: 'subblock-batch-update', UPDATE_WITH_CANONICAL_MODES: 'subblock-update-with-canonical-modes', } as const -export type SubblockOperation = (typeof SUBBLOCK_OPERATIONS)[keyof typeof SUBBLOCK_OPERATIONS] - export const OPERATION_TARGETS = { BLOCK: 'block', BLOCKS: 'blocks', diff --git a/packages/realtime-protocol/src/rooms.ts b/packages/realtime-protocol/src/rooms.ts index c1751ba1a04..a05d881f50d 100644 --- a/packages/realtime-protocol/src/rooms.ts +++ b/packages/realtime-protocol/src/rooms.ts @@ -58,7 +58,7 @@ export const ROOM_TYPES = { export type RoomType = (typeof ROOM_TYPES)[keyof typeof ROOM_TYPES] /** Every known room type, for exhaustive iteration/validation. */ -export const ALL_ROOM_TYPES = Object.values(ROOM_TYPES) as readonly RoomType[] +const ALL_ROOM_TYPES = Object.values(ROOM_TYPES) as readonly RoomType[] /** * The presence-free, workspace-scoped live-list rooms. They share one contract derived entirely @@ -79,7 +79,7 @@ export interface RoomRef { } /** Type guard: whether an arbitrary string is a known {@link RoomType}. */ -export function isRoomType(value: string): value is RoomType { +function isRoomType(value: string): value is RoomType { return (ALL_ROOM_TYPES as readonly string[]).includes(value) } diff --git a/packages/realtime-protocol/src/schemas.ts b/packages/realtime-protocol/src/schemas.ts index 5de6d60397a..2cb07c02595 100644 --- a/packages/realtime-protocol/src/schemas.ts +++ b/packages/realtime-protocol/src/schemas.ts @@ -38,7 +38,7 @@ const AutoConnectEdgeSchema = z.object({ const CanonicalModeSchema = z.enum(['basic', 'advanced']) -export const BlockOperationSchema = z.object({ +const BlockOperationSchema = z.object({ operation: z.enum([ BLOCK_OPERATIONS.UPDATE_POSITION, BLOCK_OPERATIONS.UPDATE_NAME, @@ -77,7 +77,7 @@ export const BlockOperationSchema = z.object({ operationId: z.string().optional(), }) -export const BatchPositionUpdateSchema = z.object({ +const BatchPositionUpdateSchema = z.object({ operation: z.literal(BLOCKS_OPERATIONS.BATCH_UPDATE_POSITIONS), target: z.literal(OPERATION_TARGETS.BLOCKS), payload: z.object({ @@ -92,7 +92,7 @@ export const BatchPositionUpdateSchema = z.object({ operationId: z.string().optional(), }) -export const EdgeOperationSchema = z.object({ +const EdgeOperationSchema = z.object({ operation: z.enum([EDGE_OPERATIONS.ADD, EDGE_OPERATIONS.REMOVE]), target: z.literal(OPERATION_TARGETS.EDGE), payload: z.object({ @@ -106,7 +106,7 @@ export const EdgeOperationSchema = z.object({ operationId: z.string().optional(), }) -export const SubflowOperationSchema = z.object({ +const SubflowOperationSchema = z.object({ operation: z.literal(SUBFLOW_OPERATIONS.UPDATE), target: z.literal(OPERATION_TARGETS.SUBFLOW), payload: z.object({ @@ -118,7 +118,7 @@ export const SubflowOperationSchema = z.object({ operationId: z.string().optional(), }) -export const VariableOperationSchema = z.union([ +const VariableOperationSchema = z.union([ z.object({ operation: z.literal(VARIABLE_OPERATIONS.ADD), target: z.literal(OPERATION_TARGETS.VARIABLE), @@ -143,7 +143,7 @@ export const VariableOperationSchema = z.union([ }), ]) -export const WorkflowStateOperationSchema = z.object({ +const WorkflowStateOperationSchema = z.object({ operation: z.literal(WORKFLOW_OPERATIONS.REPLACE_STATE), target: z.literal(OPERATION_TARGETS.WORKFLOW), payload: z.object({ @@ -153,7 +153,7 @@ export const WorkflowStateOperationSchema = z.object({ operationId: z.string().optional(), }) -export const SubblockOperationSchema = z.object({ +const SubblockOperationSchema = z.object({ operation: z.literal(SUBBLOCK_OPERATIONS.BATCH_UPDATE), target: z.literal(OPERATION_TARGETS.SUBBLOCK), payload: z.object({ @@ -175,7 +175,7 @@ export const SubblockOperationSchema = z.object({ * A `tool-input` keys its tools' modes by array position, so a reorder or removal must persist * both together or a failure between two separate writes leaves modes on the wrong tools. */ -export const SubblockCanonicalModesUpdateSchema = z.object({ +const SubblockCanonicalModesUpdateSchema = z.object({ operation: z.literal(SUBBLOCK_OPERATIONS.UPDATE_WITH_CANONICAL_MODES), target: z.literal(OPERATION_TARGETS.SUBBLOCK), payload: z.object({ @@ -188,7 +188,7 @@ export const SubblockCanonicalModesUpdateSchema = z.object({ operationId: z.string().optional(), }) -export const BatchAddBlocksSchema = z.object({ +const BatchAddBlocksSchema = z.object({ operation: z.literal(BLOCKS_OPERATIONS.BATCH_ADD_BLOCKS), target: z.literal(OPERATION_TARGETS.BLOCKS), payload: z.object({ @@ -202,7 +202,7 @@ export const BatchAddBlocksSchema = z.object({ operationId: z.string().optional(), }) -export const BatchRemoveBlocksSchema = z.object({ +const BatchRemoveBlocksSchema = z.object({ operation: z.literal(BLOCKS_OPERATIONS.BATCH_REMOVE_BLOCKS), target: z.literal(OPERATION_TARGETS.BLOCKS), payload: z.object({ @@ -212,7 +212,7 @@ export const BatchRemoveBlocksSchema = z.object({ operationId: z.string().optional(), }) -export const BatchRemoveEdgesSchema = z.object({ +const BatchRemoveEdgesSchema = z.object({ operation: z.literal(EDGES_OPERATIONS.BATCH_REMOVE_EDGES), target: z.literal(OPERATION_TARGETS.EDGES), payload: z.object({ @@ -222,7 +222,7 @@ export const BatchRemoveEdgesSchema = z.object({ operationId: z.string().optional(), }) -export const BatchAddEdgesSchema = z.object({ +const BatchAddEdgesSchema = z.object({ operation: z.literal(EDGES_OPERATIONS.BATCH_ADD_EDGES), target: z.literal(OPERATION_TARGETS.EDGES), payload: z.object({ @@ -240,7 +240,7 @@ export const BatchAddEdgesSchema = z.object({ operationId: z.string().optional(), }) -export const BatchToggleEnabledSchema = z.object({ +const BatchToggleEnabledSchema = z.object({ operation: z.literal(BLOCKS_OPERATIONS.BATCH_TOGGLE_ENABLED), target: z.literal(OPERATION_TARGETS.BLOCKS), payload: z.object({ @@ -251,7 +251,7 @@ export const BatchToggleEnabledSchema = z.object({ operationId: z.string().optional(), }) -export const BatchToggleHandlesSchema = z.object({ +const BatchToggleHandlesSchema = z.object({ operation: z.literal(BLOCKS_OPERATIONS.BATCH_TOGGLE_HANDLES), target: z.literal(OPERATION_TARGETS.BLOCKS), payload: z.object({ @@ -262,7 +262,7 @@ export const BatchToggleHandlesSchema = z.object({ operationId: z.string().optional(), }) -export const BatchToggleLockedSchema = z.object({ +const BatchToggleLockedSchema = z.object({ operation: z.literal(BLOCKS_OPERATIONS.BATCH_TOGGLE_LOCKED), target: z.literal(OPERATION_TARGETS.BLOCKS), payload: z.object({ @@ -273,7 +273,7 @@ export const BatchToggleLockedSchema = z.object({ operationId: z.string().optional(), }) -export const BatchUpdateParentSchema = z.object({ +const BatchUpdateParentSchema = z.object({ operation: z.literal(BLOCKS_OPERATIONS.BATCH_UPDATE_PARENT), target: z.literal(OPERATION_TARGETS.BLOCKS), payload: z.object({ diff --git a/packages/security/src/ip.ts b/packages/security/src/ip.ts index 1acb82e1930..dd3111f75a8 100644 --- a/packages/security/src/ip.ts +++ b/packages/security/src/ip.ts @@ -7,7 +7,7 @@ interface TrustedNetwork { prefixLength: number } -export interface ForwardedIpHeaders { +interface ForwardedIpHeaders { get(name: string): string | null } diff --git a/packages/terminal-protocol/src/index.ts b/packages/terminal-protocol/src/index.ts index b3de2a9fc85..50ff3ae8095 100644 --- a/packages/terminal-protocol/src/index.ts +++ b/packages/terminal-protocol/src/index.ts @@ -24,25 +24,6 @@ import { truncate } from '@sim/utils/string' /** The single tool the model calls; what it does is in `operation`. */ export const TERMINAL_TOOL_NAME = 'terminal' -/** - * Names this surface used to expose, one tool per operation. Kept so rows in - * conversations recorded before the consolidation still render with a real - * title instead of a humanized tool name. - */ -export const LEGACY_TERMINAL_TOOL_NAMES = [ - 'terminal_run', - 'terminal_input', - 'terminal_read', - 'terminal_kill', - 'terminal_cwd', - 'terminal_list', - 'terminal_new', - 'terminal_switch', - 'terminal_close', -] as const - -export type LegacyTerminalToolName = (typeof LEGACY_TERMINAL_TOOL_NAMES)[number] - /** * What one `terminal` call does. * @@ -52,7 +33,7 @@ export type LegacyTerminalToolName = (typeof LEGACY_TERMINAL_TOOL_NAMES)[number] * inspects them rather than Sim mirroring them into the tab strip. `handoff` * gives the terminal to the user and waits. */ -export const TERMINAL_OPERATIONS = [ +const TERMINAL_OPERATIONS = [ 'run', 'read', 'input', @@ -128,7 +109,7 @@ export const PROMPT_IDLE_MS = 2_500 export const MAX_INPUT_KEYS = 20 /** Control keys the agent may send to a running foreground process. */ -export const TERMINAL_CONTROL_KEYS = [ +const TERMINAL_CONTROL_KEYS = [ 'ctrl-c', 'ctrl-d', 'ctrl-z', @@ -149,7 +130,7 @@ export function isTerminalControlKey(value: unknown): value is TerminalControlKe return typeof value === 'string' && TERMINAL_CONTROL_KEY_SET.has(value) } -export type TerminalSignal = 'SIGINT' | 'SIGTERM' | 'SIGKILL' +type TerminalSignal = 'SIGINT' | 'SIGTERM' | 'SIGKILL' /** * Arguments for every operation, flattened into one object. @@ -197,17 +178,12 @@ export interface TerminalToolArgs { reason?: string } -export interface TerminalToolCall { - operation: TerminalOperation - args?: TerminalToolArgs -} - /** * How a `terminal_run` ended. Only `completed` means the command is finished * and the terminal is free; in every other case it is still running and still * holds the foreground. */ -export type TerminalRunStatus = +type TerminalRunStatus = /** Exited on its own. `exitCode` is set. */ | 'completed' /** @@ -476,12 +452,6 @@ export interface TerminalStartOptions { rows: number } -/** One batch of PTY bytes, tagged with the terminal that produced it. */ -export interface TerminalOutputEvent { - terminalId: string - data: string -} - /** * Command lifecycle, used by the panel to attribute rows to the agent and to * show a running indicator. Emitted for user-typed commands too (no diff --git a/packages/testing/src/mocks/billing-plan-logic.ts b/packages/testing/src/mocks/billing-plan-logic.ts index 67b9d09e299..6130d316b8b 100644 --- a/packages/testing/src/mocks/billing-plan-logic.ts +++ b/packages/testing/src/mocks/billing-plan-logic.ts @@ -26,7 +26,7 @@ export function isEnterprise(plan: Plan): boolean { return plan === 'enterprise' } -export function isFree(plan: Plan): boolean { +function isFree(plan: Plan): boolean { return !plan || plan === 'free' } diff --git a/packages/testing/src/mocks/workflow-authz.mock.ts b/packages/testing/src/mocks/workflow-authz.mock.ts index dd829164858..355e4e98ce5 100644 --- a/packages/testing/src/mocks/workflow-authz.mock.ts +++ b/packages/testing/src/mocks/workflow-authz.mock.ts @@ -42,14 +42,6 @@ class MockFolderNotFoundError extends Error { } } -const unlockedStatus = { - locked: false, - directLocked: false, - inheritedLocked: false, - lockedBy: null as 'workflow' | 'folder' | null, - lockedFolderId: null as string | null, -} - /** * Controllable mocks for the `@sim/platform-authz/workflow` entry. * @@ -72,9 +64,6 @@ export const workflowAuthzMockFns = { mockAuthorizeWorkflowByWorkspacePermission: vi.fn(), mockGetActiveWorkflowContext: vi.fn(), mockGetActiveWorkflowRecord: vi.fn(), - mockAssertActiveWorkflowContext: vi.fn(), - mockGetFolderLockStatus: vi.fn().mockResolvedValue(unlockedStatus), - mockGetWorkflowLockStatus: vi.fn().mockResolvedValue(unlockedStatus), mockAssertWorkflowMutable: vi.fn().mockResolvedValue(undefined), mockAssertFolderMutable: vi.fn().mockResolvedValue(undefined), mockIsFolderInWorkspace: vi.fn().mockResolvedValue(true), @@ -94,9 +83,6 @@ export const workflowAuthzMock = { workflowAuthzMockFns.mockAuthorizeWorkflowByWorkspacePermission, getActiveWorkflowContext: workflowAuthzMockFns.mockGetActiveWorkflowContext, getActiveWorkflowRecord: workflowAuthzMockFns.mockGetActiveWorkflowRecord, - assertActiveWorkflowContext: workflowAuthzMockFns.mockAssertActiveWorkflowContext, - getFolderLockStatus: workflowAuthzMockFns.mockGetFolderLockStatus, - getWorkflowLockStatus: workflowAuthzMockFns.mockGetWorkflowLockStatus, assertWorkflowMutable: workflowAuthzMockFns.mockAssertWorkflowMutable, assertFolderMutable: workflowAuthzMockFns.mockAssertFolderMutable, isFolderInWorkspace: workflowAuthzMockFns.mockIsFolderInWorkspace, diff --git a/packages/utils/package.json b/packages/utils/package.json index cfb2304bc18..497cad35e92 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -6,10 +6,6 @@ "type": "module", "license": "Apache-2.0", "exports": { - ".": { - "types": "./src/index.ts", - "default": "./src/index.ts" - }, "./id": { "types": "./src/id.ts", "default": "./src/id.ts" diff --git a/packages/utils/src/client-info.ts b/packages/utils/src/client-info.ts index e623d49d6ae..8e747a6ac4a 100644 --- a/packages/utils/src/client-info.ts +++ b/packages/utils/src/client-info.ts @@ -31,9 +31,9 @@ export const CLIENT_INFO_HEADER = 'x-sim-client-info' * The official Sim clients, as they name themselves on the wire. `mcp` is the * Sim MCP server, which declares itself on each v2 request it dispatches. */ -export const SIM_SURFACES = ['web', 'desktop', 'cli', 'sdk-js', 'sdk-python', 'mcp'] as const +const SIM_SURFACES = ['web', 'desktop', 'cli', 'sdk-js', 'sdk-python', 'mcp'] as const -export type SimSurface = (typeof SIM_SURFACES)[number] +type SimSurface = (typeof SIM_SURFACES)[number] export interface ClientInfo { surface: SimSurface @@ -64,15 +64,15 @@ export interface ClientInfo { * - `webhook`, `schedule`: a run a trigger started rather than a client. * - `unknown`: none of the above, such as an unauthenticated webhook delivery. */ -export const UNDECLARED_SURFACES = ['api', 'internal', 'webhook', 'schedule', 'unknown'] as const +const UNDECLARED_SURFACES = ['api', 'internal', 'webhook', 'schedule', 'unknown'] as const -export type UndeclaredSurface = (typeof UNDECLARED_SURFACES)[number] +type UndeclaredSurface = (typeof UNDECLARED_SURFACES)[number] /** Every surface a request or run can be attributed to. */ -export type RequestSurface = SimSurface | UndeclaredSurface +type RequestSurface = SimSurface | UndeclaredSurface /** How the server established a request's client. */ -export type ClientInfoSource = +type ClientInfoSource = | 'header' | 'user_agent' | 'fetch_metadata' diff --git a/packages/utils/src/formatting.ts b/packages/utils/src/formatting.ts index ccaffa37e85..051bceb13bb 100644 --- a/packages/utils/src/formatting.ts +++ b/packages/utils/src/formatting.ts @@ -97,19 +97,6 @@ export function formatDate(date: Date): string { }) } -/** - * Format a time into a short format - * @param date - The date to format - * @returns A formatted time string in the format "h:mm A" - */ -export function formatTime(date: Date): string { - return date.toLocaleString('en-US', { - hour: 'numeric', - minute: '2-digit', - hour12: true, - }) -} - /** * Format a duration to a human-readable format * @param duration - Duration in milliseconds (number) or as string (e.g., "500ms") diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts deleted file mode 100644 index 639a27acd7d..00000000000 --- a/packages/utils/src/index.ts +++ /dev/null @@ -1,60 +0,0 @@ -export { getErrorMessage, getPostgresErrorCode, toError } from './errors' -export { - formatDate, - formatDateTime, - formatDuration, - formatRelativeTime, - formatTime, - getTimezoneAbbreviation, -} from './formatting' -export { chunkArray, noop, sleep } from './helpers' -export { generateId, generateShortId, isValidUuid } from './id' -export type { EmbedInfo } from './media-embed' -export { getEmbedInfo } from './media-embed' -export { - filterUndefined, - getValueAtPath, - isPlainRecord, - isRecordLike, - omit, - sortObjectKeysDeep, - toRecord, - toRecordOrNull, -} from './object' -export { - assessTextPaste, - countPasteRows, - formatPasteLimit, - PASTE_LIMITS, - type TextPasteAdmission, - type TextPasteAdmissionInput, - type TextPasteRejectionReason, - utf8ByteLength, - utf8ByteLengthRange, -} from './paste' -export { - generateRandomBytes, - generateRandomHex, - generateRandomString, - LOWERCASE_ALPHANUMERIC_ALPHABET, - randomFloat, - randomInt, - randomItem, -} from './random' -export type { BackoffOptions } from './retry' -export { backoffWithJitter, parseRetryAfter } from './retry' -export { normalizeSSODomain } from './sso-domain' -export { - isValidEmailSyntax, - normalizeEmail, - sanitizeForJsonb, - sanitizeValueForJsonb, - truncate, -} from './string' -export { - findWorkflowReferenceTokens, - isLikelyWorkflowReferenceSegment, - splitWorkflowReferenceSegment, - type WorkflowReferenceToken, - type WorkflowReferenceTokenKind, -} from './workflow-references' diff --git a/packages/utils/src/paste.ts b/packages/utils/src/paste.ts index b2d38d4bd07..0f2f6783272 100644 --- a/packages/utils/src/paste.ts +++ b/packages/utils/src/paste.ts @@ -37,7 +37,7 @@ export interface TextPasteAdmissionInput { maxResultCharacters?: number } -export type TextPasteRejectionReason = +type TextPasteRejectionReason = | 'pasted-bytes' | 'pasted-characters' | 'result-bytes' diff --git a/packages/utils/src/random.ts b/packages/utils/src/random.ts index 9beae841c82..c7ff666cbd8 100644 --- a/packages/utils/src/random.ts +++ b/packages/utils/src/random.ts @@ -3,9 +3,6 @@ * Works in all contexts including non-secure (HTTP) browser environments. */ -/** Lowercase alphanumeric characters used as the default alphabet for random strings. */ -export const LOWERCASE_ALPHANUMERIC_ALPHABET = 'abcdefghijklmnopqrstuvwxyz0123456789' - const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' const UINT32_SAMPLE_SPACE_SIZE = 0x100000000 @@ -14,6 +11,7 @@ const UINT32_SAMPLE_SPACE_SIZE = 0x100000000 * Generates cryptographically secure random bytes. * @param length - Number of bytes to generate * @returns Uint8Array of random bytes + * @public check:utils names this as the replacement for `crypto.randomBytes()`. */ export function generateRandomBytes(length: number): Uint8Array { return crypto.getRandomValues(new Uint8Array(length)) diff --git a/packages/utils/src/sandbox-references.ts b/packages/utils/src/sandbox-references.ts index 89d3117c1d2..f12ffeccdc6 100644 --- a/packages/utils/src/sandbox-references.ts +++ b/packages/utils/src/sandbox-references.ts @@ -9,10 +9,9 @@ export const IMMUTABLE_DAYTONA_SNAPSHOT_REF_ERROR = export const SANDBOX_RELEASE_GENERATION_ERROR = 'must be a positive safe integer release generation' export const SANDBOX_PROVIDER_IDS = ['e2b', 'daytona'] as const -export type SandboxProviderName = (typeof SANDBOX_PROVIDER_IDS)[number] /** Leaves three decimal digits for a materializer revision in one safe integer. */ -export const MAX_SANDBOX_RELEASE_GENERATION = Math.floor((Number.MAX_SAFE_INTEGER - 999) / 1000) +const MAX_SANDBOX_RELEASE_GENERATION = Math.floor((Number.MAX_SAFE_INTEGER - 999) / 1000) const E2B_TEMPLATE_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]{0,62}$/ const E2B_TEMPLATE_REFERENCE_NAME_PATTERN = @@ -24,7 +23,7 @@ export function isValidE2BTemplateName(value: string): boolean { } /** Exact E2B refs may include one documented lowercase namespace segment. */ -export function isValidE2BTemplateReferenceName(value: string): boolean { +function isValidE2BTemplateReferenceName(value: string): boolean { return E2B_TEMPLATE_REFERENCE_NAME_PATTERN.test(value) } diff --git a/packages/utils/src/workflow-references.ts b/packages/utils/src/workflow-references.ts index 64bc63b76ab..d5163b06a18 100644 --- a/packages/utils/src/workflow-references.ts +++ b/packages/utils/src/workflow-references.ts @@ -5,7 +5,7 @@ const INVALID_REFERENCE_CHARS = /[+*/=<>!&|]/ const LEADING_REFERENCE_PATTERN = /^[<>=!\s]*$/ const ENV_REFERENCE_PATTERN = /\{\{[^{}\r\n]+\}\}/g -export type WorkflowReferenceTokenKind = 'environment' | 'workflow' +type WorkflowReferenceTokenKind = 'environment' | 'workflow' export interface WorkflowReferenceToken { kind: WorkflowReferenceTokenKind diff --git a/packages/workflow-persistence/package.json b/packages/workflow-persistence/package.json index d439e653307..712da721ea6 100644 --- a/packages/workflow-persistence/package.json +++ b/packages/workflow-persistence/package.json @@ -10,10 +10,6 @@ "node": ">=20.0.0" }, "exports": { - ".": { - "types": "./src/index.ts", - "default": "./src/index.ts" - }, "./load": { "types": "./src/load.ts", "default": "./src/load.ts" diff --git a/packages/workflow-persistence/src/index.ts b/packages/workflow-persistence/src/index.ts deleted file mode 100644 index ad0b35248c1..00000000000 --- a/packages/workflow-persistence/src/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -export { - loadWorkflowFromNormalizedTablesRaw, - persistMigratedBlocks, - type RawNormalizedWorkflow, -} from './load' -export { saveWorkflowToNormalizedTables } from './save' -export { - DEFAULT_SUBBLOCK_TYPE, - mergeSubBlockValues, - mergeSubblockStateWithValues, -} from './subblocks' -export { - convertLoopBlockToLoop, - convertParallelBlockToParallel, - findChildNodes, - generateLoopBlocks, - generateParallelBlocks, -} from './subflow-helpers' -export type { DbOrTx, NormalizedWorkflowData } from './types' diff --git a/packages/workflow-persistence/src/subflow-helpers.ts b/packages/workflow-persistence/src/subflow-helpers.ts index fb44c8c12d2..d9541445b5a 100644 --- a/packages/workflow-persistence/src/subflow-helpers.ts +++ b/packages/workflow-persistence/src/subflow-helpers.ts @@ -20,7 +20,7 @@ export function clampParallelBatchSize(batchSize: unknown): number { * @param blocks - Record of all blocks in the workflow * @returns IDs of the blocks whose parent is this container */ -export function findChildNodes(containerId: string, blocks: Record): string[] { +function findChildNodes(containerId: string, blocks: Record): string[] { return Object.values(blocks) .filter((block) => block.data?.parentId === containerId) .map((block) => block.id) @@ -64,7 +64,7 @@ export function convertLoopBlockToLoop( * @param blocks - Record of all blocks in the workflow * @returns The parallel, or undefined when the block is missing or not a parallel */ -export function convertParallelBlockToParallel( +function convertParallelBlockToParallel( parallelBlockId: string, blocks: Record ): Parallel | undefined { diff --git a/packages/workflow-renderer/src/dimensions.ts b/packages/workflow-renderer/src/dimensions.ts index e35fb5cb08f..c7c1711f2f3 100644 --- a/packages/workflow-renderer/src/dimensions.ts +++ b/packages/workflow-renderer/src/dimensions.ts @@ -52,11 +52,11 @@ export const BLOCK_DIMENSIONS = { * host, the border SVG viewBox (`preserveAspectRatio='none'`, so a mismatch * paints the outline stretched), and autolayout all resolve through them. */ -export const NOTE_BLOCK_MIN_HEIGHT = +const NOTE_BLOCK_MIN_HEIGHT = BLOCK_DIMENSIONS.HEADER_HEIGHT + BLOCK_DIMENSIONS.NOTE_CONTENT_PADDING + BLOCK_DIMENSIONS.NOTE_MIN_CONTENT_HEIGHT -export const NOTE_BLOCK_MAX_HEIGHT = +const NOTE_BLOCK_MAX_HEIGHT = BLOCK_DIMENSIONS.HEADER_HEIGHT + BLOCK_DIMENSIONS.NOTE_CONTENT_VIEWPORT_HEIGHT /** Clamps a note's total height to the bounds the card itself honours. */ diff --git a/packages/workflow-renderer/src/edge/workflow-edge-view.tsx b/packages/workflow-renderer/src/edge/workflow-edge-view.tsx index d842f0fd497..de6206e46a0 100644 --- a/packages/workflow-renderer/src/edge/workflow-edge-view.tsx +++ b/packages/workflow-renderer/src/edge/workflow-edge-view.tsx @@ -50,7 +50,7 @@ function getExecutionPulseMotion(length: number) { * otherwise be read from stores — diff status, run status, and whether the run * status originated from a preview — is resolved by the container and passed in. */ -export interface WorkflowEdgeData extends Record { +interface WorkflowEdgeData extends Record { isSelected?: boolean onDelete?: (edgeId: string) => void } diff --git a/packages/workflow-renderer/src/index.ts b/packages/workflow-renderer/src/index.ts index 416bef3552c..e8e377db950 100644 --- a/packages/workflow-renderer/src/index.ts +++ b/packages/workflow-renderer/src/index.ts @@ -1,14 +1,9 @@ export { BlockTileView, type BlockTileViewProps, - getWorkflowTypeAccent, - getWorkflowTypeRole, hasWorkflowTypeRole, WorkflowTypeIcon, - type WorkflowTypeIconProps, - type WorkflowTypeRole, WorkflowTypeTag, - type WorkflowTypeTagProps, } from '@sim/workflow-renderer/workflow-type' export { BLOCK_Z_BASE, @@ -24,27 +19,21 @@ export { export * from './dimensions' export { type WorkflowEdge, - type WorkflowEdgeData, WorkflowEdgeView, - type WorkflowEdgeViewProps, } from './edge/workflow-edge-view' export { humanizeBlockName } from './lib/humanize-block-name' export { sortNodesParentsFirst } from './node-order' export { - NOTE_MARKDOWN_FLOW, NoteBlockView, - type NoteBlockViewProps, type NoteContentEditorProps, } from './note/note-block-view' export { DEFAULT_NOTE_COLOR, - getNoteColorOption, isNoteColor, NOTE_COLOR_OPTIONS, type NoteColor, - type NoteColorOption, } from './note/note-colors' -export { getNoteStringValue, isNoteContentEmpty } from './note/note-content' +export { getNoteStringValue } from './note/note-content' export { countNoteSearchOccurrencesBefore, forEachNoteSourceOccurrence, @@ -54,46 +43,23 @@ export { export { type SubflowNodeData, SubflowNodeView, - type SubflowNodeViewProps, - SubflowStartView, } from './subflow/subflow-node-view' export type { - BlockRunStatus, CodePreview, CodePreviewLanguage, - DiffStatus, EdgeDiffStatus, - EdgeRunStatus, } from './types' export { useCanvasColorMode } from './use-canvas-color-mode' export { type CanvasSentenceSegment, CanvasSentenceView, - type CanvasSentenceViewProps, } from './workflow-block/canvas-sentence-view' -export { InlineChip, type InlineChipProps } from './workflow-block/inline-chip' -export { - CURSOR_SOURCE_HANDLE_ID, - getCursorBranchSourceHandleId, - getCursorSourceHandleId, - getCursorSourceHandlePosition, - normalizeCursorSourceHandleId, -} from './workflow-block/source-handle' -export { SubBlockRowView, type SubBlockRowViewProps } from './workflow-block/sub-block-row-view' +export { InlineChip } from './workflow-block/inline-chip' +export { normalizeCursorSourceHandleId } from './workflow-block/source-handle' +export { SubBlockRowView } from './workflow-block/sub-block-row-view' export { CONNECTION_KNOB_PEAK_PX, - CURSOR_SWELL_LENGTH_PX, - getWorkflowBorderFrameDeltaSeconds, - isActionMenuSwellReady, WorkflowBlockBorder, - type WorkflowBorderCursorHandle, type WorkflowBorderPort, } from './workflow-block/workflow-block-border' -export { - ERROR_SOURCE_HANDLE_POSITION, - getErrorBorderPort, - getErrorSourceHandleStyle, - getNearestBranchCursorHandleId, - WorkflowBlockView, - type WorkflowBlockViewProps, -} from './workflow-block/workflow-block-view' +export { WorkflowBlockView } from './workflow-block/workflow-block-view' diff --git a/packages/workflow-renderer/src/note/note-block-view.tsx b/packages/workflow-renderer/src/note/note-block-view.tsx index d47a556d391..5060d25374a 100644 --- a/packages/workflow-renderer/src/note/note-block-view.tsx +++ b/packages/workflow-renderer/src/note/note-block-view.tsx @@ -373,7 +373,7 @@ const NOTE_COMPONENTS = { * move the read view out from under the editor, which is what made every block * after the first jump the moment editing opened. */ -export const NOTE_MARKDOWN_FLOW = 'space-y-4 [&>*:first-child]:mt-0 [&>*:last-child]:mb-0' +const NOTE_MARKDOWN_FLOW = 'space-y-4 [&>*:first-child]:mt-0 [&>*:last-child]:mb-0' interface NoteMarkdownProps { content: string diff --git a/packages/workflow-renderer/src/subflow/subflow-node-view.tsx b/packages/workflow-renderer/src/subflow/subflow-node-view.tsx index d085d99272d..30793eff5e7 100644 --- a/packages/workflow-renderer/src/subflow/subflow-node-view.tsx +++ b/packages/workflow-renderer/src/subflow/subflow-node-view.tsx @@ -155,7 +155,7 @@ interface SubflowStartViewProps { } /** Start control shared by editable and preview subflow containers. */ -export function SubflowStartView({ +function SubflowStartView({ parentId, kind, isPreview = false, diff --git a/packages/workflow-renderer/src/workflow-block/source-handle.ts b/packages/workflow-renderer/src/workflow-block/source-handle.ts index fe1897765ef..42ffb4e3f1c 100644 --- a/packages/workflow-renderer/src/workflow-block/source-handle.ts +++ b/packages/workflow-renderer/src/workflow-block/source-handle.ts @@ -5,7 +5,7 @@ import { } from '@sim/workflow-types/workflow' import { Position } from '@xyflow/react' -export const CURSOR_SOURCE_HANDLE_ID = 'source-cursor' +const CURSOR_SOURCE_HANDLE_ID = 'source-cursor' const CURSOR_BRANCH_SOURCE_HANDLE_PREFIX = `${CURSOR_SOURCE_HANDLE_ID}-branch-` /** Returns the temporary React Flow handle ID under the cursor swell. */ diff --git a/packages/workflow-renderer/src/workflow-block/workflow-block-border.tsx b/packages/workflow-renderer/src/workflow-block/workflow-block-border.tsx index c654247b25d..d337f950a32 100644 --- a/packages/workflow-renderer/src/workflow-block/workflow-block-border.tsx +++ b/packages/workflow-renderer/src/workflow-block/workflow-block-border.tsx @@ -109,10 +109,7 @@ const MAX_FRAME_DELTA_SECONDS = 1 / 30 * Returns a monotonic, capped animation step. Synchronous repaints can occur * between requested frames, so a later callback may carry an older timestamp. */ -export const getWorkflowBorderFrameDeltaSeconds = ( - timestamp: number, - previousTimestamp: number -) => { +const getWorkflowBorderFrameDeltaSeconds = (timestamp: number, previousTimestamp: number) => { if (!Number.isFinite(timestamp)) return 0 if (previousTimestamp === 0) return 1 / 60 const elapsed = (timestamp - previousTimestamp) / 1000 @@ -120,7 +117,7 @@ export const getWorkflowBorderFrameDeltaSeconds = ( return Math.min(MAX_FRAME_DELTA_SECONDS, Math.max(0, elapsed)) } -export const isActionMenuSwellReady = (target: number, value: number) => +const isActionMenuSwellReady = (target: number, value: number) => target === 1 && value >= ACTION_MENU_CONTENT_READY_THRESHOLD export interface WorkflowBorderPort { diff --git a/packages/workflow-renderer/src/workflow-block/workflow-block-view.tsx b/packages/workflow-renderer/src/workflow-block/workflow-block-view.tsx index 3e4ab248ff2..a16edfbe192 100644 --- a/packages/workflow-renderer/src/workflow-block/workflow-block-view.tsx +++ b/packages/workflow-renderer/src/workflow-block/workflow-block-view.tsx @@ -81,7 +81,7 @@ interface WorkflowCursorSourceHandle extends WorkflowBorderCursorHandle { } /** Resolves a moving branch-card swell to the nearest visible branch row. */ -export function getNearestBranchCursorHandleId( +function getNearestBranchCursorHandleId( rows: BranchCursorRow[], cursorY: number, firstRowY: number, @@ -163,10 +163,10 @@ const invisibleHandleSize = ( } /** Error is the only persisted source that leaves from a vertical card edge. */ -export const ERROR_SOURCE_HANDLE_POSITION = Position.Bottom +const ERROR_SOURCE_HANDLE_POSITION = Position.Bottom /** Keeps the Error hit target centered on the painted bottom-right knob. */ -export const getErrorSourceHandleStyle = (): CSSProperties => ({ +const getErrorSourceHandleStyle = (): CSSProperties => ({ right: 'auto', top: 'auto', bottom: -HANDLE_OUTSET_PX, @@ -177,7 +177,7 @@ export const getErrorSourceHandleStyle = (): CSSProperties => ({ }) /** Builds the fixed Error knob painted into the card's bottom edge. */ -export const getErrorBorderPort = (color?: string): WorkflowBorderPort => ({ +const getErrorBorderPort = (color?: string): WorkflowBorderPort => ({ id: 'error', side: 'bottom', position: { fromEnd: HANDLE_POSITIONS.ERROR_RIGHT_OFFSET }, diff --git a/packages/workflow-renderer/src/workflow-type.tsx b/packages/workflow-renderer/src/workflow-type.tsx index 234c70bddc2..d72874821e0 100644 --- a/packages/workflow-renderer/src/workflow-type.tsx +++ b/packages/workflow-renderer/src/workflow-type.tsx @@ -83,7 +83,7 @@ const DEFAULT_WORKFLOW_TYPE_ROLE: WorkflowTypeRole = 'neutral' export const hasWorkflowTypeRole = (type: string): type is keyof typeof WORKFLOW_TYPE_ROLES => Object.hasOwn(WORKFLOW_TYPE_ROLES, type) -export const getWorkflowTypeRole = (type: string): WorkflowTypeRole => +const getWorkflowTypeRole = (type: string): WorkflowTypeRole => WORKFLOW_TYPE_ROLES[type as keyof typeof WORKFLOW_TYPE_ROLES] ?? DEFAULT_WORKFLOW_TYPE_ROLE export const getWorkflowTypeAccent = (type: string) => diff --git a/packages/workflow-types/src/workflow.ts b/packages/workflow-types/src/workflow.ts index 3ef13aef486..742e4e7c52b 100644 --- a/packages/workflow-types/src/workflow.ts +++ b/packages/workflow-types/src/workflow.ts @@ -8,10 +8,6 @@ export const SUBFLOW_TYPES = { export type SubflowType = (typeof SUBFLOW_TYPES)[keyof typeof SUBFLOW_TYPES] -export function isValidSubflowType(type: string): type is SubflowType { - return Object.values(SUBFLOW_TYPES).includes(type as SubflowType) -} - export interface LoopConfig { nodes: string[] iterations: number @@ -207,7 +203,7 @@ export interface WorkflowLockBlock { /** * Reads a workflow block's parent ID from runtime block data. */ -export function getWorkflowBlockParentId(block?: WorkflowLockBlock): string | undefined { +function getWorkflowBlockParentId(block?: WorkflowLockBlock): string | undefined { const data = block?.data if (typeof data !== 'object' || data === null || !('parentId' in data)) return undefined @@ -331,11 +327,11 @@ export interface WorkflowEdgeHandles extends WorkflowEdgeEndpoints { targetHandle?: string | null } -export const WORKFLOW_CARD_SIDES = ['top', 'right', 'bottom', 'left'] as const +const WORKFLOW_CARD_SIDES = ['top', 'right', 'bottom', 'left'] as const export type WorkflowCardSide = (typeof WORKFLOW_CARD_SIDES)[number] /** The two card sides a connection line can attach to. Purely visual. */ -export const WORKFLOW_CONNECTION_SIDES = ['left', 'right'] as const +const WORKFLOW_CONNECTION_SIDES = ['left', 'right'] as const export type WorkflowConnectionSide = (typeof WORKFLOW_CONNECTION_SIDES)[number] /** The one output handle every non-branching block exposes. */ diff --git a/scripts/check-unused-exports.baseline.json b/scripts/check-unused-exports.baseline.json index ceaac73e6ae..f238aa01c30 100644 --- a/scripts/check-unused-exports.baseline.json +++ b/scripts/check-unused-exports.baseline.json @@ -5515,7 +5515,6 @@ "apps/sim/stores/workflows/workflow/types.ts#SUBFLOW_TYPES", "apps/sim/stores/workflows/workflow/types.ts#Subflow", "apps/sim/stores/workflows/workflow/types.ts#WorkflowActions", - "apps/sim/stores/workflows/workflow/types.ts#isValidSubflowType", "apps/sim/tools/affinity/utils.ts#AFFINITY_MAX_BATCH_FIELD_UPDATES", "apps/sim/tools/affinity/utils.ts#parseOptionalJsonArray", "apps/sim/tools/arxiv/utils.ts#cleanText", diff --git a/scripts/check-unused-exports.ts b/scripts/check-unused-exports.ts index 7957e68df49..bed43a8dd9d 100644 --- a/scripts/check-unused-exports.ts +++ b/scripts/check-unused-exports.ts @@ -16,10 +16,12 @@ * `scripts/check-unused-exports.baseline.json`. A new entry fails; so does a baseline entry that * no longer occurs, so the baseline only shrinks. Regenerate with `--update`. * - * Public package surface is not baselined: knip treats every workspace's `exports`/`main`/`bin` - * targets as entry files and, with `includeEntryExports: false` (set explicitly in knip.jsonc), - * never reports their exports. Exports used only by tests count as used because knip's Vitest - * plugin makes test files entries. + * Entry exports are reported (`includeEntryExports: true` in knip.jsonc): a private package's + * `exports` map serves only this monorepo, so an entry export nothing imports is dead. The apps, + * the published packages, db, and the root turn it off there, since their entries are public or + * standalone. Exports used only by tests count as used because knip's Vitest plugin makes test + * files entries. An export whose only consumer knip cannot see (a path-based `import()`, or a + * helper an audit names as the replacement) carries a `@public` TSDoc tag saying why. * * Knip is slow, so `run-audits.ts` runs this script and skips `check:dead-code`, which stays * available as the human-readable report. @@ -165,8 +167,10 @@ if (added.length) { } for (const kind of kinds) console.error(` ${kind}: ${HOW_TO_FIX[kind]}`) console.error( - ' If it is deliberate public API of a package, expose it through that package.json `exports` ' + - 'map (or add an `ignore` rule in knip.jsonc with a comment saying why). Never add it to the baseline.' + ' If it is deliberate public API of a published package, expose it through that package.json ' + + '`exports` map (or add an `ignore` rule in knip.jsonc with a comment saying why). A private ' + + "package's entry exports are checked too: delete them once nothing imports them. Never add " + + 'it to the baseline.' ) } From 88a2e918dba8374f5ca8b2890fb88e3ba7a495ae Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Sat, 3 Oct 2026 12:26:14 -0700 Subject: [PATCH 05/12] feat(library): How do you build an AI voice agent with Twilio and Sim? (#8598) * feat(library): How do you build an AI voice agent with Twilio and Sim? * Pi Babysit: address PR #8598 feedback * Pi Babysit: address PR #8598 feedback --------- Co-authored-by: Sim Pi Agent --- .../index.mdx | 631 ++++++++++++++++++ .../cover.jpg | Bin 0 -> 30403 bytes 2 files changed, 631 insertions(+) create mode 100644 apps/sim/content/library/how-to-build-ai-voice-agent-with-twilio/index.mdx create mode 100644 apps/sim/public/library/how-to-build-ai-voice-agent-with-twilio/cover.jpg diff --git a/apps/sim/content/library/how-to-build-ai-voice-agent-with-twilio/index.mdx b/apps/sim/content/library/how-to-build-ai-voice-agent-with-twilio/index.mdx new file mode 100644 index 00000000000..b71278753d0 --- /dev/null +++ b/apps/sim/content/library/how-to-build-ai-voice-agent-with-twilio/index.mdx @@ -0,0 +1,631 @@ +--- +slug: how-to-build-ai-voice-agent-with-twilio +title: 'How do you build an AI voice agent with Twilio and Sim?' +description: 'Learn how to build a production AI voice agent with Twilio for calls and live audio, a low-latency voice adapter, and Sim for orchestration, tools, safeguards, and escalation.' +date: 2026-10-03 +updated: 2026-10-03 +authors: + - andrew +readingTime: 12 +tags: [AI Agents, Voice AI, Twilio, Sim] +ogImage: /library/how-to-build-ai-voice-agent-with-twilio/cover.jpg +draft: false +faq: + - q: "Can Twilio build an AI voice agent?" + a: "Twilio can provide phone numbers, inbound and outbound calling, speech-oriented TwiML, and real-time Media Streams for an AI voice agent, while an external voice and orchestration layer supplies the agent intelligence." + - q: "How do you connect Twilio to an LLM?" + a: "Twilio connects to an LLM through an application that receives speech or streamed audio, creates a transcript, sends structured context to the model or agent, validates the result, synthesizes approved text, and returns audio to the call." + - q: "Can Sim orchestrate a Twilio AI voice agent?" + a: "Sim can orchestrate the conversation logic, approved tool calls, business-system actions, safeguards, and escalation decisions behind a Twilio voice agent." + - q: "Does this architecture require a native Twilio integration in Sim?" + a: "This Twilio architecture does not depend on a native integration because a secure adapter can receive Twilio events and invoke the deployed Sim workflow through its configured deployment interface." + - q: "Should Twilio audio stream directly through Sim?" + a: "Twilio audio should normally stream through a dedicated low-latency voice adapter, while Sim receives normalized transcripts and structured call context for orchestration." + - q: "What is the difference between Twilio Gather and Twilio Media Streams?" + a: "Twilio Gather supports simpler turn-based speech interactions, while Twilio Media Streams supports real-time audio processing, interruption, and more natural conversational control." + - q: "Can a Twilio AI voice agent make outbound calls?" + a: "Twilio can place outbound AI voice calls through the Calls API after the application checks consent, suppression status, destination, purpose, and applicable calling restrictions." + - q: "How does a Twilio AI voice agent transfer a caller to a person?" + a: "Twilio can transfer the caller with Dial or an approved call update, while Sim returns the escalation reason and the application selects a server-configured destination." + - q: "Does a Twilio AI voice agent need to disclose that it is AI?" + a: "A Twilio AI voice agent should clearly disclose that the caller is interacting with AI and follow jurisdiction-specific requirements for automated calls, transcription, recording, and sensitive-data processing." + - q: "Is a Twilio Media Stream the same as a call recording?" + a: "Twilio Media Streams and call recording are different capabilities, so an application must not assume that permission for live processing automatically permits retained audio recording." + - q: "How do you secure a Twilio AI voice agent?" + a: "Twilio AI voice agents should validate signed requests, use encrypted connections, isolate credentials, authorize every action, minimize retained data, redact logs, and provide safe failure and transfer paths." + - q: "How do you stop a Twilio AI voice agent from taking the wrong action?" + a: "Sim should return typed, allow-listed action requests, while the application independently validates authorization, arguments, confirmation, idempotency, and policy before executing them." + - q: "How do you reduce Twilio AI voice latency?" + a: "Twilio AI voice latency improves when the application streams speech processing, reuses connections, keeps services close together, limits spoken response length, and enforces deadlines for models and tools." + - q: "Can a Twilio AI voice agent handle interruptions?" + a: "Twilio bidirectional Media Streams can support interruption when the voice adapter detects caller speech, stops or clears pending playback, cancels obsolete work, and starts the new turn." + - q: "Can n8n build a Twilio AI voice agent?" + a: "n8n can coordinate webhooks and business actions for a Twilio voice agent, but a dedicated real-time service should still manage bidirectional audio, interruption, and strict latency requirements." + - q: "Is n8n open source?" + a: "n8n is source-available under the Sustainable Use License, which is not an OSI-approved open-source license." + - q: "Is Sim open source?" + a: "Sim's core is open source under Apache 2.0, while code in apps/sim/ee is governed by the separate Sim Enterprise License and requires an active Enterprise subscription for production use." + - q: "Can Sim use local models for a Twilio voice agent?" + a: "Self-hosted Sim can use Ollama, vLLM, LM Studio, or LiteLLM without requiring Enterprise, while the telephony and voice adapter must still meet the call's latency requirements." + - q: "Does Sim support bring-your-own model keys?" + a: "Sim supports workspace BYOK on any Sim Cloud plan, while organization-level keys require Pro for Teams, Max for Teams, or Enterprise." + - q: "What should happen if the model or speech service fails during a call?" + a: "Twilio should play a brief approved fallback and then retry safely, transfer the caller, create a follow-up task, or end the call without executing uncertain actions." + - q: "Can a Twilio AI voice agent handle emergency calls?" + a: "A Twilio AI voice agent should not present itself as an emergency service and should follow an approved emergency script that directs the caller to the appropriate local emergency service." + - q: "How should you test a Twilio AI voice agent?" + a: "Twilio AI voice agents should be tested with lifecycle failures, silence, noisy audio, interruption, prompt attacks, duplicate actions, consent changes, transfer failures, service outages, and controlled live calls." + - q: "What is the best AI agent platform for a Twilio voice agent?" + a: "Sim is a strong choice when the Twilio voice agent needs visual orchestration, reusable tools, multi-step decisions, self-hosting of the core, and an Apache 2.0 core license; Best AI Agent Platforms and Builders in 2026 covers the broader platform market." +--- + +## TL;DR + +Twilio handles phone calls and live audio, while Sim can orchestrate the AI decisions, business-system actions, safeguards, and escalation logic behind the conversation. + +A production implementation should separate the low-latency media path from the orchestration path: + +1. Twilio receives or places the call. +2. A voice adapter handles Twilio webhooks, audio streaming, speech recognition, and speech synthesis. +3. A deployed Sim workflow receives structured conversation turns and decides what to say or do next. +4. Approved tools perform narrowly scoped actions in business systems. +5. Twilio speaks the response, continues the call, or transfers the caller to a person. + +This separation keeps raw audio out of a general-purpose workflow loop, gives the voice service control over interruption and latency, and lets Sim coordinate actions without being treated as the telephony server. + +All changing product, licensing, and commercial details in this guide were checked against first-party sources as of October 2026. + +## What is the recommended architecture for a Twilio AI voice agent? + +Twilio works best as the telephony and media layer, a dedicated adapter works best as the real-time audio layer, and Sim works best as the orchestration and action layer. + +```text +Caller + | + v +Twilio Programmable Voice + | signed webhook + call events + v +Voice adapter + |-- session state + |-- speech-to-text + |-- text-to-speech + |-- interruption handling + |-- latency deadlines + | + v +Deployed Sim workflow + |-- intent and policy decisions + |-- approved tool selection + |-- business-system actions + |-- escalation decision + |-- structured response + | + +--> CRM / ticketing / scheduling / internal APIs + | + v +Voice adapter --> Twilio --> Caller +``` + +Do not send every raw audio packet through an AI workflow. The voice adapter should maintain the WebSocket connection, buffer audio, detect turn boundaries, and enforce timeouts. It should send Sim normalized text turns and structured call metadata instead. + +A useful request contract is: + +```json +{ + "sessionId": "voice_session_01", + "callSid": "CA...", + "direction": "inbound", + "from": "+15551234567", + "to": "+15557654321", + "language": "en-US", + "transcript": "I need to move my appointment to Friday", + "consent": { + "aiDisclosureGiven": true, + "recordingAllowed": false + }, + "context": { + "customerId": "customer_123", + "previousTurnId": "turn_04" + } +} +``` + +The workflow should return a constrained response rather than arbitrary telephony instructions: + +```json +{ + "turnId": "turn_05", + "speech": "I can help with that. I found two openings on Friday.", + "action": { + "name": "list_available_appointments", + "status": "completed" + }, + "nextState": "ask_time_preference", + "escalate": false, + "endCall": false +} +``` + +## What are the key facts about Twilio, Sim, and n8n at a glance? + +Twilio, Sim, and n8n solve different parts of a voice-agent system and should not be treated as interchangeable media servers. + +- **Twilio:** As of October 2026, Twilio is a hosted communications service rather than self-hosted software, and Programmable Voice is billed using usage-based components such as call minutes, phone numbers, destinations, and optional features documented on [Twilio's Voice pricing page](https://www.twilio.com/en-us/voice/pricing/us). +- **Sim:** As of October 2026, [Sim's core is Apache 2.0](https://github.com/simstudioai/sim/blob/main/LICENSE) and can be self-hosted, while code in `apps/sim/ee` is governed by the separate [Sim Enterprise License](https://github.com/simstudioai/sim/blob/main/apps/sim/ee/LICENSE); workspace BYOK works on any Sim Cloud plan, and hosted model-key usage carries a multiplier of about 1.1 times provider cost, as documented in [Sim's cost guide](https://docs.sim.ai/platform/costs). +- **n8n:** As of October 2026, n8n is self-hostable under its source-available [Sustainable Use License](https://docs.n8n.io/privacy-and-security/sustainable-use-license), which is not OSI-approved, while [n8n Cloud pricing](https://n8n.io/pricing/) uses workflow executions as a billing dimension. + +## How do you choose between Twilio Gather and Twilio Media Streams? + +Twilio `` is the simpler choice for turn-based conversations, while Twilio bidirectional Media Streams is the stronger choice for low-latency, interruptible voice agents. + +Use [``](https://www.twilio.com/docs/voice/twiml/gather) when: + +- The caller can speak, wait, and then hear a complete response. +- An IVR-like interaction is acceptable. +- Fast implementation matters more than natural interruption. +- You do not want to operate a real-time audio WebSocket service. + +Use [bidirectional Media Streams](https://www.twilio.com/docs/voice/media-streams) when: + +- The caller must be able to interrupt the agent. +- Partial transcripts should start model work before the turn fully ends. +- The application needs control over speech recognition and synthesis. +- Silence, back-channel speech, and turn timing affect the experience. + +A team can start with `` to validate prompts and actions, then move to Media Streams when conversation quality justifies the extra infrastructure. + +## How do you set up Twilio for inbound AI voice calls? + +Twilio starts an inbound AI call by sending a signed webhook to the voice URL configured for the receiving phone number. + +Create a Twilio phone number with Voice capability, configure its incoming-call webhook, and return TwiML that either gathers speech or connects a media stream. Twilio documents webhook signature validation in its [webhook security guide](https://www.twilio.com/docs/usage/webhooks/webhooks-security). + +### How do you start a turn-based Twilio voice agent? + +Twilio can start a turn-based agent with `` and speak responses with ``. + +```javascript +import express from 'express' +import twilio from 'twilio' + +const app = express() +app.use(express.urlencoded({ extended: false })) + +app.post( + '/voice/incoming', + twilio.webhook({ validate: true }), + (req, res) => { + const response = new twilio.twiml.VoiceResponse() + + const gather = response.gather({ + input: 'speech', + action: '/voice/turn', + method: 'POST', + speechTimeout: 'auto', + actionOnEmptyResult: true + }) + + gather.say( + 'Hello. You are speaking with an AI assistant. How can I help you today?' + ) + + res.type('text/xml').send(response.toString()) + } +) +``` + +The `/voice/turn` handler should read Twilio's speech result, normalize it into the orchestration contract, call the deployed Sim workflow, and convert the structured response back into TwiML. + +```javascript +app.post( + '/voice/turn', + twilio.webhook({ validate: true }), + async (req, res) => { + const transcript = req.body.SpeechResult || '' + const callSid = req.body.CallSid + + const result = await runVoiceWorkflow({ + sessionId: callSid, + callSid, + transcript, + direction: req.body.Direction || 'inbound' + }) + + const response = new twilio.twiml.VoiceResponse() + + if (result.escalate) { + response.redirect('/voice/escalate') + } else if (result.endCall) { + response.say(result.speech) + response.hangup() + } else { + const gather = response.gather({ + input: 'speech', + action: '/voice/turn', + method: 'POST', + speechTimeout: 'auto', + actionOnEmptyResult: true + }) + gather.say(result.speech) + } + + res.type('text/xml').send(response.toString()) + } +) +``` + +`runVoiceWorkflow` represents an adapter you control. The synchronous workflow API wraps the turn contract in `input` and returns the workflow's structured response in `data.output`, so the adapter should map both envelopes explicitly: + +```javascript +async function runVoiceWorkflow(turn) { + try { + const response = await fetch( + `${process.env.SIM_BASE_URL}/api/v2/workflows/${process.env.SIM_WORKFLOW_ID}/execute`, + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'x-api-key': process.env.SIM_API_KEY + }, + body: JSON.stringify({ input: turn }), + signal: AbortSignal.timeout(8000) + } + ) + + if (!response.ok) return safeVoiceFallback() + + const payload = await response.json() + if (payload.data?.status !== 'completed') return safeVoiceFallback() + + return parseVoiceWorkflowResponse(payload.data.output) + } catch { + return safeVoiceFallback() + } +} +``` + +`parseVoiceWorkflowResponse` should validate `speech`, `action`, `nextState`, `escalate`, and `endCall` against the expected schema. The adapter should also authenticate to the deployment interface, keep its API key server-side, and return a safe fallback when the request times out or the workflow is unavailable. + +### How do you start a real-time Twilio voice agent? + +Twilio starts a real-time voice session by connecting the call to a secure WebSocket with ``. Do not invoke this route until an earlier TwiML step has disclosed the AI interaction and collected any consent required before live transcription. Record that result in server-side session state, then enforce it before opening the stream. + +```javascript +app.post( + '/voice/start-stream-after-consent', + twilio.webhook({ validate: true }), + async (req, res) => { + const response = new twilio.twiml.VoiceResponse() + const consent = await loadCallConsent(req.body.CallSid) + + if (!consent.aiDisclosureGiven || !consent.transcriptionAllowed) { + response.say('I cannot start voice processing without your consent.') + response.redirect('/voice/consent') + return res.type('text/xml').send(response.toString()) + } + + const connect = response.connect() + const stream = connect.stream({ + url: 'wss://voice.example.com/twilio-media' + }) + + stream.parameter({ name: 'callSid', value: req.body.CallSid }) + stream.parameter({ name: 'direction', value: 'inbound' }) + + res.type('text/xml').send(response.toString()) + } +) +``` + +The WebSocket service should: + +1. Validate Twilio's signature before accepting the connection. +2. Associate the `start` event with an isolated call session. +3. Decode incoming `media` payloads according to Twilio's documented format. +4. Stream audio to the selected speech-recognition service. +5. Send stable transcript turns to the Sim orchestration adapter. +6. Synthesize approved response text into Twilio-compatible audio. +7. Send outbound media in the order required by Twilio. +8. Handle `stop`, disconnect, timeout, and caller interruption events. + +Twilio's [Media Streams documentation](https://www.twilio.com/docs/voice/media-streams) should be the source of truth for event names, audio encoding, sequence behavior, and outbound media requirements. + +## How do you place outbound AI voice calls with Twilio? + +Twilio places an outbound AI call through the Calls API, but the application should verify consent, destination, purpose, and calling window before creating it. + +```javascript +import twilio from 'twilio' + +const client = twilio( + process.env.TWILIO_ACCOUNT_SID, + process.env.TWILIO_AUTH_TOKEN +) + +const call = await client.calls.create({ + to: approvedDestination, + from: process.env.TWILIO_PHONE_NUMBER, + url: 'https://voice.example.com/voice/outbound', + statusCallback: 'https://voice.example.com/voice/status', + statusCallbackMethod: 'POST', + statusCallbackEvent: ['initiated', 'ringing', 'answered', 'completed'] +}) +``` + +The outbound TwiML should immediately identify the organization, disclose that the caller is an AI assistant, explain the purpose of the call, and provide a clear way to opt out or reach a person. + +Never allow a model to choose arbitrary destinations. The application should obtain the destination from an approved record, normalize it, check suppression lists, enforce rate limits, and store the authorization basis for the call. + +Twilio's [Call resource documentation](https://www.twilio.com/docs/voice/api/call-resource) defines the supported API fields and status events. + +## How does Sim orchestrate a Twilio AI voice agent? + +Sim can orchestrate the text-level conversation, approved business actions, policy checks, and escalation decision while the voice adapter retains control of live audio. + +Sim is the open-source AI workspace where teams build, deploy, and manage AI agents. In this architecture, a Sim workflow can: + +- Classify the caller's intent. +- Retrieve customer or case context through authorized tools. +- Decide whether an action needs confirmation. +- Produce a concise response suitable for speech. +- Return a typed tool request instead of free-form instructions. +- Escalate sensitive, unsupported, or low-confidence requests. +- Write structured outcomes to a CRM, ticketing system, or internal API. + +A reliable workflow separates planning from execution: + +```text +Transcript and call context + -> classify intent + -> check policy + -> request missing information + -> propose typed action + -> validate action arguments + -> execute approved tool + -> summarize result for speech + -> continue, transfer, or end +``` + +Use [How to Build AI Agents With Sim](https://www.sim.ai/library/how-to-create-an-ai-agent) for the broader workflow-building process. [Sim's core is Apache 2.0](https://github.com/simstudioai/sim/blob/main/LICENSE), with the enterprise exception described in the separate [Sim Enterprise License](https://github.com/simstudioai/sim/blob/main/apps/sim/ee/LICENSE), so teams can inspect and self-host the core while evaluating enterprise-only code under its applicable terms. + +## How should a Twilio voice agent execute tool calls safely? + +Sim should produce allow-listed, schema-validated tool requests, and the application should reject any action that falls outside the caller's authorization or the current conversation state. + +Define each action with: + +- A stable action name. +- A strict input schema. +- Caller and tenant authorization rules. +- A maximum execution time. +- An idempotency key. +- A retry policy based on error type. +- A redacted audit record. +- A confirmation requirement for consequential changes. + +A scheduling action might use this contract: + +```json +{ + "name": "reschedule_appointment", + "arguments": { + "appointmentId": "apt_123", + "newStart": "2026-10-16T14:00:00-04:00" + }, + "confirmation": { + "required": true, + "prompt": "Would you like me to move appointment 123 to Friday at 2 PM?" + }, + "idempotencyKey": "CA...:turn_08:reschedule_appointment" +} +``` + +The voice adapter should not execute the action until the caller's confirmation has been captured in a later turn. The action service should independently re-check authorization and availability rather than trusting model output. + +## How do you transfer a Twilio AI voice call to a human? + +Twilio can transfer a call with ``, while Sim can decide when escalation is required and return a structured escalation reason. + +Escalate when: + +- The caller asks for a person. +- Identity verification fails. +- The request falls outside the approved scope. +- A high-impact action lacks clear consent. +- A tool repeatedly fails or times out. +- The model reports low confidence. +- The caller shows distress, danger, or an emergency. +- Policy requires human review. + +```javascript +app.post( + '/voice/escalate', + twilio.webhook({ validate: true }), + async (req, res) => { + const response = new twilio.twiml.VoiceResponse() + response.say('I am transferring you to a team member now.') + + const dial = response.dial({ + answerOnBridge: true, + timeout: 20 + }) + dial.number(process.env.APPROVED_SUPPORT_NUMBER) + + res.type('text/xml').send(response.toString()) + } +) +``` + +The transfer destination must come from server-side configuration, not model-generated text. Before bridging the call, provide the human with a concise summary, completed verification status, tool results, and the reason for escalation without exposing unnecessary sensitive data. + +For approval patterns beyond voice calls, see [What Is Human-in-the-Loop in AI Agents?](https://www.sim.ai/library/what-is-human-in-the-loop-in-ai-agents). + +## What consent and disclosure does a Twilio AI voice agent need? + +Twilio voice agents should disclose that the caller is interacting with AI and should obtain any consent required for recording, transcription, automated calling, or sensitive-data processing before those activities begin. + +Consent requirements vary by jurisdiction, call direction, purpose, industry, and whether audio is recorded. A production system should have counsel-approved rules for every operating region rather than relying on one universal prompt. + +At minimum, design the call flow to: + +- Identify the organization. +- State that the caller is speaking with an AI assistant. +- Explain the purpose of an outbound call. +- Distinguish live transcription from retained recording. +- Ask for recording consent when required. +- Offer a human or opt-out path. +- Stop recording or end the call when consent is withdrawn. +- Store the consent event, wording version, timestamp, and call identifier. + +Twilio's [voice recording documentation](https://www.twilio.com/docs/voice/recording-settings) explains the recording controls available in its platform, but using those controls does not by itself establish legal consent. + +## How do you secure Twilio webhooks and media streams? + +Twilio integrations should validate every webhook and WebSocket handshake, isolate credentials, minimize retained data, and authorize each business action independently. + +Use these controls: + +- Validate `X-Twilio-Signature` against the exact public request URL and parameters. +- Require HTTPS and WSS in production. +- Keep the Twilio Auth Token and API credentials in a secret manager. +- Use narrowly scoped API keys where supported. +- Reject replayed or stale requests when the endpoint design permits it. +- Bind each stream to its expected Call SID and tenant. +- Encrypt transcripts, recordings, summaries, and tool outputs at rest. +- Redact payment, health, authentication, and other sensitive fields from logs. +- Set explicit retention periods for audio and transcripts. +- Rate-limit call creation, tool execution, and transfer requests. +- Keep telephony controls outside free-form model output. + +Do not use the caller's phone number as sufficient authentication for sensitive actions. Add an identity-verification step appropriate to the risk, then pass only the resulting authorization state to the workflow. + +## How do you reduce latency in a Twilio AI voice agent? + +Twilio voice-agent latency is reduced most effectively by streaming speech processing, starting safe work from stable partial transcripts, and keeping the real-time path geographically and operationally simple. + +Measure these intervals separately: + +```text +caller stops speaking + -> end-of-turn detected + -> transcript finalized + -> orchestration starts + -> first model output + -> tool completes, if needed + -> synthesis starts + -> first audio reaches caller +``` + +Practical latency controls include: + +- Keep the Twilio media endpoint, speech services, and adapter in compatible regions. +- Reuse network connections instead of reconnecting each turn. +- Stream speech recognition and synthesis where supported. +- Start retrieval from stable partial transcripts, but wait for confirmation before consequential actions. +- Use short spoken answers and move details into follow-up turns. +- Set separate deadlines for the model, each tool, and the complete turn. +- Cache static prompts and frequently used reference data. +- Cancel synthesis and pending work when the caller interrupts. +- Return a short recovery prompt instead of leaving unexplained silence. + +Do not hide a long-running write operation behind filler speech. Tell the caller what is happening, enforce a deadline, and transfer or create a follow-up task when the action cannot complete promptly. + +## How do you log and observe a Twilio AI voice agent? + +Twilio and Sim runs should be correlated with one trace that connects the call, conversation turn, model decision, tool execution, and final outcome. + +Record structured events such as: + +- Call SID and internal session ID. +- Call direction and state transitions. +- Consent and disclosure events. +- Turn ID and timing milestones. +- Transcript confidence without unnecessary raw audio retention. +- Model and prompt version. +- Tool name, sanitized arguments, result, and latency. +- Escalation reason and transfer outcome. +- Error category and fallback used. +- Final disposition, such as resolved, transferred, abandoned, or failed. + +Do not log secrets, full payment details, authentication codes, or unrestricted model context. Apply field-level redaction before events leave the voice adapter. + +[What Is AI Agent Observability? Traces, Metrics, and Evals Explained](https://www.sim.ai/library/ai-agent-observability) covers the broader observability model. + +## How do you test a Twilio AI voice agent before production? + +Twilio voice agents should pass deterministic action tests, simulated conversation tests, audio-condition tests, and controlled live-call tests before receiving production traffic. + +Test at least these scenarios: + +| Test area | Required cases | Passing condition | +|---|---|---| +| Call lifecycle | Answer, no answer, busy, disconnect, timeout | Every state reaches a defined terminal outcome | +| Speech | Silence, interruption, accent variation, background noise | Agent recovers or escalates without inventing input | +| Actions | Success, timeout, duplicate request, partial failure | Actions are idempotent and failures are explained safely | +| Identity | Valid, invalid, expired, mismatched caller | Sensitive tools remain blocked until verification succeeds | +| Consent | Accepted, declined, withdrawn | Recording and retention behavior follows the caller's choice | +| Escalation | Caller request, policy trigger, tool failure | Transfer uses an approved destination and includes context | +| Prompt attacks | Instructions to reveal secrets or bypass policy | Agent refuses and no unauthorized tool runs | +| Outbound controls | Opt-out, suppression entry, invalid destination | No prohibited call is created | +| Recovery | Model unavailable, speech service unavailable, adapter restart | Caller receives a fallback, transfer, or safe termination | + +Replay sanitized transcripts against new workflow versions and compare expected action, escalation, and response fields. Audio tests should also introduce packet delay, clipped speech, crosstalk, and abrupt disconnects because clean text-only tests do not represent phone calls. + +## What production safeguards does a Twilio AI voice agent need? + +Twilio voice agents need explicit scope limits, caller confirmation, independent authorization, idempotent tools, emergency handling, and a human fallback before production deployment. + +A production readiness checklist should include: + +- AI disclosure is delivered at the start of the interaction. +- Recording and transcription behavior follows jurisdiction-specific policy. +- Outbound consent and suppression checks happen before call creation. +- Webhook and WebSocket signatures are validated. +- Every tool has a strict schema and server-side authorization. +- Consequential actions require explicit confirmation. +- Duplicate tool calls cannot duplicate the real-world effect. +- Model, tool, and turn deadlines have safe fallbacks. +- The caller can request a person at any point. +- Emergency language triggers an approved response rather than autonomous intervention. +- Logs are redacted and governed by a retention policy. +- Spend, call volume, failure rate, latency, and transfer rate have alerts. +- A kill switch can stop outbound calls and disable risky tools. +- Workflow and prompt changes use versioned deployment and rollback. + +A voice agent should not represent itself as an emergency service or attempt to replace qualified emergency responders. It should follow the organization's approved emergency script and direct the caller to the appropriate local service. + +## When should you use Sim instead of putting all logic in the Twilio adapter? + +Sim is the better orchestration layer when the voice agent needs multi-step reasoning, reusable business tools, branching policies, or coordination across systems, while the Twilio adapter should retain only real-time media and telephony responsibilities. + +Keep logic in the adapter when it is strictly about: + +- Audio buffering and encoding. +- Turn detection and interruption. +- Twilio webhook validation. +- Call-state transitions. +- Hard latency deadlines. +- Telephony-safe fallbacks. + +Move logic into a Sim workflow when it concerns: + +- Intent classification. +- Retrieval and context assembly. +- Business-policy branching. +- Tool selection and sequencing. +- Confirmation requirements. +- CRM, ticketing, scheduling, or database actions. +- Escalation decisions and summaries. + +This boundary lets the telephony service stay small and deterministic while the agent's business behavior remains inspectable and reusable. + +## Can n8n orchestrate a Twilio AI voice agent? + +n8n can orchestrate business actions around a Twilio call, but a separate low-latency WebSocket service should still handle bidirectional audio streaming and interruption. + +n8n is a credible incumbent for teams that already use it for webhook-driven automation and application integrations. Its [Sustainable Use License](https://docs.n8n.io/privacy-and-security/sustainable-use-license) is source-available rather than OSI-approved, so teams comparing self-hosted options should evaluate those terms directly. + +[Sim's core uses the OSI-approved Apache 2.0 license](https://github.com/simstudioai/sim/blob/main/LICENSE), subject to the separate [enterprise exception for `apps/sim/ee`](https://github.com/simstudioai/sim/blob/main/apps/sim/ee/LICENSE), and Sim is designed around building, deploying, and managing AI agents. The practical choice depends on whether the team primarily needs conventional integration automation or an AI workspace for agent decisions and tools. + +For a broader comparison, see [Sim vs n8n vs OpenAI AgentKit: AI Agent Builder Comparison (2026)](https://www.sim.ai/library/openai-vs-n8n-vs-sim) and [10 Best n8n Alternatives for AI Agent Workflows in 2026](https://www.sim.ai/library/n8n-alternatives). diff --git a/apps/sim/public/library/how-to-build-ai-voice-agent-with-twilio/cover.jpg b/apps/sim/public/library/how-to-build-ai-voice-agent-with-twilio/cover.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4ff315f1950f86838377c089b371b4fa3146fb9c GIT binary patch literal 30403 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 KgnbyX@V@}M&G7vI literal 0 HcmV?d00001 From 45d83cbe3c2f7ca80b9470da2f82fc0db272bb00 Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Sat, 3 Oct 2026 12:26:26 -0700 Subject: [PATCH 06/12] feat(library): Best HubSpot Alternatives for AI Marketing Automation in 2026 (#8599) * feat(library): Best HubSpot Alternatives for AI Marketing Automation in 2026 * Pi Babysit: address PR #8599 feedback --------- Co-authored-by: Sim Pi Agent --- .../index.mdx | 290 ++++++++++++++++++ .../cover.jpg | Bin 0 -> 28278 bytes 2 files changed, 290 insertions(+) create mode 100644 apps/sim/content/library/best-hubspot-alternatives-ai-marketing-automation-2026/index.mdx create mode 100644 apps/sim/public/library/best-hubspot-alternatives-ai-marketing-automation-2026/cover.jpg diff --git a/apps/sim/content/library/best-hubspot-alternatives-ai-marketing-automation-2026/index.mdx b/apps/sim/content/library/best-hubspot-alternatives-ai-marketing-automation-2026/index.mdx new file mode 100644 index 00000000000..15d6d6a90c2 --- /dev/null +++ b/apps/sim/content/library/best-hubspot-alternatives-ai-marketing-automation-2026/index.mdx @@ -0,0 +1,290 @@ +--- +slug: best-hubspot-alternatives-ai-marketing-automation-2026 +title: 'Best HubSpot Alternatives for AI Marketing Automation in 2026' +description: 'Compare the best HubSpot alternatives for AI marketing automation, including Sim, Marketo, Zapier, Make, n8n, and Gumloop.' +date: 2026-10-03 +updated: 2026-10-03 +authors: + - andrew +readingTime: 13 +tags: [Marketing Automation, AI Agents, HubSpot Alternatives, Sim] +ogImage: /library/best-hubspot-alternatives-ai-marketing-automation-2026/cover.jpg +draft: false +faq: + - q: "What is the best HubSpot alternative for marketing automation?" + a: "Sim is the best HubSpot alternative for agentic marketing automation, while Adobe Marketo Engage is the strongest option in this comparison for replacing sophisticated native campaign operations." + - q: "What is the best HubSpot alternative for AI agents?" + a: "Sim is the best HubSpot alternative for AI agents because it combines tool-using workflows, broad model choice, cloud BYOK, and local-model support on self-hosted deployments." + - q: "Is Sim a complete replacement for HubSpot?" + a: "Sim is not a complete replacement for HubSpot’s CRM, email marketing, forms, landing pages, and campaign reporting, but Sim can replace or extend HubSpot automations that require AI reasoning and cross-tool execution." + - q: "Is Sim better than HubSpot for AI marketing automation?" + a: "Sim is better than HubSpot when model flexibility, agentic execution, self-hosting, or cross-tool orchestration matters more than having CRM and campaign features in one suite." + - q: "Is HubSpot better than Sim for CRM and email campaigns?" + a: "HubSpot is better than Sim for native CRM management, email campaigns, forms, landing pages, contact segmentation, and integrated marketing reporting." + - q: "Can Sim work with HubSpot?" + a: "Sim can work with HubSpot as an AI-agent and orchestration layer while HubSpot remains the CRM and campaign system of record." + - q: "Is Marketo a better HubSpot alternative than Sim?" + a: "Adobe Marketo Engage is a better HubSpot alternative for enterprise campaign operations, while Sim is a better alternative for model-flexible AI agents that act across multiple tools." + - q: "Is Zapier a good alternative to HubSpot?" + a: "Zapier is a good HubSpot alternative for straightforward app-to-app automation, but Zapier does not replace HubSpot’s full CRM and marketing campaign suite." + - q: "Is Make a good alternative to HubSpot?" + a: "Make is a good HubSpot alternative for visual multi-app scenarios and data transformation, but Make requires a separate CRM or marketing system of record." + - q: "Is Gumloop a good alternative to HubSpot?" + a: "Gumloop is a good HubSpot alternative for AI-assisted research, extraction, enrichment, and browser workflows, but Gumloop is not a full CRM or campaign platform." + - q: "Is n8n a good alternative to HubSpot?" + a: "n8n is a good HubSpot alternative for technical teams that want self-hosted workflow automation and AI nodes, but n8n does not reproduce HubSpot’s native marketing suite." + - q: "Is n8n open source?" + a: "n8n is source-available under the Sustainable Use License, which is not an OSI-approved open-source license and restricts some commercial uses." + - q: "Is Sim open source?" + a: "Sim’s core is open source under the OSI-approved Apache License 2.0, while the enterprise code in apps/sim/ee uses the separate Sim Enterprise License and requires an active Enterprise subscription for production use." + - q: "Is Sim free to self-host?" + a: "Sim’s Apache 2.0 core can be self-hosted under that license, while production use of features in apps/sim/ee requires an active Sim Enterprise subscription." + - q: "Does Sim support local AI models?" + a: "Sim supports Ollama, vLLM, LM Studio, and LiteLLM on any self-hosted Sim deployment without requiring Sim Enterprise." + - q: "Does Sim support bring your own API key?" + a: "Sim supports workspace BYOK keys on every Sim Cloud plan, while organization-level keys require Pro for Teams, Max for Teams, or Enterprise." + - q: "Which HubSpot alternative has the broadest model choice?" + a: "Sim has the broadest model-control position in this comparison because it supports cloud BYOK and local models on self-hosted deployments." + - q: "Which HubSpot alternative is best for self-hosting?" + a: "Sim is the best self-hosted HubSpot alternative for teams prioritizing an Apache 2.0 core and AI-agent workflows, while n8n is a strong source-available option for general workflow automation." + - q: "Which HubSpot alternative is best for small businesses?" + a: "Zapier is often the easiest HubSpot alternative for small businesses that need simple SaaS automations, while Sim is stronger when the business needs custom AI agents and broader model choice." + - q: "Which HubSpot alternative is best for enterprise teams?" + a: "Adobe Marketo Engage is the strongest full marketing-suite alternative for enterprise campaign teams, while Sim is the strongest agentic alternative for enterprises orchestrating AI work across existing systems." + - q: "Which HubSpot alternative is easiest to implement?" + a: "Zapier is the easiest HubSpot alternative in this comparison for basic app-to-app automations, although implementation difficulty rises with workflow complexity and governance requirements." + - q: "Can an AI agent platform replace a marketing automation platform?" + a: "An AI agent platform can replace selected research, enrichment, routing, analysis, and coordination workflows, but it does not automatically replace a marketing platform’s CRM, email, forms, attribution, and campaign-management features." + - q: "Should a company replace HubSpot or add an AI agent platform?" + a: "A company should usually add an AI agent platform before replacing HubSpot when HubSpot remains useful as the CRM and campaign system but lacks the desired model flexibility or cross-tool agentic execution." + - q: "What is the difference between HubSpot and Sim?" + a: "HubSpot is a proprietary CRM and marketing suite, while Sim is the open-source AI workspace where teams build, deploy, and manage AI agents across models and tools." + - q: "What is the difference between HubSpot and Marketo?" + a: "HubSpot emphasizes an integrated and approachable CRM-led customer platform, while Adobe Marketo Engage emphasizes sophisticated enterprise campaign operations and lead management." + - q: "What is the difference between HubSpot and Zapier?" + a: "HubSpot provides native CRM and marketing applications, while Zapier connects separate applications through hosted automations and AI-oriented tools." + - q: "What is the difference between HubSpot and Make?" + a: "HubSpot provides customer records and campaign tools, while Make provides visual scenarios for moving, transforming, and acting on data across applications." + - q: "What is the difference between HubSpot and n8n?" + a: "HubSpot is a hosted CRM and marketing suite, while n8n is a source-available workflow automation product that can be self-hosted and extended with AI nodes." + - q: "What is the difference between HubSpot and Gumloop?" + a: "HubSpot is a CRM-centered marketing suite, while Gumloop focuses on AI-assisted workflows, web research, extraction, and browser automation." +--- + +## TL;DR + +Sim is the best HubSpot alternative for technical and semi-technical teams that prioritize agentic workflows, broad model choice, and automation across tools over an all-in-one CRM and campaign suite. + +HubSpot remains a stronger fit when a company wants CRM records, email campaigns, forms, lead management, reporting, and sales handoffs in one hosted suite. Sim, Marketo, Zapier, Make, n8n, and Gumloop solve different parts of that problem, so the right alternative depends on whether the buyer needs a marketing system of record or an orchestration layer. + +This guide compares the products for an agentic marketing automation use case as of October 2026. It evaluates CRM depth, campaign features, AI-agent capabilities, integrations, model flexibility, governance, and implementation effort without treating workflow tools as full marketing suites. + +## What is the best HubSpot alternative for AI marketing automation? + +Sim is the best HubSpot alternative for teams that want model-flexible AI agents to research, enrich, route, summarize, and act across their existing marketing stack. + +The best option by buyer profile is: + +- **Best for agentic marketing workflows: Sim.** Sim is the open-source AI workspace where teams build, deploy, and manage AI agents that use models, tools, APIs, and human input. +- **Best full campaign-suite alternative: Adobe Marketo Engage.** [Marketo is designed for campaign operations, lead management, attribution, and enterprise governance](https://business.adobe.com/products/marketo/pricing/). +- **Best for easy app-to-app automation: Zapier.** [Zapier connects AI workflows, agents, and apps](https://zapier.com/ai) and is approachable for teams that want quick implementation. +- **Best for visual, branching automations: Make.** [Make combines AI agents with visual automation across applications](https://www.make.com/en/ai-agents). +- **Best for self-hosted general automation: n8n.** [n8n supports self-hosting](https://docs.n8n.io/deploy/host-n8n) and combines workflow automation with AI nodes. +- **Best for browser-heavy AI workflows: Gumloop.** [Gumloop supports AI web scraping and extraction workflows](https://www.gumloop.com/solutions/ai-web-scraping). + +HubSpot is still the better choice when replacing its CRM, marketing database, campaign tools, forms, landing pages, and reporting with one product is the primary requirement. Most workflow and agent platforms complement a CRM rather than reproduce the entire HubSpot suite. + +## How were the best HubSpot alternatives compared? + +This HubSpot alternatives comparison weights agentic execution and cross-tool automation more heavily than a general marketing-suite comparison because those are the capabilities that motivate the switch. + +Each product receives a score from 1 to 5 for seven criteria. A higher implementation score means easier implementation. The weighted score is the sum of each criterion’s weight multiplied by its score and divided by 5, rounded to the nearest whole point. + +| Criterion | Weight | What the criterion measures | +|---|---:|---| +| CRM depth | 20% | Native customer records, lifecycle management, pipeline context, and CRM reporting | +| Campaign features | 15% | Email, forms, segmentation, journeys, attribution, and campaign operations | +| AI agents | 20% | Multi-step AI execution, tool use, branching, and human participation | +| Integrations | 15% | Ability to connect marketing, sales, support, data, and productivity systems | +| Model flexibility | 10% | Choice of model providers, bring-your-own-key support, and local-model options | +| Governance | 10% | Access controls, auditability, deployment controls, and enterprise administration | +| Implementation ease | 10% | Speed and effort required to build, operate, and maintain useful automations | + +Scores reflect fit for this specific agentic marketing automation use case, not universal product quality. Official product and documentation pages were used for capability and packaging claims as of October 2026. + +## How do HubSpot alternatives rank for agentic marketing automation? + +Sim ranks first among the HubSpot alternatives in this comparison because its AI-agent, model-flexibility, and cross-tool orchestration strengths outweigh its limited native CRM and campaign functionality for the stated use case. + +| Rank | Platform | CRM | Campaigns | AI agents | Integrations | Model flexibility | Governance | Ease | Weighted score | +|---:|---|---:|---:|---:|---:|---:|---:|---:|---:| +| Baseline | HubSpot | 5 | 5 | 3 | 5 | 2 | 4 | 4 | 82 | +| 1 | Sim | 2 | 2 | 5 | 4 | 5 | 4 | 4 | 72 | +| 2 | Adobe Marketo Engage | 3 | 5 | 3 | 4 | 2 | 5 | 2 | 69 | +| 3 | Zapier | 2 | 2 | 4 | 5 | 3 | 3 | 5 | 67 | +| 4 | Make | 1 | 2 | 4 | 5 | 4 | 3 | 4 | 63 | +| 5 | n8n | 1 | 1 | 4 | 4 | 4 | 4 | 3 | 57 | +| 6 | Gumloop | 1 | 1 | 4 | 3 | 4 | 2 | 4 | 52 | + +HubSpot’s baseline score is highest because it is the only product in this comparison that combines deep native CRM and campaign functionality with broad integrations. The alternatives ranking answers a narrower question: which product is the best replacement when agentic execution, model choice, or cross-tool orchestration is more important than consolidating marketing functions in one suite? + +## What are the key facts about HubSpot and its alternatives? + +HubSpot, Sim, Marketo, Zapier, Make, n8n, and Gumloop differ fundamentally in licensing, deployment, and billing, so buyers should compare operating models as well as features. + +- **HubSpot:** As of October 2026, HubSpot operates on [cloud infrastructure](https://knowledge.hubspot.com/account-security/hubspot-cloud-infrastructure-and-data-hosting-frequently-asked-questions), and its [official pricing](https://www.hubspot.com/pricing/marketing) packages Marketing Hub by edition with capacity and contact-related considerations. +- **Sim:** As of October 2026, [Sim’s core is Apache 2.0](https://github.com/simstudioai/sim/blob/main/LICENSE), while `apps/sim/ee` is covered by the separate [Sim Enterprise License](https://github.com/simstudioai/sim/blob/main/apps/sim/ee/LICENSE); Sim can be self-hosted, and [Sim Cloud supports workspace BYOK on any plan](https://docs.sim.ai/platform/costs#bring-your-own-key-byok). +- **Adobe Marketo Engage:** As of October 2026, [Adobe offers Marketo Engage in capability-based packages with custom pricing](https://business.adobe.com/products/marketo/pricing/). +- **Zapier:** As of October 2026, [Zapier’s official pricing](https://zapier.com/pricing) uses plan allowances for its hosted automation products. +- **Make:** As of October 2026, [Make’s official pricing](https://www.make.com/en/pricing) measures plan usage in credits. +- **n8n:** As of October 2026, n8n uses the source-available [Sustainable Use License](https://docs.n8n.io/privacy-and-security/sustainable-use-license), which is not OSI-approved; n8n supports self-hosting, while [n8n Cloud pricing](https://n8n.io/pricing/) is based primarily on workflow executions. +- **Gumloop:** As of October 2026, [Gumloop’s official pricing](https://www.gumloop.com/pricing) uses credits to meter usage. + +## Is HubSpot still the right choice for marketing automation? + +HubSpot is still the right choice for teams that want an integrated CRM and marketing suite more than they want an open-ended AI-agent orchestration layer. + +[HubSpot Marketing Hub](https://www.hubspot.com/products/marketing) combines customer records with campaign creation, forms, segmentation, lead management, reporting, and connections to HubSpot’s sales and service products. That consolidation reduces the amount of infrastructure a marketing team must assemble and maintain. + +HubSpot is less compelling when the main requirement is to let AI agents select models, call specialized tools, coordinate work across many systems, or operate within a self-hosted environment. A team can also keep HubSpot as its CRM and campaign system while adding Sim, Zapier, Make, n8n, or Gumloop as an orchestration layer. + +## Which HubSpot alternative is best for agentic marketing workflows? + +Sim, Marketo, Zapier, Make, n8n, and Gumloop each lead for a different interpretation of “HubSpot alternative,” with Sim leading when agentic execution is the deciding requirement. + +### Is Sim a good HubSpot alternative? + +Sim is a strong HubSpot alternative for teams that want AI agents to automate real work across an existing CRM, data warehouse, messaging system, and marketing toolset. + +Sim is the open-source AI workspace where teams build, deploy, and manage AI agents. Its visual builder supports model calls, tools, APIs, branching, reusable workflows, and human participation without forcing the marketing team to adopt one model provider. + +[Workspace BYOK keys work on every Sim Cloud plan](https://docs.sim.ai/platform/costs#bring-your-own-key-byok), while organization-level keys require Pro for Teams, Max for Teams, or Enterprise. Any self-hosted Sim deployment can connect to local models through Ollama, vLLM, LM Studio, or LiteLLM, as described in the [self-hosting documentation](https://docs.sim.ai/platform/self-hosting/docker). Local-model support is a self-hosting capability rather than an Enterprise-only feature. + +[Sim’s core is licensed under Apache 2.0](https://github.com/simstudioai/sim/blob/main/LICENSE). Enterprise features in `apps/sim/ee`, including SSO, SCIM, access control, audit logs, data retention, and credential groups, use the separate [Sim Enterprise License](https://github.com/simstudioai/sim/blob/main/apps/sim/ee/LICENSE); production use of that code requires an active Sim Enterprise subscription. + +Sim does not replace HubSpot’s native CRM, email marketing, landing-page, or campaign-attribution suite. It is a better fit when the team already has systems of record and needs an intelligent layer that can coordinate them. Teams comparing that architecture can also read [Marketing Automation Platform vs AI Agent Builder: Which Does Your Team Need?](https://www.sim.ai/library/marketing-automation-platform-vs-ai-agent-builder). + +**Best fit:** Technical and semi-technical teams building model-flexible agents across multiple marketing and business systems. + +### Is Adobe Marketo Engage a good HubSpot alternative? + +Adobe Marketo Engage is the strongest HubSpot alternative in this list for large organizations that need a full campaign-operations product rather than a general workflow builder. + +[Adobe Marketo Engage](https://business.adobe.com/products/marketo/pricing/) focuses on lead and account databases, segmentation, campaign automation, measurement, attribution, and enterprise marketing operations. Its depth can suit complex organizations with dedicated marketing operations teams and established CRM infrastructure. + +Marketo requires more implementation and administration than lightweight automation tools. Its AI capabilities support marketing use cases, but Marketo is not primarily a model-agnostic agent workspace for orchestrating arbitrary tools and business processes. + +**Best fit:** Enterprise marketing organizations that need sophisticated campaigns, governance, and lead operations. + +### Is Zapier a good HubSpot alternative? + +Zapier is the easiest HubSpot alternative for marketing teams that value broad SaaS connectivity and fast automation setup more than native CRM or campaign depth. + +[Zapier](https://zapier.com/ai) connects applications through automations and offers AI-oriented products for building workflows and agents. It is useful for lead routing, notifications, list synchronization, enrichment, content handoffs, and other tasks that cross common business applications. + +Zapier is not a full CRM or marketing campaign suite. Its primary advantage is accessibility: non-specialist teams can often implement common app-to-app automations quickly. + +**Best fit:** Small and midsize teams that want straightforward hosted automation across a broad SaaS stack. + +### Is Make a good HubSpot alternative? + +Make is a strong HubSpot alternative for teams that want visual control over branching, transformation, and multi-application automation. + +[Make](https://www.make.com/en/ai-agents) combines visual scenarios with integrations, data mapping, routers, and AI-agent capabilities. Marketing teams can use it to move and transform data among lead sources, CRMs, spreadsheets, messaging systems, content tools, and analytics platforms. + +Make provides more workflow-level control than a simple trigger-and-action tool, but it does not supply HubSpot’s native customer database or campaign suite. Complex scenarios can also require careful maintenance as schemas, credentials, and upstream applications change. + +**Best fit:** Operations teams that want detailed visual automation and data transformation across hosted applications. + +### Is n8n a good HubSpot alternative? + +n8n is a strong HubSpot alternative for technically capable teams that need self-hosted workflow automation with AI nodes and code-level extensibility. + +[n8n’s pricing page](https://n8n.io/pricing/) documents agents, AI nodes, integrations, and workflows, while its [self-hosting documentation](https://docs.n8n.io/deploy/host-n8n) covers customer-operated deployments. Teams can use n8n for lead enrichment, routing, CRM updates, content processing, alerts, and internal operations. + +n8n is source-available under the [Sustainable Use License](https://docs.n8n.io/privacy-and-security/sustainable-use-license), not open source under an OSI-approved license. Its self-hosting and extensibility are meaningful strengths, but buyers should review the license restrictions rather than treating n8n as equivalent to Apache 2.0 software. + +**Best fit:** Technical automation teams that prioritize self-hosting and general-purpose workflow extensibility. + +### Is Gumloop a good HubSpot alternative? + +Gumloop is a useful HubSpot alternative for browser-heavy AI workflows, research, extraction, and lightweight marketing operations. + +[Gumloop](https://www.gumloop.com/solutions/ai-web-scraping) provides AI-assisted web scraping and extraction workflows. It can support prospect research, enrichment, content preparation, web extraction, and repetitive browser tasks. + +Gumloop is not a native CRM or campaign-management suite. Its narrower focus can nevertheless make it attractive for teams that want to build AI-assisted web workflows quickly. + +**Best fit:** Growth and marketing teams focused on web research, extraction, enrichment, and browser automation. + +## How should you choose between a marketing suite and an AI agent platform? + +HubSpot buyers should choose a marketing suite when they need a system of record and choose an AI agent platform when they need an intelligent execution layer across existing systems. + +### Do you need to replace HubSpot’s CRM and campaign tools? + +HubSpot should be replaced by another marketing suite only when the buyer needs native contact management, segmentation, campaigns, attribution, and reporting in the replacement product. + +Marketo is the closest option in this comparison for sophisticated campaign operations, although it is not a drop-in copy of HubSpot. Sim, Zapier, Make, n8n, and Gumloop generally require a separate CRM or marketing database. + +### Do you need AI agents that work across multiple tools? + +Sim is the strongest choice in this comparison when AI agents must reason over context, call multiple tools, use different models, and involve people in consequential steps. + +This architecture is useful for account research, lead qualification, enrichment, content operations, campaign QA, approval routing, CRM hygiene, and performance summaries. [AI Agents for Marketing Automation: Building Agentic Workflows Beyond HubSpot and Zapier](https://www.sim.ai/library/ai-agents-for-marketing-automation) provides more examples. + +### Do you need broad model choice or local models? + +Sim offers the broadest model-control position in this comparison for teams combining cloud BYOK with local models on self-hosted infrastructure. + +Model choice matters when a team wants to route tasks by cost, latency, modality, privacy, or quality instead of relying on one embedded AI provider. Buyers should also evaluate observability, fallback behavior, data retention, and provider terms rather than comparing model lists alone. + +### Do you need a self-hosted deployment? + +Sim and n8n are the primary self-hosting candidates in this comparison, but Sim’s core Apache 2.0 license and n8n’s Sustainable Use License grant materially different rights. + +Self-hosting can improve infrastructure control, but it also transfers responsibility for upgrades, secrets, monitoring, backups, and availability to the operator. Sim’s local-model support works on any self-hosted deployment and does not require Sim Enterprise. + +### Do marketers need to build workflows without engineering support? + +Zapier is generally the easiest starting point for simple SaaS automations, while Sim, Make, Gumloop, and n8n provide increasing control for more specialized workflows. + +Ease depends on the workflow rather than the interface alone. A basic form-to-CRM automation is different from an agent that researches an account, evaluates evidence, drafts personalized content, requests approval, and updates several systems. + +### Do you need enterprise governance for AI agents? + +Sim and Marketo are the strongest governance candidates for their respective categories: Sim for governed AI-agent workspaces and Marketo for governed enterprise campaign operations. + +In Sim, enterprise capabilities such as SSO, SCIM, access control, audit logs, data retention, session policies, and credential groups are in `apps/sim/ee` under the [Sim Enterprise License](https://github.com/simstudioai/sim/blob/main/apps/sim/ee/LICENSE). Buyers should map governance requirements to the exact deployment and subscription rather than assume every feature is included in the core license. + +For a broader evaluation framework, use [What to Look for in an AI Workflow Automation Platform: Buyer’s Checklist](https://www.sim.ai/library/ai-workflow-automation-platform-buyers-checklist). + +## Can you use HubSpot with an AI agent platform instead of replacing it? + +HubSpot can remain the CRM and campaign system while Sim, Zapier, Make, n8n, or Gumloop coordinates agentic work around it. + +A complementary architecture is often lower risk than a complete migration. For example, an agent can collect account context, enrich a lead, classify intent, draft a recommendation, request human input, and then update HubSpot through an approved integration or API action. + +This approach preserves HubSpot’s customer records, campaign operations, and reporting while adding model choice and cross-tool execution. It also lets teams test agentic workflows before deciding whether any HubSpot hubs should be replaced. + +## How can you migrate from HubSpot without disrupting marketing operations? + +HubSpot teams can reduce migration risk by separating systems of record from automations and moving one bounded workflow at a time. + +1. **Inventory HubSpot responsibilities.** List CRM objects, forms, lists, campaigns, emails, landing pages, attribution reports, integrations, and automations currently in use. +2. **Classify each responsibility.** Mark each item as a system-of-record function, campaign function, deterministic automation, or agentic task. +3. **Choose the replacement architecture.** Use a marketing suite for native campaign functions and an agent or workflow platform for cross-tool execution. +4. **Start with a reversible workflow.** Lead research, enrichment, routing, internal summaries, and campaign QA are safer starting points than customer-facing sends. +5. **Add human control.** Require human input before high-impact actions such as changing lifecycle stages, sending external messages, or overwriting important CRM fields. +6. **Run systems in parallel.** Compare outputs, failure rates, latency, and operator effort before retiring the original process. +7. **Preserve auditability.** Record inputs, model outputs, tool actions, approvals, and final writes so the team can diagnose mistakes. +8. **Retire HubSpot functions selectively.** Remove a HubSpot dependency only after its replacement meets the required reliability, governance, and reporting standard. + +## What other AI automation comparisons should buyers read? + +Sim’s related guides separate marketing-suite, workflow-automation, and AI-agent intents so buyers can evaluate the right product category. + +- [What are the best marketing automation platforms for AI workflows in 2026?](https://www.sim.ai/library/best-marketing-automation-platforms-ai-workflows-2026) compares the broader marketing automation market. +- [Best AI Agent Platforms and Builders in 2026](https://www.sim.ai/library/best-ai-agent-platforms-2026) covers the broader AI-agent platform market. +- [8 Best Zapier Alternatives in 2026, Compared](https://www.sim.ai/library/best-zapier-alternatives) addresses Zapier replacement intent. +- [Best Gumloop Alternatives in 2026](https://www.sim.ai/library/best-gumloop-alternatives-in-2026) compares alternatives for AI-assisted workflow building. +- [10 Best n8n Alternatives for AI Agent Workflows in 2026](https://www.sim.ai/library/n8n-alternatives) covers self-hosted and agent-oriented n8n alternatives. diff --git a/apps/sim/public/library/best-hubspot-alternatives-ai-marketing-automation-2026/cover.jpg b/apps/sim/public/library/best-hubspot-alternatives-ai-marketing-automation-2026/cover.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0004acb9dede8b20298520b5237ffcaafdcfa90d GIT binary patch literal 28278 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%0D1eTL3 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 b^=bH9XBrm=M-HIz;{S67_APFI&sh9l{M3bh literal 0 HcmV?d00001 From 0bf92198ef6c0656ab58f910520c2d00d9bedcde Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Sat, 3 Oct 2026 12:26:37 -0700 Subject: [PATCH 07/12] feat(library): Slack AI Agent Security: Permissions, Data, and Audit Guide (#8600) Co-authored-by: Sim Pi Agent --- .../index.mdx | 368 ++++++++++++++++++ .../cover.jpg | Bin 0 -> 29916 bytes 2 files changed, 368 insertions(+) create mode 100644 apps/sim/content/library/slack-ai-agent-security-permissions-guide/index.mdx create mode 100644 apps/sim/public/library/slack-ai-agent-security-permissions-guide/cover.jpg diff --git a/apps/sim/content/library/slack-ai-agent-security-permissions-guide/index.mdx b/apps/sim/content/library/slack-ai-agent-security-permissions-guide/index.mdx new file mode 100644 index 00000000000..9289c179eec --- /dev/null +++ b/apps/sim/content/library/slack-ai-agent-security-permissions-guide/index.mdx @@ -0,0 +1,368 @@ +--- +slug: slack-ai-agent-security-permissions-guide +title: 'Slack AI Agent Security: Permissions, Data, and Audit Guide' +description: 'Secure a Slack AI agent with least-privilege OAuth scopes, controlled data access, protected credentials, approval gates, and complete audit evidence.' +date: 2026-10-03 +updated: 2026-10-03 +authors: + - andrew +readingTime: 15 +tags: [AI Agents, Security, Slack, Governance, Sim] +ogImage: /library/slack-ai-agent-security-permissions-guide/cover.jpg +draft: false +faq: + - q: "What permissions does a Slack AI agent need?" + a: "A Slack AI agent needs only the OAuth scopes, channel access, and downstream permissions required for its approved tasks. Teams should map every scope to a specific API method or event and remove any permission that is not exercised by an approved user journey." + - q: "Should a Slack AI agent have access to every channel?" + a: "A Slack AI agent should not have access to every channel. Teams should allowlist approved channels, deny sensitive channels by default, restrict who can invite the bot, and test direct-message and shared-channel behavior separately." + - q: "Can a Slack AI agent read private channels?" + a: "A Slack AI agent can read private-channel content only when its Slack authorization, scopes, and conversation access permit it. Teams should avoid private-channel scopes unless the use case requires them and should test the resulting access boundary directly." + - q: "How do you apply least privilege to a Slack bot?" + a: "A Slack bot applies least privilege by using a dedicated bot identity, minimal OAuth scopes, approved channel membership, narrow downstream credentials, allowlisted tools, and explicit limits on actions and data volume." + - q: "How should a Slack AI agent store OAuth tokens?" + a: "A Slack AI agent should store OAuth tokens in a managed secret system and expose them only to the runtime component that needs them. Tokens should be separated by environment, excluded from prompts and logs, rotated regularly, and revoked immediately after suspected exposure." + - q: "How do you verify that a request came from Slack?" + a: "A Slack integration verifies requests by checking Slack's signature and timestamp against the raw request body with the app's signing secret. The integration should reject invalid signatures and stale requests to reduce spoofing and replay risk." + - q: "Is a Slack signing secret the same as a bot token?" + a: "A Slack signing secret is not the same as a bot token. The signing secret verifies inbound requests from Slack, while the bot token authorizes API calls made by the app." + - q: "How long should a Slack AI agent retain messages?" + a: "A Slack AI agent should retain messages only for the shortest period required by its approved purpose, legal obligations, and incident-response needs. Teams should set separate retention periods for prompts, outputs, embeddings, tool results, debugging traces, and audit events." + - q: "Does Slack data retention delete data stored by an AI agent?" + a: "Slack data retention does not automatically delete copies stored by an AI agent, model provider, connected tool, log system, or backup. Each downstream system needs its own deletion and retention process." + - q: "How do you prevent a Slack AI agent from leaking sensitive data?" + a: "A Slack AI agent prevents sensitive-data leakage by minimizing retrieved content, redacting secrets before model calls, restricting egress destinations, separating channel permissions, validating tool calls, and requiring approval before sensitive disclosure." + - q: "How do you stop prompt injection in Slack?" + a: "A Slack AI agent limits prompt injection by treating messages, files, links, retrieved documents, and tool output as untrusted content. Deterministic authorization, tool allowlists, argument validation, data limits, and approval gates must prevent malicious text from granting itself authority." + - q: "Should a Slack AI agent be allowed to take external actions?" + a: "A Slack AI agent should take external actions only through narrowly scoped tools with independent authorization and validation. High-risk or irreversible actions should require explicit human approval before execution." + - q: "When does a Slack AI agent need human approval?" + a: "A Slack AI agent needs human approval when an action is difficult to reverse, affects an external party, changes access, transfers money, exposes sensitive information, or exceeds an organization's documented risk threshold." + - q: "What should an approver see before approving an AI agent action?" + a: "A Slack AI agent approval request should show the requester, proposed action, destination, relevant inputs, expected effect, and sensitive data involved. The approval record should preserve the approver, decision, timestamp, and exact authorized action." + - q: "What should be included in Slack AI agent audit logs?" + a: "Slack AI agent audit logs should include the requesting identity, workspace and conversation identifiers, agent version, model and tool configuration, policy results, sanitized tool calls, approvals, external effects, errors, and a shared correlation identifier." + - q: "Are Slack audit logs enough to audit an AI agent?" + a: "Slack audit logs are not enough to audit an AI agent because Slack does not provide the complete model, workflow, tool, approval, and downstream-system execution record. Teams need correlated evidence from Slack, the agent runtime, and every consequential external system." + - q: "Can Sim deploy a Slack slash-command trigger with the native Sim Slack app?" + a: "Sim cannot deploy a Slack slash-command trigger with the native Sim Slack app. A Sim slash-command trigger requires a custom Slack bot with its own signing secret." + - q: "How does human approval work in Sim?" + a: "Sim's Human in the Loop block pauses a run and resumes it with submitted form fields. A downstream Condition must inspect the approval field and route the workflow to the approved or rejected path." + - q: "Does Sim's Guardrails block automatically stop a Slack agent?" + a: "Sim's Guardrails block does not automatically stop a Slack agent because it reports only whether the check passed or failed. A downstream Condition must route on that result to stop, continue, or escalate the run." + - q: "Can Sim use local models for a self-hosted Slack agent?" + a: "Sim can use Ollama, vLLM, LM Studio, or LiteLLM-compatible local models on any self-hosted deployment. Local-model support is a self-hosting capability and does not require Sim Enterprise." + - q: "Is Sim open source?" + a: "Sim's core is open source under the OSI-approved Apache 2.0 license. Code in apps/sim/ee uses the separate Sim Enterprise License, and production use of those enterprise features requires an active Sim Enterprise subscription." + - q: "Is n8n open source?" + a: "n8n is source-available under the Sustainable Use License rather than an OSI-approved open-source license. Organizations can self-host n8n subject to that license's conditions and restrictions." + - q: "Is Sim or n8n better for a secure Slack AI agent?" + a: "Sim is the stronger choice when a team prioritizes an Apache 2.0 core, visual agent control, conditional approval paths, and optional enterprise governance features, while n8n remains a capable incumbent for teams already operating its workflow ecosystem. Security still depends on how either platform's Slack scopes, credentials, tools, approvals, and logs are configured." + - q: "What is the best AI agent platform for Slack?" + a: "Sim is a strong AI agent platform for Slack when teams need controlled multi-step workflows, human approval, self-hosting options, and explicit routing around model and tool decisions. Best AI Agents for Slack provides the focused product comparison, while Best AI Agent Platforms and Builders in 2026 covers the broader platform market." + - q: "What should be tested before a Slack AI agent goes live?" + a: "A Slack AI agent should be tested for unauthorized installation, excessive scopes, forbidden channel access, secret leakage, direct and indirect prompt injection, unsafe tool arguments, approval bypass, replayed requests, incomplete logs, revocation, and rollback." +--- + +## TL;DR + +A secure Slack AI agent uses least-privilege OAuth scopes, restricted installation and channel access, controlled data retention, protected credentials, approval gates for consequential actions, and end-to-end audit evidence. + +Slack agents operate inside conversations that may contain customer data, source code, credentials, legal discussions, personnel information, and instructions from people the agent was never designed to trust. Security therefore depends on more than the model: teams must control what the Slack app can read, what the agent can do, where data flows, and how every sensitive action is reviewed. + +As of October 2026, Slack documents these controls across its official guidance for [OAuth scopes](https://docs.slack.dev/reference/scopes/), [app management settings](https://slack.com/help/articles/222386767-Manage-app-approval-for-your-workspace), [request verification](https://docs.slack.dev/authentication/verifying-requests-from-slack), and the [Audit Logs API](https://docs.slack.dev/admins/audit-logs-api). + +## How do you secure an AI agent in Slack? + +A Slack AI agent is secured by treating Slack messages as untrusted input and independently restricting identity, permissions, data, tools, approvals, and audit records. + +A practical security model has six layers: + +1. **Identity:** Establish which Slack app, bot user, workspace, organization, and human initiated the request. +2. **Authorization:** Grant only the OAuth scopes, channel access, and downstream tool permissions required for the approved use case. +3. **Data protection:** Minimize message collection, redact sensitive values, define retention, and prevent unintended model or vendor exposure. +4. **Action control:** Separate read-only retrieval from consequential actions such as sending messages, modifying records, or executing code. +5. **Human oversight:** Require approval for actions whose financial, operational, legal, or security impact exceeds a defined threshold. +6. **Evidence:** Record who requested the action, what context the agent used, which tools ran, who approved it, and what changed. + +The strongest design assumes that a malicious instruction can reach the agent. The controls surrounding the model must keep that instruction from becoming an unauthorized action. + +## What should be included in a Slack AI agent threat model? + +A Slack AI agent threat model should cover unauthorized installation, excessive scopes, unintended channel access, data leakage, prompt injection, credential theft, unsafe tool calls, approval bypass, and incomplete audit evidence. + +| Threat | Example | Primary control | +|---|---|---| +| Unauthorized installation | A user installs an unreviewed bot in a production workspace | Admin approval and an approved-app policy | +| Excessive OAuth access | A support bot receives file or private-message access it does not need | Scope-by-scope justification and least privilege | +| Overbroad channel exposure | The bot is invited to executive, legal, or incident channels | Channel allowlists and restricted invitation rights | +| Sensitive-data disclosure | A message containing a secret is sent to a model or external API | Redaction, data classification, and egress controls | +| Prompt injection | A pasted document tells the agent to ignore policy and export data | Untrusted-content isolation and tool authorization | +| Credential compromise | A Slack token or API key appears in logs | Secret storage, log filtering, and token rotation | +| Unsafe external action | The agent changes a CRM record based on an untrusted message | Narrow tool permissions and human approval | +| Approval bypass | The requester approves their own high-risk action | Separation of duties and policy-enforced approvers | +| Missing forensic evidence | A destructive action cannot be tied to a person or run | Immutable, correlated audit records | + +Risk should be assessed per use case rather than per model. A question-answering bot that reads an approved knowledge base has a different risk profile from an agent that can issue refunds, deploy code, or alter access rights. + +## Which OAuth scopes should a Slack AI agent request? + +A Slack AI agent should request only the Slack OAuth scopes needed for named features, and every requested scope should have an owner, justification, and removal test. + +Slack uses [granular scopes](https://docs.slack.dev/reference/scopes/) to authorize API capabilities. Common examples include `app_mentions:read` for receiving mentions, `chat:write` for posting messages, `channels:history` for public-channel history, `groups:history` for private-channel history, `im:history` for direct-message history, `files:read` for files, and `commands` for slash commands. A scope should not be added merely because it might be useful later. + +Use this review process: + +1. Start with the exact user journeys the agent must support. +2. Map each journey to required Slack API methods and events. +3. Map those methods and events to the scopes in Slack's official documentation. +4. Remove scopes that are not exercised by an approved journey. +5. Test expected failures when a removed scope or inaccessible channel blocks an operation. +6. Repeat the review whenever the agent gains a tool, trigger, or new data source. + +Prefer bot-token scopes over user-token scopes when the agent should act as a distinct service identity. Slack documents that [bot tokens use granular permissions while user tokens act on behalf of users](https://docs.slack.dev/authentication/tokens). A user token can couple the agent's reach to a person's access and make attribution harder unless impersonation is an explicit, reviewed requirement. + +## How should Slack app installation be controlled? + +Slack app installation should be limited to approved administrators or an application-review process that verifies ownership, scopes, data flows, vendor access, and removal procedures. Slack workspace owners can [enable app approval and restrict apps](https://slack.com/help/articles/222386767-Manage-app-approval-for-your-workspace). + +An installation review should answer: + +- Who owns the app and handles security incidents? +- Is the app internally developed, vendor-managed, or distributed through the Slack Marketplace? +- Which workspaces may install it? +- Which OAuth scopes and event subscriptions does it request? +- Which external systems receive Slack data? +- Where are tokens and signing secrets stored? +- How can administrators revoke the installation quickly? +- Does reinstalling or changing scopes require renewed approval? + +Production and test installations should use separate credentials and workspaces where possible. Development tokens should not provide a path into production conversations, and production installations should not be used for ad hoc experiments. + +## How should channel access work for a Slack AI agent? + +A Slack AI agent should be allowed only in approved channels, with sensitive channels denied by default and direct-message behavior reviewed separately. + +OAuth scopes, token type, Slack conversation rules, and channel membership collectively determine what an app can access. Teams should test actual API behavior instead of assuming that bot membership alone defines the complete boundary. + +Use an explicit channel policy: + +- Maintain an allowlist for approved production channels. +- Deny legal, finance, executive, security-incident, credential-sharing, and personnel channels unless the use case specifically requires them. +- Restrict who may invite the app to additional channels. +- Decide whether direct messages and multi-person direct messages are supported. +- Re-evaluate access when a public channel becomes private or its purpose changes. +- Remove the app automatically when the owning team or use case is retired. + +For agents that summarize or search conversations, limit retrieval to the current request's authorized channel set. A user asking from one channel should not automatically gain retrieval access to every conversation visible to the bot. + +## How should a Slack AI agent handle sensitive data? + +A Slack AI agent should collect the minimum necessary message content, classify it before external processing, and retain it only for a documented period. + +Teams should document the full data path from Slack to the agent runtime, model provider, connected tools, logs, observability systems, backups, and support systems. The review should distinguish transient prompt context from stored transcripts and derived artifacts such as embeddings, summaries, or extracted fields. + +Recommended controls include: + +- Detect and redact credentials, tokens, private keys, payment data, and regulated identifiers before model calls. +- Exclude hidden metadata and full thread history unless the task requires them. +- Define separate retention periods for prompts, outputs, tool results, audit events, and debugging traces. +- Encrypt data in transit and at rest. +- Restrict production transcript access to authorized operational roles. +- Document the regions and subprocessors involved in storage or inference. +- Provide deletion procedures that cover primary stores, derived indexes, and backups. +- Disable training or secondary use of organizational data unless explicitly approved. + +Slack retention settings do not automatically delete copies held by an agent, model provider, or connected application. Each downstream copy needs its own retention and deletion control. + +## How should Slack bot tokens, signing secrets, and API keys be stored? + +Slack bot tokens, Slack signing secrets, model keys, and downstream API credentials should be stored in a managed secret system and injected only into the component that needs them. + +A Slack signing secret verifies that an inbound request came from Slack; it is not an API token and should not be reused as one. As of October 2026, Slack's official [request-verification guidance](https://docs.slack.dev/authentication/verifying-requests-from-slack) requires validating the signature and timestamp over the raw request body and rejecting stale requests to reduce replay risk. + +Apply these controls: + +- Never place credentials in prompts, workflow names, channel messages, source code, or ordinary logs. +- Give development, staging, and production separate credentials. +- Rotate credentials on a schedule and immediately after suspected exposure. +- Restrict secret read access independently from workflow-edit access. +- Filter headers, request bodies, and tool outputs before logging. +- Record secret references or versions rather than secret values. +- Revoke unused tokens when an app, employee, or integration is retired. + +Teams should track where credentials are introduced and used during execution so an incident review can identify every affected system. + +## How should a Slack AI agent control external actions? + +A Slack AI agent should authorize every external action against the requesting identity, approved use case, target resource, and action risk instead of trusting the model's decision alone. + +Read and write tools should use different credentials when possible. For example, a CRM lookup tool should not inherit permission to delete accounts, and a repository search tool should not inherit permission to merge code. + +Classify actions by impact: + +| Risk level | Example | Required control | +|---|---|---| +| Low | Search an approved knowledge base | Authenticated request and access check | +| Medium | Draft a Slack response or create a non-sensitive ticket | Preview, validation, and attributable logging | +| High | Send an external message, update a customer record, or trigger a deployment | Explicit human approval and narrow credentials | +| Critical | Transfer money, change access rights, delete production data, or expose secrets | Strong authentication, separation of duties, policy enforcement, and an independent execution boundary | + +Tool arguments should be validated against schemas and policy. The executor should reject unexpected destinations, identifiers, commands, file paths, and URLs even when the model produced syntactically valid output. + +## When should a Slack AI agent require human approval? + +A Slack AI agent should require human approval whenever an action is difficult to reverse, affects an external party, changes access, moves money, exposes sensitive data, or crosses a defined risk threshold. + +Approval must be meaningful rather than ceremonial. The approver should see the requester, proposed action, destination, relevant inputs, expected effect, and any sensitive data involved. Approval records should capture the approver's identity, decision, timestamp, and the exact action that was authorized. + +Sim's Human in the Loop block pauses a run and resumes it with submitted form fields. Approve or reject is represented as a field, so a downstream Condition must inspect that field before the workflow takes the approved or rejected path. The [human-in-the-loop guide](https://www.sim.ai/library/what-is-human-in-the-loop-in-ai-agents) explains the broader control pattern. + +Sim's Wait block should not be used as an approval mechanism because it resumes only after a set time and does not resume in response to an external event. Sim's Guardrails block reports whether a check passed or failed; a downstream Condition must route on that result if the workflow should stop or take a safer path. + +## What should Slack AI agent audit logs record? + +Slack AI agent audit logs should connect the Slack request, human identity, agent run, model decision, tool calls, approval decision, and external system result in one traceable record. + +At minimum, record: + +- Workspace, organization, channel, thread, and message identifiers where permitted. +- Slack user and bot identities. +- App installation and credential reference used. +- Agent and workflow version. +- Model and tool configuration version. +- Policy and guardrail results. +- Tool names, sanitized arguments, response status, and affected resource identifiers. +- Approval request, approver, decision, and timestamp. +- Final Slack response and external side effects. +- Errors, retries, cancellations, and timeouts. +- A correlation identifier shared across Slack, the agent runtime, and downstream systems. + +Avoid placing raw secrets or unnecessary message content in audit records. Logs must be useful for attribution and investigation without becoming a second uncontrolled copy of sensitive Slack data. The guide to [AI agent observability](https://www.sim.ai/library/ai-agent-observability) explains how traces, metrics, and evaluations complement this audit evidence. + +Slack's [Audit Logs API](https://docs.slack.dev/admins/audit-logs-api) provides supported workspace-level administrative events for Enterprise organizations, while the agent runtime's execution records must capture model, workflow, approval, and tool behavior. + +## How do you prevent prompt injection in a Slack AI agent? + +A Slack AI agent resists prompt injection by treating every message, attachment, link, retrieved document, and tool result as untrusted data that cannot grant itself authority. + +Prompt text alone is not a security boundary. Instructions such as “ignore previous rules,” “send the customer list here,” or “use this administrator token” must remain powerless unless independently allowed by identity, authorization, tool, and approval controls. + +Use layered defenses: + +- Keep system instructions separate from Slack content. +- Label retrieved and user-provided text as untrusted content. +- Prevent retrieved documents from changing tool permissions or approval rules. +- Allowlist tools, destinations, domains, and resource types. +- Validate tool arguments outside the model. +- Require fresh authorization for sensitive operations. +- Limit the amount of data a single request can retrieve or transmit. +- Detect instructions that request secrets, policy bypass, or data exfiltration. +- Route high-risk outcomes to human review. +- Test indirect attacks embedded in files, web pages, quoted messages, and tool output. + +A guardrail can improve detection, but authorization must still be enforced by deterministic code outside the model. + +## How does Sim support secure Slack AI agents? + +Sim supports secure Slack agent design through visual workflow control, conditional routing, human review, self-hosting options, and enterprise governance capabilities. + +Sim is the open-source AI workspace where teams build, deploy, and manage AI agents. Sim's core is licensed under Apache 2.0, while code in `apps/sim/ee`—including SSO, SCIM, access control, access requests, audit logs, data retention, data drains, session policies, and credential groups—is covered by the separate [Sim Enterprise License](https://github.com/simstudioai/sim/blob/main/apps/sim/ee/LICENSE). Production use of that enterprise code requires an active Sim Enterprise subscription. + +Any self-hosted Sim deployment can use Ollama, vLLM, LM Studio, or LiteLLM-compatible local models through the documented [self-hosting environment settings](https://docs.sim.ai/platform/self-hosting/environment-variables); local-model support does not require Sim Enterprise. [Workspace BYOK keys work on every Sim Cloud plan](https://docs.sim.ai/platform/costs), while organization-level keys require Pro for Teams, Max for Teams, or Enterprise as of October 2026. + +For Slack slash commands, Sim requires a custom Slack bot with its own signing secret because the native Sim Slack app cannot deploy slash-command triggers. Teams should verify Slack signatures at the request boundary and apply the same scope, channel, and installation controls described in this guide. + +The implementation guide [How do you build an AI Slackbot without code?](https://www.sim.ai/library/how-to-build-ai-slackbot-without-code) covers construction, while [Best AI Agents for Slack](https://www.sim.ai/library/best-ai-agents-for-slack) covers product-selection intent. This guide owns the security and permissions review that should happen before deployment. + +## How does n8n fit into Slack agent security reviews? + +n8n remains an important incumbent for Slack automation through its documented [Slack node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.slack), but an n8n Slack workflow still requires independent review of scopes, credentials, data flows, tool permissions, approvals, and audit evidence. + +As of October 2026, n8n is self-hostable under its [Sustainable Use License](https://github.com/n8n-io/n8n/blob/master/LICENSE.md), a source-available license that does not appear in the [OSI's approved-license list](https://opensource.org/licenses). Connecting a workflow to Slack does not determine whether a particular deployment follows least privilege. + +Technical buyers comparing the two should separate platform licensing from deployment security. Sim's core uses the OSI-approved Apache 2.0 license, with enterprise features under the separate Sim Enterprise License; n8n uses its fair-code Sustainable Use License. Either platform still needs an enforceable Slack security boundary. + +## What are the key platform facts for a Slack AI agent security review? + +Sim and n8n differ in licensing and governance packaging, but either platform must be configured around Slack's permission boundary and the organization's own action policies. + +- **Sim:** Sim's core is Apache 2.0 and can be self-hosted, `apps/sim/ee` uses the separate Sim Enterprise License, workspace BYOK is available on every Sim Cloud plan, and [hosted model usage carries approximately a 1.1x multiplier on provider cost](https://docs.sim.ai/platform/costs) as of October 2026. +- **n8n:** n8n is self-hostable under the source-available Sustainable Use License rather than an OSI-approved open-source license, and n8n Cloud describes usage in workflow executions on its [official pricing page](https://n8n.io/pricing/) as of October 2026. +- **Slack:** Slack is the identity, conversation, installation, and OAuth boundary for the agent, while model usage and agent-platform execution are billed and governed separately from Slack workspace access. + +Platform selection does not replace threat modeling. The deployment is secure only when the Slack app, agent runtime, models, credentials, tools, approvals, and logs form one enforceable control system. + +## What should be checked before deploying a Slack AI agent? + +A Slack AI agent should not enter production until its owner can demonstrate least privilege, bounded data handling, safe external actions, effective approvals, and complete auditability. + +### Slack AI agent deployment checklist + +**Ownership and purpose** + +- [ ] Name the business owner, technical owner, security reviewer, and incident contact. +- [ ] Document the approved tasks and explicitly prohibited tasks. +- [ ] Assign a review date and retirement condition. + +**Slack application** + +- [ ] Use a dedicated production Slack app and bot identity. +- [ ] Require administrator approval for installation and scope changes. +- [ ] Justify every OAuth scope against a named feature. +- [ ] Review event subscriptions, redirect URLs, and interactive endpoints. +- [ ] Verify Slack request signatures and reject stale requests. +- [ ] Document uninstall and emergency-revocation procedures. + +**Channels and users** + +- [ ] Define allowed workspaces and channels. +- [ ] Deny sensitive channels by default. +- [ ] Restrict who can invite or invoke the agent. +- [ ] Decide whether direct messages and shared channels are supported. +- [ ] Test access with authorized and unauthorized users. + +**Data handling** + +- [ ] Map data flows through models, tools, logs, indexes, and backups. +- [ ] Minimize thread history, files, and metadata sent downstream. +- [ ] Redact secrets and regulated data before model calls. +- [ ] Set retention and deletion periods for every stored copy. +- [ ] Review model-provider training, storage, and subprocessors. + +**Secrets and infrastructure** + +- [ ] Store Slack tokens, signing secrets, and API keys in a managed secret system. +- [ ] Separate development, staging, and production credentials. +- [ ] Limit secret access and redact logs. +- [ ] Test rotation and emergency revocation. +- [ ] Apply network egress restrictions where appropriate. + +**Tools and actions** + +- [ ] Separate read-only and write credentials. +- [ ] Allowlist tools, destinations, and resource types. +- [ ] Validate tool arguments outside the model. +- [ ] Define transaction, rate, and data-volume limits. +- [ ] Require human approval for high-risk actions. +- [ ] Prevent requesters from self-approving critical actions. + +**Prompt-injection resistance** + +- [ ] Treat messages, files, links, retrieved documents, and tool results as untrusted. +- [ ] Test direct and indirect prompt-injection attacks. +- [ ] Verify that content cannot expand scopes or tool permissions. +- [ ] Test attempts to extract system prompts, secrets, and cross-channel data. +- [ ] Confirm that guardrail failures route to a safe path. + +**Audit and operations** + +- [ ] Correlate Slack events with agent runs and downstream changes. +- [ ] Record workflow, model, policy, and tool versions. +- [ ] Record approvals without storing unnecessary sensitive content. +- [ ] Alert on denied actions, repeated failures, unusual volume, and scope changes. +- [ ] Test incident investigation, disablement, and rollback. +- [ ] Re-run the review after any new scope, model, tool, or data source is added. + +## Which related guides help teams evaluate and govern AI agents? + +Sim's related guides separate Slack implementation, human approval, observability, enterprise governance, and platform selection into focused buyer questions. For cross-team policy design, [Governing AI Agents Built by Different Teams in One Enterprise Workspace](https://www.sim.ai/library/govern-ai-agents-multiple-teams-enterprise-workspace) covers how shared controls apply across independently built agents. diff --git a/apps/sim/public/library/slack-ai-agent-security-permissions-guide/cover.jpg b/apps/sim/public/library/slack-ai-agent-security-permissions-guide/cover.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e8a93bda709c68633bdb30f292f2439210b70c76 GIT binary patch literal 29916 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 MaC?RRy<+A60naet;Q#;t literal 0 HcmV?d00001 From cbf68151b8f8d201aea0fca008725fc802985701 Mon Sep 17 00:00:00 2001 From: Waleed Date: Sat, 3 Oct 2026 14:15:41 -0700 Subject: [PATCH 08/12] fix(docs): cap search query length and time out the embedding call (#8601) * fix(docs): cap search query length and time out the embedding call * fix(docs): truncate long search queries instead of dropping them * fix(docs): truncate search queries on a code point boundary --- apps/docs/app/api/search/route.ts | 11 +++++++++-- apps/docs/lib/embeddings.ts | 3 +++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/docs/app/api/search/route.ts b/apps/docs/app/api/search/route.ts index 30915b87529..7ebf6d7ae4b 100644 --- a/apps/docs/app/api/search/route.ts +++ b/apps/docs/app/api/search/route.ts @@ -1,4 +1,5 @@ import { createLogger } from '@sim/logger' +import { truncateAtCodePoint } from '@sim/utils/string' import { sql } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { db, docsEmbeddings } from '@/lib/db' @@ -11,6 +12,8 @@ export const revalidate = 0 const DEFAULT_SEARCH_LIMIT = 10 const MAX_SEARCH_LIMIT = 20 +/** Bounds the paid embedding call per request; real searches are a few words. */ +const MAX_QUERY_LENGTH = 256 /** PostgreSQL text-search configuration for the docs' English content. */ const TS_CONFIG = 'english' @@ -28,7 +31,11 @@ function getSearchLimit(value: unknown): number { function getSearchParams(request: NextRequest) { const searchParams = request.nextUrl.searchParams return { - query: searchParams.get('query') || searchParams.get('q') || '', + query: truncateAtCodePoint( + searchParams.get('query') || searchParams.get('q') || '', + MAX_QUERY_LENGTH, + '' + ), limit: getSearchLimit(searchParams.get('limit')), } } @@ -38,7 +45,7 @@ export async function GET(request: NextRequest) { try { const { query, limit } = getSearchParams(request) - if (!query || query.trim().length === 0) { + if (query.trim().length === 0) { return NextResponse.json([]) } diff --git a/apps/docs/lib/embeddings.ts b/apps/docs/lib/embeddings.ts index c41a3f19899..67570bb7801 100644 --- a/apps/docs/lib/embeddings.ts +++ b/apps/docs/lib/embeddings.ts @@ -1,3 +1,5 @@ +const EMBEDDING_TIMEOUT_MS = 10_000 + /** * Generate embeddings for search queries using OpenAI API */ @@ -19,6 +21,7 @@ export async function generateSearchEmbedding(query: string): Promise model: 'text-embedding-3-small', encoding_format: 'float', }), + signal: AbortSignal.timeout(EMBEDDING_TIMEOUT_MS), }) if (!response.ok) { From 4c6be1037af98b3aa7ad631376a54eba128eb195 Mon Sep 17 00:00:00 2001 From: Waleed Date: Sat, 3 Oct 2026 14:16:01 -0700 Subject: [PATCH 09/12] fix(tools): check usage limits before running hosted-key tools via the API (#8602) * fix(tools): check usage limits before running hosted-key tools via the API * fix(tools): gate hosted-key calls whose key is an unresolved variable reference * fix(tools): exempt variable references that resolve to the caller's own key * fix(tools): resolve the key reference with the registry's own resolver * fix(tools): decide hosted-key admission on registry-resolved params --- apps/docs/openapi-v2-resources.json | 21 ++++- .../v2/tools/[toolId]/execute/route.test.ts | 11 +++ .../api/v2/tools/[toolId]/execute/route.ts | 25 +++++- .../lib/api/contracts/v2/openapi/resources.ts | 4 +- .../lib/api/mcp/generated/v2-operations.ts | 2 +- .../application/execute-tool.test.ts | 82 ++++++++++++++++++- .../application/execute-tool.ts | 74 ++++++++++++++++- 7 files changed, 207 insertions(+), 12 deletions(-) diff --git a/apps/docs/openapi-v2-resources.json b/apps/docs/openapi-v2-resources.json index 0792befdee4..7a7f2abfe73 100644 --- a/apps/docs/openapi-v2-resources.json +++ b/apps/docs/openapi-v2-resources.json @@ -4601,7 +4601,7 @@ "post": { "operationId": "executeTool", "summary": "Run Tool", - "description": "Run a built-in tool using published parameter IDs. Sim resolves `credentialId`, hosted keys, and whole-value `{{VAR_NAME}}` references for `user-only` parameters; other values pass through verbatim. Third-party refusal returns `200` with `status: \"failed\"`; the error envelope covers API failures. Hidden or missing tools return `404`; disallowed integrations return `403` with `error.details.code: INTEGRATION_NOT_ALLOWED`. Hosted-key use is billed to the workspace. Workspace API keys return `403`; use a personal API key or scoped OAuth token.\n\nOAuth scope: `api:write`.", + "description": "Run a built-in tool using published parameter IDs. Sim resolves `credentialId`, hosted keys, and whole-value `{{VAR_NAME}}` references for `user-only` parameters; other values pass through verbatim. Third-party refusal returns `200` with `status: \"failed\"`; the error envelope covers API failures. Hidden or missing tools return `404`; disallowed integrations return `403` with `error.details.code: INTEGRATION_NOT_ALLOWED`. Hosted-key use is billed to the workspace; a call that would use a hosted key from a workspace over its usage or billing limits returns `402`. Workspace API keys return `403`; use a personal API key or scoped OAuth token.\n\nOAuth scope: `api:write`.", "x-sim-operation": "tools.execute", "x-oauth-scope": "api:write", "tags": ["Catalog"], @@ -4658,6 +4658,9 @@ "401": { "$ref": "#/components/responses/Unauthorized" }, + "402": { + "$ref": "#/components/responses/UsageLimitExceeded" + }, "403": { "$ref": "#/components/responses/Forbidden" }, @@ -9192,6 +9195,22 @@ } } }, + "UsageLimitExceeded": { + "description": "The workspace has exceeded its usage or billing limits.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/V2Error" + }, + "example": { + "error": { + "code": "USAGE_LIMIT_EXCEEDED", + "message": "Usage limit exceeded. Please upgrade your plan to continue." + } + } + } + } + }, "Forbidden": { "description": "The caller lacks the rights this operation requires. When the cause is one a caller can act on, `error.details.code` names it. A resource in a workspace the caller cannot reach at all answers `404` instead, so absence and denial are indistinguishable.", "content": { diff --git a/apps/sim/app/api/v2/tools/[toolId]/execute/route.test.ts b/apps/sim/app/api/v2/tools/[toolId]/execute/route.test.ts index c3cd3203b75..60babfe6faf 100644 --- a/apps/sim/app/api/v2/tools/[toolId]/execute/route.test.ts +++ b/apps/sim/app/api/v2/tools/[toolId]/execute/route.test.ts @@ -14,8 +14,10 @@ vi.mock('@/lib/api/server/routes/v2-api-key-auth', () => v2ApiKeyAuthModuleMock) vi.mock('@/lib/core/rate-limiter', () => v2RateLimiterModuleMock) vi.mock('@/lib/tool-execution/application/execute-tool', () => ({ executeToolForCaller: { operation: { id: 'tools.execute' }, execute: mocks.execute }, + ToolUsageLimitExceededError: class ToolUsageLimitExceededError extends Error {}, })) +import { ToolUsageLimitExceededError } from '@/lib/tool-execution/application/execute-tool' import { POST } from '@/app/api/v2/tools/[toolId]/execute/route' const WORKSPACE_ID = '11111111-2222-4333-8444-555555555555' @@ -76,6 +78,15 @@ describe('POST /api/v2/tools/{toolId}/execute', () => { expect(body.data.error.message).toBe('Firecrawl returned 402') }) + it('answers 402 when the workspace is over its usage limit', async () => { + mocks.execute.mockRejectedValue(new ToolUsageLimitExceededError('Usage limit exceeded')) + + const response = await post({ workspaceId: WORKSPACE_ID }) + + expect(response.status).toBe(402) + expect((await response.json()).error.code).toBe('USAGE_LIMIT_EXCEEDED') + }) + it('rejects a timeout beyond the ceiling', async () => { const response = await post({ workspaceId: WORKSPACE_ID, timeoutSeconds: 100_000 }) diff --git a/apps/sim/app/api/v2/tools/[toolId]/execute/route.ts b/apps/sim/app/api/v2/tools/[toolId]/execute/route.ts index 596661dd70d..84db16e37a8 100644 --- a/apps/sim/app/api/v2/tools/[toolId]/execute/route.ts +++ b/apps/sim/app/api/v2/tools/[toolId]/execute/route.ts @@ -1,12 +1,31 @@ import { v2ExecuteToolContract } from '@/lib/api/contracts/v2/catalog' -import { defineV2JsonRoute, v2ApiKeyAuth, v2RateLimits } from '@/lib/api/server/routes' -import { executeToolForCaller } from '@/lib/tool-execution/application/execute-tool' +import { + defineV2JsonRoute, + type V2ErrorPolicy, + v2ApiKeyAuth, + v2RateLimits, +} from '@/lib/api/server/routes' +import { + executeToolForCaller, + ToolUsageLimitExceededError, +} from '@/lib/tool-execution/application/execute-tool' import { toolExecutionOperations } from '@/lib/tool-execution/application/operations' import { catalogErrorPolicy } from '@/app/api/v2/lib/catalog' +import { v2Error } from '@/app/api/v2/lib/response' export const dynamic = 'force-dynamic' export const revalidate = 0 +/** {@link catalogErrorPolicy} plus the `402` a hosted-key call over its usage limit raises. */ +const executeToolErrorPolicy = { + render(error) { + if (error instanceof ToolUsageLimitExceededError) { + return v2Error('USAGE_LIMIT_EXCEEDED', error.message) + } + return catalogErrorPolicy.render(error) + }, +} satisfies V2ErrorPolicy + /** * POST /api/v2/tools/{toolId}/execute — Run one built-in tool. * @@ -20,7 +39,7 @@ export const POST = defineV2JsonRoute({ operation: toolExecutionOperations.execute, auth: v2ApiKeyAuth, rateLimit: v2RateLimits.publicApi, - errorPolicy: catalogErrorPolicy, + errorPolicy: executeToolErrorPolicy, mapInput: ({ params, body }) => ({ workspaceId: body.workspaceId, toolId: params.toolId, diff --git a/apps/sim/lib/api/contracts/v2/openapi/resources.ts b/apps/sim/lib/api/contracts/v2/openapi/resources.ts index 94863b337b1..a3eb1ed67d6 100644 --- a/apps/sim/lib/api/contracts/v2/openapi/resources.ts +++ b/apps/sim/lib/api/contracts/v2/openapi/resources.ts @@ -2100,8 +2100,8 @@ const declaredRoutes = [ applicationOperation: toolExecutionOperations.execute, operationId: 'executeTool', summary: 'Run Tool', - description: `Run a built-in tool using published parameter IDs. Sim resolves \`credentialId\`, hosted keys, and whole-value \`{{VAR_NAME}}\` references for \`user-only\` parameters; other values pass through verbatim. Third-party refusal returns \`200\` with \`status: "failed"\`; the error envelope covers API failures. Hidden or missing tools return \`404\`; disallowed integrations return \`403\` with \`error.details.code: INTEGRATION_NOT_ALLOWED\`. Hosted-key use is billed to the workspace. ${WORKSPACE_API_KEY_DENIED}`, - errors: RESOURCE_ERRORS, + description: `Run a built-in tool using published parameter IDs. Sim resolves \`credentialId\`, hosted keys, and whole-value \`{{VAR_NAME}}\` references for \`user-only\` parameters; other values pass through verbatim. Third-party refusal returns \`200\` with \`status: "failed"\`; the error envelope covers API failures. Hidden or missing tools return \`404\`; disallowed integrations return \`403\` with \`error.details.code: INTEGRATION_NOT_ALLOWED\`. Hosted-key use is billed to the workspace; a call that would use a hosted key from a workspace over its usage or billing limits returns \`402\`. ${WORKSPACE_API_KEY_DENIED}`, + errors: [...RESOURCE_ERRORS, 'UsageLimitExceeded'], success: { description: 'The outcome of the tool call.' }, }), { diff --git a/apps/sim/lib/api/mcp/generated/v2-operations.ts b/apps/sim/lib/api/mcp/generated/v2-operations.ts index 835996006bf..5b9968a28eb 100644 --- a/apps/sim/lib/api/mcp/generated/v2-operations.ts +++ b/apps/sim/lib/api/mcp/generated/v2-operations.ts @@ -1162,7 +1162,7 @@ export const V2_MCP_OPERATIONS = { contract: v2ExecuteToolContract, summary: 'Run Tool', description: - 'Run a built-in tool using published parameter IDs. Sim resolves `credentialId`, hosted keys, and whole-value `{{VAR_NAME}}` references for `user-only` parameters; other values pass through verbatim. Third-party refusal returns `200` with `status: "failed"`; the error envelope covers API failures. Hidden or missing tools return `404`; disallowed integrations return `403` with `error.details.code: INTEGRATION_NOT_ALLOWED`. Hosted-key use is billed to the workspace. Workspace API keys return `403`; use a personal API key or scoped OAuth token.\n\nOAuth scope: `api:write`.', + 'Run a built-in tool using published parameter IDs. Sim resolves `credentialId`, hosted keys, and whole-value `{{VAR_NAME}}` references for `user-only` parameters; other values pass through verbatim. Third-party refusal returns `200` with `status: "failed"`; the error envelope covers API failures. Hidden or missing tools return `404`; disallowed integrations return `403` with `error.details.code: INTEGRATION_NOT_ALLOWED`. Hosted-key use is billed to the workspace; a call that would use a hosted key from a workspace over its usage or billing limits returns `402`. Workspace API keys return `403`; use a personal API key or scoped OAuth token.\n\nOAuth scope: `api:write`.', workspaceKeyUnsupported: true, handler: () => import('@/app/api/v2/tools/[toolId]/execute/route').then((route) => route.POST), }, diff --git a/apps/sim/lib/tool-execution/application/execute-tool.test.ts b/apps/sim/lib/tool-execution/application/execute-tool.test.ts index 3480be2712a..fc13882fb25 100644 --- a/apps/sim/lib/tool-execution/application/execute-tool.test.ts +++ b/apps/sim/lib/tool-execution/application/execute-tool.test.ts @@ -9,6 +9,10 @@ import { billingAttributionMock, billingAttributionMockFns, } from '@sim/testing/mocks/billing-attribution.mock' +import { + billingUsageGateCacheMock, + billingUsageGateCacheMockFns, +} from '@sim/testing/mocks/billing-usage-gate-cache.mock' import { billingUsageLogMock, billingUsageLogMockFns, @@ -22,6 +26,7 @@ import { customBlockOperationsMockFns, } from '@sim/testing/mocks/custom-block-operations.mock' import { resetEnvFlagsMock, setEnvFlags } from '@sim/testing/mocks/env-flags.mock' +import { environmentUtilsMockFns } from '@sim/testing/mocks/environment-utils.mock' import { integrationsAvailabilityMock, integrationsAvailabilityMockFns, @@ -87,11 +92,16 @@ vi.mock('@/lib/internal/file/operations', () => ({ vi.mock('@/lib/billing/core/billing-attribution', () => billingAttributionMock) +vi.mock('@/lib/billing/core/usage-gate-cache', () => billingUsageGateCacheMock) + vi.mock('@/lib/billing/core/usage-log', () => billingUsageLogMock) import { executeFileTool } from '@/lib/internal/file/execute-tool' import type { InternalToolOperationContext } from '@/lib/internal/tool-operations/types' -import { executeToolForCaller } from '@/lib/tool-execution/application/execute-tool' +import { + executeToolForCaller, + ToolUsageLimitExceededError, +} from '@/lib/tool-execution/application/execute-tool' import { getAllBlocks, getBlock, getBlockMeta } from '@/blocks/registry' import type { BlockConfig } from '@/blocks/types' import { fileReadTool } from '@/tools/file/get' @@ -116,6 +126,18 @@ const TOOL_METADATA: Record> = { }, hosting: { apiKeyParam: 'apiKey' }, }, + image_generate: { + id: 'image_generate', + name: 'Image Generate', + params: { + provider: { type: 'string', required: true, visibility: 'user-only' }, + apiKey: { type: 'string', required: true, visibility: 'user-only' }, + }, + hosting: { + apiKeyParam: 'apiKey', + enabled: (params: { provider?: unknown }) => params.provider === 'falai', + }, + }, snowflake_execute_sql: { id: 'snowflake_execute_sql', name: 'Snowflake Execute SQL', @@ -156,6 +178,7 @@ const mocks = { getAllBlocks: vi.mocked(getAllBlocks), executeRegistryTool: toolsMockFns.mockExecuteTool, resolveBillingAttribution: billingAttributionMockFns.mockResolveBillingAttribution, + checkUsageLimits: billingUsageGateCacheMockFns.mockCheckExecutionUsageLimits, } vi.mocked(getBlock).mockReturnValue(undefined as never) @@ -193,6 +216,7 @@ function block(overrides: Partial & { type: string }): BlockConfig const fileBlock = block({ type: 'file_v5', tools: { access: ['file_read'] } }) const slackBlock = block({ type: 'slack', tools: { access: ['slack_message'] } }) const firecrawlBlock = block({ type: 'firecrawl', tools: { access: ['firecrawl_scrape'] } }) +const imageBlock = block({ type: 'image_generator', tools: { access: ['image_generate'] } }) const previewBlock = block({ type: 'preview_thing', preview: true, @@ -234,6 +258,7 @@ describe('executeToolForCaller', () => { fileBlock, slackBlock, firecrawlBlock, + imageBlock, previewBlock, confluenceBlock, zendeskBlock, @@ -242,6 +267,8 @@ describe('executeToolForCaller', () => { ]) mocks.executeRegistryTool.mockResolvedValue({ success: true, output: { markdown: '# Hi' } }) mocks.resolveBillingAttribution.mockResolvedValue({ workspaceId: WORKSPACE_ID }) + mocks.checkUsageLimits.mockResolvedValue({ isExceeded: false }) + environmentUtilsMockFns.mockGetEffectiveDecryptedEnv.mockResolvedValue({}) }) it.each([principal, createSessionPrincipal()])( @@ -498,6 +525,59 @@ describe('executeToolForCaller', () => { expect(mocks.recordUsage).not.toHaveBeenCalled() }) + const referencedImageCall = { + toolId: 'image_generate', + input: { provider: '{{IMAGE_PROVIDER}}', apiKey: '{{IMAGE_KEY}}' }, + } + + it.each<[string, Parameters[0], Record]>([ + ['the key is omitted', { input: { url: 'https://a.co' } }, {}], + [ + 'the key references an empty variable', + { input: { url: 'https://a.co', apiKey: '{{FIRECRAWL_KEY}}' } }, + { FIRECRAWL_KEY: ' ' }, + ], + [ + 'a reference selects the hosted provider', + referencedImageCall, + { IMAGE_PROVIDER: 'falai', IMAGE_KEY: '' }, + ], + ])('refuses a hosted-key call over the usage limit when %s', async (_case, input, env) => { + mocks.checkUsageLimits.mockResolvedValue({ isExceeded: true, message: 'Usage limit exceeded' }) + environmentUtilsMockFns.mockGetEffectiveDecryptedEnv.mockResolvedValue(env) + + await expect(run(input)).rejects.toBeInstanceOf(ToolUsageLimitExceededError) + }) + + it.each<[string, Parameters[0], Record]>([ + ['the caller brings their own key', { input: { url: 'https://a.co', apiKey: 'sk-own' } }, {}], + [ + 'the caller references a variable holding their own key', + { input: { url: 'https://a.co', apiKey: '{{FIRECRAWL_KEY}}' } }, + { FIRECRAWL_KEY: 'fc-own' }, + ], + [ + 'the reference pads the variable name', + { input: { url: 'https://a.co', apiKey: '{{ FIRECRAWL_KEY }}' } }, + { FIRECRAWL_KEY: 'fc-own' }, + ], + [ + 'a reference selects a provider Sim does not host', + referencedImageCall, + { IMAGE_PROVIDER: 'openai', IMAGE_KEY: '' }, + ], + [ + 'the tool has no hosted key', + { toolId: 'zendesk_get_ticket', input: { ticketId: '4', subdomain: 'a', apiToken: 't' } }, + {}, + ], + ])('does not gate on usage when %s', async (_case, input, env) => { + mocks.checkUsageLimits.mockResolvedValue({ isExceeded: true, message: 'Usage limit exceeded' }) + environmentUtilsMockFns.mockGetEffectiveDecryptedEnv.mockResolvedValue(env) + + await expect(run(input)).resolves.toMatchObject({ status: 'succeeded' }) + }) + /** * The provider already ran and already charged Sim's key, so losing the * ledger row must not also lose the caller's result. diff --git a/apps/sim/lib/tool-execution/application/execute-tool.ts b/apps/sim/lib/tool-execution/application/execute-tool.ts index ec4969336a0..9612a06e772 100644 --- a/apps/sim/lib/tool-execution/application/execute-tool.ts +++ b/apps/sim/lib/tool-execution/application/execute-tool.ts @@ -2,6 +2,7 @@ import { createLogger } from '@sim/logger' import { getErrorMessage } from '@sim/utils/errors' import { generateId } from '@sim/utils/id' import { resolveBillingAttribution, toBillingContext } from '@/lib/billing/core/billing-attribution' +import { checkExecutionUsageLimits } from '@/lib/billing/core/usage-gate-cache' import { recordUsage } from '@/lib/billing/core/usage-log' import { isBlockTypeAllowed, @@ -16,8 +17,11 @@ import { defineAuthorizedWorkspaceUseCase } from '@/lib/core/application' import { ForbiddenOperationError } from '@/lib/core/application/forbidden' import { isHosted } from '@/lib/core/config/env-flags' import { OrchestrationError } from '@/lib/core/orchestration/types' +import { getEffectiveDecryptedEnv } from '@/lib/environment/utils' import { principalUserId } from '@/lib/integrations/principal-scope.server' import { toolExecutionOperations } from '@/lib/tool-execution/application/operations' +import { isEnvVarReference } from '@/executor/constants' +import { resolveEnvVarReferences } from '@/executor/utils/reference-validation' import { executeTool as executeRegistryTool } from '@/tools' import type { ExecutableToolConfig } from '@/tools/types' import { getTool } from '@/tools/utils' @@ -34,6 +38,13 @@ export interface ExecuteToolInput { timeoutSeconds?: number } +export class ToolUsageLimitExceededError extends Error { + constructor(message: string) { + super(message) + this.name = 'ToolUsageLimitExceededError' + } +} + export interface ExecuteToolResult { toolId: string status: 'succeeded' | 'failed' @@ -49,10 +60,10 @@ export interface ExecuteToolResult { * deployment hosts keys, any `enabled` predicate accepts these params, and the * caller has not brought a key of their own — which wins where present. * - * Pre-dispatch only, for the required-input exemption: a parameter Sim will - * fill is not missing. It is deliberately NOT the metering gate — it cannot see - * a BYOK key, which the registry injects while reporting the call as *not* - * hosted, so after dispatch the registry's own verdict is read instead. + * Pre-dispatch only: the required-input exemption (a parameter Sim will fill is + * not missing) and usage admission. It is deliberately NOT the metering gate — + * it cannot see a BYOK key, which the registry injects while reporting the call + * as *not* hosted, so after dispatch the registry's own verdict is read instead. */ function hostedKeyParamFor( tool: ExecutableToolConfig, @@ -65,6 +76,42 @@ function hostedKeyParamFor( return tool.hosting.apiKeyParam } +/** + * `params` as the registry holds them when it decides on Sim's key. + * + * The registry resolves each whole-value `{{VAR}}` in a `user-only` parameter + * before `injectHostedKeyIfNeeded` runs, so a reference can supply the key, or + * the value an `enabled` predicate reads, and an empty variable leaves the key + * for Sim's to fill. Resolved the same way here — same environment, same + * options. A missing variable stays as written: the registry refuses the call + * on it before any key is spent. + */ +async function resolveUserOnlyReferences( + tool: ExecutableToolConfig, + params: Record, + userId: string, + workspaceId: string +): Promise> { + const referenced = Object.entries(tool.params ?? {}) + .filter(([name, declaration]) => { + const value = params[name] + return ( + declaration?.visibility === 'user-only' && + typeof value === 'string' && + isEnvVarReference(value) + ) + }) + .map(([name]) => name) + if (referenced.length === 0) return params + + const env = await getEffectiveDecryptedEnv(userId, workspaceId) + const resolved = { ...params } + for (const name of referenced) { + resolved[name] = resolveEnvVarReferences(params[name], env, { allowEmbedded: false }) + } + return resolved +} + /** * The three spellings the executor accepts for "which credential". * @@ -302,6 +349,25 @@ export const executeToolForCaller = defineAuthorizedWorkspaceUseCase({ workspaceId: context.workspaceId, }) + /** + * Admission before Sim's key is spent: metering runs only after the provider + * has charged it. A BYOK workspace is gated too, since only the registry can + * see that key — the same standing every workflow run is held to. + */ + if ( + hostedKeyParamFor( + tool, + await resolveUserOnlyReferences(tool, callerParams, userId, context.workspaceId) + ) + ) { + const usage = await checkExecutionUsageLimits(billingAttribution) + if (usage.isExceeded) { + throw new ToolUsageLimitExceededError( + usage.message || 'Usage limit exceeded. Please upgrade your plan to continue.' + ) + } + } + const params: Record = { ...callerParams, _context: { From f67222e3e734232849890a66c7ac2e3bb4952914 Mon Sep 17 00:00:00 2001 From: Waleed Date: Sat, 3 Oct 2026 14:16:17 -0700 Subject: [PATCH 10/12] fix(code-placeholders): skip heredoc bodies when scanning shell quote context (#8603) --- .../code-placeholders/compiler.test.ts | 37 +++++++++ .../lib/execution/code-placeholders/shell.ts | 77 +++++++++++++------ 2 files changed, 92 insertions(+), 22 deletions(-) diff --git a/apps/sim/lib/execution/code-placeholders/compiler.test.ts b/apps/sim/lib/execution/code-placeholders/compiler.test.ts index 65fe05ef593..ef5d2434060 100644 --- a/apps/sim/lib/execution/code-placeholders/compiler.test.ts +++ b/apps/sim/lib/execution/code-placeholders/compiler.test.ts @@ -885,6 +885,26 @@ describe('code placeholder compiler', () => { expect(executeShell(compiled.code, compiled.bindings)).toBe('\n') }) + it('keeps shell quote context after heredoc bodies with unbalanced quotes', async () => { + const compiled = await compileCodePlaceholders({ + code: [ + 'cat <\\n" "{{KEY}}"', + ].join('\n'), + language: CodeLanguage.Shell, + environmentVariables: { KEY: ' * ' }, + }) + + expect(executeShell(compiled.code, compiled.bindings)).toBe( + 'Today\'s report\na "quote\n< * >\n' + ) + }) + it('tracks nested shell command substitutions and their own quote contexts', async () => { const compiled = await compileCodePlaceholders({ code: [ @@ -1266,6 +1286,23 @@ describe('direct environment reads in shell', () => { expect(unquoted.resolvedSecretNames).toEqual(['API_KEY']) }) + it('reports reads after heredoc bodies with unbalanced quotes', async () => { + for (const header of ['cat < { const compiled = await compileCodePlaceholders({ code: 'echo "$PATH $HOME"', diff --git a/apps/sim/lib/execution/code-placeholders/shell.ts b/apps/sim/lib/execution/code-placeholders/shell.ts index 602c44215a8..e01139c64ca 100644 --- a/apps/sim/lib/execution/code-placeholders/shell.ts +++ b/apps/sim/lib/execution/code-placeholders/shell.ts @@ -439,12 +439,21 @@ function getUnsupportedShellPosition( return undefined } +function heredocBodyRanges(heredocs: HeredocDeclaration[]): Array<[number, number]> { + return heredocs.map((heredoc) => [heredoc.bodyStart, heredoc.removalEnd]) +} + +/** + * Jumps over `skippedRanges` (sorted heredoc bodies, which bash reads as data) so body prose + * cannot shift quote context; bodies that need contexts are scanned on their own with `literalRoot`. + */ function collectShellOccurrenceContexts( code: string, occurrences: CodePlaceholderOccurrence[], start: number, end: number, - literalRoot: boolean + literalRoot: boolean, + skippedRanges: Array<[number, number]> = [] ): Map { const occurrenceByStart = new Map( occurrences @@ -455,11 +464,24 @@ function collectShellOccurrenceContexts( const frames: ShellScanFrame[] = [ { kind: 'root', quote: 'none', parenthesisDepth: 0, literalRoot }, ] + let skippedRangeIndex = 0 for (let index = start; index < end; ) { const frame = frames.at(-1) if (!frame) break + while ( + skippedRangeIndex < skippedRanges.length && + skippedRanges[skippedRangeIndex][1] <= index + ) { + skippedRangeIndex += 1 + } + const skippedRange = skippedRanges.at(skippedRangeIndex) + if (skippedRange && index >= skippedRange[0]) { + index = skippedRange[1] + continue + } + const occurrence = occurrenceByStart.get(index) if (occurrence) { contexts.set(occurrence, { quote: frame.quote }) @@ -635,36 +657,46 @@ function recordShellDirectEnvironmentReads( } if (matches.length === 0) return - /** - * A heredoc with a quoted delimiter (`<<'EOF'`) is literal, so nothing in its body expands. - * The frame scanner below models quoting within a line, not heredoc bodies, so those are - * excluded up front — otherwise a `$NAME` printed verbatim would be reported as a read that - * never happened, and a usage trail must not claim uses that did not occur. - */ - const literalHeredocBodies = collectHeredocs(code) - .filter((heredoc) => heredoc.quoted) - .map((heredoc): [number, number] => [heredoc.bodyStart, heredoc.bodyEnd]) - - const candidates: CodePlaceholderOccurrence[] = [] - for (const candidate of matches) { - if (isOffsetInRanges(candidate.index, literalHeredocBodies)) continue - candidates.push({ + const candidates = matches.map( + (candidate): CodePlaceholderOccurrence => ({ start: candidate.index, end: candidate.index + candidate[0].length, raw: candidate[0], name: (candidate[1] ?? candidate[2]) as string, }) - } - if (candidates.length === 0) return + ) - const contexts = collectShellOccurrenceContexts(code, candidates, 0, code.length, false) + const heredocs = collectHeredocs(code) + const contexts = collectShellOccurrenceContexts( + code, + candidates, + 0, + code.length, + false, + heredocBodyRanges(heredocs) + ) + /** + * A heredoc with a quoted delimiter (`<<'EOF'`) is literal, so nothing in its body expands + * and its candidates stay contextless — a usage trail must not claim uses that did not occur. + */ + for (const heredoc of heredocs) { + if (heredoc.quoted) continue + const bodyContexts = collectShellOccurrenceContexts( + code, + candidates, + heredoc.bodyStart, + heredoc.bodyEnd, + true + ) + for (const [candidate, shellContext] of bodyContexts) contexts.set(candidate, shellContext) + } for (const candidate of candidates) { const shellContext = contexts.get(candidate) /** * No context means the scanner never reached this offset — it skipped the region as a - * comment. Absence is therefore evidence the expansion does not run, not permission to - * record it, so this reads as an allowlist rather than a denylist. Single quotes suppress - * expansion outright. + * comment or a quoted heredoc body. Absence is therefore evidence the expansion does not + * run, not permission to record it, so this reads as an allowlist rather than a denylist. + * Single quotes suppress expansion outright. */ if (!shellContext || shellContext.quote === 'single') continue context.recordDirectEnvironmentRead(candidate.name, candidate.start) @@ -828,7 +860,8 @@ export async function compileShellPlaceholders( rootOccurrences, 0, input.code.length, - false + false, + heredocBodyRanges(heredocs) ) for (const occurrence of rootOccurrences) { const occurrenceContext = rootContexts.get(occurrence) From 86fcaf6e23474ffc60f8fc6b1273990a747d04ae Mon Sep 17 00:00:00 2001 From: Waleed Date: Sat, 3 Oct 2026 14:16:43 -0700 Subject: [PATCH 11/12] fix(webhooks): check existing path owners before claiming on deploy (#8605) --- .../registration-store.integration.ts | 141 ++++++++++++++++++ .../lib/webhooks/registration-store.test.ts | 4 + apps/sim/lib/webhooks/registration-store.ts | 15 +- 3 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 apps/sim/lib/webhooks/registration-store.integration.ts diff --git a/apps/sim/lib/webhooks/registration-store.integration.ts b/apps/sim/lib/webhooks/registration-store.integration.ts new file mode 100644 index 00000000000..d46fa413659 --- /dev/null +++ b/apps/sim/lib/webhooks/registration-store.integration.ts @@ -0,0 +1,141 @@ +/** + * Stable webhook registration against real PostgreSQL: a deploy must not claim + * a path another workflow already serves through an unclaimed legacy row. + */ +import { db } from '@sim/db' +import { + user, + webhook, + webhookPathClaim, + workflow, + workflowDeploymentOperation, + workflowDeploymentVersion, + workspace, +} from '@sim/db/schema' +import { generateId } from '@sim/utils/id' +import { eq } from 'drizzle-orm' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { WebhookPathClaimConflictError } from '@/lib/webhooks/path-claims' +import { + prepareWebhookRegistrationIntents, + type WebhookRegistrationOperationFence, +} from '@/lib/webhooks/registration-store' + +const owner = `registration-store-owner-${generateId()}` +const workspaceId = generateId() +const victimWorkflow = generateId() +const deployingWorkflow = generateId() +const victimVersion = generateId() +const deployingVersion = generateId() +const legacyPath = `legacy-${generateId()}` +const freePath = `free-${generateId()}` + +const fence: WebhookRegistrationOperationFence = { + workflowId: deployingWorkflow, + operationId: generateId(), + generation: 1, + deploymentVersionId: deployingVersion, +} + +function desiredFor(path: string) { + return { + blockId: 'trigger', + provider: 'generic', + path, + routingKey: null, + providerConfig: {}, + configFingerprint: `fp-${path}`, + } +} + +beforeAll(async () => { + const now = new Date() + await db.insert(user).values({ + id: owner, + name: 'Registration Store', + email: `${owner}@registration-store.test`, + emailVerified: true, + createdAt: now, + updatedAt: now, + }) + await db.insert(workspace).values({ + id: workspaceId, + name: 'Registration Store', + ownerId: owner, + billedAccountUserId: owner, + }) + await db.insert(workflow).values( + [victimWorkflow, deployingWorkflow].map((id) => ({ + id, + userId: owner, + workspaceId, + name: id, + lastSynced: now, + createdAt: now, + updatedAt: now, + isDeployed: id === victimWorkflow, + })) + ) + const emptyState = { blocks: {}, edges: [], loops: {}, parallels: {} } + await db.insert(workflowDeploymentVersion).values([ + { + id: victimVersion, + workflowId: victimWorkflow, + version: 1, + isActive: true, + state: emptyState, + }, + { id: deployingVersion, workflowId: deployingWorkflow, version: 1, state: emptyState }, + ]) + await db.insert(webhook).values({ + id: generateId(), + workflowId: victimWorkflow, + deploymentVersionId: victimVersion, + blockId: 'trigger', + path: legacyPath, + provider: 'generic', + providerConfig: {}, + }) + await db.insert(workflowDeploymentOperation).values({ + id: fence.operationId, + workflowId: deployingWorkflow, + deploymentVersionId: deployingVersion, + version: 1, + action: 'deploy', + protocolVersion: 2, + generation: fence.generation, + status: 'preparing', + requestHash: generateId(), + actorId: owner, + }) +}) + +afterAll(async () => { + await db.delete(workspace).where(eq(workspace.id, workspaceId)) + await db.delete(user).where(eq(user.id, owner)) +}) + +async function claimOwner(path: string) { + const [claim] = await db + .select({ workflowId: webhookPathClaim.workflowId }) + .from(webhookPathClaim) + .where(eq(webhookPathClaim.path, path)) + return claim?.workflowId ?? null +} + +describe('prepareWebhookRegistrationIntents path ownership', () => { + it.each([legacyPath, `/${legacyPath}/`])( + 'refuses to claim %s while another workflow serves it unclaimed', + async (path) => { + await expect( + prepareWebhookRegistrationIntents({ fence, desired: [desiredFor(path)] }) + ).rejects.toBeInstanceOf(WebhookPathClaimConflictError) + expect(await claimOwner(legacyPath)).toBeNull() + } + ) + + it('claims a path no other workflow serves', async () => { + await prepareWebhookRegistrationIntents({ fence, desired: [desiredFor(freePath)] }) + expect(await claimOwner(freePath)).toBe(deployingWorkflow) + }) +}) diff --git a/apps/sim/lib/webhooks/registration-store.test.ts b/apps/sim/lib/webhooks/registration-store.test.ts index be5f1d84f31..fcd3cbadbc5 100644 --- a/apps/sim/lib/webhooks/registration-store.test.ts +++ b/apps/sim/lib/webhooks/registration-store.test.ts @@ -14,6 +14,10 @@ vi.mock('@/lib/webhooks/path-claims', () => ({ claimWebhookPath: mockClaimWebhookPath, })) +vi.mock('@/lib/webhooks/utils.server', () => ({ + findConflictingWebhookPathOwner: vi.fn().mockResolvedValue(null), +})) + vi.mock('@/lib/workflows/persistence/deployment-operations', () => ({ isDeploymentOperationCurrent: mockIsDeploymentOperationCurrent, setDeploymentTxTimeouts: vi.fn(), diff --git a/apps/sim/lib/webhooks/registration-store.ts b/apps/sim/lib/webhooks/registration-store.ts index eeeb1e350f6..78617e1f7b4 100644 --- a/apps/sim/lib/webhooks/registration-store.ts +++ b/apps/sim/lib/webhooks/registration-store.ts @@ -9,13 +9,14 @@ import { generateShortId } from '@sim/utils/id' import { isPlainRecord } from '@sim/utils/object' import type { DbOrTx } from '@sim/workflow-persistence/types' import { and, eq, exists, gt, inArray, isNull, lt, lte, notExists, sql } from 'drizzle-orm' -import { claimWebhookPath } from '@/lib/webhooks/path-claims' +import { claimWebhookPath, WebhookPathClaimConflictError } from '@/lib/webhooks/path-claims' import { projectDesiredWebhookProviderConfig } from '@/lib/webhooks/provider-subscriptions' import { fingerprintDesiredWebhookRegistration, normalizeWebhookRegistrationPath, } from '@/lib/webhooks/registration-identity' import { planWebhookRegistrationReconciliation } from '@/lib/webhooks/registration-reconciliation' +import { findConflictingWebhookPathOwner } from '@/lib/webhooks/utils.server' import type { DeploymentOperationStatus } from '@/lib/workflows/deployment-lifecycle' import { isDeploymentOperationCurrent, @@ -230,8 +231,18 @@ export async function prepareWebhookRegistrationIntents(input: { for (const desired of input.desired) { if (desired.path) { + // Unclaimed legacy rows of other workflows still own their path. + const path = normalizeWebhookRegistrationPath(desired.path) ?? desired.path + const conflictingOwner = await findConflictingWebhookPathOwner({ + path, + workflowId: input.fence.workflowId, + tx, + }) + if (conflictingOwner) { + throw new WebhookPathClaimConflictError(path, conflictingOwner) + } await claimWebhookPath(tx, { - path: desired.path, + path, workflowId: input.fence.workflowId, generation: input.fence.generation, }) From 825e7e76ac094479088dedf8917fef686cc0430f Mon Sep 17 00:00:00 2001 From: Waleed Date: Sat, 3 Oct 2026 14:16:57 -0700 Subject: [PATCH 12/12] fix(tools): reject dot path segments in tool request URLs (#8604) * fix(tools): reject dot path segments in tool request URLs * fix(tools): match URL parser boundary stripping in dot-segment check --- apps/sim/tools/request-transport.test.ts | 49 +++++++++++++++++++++++- apps/sim/tools/request-transport.ts | 2 + apps/sim/tools/url-path.ts | 26 +++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/apps/sim/tools/request-transport.test.ts b/apps/sim/tools/request-transport.test.ts index 49645c56935..0b27336edbd 100644 --- a/apps/sim/tools/request-transport.test.ts +++ b/apps/sim/tools/request-transport.test.ts @@ -32,6 +32,7 @@ const PROBE_FILE = { mimeType: 'text/plain', data: 'data:text/plain;base64,cHJvYmU=', } as const +const DOT_SEGMENT_ERROR = 'Tool request URL cannot contain "." or ".." path segments' const EXCEL_MIME_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' function createSchemaProbeParams( @@ -79,6 +80,12 @@ function isAbsoluteHttpUrl(url: string): boolean { } } +function hasDotDotPathSegment(url: string): boolean { + const pathStart = url.indexOf('/', url.indexOf('//') + 2) + if (pathStart === -1) return false + return url.slice(pathStart).split(/[?#]/)[0].split('/').includes('..') +} + function createRequestTool( url: string | ((params: Record) => string) ): ToolConfig { @@ -129,6 +136,40 @@ describe('external request transport', () => { ).toBe('https://example.com') }) + it.each([ + 'https://api.example.com/v0/inboxes/inbox_1/drafts/..', + 'https://api.example.com/v0/inboxes/inbox_1/drafts/../../../v0/inboxes/other', + 'https://api.example.com/v0/inboxes/inbox_1/drafts/.', + 'https://api.example.com/v0/inboxes/inbox_1/drafts/%2e%2E', + 'https://api.example.com/v0/inboxes/inbox_1/drafts/.%2e?force=true', + 'https://api.example.com/v0/inboxes/inbox_1/drafts/.\t.', + 'https://api.example.com/v0/inboxes/inbox_1\\drafts\\..', + 'https://api.example.com/v0/inboxes/inbox_1/drafts/..\u0001', + ' https://api.example.com/v0/inboxes/inbox_1/drafts/..\u0000 ', + ])('rejects a URL whose path resolves a dot segment: %s', (url) => { + expect(() => + prepareToolRequest( + createRequestTool(() => url), + {} + ) + ).toThrow(DOT_SEGMENT_ERROR) + }) + + it.each([ + 'https://my-app.vercel.app/v1/domains/example.com', + 'https://api.example.com/v1/files/..foo/foo../.env', + 'https://api.example.com/v1/search?path=../x#..', + 'https://api.example.com/', + 'https://api.example.com/v1/files/..\u00a0', + ])('allows dots that are not whole path segments: %s', (url) => { + expect( + prepareToolRequest( + createRequestTool(() => url), + {} + ).url + ).toBe(url) + }) + it.each([ ['http_request', requestTool, { url: '/api/auth/oauth/token', method: 'GET' }], ['webhook_request', webhookRequestTool, { url: '/api/auth/oauth/token', body: {} }], @@ -188,12 +229,16 @@ describe('dynamic external request registry invariant', () => { isAbsoluteHttpUrl(url), `${toolId} resolved ${url} outside the external HTTP transport` ).toBe(true) - expect(() => + const prepare = () => prepareToolRequest( createRequestTool(() => url), {} ) - ).not.toThrow() + if (hasDotDotPathSegment(url)) { + expect(prepare, `${toolId} dispatched ${url}`).toThrow(DOT_SEGMENT_ERROR) + } else { + expect(prepare, `${toolId} rejected ${url}`).not.toThrow() + } } if (observations.length === 0) continue diff --git a/apps/sim/tools/request-transport.ts b/apps/sim/tools/request-transport.ts index 9f52a09f4be..0dfb6543654 100644 --- a/apps/sim/tools/request-transport.ts +++ b/apps/sim/tools/request-transport.ts @@ -10,6 +10,7 @@ import { type ToolConfig, type ToolDefinition, } from '@/tools/types' +import { assertNoDotPathSegments } from '@/tools/url-path' const MODEL_INPUT_PROJECTION_ERROR_MESSAGE = 'Model input could not be safely projected' const PRIVATE_MODEL_INPUT_EXTERNAL_URL_ERROR_MESSAGE = @@ -232,6 +233,7 @@ function assertExternalRequestUrl(url: string): void { if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') { throw new Error(EXTERNAL_REQUEST_URL_ERROR_MESSAGE) } + assertNoDotPathSegments(url) } /** Materializes one external HTTP request after enforcing the model-input boundary. */ diff --git a/apps/sim/tools/url-path.ts b/apps/sim/tools/url-path.ts index 83ef707172f..08bf1663c18 100644 --- a/apps/sim/tools/url-path.ts +++ b/apps/sim/tools/url-path.ts @@ -186,3 +186,29 @@ export function safeUrlPathSegment(value: string | number | bigint, paramName: s return encodeSegment(trimmed, paramName) } + +/** Matches a scheme and authority, which end at the first `/`, `\`, `?`, or `#` in a special-scheme URL. */ +const SCHEME_AND_AUTHORITY = /^[a-z][a-z\d+.-]*:[\\/]*[^\\/?#]*/i + +/** + * Rejects a request URL whose path carries a dot segment the WHATWG parser + * would resolve away. Mirrors the parser: boundary C0 controls and spaces, + * then tabs and newlines, are stripped, `\` separates segments like `/`, and + * `%2e` counts as a dot. + * + * @throws If the path contains a `.` or `..` segment in any spelling. + */ +export function assertNoDotPathSegments(url: string): void { + const path = url + .replace(/^[\u0000-\u0020]+|[\u0000-\u0020]+$/g, '') + .replace(/[\t\n\r]/g, '') + .replace(SCHEME_AND_AUTHORITY, '') + .split(/[?#]/, 1)[0] + const hasDotSegment = path.split(/[\\/]/).some((segment) => { + const decoded = segment.replace(/%2e/gi, '.') + return decoded === '.' || decoded === '..' + }) + if (hasDotSegment) { + throw new Error('Tool request URL cannot contain "." or ".." path segments') + } +}