Skip to content

Commit c18044f

Browse files
committed
feat: scaffold backend + desktop + infra (k8s, tauri, M3 tokens)
foundation for the FrameOS product. brings up three workspaces: apps/backend/ — python 3.12 + fastapi - /health endpoint with response schema, pydantic v2 models for the JSON timeline + analysis (mirrors apps/desktop/src/types/timeline.ts) - pytest smoke test, ruff (google py style) + pyright strict - uv-managed deps: fastapi, pydantic-settings, google-genai, aiobotocore, httpx, structlog infra/ — kind + skaffold + plain k8s yaml - single-node kind cluster, NodePort mappings to host (30080 backend, 30333 seaweedfs S3, 30888 seaweedfs filer UI) - skaffold orchestrates docker build → load into kind → apply manifests - backend Deployment + Service, seaweedfs Deployment + Service + PVC + S3 identities ConfigMap, api-keys Secret template - single-stage Dockerfile.backend with ffmpeg bundled apps/desktop/ — tauri 2 + vite + react 18 + tailwind 3.4 - tauri rust core with a smoke `ping` command for IPC verification - 3-pane editor shell (assets | preview+timeline | chat) using lucide icons, react-dropzone, zustand, zod-validated api client - M3 dark theme tokens via CSS variables in src/styles/tokens.css — the SOLE design layer, swap one file when claude.ai/design ships - HEALTH badge in the top bar proves desktop ↔ backend wiring is alive - shadcn components.json wired so `pnpm dlx shadcn add ...` just works - deps lean on existing npm packages (Vercel AI SDK, @remotion/player, react-dropzone, lucide-react, clsx, tailwind-merge, zod) — minimizes hand-rolled code per the "use packages, smaller codebase" rule deferred: - packages/* extraction (premature; minimize codebase per recent guidance) - bazel wrappers for these apps (cargo/uv/pnpm directly; bazel still drives apps/marketing-video) - icons, packaging, signing (stretch / polish at hour 18+) next: pnpm install + create kind cluster + skaffold dev + tauri dev to verify the desktop ↔ backend hello-world end-to-end.
1 parent 7bfd48c commit c18044f

30 files changed

Lines changed: 3201 additions & 43 deletions

.github/workflows/ci.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
jobs:
9+
test:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Setup Bazel
15+
uses: bazel-contrib/setup-bazel@0.9.1
16+
with:
17+
bazelisk-cache: true
18+
disk-cache: ${{ github.workflow }}
19+
repository-cache: true
20+
21+
- name: Setup Node
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: '20.11.1'
25+
26+
- name: Install pnpm
27+
run: npm install -g pnpm@9.12.0
28+
29+
- name: pnpm install
30+
run: pnpm install --frozen-lockfile
31+
32+
- name: Run all tests
33+
run: bazel test //:all_tests
34+
35+
- name: Render hero MP4
36+
run: bazel build //apps/marketing-video:render
37+
38+
- name: Upload rendered video
39+
uses: actions/upload-artifact@v4
40+
with:
41+
name: hero.mp4
42+
path: bazel-bin/apps/marketing-video/hero.mp4
43+
retention-days: 14

BUILD.bazel

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,14 @@ alias(
1212
name = "render",
1313
actual = "//apps/marketing-video:render",
1414
)
15+
16+
# Aggregate test target — runs all package tests + video typecheck.
17+
test_suite(
18+
name = "all_tests",
19+
tests = [
20+
"//packages/brand:test",
21+
"//packages/sfx:test",
22+
"//packages/ui-mocks:test",
23+
"//apps/marketing-video:typecheck",
24+
],
25+
)

apps/marketing-video/BUILD.bazel

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
load("@aspect_rules_js//js:defs.bzl", "js_library", "js_test")
2+
load("@aspect_rules_ts//ts:defs.bzl", "ts_project")
3+
load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
4+
load("@npm//:defs.bzl", "npm_link_all_packages")
5+
load(
6+
"@npm//apps/marketing-video:@remotion/cli/package_json.bzl",
7+
remotion_bin = "bin",
8+
)
9+
load(
10+
"@npm//apps/marketing-video:typescript/package_json.bzl",
11+
typescript_bin = "bin",
12+
)
13+
14+
npm_link_all_packages(name = "node_modules")
15+
16+
# Copy SFX mp3s into public/sfx so staticFile() resolves them.
17+
copy_to_directory(
18+
name = "public_sfx",
19+
srcs = ["//packages/sfx:assets"],
20+
out = "public/sfx",
21+
root_paths = ["packages/sfx/assets"],
22+
)
23+
24+
ts_project(
25+
name = "video_lib",
26+
srcs = glob(["src/**/*.ts", "src/**/*.tsx"]),
27+
declaration = True,
28+
tsconfig = "tsconfig.json",
29+
deps = [
30+
":node_modules/@frameos/brand",
31+
":node_modules/@frameos/sfx",
32+
":node_modules/@frameos/ui-mocks",
33+
":node_modules/@remotion/cli",
34+
":node_modules/@remotion/google-fonts",
35+
":node_modules/@remotion/media",
36+
":node_modules/@types/react",
37+
":node_modules/@types/react-dom",
38+
":node_modules/react",
39+
":node_modules/react-dom",
40+
":node_modules/remotion",
41+
":node_modules/zod",
42+
],
43+
)
44+
45+
filegroup(
46+
name = "runtime_files",
47+
srcs = [
48+
":video_lib",
49+
":public_sfx",
50+
"package.json",
51+
"remotion.config.ts",
52+
],
53+
visibility = ["//visibility:private"],
54+
)
55+
56+
remotion_bin.remotion_binary(
57+
name = "studio",
58+
args = ["studio", "src/index.ts"],
59+
chdir = package_name(),
60+
data = [":runtime_files"],
61+
)
62+
63+
remotion_bin.remotion(
64+
name = "render",
65+
srcs = [":runtime_files"],
66+
outs = ["hero.mp4"],
67+
args = [
68+
"render",
69+
"src/index.ts",
70+
"FrameOS-Hero-30s",
71+
"$(execpath :hero.mp4)",
72+
],
73+
chdir = package_name(),
74+
)
75+
76+
[
77+
remotion_bin.remotion(
78+
name = "still_" + scene,
79+
srcs = [":runtime_files"],
80+
outs = ["still_" + scene + ".png"],
81+
args = [
82+
"still",
83+
"src/index.ts",
84+
"Scene-" + scene,
85+
"$(execpath :still_" + scene + ".png)",
86+
],
87+
chdir = package_name(),
88+
tags = ["manual"],
89+
)
90+
for scene in ["pain", "trigger", "magic", "outro"]
91+
]
92+
93+
typescript_bin.tsc_test(
94+
name = "typecheck",
95+
args = ["--noEmit", "--project", "$(location tsconfig.json)"],
96+
chdir = package_name(),
97+
data = [
98+
":video_lib",
99+
"tsconfig.json",
100+
"//:tsconfig.base.json",
101+
],
102+
tags = ["typecheck"],
103+
)

