@opvs-ai/cli 0.22.0 → 0.23.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/dist/.build-stamp.json +5 -5
- package/dist/commands/memory-hook.d.ts +21 -0
- package/dist/commands/memory-hook.js +129 -0
- package/dist/commands/memory-hook.js.map +1 -0
- package/dist/commands/memory.d.ts +24 -0
- package/dist/commands/memory.js +233 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/myMail.d.ts +3 -0
- package/dist/commands/myMail.js +119 -0
- package/dist/commands/myMail.js.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/.build-stamp.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"stamp_version": 1,
|
|
3
3
|
"package": "@opvs-ai/cli",
|
|
4
|
-
"version": "0.
|
|
5
|
-
"source_digest": "
|
|
6
|
-
"source_files":
|
|
7
|
-
"built_at": "2026-
|
|
8
|
-
"node": "v22.23.
|
|
4
|
+
"version": "0.23.0",
|
|
5
|
+
"source_digest": "8454f10e0b60d2a9819d9dad5c659b62e77f517d3566b9bf086a16eb15067f70",
|
|
6
|
+
"source_files": 48,
|
|
7
|
+
"built_at": "2026-10-02T07:42:54.466Z",
|
|
8
|
+
"node": "v22.23.3"
|
|
9
9
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { createClient, getEffectiveConfig } from "@opvs-ai/core";
|
|
3
|
+
export declare const MEMORY_CONTEXT_CHAR_BUDGET = 12000;
|
|
4
|
+
type MemoryEntry = Record<string, unknown>;
|
|
5
|
+
type SessionStartDependencies = {
|
|
6
|
+
getConfig: typeof getEffectiveConfig;
|
|
7
|
+
makeClient: typeof createClient;
|
|
8
|
+
readInput: () => Promise<string>;
|
|
9
|
+
writeOutput: (text: string) => void;
|
|
10
|
+
repoRoot: (cwd: string) => string;
|
|
11
|
+
readServices: (root: string) => string;
|
|
12
|
+
};
|
|
13
|
+
/** Render complete entries where possible, then hard-truncate at the budget. */
|
|
14
|
+
export declare function renderMemoryContext(entries: MemoryEntry[], budget?: number): string;
|
|
15
|
+
/**
|
|
16
|
+
* Run the SessionStart read path. All errors are intentionally swallowed so
|
|
17
|
+
* the command emits no bytes and resolves normally (CLI exit status 0).
|
|
18
|
+
*/
|
|
19
|
+
export declare function runSessionStartHook(dependencies?: Partial<SessionStartDependencies>, budget?: number): Promise<void>;
|
|
20
|
+
export declare function registerMemoryHooks(memory: Command): void;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code memory hooks.
|
|
3
|
+
*
|
|
4
|
+
* SessionStart is deliberately fail-open: a missing login, an unavailable
|
|
5
|
+
* gateway, malformed hook input, or an unexpected response must never stop a
|
|
6
|
+
* Claude Code session from opening.
|
|
7
|
+
*/
|
|
8
|
+
import { execFileSync } from "node:child_process";
|
|
9
|
+
import { readFileSync } from "node:fs";
|
|
10
|
+
import { relative, resolve } from "node:path";
|
|
11
|
+
import { createClient, getEffectiveConfig } from "@opvs-ai/core";
|
|
12
|
+
import { parseServicePatterns, serviceForPath } from "./memory.js";
|
|
13
|
+
export const MEMORY_CONTEXT_CHAR_BUDGET = 12_000;
|
|
14
|
+
const DEFAULT_DEPENDENCIES = {
|
|
15
|
+
getConfig: (workspace) => getEffectiveConfig(workspace),
|
|
16
|
+
makeClient: createClient,
|
|
17
|
+
readInput: async () => {
|
|
18
|
+
let input = "";
|
|
19
|
+
for await (const chunk of process.stdin)
|
|
20
|
+
input += String(chunk);
|
|
21
|
+
return input;
|
|
22
|
+
},
|
|
23
|
+
writeOutput: (text) => process.stdout.write(text),
|
|
24
|
+
repoRoot: (cwd) => execFileSync("git", ["rev-parse", "--show-toplevel"], {
|
|
25
|
+
cwd,
|
|
26
|
+
encoding: "utf8",
|
|
27
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
28
|
+
}).trim(),
|
|
29
|
+
readServices: (root) => readFileSync(resolve(root, "memory", "services.yaml"), "utf8"),
|
|
30
|
+
};
|
|
31
|
+
function entriesFrom(payload) {
|
|
32
|
+
if (Array.isArray(payload)) {
|
|
33
|
+
return payload.filter((item) => item !== null && typeof item === "object");
|
|
34
|
+
}
|
|
35
|
+
if (!payload || typeof payload !== "object")
|
|
36
|
+
return [];
|
|
37
|
+
const body = payload;
|
|
38
|
+
for (const key of ["items", "entries", "memories"]) {
|
|
39
|
+
const value = body[key];
|
|
40
|
+
if (Array.isArray(value)) {
|
|
41
|
+
return value.filter((item) => item !== null && typeof item === "object");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
function pinned(entry) {
|
|
47
|
+
return entry.pinned === true || entry.is_pinned === true;
|
|
48
|
+
}
|
|
49
|
+
function entryBody(entry) {
|
|
50
|
+
for (const key of ["body", "content", "text", "core", "summary"]) {
|
|
51
|
+
if (typeof entry[key] === "string" && entry[key])
|
|
52
|
+
return entry[key];
|
|
53
|
+
}
|
|
54
|
+
return JSON.stringify(entry);
|
|
55
|
+
}
|
|
56
|
+
/** Render complete entries where possible, then hard-truncate at the budget. */
|
|
57
|
+
export function renderMemoryContext(entries, budget = MEMORY_CONTEXT_CHAR_BUDGET) {
|
|
58
|
+
if (!Number.isFinite(budget) || budget <= 0 || entries.length === 0)
|
|
59
|
+
return "";
|
|
60
|
+
const ordered = entries
|
|
61
|
+
.map((entry, index) => ({ entry, index }))
|
|
62
|
+
.sort((a, b) => Number(pinned(b.entry)) - Number(pinned(a.entry)) || a.index - b.index)
|
|
63
|
+
.map(({ entry }) => entry);
|
|
64
|
+
const sections = ordered.map((entry) => {
|
|
65
|
+
const id = [entry.type, entry.id ?? entry.path]
|
|
66
|
+
.filter((value) => typeof value === "string" && value)
|
|
67
|
+
.join(" · ");
|
|
68
|
+
const label = `${pinned(entry) ? "[pinned] " : ""}${id || "memory"}`;
|
|
69
|
+
return `## ${label}\n${entryBody(entry)}`;
|
|
70
|
+
});
|
|
71
|
+
const rendered = `# Relevant OPVS memories\n\n${sections.join("\n\n")}`;
|
|
72
|
+
if (rendered.length < budget)
|
|
73
|
+
return `${rendered}\n`;
|
|
74
|
+
if (rendered.length === budget)
|
|
75
|
+
return rendered;
|
|
76
|
+
if (budget === 1)
|
|
77
|
+
return "…";
|
|
78
|
+
return `${rendered.slice(0, budget - 1)}…`;
|
|
79
|
+
}
|
|
80
|
+
function searchParams(cwd, deps) {
|
|
81
|
+
const root = deps.repoRoot(cwd);
|
|
82
|
+
const rel = relative(root, cwd).replace(/\\/g, "/");
|
|
83
|
+
const params = new URLSearchParams({ pinned_first: "true" });
|
|
84
|
+
if (rel) {
|
|
85
|
+
const patterns = parseServicePatterns(deps.readServices(root));
|
|
86
|
+
const service = serviceForPath(`${rel.replace(/\/$/, "")}/`, patterns)
|
|
87
|
+
?? serviceForPath(rel, patterns);
|
|
88
|
+
if (service)
|
|
89
|
+
params.set("scope", `service:${service}`);
|
|
90
|
+
}
|
|
91
|
+
return params;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Run the SessionStart read path. All errors are intentionally swallowed so
|
|
95
|
+
* the command emits no bytes and resolves normally (CLI exit status 0).
|
|
96
|
+
*/
|
|
97
|
+
export async function runSessionStartHook(dependencies = {}, budget = MEMORY_CONTEXT_CHAR_BUDGET) {
|
|
98
|
+
const deps = { ...DEFAULT_DEPENDENCIES, ...dependencies };
|
|
99
|
+
try {
|
|
100
|
+
const input = JSON.parse(await deps.readInput());
|
|
101
|
+
if (typeof input.cwd !== "string" || input.cwd.length === 0)
|
|
102
|
+
return;
|
|
103
|
+
const params = searchParams(input.cwd, deps);
|
|
104
|
+
const workspace = process.env.OPVS_WORKSPACE;
|
|
105
|
+
const cfg = deps.getConfig(workspace);
|
|
106
|
+
if (!cfg.token)
|
|
107
|
+
return;
|
|
108
|
+
const response = await deps
|
|
109
|
+
.makeClient(workspace)
|
|
110
|
+
.get(`/api/v1/memory/entries/search?${params.toString()}`);
|
|
111
|
+
const output = renderMemoryContext(entriesFrom(await response.json()), budget);
|
|
112
|
+
if (output)
|
|
113
|
+
deps.writeOutput(output);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// Session startup must remain available when memory is not.
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export function registerMemoryHooks(memory) {
|
|
120
|
+
memory
|
|
121
|
+
.command("hook")
|
|
122
|
+
.description("Claude Code memory hooks")
|
|
123
|
+
.command("session-start")
|
|
124
|
+
.description("Print relevant memories for a Claude Code SessionStart hook")
|
|
125
|
+
.action(async () => {
|
|
126
|
+
await runSessionStartHook();
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=memory-hook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-hook.js","sourceRoot":"","sources":["../../src/commands/memory-hook.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* opvs memory — search typed repository memory and propose human curation.
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
interface MemoryEntry {
|
|
6
|
+
id: string;
|
|
7
|
+
card?: string | null;
|
|
8
|
+
scopes?: string[];
|
|
9
|
+
anchors?: string[];
|
|
10
|
+
pinned?: boolean;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
interface ServicePattern {
|
|
14
|
+
service: string;
|
|
15
|
+
pattern: string;
|
|
16
|
+
}
|
|
17
|
+
/** Keep the API's relative order within the pinned and unpinned groups. */
|
|
18
|
+
export declare function pinnedFirst(entries: MemoryEntry[]): MemoryEntry[];
|
|
19
|
+
/** Read the service names and path patterns from the canonical registry. */
|
|
20
|
+
export declare function parseServicePatterns(registry: string): ServicePattern[];
|
|
21
|
+
/** Apply services.yaml's global "most specific wins" rule to a repository path. */
|
|
22
|
+
export declare function serviceForPath(path: string, patterns: ServicePattern[]): string | undefined;
|
|
23
|
+
export declare function registerMemoryCommands(program: Command): void;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* opvs memory — search typed repository memory and propose human curation.
|
|
3
|
+
*/
|
|
4
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
+
import { dirname, join, resolve } from "node:path";
|
|
6
|
+
import { createClient } from "@opvs-ai/core";
|
|
7
|
+
import { buildUrl, printJson } from "../lib/format.js";
|
|
8
|
+
import { registerMemoryHooks } from "./memory-hook.js";
|
|
9
|
+
const SEARCH_PATH = "/api/v1/memory/entries/search";
|
|
10
|
+
/** Keep the API's relative order within the pinned and unpinned groups. */
|
|
11
|
+
export function pinnedFirst(entries) {
|
|
12
|
+
return entries
|
|
13
|
+
.map((entry, index) => ({ entry, index }))
|
|
14
|
+
.sort((a, b) => Number(Boolean(b.entry.pinned)) - Number(Boolean(a.entry.pinned)) || a.index - b.index)
|
|
15
|
+
.map(({ entry }) => entry);
|
|
16
|
+
}
|
|
17
|
+
function unquote(value) {
|
|
18
|
+
const trimmed = value.trim();
|
|
19
|
+
if (trimmed.length >= 2 &&
|
|
20
|
+
((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
|
|
21
|
+
(trimmed.startsWith("'") && trimmed.endsWith("'")))) {
|
|
22
|
+
return trimmed.slice(1, -1);
|
|
23
|
+
}
|
|
24
|
+
return trimmed;
|
|
25
|
+
}
|
|
26
|
+
/** Read the service names and path patterns from the canonical registry. */
|
|
27
|
+
export function parseServicePatterns(registry) {
|
|
28
|
+
const patterns = [];
|
|
29
|
+
let service;
|
|
30
|
+
let inCodePaths = false;
|
|
31
|
+
for (const line of registry.split(/\r?\n/)) {
|
|
32
|
+
const serviceMatch = line.match(/^ {2}- name:\s*(\S+)\s*$/);
|
|
33
|
+
if (serviceMatch) {
|
|
34
|
+
service = unquote(serviceMatch[1]);
|
|
35
|
+
inCodePaths = false;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (!service)
|
|
39
|
+
continue;
|
|
40
|
+
const planningMatch = line.match(/^ {4}planning_dir:\s*(.+?)\s*$/);
|
|
41
|
+
if (planningMatch) {
|
|
42
|
+
const planningDir = unquote(planningMatch[1].replace(/\s+#.*$/, ""));
|
|
43
|
+
if (planningDir !== "null")
|
|
44
|
+
patterns.push({ service, pattern: planningDir });
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (/^ {4}code_paths:\s*$/.test(line)) {
|
|
48
|
+
inCodePaths = true;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (/^ {4}\S/.test(line)) {
|
|
52
|
+
inCodePaths = false;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (inCodePaths) {
|
|
56
|
+
const pathMatch = line.match(/^ {6}-\s+(.+?)\s*$/);
|
|
57
|
+
if (pathMatch) {
|
|
58
|
+
const pattern = unquote(pathMatch[1].replace(/\s+#.*$/, ""));
|
|
59
|
+
if (pattern)
|
|
60
|
+
patterns.push({ service, pattern });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return patterns;
|
|
65
|
+
}
|
|
66
|
+
function globRegex(pattern) {
|
|
67
|
+
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*+/g, ".*");
|
|
68
|
+
return new RegExp(`^${escaped}${pattern.endsWith("/") ? "" : "$"}`);
|
|
69
|
+
}
|
|
70
|
+
function matchesPattern(path, pattern) {
|
|
71
|
+
if (pattern.includes("*"))
|
|
72
|
+
return globRegex(pattern).test(path);
|
|
73
|
+
return pattern.endsWith("/") ? path.startsWith(pattern) : path === pattern;
|
|
74
|
+
}
|
|
75
|
+
function specificity(pattern) {
|
|
76
|
+
const wildcard = pattern.indexOf("*");
|
|
77
|
+
return [wildcard === -1 ? pattern.length : wildcard, pattern.length];
|
|
78
|
+
}
|
|
79
|
+
/** Apply services.yaml's global "most specific wins" rule to a repository path. */
|
|
80
|
+
export function serviceForPath(path, patterns) {
|
|
81
|
+
const normalized = path.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
82
|
+
let best;
|
|
83
|
+
for (const candidate of patterns) {
|
|
84
|
+
if (!matchesPattern(normalized, candidate.pattern))
|
|
85
|
+
continue;
|
|
86
|
+
if (!best) {
|
|
87
|
+
best = candidate;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const [candidatePrefix, candidateLength] = specificity(candidate.pattern);
|
|
91
|
+
const [bestPrefix, bestLength] = specificity(best.pattern);
|
|
92
|
+
if (candidatePrefix > bestPrefix || (candidatePrefix === bestPrefix && candidateLength > bestLength)) {
|
|
93
|
+
best = candidate;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return best?.service;
|
|
97
|
+
}
|
|
98
|
+
function findServicesRegistry(start) {
|
|
99
|
+
let directory = resolve(start);
|
|
100
|
+
while (true) {
|
|
101
|
+
const candidate = join(directory, "memory", "services.yaml");
|
|
102
|
+
if (existsSync(candidate))
|
|
103
|
+
return candidate;
|
|
104
|
+
const parent = dirname(directory);
|
|
105
|
+
if (parent === directory)
|
|
106
|
+
throw new Error("memory/services.yaml was not found in this repository");
|
|
107
|
+
directory = parent;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function entriesFrom(payload) {
|
|
111
|
+
if (!payload || typeof payload !== "object")
|
|
112
|
+
return [];
|
|
113
|
+
const items = payload.items;
|
|
114
|
+
return Array.isArray(items) ? items : [];
|
|
115
|
+
}
|
|
116
|
+
function uniqueEntries(entries) {
|
|
117
|
+
const seen = new Set();
|
|
118
|
+
return entries.filter((entry) => {
|
|
119
|
+
if (seen.has(entry.id))
|
|
120
|
+
return false;
|
|
121
|
+
seen.add(entry.id);
|
|
122
|
+
return true;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
async function searchEntries(client, params) {
|
|
126
|
+
const response = await client.get(buildUrl(SEARCH_PATH, params));
|
|
127
|
+
return (await response.json());
|
|
128
|
+
}
|
|
129
|
+
function contextResult(entries) {
|
|
130
|
+
const sorted = pinnedFirst(uniqueEntries(entries));
|
|
131
|
+
return { total: sorted.length, items: sorted };
|
|
132
|
+
}
|
|
133
|
+
function fail(error, fallback) {
|
|
134
|
+
const detail = error?.detail;
|
|
135
|
+
console.error(`Error: ${detail || (error instanceof Error ? error.message : fallback)}`);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
export function registerMemoryCommands(program) {
|
|
139
|
+
const memory = program.command("memory").description("Search typed repository memory and request curation");
|
|
140
|
+
registerMemoryHooks(memory);
|
|
141
|
+
memory
|
|
142
|
+
.command("search <query>")
|
|
143
|
+
.description("Search typed memory, with pinned entries first")
|
|
144
|
+
.option("--service <name>", "Restrict to the service scope from memory/services.yaml")
|
|
145
|
+
.option("--type <type>", "Restrict to an entry type")
|
|
146
|
+
.action(async (query, opts) => {
|
|
147
|
+
const wsSlug = program.opts().workspace;
|
|
148
|
+
try {
|
|
149
|
+
const client = createClient(wsSlug);
|
|
150
|
+
const params = { q: query, pinned_first: "true" };
|
|
151
|
+
if (opts.service)
|
|
152
|
+
params.scope = `service:${opts.service}`;
|
|
153
|
+
if (opts.type)
|
|
154
|
+
params.type = opts.type;
|
|
155
|
+
const result = await searchEntries(client, params);
|
|
156
|
+
const items = pinnedFirst(entriesFrom(result));
|
|
157
|
+
printJson({ ...result, total: items.length, items });
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
fail(error, "Failed to search memory");
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
memory
|
|
164
|
+
.command("context")
|
|
165
|
+
.description("Show memory relevant to repository files or a card, with pinned entries first")
|
|
166
|
+
.option("--files <paths>", "Comma-separated repository paths")
|
|
167
|
+
.option("--card <ref>", "Card ref whose memory should be shown")
|
|
168
|
+
.action(async (opts) => {
|
|
169
|
+
if (Boolean(opts.files) === Boolean(opts.card)) {
|
|
170
|
+
console.error("Error: provide exactly one of --files <paths> or --card <ref>");
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
const wsSlug = program.opts().workspace;
|
|
174
|
+
try {
|
|
175
|
+
const client = createClient(wsSlug);
|
|
176
|
+
if (opts.card) {
|
|
177
|
+
const result = await searchEntries(client, {
|
|
178
|
+
card: opts.card,
|
|
179
|
+
pinned_first: "true",
|
|
180
|
+
});
|
|
181
|
+
printJson(contextResult(entriesFrom(result).filter((entry) => entry.card === opts.card)));
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const files = (opts.files ?? "")
|
|
185
|
+
.split(",")
|
|
186
|
+
.map((path) => path.trim().replace(/\\/g, "/").replace(/^\.\//, ""))
|
|
187
|
+
.filter(Boolean);
|
|
188
|
+
const registry = readFileSync(findServicesRegistry(process.cwd()), "utf8");
|
|
189
|
+
const patterns = parseServicePatterns(registry);
|
|
190
|
+
const services = new Set(files.map((path) => serviceForPath(path, patterns)).filter(Boolean));
|
|
191
|
+
const entries = [];
|
|
192
|
+
for (const anchor of files) {
|
|
193
|
+
const result = await searchEntries(client, { anchor, pinned_first: "true" });
|
|
194
|
+
entries.push(...entriesFrom(result));
|
|
195
|
+
}
|
|
196
|
+
for (const service of services) {
|
|
197
|
+
const result = await searchEntries(client, {
|
|
198
|
+
scope: `service:${service}`,
|
|
199
|
+
pinned_first: "true",
|
|
200
|
+
});
|
|
201
|
+
entries.push(...entriesFrom(result));
|
|
202
|
+
}
|
|
203
|
+
printJson(contextResult(entries));
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
fail(error, "Failed to load memory context");
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
memory
|
|
210
|
+
.command("pin-request <id>")
|
|
211
|
+
.description("Propose a pin by commenting on the entry's card; this never pins the entry")
|
|
212
|
+
.requiredOption("--reason <text>", "Why a human should pin this entry")
|
|
213
|
+
.action(async (id, opts) => {
|
|
214
|
+
const wsSlug = program.opts().workspace;
|
|
215
|
+
try {
|
|
216
|
+
const client = createClient(wsSlug);
|
|
217
|
+
const response = await client.get(`/api/v1/memory/entries/${encodeURIComponent(id)}`);
|
|
218
|
+
const entry = (await response.json());
|
|
219
|
+
if (!entry.card) {
|
|
220
|
+
console.error("Error: this memory entry has no card on which to record a pin request");
|
|
221
|
+
process.exit(1);
|
|
222
|
+
}
|
|
223
|
+
const comment = await client.post(`/api/v1/board/tasks/${encodeURIComponent(entry.card)}/comments`, {
|
|
224
|
+
content: `Pin request for memory entry \`${entry.id}\`: ${opts.reason}`,
|
|
225
|
+
});
|
|
226
|
+
printJson(await comment.json());
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
fail(error, "Failed to request a memory pin");
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/commands/memory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { createClient, getEffectiveConfig } from "@opvs-ai/core";
|
|
3
|
+
import { Option } from "commander";
|
|
4
|
+
import { buildUrl, printJson, printResponse } from "../lib/format.js";
|
|
5
|
+
function fail(err, fallback) {
|
|
6
|
+
const error = err;
|
|
7
|
+
console.error(`Error: ${error.detail || error.message || fallback}`);
|
|
8
|
+
return process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
function isNotFound(err) {
|
|
11
|
+
const error = err;
|
|
12
|
+
return error.status === 404 || error.statusCode === 404 || error.detail === "Not found";
|
|
13
|
+
}
|
|
14
|
+
function rejectRefused(result) {
|
|
15
|
+
if (result.status === "rejected") {
|
|
16
|
+
console.error(`Error: ${result.reason || "Message rejected"}`);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
/** Register commands for the current person's PAT-backed OPVS mailbox. */
|
|
23
|
+
export function registerMyMailCommands(program) {
|
|
24
|
+
const myMail = program
|
|
25
|
+
.command("my-mail")
|
|
26
|
+
.description("Read and write your OPVS mailbox");
|
|
27
|
+
myMail
|
|
28
|
+
.command("inbox")
|
|
29
|
+
.description("List messages in your OPVS mailbox")
|
|
30
|
+
.option("--status <status>", "Filter by message status")
|
|
31
|
+
.option("--limit <n>", "Maximum messages to return", "50")
|
|
32
|
+
.action(async (opts) => {
|
|
33
|
+
const workspace = program.opts().workspace;
|
|
34
|
+
const config = getEffectiveConfig(workspace);
|
|
35
|
+
const params = {};
|
|
36
|
+
if (opts.status)
|
|
37
|
+
params.status = opts.status;
|
|
38
|
+
if (opts.limit)
|
|
39
|
+
params.limit = opts.limit;
|
|
40
|
+
try {
|
|
41
|
+
const response = await createClient(workspace).get(buildUrl("/api/v1/me/mail", params, config.format));
|
|
42
|
+
await printResponse(response);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
if (isNotFound(err)) {
|
|
46
|
+
console.error("You have no OPVS mailbox yet.");
|
|
47
|
+
process.exit(1);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
fail(err, "Failed to fetch your mailbox");
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
myMail
|
|
54
|
+
.command("thread <thread_id>")
|
|
55
|
+
.description("Read a thread in your OPVS mailbox")
|
|
56
|
+
.action(async (threadId) => {
|
|
57
|
+
const workspace = program.opts().workspace;
|
|
58
|
+
const config = getEffectiveConfig(workspace);
|
|
59
|
+
try {
|
|
60
|
+
const response = await createClient(workspace).get(buildUrl(`/api/v1/me/mail/threads/${encodeURIComponent(threadId)}`, {}, config.format));
|
|
61
|
+
await printResponse(response);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
fail(err, "Failed to read thread");
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
myMail
|
|
68
|
+
.command("send <to> <body>")
|
|
69
|
+
.description("Send a message from your OPVS mailbox")
|
|
70
|
+
.addOption(new Option("--type <type>", "Message type: ? ! ~ ^ . > <")
|
|
71
|
+
.choices(["?", "!", "~", "^", ".", ">", "<"])
|
|
72
|
+
.default("."))
|
|
73
|
+
.action(async (to, body, opts) => {
|
|
74
|
+
const workspace = program.opts().workspace;
|
|
75
|
+
// Create this once per command invocation. createClient may retry the
|
|
76
|
+
// request, and each attempt must carry the same idempotency key.
|
|
77
|
+
const idempotencyKey = randomUUID();
|
|
78
|
+
try {
|
|
79
|
+
const response = await createClient(workspace).post("/api/v1/me/mail/send", { to, body, type: opts.type }, { "Idempotency-Key": idempotencyKey });
|
|
80
|
+
const result = (await response.json());
|
|
81
|
+
if (rejectRefused(result))
|
|
82
|
+
return;
|
|
83
|
+
printJson(result);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
fail(err, "Failed to send message");
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
myMail
|
|
90
|
+
.command("reply <message_id> <body>")
|
|
91
|
+
.description("Reply to a message in your OPVS mailbox")
|
|
92
|
+
.action(async (messageId, body) => {
|
|
93
|
+
const workspace = program.opts().workspace;
|
|
94
|
+
try {
|
|
95
|
+
const response = await createClient(workspace).post(`/api/v1/me/mail/messages/${encodeURIComponent(messageId)}/reply`, { body });
|
|
96
|
+
const result = (await response.json());
|
|
97
|
+
if (rejectRefused(result))
|
|
98
|
+
return;
|
|
99
|
+
printJson(result);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
fail(err, "Failed to reply");
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
myMail
|
|
106
|
+
.command("status <message_id> <status>")
|
|
107
|
+
.description("Update a message status in your OPVS mailbox")
|
|
108
|
+
.action(async (messageId, status) => {
|
|
109
|
+
const workspace = program.opts().workspace;
|
|
110
|
+
try {
|
|
111
|
+
const response = await createClient(workspace).patch(`/api/v1/me/mail/messages/${encodeURIComponent(messageId)}/status`, { status });
|
|
112
|
+
await printResponse(response);
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
fail(err, "Failed to update message status");
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=myMail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"myMail.js","sourceRoot":"","sources":["../../src/commands/myMail.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -41,11 +41,13 @@ import { registerBoardLinkCommands } from "./commands/board-links.js";
|
|
|
41
41
|
import { registerSkillCommands } from "./commands/skills.js";
|
|
42
42
|
import { registerToolsCommands } from "./commands/tools.js";
|
|
43
43
|
import { registerMailCommands } from "./commands/mail.js";
|
|
44
|
+
import { registerMyMailCommands } from "./commands/myMail.js";
|
|
44
45
|
import { registerReportCommands } from "./commands/report.js";
|
|
45
46
|
import { registerProfessionCommands } from "./commands/professions.js";
|
|
46
47
|
import { registerEmployeeCommands } from "./commands/employees.js";
|
|
47
48
|
import { registerCodeCommands } from "./commands/code.js";
|
|
48
49
|
import { registerEnvCommands } from "./commands/env.js";
|
|
50
|
+
import { registerMemoryCommands } from "./commands/memory.js";
|
|
49
51
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
50
52
|
const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf8"));
|
|
51
53
|
const program = new Command();
|
|
@@ -79,11 +81,13 @@ registerBoardLinkCommands(program);
|
|
|
79
81
|
registerSkillCommands(program);
|
|
80
82
|
registerToolsCommands(program);
|
|
81
83
|
registerMailCommands(program);
|
|
84
|
+
registerMyMailCommands(program);
|
|
82
85
|
registerReportCommands(program);
|
|
83
86
|
registerProfessionCommands(program);
|
|
84
87
|
registerEmployeeCommands(program);
|
|
85
88
|
registerCodeCommands(program);
|
|
86
89
|
registerEnvCommands(program);
|
|
90
|
+
registerMemoryCommands(program);
|
|
87
91
|
registerConfigCommands(program);
|
|
88
92
|
// A config error is a message, not a crash.
|
|
89
93
|
//
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|