experiments in a post-browser web
10
fork

Configure Feed

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

fix(build): electron-builder uses yml config via extends

package.json had its own build section with incomplete exclusions,
which overrode electron-builder.yml. Changed to use "extends" to
delegate to the yml file.

Build size: 3.2GB → 297MB
Build time: 83s → 5s

+106 -36
+29 -15
electron-builder.yml
··· 16 16 - "**/*" 17 17 - "assets/**/*" 18 18 # Exclude build output (critical - prevents recursive bloat) 19 - - "!out/**/*" 19 + - "!out" 20 + - "!out/**" 20 21 # Exclude version control and tooling 21 - - "!.jj/**/*" 22 - - "!.yarn/**/*" 23 - - "!.claude/**/*" 22 + - "!.jj" 23 + - "!.jj/**" 24 + - "!.yarn" 25 + - "!.yarn/**" 26 + - "!.claude" 27 + - "!.claude/**" 24 28 # Exclude agent workflow (symlink to external directory) 25 29 - "!.agent-workflow" 26 30 - "!.agent-task.md" 27 - # Exclude agent workspaces 28 - - "!tmp/**/*" 31 + # Exclude agent workspaces (CRITICAL - these are full project copies) 32 + - "!tmp" 33 + - "!tmp/**" 29 34 # Exclude backend directories not needed for Electron 30 - - "!backend/tauri/**/*" 31 - - "!backend/server/**/*" 32 - - "!backend/tauri-mobile/**/*" 33 - - "!backend/tests/**/*" 35 + - "!backend/tauri" 36 + - "!backend/tauri/**" 37 + - "!backend/server" 38 + - "!backend/server/**" 39 + - "!backend/tauri-mobile" 40 + - "!backend/tauri-mobile/**" 41 + - "!backend/tests" 42 + - "!backend/tests/**" 34 43 # Exclude development/test directories 35 - - "!tests/**/*" 36 - - "!notes/**/*" 37 - - "!docs/**/*" 38 - - "!old-extension/**/*" 44 + - "!tests" 45 + - "!tests/**" 46 + - "!notes" 47 + - "!notes/**" 48 + - "!docs" 49 + - "!docs/**" 50 + - "!old-extension" 51 + - "!old-extension/**" 39 52 # Exclude dev scripts and config 40 - - "!scripts/**/*" 53 + - "!scripts" 54 + - "!scripts/**" 41 55 - "!playwright.config.ts" 42 56 # Exclude dev artifacts and docs 43 57 - "!settings-screenshot.png"
+1 -16
package.json
··· 14 14 "url": "https://github.com/autonome/peek" 15 15 }, 16 16 "build": { 17 - "appId": "com.autonome.peek", 18 - "productName": "Peek", 19 - "files": [ 20 - "**/*", 21 - "!backend/tauri/**/*", 22 - "!backend/server/**/*", 23 - "!backend/tauri-mobile/**/*" 24 - ], 25 - "mac": { 26 - "icon": "assets/appicon.icns", 27 - "category": "public.app-category.productivity", 28 - "identity": null 29 - }, 30 - "directories": { 31 - "output": "out" 32 - } 17 + "extends": "electron-builder.yml" 33 18 }, 34 19 "scripts": { 35 20 "postinstall": "electron-rebuild -f -w better-sqlite3",
+15 -1
schema/generated/sqlite-full.sql
··· 5 5 -- Unified content storage - URLs, text notes, tagsets, and images 6 6 CREATE TABLE IF NOT EXISTS items ( 7 7 id TEXT PRIMARY KEY NOT NULL, 8 - type TEXT NOT NULL CHECK(type IN ('url', 'text', 'tagset', 'image')), 8 + type TEXT NOT NULL CHECK(type IN ('url', 'text', 'tagset', 'image', 'series', 'feed')), 9 9 content TEXT, 10 10 mimeType TEXT DEFAULT '', 11 11 metadata TEXT DEFAULT '{}', ··· 67 67 CREATE INDEX IF NOT EXISTS idx_item_tags_itemId ON item_tags(itemId); 68 68 CREATE INDEX IF NOT EXISTS idx_item_tags_tagId ON item_tags(tagId); 69 69 CREATE UNIQUE INDEX IF NOT EXISTS idx_item_tags_unique ON item_tags(itemId, tagId); 70 + 71 + -- Events/entries for series and feeds - append-only time-series data 72 + CREATE TABLE IF NOT EXISTS item_events ( 73 + id TEXT PRIMARY KEY NOT NULL, 74 + itemId TEXT NOT NULL, 75 + content TEXT, 76 + value REAL, 77 + occurredAt INTEGER NOT NULL, 78 + metadata TEXT DEFAULT '{}', 79 + createdAt INTEGER NOT NULL 80 + ); 81 + 82 + CREATE INDEX IF NOT EXISTS idx_item_events_item_time ON item_events(itemId, occurredAt DESC); 83 + CREATE INDEX IF NOT EXISTS idx_item_events_occurred ON item_events(occurredAt DESC);
+15 -1
schema/generated/sqlite-sync.sql
··· 5 5 -- Unified content storage - URLs, text notes, tagsets, and images 6 6 CREATE TABLE IF NOT EXISTS items ( 7 7 id TEXT PRIMARY KEY NOT NULL, 8 - type TEXT NOT NULL CHECK(type IN ('url', 'text', 'tagset', 'image')), 8 + type TEXT NOT NULL CHECK(type IN ('url', 'text', 'tagset', 'image', 'series', 'feed')), 9 9 content TEXT, 10 10 mimeType TEXT DEFAULT '', 11 11 metadata TEXT DEFAULT '{}', ··· 49 49 CREATE INDEX IF NOT EXISTS idx_item_tags_itemId ON item_tags(itemId); 50 50 CREATE INDEX IF NOT EXISTS idx_item_tags_tagId ON item_tags(tagId); 51 51 CREATE UNIQUE INDEX IF NOT EXISTS idx_item_tags_unique ON item_tags(itemId, tagId); 52 + 53 + -- Events/entries for series and feeds - append-only time-series data 54 + CREATE TABLE IF NOT EXISTS item_events ( 55 + id TEXT PRIMARY KEY NOT NULL, 56 + itemId TEXT NOT NULL, 57 + content TEXT, 58 + value REAL, 59 + occurredAt INTEGER NOT NULL, 60 + metadata TEXT DEFAULT '{}', 61 + createdAt INTEGER NOT NULL 62 + ); 63 + 64 + CREATE INDEX IF NOT EXISTS idx_item_events_item_time ON item_events(itemId, occurredAt DESC); 65 + CREATE INDEX IF NOT EXISTS idx_item_events_occurred ON item_events(occurredAt DESC);
+23 -1
schema/generated/types.rs
··· 9 9 pub struct SchemaItems { 10 10 /// Unique identifier (UUID or generated ID) 11 11 pub id: String, 12 - /// Content type: url, text, tagset, or image 12 + /// Content type: url, text, tagset, image, series, or feed 13 13 pub r#type: String, 14 14 /// URL for type=url, text content for type=text, null for tagset/image 15 15 pub content: Option<String>, ··· 106 106 /// Link creation timestamp (Unix ms) 107 107 pub created_at: i64, 108 108 } 109 + 110 + /// Events/entries for series and feeds - append-only time-series data 111 + #[derive(Debug, Clone, Serialize, Deserialize)] 112 + pub struct SchemaItemEvents { 113 + /// Unique identifier (UUID) 114 + pub id: String, 115 + #[serde(rename = "itemId")] 116 + /// Reference to parent series or feed item 117 + pub item_id: String, 118 + /// Text value, URL, or message 119 + pub content: Option<String>, 120 + /// Numeric value (for series observations) 121 + pub value: Option<f64>, 122 + #[serde(rename = "occurredAt")] 123 + /// When the event happened (Unix ms) 124 + pub occurred_at: i64, 125 + /// JSON metadata object 126 + pub metadata: String, 127 + #[serde(rename = "createdAt")] 128 + /// Creation timestamp (Unix ms) 129 + pub created_at: i64, 130 + }
+21 -2
schema/generated/types.ts
··· 8 8 export interface SchemaItems { 9 9 /** Unique identifier (UUID or generated ID) */ 10 10 id: string; 11 - /** Content type: url, text, tagset, or image */ 11 + /** Content type: url, text, tagset, image, series, or feed */ 12 12 type: string; 13 13 /** URL for type=url, text content for type=text, null for tagset/image */ 14 14 content: string | null; ··· 86 86 createdAt: number; 87 87 } 88 88 89 + /** Events/entries for series and feeds - append-only time-series data */ 90 + export interface SchemaItemEvents { 91 + /** Unique identifier (UUID) */ 92 + id: string; 93 + /** Reference to parent series or feed item */ 94 + itemId: string; 95 + /** Text value, URL, or message */ 96 + content: string | null; 97 + /** Numeric value (for series observations) */ 98 + value: number | null; 99 + /** When the event happened (Unix ms) */ 100 + occurredAt: number; 101 + /** JSON metadata object */ 102 + metadata: string; 103 + /** Creation timestamp (Unix ms) */ 104 + createdAt: number; 105 + } 106 + 89 107 /** Valid sync table names */ 90 - export type SchemaSyncTableName = 'items' | 'tags' | 'item_tags'; 108 + export type SchemaSyncTableName = 'items' | 'tags' | 'item_tags' | 'item_events'; 91 109 92 110 /** Required sync columns by table */ 93 111 export const REQUIRED_SYNC_COLUMNS: Record<SchemaSyncTableName, string[]> = { 94 112 items: ["id","type","content","syncId","syncSource","syncedAt","createdAt","updatedAt","deletedAt"], 95 113 tags: ["id","name","frequency","lastUsed","frecencyScore","createdAt","updatedAt"], 96 114 item_tags: ["itemId","tagId","createdAt"], 115 + item_events: ["id","itemId","content","value","occurredAt","metadata","createdAt"], 97 116 };
+2
schema/generated/validate.js
··· 17 17 items: ["id","type","content","syncId","syncSource","syncedAt","createdAt","updatedAt","deletedAt"], 18 18 tags: ["id","name","frequency","lastUsed","frecencyScore","createdAt","updatedAt"], 19 19 item_tags: ["itemId","tagId","createdAt"], 20 + item_events: ["id","itemId","content","value","occurredAt","metadata","createdAt"], 20 21 }; 21 22 22 23 const missing = []; ··· 59 60 items: ["id","type","content","syncId","syncSource","syncedAt","createdAt","updatedAt","deletedAt"], 60 61 tags: ["id","name","frequency","lastUsed","frecencyScore","createdAt","updatedAt"], 61 62 item_tags: ["itemId","tagId","createdAt"], 63 + item_events: ["id","itemId","content","value","occurredAt","metadata","createdAt"], 62 64 };