Context and motivation
The codebase has accumulated deviations from our target const/type conventions:
- Same-file first, feature-folder second, root shared only for cross-cutting symbols
type over interface
as const objects over TypeScript enum
- enumeration
as const objects and their same-named type in uppercase SNAKE_CASE
Current state:
src/const.ts (217 lines, 50+ exports) mixes unrelated domains — cache config, Skyfire payment strings, telemetry params, actor limits — many used by only 1–2 files
src/types.ts (698 lines, 47 exports) contains 3 dead exports, 6 single-consumer types, and pricing types only used in src/utils/pricing_info.ts
src/web/src/types.ts uses interface where type is the convention
HelperTools is a TypeScript enum (123 imports across 35+ files) — convention says as const
ServerMode (src/types.ts) is already an as const object but is PascalCase — the enumeration convention wants uppercase SNAKE_CASE (SERVER_MODE)
Scope
In scope
- Remove dead/unused exports from
src/types.ts and src/const.ts
- Move single-consumer constants from root
src/const.ts to their consuming files
- Move single-consumer types from root
src/types.ts to their consuming files
- Move Skyfire constants to
src/payments/const.ts
- Convert
interface to type in src/web/src/types.ts
- Convert
HelperTools enum to as const object
- Rename the
ServerMode enumeration object + type to SERVER_MODE (SNAKE_CASE)
Out of scope
- Broad mechanical rewrites of existing code
- Moving cross-cutting types/constants that are genuinely shared (10+ consumers)
- Refactoring
src/types.ts types that have complex dependency chains (e.g., ActorDefinitionWithDesc — used by ActorDefinitionPruned via Pick<>)
- Changes to
src/payments/types.ts (already well-organized)
Phased plan
Each phase is an independent PR. Phases 1, 2, 5 can run in parallel.
Phase 1 (dead code) ─┬─→ Phase 3 (localize types)
└─→ Phase 4 (Skyfire constants)
Phase 2 (localize consts) (independent)
Phase 5 (interface→type) (independent)
Phase 6 (HelperTools enum) (after Phases 1–4)
Phase 7 (ServerMode naming) (independent)
Sub-issues
Phase 1: Remove dead exports
| File |
Change |
src/types.ts |
Un-export PricingTier and TieredEventPrice — inline into ActorChargeEvent field type |
src/const.ts |
Remove export from SKYFIRE_MIN_CHARGE_USD and SKYFIRE_SELLER_ID (0 external imports) |
Phase 2: Localize single-consumer constants
Move constants from src/const.ts to their sole consumer:
| Constant(s) |
Move to |
ACTOR_CACHE_MAX_SIZE, ACTOR_CACHE_TTL_SECS, APIFY_DOCS_CACHE_MAX_SIZE, APIFY_DOCS_CACHE_TTL_SECS, MCP_SERVER_CACHE_MAX_SIZE, MCP_SERVER_CACHE_TTL_SECS |
src/state.ts |
USER_CACHE_MAX_SIZE, USER_CACHE_TTL_SECS |
src/utils/userid_cache.ts |
MCP_STREAMABLE_ENDPOINT |
src/mcp/const.ts |
ACTOR_SEARCH_ABOVE_LIMIT |
src/utils/actor_search.ts |
PROGRESS_NOTIFICATION_INTERVAL_MS |
src/utils/progress.ts |
USER_AGENT_ORIGIN |
src/apify_client.ts |
SEGMENT_FLUSH_AT_EVENTS, SEGMENT_FLUSH_INTERVAL_MS |
src/telemetry.ts |
Phase 3: Localize single-consumer types
| Type |
Move to |
Notes |
ActorInputSchemaProperties |
src/tools/utils.ts |
Trivial alias, used only there |
ActorChargeEvent |
src/utils/pricing_info.ts |
Only production consumer |
ActorPricingModel |
src/utils/actor_search.ts |
Derived type, used only there |
TieredPricing, PricingInfo, PricePerEventActorPricingInfo |
src/utils/pricing_info.ts |
Pricing type cluster |
Update src/utils/actor_card.ts to import PricingInfo from ./pricing_info.js.
Note: ActorDefinitionWithDesc stays — ActorDefinitionPruned depends on it via Pick<>.
Phase 4: Move Skyfire constants to src/payments/
Create src/payments/const.ts with:
SKYFIRE_MIN_CHARGE_USD, SKYFIRE_SELLER_ID, SKYFIRE_TOOL_INSTRUCTIONS, SKYFIRE_PAY_ID_PROPERTY_DESCRIPTION, SKYFIRE_README_CONTENT, SKYFIRE_ENABLED_TOOLS
Move CALL_ACTOR_MCP_MISSING_TOOL_NAME_MSG → src/tools/core/call_actor_common.ts (only consumer).
Phase 5: Convert interface to type in web UI
src/web/src/types.ts: Change interface ActorStats, interface ActorDetails, interface Actor to type.
Keep declare global { interface Window { ... } } (correct use of interface).
Phase 6: Convert HelperTools enum to as const
6a (additive): Add HELPER_TOOLS as const object + HelperToolName type alongside existing enum. Re-export both from index_internals.ts.
6b (migration): Replace HelperTools.X → HELPER_TOOLS.X across 40+ files. Update CONTRIBUTING.md and CLAUDE.md.
6c (cleanup): Remove enum HelperTools. Keep backwards-compat alias in index_internals.ts if internal repo needs migration time.
Also convert local TransportType/Routes enums in src/dev_server.ts. (dropped — those enums no longer exist)
Delivered in PR #1043: enum removed; migrated ~460 refs across 52 files; kept a @deprecated HelperTools value+type alias in index_internals.ts, so the internal repo needs no changes (backward compatible).
Phase 7: Rename ServerMode → SERVER_MODE
Found during Phase 6. ServerMode in src/types.ts is already an as const object + same-named type, but PascalCase — the enumeration convention (CONTRIBUTING.md) wants uppercase SNAKE_CASE. Rename the object and its type to SERVER_MODE (keys DEFAULT/APPS and values 'default'/'apps' unchanged). ~140 references (80 src + 60 tests). Not exported via index_internals.ts, and the internal repo has its own ServerMode, so no cross-repo coordination needed. Bundled into PR #1043.
Internal repo impact
- Phases 1–5, 7: No impact.
- Phase 6:
HelperTools is exported via index_internals.ts. Shipped with a @deprecated HelperTools alias, so the internal repo keeps compiling unchanged.
Verification checklist (every phase)
Open questions
Phase 6: coordinate with internal repo upfront, or use deprecation alias approach? Resolved: deprecation alias (backward compatible), internal repo untouched.
Context and motivation
The codebase has accumulated deviations from our target const/type conventions:
typeoverinterfaceas constobjects over TypeScriptenumas constobjects and their same-named type in uppercaseSNAKE_CASECurrent state:
src/const.ts(217 lines, 50+ exports) mixes unrelated domains — cache config, Skyfire payment strings, telemetry params, actor limits — many used by only 1–2 filessrc/types.ts(698 lines, 47 exports) contains 3 dead exports, 6 single-consumer types, and pricing types only used insrc/utils/pricing_info.tssrc/web/src/types.tsusesinterfacewheretypeis the conventionHelperToolsis a TypeScriptenum(123 imports across 35+ files) — convention saysas constServerMode(src/types.ts) is already anas constobject but isPascalCase— the enumeration convention wants uppercaseSNAKE_CASE(SERVER_MODE)Scope
In scope
src/types.tsandsrc/const.tssrc/const.tsto their consuming filessrc/types.tsto their consuming filessrc/payments/const.tsinterfacetotypeinsrc/web/src/types.tsHelperToolsenum toas constobjectServerModeenumeration object + type toSERVER_MODE(SNAKE_CASE)Out of scope
src/types.tstypes that have complex dependency chains (e.g.,ActorDefinitionWithDesc— used byActorDefinitionPrunedviaPick<>)src/payments/types.ts(already well-organized)Phased plan
Each phase is an independent PR. Phases 1, 2, 5 can run in parallel.
Sub-issues
src/payments/(M) refactor: Move Skyfire constants to src/payments/ (issue #643 phase 4) #807interfacetotypein web UI (S)HelperToolsenum toas const(L) refactor: HelperTools and ServerMode enums to SNAKE_CASE as const #1043ServerMode→SERVER_MODE(M) refactor: HelperTools and ServerMode enums to SNAKE_CASE as const #1043Phase 1: Remove dead exports
src/types.tsPricingTierandTieredEventPrice— inline intoActorChargeEventfield typesrc/const.tsexportfromSKYFIRE_MIN_CHARGE_USDandSKYFIRE_SELLER_ID(0 external imports)Phase 2: Localize single-consumer constants
Move constants from
src/const.tsto their sole consumer:ACTOR_CACHE_MAX_SIZE,ACTOR_CACHE_TTL_SECS,APIFY_DOCS_CACHE_MAX_SIZE,APIFY_DOCS_CACHE_TTL_SECS,MCP_SERVER_CACHE_MAX_SIZE,MCP_SERVER_CACHE_TTL_SECSsrc/state.tsUSER_CACHE_MAX_SIZE,USER_CACHE_TTL_SECSsrc/utils/userid_cache.tsMCP_STREAMABLE_ENDPOINTsrc/mcp/const.tsACTOR_SEARCH_ABOVE_LIMITsrc/utils/actor_search.tsPROGRESS_NOTIFICATION_INTERVAL_MSsrc/utils/progress.tsUSER_AGENT_ORIGINsrc/apify_client.tsSEGMENT_FLUSH_AT_EVENTS,SEGMENT_FLUSH_INTERVAL_MSsrc/telemetry.tsPhase 3: Localize single-consumer types
ActorInputSchemaPropertiessrc/tools/utils.tsActorChargeEventsrc/utils/pricing_info.tsActorPricingModelsrc/utils/actor_search.tsTieredPricing,PricingInfo,PricePerEventActorPricingInfosrc/utils/pricing_info.tsUpdate
src/utils/actor_card.tsto importPricingInfofrom./pricing_info.js.Note:
ActorDefinitionWithDescstays —ActorDefinitionPruneddepends on it viaPick<>.Phase 4: Move Skyfire constants to
src/payments/Create
src/payments/const.tswith:SKYFIRE_MIN_CHARGE_USD,SKYFIRE_SELLER_ID,SKYFIRE_TOOL_INSTRUCTIONS,SKYFIRE_PAY_ID_PROPERTY_DESCRIPTION,SKYFIRE_README_CONTENT,SKYFIRE_ENABLED_TOOLSMove
CALL_ACTOR_MCP_MISSING_TOOL_NAME_MSG→src/tools/core/call_actor_common.ts(only consumer).Phase 5: Convert
interfacetotypein web UIsrc/web/src/types.ts: Changeinterface ActorStats,interface ActorDetails,interface Actortotype.Keep
declare global { interface Window { ... } }(correct use ofinterface).Phase 6: Convert
HelperToolsenum toas const6a (additive): Add
HELPER_TOOLSas constobject +HelperToolNametype alongside existing enum. Re-export both fromindex_internals.ts.6b (migration): Replace
HelperTools.X→HELPER_TOOLS.Xacross 40+ files. UpdateCONTRIBUTING.mdandCLAUDE.md.6c (cleanup): Remove
enum HelperTools. Keep backwards-compat alias inindex_internals.tsif internal repo needs migration time.Also convert local(dropped — those enums no longer exist)TransportType/Routesenums insrc/dev_server.ts.Delivered in PR #1043: enum removed; migrated ~460 refs across 52 files; kept a
@deprecatedHelperToolsvalue+type alias inindex_internals.ts, so the internal repo needs no changes (backward compatible).Phase 7: Rename
ServerMode→SERVER_MODEFound during Phase 6.
ServerModeinsrc/types.tsis already anas constobject + same-named type, butPascalCase— the enumeration convention (CONTRIBUTING.md) wants uppercaseSNAKE_CASE. Rename the object and its type toSERVER_MODE(keysDEFAULT/APPSand values'default'/'apps'unchanged). ~140 references (80 src + 60 tests). Not exported viaindex_internals.ts, and the internal repo has its ownServerMode, so no cross-repo coordination needed. Bundled into PR #1043.Internal repo impact
HelperToolsis exported viaindex_internals.ts. Shipped with a@deprecatedHelperToolsalias, so the internal repo keeps compiling unchanged.Verification checklist (every phase)
npm run type-checkpassesnpm run lintpassesnpm run test:unitpassesOpen questions
Phase 6: coordinate with internal repo upfront, or use deprecation alias approach?Resolved: deprecation alias (backward compatible), internal repo untouched.