Monorepo for Aesthetic.Computer
aesthetic.computer
Scripts Architecture#
✅ Final Organization (November 2024)#
After investigating script placement and dependency resolution, we arrived at this clean architecture:
Location: scripts/ (workspace root)#
Why root level?
- Logical separation: deployment code in
system/, operational tools inscripts/ - Clear organization: not buried in implementation directories
- Consistent with existing
at/scripts/pattern
Dependency Strategy: Shared Dependencies#
Problem: Scripts need packages like @atproto/api, mongodb, etc. that are installed in system/node_modules/
Solution: Install same packages at root level
- Added to root
package.jsondependencies - Small duplication (fine architecturally)
- Node.js walks up from
scripts/atproto/→scripts/→ root → findsnode_modules/ - Same packages in
system/for Netlify functions (they need bundled deps)
Dependencies shared:
{
"@atproto/api": "^0.17.2",
"@aws-sdk/client-s3": "^3.896.0",
"mongodb": "^6.20.0",
"dotenv": "^16.4.7",
"node-fetch": "^3.3.2"
}
Import Paths#
Scripts use relative paths to access backend modules:
// From scripts/atproto/*.mjs
import { connect } from "../../system/backend/database.mjs";
import { createMediaRecord } from "../../system/backend/media-atproto.mjs";
// From scripts/recovery/*.mjs
import { connect } from "../../system/backend/database.mjs";
import { userIDFromHandle } from "../../system/backend/authorization.mjs";
Path breakdown: ../../system/backend/
../- up fromscripts/atproto/toscripts/../- up fromscripts/to workspace rootsystem/backend/- into backend module directory
Environment Variables#
Scripts load .env from system/.env:
import { config } from 'dotenv';
config({ path: './system/.env' }); // Relative to workspace root
Must run from workspace root so ./system/.env resolves correctly.
🏗️ Directory Structure#
/workspaces/aesthetic-computer/
├── scripts/ # Operational scripts (NEW!)
│ ├── README.md # Omakase menu for LLM
│ ├── SETUP.md # Setup instructions
│ ├── ARCHITECTURE.md # This file
│ ├── atproto/ # ATProto sync/backfill tools
│ │ ├── sync-atproto.mjs
│ │ ├── backfill-kidlisp-rkeys.mjs
│ │ └── ...
│ └── recovery/ # Data recovery tools
│ ├── recover-deleted-tapes.mjs
│ └── check-tape-zips-in-spaces.mjs
│
├── system/ # Deployment code
│ ├── backend/ # Reusable modules
│ │ ├── database.mjs
│ │ ├── media-atproto.mjs
│ │ ├── authorization.mjs
│ │ └── ...
│ ├── netlify/
│ │ └── functions/ # Netlify edge functions
│ ├── .env # Secrets (in .gitignore)
│ ├── node_modules/ # System dependencies
│ └── package.json
│
├── at/scripts/atproto/ # External AT Protocol tools
│ └── ... # Federation, lexicon publishing, etc.
│
├── node_modules/ # Root dependencies (includes script deps)
└── package.json # Root packages (includes script deps)
🎯 Design Principles#
-
Separation of Concerns
system/= deployment infrastructure (Netlify functions, edge compute)scripts/= operational tools (maintenance, sync, recovery)at/scripts/= external protocol tools (federation with other PDS)
-
Shared Dependencies
- Accept small duplication for cleaner architecture
- Root level for scripts, system level for functions
- Both can use same versions (kept in sync)
-
Backend Modules as Library
system/backend/*.mjs= reusable utilities- Used by: Netlify functions, operational scripts, AT tools
- Never create duplicate implementations
-
LLM-Friendly Documentation
README.md= "Omakase menu" of available scriptsSETUP.md= Getting started, troubleshootingARCHITECTURE.md= Design decisions (this file)
🚀 Usage Pattern#
# 1. Ensure dependencies installed
npm install # (at root)
# 2. Ensure secrets available
ls system/.env # or copy from vault
# 3. Run scripts from root
node scripts/atproto/sync-atproto.mjs live --kidlisp-only
node scripts/recovery/check-tape-zips-in-spaces.mjs @jeffrey
🔄 Alternatives Considered#
❌ Keep in system/backend/#
- Pros: Natural access to system/node_modules
- Cons: Mixed with library code, unclear which are operations vs utilities
❌ Move to system/scripts/#
- Pros: Still in system where deps are
- Cons: Scripts aren't really "system" deployment code
❌ Use NODE_PATH hack#
- Pros: Scripts could stay anywhere
- Cons: Hacky, requires wrapper scripts, confusing
✅ Root scripts/ + shared deps (CHOSEN)#
- Pros: Clean separation, logical organization, minimal duplication
- Cons: Some deps duplicated (acceptable tradeoff)
📝 Commit Strategy#
Group related changes:
- Script organization (moves, README, SETUP)
- Dependency sharing (package.json updates)
- Netlify config fixes (@atproto/api externals)
Message:
Organize operational scripts with shared dependencies
- Move provisional scripts from system/backend/ to scripts/
- Add atproto/ (sync/backfill) and recovery/ subdirectories
- Share dependencies: install @atproto/api, mongodb, etc. at root
- Fix netlify.toml: add @atproto/api to 4 function externals
- Add documentation: README (omakase menu), SETUP, ARCHITECTURE
All kidlisp/tapes/moods synced to ATProto successfully