echoes-vault-opencode 2.0.0 → 2.0.1
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/index.ts +12 -11
- package/package.json +1 -1
- package/runtime.ts +21 -2
- package/tui.tsx +1 -1
package/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { tool } from "@opencode-ai/plugin"
|
|
|
3
3
|
import * as fs from "node:fs/promises"
|
|
4
4
|
import * as path from "node:path"
|
|
5
5
|
import { fileURLToPath } from "node:url"
|
|
6
|
-
import { runEchoes } from "./runtime.ts"
|
|
6
|
+
import { resolveEchoesWorkspace, runEchoes } from "./runtime.ts"
|
|
7
7
|
|
|
8
8
|
const PLUGIN_ROOT = path.dirname(fileURLToPath(import.meta.url))
|
|
9
9
|
|
|
@@ -48,7 +48,8 @@ const OpenCodeEchoes: Plugin = async ({ directory, worktree }) => {
|
|
|
48
48
|
|
|
49
49
|
// Lifecycle tools are one-shot capabilities granted only by the matching explicit slash command.
|
|
50
50
|
const authorizedStatusActions = new Map<string, StatusAction>()
|
|
51
|
-
const
|
|
51
|
+
const workspaceFor = (contextDirectory?: string, contextWorktree?: string): string =>
|
|
52
|
+
resolveEchoesWorkspace(contextDirectory, contextWorktree, directory, worktree)
|
|
52
53
|
|
|
53
54
|
const requireAuthorization = (sessionID: string, expected: StatusAction): void => {
|
|
54
55
|
if (authorizedStatusActions.get(sessionID) !== expected) {
|
|
@@ -81,7 +82,7 @@ const OpenCodeEchoes: Plugin = async ({ directory, worktree }) => {
|
|
|
81
82
|
async execute(_args, ctx) {
|
|
82
83
|
requireAuthorization(ctx.sessionID, "init")
|
|
83
84
|
const output = displayOutput(
|
|
84
|
-
await runEchoes(ctx.
|
|
85
|
+
await runEchoes(workspaceFor(ctx.directory, ctx.worktree), "init", {
|
|
85
86
|
signal: ctx.abort,
|
|
86
87
|
}),
|
|
87
88
|
)
|
|
@@ -97,7 +98,7 @@ const OpenCodeEchoes: Plugin = async ({ directory, worktree }) => {
|
|
|
97
98
|
async execute(_args, ctx) {
|
|
98
99
|
requireAuthorization(ctx.sessionID, "start")
|
|
99
100
|
const output = displayOutput(
|
|
100
|
-
await runEchoes(ctx.
|
|
101
|
+
await runEchoes(workspaceFor(ctx.directory, ctx.worktree), "start", {
|
|
101
102
|
args: ["--recent", "3"],
|
|
102
103
|
signal: ctx.abort,
|
|
103
104
|
}),
|
|
@@ -113,7 +114,7 @@ const OpenCodeEchoes: Plugin = async ({ directory, worktree }) => {
|
|
|
113
114
|
args: {},
|
|
114
115
|
async execute(_args, ctx) {
|
|
115
116
|
return displayOutput(
|
|
116
|
-
await runEchoes(ctx.
|
|
117
|
+
await runEchoes(workspaceFor(ctx.directory, ctx.worktree), "status", {
|
|
117
118
|
args: ["--format", "card"],
|
|
118
119
|
signal: ctx.abort,
|
|
119
120
|
}),
|
|
@@ -148,7 +149,7 @@ const OpenCodeEchoes: Plugin = async ({ directory, worktree }) => {
|
|
|
148
149
|
async execute(args, ctx) {
|
|
149
150
|
requireAuthorization(ctx.sessionID, "end")
|
|
150
151
|
const output = displayOutput(
|
|
151
|
-
await runEchoes(ctx.
|
|
152
|
+
await runEchoes(workspaceFor(ctx.directory, ctx.worktree), "end", {
|
|
152
153
|
args: ["--confirm-explicit-user-end", "--payload", "-"],
|
|
153
154
|
payload: {
|
|
154
155
|
dailySummary: args.dailySummary,
|
|
@@ -173,7 +174,7 @@ const OpenCodeEchoes: Plugin = async ({ directory, worktree }) => {
|
|
|
173
174
|
},
|
|
174
175
|
async execute(args, ctx) {
|
|
175
176
|
return displayOutput(
|
|
176
|
-
await runEchoes(ctx.
|
|
177
|
+
await runEchoes(workspaceFor(ctx.directory, ctx.worktree), "append", {
|
|
177
178
|
args: ["--payload", "-"],
|
|
178
179
|
payload: { entry: args.logEntry },
|
|
179
180
|
signal: ctx.abort,
|
|
@@ -193,7 +194,7 @@ const OpenCodeEchoes: Plugin = async ({ directory, worktree }) => {
|
|
|
193
194
|
const runtimeArgs = [args.query]
|
|
194
195
|
if (args.limit !== undefined) runtimeArgs.push("--limit", String(args.limit))
|
|
195
196
|
return displayOutput(
|
|
196
|
-
await runEchoes(ctx.
|
|
197
|
+
await runEchoes(workspaceFor(ctx.directory, ctx.worktree), "search", {
|
|
197
198
|
args: runtimeArgs,
|
|
198
199
|
signal: ctx.abort,
|
|
199
200
|
}),
|
|
@@ -209,7 +210,7 @@ const OpenCodeEchoes: Plugin = async ({ directory, worktree }) => {
|
|
|
209
210
|
},
|
|
210
211
|
async execute(args, ctx) {
|
|
211
212
|
return displayOutput(
|
|
212
|
-
await runEchoes(ctx.
|
|
213
|
+
await runEchoes(workspaceFor(ctx.directory, ctx.worktree), "hash", {
|
|
213
214
|
args: [args.filename],
|
|
214
215
|
signal: ctx.abort,
|
|
215
216
|
}),
|
|
@@ -233,7 +234,7 @@ const OpenCodeEchoes: Plugin = async ({ directory, worktree }) => {
|
|
|
233
234
|
},
|
|
234
235
|
async execute(args, ctx) {
|
|
235
236
|
return displayOutput(
|
|
236
|
-
await runEchoes(ctx.
|
|
237
|
+
await runEchoes(workspaceFor(ctx.directory, ctx.worktree), "upsert", {
|
|
237
238
|
args: ["--payload", "-"],
|
|
238
239
|
payload: {
|
|
239
240
|
filename: args.filename,
|
|
@@ -252,7 +253,7 @@ const OpenCodeEchoes: Plugin = async ({ directory, worktree }) => {
|
|
|
252
253
|
args: {},
|
|
253
254
|
async execute(_args, ctx) {
|
|
254
255
|
return displayOutput(
|
|
255
|
-
await runEchoes(ctx.
|
|
256
|
+
await runEchoes(workspaceFor(ctx.directory, ctx.worktree), "hydrate", {
|
|
256
257
|
signal: ctx.abort,
|
|
257
258
|
}),
|
|
258
259
|
)
|
package/package.json
CHANGED
package/runtime.ts
CHANGED
|
@@ -45,6 +45,24 @@ export class EchoesRuntimeError extends Error {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Prefer OpenCode's current session directory over its worktree hint. Some global-plugin launches
|
|
50
|
+
* report `/` as the worktree even when the session directory points at the real project.
|
|
51
|
+
*/
|
|
52
|
+
export const resolveEchoesWorkspace = (...candidates: Array<string | undefined>): string => {
|
|
53
|
+
for (const candidate of candidates) {
|
|
54
|
+
if (!candidate?.trim()) continue
|
|
55
|
+
const resolved = path.resolve(candidate)
|
|
56
|
+
if (resolved !== path.parse(resolved).root) return resolved
|
|
57
|
+
}
|
|
58
|
+
throw new EchoesRuntimeError(
|
|
59
|
+
"OpenCode did not provide a safe project directory. Refusing to use the filesystem root as the EchoesVault workspace.",
|
|
60
|
+
null,
|
|
61
|
+
"",
|
|
62
|
+
"",
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
48
66
|
let adapterVersionPromise: Promise<string> | undefined
|
|
49
67
|
|
|
50
68
|
export const getAdapterVersion = async (): Promise<string> => {
|
|
@@ -81,6 +99,7 @@ export const runEchoes = async (
|
|
|
81
99
|
command: EchoesCommand,
|
|
82
100
|
options: RunEchoesOptions = {},
|
|
83
101
|
): Promise<string> => {
|
|
102
|
+
const resolvedWorkspace = resolveEchoesWorkspace(workspace)
|
|
84
103
|
const adapterVersion = options.adapterVersion ?? (await getAdapterVersion())
|
|
85
104
|
const launcher = options.launcherPath ?? BUNDLED_RUNTIME
|
|
86
105
|
const commandArgs = options.args ?? []
|
|
@@ -90,7 +109,7 @@ export const runEchoes = async (
|
|
|
90
109
|
const argv = [
|
|
91
110
|
launcher,
|
|
92
111
|
"--workspace",
|
|
93
|
-
|
|
112
|
+
resolvedWorkspace,
|
|
94
113
|
"--agent",
|
|
95
114
|
"opencode",
|
|
96
115
|
"--adapter-version",
|
|
@@ -101,7 +120,7 @@ export const runEchoes = async (
|
|
|
101
120
|
|
|
102
121
|
return await new Promise<string>((resolve, reject) => {
|
|
103
122
|
const child = spawn(python, argv, {
|
|
104
|
-
cwd:
|
|
123
|
+
cwd: resolvedWorkspace,
|
|
105
124
|
stdio: [payload === undefined ? "ignore" : "pipe", "pipe", "pipe"],
|
|
106
125
|
})
|
|
107
126
|
const stdout: Buffer[] = []
|
package/tui.tsx
CHANGED
|
@@ -50,7 +50,7 @@ const readSnapshot = (workspace: string): VaultSnapshot => ({
|
|
|
50
50
|
|
|
51
51
|
const tui: TuiPlugin = async (api, _options, meta) => {
|
|
52
52
|
const theme = api.theme.current
|
|
53
|
-
const workspace = api.state.path.
|
|
53
|
+
const workspace = api.state.path.directory || api.state.path.worktree || process.cwd()
|
|
54
54
|
|
|
55
55
|
api.slots.register({
|
|
56
56
|
slots: {
|