echoes-vault-opencode 1.1.1 → 1.1.3

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.
Files changed (3) hide show
  1. package/index.ts +37 -29
  2. package/package.json +1 -1
  3. package/tui.tsx +19 -22
package/index.ts CHANGED
@@ -29,13 +29,13 @@ type EchoesState = {
29
29
  version: number
30
30
  pluginVersion: string
31
31
  initialized: boolean
32
- stats: VaultStats
33
32
  session: {
34
33
  started: boolean
35
34
  saved: boolean
36
35
  lastStart: string | null
37
36
  lastSave: string | null
38
37
  }
38
+ stats: VaultStats
39
39
  }
40
40
 
41
41
  const STATE_FILENAME = ".opencode/echoes-state.json"
@@ -54,41 +54,19 @@ const defaultState = (): EchoesState => ({
54
54
  version: 1,
55
55
  pluginVersion: "0.0.0",
56
56
  initialized: false,
57
- stats: { totalPages: 0, totalDailyLogs: 0, deprecatedPages: 0 },
58
57
  session: {
59
58
  started: false,
60
59
  saved: false,
61
60
  lastStart: null,
62
61
  lastSave: null,
63
62
  },
63
+ stats: {
64
+ totalPages: 0,
65
+ totalDailyLogs: 0,
66
+ deprecatedPages: 0,
67
+ },
64
68
  })
65
69
 