apps/marketing-video/package.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "@frameos/marketing-video",
3+
"version": "0.0.0",
4+
"private": true,
5+
"type": "module",
6+
"scripts": {
7+
"studio": "remotion studio",
8+
"render": "remotion render FrameOS-Hero-30s out/hero.mp4",
9+
"still": "remotion still FrameOS-Hero-30s out/still.png",
10+
"typecheck": "tsc --noEmit"
11+
},
12+
"dependencies": {
13+
"@frameos/brand": "workspace:*",
14+
"@frameos/sfx": "workspace:*",
15+
"@frameos/ui-mocks": "workspace:*",
16+
"@remotion/cli": "4.0.462",
17+
"@remotion/google-fonts": "4.0.462",
18+
"@remotion/media": "4.0.462",
19+
"@remotion/zod-types": "4.0.462",
20+
"react": "18.3.1",
21+
"react-dom": "18.3.1",
22+
"remotion": "4.0.462",
23+
"zod": "4.3.6"
24+
},
25+
"devDependencies": {
26+
"@types/react": "18.3.12",
27+
"@types/react-dom": "18.3.1",
28+
"typescript": "5.6.3"
29+
}
30+
}
2.38 KB
Binary file not shown.
2.38 KB
Binary file not shown.
2.38 KB
Binary file not shown.
2.38 KB
Binary file not shown.
2.38 KB
Binary file not shown.
2.38 KB
Binary file not shown.

0 commit comments

Comments
 (0)