Skip to content

Commit cb7ba65

Browse files
committed
improvement(tools): widen the internal-route audit and fix its guidance path
The line-scoped matcher missed a builder whose body the formatter wrapped onto the next line. The audit now collapses each url builder before matching. Also points the diagnostic and docs at the primitive's actual module path.
1 parent 2c57ff7 commit cb7ba65

14 files changed

Lines changed: 51 additions & 31 deletions

File tree

.agents/skills/add-integration/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -873,7 +873,7 @@ export const {service}UploadTool: ToolConfig<Params, Response> = {
873873
},
874874
request: {
875875
// Internal route. A static string is a source literal, so the transport trusts it. When the
876-
// path is dynamic, use `internalRoute` from '@/tools/internal-route' instead of a template
876+
// path is dynamic, use `internalRoute` from '@/lib/core/utils/internal-route' instead of a template
877877
// string — a builder's plain `/api/...` string is treated as external, because a caller- or
878878
// model-supplied param can produce one:
879879
// url: (params) => internalRoute`/api/tools/{service}/upload/${params.folderId}`

.agents/skills/add-tools/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ can make any tool emit `/api/...` (the HTTP Request tool passes its `url` throug
157157
self-hosted integration with a blank host param collapses `${host}/api/v2/x` to `/api/v2/x`).
158158

159159
```typescript
160-
import { internalRoute } from '@/tools/internal-route'
160+
import { internalRoute } from '@/lib/core/utils/internal-route'
161161

162162
// ✓ Static route — a source literal no param can influence
163163
url: '/api/tools/{service}/{action}',

.agents/skills/validate-integration/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ For **every** tool file, check:
7474
### Request URL
7575
- [ ] A tool calling a third-party service returns an ABSOLUTE `https://...` URL
7676
- [ ] A tool calling Sim's own API declares it: a static `/api/...` string, or `internalRoute` from
77-
`@/tools/internal-route` when the path is dynamic (query params via `.withQuery({...})`)
77+
`@/lib/core/utils/internal-route` when the path is dynamic (query params via `.withQuery({...})`)
7878
- [ ] No builder returns a bare `` `/api/...` `` template string — that is treated as external and
7979
will fail, because a `user-or-llm` param can produce the same string
8080
- [ ] No `encodeURIComponent` inside an `internalRoute` template (the tag already encodes, so this

.claude/commands/add-integration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ export const {service}UploadTool: ToolConfig<Params, Response> = {
872872
},
873873
request: {
874874
// Internal route. A static string is a source literal, so the transport trusts it. When the
875-
// path is dynamic, use `internalRoute` from '@/tools/internal-route' instead of a template
875+
// path is dynamic, use `internalRoute` from '@/lib/core/utils/internal-route' instead of a template
876876
// string — a builder's plain `/api/...` string is treated as external, because a caller- or
877877
// model-supplied param can produce one:
878878
// url: (params) => internalRoute`/api/tools/{service}/upload/${params.folderId}`

.claude/commands/add-tools.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ can make any tool emit `/api/...` (the HTTP Request tool passes its `url` throug
156156
self-hosted integration with a blank host param collapses `${host}/api/v2/x` to `/api/v2/x`).
157157

158158
```typescript
159-
import { internalRoute } from '@/tools/internal-route'
159+
import { internalRoute } from '@/lib/core/utils/internal-route'
160160

161161
// ✓ Static route — a source literal no param can influence
162162
url: '/api/tools/{service}/{action}',

.claude/commands/validate-integration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ For **every** tool file, check:
7373
### Request URL
7474
- [ ] A tool calling a third-party service returns an ABSOLUTE `https://...` URL
7575
- [ ] A tool calling Sim's own API declares it: a static `/api/...` string, or `internalRoute` from
76-
`@/tools/internal-route` when the path is dynamic (query params via `.withQuery({...})`)
76+
`@/lib/core/utils/internal-route` when the path is dynamic (query params via `.withQuery({...})`)
7777
- [ ] No builder returns a bare `` `/api/...` `` template string — that is treated as external and
7878
will fail, because a `user-or-llm` param can produce the same string
7979
- [ ] No `encodeURIComponent` inside an `internalRoute` template (the tag already encodes, so this

.claude/rules/sim-integrations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ The full authoring instructions — tool/block/icon/trigger scaffolding, SubBloc
1414
## Hard rules (don't get these wrong)
1515

1616
- Tool IDs are `snake_case` (`service_action`). Register tools in `tools/registry.ts`, blocks in `blocks/registry-maps.ts` (the `BLOCK_REGISTRY` config map + `BLOCK_META_REGISTRY` catalog-meta map, alphabetically — `blocks/registry.ts` holds only the accessor functions), triggers in `triggers/registry.ts`.
17-
- A tool that calls Sim's own API declares it: a static `request.url` string (`'/api/tools/{service}/{action}'`), or `` internalRoute`/api/table/${params.tableId}/rows` `` from `@/tools/internal-route` when the path is dynamic (query params via `.withQuery({...})`). The transport signs internal requests with the executing user's token, so that decision follows the tool's source, never the resolved string — a builder returning a bare `/api/...` string is treated as EXTERNAL, because a `user-or-llm` param can produce one. `internalRoute` encodes every `${...}`; never add `encodeURIComponent` inside the template.
17+
- A tool that calls Sim's own API declares it: a static `request.url` string (`'/api/tools/{service}/{action}'`), or `` internalRoute`/api/table/${params.tableId}/rows` `` from `@/lib/core/utils/internal-route` when the path is dynamic (query params via `.withQuery({...})`). The transport signs internal requests with the executing user's token, so that decision follows the tool's source, never the resolved string — a builder returning a bare `/api/...` string is treated as EXTERNAL, because a `user-or-llm` param can produce one. `internalRoute` encodes every `${...}`; never add `encodeURIComponent` inside the template.
1818
- Type coercions (`Number()`, etc.) belong in `tools.config.params` (runs at execution, after variable resolution) — never in `tools.config.tool` (runs at serialization; coercing there destroys dynamic `<Block.output>` references).
1919
- `canonicalParamId` must NOT match any subblock's `id`, must be unique **block-wide** (groups are keyed by canonical id across every subblock and hold exactly one `basicId`, so two operations that each need a pair need two different canonical ids), and all subblocks in a canonical group must share the same `required` status. The `inputs` section and the params function reference canonical IDs, not raw subblock IDs — the serializer deletes the subblock IDs and republishes the active member's value under the canonical ID.
2020
- A canonical pair carries ONE concept. For files that is upload (basic) + file reference (advanced), as in Gmail attachments (`blocks/blocks/gmail.ts`). Never overload the advanced side with alternate identifiers (URL, provider asset ID) — give those their own subblocks, mark mutually exclusive sources `required: false`, and enforce "exactly one" at execution.

.cursor/commands/add-integration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ export const {service}UploadTool: ToolConfig<Params, Response> = {
867867
},
868868
request: {
869869
// Internal route. A static string is a source literal, so the transport trusts it. When the
870-
// path is dynamic, use `internalRoute` from '@/tools/internal-route' instead of a template
870+
// path is dynamic, use `internalRoute` from '@/lib/core/utils/internal-route' instead of a template
871871
// string — a builder's plain `/api/...` string is treated as external, because a caller- or
872872
// model-supplied param can produce one:
873873
// url: (params) => internalRoute`/api/tools/{service}/upload/${params.folderId}`

.cursor/commands/add-tools.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ can make any tool emit `/api/...` (the HTTP Request tool passes its `url` throug
151151
self-hosted integration with a blank host param collapses `${host}/api/v2/x` to `/api/v2/x`).
152152

153153
```typescript
154-
import { internalRoute } from '@/tools/internal-route'
154+
import { internalRoute } from '@/lib/core/utils/internal-route'
155155

156156
// ✓ Static route — a source literal no param can influence
157157
url: '/api/tools/{service}/{action}',

.cursor/commands/validate-integration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ For **every** tool file, check:
6868
### Request URL
6969
- [ ] A tool calling a third-party service returns an ABSOLUTE `https://...` URL
7070
- [ ] A tool calling Sim's own API declares it: a static `/api/...` string, or `internalRoute` from
71-
`@/tools/internal-route` when the path is dynamic (query params via `.withQuery({...})`)
71+
`@/lib/core/utils/internal-route` when the path is dynamic (query params via `.withQuery({...})`)
7272
- [ ] No builder returns a bare `` `/api/...` `` template string — that is treated as external and
7373
will fail, because a `user-or-llm` param can produce the same string
7474
- [ ] No `encodeURIComponent` inside an `internalRoute` template (the tag already encodes, so this

0 commit comments

Comments
 (0)