Compare commits
No files matched your search
@@ -2,6 +2,47 @@
|
||||
|
||||
本项目按 `v主版本.次版本.修订版本` 标记发布。下列内容以对应 Git tag 和已提交功能为准。
|
||||
|
||||
## v1.14.2 — 2026-09-28
|
||||
|
||||
- 修复数据库管理器首次设置密码时 PBKDF2 迭代次数超过托管环境上限,导致服务器返回错误页面的问题。
|
||||
- 接口返回非 JSON 内容时显示可读的中英文错误提示,不再暴露原始解析异常。
|
||||
|
||||
## v1.14.1 — 2026-09-28
|
||||
|
||||
- 数据库管理器改为每个 ChatGPT 账号首次进入时设置自己的密码,停用旧的共用口令。
|
||||
- 密码以独立盐值和 PBKDF2 摘要保存;可在管理页验证旧密码后修改,修改时注销旧会话。
|
||||
- 增加首次设置、不同账号密码隔离、旧会话失效和修改密码的验证。
|
||||
|
||||
## v1.14.0 — 2026-09-28
|
||||
|
||||
- 新增数据库管理器 App:固定服务器与用户名的登录页、直接操作数据库的确认提示、按表分页浏览及 JSON 增删改查。
|
||||
- 管理操作只作用于当前 ChatGPT 登录用户的记录;口令保存在服务端密钥中,短时会话、失败次数限制、版本冲突检测与写入二次确认保护数据。
|
||||
- 记忆、目标、待办、收藏、档案与设置可在管理器查看;标签由记忆内容维护,旧版备份表不开放直接编辑。
|
||||
|
||||
## v1.13.0 — 2026-09-28
|
||||
|
||||
- D1 新增按记录存储的记忆、标签、目标、待办和收藏表;资料与设置保留 JSON。
|
||||
- 用户首次访问时从旧状态表回填数据,旧表保留为只读迁移来源;浏览器备份格式仍为 Schema v2。
|
||||
- 云同步改为逐条提交与版本校验;跨设备修改同一记录时保存本地冲突副本并让用户选择。旧版整份状态写入接口停止接收写入。
|
||||
- 增加 SQLite 集成验证,覆盖回填、标签更新、删除标记、版本冲突和用户隔离。
|
||||
|
||||
## v1.12.0 — 2026-09-28
|
||||
|
||||
- 目标与待办可在终端逐项创建;记忆、目标、待办可先选择记录,再输入 `yes` 确认删除。
|
||||
- 终端打开时显示欢迎信息,增加日期、时间、会话运行时间、版本、统计和命令历史等常用命令。
|
||||
- 开放 `LifeOS.run()`、`LifeOS.note()` 等浏览器开发者控制台入口,复用终端命令与删除确认;图形界面和终端共用删除操作。
|
||||
|
||||
## v1.11.0 — 2026-09-28
|
||||
|
||||
- `memory add` 增加交互式逐项输入,可依次填写标题、日期、标签、能量、天气、地点、关联待办和正文。
|
||||
- 回车接受默认值,`back` 返回上一步,`cancel` 或 Escape 取消;原有带参数命令仍可用。
|
||||
|
||||
## v1.10.0 — 2026-09-28
|
||||
|
||||
- 增加交互式终端 App:创建和查询记忆、目标与待办,完成或重新开启待办,并打开其他 App。
|
||||
- 支持带引号的标题、选项、命令历史、Tab 补全与多行记忆输入;终端提示提供中文和英文。
|
||||
- 记忆、目标与待办的图形表单与终端共用数据写入入口,沿用现有云同步和备份结构。
|
||||
|
||||
## v1.9.0 — 2026-09-28
|
||||
|
||||
- 增加轻量浏览器 App,默认在 iframe 中打开 Google,支持地址栏搜索、后退、前进与刷新。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
以桌面操作系统为交互方式的个人记录网站。用 App 记录日常、管理目标与待办,并沿时间线回看已经留下的内容。
|
||||
|
||||
在线站点:[Life OS](https://life-os-personal-desktop.biss0.chatgpt.site) · 当前应用版本:**v1.9.0** · [更新日志](CHANGELOG.md)
|
||||
在线站点:[Life OS](https://life-os-personal-desktop.biss0.chatgpt.site) · 当前应用版本:**v1.14.2** · [更新日志](CHANGELOG.md)
|
||||
|
||||
## 功能
|
||||
|
||||
@@ -13,22 +13,30 @@
|
||||
| 博物馆 | 回看收藏的记忆。 |
|
||||
| 目标与待办 | 创建目标和任务,设置截止日期、优先级和完成状态;目标倒计时可选择显示在桌面。 |
|
||||
| 日历 | 在月视图与日视图中查看记忆、任务和目标节点,并为选定日期新增记忆。 |
|
||||
| 数据库管理器 | 在再次登录并确认风险后,按表查看、创建、编辑和删除当前账号的云端记录。 |
|
||||
| 洞察 | 周报和月报展示记录频率、完成任务数、常见天气、能量记录及收藏或标记高光的记忆;仅依据已保存的数据统计。 |
|
||||
| 档案 | 查看记录概况并维护个人资料。 |
|
||||
| 浏览器 | 在桌面窗口里打开网页或使用 Google 搜索,支持后退、前进、刷新和外部打开。默认打开 Google;第三方网站可能禁止 iframe 嵌入。 |
|
||||
| 终端 | 逐项创建记忆、目标与待办;选择并确认删除记录,管理完成状态,查询数据和打开其他 App。 |
|
||||
| 系统设置 | 选择语言、主题、壁纸、桌面快捷方式和开机 App,管理备份。 |
|
||||
|
||||
桌面端支持单击选择、双击打开 App、多窗口、任务栏恢复、图标拖动排列和窗口布局记忆。拖动图标或小部件时会显示吸附网格;目标倒计时、时钟、今日概览与快捷操作小部件可移动、调整大小和分别开关。移动端以横排图标和全屏 App 为主,小部件在桌面下方排列。可选必应每日图片、内置背景或自定义 HTTPS 图片链接。中文与英文可自动跟随浏览器语言,也可手动选择。
|
||||
|
||||
快捷键:`Ctrl / ⌘ + K` 打开启动器,`Ctrl / ⌘ + F` 搜索记忆,`Ctrl / ⌘ + S` 保存今日记忆;`Alt + 1–9` 打开对应 App。站点包含 PWA 清单和 Service Worker,离线时可打开已缓存的应用外壳;云同步、外部网页与必应图片仍需要联网。
|
||||
快捷键:`Ctrl / ⌘ + K` 打开启动器,`Ctrl / ⌘ + F` 搜索记忆,`Ctrl / ⌘ + S` 保存今日记忆;`Alt + 1–9` 打开原有 App,`Alt + 0` 打开终端。终端内 ↑↓ 浏览命令历史,Tab 补全命令,记忆正文输入时 `Ctrl / ⌘ + Enter` 保存。站点包含 PWA 清单和 Service Worker,离线时可打开已缓存的应用外壳;云同步、外部网页与必应图片仍需要联网。
|
||||
|
||||
终端首次打开显示欢迎信息,输入 `help` 查看命令。`memory add`、`goal add`、`task add` 可逐项创建;回车保留默认值,`back` 返回,`cancel` 取消。`memory delete`、`goal delete`、`task delete` 会列出记录供选择,并要求输入 `yes` 确认。原有带参数的快速输入仍可用,例如 `memory add "实验记录" --date 2026-09-28 --tag 学习 --text "完成实验"`、`task add "背单词" --due tomorrow --priority high`。`date`、`time`、`datetime` 读取当前设备时间;另有 `uptime`、`status`、`apps`、`history`、`echo`、`version` 等命令。终端只执行明确支持的 Life OS 操作,不是系统 shell。
|
||||
|
||||
浏览器开发者工具的 Console 也可使用同一套命令:`LifeOS.help()`、`LifeOS.run('date')`、`LifeOS.run('memory add')`;逐项填写后用 `LifeOS.note('正文')` 保存记忆,或用 `LifeOS.cancel()` 取消。该入口不会替换或拦截浏览器原生的 `console`,删除操作同样需要在后续调用 `LifeOS.run('yes')` 确认。
|
||||
|
||||
## 数据与备份
|
||||
|
||||
站点使用 ChatGPT 登录标识隔离不同用户的数据。登录后,资料通过同源 API 保存到 Sites 的 D1 数据库;浏览器 `localStorage` 充当缓存、草稿及首次迁移来源。首次云端恢复前,本地资料会保留一份迁移前副本。目标与任务存于 `lifeos_system.tasksBoard`,记忆及其可选信息存于 `lifeos_memories`。
|
||||
站点使用 ChatGPT 登录标识隔离不同用户的数据。登录后,资料通过同源 API 保存到 Sites 的 D1 数据库;浏览器 `localStorage` 充当缓存、草稿及首次迁移来源。首次云端恢复前,本地资料会保留一份迁移前副本。浏览器缓存与 JSON 备份仍使用 `lifeos_system.tasksBoard`;云端将其中的目标和待办拆分为独立记录。
|
||||
|
||||
**系统设置 → 导出数据** 会生成 JSON 备份;导入支持合并或覆盖。备份格式使用 `schemaVersion: 2`,仍可导入 v1 备份。壁纸来源、快捷方式、开机 App 和小部件开关包含在同步与备份中;窗口布局与小部件格位分别保存在本设备的 `lifeos_window_layout_v1`、`lifeos_widget_layout_v1`,也包含在 JSON 导出中,覆盖导入时可恢复。未保存的今日草稿仅留在本机。
|
||||
|
||||
主要数据键:`lifeos_memories`、`lifeos_museum`、`lifeos_profile`、`lifeos_settings`、`lifeos_system`。D1 的初始迁移位于 `drizzle/0000_lifeos_cloud_state.sql`:它将各类数据作为 JSON 字段保存在每个用户的一行记录中;应用的备份 schema 版本与数据库迁移编号是两回事。建议定期导出备份。
|
||||
主要本地数据键:`lifeos_memories`、`lifeos_museum`、`lifeos_profile`、`lifeos_settings`、`lifeos_system`。云端表结构见 `drizzle/0001_lifeos_records.sql`:记忆、标签、目标、待办、收藏各自按记录保存,资料与设置保留按用户存储的 JSON。旧版 `lifeos_states` 作为只读迁移来源保留;用户首次访问新版本时自动回填新表,旧表不会被清空。单条记录的修改使用版本号校验;冲突时会保存本地副本并要求选择。旧版浏览器标签页需刷新,整份状态写入接口已停用,避免覆盖新数据。应用的备份 `schemaVersion: 2` 与数据库迁移编号是两回事。建议定期导出备份。
|
||||
|
||||
数据库管理器的服务器固定为本站 D1,用户名固定为 `lifeos-admin`。每个 ChatGPT 账号首次打开管理器时设置自己的密码(至少 12 个字符),旧版共用口令不再有效。密码以独立盐值与 PBKDF2 摘要存入 `lifeos_admin_credentials`,不保存明文,也不写进仓库或浏览器;管理页可验证当前密码后更换。它在原有账号登录之上再次验证密码;会话仅在当前页面内存中保留 20 分钟,退出或修改密码后旧会话立即失效,连续五次输错锁定 15 分钟。管理 API 只允许当前账号在预设表内按记录操作,没有任意 SQL 执行入口。更改云端记录后应刷新桌面,使其他 App 重新加载数据。派生的标签索引和旧版状态备份不能在管理器中单独修改。
|
||||
|
||||
## 构建与验证
|
||||
|
||||
@@ -37,9 +45,10 @@
|
||||
```bash
|
||||
npm run build
|
||||
npm run validate
|
||||
npm run test:cloud
|
||||
```
|
||||
|
||||
`build` 将页面及 App 脚本打包成 `dist/server/` 中的 Cloudflare Worker 产物;`validate` 检查产物、双语键与主要交互。生产托管配置在 `.openai/hosting.json`,含 Sites 项目 ID 和 D1 逻辑绑定。直接在其他环境部署时,需要提供兼容的 Worker 环境与 `DB` 绑定;云端 API 还依赖托管层提供的 `oai-authenticated-user-id` 请求头。
|
||||
`build` 将页面及 App 脚本打包成 `dist/server/` 中的 Cloudflare Worker 产物;`validate` 检查产物、双语键与主要交互;`test:cloud` 使用内存 SQLite 检查旧数据回填、版本冲突与租户隔离。生产托管配置在 `.openai/hosting.json`,含 Sites 项目 ID 和 D1 逻辑绑定。直接在其他环境部署时,需要提供兼容的 Worker 环境与 `DB` 绑定;云端 API 还依赖托管层提供的 `oai-authenticated-user-id` 请求头。
|
||||
|
||||
## 项目结构
|
||||
|
||||
@@ -48,14 +57,19 @@ public/index.html 桌面框架与窗口基础交互
|
||||
public/tasks.js 目标与待办
|
||||
public/calendar.js 日历
|
||||
public/browser-app.js iframe 浏览器
|
||||
public/terminal-app.js 命令解析与终端界面
|
||||
public/db-admin.js 数据库管理器界面
|
||||
public/data-actions.js 图形界面与终端共用的数据写入
|
||||
public/i18n-renderers.js 记忆、洞察、设置等双语界面
|
||||
public/desktop-personalization.js 图标、窗口与壁纸偏好
|
||||
public/desktop-widgets.js 吸附网格与桌面小部件
|
||||
public/addons.js 导入导出、云同步与辅助操作
|
||||
public/locales/ 中文、英文文案
|
||||
public/service-worker.js PWA 缓存
|
||||
worker/index.js Worker 路由、数据 API、必应图片代理
|
||||
drizzle/ D1 初始迁移
|
||||
worker/index.js Worker 路由与必应图片代理
|
||||
worker/cloud-state.js 云端记录迁移与同步 API
|
||||
worker/db-admin.js 当前用户的数据库管理 API
|
||||
drizzle/ D1 数据表迁移
|
||||
scripts/ 构建与产物验证
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
CREATE TABLE lifeos_migrations (
|
||||
user_id TEXT PRIMARY KEY,
|
||||
migrated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE lifeos_meta (
|
||||
user_id TEXT NOT NULL,
|
||||
kind TEXT NOT NULL CHECK (kind IN ('profile', 'settings', 'system')),
|
||||
value_json TEXT NOT NULL,
|
||||
revision INTEGER NOT NULL DEFAULT 1,
|
||||
updated_at TEXT NOT NULL,
|
||||
PRIMARY KEY (user_id, kind)
|
||||
);
|
||||
|
||||
CREATE TABLE lifeos_memories (
|
||||
user_id TEXT NOT NULL,
|
||||
id TEXT NOT NULL,
|
||||
memory_date TEXT,
|
||||
value_json TEXT NOT NULL,
|
||||
revision INTEGER NOT NULL DEFAULT 1,
|
||||
updated_at TEXT NOT NULL,
|
||||
deleted_at TEXT,
|
||||
PRIMARY KEY (user_id, id)
|
||||
);
|
||||
CREATE INDEX idx_lifeos_memories_user_date ON lifeos_memories(user_id, memory_date DESC) WHERE deleted_at IS NULL;
|
||||
|
||||
CREATE TABLE lifeos_memory_tags (
|
||||
user_id TEXT NOT NULL,
|
||||
memory_id TEXT NOT NULL,
|
||||
tag TEXT NOT NULL,
|
||||
PRIMARY KEY (user_id, memory_id, tag),
|
||||
FOREIGN KEY (user_id, memory_id) REFERENCES lifeos_memories(user_id, id)
|
||||
);
|
||||
CREATE INDEX idx_lifeos_memory_tags_user_tag ON lifeos_memory_tags(user_id, tag);
|
||||
CREATE TRIGGER lifeos_memory_tags_insert AFTER INSERT ON lifeos_memories
|
||||
WHEN NEW.deleted_at IS NULL
|
||||
BEGIN
|
||||
INSERT OR IGNORE INTO lifeos_memory_tags(user_id, memory_id, tag)
|
||||
SELECT NEW.user_id, NEW.id, value FROM json_each(NEW.value_json, '$.tags')
|
||||
WHERE type = 'text' AND value <> '';
|
||||
END;
|
||||
CREATE TRIGGER lifeos_memory_tags_update AFTER UPDATE OF value_json, deleted_at ON lifeos_memories
|
||||
BEGIN
|
||||
DELETE FROM lifeos_memory_tags WHERE user_id = NEW.user_id AND memory_id = NEW.id;
|
||||
INSERT OR IGNORE INTO lifeos_memory_tags(user_id, memory_id, tag)
|
||||
SELECT NEW.user_id, NEW.id, value FROM json_each(NEW.value_json, '$.tags')
|
||||
WHERE NEW.deleted_at IS NULL AND type = 'text' AND value <> '';
|
||||
END;
|
||||
|
||||
CREATE TABLE lifeos_goals (
|
||||
user_id TEXT NOT NULL,
|
||||
id TEXT NOT NULL,
|
||||
target_date TEXT,
|
||||
done INTEGER NOT NULL DEFAULT 0,
|
||||
value_json TEXT NOT NULL,
|
||||
revision INTEGER NOT NULL DEFAULT 1,
|
||||
updated_at TEXT NOT NULL,
|
||||
deleted_at TEXT,
|
||||
PRIMARY KEY (user_id, id)
|
||||
);
|
||||
CREATE INDEX idx_lifeos_goals_user_status_date ON lifeos_goals(user_id, done, target_date) WHERE deleted_at IS NULL;
|
||||
|
||||
CREATE TABLE lifeos_tasks (
|
||||
user_id TEXT NOT NULL,
|
||||
id TEXT NOT NULL,
|
||||
goal_id TEXT,
|
||||
due_date TEXT,
|
||||
done INTEGER NOT NULL DEFAULT 0,
|
||||
value_json TEXT NOT NULL,
|
||||
revision INTEGER NOT NULL DEFAULT 1,
|
||||
updated_at TEXT NOT NULL,
|
||||
deleted_at TEXT,
|
||||
PRIMARY KEY (user_id, id)
|
||||
);
|
||||
CREATE INDEX idx_lifeos_tasks_user_status_date ON lifeos_tasks(user_id, done, due_date) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX idx_lifeos_tasks_user_goal ON lifeos_tasks(user_id, goal_id) WHERE deleted_at IS NULL;
|
||||
|
||||
CREATE TABLE lifeos_favorites (
|
||||
user_id TEXT NOT NULL,
|
||||
id TEXT NOT NULL,
|
||||
memory_id TEXT,
|
||||
value_json TEXT NOT NULL,
|
||||
revision INTEGER NOT NULL DEFAULT 1,
|
||||
updated_at TEXT NOT NULL,
|
||||
deleted_at TEXT,
|
||||
PRIMARY KEY (user_id, id)
|
||||
);
|
||||
CREATE INDEX idx_lifeos_favorites_user_memory ON lifeos_favorites(user_id, memory_id) WHERE deleted_at IS NULL;
|
||||
Loaded 3 of 23 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user