A container registry that uses the AT Protocol for manifest storage and S3 for blob storage.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

update configs, fix foreign key issues

+63 -3
+9 -1
config-appview.example.yaml
··· 39 39 registry_domains: [] 40 40 # Web UI settings. 41 41 ui: 42 - # SQLite database for OAuth sessions, stars, pull counts, and device approvals. 42 + # SQLite/libSQL database for OAuth sessions, stars, pull counts, and device approvals. 43 43 database_path: /var/lib/atcr/ui.db 44 + # Visual theme name (e.g. "seamark"). Empty uses default atcr.io branding. 45 + theme: "" 46 + # libSQL sync URL (libsql://...). Works with Turso cloud or self-hosted libsql-server. Leave empty for local-only SQLite. 47 + libsql_sync_url: "" 48 + # Auth token for libSQL sync. Required if libsql_sync_url is set. 49 + libsql_auth_token: "" 50 + # How often to sync with remote libSQL server. Default: 60s. 51 + libsql_sync_interval: 1m0s 44 52 # Health check and cache settings. 45 53 health: 46 54 # How long to cache hold health check results.
+4
config-hold.example.yaml
··· 86 86 defaults: 87 87 # Tier assigned to new crew members who don't have an explicit tier. 88 88 new_crew_tier: deckhand 89 + # Vulnerability scanner settings. Empty disables scanning. 90 + scanner: 91 + # Shared secret for scanner WebSocket auth. Empty disables scanning. 92 + secret: ""
+15
deploy/upcloud/configs/appview.yaml.tmpl
··· 1 1 version: "0.1" 2 2 log_level: info 3 + log_shipper: 4 + backend: "" 5 + url: "" 6 + batch_size: 100 7 + flush_interval: 5s 8 + username: "" 9 + password: "" 3 10 server: 4 11 addr: :5000 5 12 base_url: "https://seamark.dev" ··· 13 20 ui: 14 21 database_path: "{{.BasePath}}/ui.db" 15 22 theme: seamark 23 + libsql_sync_url: "" 24 + libsql_auth_token: "" 25 + libsql_sync_interval: 1m0s 26 + health: 27 + cache_ttl: 15m0s 28 + check_interval: 15m0s 16 29 jetstream: 17 30 url: wss://jetstream2.us-west.bsky.network/subscribe 18 31 backfill_enabled: true ··· 20 33 auth: 21 34 key_path: "{{.BasePath}}/auth/private-key.pem" 22 35 cert_path: "{{.BasePath}}/auth/private-key.crt" 36 + credential_helper: 37 + tangled_repo: "" 23 38 legal: 24 39 company_name: Seamark 25 40 jurisdiction: State of Texas, United States
+2 -2
deploy/upcloud/configs/cloudinit.sh.tmpl
··· 43 43 npm ci 44 44 go generate ./... 45 45 CGO_ENABLED=1 go build \ 46 - -ldflags="-s -w -linkmode external -extldflags '-static'" \ 47 - -tags sqlite_omit_load_extension -trimpath \ 46 + -ldflags="-s -w" \ 47 + -trimpath \ 48 48 -o bin/{{.BinaryName}} ./cmd/{{.BuildCmd}} 49 49 50 50 # Service user & data dirs
+15
deploy/upcloud/configs/hold.yaml.tmpl
··· 1 1 version: "0.1" 2 2 log_level: info 3 + log_shipper: 4 + backend: "" 5 + url: "" 6 + batch_size: 100 7 + flush_interval: 5s 8 + username: "" 9 + password: "" 3 10 storage: 4 11 access_key: "{{.S3AccessKey}}" 5 12 secret_key: "{{.S3SecretKey}}" ··· 10 17 addr: :8080 11 18 public_url: "https://{{.HoldDomain}}" 12 19 public: false 20 + relay_endpoint: "" 21 + read_timeout: 5m0s 22 + write_timeout: 5m0s 13 23 registration: 14 24 owner_did: "did:plc:pddp4xt5lgnv2qsegbzzs4xg" 15 25 allow_all_crew: true 26 + profile_avatar_url: https://imgs.blue/evan.jarrett.net/1TpTOdtS60GdJWBYEqtK22y688jajbQ9a5kbYRFtwuqrkBAE 16 27 enable_bluesky_posts: false 28 + region: "" 17 29 database: 18 30 path: "{{.BasePath}}" 31 + key_path: "" 19 32 admin: 20 33 enabled: true 21 34 quota: ··· 28 41 quota: 100GB 29 42 defaults: 30 43 new_crew_tier: deckhand 44 + scanner: 45 + secret: ""
+8
pkg/appview/jetstream/processor.go
··· 410 410 if err := json.Unmarshal(recordData, &starRecord); err != nil { 411 411 return fmt.Errorf("failed to unmarshal star: %w", err) 412 412 } 413 + 414 + // Ensure the starred repository's owner exists in the users table 415 + // (the starrer is already ensured by ProcessRecord, but the owner 416 + // may not have been processed yet during backfill or live events) 417 + if err := p.EnsureUser(ctx, starRecord.Subject.DID); err != nil { 418 + return fmt.Errorf("failed to ensure star subject user: %w", err) 419 + } 420 + 413 421 // Upsert the star record (idempotent - won't duplicate) 414 422 // The DID here is the starrer (user who starred) 415 423 // The subject contains the owner DID and repository
+10
pkg/appview/jetstream/processor_test.go
··· 425 425 database := setupTestDB(t) 426 426 defer database.Close() 427 427 428 + // Insert test users (starrer + owner) so EnsureUser finds them without network calls 429 + for _, did := range []string{"did:plc:starrer123", "did:plc:owner123"} { 430 + _, err := database.Exec( 431 + `INSERT INTO users (did, handle, pds_endpoint, last_seen) VALUES (?, ?, ?, ?)`, 432 + did, did+".test", "https://pds.example.com", time.Now()) 433 + if err != nil { 434 + t.Fatalf("Failed to insert test user %s: %v", did, err) 435 + } 436 + } 437 + 428 438 p := NewProcessor(database, false, nil) 429 439 ctx := context.Background() 430 440