opencode-extended-sidebar 0.2.90 → 0.2.91
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/.oesignore +17 -17
- package/CHANGELOG.md +96 -95
- package/LICENSE +21 -21
- package/README.md +150 -235
- package/oes.json +13 -11
- package/package.json +100 -100
- package/scripts/install-git-hooks.mjs +29 -29
- package/src/pware.oc.core/constants/index.ts +18 -18
- package/src/pware.oc.core/constants/pware.oc.core.constants.eventKind.ts +29 -29
- package/src/pware.oc.core/constants/pware.oc.core.constants.eventName.ts +15 -13
- package/src/pware.oc.core/constants/pware.oc.core.constants.eventType.ts +241 -241
- package/src/pware.oc.core/constants/pware.oc.core.constants.myWork.ts +55 -55
- package/src/pware.oc.core/constants/pware.oc.core.constants.partType.ts +65 -65
- package/src/pware.oc.core/constants/pware.oc.core.constants.phase.ts +58 -58
- package/src/pware.oc.core/constants/pware.oc.core.constants.pulse.ts +63 -63
- package/src/pware.oc.core/constants/pware.oc.core.constants.rowKind.ts +34 -34
- package/src/pware.oc.core/constants/pware.oc.core.constants.status.ts +74 -74
- package/src/pware.oc.core/constants/pware.oc.core.constants.toolName.ts +69 -69
- package/src/pware.oc.core/git/index.ts +7 -7
- package/src/pware.oc.core/git/pware.oc.core.git.ts +237 -237
- package/src/pware.oc.core/git/pware.oc.core.gitignore.ts +87 -87
- package/src/pware.oc.core/index.ts +19 -18
- package/src/pware.oc.core/pware.oc.core.bus.ts +42 -42
- package/src/pware.oc.core/pware.oc.core.cache.ts +48 -48
- package/src/pware.oc.core/pware.oc.core.clipboard.ts +97 -97
- package/src/pware.oc.core/pware.oc.core.debug.ts +280 -280
- package/src/pware.oc.core/pware.oc.core.events.ts +79 -79
- package/src/pware.oc.core/pware.oc.core.glyph.ts +135 -135
- package/src/pware.oc.core/pware.oc.core.layout.ts +234 -234
- package/src/pware.oc.core/pware.oc.core.oes.ts +99 -89
- package/src/pware.oc.core/pware.oc.core.paths.ts +240 -240
- package/src/pware.oc.core/pware.oc.core.preview.ts +74 -74
- package/src/pware.oc.core/pware.oc.core.pulse.ts +726 -726
- package/src/pware.oc.core/pware.oc.core.runtimeConfig.ts +41 -0
- package/src/pware.oc.core/pware.oc.core.sqlite.ts +164 -175
- package/src/pware.oc.core/pware.oc.core.sqliteGateway.ts +89 -0
- package/src/pware.oc.core/pware.oc.core.status.ts +214 -214
- package/src/pware.oc.core/pware.oc.core.timing.ts +63 -63
- package/src/pware.oc.core/pware.oc.core.width.ts +215 -215
- package/src/pware.oc.omo/constants/index.ts +15 -15
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.backgroundTask.ts +18 -18
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.boulderStatus.ts +49 -49
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.docKind.ts +29 -29
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.eventName.ts +11 -11
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.planStatus.ts +60 -60
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.reviewStatus.ts +49 -49
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.startWork.ts +25 -25
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.verdict.ts +38 -38
- package/src/pware.oc.omo/index.ts +7 -7
- package/src/pware.oc.omo/resolver/index.ts +19 -19
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.approval.ts +179 -179
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.approvalGroup.ts +116 -116
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.approvalState.ts +34 -34
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.boulder.ts +503 -503
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.config.ts +40 -40
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.doc.ts +269 -269
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.draftFile.ts +18 -18
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.notepadsFile.ts +18 -18
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.plan.ts +155 -155
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.planFile.ts +363 -361
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.proofFile.ts +18 -18
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.rulesFile.ts +11 -11
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.runContinuationFile.ts +14 -14
- package/src/pware.oc.opencode/constants/index.ts +10 -10
- package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.eventName.ts +15 -15
- package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.fileTouch.ts +18 -18
- package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.questionKind.ts +45 -45
- package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.sessionStatus.ts +58 -58
- package/src/pware.oc.opencode/index.ts +8 -8
- package/src/pware.oc.opencode/pware.oc.opencode.events.ts +182 -182
- package/src/pware.oc.opencode/pware.oc.opencode.files.ts +399 -399
- package/src/pware.oc.opencode/resolver/index.ts +223 -170
- package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.file.ts +150 -162
- package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.question.ts +149 -185
- package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.session.ts +248 -211
- package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.todo.ts +22 -26
- package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.tool.ts +224 -236
- package/src/pware.oc.perf/index.ts +14 -14
- package/src/pware.oc.perf/pware.oc.perf.asciichart.d.ts +15 -15
- package/src/pware.oc.perf/pware.oc.perf.charts.ts +284 -284
- package/src/pware.oc.perf/pware.oc.perf.reader.ts +962 -927
- package/src/pware.oc.perf/pware.oc.perf.realtime.ts +88 -88
- package/src/pware.oc.perf/pware.oc.perf.realtimeBlock.ts +118 -118
- package/src/pware.oc.perf/pware.oc.perf.realtimeCpuRam.ts +79 -79
- package/src/pware.oc.perf/pware.oc.perf.realtimeSampler.ts +71 -71
- package/src/pware.oc.perf/pware.oc.perf.realtimeTimeline.ts +214 -214
- package/src/pware.oc.perf/pware.oc.perf.self.ts +179 -179
- package/src/pware.oc.perf/pware.oc.perf.view.tsx +463 -462
- package/src/pware.oc.runtime/index.ts +13 -13
- package/src/pware.oc.runtime/pware.oc.runtime.monitor.ts +142 -142
- package/src/pware.oc.runtime/pware.oc.runtime.mywork-enrich.ts +87 -79
- package/src/pware.oc.runtime/pware.oc.runtime.mywork.ts +282 -253
- package/src/pware.oc.runtime/pware.oc.runtime.omoRead.ts +37 -0
- package/src/pware.oc.runtime/pware.oc.runtime.questions.ts +83 -95
- package/src/pware.oc.runtime/pware.oc.runtime.snapshotClient.ts +130 -129
- package/src/pware.oc.runtime/pware.oc.runtime.source.ts +105 -105
- package/src/pware.oc.runtime/pware.oc.runtime.worker.ts +44 -43
- package/src/pware.oc.runtime/resolver/index.ts +268 -224
- package/src/pware.oc.runtime/resolver/pware.oc.runtime.resolver.delegate.ts +146 -146
- package/src/pware.oc.ui/index.ts +12 -12
- package/src/pware.oc.ui/pware.oc.ui.chrome.tsx +381 -339
- package/src/pware.oc.ui/pware.oc.ui.glyphs.tsx +144 -144
- package/src/pware.oc.ui/pware.oc.ui.host.tsx +111 -111
- package/src/pware.oc.ui/pware.oc.ui.live.tsx +82 -82
- package/src/pware.oc.ui/pware.oc.ui.menudialogs.tsx +843 -843
- package/src/pware.oc.ui/pware.oc.ui.sections.tsx +552 -526
- package/src/pware.oc.ui/pware.oc.ui.sidebar.tsx +1718 -1629
- package/src/pware.oc.ui.tsx +98 -98
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* pware.oc.runtime
|
|
3
|
-
*
|
|
4
|
-
* Runtime composition: the only layer that combines opencode + omo into one
|
|
5
|
-
* snapshot, plus the monitor that keeps it fresh and the My work queue.
|
|
6
|
-
*/
|
|
7
|
-
export * from "./pware.oc.runtime.monitor.js"
|
|
8
|
-
export * from "./pware.oc.runtime.source.js"
|
|
9
|
-
export * from "./pware.oc.runtime.snapshotClient.js"
|
|
10
|
-
export * from "./pware.oc.runtime.mywork.js"
|
|
11
|
-
export * from "./pware.oc.runtime.mywork-enrich.js"
|
|
12
|
-
export * from "./pware.oc.runtime.questions.js"
|
|
13
|
-
export * from "./resolver/index.js"
|
|
1
|
+
/**
|
|
2
|
+
* pware.oc.runtime
|
|
3
|
+
*
|
|
4
|
+
* Runtime composition: the only layer that combines opencode + omo into one
|
|
5
|
+
* snapshot, plus the monitor that keeps it fresh and the My work queue.
|
|
6
|
+
*/
|
|
7
|
+
export * from "./pware.oc.runtime.monitor.js"
|
|
8
|
+
export * from "./pware.oc.runtime.source.js"
|
|
9
|
+
export * from "./pware.oc.runtime.snapshotClient.js"
|
|
10
|
+
export * from "./pware.oc.runtime.mywork.js"
|
|
11
|
+
export * from "./pware.oc.runtime.mywork-enrich.js"
|
|
12
|
+
export * from "./pware.oc.runtime.questions.js"
|
|
13
|
+
export * from "./resolver/index.js"
|
|
@@ -1,142 +1,142 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Watch boulder.json + poll SQLite stamps. Invokes onChange when fingerprint changes.
|
|
3
|
-
*/
|
|
4
|
-
import fs from "node:fs"
|
|
5
|
-
import path from "node:path"
|
|
6
|
-
import type { PwareEvent } from "../pware.oc.core/pware.oc.core.bus.js"
|
|
7
|
-
import { EV_OES_SNAPSHOT } from "../pware.oc.core/constants/pware.oc.core.constants.eventName.js"
|
|
8
|
-
import { EV_OMO_BOULDER_CHANGED } from "../pware.oc.omo/constants/pware.oc.omo.constants.eventName.js"
|
|
9
|
-
import { findBoulder } from "../pware.oc.omo/resolver/index.js"
|
|
10
|
-
import { computeFingerprint, type RuntimeSnapshot } from "./resolver/index.js"
|
|
11
|
-
import { readRuntimeSnapshotAsync } from "./pware.oc.runtime.snapshotClient.js"
|
|
12
|
-
import { getOpenCodeDbPath } from "../pware.oc.core/pware.oc.core.paths.js"
|
|
13
|
-
import { MONITOR_POLL_MS, MONITOR_WATCH_DEBOUNCE_MS } from "../pware.oc.core/pware.oc.core.timing.js"
|
|
14
|
-
import { dbg, profile } from "../pware.oc.core/pware.oc.core.debug.js"
|
|
15
|
-
|
|
16
|
-
export type MonitorOptions = {
|
|
17
|
-
sessionId: string
|
|
18
|
-
projectRoot: string | null
|
|
19
|
-
dbPath?: string
|
|
20
|
-
pollMs?: number
|
|
21
|
-
onChange?: (snap: RuntimeSnapshot) => void
|
|
22
|
-
emit?: (evt: PwareEvent) => void
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export type MonitorHandle = {
|
|
26
|
-
stop: () => void
|
|
27
|
-
refresh: () => void
|
|
28
|
-
question: (sessionId: string) => void
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function startMonitor(opts: MonitorOptions): MonitorHandle {
|
|
32
|
-
const dbPath = opts.dbPath || getOpenCodeDbPath(process.env, undefined, opts.projectRoot)
|
|
33
|
-
dbg("monitor", "start", { dbPath, sessionId: opts.sessionId, projectRoot: opts.projectRoot ?? null })
|
|
34
|
-
const pollMs = opts.pollMs ?? MONITOR_POLL_MS
|
|
35
|
-
let lastFp = ""
|
|
36
|
-
let stopped = false
|
|
37
|
-
let emitGen = 0
|
|
38
|
-
let debounce: ReturnType<typeof setTimeout> | null = null
|
|
39
|
-
let pendingQuestionHint: string | null = null
|
|
40
|
-
const watchers: fs.FSWatcher[] = []
|
|
41
|
-
|
|
42
|
-
const emit = (force = false) =>
|
|
43
|
-
profile("monitor.emit", () => {
|
|
44
|
-
if (stopped) return
|
|
45
|
-
const fp = computeFingerprint({
|
|
46
|
-
dbPath,
|
|
47
|
-
projectRoot: opts.projectRoot,
|
|
48
|
-
sessionId: opts.sessionId,
|
|
49
|
-
})
|
|
50
|
-
if (!force && fp === lastFp) return
|
|
51
|
-
dbg("monitor", "emit", { force, fp: fp.slice(0, 40) })
|
|
52
|
-
lastFp = fp
|
|
53
|
-
const gen = ++emitGen
|
|
54
|
-
const questionHint = pendingQuestionHint ?? undefined
|
|
55
|
-
pendingQuestionHint = null
|
|
56
|
-
void readRuntimeSnapshotAsync({
|
|
57
|
-
sessionId: opts.sessionId,
|
|
58
|
-
projectRoot: opts.projectRoot,
|
|
59
|
-
dbPath,
|
|
60
|
-
questionHint,
|
|
61
|
-
}).then((snapshot) => {
|
|
62
|
-
if (stopped || gen !== emitGen) return
|
|
63
|
-
opts.onChange?.(snapshot)
|
|
64
|
-
opts.emit?.({
|
|
65
|
-
type: EV_OES_SNAPSHOT,
|
|
66
|
-
ts: Date.now(),
|
|
67
|
-
data: { snapshot },
|
|
68
|
-
})
|
|
69
|
-
})
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
const schedule = () => {
|
|
73
|
-
if (stopped) return
|
|
74
|
-
if (debounce) clearTimeout(debounce)
|
|
75
|
-
debounce = setTimeout(() => {
|
|
76
|
-
debounce = null
|
|
77
|
-
emit()
|
|
78
|
-
}, MONITOR_WATCH_DEBOUNCE_MS)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Initial
|
|
82
|
-
emit(true)
|
|
83
|
-
|
|
84
|
-
const interval = setInterval(schedule, pollMs)
|
|
85
|
-
|
|
86
|
-
const root = opts.projectRoot
|
|
87
|
-
if (root) {
|
|
88
|
-
const boulderPath = findBoulder(root)
|
|
89
|
-
if (boulderPath) {
|
|
90
|
-
try {
|
|
91
|
-
watchers.push(
|
|
92
|
-
fs.watch(boulderPath, { persistent: false }, () => {
|
|
93
|
-
opts.emit?.({
|
|
94
|
-
type: EV_OMO_BOULDER_CHANGED,
|
|
95
|
-
ts: Date.now(),
|
|
96
|
-
data: {},
|
|
97
|
-
})
|
|
98
|
-
schedule()
|
|
99
|
-
}),
|
|
100
|
-
)
|
|
101
|
-
} catch {
|
|
102
|
-
// poll covers it
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// SQLite: watching the file is flaky under WAL — poll stamps instead.
|
|
108
|
-
// Still try a non-recursive watch on the data dir for companions.
|
|
109
|
-
try {
|
|
110
|
-
const dataDir = path.dirname(dbPath)
|
|
111
|
-
if (fs.existsSync(dataDir)) {
|
|
112
|
-
watchers.push(
|
|
113
|
-
fs.watch(dataDir, { persistent: false }, (event, filename) => {
|
|
114
|
-
const name = filename?.toString() || ""
|
|
115
|
-
if (!name || name.includes("opencode.db")) schedule()
|
|
116
|
-
}),
|
|
117
|
-
)
|
|
118
|
-
}
|
|
119
|
-
} catch {
|
|
120
|
-
// poll only
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return {
|
|
124
|
-
refresh: () => emit(true),
|
|
125
|
-
question: (sessionId: string) => {
|
|
126
|
-
pendingQuestionHint = sessionId
|
|
127
|
-
emit(true)
|
|
128
|
-
},
|
|
129
|
-
stop: () => {
|
|
130
|
-
stopped = true
|
|
131
|
-
if (debounce) clearTimeout(debounce)
|
|
132
|
-
clearInterval(interval)
|
|
133
|
-
for (const w of watchers) {
|
|
134
|
-
try {
|
|
135
|
-
w.close()
|
|
136
|
-
} catch {
|
|
137
|
-
// ignore
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
},
|
|
141
|
-
}
|
|
142
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Watch boulder.json + poll SQLite stamps. Invokes onChange when fingerprint changes.
|
|
3
|
+
*/
|
|
4
|
+
import fs from "node:fs"
|
|
5
|
+
import path from "node:path"
|
|
6
|
+
import type { PwareEvent } from "../pware.oc.core/pware.oc.core.bus.js"
|
|
7
|
+
import { EV_OES_SNAPSHOT } from "../pware.oc.core/constants/pware.oc.core.constants.eventName.js"
|
|
8
|
+
import { EV_OMO_BOULDER_CHANGED } from "../pware.oc.omo/constants/pware.oc.omo.constants.eventName.js"
|
|
9
|
+
import { findBoulder } from "../pware.oc.omo/resolver/index.js"
|
|
10
|
+
import { computeFingerprint, type RuntimeSnapshot } from "./resolver/index.js"
|
|
11
|
+
import { readRuntimeSnapshotAsync } from "./pware.oc.runtime.snapshotClient.js"
|
|
12
|
+
import { getOpenCodeDbPath } from "../pware.oc.core/pware.oc.core.paths.js"
|
|
13
|
+
import { MONITOR_POLL_MS, MONITOR_WATCH_DEBOUNCE_MS } from "../pware.oc.core/pware.oc.core.timing.js"
|
|
14
|
+
import { dbg, profile } from "../pware.oc.core/pware.oc.core.debug.js"
|
|
15
|
+
|
|
16
|
+
export type MonitorOptions = {
|
|
17
|
+
sessionId: string
|
|
18
|
+
projectRoot: string | null
|
|
19
|
+
dbPath?: string
|
|
20
|
+
pollMs?: number
|
|
21
|
+
onChange?: (snap: RuntimeSnapshot) => void
|
|
22
|
+
emit?: (evt: PwareEvent) => void
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type MonitorHandle = {
|
|
26
|
+
stop: () => void
|
|
27
|
+
refresh: () => void
|
|
28
|
+
question: (sessionId: string) => void
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function startMonitor(opts: MonitorOptions): MonitorHandle {
|
|
32
|
+
const dbPath = opts.dbPath || getOpenCodeDbPath(process.env, undefined, opts.projectRoot)
|
|
33
|
+
dbg("monitor", "start", { dbPath, sessionId: opts.sessionId, projectRoot: opts.projectRoot ?? null })
|
|
34
|
+
const pollMs = opts.pollMs ?? MONITOR_POLL_MS
|
|
35
|
+
let lastFp = ""
|
|
36
|
+
let stopped = false
|
|
37
|
+
let emitGen = 0
|
|
38
|
+
let debounce: ReturnType<typeof setTimeout> | null = null
|
|
39
|
+
let pendingQuestionHint: string | null = null
|
|
40
|
+
const watchers: fs.FSWatcher[] = []
|
|
41
|
+
|
|
42
|
+
const emit = (force = false) =>
|
|
43
|
+
profile("monitor.emit", () => {
|
|
44
|
+
if (stopped) return
|
|
45
|
+
const fp = computeFingerprint({
|
|
46
|
+
dbPath,
|
|
47
|
+
projectRoot: opts.projectRoot,
|
|
48
|
+
sessionId: opts.sessionId,
|
|
49
|
+
})
|
|
50
|
+
if (!force && fp === lastFp) return
|
|
51
|
+
dbg("monitor", "emit", { force, fp: fp.slice(0, 40) })
|
|
52
|
+
lastFp = fp
|
|
53
|
+
const gen = ++emitGen
|
|
54
|
+
const questionHint = pendingQuestionHint ?? undefined
|
|
55
|
+
pendingQuestionHint = null
|
|
56
|
+
void readRuntimeSnapshotAsync({
|
|
57
|
+
sessionId: opts.sessionId,
|
|
58
|
+
projectRoot: opts.projectRoot,
|
|
59
|
+
dbPath,
|
|
60
|
+
questionHint,
|
|
61
|
+
}).then((snapshot) => {
|
|
62
|
+
if (stopped || gen !== emitGen) return
|
|
63
|
+
opts.onChange?.(snapshot)
|
|
64
|
+
opts.emit?.({
|
|
65
|
+
type: EV_OES_SNAPSHOT,
|
|
66
|
+
ts: Date.now(),
|
|
67
|
+
data: { snapshot },
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const schedule = () => {
|
|
73
|
+
if (stopped) return
|
|
74
|
+
if (debounce) clearTimeout(debounce)
|
|
75
|
+
debounce = setTimeout(() => {
|
|
76
|
+
debounce = null
|
|
77
|
+
emit()
|
|
78
|
+
}, MONITOR_WATCH_DEBOUNCE_MS)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Initial
|
|
82
|
+
emit(true)
|
|
83
|
+
|
|
84
|
+
const interval = setInterval(schedule, pollMs)
|
|
85
|
+
|
|
86
|
+
const root = opts.projectRoot
|
|
87
|
+
if (root) {
|
|
88
|
+
const boulderPath = findBoulder(root)
|
|
89
|
+
if (boulderPath) {
|
|
90
|
+
try {
|
|
91
|
+
watchers.push(
|
|
92
|
+
fs.watch(boulderPath, { persistent: false }, () => {
|
|
93
|
+
opts.emit?.({
|
|
94
|
+
type: EV_OMO_BOULDER_CHANGED,
|
|
95
|
+
ts: Date.now(),
|
|
96
|
+
data: {},
|
|
97
|
+
})
|
|
98
|
+
schedule()
|
|
99
|
+
}),
|
|
100
|
+
)
|
|
101
|
+
} catch {
|
|
102
|
+
// poll covers it
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// SQLite: watching the file is flaky under WAL — poll stamps instead.
|
|
108
|
+
// Still try a non-recursive watch on the data dir for companions.
|
|
109
|
+
try {
|
|
110
|
+
const dataDir = path.dirname(dbPath)
|
|
111
|
+
if (fs.existsSync(dataDir)) {
|
|
112
|
+
watchers.push(
|
|
113
|
+
fs.watch(dataDir, { persistent: false }, (event, filename) => {
|
|
114
|
+
const name = filename?.toString() || ""
|
|
115
|
+
if (!name || name.includes("opencode.db")) schedule()
|
|
116
|
+
}),
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
} catch {
|
|
120
|
+
// poll only
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
refresh: () => emit(true),
|
|
125
|
+
question: (sessionId: string) => {
|
|
126
|
+
pendingQuestionHint = sessionId
|
|
127
|
+
emit(true)
|
|
128
|
+
},
|
|
129
|
+
stop: () => {
|
|
130
|
+
stopped = true
|
|
131
|
+
if (debounce) clearTimeout(debounce)
|
|
132
|
+
clearInterval(interval)
|
|
133
|
+
for (const w of watchers) {
|
|
134
|
+
try {
|
|
135
|
+
w.close()
|
|
136
|
+
} catch {
|
|
137
|
+
// ignore
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -1,79 +1,87 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* pware.oc.runtime.mywork-enrich
|
|
3
|
-
*
|
|
4
|
-
* Enriches the OMO approval queue with the writer session's activity state:
|
|
5
|
-
* builds the plan-file → writer-session index once, then per item resolves the
|
|
6
|
-
* writer via `basenameOf(item.rel)` and asks `sessionActivityState` (SQLite
|
|
7
|
-
* freshness + the omo `.omo/run-continuation` marker). Soft-fails to
|
|
8
|
-
* `sessionState: null` per item — never throws. This is the runtime layer's
|
|
9
|
-
* job: it composes omo (`.omo/run-continuation`) with opencode (SQLite session
|
|
10
|
-
* activity).
|
|
11
|
-
*/
|
|
12
|
-
import
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
} from "../pware.oc.opencode/resolver/pware.oc.opencode.resolver.
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import { basenameOf } from "../pware.oc.core/pware.oc.core.paths.js"
|
|
22
|
-
import { readRunContinuationState } from "../pware.oc.omo/resolver/pware.oc.omo.resolver.approvalState.js"
|
|
23
|
-
import { BACKGROUND_TASK_ACTIVE } from "../pware.oc.omo/constants/pware.oc.omo.constants.backgroundTask.js"
|
|
24
|
-
import { STATUS_COMPLETED } from "../pware.oc.core/constants/pware.oc.core.constants.status.js"
|
|
25
|
-
import type { ApprovalItem } from "../pware.oc.omo/resolver/pware.oc.omo.resolver.plan.js"
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* An approval item with its planner-session activity attached. `sessionState`
|
|
29
|
-
* is a runtime enrichment: it lives here on the runtime layer's enriched type,
|
|
30
|
-
* not on omo's base `ApprovalItem` (omo must not import the opencode session type).
|
|
31
|
-
*/
|
|
32
|
-
export type EnrichedApproval = ApprovalItem & {
|
|
33
|
-
sessionState: SessionActivityState | null
|
|
34
|
-
/** Writer session's todos all completed (and at least one present). */
|
|
35
|
-
todosDone: boolean
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function blank(items: readonly ApprovalItem[]): EnrichedApproval[] {
|
|
39
|
-
return items.map((item) => ({ ...item, sessionState: null, todosDone: false }))
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function sessionTodosDone(db: SqlDb, sessionId: string): boolean {
|
|
43
|
-
const todos = listTodos(db, sessionId)
|
|
44
|
-
return todos.length > 0 && todos.every((t) => t.status === STATUS_COMPLETED)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
1
|
+
/**
|
|
2
|
+
* pware.oc.runtime.mywork-enrich
|
|
3
|
+
*
|
|
4
|
+
* Enriches the OMO approval queue with the writer session's activity state:
|
|
5
|
+
* builds the plan-file → writer-session index once, then per item resolves the
|
|
6
|
+
* writer via `basenameOf(item.rel)` and asks `sessionActivityState` (SQLite
|
|
7
|
+
* freshness + the omo `.omo/run-continuation` marker). Soft-fails to
|
|
8
|
+
* `sessionState: null` per item — never throws. This is the runtime layer's
|
|
9
|
+
* job: it composes omo (`.omo/run-continuation`) with opencode (SQLite session
|
|
10
|
+
* activity).
|
|
11
|
+
*/
|
|
12
|
+
import {
|
|
13
|
+
sessionActivityState,
|
|
14
|
+
type SessionActivityState,
|
|
15
|
+
} from "../pware.oc.opencode/resolver/pware.oc.opencode.resolver.session.js"
|
|
16
|
+
import { listTodos } from "../pware.oc.opencode/resolver/pware.oc.opencode.resolver.todo.js"
|
|
17
|
+
import { planSessionIndex, type PlanSessionIndex } from "../pware.oc.omo/resolver/index.js"
|
|
18
|
+
import type { SqlDb } from "../pware.oc.core/pware.oc.core.sqlite.js"
|
|
19
|
+
import { readonlyReadGateway } from "../pware.oc.core/pware.oc.core.sqliteGateway.js"
|
|
20
|
+
import { profileAsync } from "../pware.oc.core/pware.oc.core.debug.js"
|
|
21
|
+
import { basenameOf } from "../pware.oc.core/pware.oc.core.paths.js"
|
|
22
|
+
import { readRunContinuationState } from "../pware.oc.omo/resolver/pware.oc.omo.resolver.approvalState.js"
|
|
23
|
+
import { BACKGROUND_TASK_ACTIVE } from "../pware.oc.omo/constants/pware.oc.omo.constants.backgroundTask.js"
|
|
24
|
+
import { STATUS_COMPLETED } from "../pware.oc.core/constants/pware.oc.core.constants.status.js"
|
|
25
|
+
import type { ApprovalItem } from "../pware.oc.omo/resolver/pware.oc.omo.resolver.plan.js"
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* An approval item with its planner-session activity attached. `sessionState`
|
|
29
|
+
* is a runtime enrichment: it lives here on the runtime layer's enriched type,
|
|
30
|
+
* not on omo's base `ApprovalItem` (omo must not import the opencode session type).
|
|
31
|
+
*/
|
|
32
|
+
export type EnrichedApproval = ApprovalItem & {
|
|
33
|
+
sessionState: SessionActivityState | null
|
|
34
|
+
/** Writer session's todos all completed (and at least one present). */
|
|
35
|
+
todosDone: boolean
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function blank(items: readonly ApprovalItem[]): EnrichedApproval[] {
|
|
39
|
+
return items.map((item) => ({ ...item, sessionState: null, todosDone: false }))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function sessionTodosDone(db: SqlDb, sessionId: string): boolean {
|
|
43
|
+
const todos = listTodos(db, sessionId)
|
|
44
|
+
return todos.length > 0 && todos.every((t) => t.status === STATUS_COMPLETED)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
type EnrichmentRead = {
|
|
48
|
+
readonly index: PlanSessionIndex | null
|
|
49
|
+
readonly approvals: EnrichedApproval[]
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export async function enrichApprovalSessionStates(
|
|
53
|
+
items: readonly ApprovalItem[],
|
|
54
|
+
opts: { dbPath: string | null | undefined; projectRoot: string | null | undefined; now?: number },
|
|
55
|
+
): Promise<EnrichedApproval[]> {
|
|
56
|
+
if (items.length === 0) return []
|
|
57
|
+
const dbPath = opts.dbPath
|
|
58
|
+
const projectRoot = opts.projectRoot
|
|
59
|
+
if (!dbPath || !projectRoot) return blank(items)
|
|
60
|
+
const itemStages = items.map((item) => (db: SqlDb, state: EnrichmentRead): EnrichmentRead => {
|
|
61
|
+
const sessionId = state.index?.fileWriter.get(basenameOf(item.rel))?.sessionId ?? null
|
|
62
|
+
const sessionState = sessionId
|
|
63
|
+
? sessionActivityState(db, sessionId, {
|
|
64
|
+
backgroundTaskActive:
|
|
65
|
+
readRunContinuationState(projectRoot, sessionId) === BACKGROUND_TASK_ACTIVE,
|
|
66
|
+
now: opts.now,
|
|
67
|
+
})
|
|
68
|
+
: null
|
|
69
|
+
const todosDone = sessionId ? sessionTodosDone(db, sessionId) : false
|
|
70
|
+
return {
|
|
71
|
+
...state,
|
|
72
|
+
approvals: [...state.approvals, { ...item, sessionState, todosDone }],
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
const result = await profileAsync("mywork.approvals", () =>
|
|
76
|
+
readonlyReadGateway.run<EnrichmentRead>({
|
|
77
|
+
dbPath,
|
|
78
|
+
initial: () => ({ index: null, approvals: [] }),
|
|
79
|
+
stages: [
|
|
80
|
+
(db, state) => ({ ...state, index: planSessionIndex(db, null, projectRoot) }),
|
|
81
|
+
...itemStages,
|
|
82
|
+
],
|
|
83
|
+
fallback: () => ({ index: null, approvals: blank(items) }),
|
|
84
|
+
}),
|
|
85
|
+
)
|
|
86
|
+
return result.approvals
|
|
87
|
+
}
|