openwolf-enhanced 1.16.2 → 1.16.4
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/CHANGELOG.md +51 -0
- package/README.md +34 -0
- package/dist/dashboard/assets/{AISuggestions-CfYkcPYt.js → AISuggestions-Bk2F6IMl.js} +1 -1
- package/dist/dashboard/assets/{ActivityLog-BuDuAa3X.js → ActivityLog-D7u5Uwi1.js} +1 -1
- package/dist/dashboard/assets/{ActivityTimeline-DnCceH8C.js → ActivityTimeline-CLPCD9dE.js} +1 -1
- package/dist/dashboard/assets/{AnatomyBrowser-Cf_co7GW.js → AnatomyBrowser-BVsQpjKI.js} +1 -1
- package/dist/dashboard/assets/{BugLog-DAXpYi7z.js → BugLog-n1EpyWfO.js} +1 -1
- package/dist/dashboard/assets/{CerebrumViewer-CYj5_iUs.js → CerebrumViewer-W7MFBI7b.js} +1 -1
- package/dist/dashboard/assets/{CronStatus-D712dZ8M.js → CronStatus-C9FslgLc.js} +1 -1
- package/dist/dashboard/assets/{DesignQC-CC-TLk8k.js → DesignQC-DvTlN82L.js} +1 -1
- package/dist/dashboard/assets/{MemoryViewer-DO_yKWg4.js → MemoryViewer-CFJ7Bol5.js} +1 -1
- package/dist/dashboard/assets/{NativeMemory-A6y1FYZs.js → NativeMemory-DXCXjoAZ.js} +1 -1
- package/dist/dashboard/assets/{ProjectOverview-gbvCVUph.js → ProjectOverview-BMbticJw.js} +1 -1
- package/dist/dashboard/assets/{ProjectsAggregate-DAczLz74.js → ProjectsAggregate-BZWOl8-e.js} +1 -1
- package/dist/dashboard/assets/{StatusBadge-DKcN72KZ.js → StatusBadge-D7dxnKHj.js} +1 -1
- package/dist/dashboard/assets/{TokenUsage-C82cZ5my.js → TokenUsage-B0slEA8g.js} +1 -1
- package/dist/dashboard/assets/{index-wA0SliM2.js → index-mmPsxyms.js} +3 -3
- package/dist/dashboard/index.html +1 -1
- package/dist/src/cli/index.js +25 -1
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/init.js +2 -0
- package/dist/src/cli/init.js.map +1 -1
- package/dist/src/cli/link-cmd.js +65 -0
- package/dist/src/cli/link-cmd.js.map +1 -0
- package/dist/src/cli/push-cmd.js +90 -0
- package/dist/src/cli/push-cmd.js.map +1 -0
- package/dist/src/cli/recall-cmd.js +93 -9
- package/dist/src/cli/recall-cmd.js.map +1 -1
- package/dist/src/cli/update.js +6 -0
- package/dist/src/cli/update.js.map +1 -1
- package/dist/src/utils/remote.js +226 -0
- package/dist/src/utils/remote.js.map +1 -0
- package/dist/src/utils/wolf-gitignore.js +40 -0
- package/dist/src/utils/wolf-gitignore.js.map +1 -0
- package/package.json +1 -1
- package/src/templates/config.json +15 -2
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { readJSON, writeJSON } from "./fs-safe.js";
|
|
4
|
+
import { blocksFor, entryId } from "./recall.js";
|
|
5
|
+
import { assertSafeBaseUrl } from "../daemon/llm-provider.js";
|
|
6
|
+
export function remoteTokenPath(wolfDir) {
|
|
7
|
+
return path.join(wolfDir, "remote-token");
|
|
8
|
+
}
|
|
9
|
+
export function readRemoteToken(wolfDir) {
|
|
10
|
+
try {
|
|
11
|
+
return fs.readFileSync(remoteTokenPath(wolfDir), "utf-8").trim();
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return "";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function writeRemoteToken(wolfDir, token) {
|
|
18
|
+
const p = remoteTokenPath(wolfDir);
|
|
19
|
+
fs.writeFileSync(p, token, { mode: 0o600 });
|
|
20
|
+
try {
|
|
21
|
+
fs.chmodSync(p, 0o600);
|
|
22
|
+
}
|
|
23
|
+
catch { /* best effort on platforms without chmod */ }
|
|
24
|
+
}
|
|
25
|
+
export function clearRemoteToken(wolfDir) {
|
|
26
|
+
try {
|
|
27
|
+
fs.unlinkSync(remoteTokenPath(wolfDir));
|
|
28
|
+
}
|
|
29
|
+
catch { /* already gone */ }
|
|
30
|
+
}
|
|
31
|
+
// Read openwolf.remote from config.json. Returns null when the project was never linked.
|
|
32
|
+
export function getRemoteConfig(wolfDir) {
|
|
33
|
+
const cfg = readJSON(path.join(wolfDir, "config.json"), {});
|
|
34
|
+
const r = cfg.openwolf?.remote;
|
|
35
|
+
if (!r || !r.base_url)
|
|
36
|
+
return null;
|
|
37
|
+
return { enabled: r.enabled !== false, baseUrl: String(r.base_url), project: r.project };
|
|
38
|
+
}
|
|
39
|
+
// Persist the link. The token is NOT written here — config.json gets committed to git.
|
|
40
|
+
export function setRemoteConfig(wolfDir, remote) {
|
|
41
|
+
const p = path.join(wolfDir, "config.json");
|
|
42
|
+
const cfg = readJSON(p, {});
|
|
43
|
+
cfg.openwolf = { ...(cfg.openwolf ?? {}), remote: { ...remote } };
|
|
44
|
+
writeJSON(p, cfg);
|
|
45
|
+
}
|
|
46
|
+
// A linked project must have BOTH a base url and a token — either alone is a half-configured state
|
|
47
|
+
// that would fail at the first request with a confusing error.
|
|
48
|
+
export function isLinked(wolfDir) {
|
|
49
|
+
const cfg = getRemoteConfig(wolfDir);
|
|
50
|
+
return !!cfg && cfg.enabled && !!readRemoteToken(wolfDir);
|
|
51
|
+
}
|
|
52
|
+
// One hardened request. Reuses assertSafeBaseUrl() from the LLM provider — the SSRF fix from 1.15.1
|
|
53
|
+
// (https-only unless loopback, no private/link-local/metadata hosts) applies here for free, and
|
|
54
|
+
// redirect:"error" keeps a 3xx from carrying the bearer token to another host.
|
|
55
|
+
export async function apiFetch(cfg, token, route, opts = {}) {
|
|
56
|
+
assertSafeBaseUrl(cfg.baseUrl);
|
|
57
|
+
const url = cfg.baseUrl.replace(/\/+$/, "") + route;
|
|
58
|
+
const ac = new AbortController();
|
|
59
|
+
const timer = setTimeout(() => ac.abort(), opts.timeoutMs ?? 20_000);
|
|
60
|
+
try {
|
|
61
|
+
const res = await fetch(url, {
|
|
62
|
+
method: opts.method ?? "GET",
|
|
63
|
+
headers: {
|
|
64
|
+
"content-type": "application/json",
|
|
65
|
+
authorization: `Bearer ${token}`,
|
|
66
|
+
},
|
|
67
|
+
body: opts.body === undefined ? undefined : JSON.stringify(opts.body),
|
|
68
|
+
signal: ac.signal,
|
|
69
|
+
redirect: "error",
|
|
70
|
+
});
|
|
71
|
+
let data = null;
|
|
72
|
+
try {
|
|
73
|
+
data = await res.json();
|
|
74
|
+
}
|
|
75
|
+
catch { /* empty or non-JSON body */ }
|
|
76
|
+
if (!res.ok) {
|
|
77
|
+
const msg = res.status === 401 ? "invalid or revoked token" :
|
|
78
|
+
res.status === 402 ? "workspace plan limit reached (Free = 1 project)" :
|
|
79
|
+
res.status === 403 ? "this token is read-only" :
|
|
80
|
+
data?.error || `HTTP ${res.status}`;
|
|
81
|
+
return { ok: false, status: res.status, data: null, error: msg };
|
|
82
|
+
}
|
|
83
|
+
return { ok: true, status: res.status, data: data };
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
const msg = e.name === "AbortError" ? "timed out" : e.message;
|
|
87
|
+
return { ok: false, status: 0, data: null, error: msg };
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
clearTimeout(timer);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Team citation ids are shown with a `t-` prefix.
|
|
94
|
+
//
|
|
95
|
+
// Both systems mint ids of the shape `c-3f9a2b`, from DIFFERENT hashes over DIFFERENT text — so a
|
|
96
|
+
// local `c-3f9a2b` and a team `c-3f9a2b` can coexist and mean unrelated things. Models already
|
|
97
|
+
// invent citation ids; handing them two colliding namespaces would make every citation unverifiable.
|
|
98
|
+
// One prefix, and the ambiguity is gone.
|
|
99
|
+
export function teamId(cite) {
|
|
100
|
+
const suffix = (cite ?? "").replace(/^c-/, "");
|
|
101
|
+
return suffix ? `t-${suffix}` : "t-?";
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* `t-3f9a2b` → `c-3f9a2b` (what the workspace knows it as).
|
|
105
|
+
* Also accepts a bare `c-…` — that is what someone pastes from the workspace's web UI, and
|
|
106
|
+
* blindly prefixing it would ask the server for `c-c-3f9a2b`, which exists nowhere.
|
|
107
|
+
*/
|
|
108
|
+
export function teamCiteFromId(id) {
|
|
109
|
+
return "c-" + id.replace(/^[tc]-/, "");
|
|
110
|
+
}
|
|
111
|
+
export async function teamRecall(cfg, token, query, limit) {
|
|
112
|
+
const qs = new URLSearchParams({ q: query, limit: String(limit) });
|
|
113
|
+
if (cfg.project)
|
|
114
|
+
qs.set("project", cfg.project);
|
|
115
|
+
const res = await apiFetch(cfg, token, `/api/memory?${qs}`);
|
|
116
|
+
if (!res.ok)
|
|
117
|
+
throw new Error(res.error || "recall failed");
|
|
118
|
+
return res.data?.entries ?? [];
|
|
119
|
+
}
|
|
120
|
+
export async function teamResolve(cfg, token, id) {
|
|
121
|
+
const qs = new URLSearchParams({ cite: teamCiteFromId(id) });
|
|
122
|
+
const res = await apiFetch(cfg, token, `/api/memory?${qs}`);
|
|
123
|
+
if (!res.ok)
|
|
124
|
+
return null;
|
|
125
|
+
return res.data?.entries?.[0] ?? null;
|
|
126
|
+
}
|
|
127
|
+
// Which cerebrum sections map to which remote type.
|
|
128
|
+
//
|
|
129
|
+
// memory.md is deliberately NOT a source: it is mostly mechanical ("Edited foo.ts, 3→5 lines").
|
|
130
|
+
// Pushing that into a shared brain is noise, and noise is what makes people stop reading it.
|
|
131
|
+
// User Preferences are also skipped by default — they describe how *this person* wants to be worked
|
|
132
|
+
// with, which is not the team's business unless they say so (--with-preferences).
|
|
133
|
+
const SECTION_MAP = [
|
|
134
|
+
{ match: /^#+\s*Key Learnings/i, type: "learning", tag: "key-learning" },
|
|
135
|
+
{ match: /^#+\s*Decision Log/i, type: "decision", tag: "decision" },
|
|
136
|
+
{ match: /^#+\s*Do-Not-Repeat/i, type: "learning", tag: "do-not-repeat" },
|
|
137
|
+
{ match: /^#+\s*User Preferences/i, type: "note", tag: "preference", personal: true },
|
|
138
|
+
];
|
|
139
|
+
/** First line of a block, stripped of markdown noise, as a title. */
|
|
140
|
+
export function titleFor(blockText) {
|
|
141
|
+
const first = blockText.split("\n")[0] || "";
|
|
142
|
+
return first
|
|
143
|
+
.replace(/^[-*]\s+/, "")
|
|
144
|
+
.replace(/^#+\s+/, "")
|
|
145
|
+
.replace(/\*\*/g, "")
|
|
146
|
+
.trim()
|
|
147
|
+
.slice(0, 120);
|
|
148
|
+
}
|
|
149
|
+
/** Cerebrum entries, grouped by the section they live under. */
|
|
150
|
+
export function cerebrumCandidates(content, opts = {}) {
|
|
151
|
+
const lines = content.split(/\r?\n/);
|
|
152
|
+
// blocksFor() already blanks <private> regions, so private text can never reach a candidate.
|
|
153
|
+
const blocks = blocksFor("cerebrum.md", content);
|
|
154
|
+
const out = [];
|
|
155
|
+
for (const b of blocks) {
|
|
156
|
+
// Which section is this block under? Walk backwards to the nearest heading.
|
|
157
|
+
let section;
|
|
158
|
+
for (let i = b.start - 1; i >= 0; i--) {
|
|
159
|
+
const line = lines[i] ?? "";
|
|
160
|
+
if (!/^#+\s/.test(line))
|
|
161
|
+
continue;
|
|
162
|
+
section = SECTION_MAP.find((s) => s.match.test(line));
|
|
163
|
+
break; // nearest heading decides, even if it maps to nothing
|
|
164
|
+
}
|
|
165
|
+
if (!section)
|
|
166
|
+
continue;
|
|
167
|
+
if (section.personal && !opts.withPreferences)
|
|
168
|
+
continue;
|
|
169
|
+
// The heading itself is a block — don't push the heading as an entry.
|
|
170
|
+
if (/^#+\s/.test(b.text))
|
|
171
|
+
continue;
|
|
172
|
+
const text = b.text.trim();
|
|
173
|
+
if (text.length < 40)
|
|
174
|
+
continue; // one-liners are rarely worth a team entry
|
|
175
|
+
out.push({
|
|
176
|
+
localId: entryId("cerebrum.md", b.text),
|
|
177
|
+
type: section.type,
|
|
178
|
+
title: titleFor(text),
|
|
179
|
+
body: text,
|
|
180
|
+
tags: ["openwolf", section.tag],
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
return out;
|
|
184
|
+
}
|
|
185
|
+
/** buglog.json entries → type "bug". Auto-detected ones are skipped: they are guesses, not knowledge. */
|
|
186
|
+
export function buglogCandidates(raw) {
|
|
187
|
+
const bugs = Array.isArray(raw)
|
|
188
|
+
? raw
|
|
189
|
+
: (raw?.bugs ?? []);
|
|
190
|
+
const out = [];
|
|
191
|
+
for (const b of bugs) {
|
|
192
|
+
const tags = b.tags ?? [];
|
|
193
|
+
if (tags.includes("auto-detected"))
|
|
194
|
+
continue; // pattern guesses from the write hook, not real findings
|
|
195
|
+
if (!b.error_message || !b.fix)
|
|
196
|
+
continue;
|
|
197
|
+
const body = [
|
|
198
|
+
b.error_message,
|
|
199
|
+
b.file ? `File: ${b.file}` : "",
|
|
200
|
+
b.root_cause ? `Root cause: ${b.root_cause}` : "",
|
|
201
|
+
`Fix: ${b.fix}`,
|
|
202
|
+
].filter(Boolean).join("\n");
|
|
203
|
+
out.push({
|
|
204
|
+
localId: entryId("buglog.json", body),
|
|
205
|
+
type: "bug",
|
|
206
|
+
title: titleFor(b.error_message),
|
|
207
|
+
body,
|
|
208
|
+
tags: ["openwolf", "bug", ...tags.slice(0, 5)],
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
return out;
|
|
212
|
+
}
|
|
213
|
+
export function pushStatePath(wolfDir) {
|
|
214
|
+
return path.join(wolfDir, "remote-pushed.json");
|
|
215
|
+
}
|
|
216
|
+
export function readPushed(wolfDir) {
|
|
217
|
+
const s = readJSON(pushStatePath(wolfDir), { pushed: [] });
|
|
218
|
+
return new Set(s.pushed ?? []);
|
|
219
|
+
}
|
|
220
|
+
export function markPushed(wolfDir, ids) {
|
|
221
|
+
const cur = readPushed(wolfDir);
|
|
222
|
+
for (const id of ids)
|
|
223
|
+
cur.add(id);
|
|
224
|
+
writeJSON(pushStatePath(wolfDir), { pushed: [...cur] });
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=remote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../../../src/utils/remote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAqB9D,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,YAAY,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,KAAa;IAC7D,MAAM,CAAC,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACnC,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5C,IAAI,CAAC;QAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,4CAA4C,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,IAAI,CAAC;QAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;AAC/E,CAAC;AAKD,yFAAyF;AACzF,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,MAAM,GAAG,GAAG,QAAQ,CAAwC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC;IACnG,MAAM,CAAC,GAAG,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC/B,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;AAC3F,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,MAAiB;IAChE,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,QAAQ,CAAyC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpE,GAAG,CAAC,QAAQ,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC;IAClE,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACpB,CAAC;AAED,mGAAmG;AACnG,+DAA+D;AAC/D,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;AAC5D,CAAC;AASD,oGAAoG;AACpG,gGAAgG;AAChG,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,GAAiB,EACjB,KAAa,EACb,KAAa,EACb,IAAI,GAA4D,EAAE;IAElE,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC;IACpD,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC;IACrE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC3B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK;YAC5B,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,KAAK,EAAE;aACjC;YACD,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;YACrE,MAAM,EAAE,EAAE,CAAC,MAAM;YACjB,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;QACH,IAAI,IAAI,GAAY,IAAI,CAAC;QACzB,IAAI,CAAC;YAAC,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,4BAA4B,CAAC,CAAC;QACvE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,GAAG,GACP,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC;gBACjD,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,iDAAiD,CAAC,CAAC;oBACxE,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC;wBAC/C,IAAkC,EAAE,KAAK,IAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC;YACrE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QACnE,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAS,EAAE,CAAC;IAC3D,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,GAAG,GAAI,CAAW,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAE,CAAW,CAAC,OAAO,CAAC;QACpF,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IAC1D,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAgBD,kDAAkD;AAClD,EAAE;AACF,kGAAkG;AAClG,+FAA+F;AAC/F,qGAAqG;AACrG,yCAAyC;AACzC,MAAM,UAAU,MAAM,CAAC,IAA+B;IACpD,MAAM,MAAM,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC/C,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;AACxC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,OAAO,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAiB,EAAE,KAAa,EAAE,KAAa,EAAE,KAAa;IAE9D,MAAM,EAAE,GAAG,IAAI,eAAe,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnE,IAAI,GAAG,CAAC,OAAO;QAAE,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAA4B,GAAG,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;IACvF,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,eAAe,CAAC,CAAC;IAC3D,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,GAAiB,EAAE,KAAa,EAAE,EAAU;IAE5C,MAAM,EAAE,GAAG,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC7D,MAAM,GAAG,GAAG,MAAM,QAAQ,CAA4B,GAAG,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;IACvF,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACzB,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACxC,CAAC;AAgBD,oDAAoD;AACpD,EAAE;AACF,gGAAgG;AAChG,6FAA6F;AAC7F,oGAAoG;AACpG,kFAAkF;AAClF,MAAM,WAAW,GAAgF;IAC/F,EAAE,KAAK,EAAE,sBAAsB,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,cAAc,EAAE;IACxE,EAAE,KAAK,EAAE,qBAAqB,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE;IACnE,EAAE,KAAK,EAAE,sBAAsB,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,eAAe,EAAE;IACzE,EAAE,KAAK,EAAE,yBAAyB,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE;CACtF,CAAC;AAEF,qEAAqE;AACrE,MAAM,UAAU,QAAQ,CAAC,SAAiB;IACxC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7C,OAAO,KAAK;SACT,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;SACpB,IAAI,EAAE;SACN,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACnB,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,IAAI,GAAkC,EAAE;IAC1F,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACrC,6FAA6F;IAC7F,MAAM,MAAM,GAAG,SAAS,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACjD,MAAM,GAAG,GAAgB,EAAE,CAAC;IAE5B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,4EAA4E;QAC5E,IAAI,OAAiD,CAAC;QACtD,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,SAAS;YAClC,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACtD,MAAM,CAAC,sDAAsD;QAC/D,CAAC;QACD,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,SAAS;QACxD,sEAAsE;QACtE,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YAAE,SAAS;QAEnC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE;YAAE,SAAS,CAAC,2CAA2C;QAE3E,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC;YACvC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC;YACrB,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC;SAChC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAWD,yGAAyG;AACzG,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,MAAM,IAAI,GAAe,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QACzC,CAAC,CAAE,GAAkB;QACrB,CAAC,CAAC,CAAE,GAAoC,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;IACxD,MAAM,GAAG,GAAgB,EAAE,CAAC;IAE5B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;YAAE,SAAS,CAAC,yDAAyD;QACvG,IAAI,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,GAAG;YAAE,SAAS;QAEzC,MAAM,IAAI,GAAG;YACX,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;YAC/B,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE;YACjD,QAAQ,CAAC,CAAC,GAAG,EAAE;SAChB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE7B,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC;YACrC,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC;YAChC,IAAI;YACJ,IAAI,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;SAC/C,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AASD,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,MAAM,CAAC,GAAG,QAAQ,CAAY,aAAa,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACtE,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,GAAa;IACvD,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAChC,KAAK,MAAM,EAAE,IAAI,GAAG;QAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClC,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
// .wolf/.gitignore — keep local secrets out of the repository.
|
|
4
|
+
//
|
|
5
|
+
// The .wolf directory is meant to be committed: that is the whole point of a shared brain. But two
|
|
6
|
+
// files in it must never be, and one of them now grants write access to a team workspace. 0600 file
|
|
7
|
+
// permissions protect against other users on the machine; they do nothing against `git add .wolf`.
|
|
8
|
+
//
|
|
9
|
+
// Written from code, not from src/templates/: npm silently drops files named .gitignore from the
|
|
10
|
+
// published package, so a template would exist in the repo and be missing in every install.
|
|
11
|
+
const ENTRIES = [
|
|
12
|
+
{ pattern: "dashboard-token", why: "bearer token for the local dashboard API" },
|
|
13
|
+
{ pattern: "remote-token", why: "workspace token — grants write access to the team's memory" },
|
|
14
|
+
{ pattern: "remote-pushed.json", why: "per-machine push bookkeeping, not shared state" },
|
|
15
|
+
];
|
|
16
|
+
const HEADER = "# Managed by OpenWolf — local secrets and machine-local state, never commit these.";
|
|
17
|
+
/** Create or extend .wolf/.gitignore. Idempotent: only missing lines are appended. */
|
|
18
|
+
export function ensureWolfGitignore(wolfDir) {
|
|
19
|
+
const p = path.join(wolfDir, ".gitignore");
|
|
20
|
+
let existing = "";
|
|
21
|
+
try {
|
|
22
|
+
existing = fs.readFileSync(p, "utf-8");
|
|
23
|
+
}
|
|
24
|
+
catch { /* not there yet */ }
|
|
25
|
+
// Compare against the PATTERN, not the raw line: we write `remote-token # why`, so a naive
|
|
26
|
+
// line-equality check never matches and every update would append the block again.
|
|
27
|
+
const present = new Set(existing.split(/\r?\n/).map((l) => l.replace(/#.*$/, "").trim()).filter(Boolean));
|
|
28
|
+
const missing = ENTRIES.filter((e) => !present.has(e.pattern));
|
|
29
|
+
if (existing && missing.length === 0)
|
|
30
|
+
return "ok";
|
|
31
|
+
const block = missing.map((e) => `${e.pattern} # ${e.why}`).join("\n");
|
|
32
|
+
if (!existing) {
|
|
33
|
+
fs.writeFileSync(p, `${HEADER}\n${block}\n`, "utf-8");
|
|
34
|
+
return "created";
|
|
35
|
+
}
|
|
36
|
+
const sep = existing.endsWith("\n") ? "" : "\n";
|
|
37
|
+
fs.appendFileSync(p, `${sep}${HEADER}\n${block}\n`, "utf-8");
|
|
38
|
+
return "updated";
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=wolf-gitignore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wolf-gitignore.js","sourceRoot":"","sources":["../../../src/utils/wolf-gitignore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,+DAA+D;AAC/D,EAAE;AACF,mGAAmG;AACnG,oGAAoG;AACpG,mGAAmG;AACnG,EAAE;AACF,iGAAiG;AACjG,4FAA4F;AAC5F,MAAM,OAAO,GAA4C;IACvD,EAAE,OAAO,EAAE,iBAAiB,EAAE,GAAG,EAAE,0CAA0C,EAAE;IAC/E,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,4DAA4D,EAAE;IAC9F,EAAE,OAAO,EAAE,oBAAoB,EAAE,GAAG,EAAE,gDAAgD,EAAE;CACzF,CAAC;AAEF,MAAM,MAAM,GAAG,oFAAoF,CAAC;AAEpG,sFAAsF;AACtF,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAE3C,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,IAAI,CAAC;QAAC,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC;IAE7E,8FAA8F;IAC9F,mFAAmF;IACnF,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CACjF,CAAC;IACF,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/D,IAAI,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAElD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE1E,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,GAAG,MAAM,KAAK,KAAK,IAAI,EAAE,OAAO,CAAC,CAAC;QACtD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAChD,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,GAAG,GAAG,GAAG,MAAM,KAAK,KAAK,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7D,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openwolf-enhanced",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.4",
|
|
4
4
|
"description": "A second brain for Claude Code, Codex & Gemini — persistent git-native project memory with searchable citations, an MCP server for Claude Desktop, and invisible hook-based context. No database.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -56,6 +56,11 @@
|
|
|
56
56
|
"enabled": false,
|
|
57
57
|
"log_max_bytes": 131072
|
|
58
58
|
},
|
|
59
|
+
"remote": {
|
|
60
|
+
"enabled": false,
|
|
61
|
+
"base_url": "",
|
|
62
|
+
"project": ""
|
|
63
|
+
},
|
|
59
64
|
"session_context": {
|
|
60
65
|
"enabled": true,
|
|
61
66
|
"max_chars": 6000
|
|
@@ -85,8 +90,16 @@
|
|
|
85
90
|
"designqc": {
|
|
86
91
|
"enabled": true,
|
|
87
92
|
"viewports": [
|
|
88
|
-
{
|
|
89
|
-
|
|
93
|
+
{
|
|
94
|
+
"name": "desktop",
|
|
95
|
+
"width": 1440,
|
|
96
|
+
"height": 900
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"name": "mobile",
|
|
100
|
+
"width": 375,
|
|
101
|
+
"height": 812
|
|
102
|
+
}
|
|
90
103
|
],
|
|
91
104
|
"max_screenshots": 6,
|
|
92
105
|
"chrome_path": null
|