@witness-ai/opencode 0.6.0 → 0.6.1-beta.0
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/package.json +3 -3
- package/witness.js +30 -10
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@witness-ai/opencode",
|
|
3
3
|
"mcpName": "io.github.IngTian/witness",
|
|
4
|
-
"version": "0.6.0",
|
|
4
|
+
"version": "0.6.1-beta.0",
|
|
5
5
|
"description": "MCP memory / second brain for Claude Code & OpenCode — captures your coding sessions and distills how your knowledge and habits evolve over time, queryable by your agent.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./witness.js",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"README.md"
|
|
22
22
|
],
|
|
23
23
|
"optionalDependencies": {
|
|
24
|
-
"@witness-ai/opencode-darwin-arm64": "0.6.0",
|
|
25
|
-
"@witness-ai/opencode-linux-x64": "0.6.0"
|
|
24
|
+
"@witness-ai/opencode-darwin-arm64": "0.6.1-beta.0",
|
|
25
|
+
"@witness-ai/opencode-linux-x64": "0.6.1-beta.0"
|
|
26
26
|
},
|
|
27
27
|
"keywords": [
|
|
28
28
|
"mcp",
|
package/witness.js
CHANGED
|
@@ -8,6 +8,7 @@ const DOWNLOAD_RETRY_MAX = 6
|
|
|
8
8
|
const DOWNLOAD_RETRY_BASE_MS = 1000
|
|
9
9
|
const DOWNLOAD_RETRY_CAP_MS = 30000
|
|
10
10
|
const IMPORT_GRACE_MS = 5000
|
|
11
|
+
const QUIET_PERIOD_MS = 5 * 60 * 1000
|
|
11
12
|
|
|
12
13
|
const platformBin = platformWitnessBin()
|
|
13
14
|
const WITNESS_BIN = globalThis.WITNESS_SHIM || process.env.WITNESS_BIN || (existsSync(platformBin) ? platformBin : "")
|
|
@@ -78,13 +79,14 @@ const plugin = async () => {
|
|
|
78
79
|
let disposing = false
|
|
79
80
|
let disposePromise = null
|
|
80
81
|
let retryTimer = null
|
|
82
|
+
let quietTimer = null
|
|
81
83
|
let download = null
|
|
82
84
|
let activeImport = null
|
|
83
85
|
let activeWaiters = null
|
|
84
86
|
let globalImportPending = false
|
|
85
87
|
const pendingSessions = new Set()
|
|
86
88
|
const sessionWaiters = new Map()
|
|
87
|
-
const
|
|
89
|
+
const idleCycles = new Map()
|
|
88
90
|
const idleWaiters = []
|
|
89
91
|
|
|
90
92
|
function clearRetry() {
|
|
@@ -92,6 +94,21 @@ const plugin = async () => {
|
|
|
92
94
|
retryTimer = null
|
|
93
95
|
}
|
|
94
96
|
|
|
97
|
+
function clearQuietTimer() {
|
|
98
|
+
if (quietTimer) clearTimeout(quietTimer)
|
|
99
|
+
quietTimer = null
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function scheduleQuietWorker() {
|
|
103
|
+
clearQuietTimer()
|
|
104
|
+
quietTimer = setTimeout(() => {
|
|
105
|
+
quietTimer = null
|
|
106
|
+
if (disposed || disposing) return
|
|
107
|
+
spawnWitness(["worker-run", "--auto"])
|
|
108
|
+
}, QUIET_PERIOD_MS)
|
|
109
|
+
quietTimer.unref?.()
|
|
110
|
+
}
|
|
111
|
+
|
|
95
112
|
function scheduleRetry(attempt) {
|
|
96
113
|
if (disposed || disposing || process.env.WITNESS_SKIP_MODEL_DOWNLOAD === "1" || modelReady(PACKAGE_ROOT) || attempt > DOWNLOAD_RETRY_MAX) return
|
|
97
114
|
clearRetry()
|
|
@@ -123,7 +140,7 @@ const plugin = async () => {
|
|
|
123
140
|
}
|
|
124
141
|
|
|
125
142
|
function syncOpenCode(sessions = []) {
|
|
126
|
-
const args = ["import", "--agent", "opencode", "--quiet"
|
|
143
|
+
const args = ["import", "--agent", "opencode", "--quiet"]
|
|
127
144
|
for (const sessionID of sessions) args.push("--session", sessionID)
|
|
128
145
|
const proc = spawnWitness(args)
|
|
129
146
|
if (!proc) return
|
|
@@ -225,7 +242,8 @@ const plugin = async () => {
|
|
|
225
242
|
if (disposePromise) return disposePromise
|
|
226
243
|
disposing = true
|
|
227
244
|
clearRetry()
|
|
228
|
-
|
|
245
|
+
clearQuietTimer()
|
|
246
|
+
idleCycles.clear()
|
|
229
247
|
disposePromise = (async () => {
|
|
230
248
|
let timer
|
|
231
249
|
const drained = await Promise.race([
|
|
@@ -262,19 +280,21 @@ const plugin = async () => {
|
|
|
262
280
|
const type = eventType(event)
|
|
263
281
|
const sessionID = event?.properties?.sessionID
|
|
264
282
|
const modernIdle = type === "session.status" && event?.properties?.status?.type === "idle"
|
|
265
|
-
if (type === "session.idle" && sessionID && modernIdleWaiters.has(sessionID)) {
|
|
266
|
-
const done = modernIdleWaiters.get(sessionID)
|
|
267
|
-
modernIdleWaiters.delete(sessionID)
|
|
268
|
-
return done
|
|
269
|
-
}
|
|
270
283
|
if ((type === "session.idle" || modernIdle) && sessionID) {
|
|
284
|
+
const existing = idleCycles.get(sessionID)
|
|
285
|
+
if (existing) return existing
|
|
271
286
|
clearRetry()
|
|
272
287
|
ensureDownload()
|
|
273
288
|
const done = syncSessions(sessionID)
|
|
274
|
-
|
|
289
|
+
idleCycles.set(sessionID, done)
|
|
290
|
+
scheduleQuietWorker()
|
|
275
291
|
return done
|
|
276
292
|
}
|
|
277
|
-
|
|
293
|
+
const sessionActivity = sessionID && (type.startsWith("message.") || type.startsWith("session."))
|
|
294
|
+
if (sessionActivity) {
|
|
295
|
+
if (sessionID) idleCycles.delete(sessionID)
|
|
296
|
+
clearQuietTimer()
|
|
297
|
+
}
|
|
278
298
|
},
|
|
279
299
|
}
|
|
280
300
|
}
|