How the code is organised

A map of the repository, how the renderer talks to the main process, where each feature lives, and the conventions to follow.

Updated 5 min read

This is the map to read before you change anything. It names the folders, shows how a request travels from a button to the disk, and points at where to read more. It describes the public repository at github.com/kwebby/cutscript, which holds the app only. The cutscript.dev website and these docs are not in it.

The top level

src/          the app: main process, preload script, renderer, shared code, design runtime
native/       Swift helpers: capture, cutout, track
resources/    files that ship with the app: ffmpeg, cursor styles, icons, skills, Design pack
scripts/      build, packaging, licence, changelog and skill-check scripts
tests/        end-to-end scripts, fixtures and the skill conformance tests
build/        icons, entitlements and installer files
docs/         only record-motion/ffmpeg-lgpl: the build scripts and notes for the bundled ffmpeg

Other files at the top level that you will meet: README.md, LICENSE (the GNU AGPL-3.0-only text), NOTICE (the additional permission for linking with Remotion), THIRD-PARTY-NOTICES.md, package.json, electron.vite.config.ts, electron-builder.yml, eslint.config.mjs, the TypeScript configs and CHANGELOG.md. The changelog file only points to cutscript.dev/changelog, where the release notes are published.

Inside src/

FolderWhat lives there
src/mainThe Electron main process. index.ts starts the app. ipc/ registers the typed handlers. services/ holds the work: projects, settings, ffmpeg, export, transcription, recording, the AI director, One AI, design, tracking, voice enhance and link download. windows/ and platform/ hold the windows, menus and operating-system details. jobs.ts runs background jobs with progress and cancellation.
src/preloadThe preload script that exposes window.api to the renderer.
src/renderer/srcThe React interface. features/ has a folder for each area (dashboard, editor, script, timeline, preview, properties, captions, export, settings, recorder, director, oneAi and more). components/ui is the shared kit. stores/ holds the zustand stores. styles/ holds the design tokens.
src/sharedCode both processes use: the types, the IPC contract in api.ts, the defaults, the edit engine in edit.ts, the time model and the pure logic for motion, scenes, the director and One AI.
src/design-runtimeThe kit and the host that render AI-designed and Design pack graphics frame by frame. scripts/build-design-kit.mjs and scripts/build-design-host.mjs build them into resources/design-kit.

The main process has three entry points, set in electron.vite.config.ts: the app, a worker that reads attachments for the AI director, and a worker for the tracking blur.

How a request travels

  1. A component calls a method on window.api, such as window.api.director.estimate(...).
  2. The preload script sends it as an IPC call named <namespace>:<method>.
  3. A typed handler receives it and calls a service in src/main/services. Most handlers are registered in src/main/ipc/index.ts. The larger areas, such as the director and One AI, register their own.
  4. The service does the work. For long work it starts a job in jobs.ts, which streams progress back as events.

The contract between the two sides is one file, src/shared/api.ts. It lists every method and event channel. Add a method there first, and the compiler then tells you what else needs changing.

The edit model

The transcript is never modified. An edit is a small record: which words are deleted, ignored or hidden, which words you corrected, which pauses you shortened, and the extra cuts. src/shared/edit.ts turns that record into a list of kept ranges of the source file. The preview plays the original file and skips the cut ranges. A plain export renders the kept ranges with ffmpeg. A project with motion effects is drawn frame by frame by the same scene code the preview uses, so the preview and the file match.

That is why the filler, pause and repetition finders are pure functions in edit.ts, with their tests beside them.

Where to look for a feature

You want to changeStart in
Filler, pause and repeat detectionsrc/shared/edit.ts, src/shared/defaults.ts, src/renderer/src/features/ai
Export options and formatssrc/renderer/src/features/export, src/main/services/export
Transcription providers and modelssrc/main/services/stt, src/shared/aiCapabilities.ts, src/shared/aiModelFacts.ts
Recordingsrc/main/services/recording, src/renderer/src/features/recorder, native/capture
Tracking blursrc/shared/tracking, src/main/services/tracking, native/track
Captionssrc/renderer/src/features/captions, src/shared/captionFit.ts, src/shared/defaults.ts
The AI director and One AIsrc/main/services/director, src/main/services/oneAi, src/shared/oneAi
Graphics and the Design packsrc/main/services/designDirector, src/shared/design, resources/design-exemplars
Skillsresources/director-skills, src/shared/director/skillbook
Release notesscripts/changelog-notes.mjs
The bundled ffmpegdocs/record-motion/ffmpeg-lgpl

Notes in the code

The repository has no per-area design notes. Many source files open with a comment that says what the file owns and the rules it keeps, so read that comment before you change the file. The one folder under docs/ is docs/record-motion/ffmpeg-lgpl, which holds the build scripts, build notes and checksums for the bundled ffmpeg.

Conventions

  • Format. Prettier with single quotes, no semicolons, a line width of 100 and no trailing commas. Two spaces, LF line endings. Run npm run format.
  • Types. ESLint asks for explicit return types on functions. Run npm run lint and npm run typecheck.
  • Tests beside the code. A file foo.ts has foo.test.ts next to it. Several modules say in their header that they use relative imports so Vitest can load them, and you should follow that note where you see it.
  • Pure logic goes in src/shared when both processes or the tests need it.
  • Generated files stay generated. CHANGELOG.md only points to the website, and release notes are written in scripts/changelog-notes.mjs. resources/design-exemplars/index.json comes from node scripts/check-design-guidance.mjs --write-index. resources/native is a build output.

Where your data lives

A running Cutscript keeps its data in ~/Library/Application Support/Cutscript. Projects are in projects/<id>/, with project.json, generated audio in assets/ and derived files in cache/. Settings are in settings.json, and API keys are in secrets.json, encrypted with the macOS keychain. Imported media is referenced where it is, not copied.

Was this page helpful?

Comments

Longer questions go better in the forum.

No comments yet. Ask a question or add what you found.

Loading the index…