66
- const collectStats = async (vaultPaths: VaultPaths): Promise<VaultStats> => {
67
- let totalPages = 0
68
- let deprecatedPages = 0
69
- let totalDailyLogs = 0
70
- try {
71
- const pageFiles = (await fs.readdir(vaultPaths.pages)).filter((f) => f.endsWith(".md"))
72
- totalPages = pageFiles.length
73
- for (const file of pageFiles) {
74
- const content = await fs.readFile(path.join(vaultPaths.pages, file), "utf-8")
75
- if (content.includes("> [!warning] DEPRECATED")) {
76
- deprecatedPages++
77
- }
78
- }
79
- } catch { /* pages dir may not exist */ }
80
- try {
81
- totalDailyLogs = (await fs.readdir(vaultPaths.daily)).filter((f) => f.endsWith(".md")).length
82
- } catch { /* daily dir may not exist */ }
83
- return { totalPages, totalDailyLogs, deprecatedPages }
84
- }
85
-
86
- const updateStats = async (directory: string, vaultPaths: VaultPaths): Promise<void> => {
87
- const st = await readState(directory)
88
- st.stats = await collectStats(vaultPaths)
89
- await writeState(directory, st)
90
- }
91
-
92
70
  const readState = async (directory: string): Promise<EchoesState> => {
93
71
  try {
94
72
  const raw = await fs.readFile(path.join(directory, STATE_FILENAME), "utf-8")
@@ -122,6 +100,36 @@ const ensureVaultDirs = async (paths: VaultPaths): Promise<void> => {
122
100
  await fs.mkdir(paths.assets, { recursive: true })
123
101
  }
124
102
 
103
+ const collectStats = async (vaultPaths: VaultPaths): Promise<VaultStats> => {
104
+ let totalPages = 0
105
+ let totalDailyLogs = 0
106
+ let deprecatedPages = 0
107
+
108
+ try {
109
+ const pageFiles = (await fs.readdir(vaultPaths.pages)).filter((f) => f.endsWith(".md"))
110
+ totalPages = pageFiles.length
111
+ for (const file of pageFiles) {
112
+ const content = await fs.readFile(path.join(vaultPaths.pages, file), "utf-8")
113
+ if (content.includes("DEPRECATED")) {
114
+ deprecatedPages++
115
+ }
116
+ }
117
+ } catch { /* pages dir may not exist yet */ }
118
+
119
+ try {
120
+ const dailyFiles = (await fs.readdir(vaultPaths.daily)).filter((f) => f.endsWith(".md"))
121
+ totalDailyLogs = dailyFiles.length
122
+ } catch { /* daily dir may not exist yet */ }
123
+
124
+ return { totalPages, totalDailyLogs, deprecatedPages }
125
+ }
126
+
127
+ const updateStats = async (directory: string, vaultPaths: VaultPaths): Promise<void> => {
128
+ const st = await readState(directory)
129
+ st.stats = await collectStats(vaultPaths)
130
+ await writeState(directory, st)
131
+ }
132
+
125
133
  const DEFAULT_INDEX = `# EchoesVault Index
126
134
 
127
135
  Welcome to the EchoesVault knowledge base.
@@ -407,9 +415,9 @@ const OpenCodeEchoes: Plugin = async ({ directory }) => {
407
415
 
408
416
  const state = await readState(directory)
409
417
  state.pluginVersion = await getPluginVersion()
410
- state.stats = await collectStats(paths)
411
418
  state.session.started = false
412
419
  state.session.saved = false
420
+ state.stats = await collectStats(paths)
413
421
  await writeState(directory, state)
414
422
 
415
423
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "echoes-vault-opencode",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "EchoesVault — persistent memory plugin for OpenCode. Obsidian-style knowledge base with daily logs, encyclopedia pages, and session resumption.",
5
5
  "type": "module",
6
6
  "main": "index.ts",
package/tui.tsx CHANGED
@@ -14,18 +14,15 @@ type EchoesState = {
14
14
  version: number
15
15
  pluginVersion: string
16
16
  initialized: boolean
17
- stats: VaultStats
18
17
  session: {
19
18
  started: boolean
20
19
  saved: boolean
21
20
  lastStart: string | null
22
21
  lastSave: string | null
23
22
  }
23
+ stats: VaultStats
24
24
  }
25
25
 
26
- const CAPACITY_LIMIT = 200
27
- const CAPACITY_WARNING = 170
28
-
29
26
  const STATE_PATH = path.join(process.cwd(), ".opencode", "echoes-state.json")
30
27
 
31
28
  const readState = (): EchoesState | null => {
@@ -64,6 +61,18 @@ const tui: TuiPlugin = async (api) => {
64
61
  return "Session Not Started"
65
62
  }
66
63
 
64
+ const vaultHealthColor = () => {
65
+ const pages = state()?.stats?.totalPages ?? 0
66
+ if (pages > 200) return theme.error
67
+ if (pages >= 170) return theme.warning
68
+ return theme.success
69
+ }
70
+
71
+ const vaultUsagePercent = () => {
72
+ const pages = state()?.stats?.totalPages ?? 0
73
+ return Math.round((pages / 200) * 100)
74
+ }
75
+
67
76
  const statusDesc = () => {
68
77
  const s = state()
69
78
  if (!s || !s.initialized) return null
@@ -88,17 +97,6 @@ const tui: TuiPlugin = async (api) => {
88
97
  return "to load context"
89
98
  }
90
99
 
91
- const pages = () => state()?.stats?.totalPages ?? 0
92
-
93
- const capacityColor = () => {
94
- const p = pages()
95
- if (p > CAPACITY_LIMIT) return theme.error
96
- if (p > CAPACITY_WARNING) return theme.warning
97
- return theme.success
98
- }
99
-
100
- const capacityPercent = () => Math.round((pages() / CAPACITY_LIMIT) * 100)
101
-
102
100
  return (
103
101
  <box flexDirection="column">
104
102
  <box flexDirection="row">
@@ -120,15 +118,14 @@ const tui: TuiPlugin = async (api) => {
120
118
  )}
121
119
  {state()?.initialized && (
122
120
  <box flexDirection="column">
123
- <text> </text>
124
121
  <box flexDirection="row">
125
- <text fg={capacityColor()}><b>• </b></text>
126
- <text fg={theme.text}><b>Vault Capacity</b></text>
122
+ <text fg={vaultHealthColor()}>• </text>
123
+ <text fg={theme.text}><b>Vault Health</b></text>
127
124
  </box>
128
- <text fg={theme.textMuted}>Pages: {pages()}</text>
129
- <text fg={theme.textMuted}>Usage: {capacityPercent()}%</text>
130
- {pages() > CAPACITY_LIMIT && (
131
- <text fg={theme.textMuted}>Consider migrating to RAG</text>
125
+ <text fg={theme.textMuted}> Pages: {state()?.stats?.totalPages ?? 0}</text>
126
+ <text fg={theme.textMuted}> Usage: {vaultUsagePercent()}%</text>
127
+ {(state()?.stats?.totalPages ?? 0) > 200 && (
128
+ <text fg={theme.textMuted}> Consider migrating to RAG</text>
132
129
  )}
133
130
  </box>
134
131
  )}