luckytri 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.en.md +2 -0
- package/README.md +2 -0
- package/docs/en/CHANGELOG.md +20 -13
- package/docs/en/guide.md +7 -5
- package/docs/en/her-life.md +2 -2
- package/docs/en/webui.md +1 -1
- package/docs/zh/CHANGELOG.md +20 -13
- package/docs/zh/guide.md +7 -5
- package/docs/zh/her-life.md +2 -2
- package/docs/zh/webui.md +1 -1
- package/package.json +2 -1
- package/public/app/assets/ChatsPage-CFMVozoG.css +1 -0
- package/public/app/assets/{ChatsPage-CshdtTzV.js → ChatsPage-DCYMkJ91.js} +2 -2
- package/public/app/assets/{Empty-C7yzOBzy.js → Empty-CLyZkxR5.js} +1 -1
- package/public/app/assets/{Empty-DmUB2-Bk.css → Empty-DIobYG3x.css} +1 -1
- package/public/app/assets/{Field-BjFv4Rfn.js → Field-BpaRwLI_.js} +1 -1
- package/public/app/assets/{HeartPage-eqo6ru16.js → HeartPage-BIOMTiwr.js} +1 -1
- package/public/app/assets/HeartPage-C-2jvgzF.css +1 -0
- package/public/app/assets/{LifePage-CN8GE5NK.js → LifePage-BCgM4JkR.js} +1 -1
- package/public/app/assets/LifePage-CG1OHbRK.css +1 -0
- package/public/app/assets/MemoryPage-C_Bu4rfb.css +1 -0
- package/public/app/assets/{MemoryPage-CCpMN4Wg.js → MemoryPage-vShvRqMt.js} +1 -1
- package/public/app/assets/NaturePage-CPZlImT0.css +1 -0
- package/public/app/assets/{NaturePage-C0JqdBTR.js → NaturePage-Cy9ptr4G.js} +2 -2
- package/public/app/assets/PeoplePage-3RRUITDz.css +1 -0
- package/public/app/assets/{PeoplePage-BXGBbO4u.js → PeoplePage-CUZekB2E.js} +1 -1
- package/public/app/assets/{PluginsPage-Dksp5AV5.js → PluginsPage-1RM4rmJP.js} +1 -1
- package/public/app/assets/{SystemPage-BenIyTvk.css → SystemPage-BI2CB5Ig.css} +1 -1
- package/public/app/assets/{SystemPage-Cd7aa8eE.js → SystemPage-BeT5TmIV.js} +1 -1
- package/public/app/assets/TimePage-C-guwPk2.css +1 -0
- package/public/app/assets/{TimePage-Bs_zImb4.js → TimePage-taTmPMM8.js} +2 -2
- package/public/app/assets/{index-BHZcHUMh.css → index-DY5AM0Hz.css} +1 -1
- package/public/app/assets/{index-CyRtYxP3.js → index-DdYwC5ZU.js} +3 -3
- package/public/app/assets/{knowledge-BJOIyuJo.js → knowledge-DJmfu2KN.js} +1 -1
- package/public/app/assets/{media-Bwtx8blz.js → media-BEtnE0Gv.js} +1 -1
- package/public/app/assets/{mind-DtTVrW6Z.js → mind-Dtiw0-QK.js} +1 -1
- package/public/app/index.html +6 -5
- package/public/guide.en.html +11 -3
- package/public/guide.html +6 -3
- package/public/tutorial.en.md +2 -0
- package/public/tutorial.md +2 -0
- package/scripts/import-data.js +128 -128
- package/scripts/proxy-config.js +167 -167
- package/scripts/service-supervisor.js +50 -0
- package/scripts/start-server.js +71 -16
- package/scripts/update-instance.js +201 -201
- package/server/channels/adapters.js +27 -27
- package/server/channels/onebot/adapter.js +288 -288
- package/server/channels/qqbot/adapter.js +253 -253
- package/server/channels/qqbot/api.js +199 -199
- package/server/channels/qqbot/credentials.js +11 -11
- package/server/channels/qqbot/gateway.js +274 -274
- package/server/channels/qqbot/index.js +389 -389
- package/server/channels/segments.js +40 -40
- package/server/channels/session-key.js +153 -153
- package/server/channels/state.js +42 -42
- package/server/core/api.js +564 -564
- package/server/core/context-builder.js +288 -288
- package/server/core/context-compactor.js +454 -454
- package/server/core/conversation-cues.js +325 -325
- package/server/core/conversation-manager.js +87 -87
- package/server/core/feedback.js +8 -8
- package/server/core/group-style.js +72 -72
- package/server/core/initiative-context.js +66 -66
- package/server/core/input-budget.js +32 -32
- package/server/core/local-demo.js +98 -98
- package/server/core/message-manager.js +118 -118
- package/server/core/message-scheduler.js +78 -78
- package/server/core/model-json.js +190 -190
- package/server/core/model-presets.js +900 -900
- package/server/core/name-call.js +29 -29
- package/server/core/network.js +157 -157
- package/server/core/person-name.js +22 -22
- package/server/core/persona-manager.js +2 -1
- package/server/core/reply-delivery.js +404 -403
- package/server/core/reply-target-resolver.js +50 -50
- package/server/core/response-generator.js +50 -50
- package/server/core/response-validator.js +14 -2
- package/server/core/retired-prompts.js +51 -51
- package/server/core/sessions.js +109 -109
- package/server/core/speaker-names.js +92 -92
- package/server/core/topic-tracker.js +65 -65
- package/server/http.js +18 -18
- package/server/i18n/decisions.js +209 -206
- package/server/i18n/errors.js +4 -0
- package/server/i18n/index.js +144 -144
- package/server/i18n/models.js +111 -111
- package/server/knowledge/api.js +342 -342
- package/server/knowledge/embedding-profile.js +114 -114
- package/server/knowledge/index.js +13 -13
- package/server/knowledge/retrieval.js +93 -93
- package/server/knowledge/schema.js +158 -158
- package/server/knowledge/vector-index.js +90 -90
- package/server/mind/affect.js +265 -265
- package/server/mind/attention.js +200 -200
- package/server/mind/bonds.js +565 -565
- package/server/mind/clock.js +83 -83
- package/server/mind/continuity.js +562 -562
- package/server/mind/conversation-origin.js +175 -175
- package/server/mind/days.js +210 -210
- package/server/mind/evidence-read.js +45 -45
- package/server/mind/faces.js +373 -373
- package/server/mind/guard.js +60 -60
- package/server/mind/initiative.js +338 -338
- package/server/mind/life/activities.js +21 -21
- package/server/mind/life/context.js +330 -323
- package/server/mind/life/diary.js +20 -0
- package/server/mind/life/growth.js +261 -254
- package/server/mind/life/index.js +10 -2
- package/server/mind/life/presence.js +305 -305
- package/server/mind/meetings.js +1069 -1069
- package/server/mind/memory-policy.js +48 -48
- package/server/mind/memory.js +888 -888
- package/server/mind/nature.js +358 -358
- package/server/mind/novelty.js +19 -19
- package/server/mind/periods.js +118 -118
- package/server/mind/reading.js +120 -120
- package/server/mind/relationship-context.js +71 -0
- package/server/mind/relationships.js +390 -279
- package/server/mind/salience.js +201 -201
- package/server/mind/schema.js +567 -567
- package/server/mind/self.js +484 -484
- package/server/mind/thoughts.js +274 -274
- package/server/mind/time/agenda.js +242 -242
- package/server/mind/time/api.js +200 -200
- package/server/mind/time/attention.js +34 -34
- package/server/mind/time/delivery-links.js +130 -130
- package/server/mind/time/model-material.js +77 -77
- package/server/mind/time/presentation.js +51 -51
- package/server/mind/time/schedule.js +83 -83
- package/server/mind/time/schema.js +84 -84
- package/server/mind/time/search.js +383 -383
- package/server/mind/time/sharing.js +472 -472
- package/server/mind/time/task-links.js +311 -311
- package/server/mind/time/works.js +432 -432
- package/server/mind/traits.js +191 -191
- package/server/mind/view.js +9 -1
- package/server/runtime/installation.js +116 -116
- package/server/runtime/update-execution.js +2 -1
- package/server/runtime/update-manager.js +140 -140
- package/server/storage/data-package.js +298 -298
- package/server/storage/data-transfer-api.js +50 -50
- package/server/storage/data-transfer-worker.js +18 -18
- package/server/storage/data-transfer.js +416 -416
- package/server/studio/display-names.js +139 -139
- package/server/studio/management.js +102 -102
- package/server/studio/updates.js +144 -144
- package/server/version.js +10 -10
- package/public/app/assets/ChatsPage-DfyPCS9N.css +0 -1
- package/public/app/assets/HeartPage-Bft9wZp5.css +0 -1
- package/public/app/assets/LifePage-BUi5euBF.css +0 -1
- package/public/app/assets/MemoryPage-cZvXfkXb.css +0 -1
- package/public/app/assets/NaturePage-CHkpb5NK.css +0 -1
- package/public/app/assets/PeoplePage-BTU0H1pM.css +0 -1
- package/public/app/assets/TimePage-BOms_n4I.css +0 -1
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
import { dayKey, zonedTime } from "../util.js";
|
|
2
|
-
import { localClock } from "../../core/conversation-cues.js";
|
|
3
|
-
import { gameText } from "./presentation.js";
|
|
4
|
-
export function spokenDate(words, at, zone) {
|
|
5
|
-
const absolute = String(words).match(/20\d{2}-\d{2}-\d{2}(?: \d{2}:\d{2})?/);
|
|
6
|
-
if (absolute)
|
|
7
|
-
return {
|
|
8
|
-
dueAt: zonedTime(absolute[0], zone),
|
|
9
|
-
duePrecision: absolute[0].includes(":") ? "time" : "day",
|
|
10
|
-
};
|
|
11
|
-
if (/后天|明天|明晚|今晚|今天/.test(words)) {
|
|
12
|
-
const offset = /后天/.test(words) ? 2 : /明天|明晚/.test(words) ? 1 : 0;
|
|
13
|
-
return {
|
|
14
|
-
dueAt: zonedTime(dayKey(at + offset * 86400000, zone) + " 23:59", zone),
|
|
15
|
-
duePrecision: "day",
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
return { dueAt: null, duePrecision: "none" };
|
|
19
|
-
}
|
|
20
|
-
export function nextAwakeSlot(mind, now) {
|
|
21
|
-
const zone = mind.timeZone(),
|
|
22
|
-
rhythm = mind.nature.current(now).rhythm;
|
|
23
|
-
let at = Math.ceil(now / 300000) * 300000;
|
|
24
|
-
if (rhythm?.enabled) {
|
|
25
|
-
const clock = localClock(now, zone),
|
|
26
|
-
wake = zonedTime(dayKey(now, zone) + " " + rhythm.wake, zone);
|
|
27
|
-
if (wake > now) at = wake;
|
|
28
|
-
else if (
|
|
29
|
-
mind.affect.state(now).phase === "asleep" ||
|
|
30
|
-
mind.affect.state(now).phase === "sleepy"
|
|
31
|
-
)
|
|
32
|
-
at = zonedTime(dayKey(now + 86400000, zone) + " " + rhythm.wake, zone);
|
|
33
|
-
}
|
|
34
|
-
return at;
|
|
35
|
-
}
|
|
36
|
-
export function deadlineAt(at, precision, zone) {
|
|
37
|
-
if (!Number.isFinite(at)) return null;
|
|
38
|
-
return precision === "day"
|
|
39
|
-
? zonedTime(dayKey(at, zone) + " 23:59", zone) + 59999
|
|
40
|
-
: at;
|
|
41
|
-
}
|
|
42
|
-
export function taskSchedule(task, time, now = time.now()) {
|
|
43
|
-
const plan = task.checkpoint?.schedule;
|
|
44
|
-
const waiting = task.state === "waiting";
|
|
45
|
-
const focus =
|
|
46
|
-
plan?.durationMinutes || plan?.focusMinutes || time.settings().focusMinutes;
|
|
47
|
-
const proposed =
|
|
48
|
-
plan?.chosenAt || plan?.proposedAt > now
|
|
49
|
-
? plan.proposedAt
|
|
50
|
-
: task.state === "scheduled" && task.ready_at > now
|
|
51
|
-
? task.ready_at
|
|
52
|
-
: null;
|
|
53
|
-
const live =
|
|
54
|
-
task.state === "doing"
|
|
55
|
-
? time.db
|
|
56
|
-
.prepare(
|
|
57
|
-
"SELECT started FROM mind_time_spans WHERE task_id=? AND ended IS NULL",
|
|
58
|
-
)
|
|
59
|
-
.get(task.id)
|
|
60
|
-
: null;
|
|
61
|
-
return {
|
|
62
|
-
earliestAt: task.ready_at,
|
|
63
|
-
proposedAt: proposed,
|
|
64
|
-
proposedEnd: proposed ? proposed + focus * 60000 : null,
|
|
65
|
-
startedAt: live?.started || null,
|
|
66
|
-
focusMinutes: focus,
|
|
67
|
-
chosenAt: plan?.chosenAt || null,
|
|
68
|
-
chosenBy: plan?.chosenBy || null,
|
|
69
|
-
durationMinutes: plan?.durationMinutes || null,
|
|
70
|
-
reason: plan?.reason || "",
|
|
71
|
-
conditional: waiting,
|
|
72
|
-
deadlinePrecision: task.due_precision || "time",
|
|
73
|
-
deadlineAt: task.due_at,
|
|
74
|
-
nextAttemptAt:
|
|
75
|
-
task.next_step > now && task.next_step < 8e15 ? task.next_step : null,
|
|
76
|
-
outcome:
|
|
77
|
-
task.activity === "game"
|
|
78
|
-
? gameText(plan?.outcome || task.checkpoint?.contract?.outcome || "")
|
|
79
|
-
: plan?.outcome || task.checkpoint?.contract?.outcome || "",
|
|
80
|
-
estimatedMs: task.checkpoint?.activityClock?.plannedMs || null,
|
|
81
|
-
condition: waiting ? task.wait_reason : "",
|
|
82
|
-
};
|
|
83
|
-
}
|
|
1
|
+
import { dayKey, zonedTime } from "../util.js";
|
|
2
|
+
import { localClock } from "../../core/conversation-cues.js";
|
|
3
|
+
import { gameText } from "./presentation.js";
|
|
4
|
+
export function spokenDate(words, at, zone) {
|
|
5
|
+
const absolute = String(words).match(/20\d{2}-\d{2}-\d{2}(?: \d{2}:\d{2})?/);
|
|
6
|
+
if (absolute)
|
|
7
|
+
return {
|
|
8
|
+
dueAt: zonedTime(absolute[0], zone),
|
|
9
|
+
duePrecision: absolute[0].includes(":") ? "time" : "day",
|
|
10
|
+
};
|
|
11
|
+
if (/后天|明天|明晚|今晚|今天/.test(words)) {
|
|
12
|
+
const offset = /后天/.test(words) ? 2 : /明天|明晚/.test(words) ? 1 : 0;
|
|
13
|
+
return {
|
|
14
|
+
dueAt: zonedTime(dayKey(at + offset * 86400000, zone) + " 23:59", zone),
|
|
15
|
+
duePrecision: "day",
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return { dueAt: null, duePrecision: "none" };
|
|
19
|
+
}
|
|
20
|
+
export function nextAwakeSlot(mind, now) {
|
|
21
|
+
const zone = mind.timeZone(),
|
|
22
|
+
rhythm = mind.nature.current(now).rhythm;
|
|
23
|
+
let at = Math.ceil(now / 300000) * 300000;
|
|
24
|
+
if (rhythm?.enabled) {
|
|
25
|
+
const clock = localClock(now, zone),
|
|
26
|
+
wake = zonedTime(dayKey(now, zone) + " " + rhythm.wake, zone);
|
|
27
|
+
if (wake > now) at = wake;
|
|
28
|
+
else if (
|
|
29
|
+
mind.affect.state(now).phase === "asleep" ||
|
|
30
|
+
mind.affect.state(now).phase === "sleepy"
|
|
31
|
+
)
|
|
32
|
+
at = zonedTime(dayKey(now + 86400000, zone) + " " + rhythm.wake, zone);
|
|
33
|
+
}
|
|
34
|
+
return at;
|
|
35
|
+
}
|
|
36
|
+
export function deadlineAt(at, precision, zone) {
|
|
37
|
+
if (!Number.isFinite(at)) return null;
|
|
38
|
+
return precision === "day"
|
|
39
|
+
? zonedTime(dayKey(at, zone) + " 23:59", zone) + 59999
|
|
40
|
+
: at;
|
|
41
|
+
}
|
|
42
|
+
export function taskSchedule(task, time, now = time.now()) {
|
|
43
|
+
const plan = task.checkpoint?.schedule;
|
|
44
|
+
const waiting = task.state === "waiting";
|
|
45
|
+
const focus =
|
|
46
|
+
plan?.durationMinutes || plan?.focusMinutes || time.settings().focusMinutes;
|
|
47
|
+
const proposed =
|
|
48
|
+
plan?.chosenAt || plan?.proposedAt > now
|
|
49
|
+
? plan.proposedAt
|
|
50
|
+
: task.state === "scheduled" && task.ready_at > now
|
|
51
|
+
? task.ready_at
|
|
52
|
+
: null;
|
|
53
|
+
const live =
|
|
54
|
+
task.state === "doing"
|
|
55
|
+
? time.db
|
|
56
|
+
.prepare(
|
|
57
|
+
"SELECT started FROM mind_time_spans WHERE task_id=? AND ended IS NULL",
|
|
58
|
+
)
|
|
59
|
+
.get(task.id)
|
|
60
|
+
: null;
|
|
61
|
+
return {
|
|
62
|
+
earliestAt: task.ready_at,
|
|
63
|
+
proposedAt: proposed,
|
|
64
|
+
proposedEnd: proposed ? proposed + focus * 60000 : null,
|
|
65
|
+
startedAt: live?.started || null,
|
|
66
|
+
focusMinutes: focus,
|
|
67
|
+
chosenAt: plan?.chosenAt || null,
|
|
68
|
+
chosenBy: plan?.chosenBy || null,
|
|
69
|
+
durationMinutes: plan?.durationMinutes || null,
|
|
70
|
+
reason: plan?.reason || "",
|
|
71
|
+
conditional: waiting,
|
|
72
|
+
deadlinePrecision: task.due_precision || "time",
|
|
73
|
+
deadlineAt: task.due_at,
|
|
74
|
+
nextAttemptAt:
|
|
75
|
+
task.next_step > now && task.next_step < 8e15 ? task.next_step : null,
|
|
76
|
+
outcome:
|
|
77
|
+
task.activity === "game"
|
|
78
|
+
? gameText(plan?.outcome || task.checkpoint?.contract?.outcome || "")
|
|
79
|
+
: plan?.outcome || task.checkpoint?.contract?.outcome || "",
|
|
80
|
+
estimatedMs: task.checkpoint?.activityClock?.plannedMs || null,
|
|
81
|
+
condition: waiting ? task.wait_reason : "",
|
|
82
|
+
};
|
|
83
|
+
}
|
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
export function migrateTime(db) {
|
|
2
|
-
db.exec(`
|
|
3
|
-
CREATE TABLE IF NOT EXISTS mind_time_projects(id TEXT PRIMARY KEY,created INTEGER NOT NULL,updated INTEGER NOT NULL,kind TEXT NOT NULL,title TEXT NOT NULL,why TEXT NOT NULL DEFAULT '',state TEXT NOT NULL DEFAULT 'active',session_id TEXT,discretion TEXT NOT NULL DEFAULT 'open',sources TEXT NOT NULL DEFAULT '[]',bible TEXT NOT NULL DEFAULT '{}',summary TEXT NOT NULL DEFAULT '',serial INTEGER NOT NULL DEFAULT 0,revision INTEGER NOT NULL DEFAULT 1);
|
|
4
|
-
CREATE TABLE IF NOT EXISTS mind_time_tasks(id TEXT PRIMARY KEY,created INTEGER NOT NULL,updated INTEGER NOT NULL,kind TEXT NOT NULL,activity TEXT NOT NULL,title TEXT NOT NULL,why TEXT NOT NULL DEFAULT '',state TEXT NOT NULL DEFAULT 'todo',ready_at INTEGER NOT NULL,due_at INTEGER,session_id TEXT,subject TEXT,discretion TEXT NOT NULL DEFAULT 'open',sources TEXT NOT NULL DEFAULT '[]',anticipation_id TEXT UNIQUE,project_id TEXT,work_id TEXT,checkpoint TEXT NOT NULL DEFAULT '{}',revision INTEGER NOT NULL DEFAULT 1,next_step INTEGER NOT NULL DEFAULT 0,wait_reason TEXT NOT NULL DEFAULT '',share_state TEXT NOT NULL DEFAULT 'none',share_reason TEXT NOT NULL DEFAULT '',depends_on TEXT,lease TEXT,lease_at INTEGER,completed INTEGER);
|
|
5
|
-
CREATE INDEX IF NOT EXISTS mind_time_tasks_queue ON mind_time_tasks(state,ready_at,next_step);
|
|
6
|
-
CREATE UNIQUE INDEX IF NOT EXISTS mind_time_single_main ON mind_time_tasks((1)) WHERE state='doing';
|
|
7
|
-
CREATE TABLE IF NOT EXISTS mind_time_spans(id TEXT PRIMARY KEY,task_id TEXT NOT NULL,started INTEGER NOT NULL,updated INTEGER NOT NULL,ended INTEGER,active_ms INTEGER NOT NULL DEFAULT 0);
|
|
8
|
-
CREATE INDEX IF NOT EXISTS mind_time_spans_task ON mind_time_spans(task_id,started);
|
|
9
|
-
CREATE TABLE IF NOT EXISTS mind_time_events(id INTEGER PRIMARY KEY,created INTEGER NOT NULL,task_id TEXT,kind TEXT NOT NULL,reason TEXT NOT NULL DEFAULT '',data TEXT NOT NULL DEFAULT '{}');
|
|
10
|
-
CREATE INDEX IF NOT EXISTS mind_time_events_time ON mind_time_events(created);
|
|
11
|
-
CREATE TABLE IF NOT EXISTS mind_time_works(id TEXT PRIMARY KEY,created INTEGER NOT NULL,updated INTEGER NOT NULL,task_id TEXT,project_id TEXT,ordinal INTEGER NOT NULL DEFAULT 1,title TEXT NOT NULL,state TEXT NOT NULL DEFAULT 'draft',version INTEGER NOT NULL DEFAULT 0,session_id TEXT,discretion TEXT NOT NULL DEFAULT 'open',legacy_creation TEXT UNIQUE,UNIQUE(project_id,ordinal));
|
|
12
|
-
CREATE TABLE IF NOT EXISTS mind_time_versions(id TEXT PRIMARY KEY,work_id TEXT NOT NULL,version INTEGER NOT NULL,created INTEGER NOT NULL,title TEXT NOT NULL,content TEXT NOT NULL,summary TEXT NOT NULL DEFAULT '',sources TEXT NOT NULL DEFAULT '[]',run_id TEXT,UNIQUE(work_id,version));
|
|
13
|
-
CREATE INDEX IF NOT EXISTS mind_time_versions_work ON mind_time_versions(work_id,version);
|
|
14
|
-
CREATE INDEX IF NOT EXISTS mind_time_works_recent ON mind_time_works(updated DESC);
|
|
15
|
-
CREATE INDEX IF NOT EXISTS mind_time_works_task ON mind_time_works(task_id);
|
|
16
|
-
CREATE INDEX IF NOT EXISTS mind_time_projects_recent ON mind_time_projects(updated DESC);
|
|
17
|
-
CREATE TABLE IF NOT EXISTS mind_time_sources(id TEXT PRIMARY KEY,project_id TEXT NOT NULL,created INTEGER NOT NULL,title TEXT NOT NULL,url TEXT NOT NULL,content TEXT NOT NULL,hash TEXT NOT NULL,UNIQUE(project_id,url,hash));
|
|
18
|
-
CREATE TABLE IF NOT EXISTS mind_time_searches(id INTEGER PRIMARY KEY,created INTEGER NOT NULL,provider TEXT NOT NULL,query TEXT NOT NULL,state TEXT NOT NULL,error TEXT NOT NULL DEFAULT '');
|
|
19
|
-
CREATE TABLE IF NOT EXISTS mind_time_shares(id TEXT PRIMARY KEY,created INTEGER NOT NULL,updated INTEGER NOT NULL,work_id TEXT NOT NULL,version INTEGER NOT NULL,session_id TEXT NOT NULL,offset INTEGER NOT NULL DEFAULT 0,state TEXT NOT NULL DEFAULT 'pending',reason TEXT NOT NULL DEFAULT '',trace_id TEXT,UNIQUE(work_id,version,session_id));
|
|
20
|
-
CREATE TABLE IF NOT EXISTS mind_time_task_aliases(kind TEXT NOT NULL,alias_id TEXT NOT NULL,task_id TEXT NOT NULL,created INTEGER NOT NULL,PRIMARY KEY(kind,alias_id));
|
|
21
|
-
CREATE INDEX IF NOT EXISTS mind_time_task_aliases_task ON mind_time_task_aliases(task_id);
|
|
22
|
-
CREATE TABLE IF NOT EXISTS mind_time_activity_ticks(span_id TEXT NOT NULL,started INTEGER NOT NULL,ended INTEGER NOT NULL,PRIMARY KEY(span_id,ended));
|
|
23
|
-
CREATE INDEX IF NOT EXISTS mind_time_activity_ticks_time ON mind_time_activity_ticks(ended,started);
|
|
24
|
-
CREATE TABLE IF NOT EXISTS mind_time_commitment_reviews(seq INTEGER PRIMARY KEY,reviewed INTEGER NOT NULL,task_ids TEXT NOT NULL DEFAULT '[]');
|
|
25
|
-
CREATE INDEX IF NOT EXISTS mind_time_assistant_review ON core_events(seq,time,session_id) WHERE role='assistant';
|
|
26
|
-
CREATE INDEX IF NOT EXISTS mind_time_source_lookup ON mind_time_task_aliases(kind,substr(alias_id,instr(alias_id,':')+1));
|
|
27
|
-
`);
|
|
28
|
-
const columns = new Set(
|
|
29
|
-
db
|
|
30
|
-
.prepare("PRAGMA table_info(mind_time_tasks)")
|
|
31
|
-
.all()
|
|
32
|
-
.map((c) => c.name),
|
|
33
|
-
);
|
|
34
|
-
if (!columns.has("intent_key"))
|
|
35
|
-
db.exec("ALTER TABLE mind_time_tasks ADD COLUMN intent_key TEXT");
|
|
36
|
-
if (!columns.has("due_precision"))
|
|
37
|
-
db.exec(
|
|
38
|
-
"ALTER TABLE mind_time_tasks ADD COLUMN due_precision TEXT NOT NULL DEFAULT 'time'",
|
|
39
|
-
);
|
|
40
|
-
if (!columns.has("priority"))
|
|
41
|
-
db.exec(
|
|
42
|
-
"ALTER TABLE mind_time_tasks ADD COLUMN priority INTEGER NOT NULL DEFAULT 1 CHECK(priority BETWEEN 0 AND 3); UPDATE mind_time_tasks SET priority=2 WHERE kind='promise';",
|
|
43
|
-
);
|
|
44
|
-
db.exec(
|
|
45
|
-
"CREATE INDEX IF NOT EXISTS mind_time_tasks_intent ON mind_time_tasks(intent_key);",
|
|
46
|
-
);
|
|
47
|
-
const sourceColumns = new Set(
|
|
48
|
-
db
|
|
49
|
-
.prepare("PRAGMA table_info(mind_time_sources)")
|
|
50
|
-
.all()
|
|
51
|
-
.map((c) => c.name),
|
|
52
|
-
);
|
|
53
|
-
for (const [name, fallback] of [
|
|
54
|
-
["kind", "web"],
|
|
55
|
-
["model", ""],
|
|
56
|
-
["uncertainty", ""],
|
|
57
|
-
])
|
|
58
|
-
if (!sourceColumns.has(name))
|
|
59
|
-
db.exec(
|
|
60
|
-
`ALTER TABLE mind_time_sources ADD COLUMN ${name} TEXT NOT NULL DEFAULT '${fallback}'`,
|
|
61
|
-
);
|
|
62
|
-
for (const [table, column, type, fallback] of [
|
|
63
|
-
["mind_time_sources", "timing", "TEXT", "'{}'"],
|
|
64
|
-
["mind_time_versions", "provenance", "TEXT", "'{}'"],
|
|
65
|
-
["mind_time_spans", "engaged_ms", "INTEGER", "0"],
|
|
66
|
-
["mind_time_spans", "clocked", "INTEGER", "0"],
|
|
67
|
-
["mind_time_shares", "review_offset", "INTEGER", "0"],
|
|
68
|
-
["mind_time_shares", "review_notes", "TEXT", "'[]'"],
|
|
69
|
-
["mind_time_shares", "report", "TEXT", "'[]'"],
|
|
70
|
-
["mind_time_shares", "send_index", "INTEGER", "0"],
|
|
71
|
-
["mind_time_shares", "delivery_kind", "TEXT", "'body'"],
|
|
72
|
-
["mind_time_shares", "next_step", "INTEGER", "0"],
|
|
73
|
-
["mind_time_searches", "purpose", "TEXT", "'activity'"],
|
|
74
|
-
])
|
|
75
|
-
if (
|
|
76
|
-
!db
|
|
77
|
-
.prepare(`PRAGMA table_info(${table})`)
|
|
78
|
-
.all()
|
|
79
|
-
.some((c) => c.name === column)
|
|
80
|
-
)
|
|
81
|
-
db.exec(
|
|
82
|
-
`ALTER TABLE ${table} ADD COLUMN ${column} ${type} NOT NULL DEFAULT ${fallback}`,
|
|
83
|
-
);
|
|
84
|
-
}
|
|
1
|
+
export function migrateTime(db) {
|
|
2
|
+
db.exec(`
|
|
3
|
+
CREATE TABLE IF NOT EXISTS mind_time_projects(id TEXT PRIMARY KEY,created INTEGER NOT NULL,updated INTEGER NOT NULL,kind TEXT NOT NULL,title TEXT NOT NULL,why TEXT NOT NULL DEFAULT '',state TEXT NOT NULL DEFAULT 'active',session_id TEXT,discretion TEXT NOT NULL DEFAULT 'open',sources TEXT NOT NULL DEFAULT '[]',bible TEXT NOT NULL DEFAULT '{}',summary TEXT NOT NULL DEFAULT '',serial INTEGER NOT NULL DEFAULT 0,revision INTEGER NOT NULL DEFAULT 1);
|
|
4
|
+
CREATE TABLE IF NOT EXISTS mind_time_tasks(id TEXT PRIMARY KEY,created INTEGER NOT NULL,updated INTEGER NOT NULL,kind TEXT NOT NULL,activity TEXT NOT NULL,title TEXT NOT NULL,why TEXT NOT NULL DEFAULT '',state TEXT NOT NULL DEFAULT 'todo',ready_at INTEGER NOT NULL,due_at INTEGER,session_id TEXT,subject TEXT,discretion TEXT NOT NULL DEFAULT 'open',sources TEXT NOT NULL DEFAULT '[]',anticipation_id TEXT UNIQUE,project_id TEXT,work_id TEXT,checkpoint TEXT NOT NULL DEFAULT '{}',revision INTEGER NOT NULL DEFAULT 1,next_step INTEGER NOT NULL DEFAULT 0,wait_reason TEXT NOT NULL DEFAULT '',share_state TEXT NOT NULL DEFAULT 'none',share_reason TEXT NOT NULL DEFAULT '',depends_on TEXT,lease TEXT,lease_at INTEGER,completed INTEGER);
|
|
5
|
+
CREATE INDEX IF NOT EXISTS mind_time_tasks_queue ON mind_time_tasks(state,ready_at,next_step);
|
|
6
|
+
CREATE UNIQUE INDEX IF NOT EXISTS mind_time_single_main ON mind_time_tasks((1)) WHERE state='doing';
|
|
7
|
+
CREATE TABLE IF NOT EXISTS mind_time_spans(id TEXT PRIMARY KEY,task_id TEXT NOT NULL,started INTEGER NOT NULL,updated INTEGER NOT NULL,ended INTEGER,active_ms INTEGER NOT NULL DEFAULT 0);
|
|
8
|
+
CREATE INDEX IF NOT EXISTS mind_time_spans_task ON mind_time_spans(task_id,started);
|
|
9
|
+
CREATE TABLE IF NOT EXISTS mind_time_events(id INTEGER PRIMARY KEY,created INTEGER NOT NULL,task_id TEXT,kind TEXT NOT NULL,reason TEXT NOT NULL DEFAULT '',data TEXT NOT NULL DEFAULT '{}');
|
|
10
|
+
CREATE INDEX IF NOT EXISTS mind_time_events_time ON mind_time_events(created);
|
|
11
|
+
CREATE TABLE IF NOT EXISTS mind_time_works(id TEXT PRIMARY KEY,created INTEGER NOT NULL,updated INTEGER NOT NULL,task_id TEXT,project_id TEXT,ordinal INTEGER NOT NULL DEFAULT 1,title TEXT NOT NULL,state TEXT NOT NULL DEFAULT 'draft',version INTEGER NOT NULL DEFAULT 0,session_id TEXT,discretion TEXT NOT NULL DEFAULT 'open',legacy_creation TEXT UNIQUE,UNIQUE(project_id,ordinal));
|
|
12
|
+
CREATE TABLE IF NOT EXISTS mind_time_versions(id TEXT PRIMARY KEY,work_id TEXT NOT NULL,version INTEGER NOT NULL,created INTEGER NOT NULL,title TEXT NOT NULL,content TEXT NOT NULL,summary TEXT NOT NULL DEFAULT '',sources TEXT NOT NULL DEFAULT '[]',run_id TEXT,UNIQUE(work_id,version));
|
|
13
|
+
CREATE INDEX IF NOT EXISTS mind_time_versions_work ON mind_time_versions(work_id,version);
|
|
14
|
+
CREATE INDEX IF NOT EXISTS mind_time_works_recent ON mind_time_works(updated DESC);
|
|
15
|
+
CREATE INDEX IF NOT EXISTS mind_time_works_task ON mind_time_works(task_id);
|
|
16
|
+
CREATE INDEX IF NOT EXISTS mind_time_projects_recent ON mind_time_projects(updated DESC);
|
|
17
|
+
CREATE TABLE IF NOT EXISTS mind_time_sources(id TEXT PRIMARY KEY,project_id TEXT NOT NULL,created INTEGER NOT NULL,title TEXT NOT NULL,url TEXT NOT NULL,content TEXT NOT NULL,hash TEXT NOT NULL,UNIQUE(project_id,url,hash));
|
|
18
|
+
CREATE TABLE IF NOT EXISTS mind_time_searches(id INTEGER PRIMARY KEY,created INTEGER NOT NULL,provider TEXT NOT NULL,query TEXT NOT NULL,state TEXT NOT NULL,error TEXT NOT NULL DEFAULT '');
|
|
19
|
+
CREATE TABLE IF NOT EXISTS mind_time_shares(id TEXT PRIMARY KEY,created INTEGER NOT NULL,updated INTEGER NOT NULL,work_id TEXT NOT NULL,version INTEGER NOT NULL,session_id TEXT NOT NULL,offset INTEGER NOT NULL DEFAULT 0,state TEXT NOT NULL DEFAULT 'pending',reason TEXT NOT NULL DEFAULT '',trace_id TEXT,UNIQUE(work_id,version,session_id));
|
|
20
|
+
CREATE TABLE IF NOT EXISTS mind_time_task_aliases(kind TEXT NOT NULL,alias_id TEXT NOT NULL,task_id TEXT NOT NULL,created INTEGER NOT NULL,PRIMARY KEY(kind,alias_id));
|
|
21
|
+
CREATE INDEX IF NOT EXISTS mind_time_task_aliases_task ON mind_time_task_aliases(task_id);
|
|
22
|
+
CREATE TABLE IF NOT EXISTS mind_time_activity_ticks(span_id TEXT NOT NULL,started INTEGER NOT NULL,ended INTEGER NOT NULL,PRIMARY KEY(span_id,ended));
|
|
23
|
+
CREATE INDEX IF NOT EXISTS mind_time_activity_ticks_time ON mind_time_activity_ticks(ended,started);
|
|
24
|
+
CREATE TABLE IF NOT EXISTS mind_time_commitment_reviews(seq INTEGER PRIMARY KEY,reviewed INTEGER NOT NULL,task_ids TEXT NOT NULL DEFAULT '[]');
|
|
25
|
+
CREATE INDEX IF NOT EXISTS mind_time_assistant_review ON core_events(seq,time,session_id) WHERE role='assistant';
|
|
26
|
+
CREATE INDEX IF NOT EXISTS mind_time_source_lookup ON mind_time_task_aliases(kind,substr(alias_id,instr(alias_id,':')+1));
|
|
27
|
+
`);
|
|
28
|
+
const columns = new Set(
|
|
29
|
+
db
|
|
30
|
+
.prepare("PRAGMA table_info(mind_time_tasks)")
|
|
31
|
+
.all()
|
|
32
|
+
.map((c) => c.name),
|
|
33
|
+
);
|
|
34
|
+
if (!columns.has("intent_key"))
|
|
35
|
+
db.exec("ALTER TABLE mind_time_tasks ADD COLUMN intent_key TEXT");
|
|
36
|
+
if (!columns.has("due_precision"))
|
|
37
|
+
db.exec(
|
|
38
|
+
"ALTER TABLE mind_time_tasks ADD COLUMN due_precision TEXT NOT NULL DEFAULT 'time'",
|
|
39
|
+
);
|
|
40
|
+
if (!columns.has("priority"))
|
|
41
|
+
db.exec(
|
|
42
|
+
"ALTER TABLE mind_time_tasks ADD COLUMN priority INTEGER NOT NULL DEFAULT 1 CHECK(priority BETWEEN 0 AND 3); UPDATE mind_time_tasks SET priority=2 WHERE kind='promise';",
|
|
43
|
+
);
|
|
44
|
+
db.exec(
|
|
45
|
+
"CREATE INDEX IF NOT EXISTS mind_time_tasks_intent ON mind_time_tasks(intent_key);",
|
|
46
|
+
);
|
|
47
|
+
const sourceColumns = new Set(
|
|
48
|
+
db
|
|
49
|
+
.prepare("PRAGMA table_info(mind_time_sources)")
|
|
50
|
+
.all()
|
|
51
|
+
.map((c) => c.name),
|
|
52
|
+
);
|
|
53
|
+
for (const [name, fallback] of [
|
|
54
|
+
["kind", "web"],
|
|
55
|
+
["model", ""],
|
|
56
|
+
["uncertainty", ""],
|
|
57
|
+
])
|
|
58
|
+
if (!sourceColumns.has(name))
|
|
59
|
+
db.exec(
|
|
60
|
+
`ALTER TABLE mind_time_sources ADD COLUMN ${name} TEXT NOT NULL DEFAULT '${fallback}'`,
|
|
61
|
+
);
|
|
62
|
+
for (const [table, column, type, fallback] of [
|
|
63
|
+
["mind_time_sources", "timing", "TEXT", "'{}'"],
|
|
64
|
+
["mind_time_versions", "provenance", "TEXT", "'{}'"],
|
|
65
|
+
["mind_time_spans", "engaged_ms", "INTEGER", "0"],
|
|
66
|
+
["mind_time_spans", "clocked", "INTEGER", "0"],
|
|
67
|
+
["mind_time_shares", "review_offset", "INTEGER", "0"],
|
|
68
|
+
["mind_time_shares", "review_notes", "TEXT", "'[]'"],
|
|
69
|
+
["mind_time_shares", "report", "TEXT", "'[]'"],
|
|
70
|
+
["mind_time_shares", "send_index", "INTEGER", "0"],
|
|
71
|
+
["mind_time_shares", "delivery_kind", "TEXT", "'body'"],
|
|
72
|
+
["mind_time_shares", "next_step", "INTEGER", "0"],
|
|
73
|
+
["mind_time_searches", "purpose", "TEXT", "'activity'"],
|
|
74
|
+
])
|
|
75
|
+
if (
|
|
76
|
+
!db
|
|
77
|
+
.prepare(`PRAGMA table_info(${table})`)
|
|
78
|
+
.all()
|
|
79
|
+
.some((c) => c.name === column)
|
|
80
|
+
)
|
|
81
|
+
db.exec(
|
|
82
|
+
`ALTER TABLE ${table} ADD COLUMN ${column} ${type} NOT NULL DEFAULT ${fallback}`,
|
|
83
|
+
);
|
|
84
|
+
}
|