mnemos-capture 1.4.0 → 1.5.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/README.md +13 -13
- package/dist/cli/hooks.js +10 -17
- package/dist/cli/index.js +1 -1
- package/dist/cli/kos.js +55 -17
- package/dist/cli/mcp-server.js +2 -2
- package/dist/cli/version-check.js +7 -5
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<br>
|
|
3
|
-
<a href="https://
|
|
3
|
+
<a href="https://xkg.xmu.sh">
|
|
4
4
|
<picture>
|
|
5
|
-
<source media="(prefers-color-scheme: dark)" srcset="public/
|
|
6
|
-
<img src="public/
|
|
5
|
+
<source media="(prefers-color-scheme: dark)" srcset="public/xkg-hero-dark.gif">
|
|
6
|
+
<img src="public/xkg-hero-light.gif" width="160" height="160" alt="xkg">
|
|
7
7
|
</picture>
|
|
8
8
|
</a>
|
|
9
9
|
<br>
|
|
@@ -53,7 +53,7 @@ You find useful stuff, you capture through the web app, then xkg connects it int
|
|
|
53
53
|
xkg will continuously compound that knowledge over time — keeping AI workers' context up to date as human knowledge evolves.
|
|
54
54
|
|
|
55
55
|
> [!IMPORTANT]
|
|
56
|
-
> We are migrating from **mnemos** / **Xmu** to **xkg**. The app
|
|
56
|
+
> We are migrating from **mnemos** / **Xmu** to **xkg**. The app now lives at [xkg.xmu.sh](https://xkg.xmu.sh) and the code at [xmu-labs/xkg](https://github.com/xmu-labs/xkg). Connectors set up with `mnemos-capture.vercel.app` keep working. The npm package still says `mnemos-capture`. Sorry for the inconvenience.
|
|
57
57
|
|
|
58
58
|
## Start here
|
|
59
59
|
|
|
@@ -61,7 +61,7 @@ You do not need a terminal to start.
|
|
|
61
61
|
|
|
62
62
|
### 1. Create your account
|
|
63
63
|
|
|
64
|
-
Open **[
|
|
64
|
+
Open **[xkg.xmu.sh](https://xkg.xmu.sh)** and sign in with GitHub.
|
|
65
65
|
|
|
66
66
|
xkg will:
|
|
67
67
|
|
|
@@ -91,7 +91,7 @@ xkg is LLM-agnostic. Any worker that speaks MCP can use the same knowledge.
|
|
|
91
91
|
Two primitives:
|
|
92
92
|
|
|
93
93
|
```text
|
|
94
|
-
https://
|
|
94
|
+
https://xkg.xmu.sh/api/mcp
|
|
95
95
|
```
|
|
96
96
|
|
|
97
97
|
```bash
|
|
@@ -104,7 +104,7 @@ The CLI binary is **`xkg`** (also `xmu` and `mnemos-capture`). `npx` still uses
|
|
|
104
104
|
|
|
105
105
|
### On the web
|
|
106
106
|
|
|
107
|
-
Name the connector `xkg`, paste `https://
|
|
107
|
+
Name the connector `xkg`, paste `https://xkg.xmu.sh/api/mcp`, sign in with GitHub when asked.
|
|
108
108
|
|
|
109
109
|
#### Claude
|
|
110
110
|
|
|
@@ -114,7 +114,7 @@ Name the connector `xkg`, paste `https://mnemos-capture.vercel.app/api/mcp`, sig
|
|
|
114
114
|
|
|
115
115
|
1. Settings → Plugins → Browse plugins
|
|
116
116
|
2. Name it xkg
|
|
117
|
-
3. Paste `https://
|
|
117
|
+
3. Paste `https://xkg.xmu.sh/api/mcp`
|
|
118
118
|
4. Sign in with GitHub when asked
|
|
119
119
|
|
|
120
120
|
#### Grok
|
|
@@ -192,7 +192,7 @@ claude mcp add xkg -- npx -y mnemos-capture@latest serve-mcp --key YOUR_API_KEY
|
|
|
192
192
|
Or the URL, no API key:
|
|
193
193
|
|
|
194
194
|
```bash
|
|
195
|
-
claude mcp add --transport http xkg https://
|
|
195
|
+
claude mcp add --transport http xkg https://xkg.xmu.sh/api/mcp
|
|
196
196
|
```
|
|
197
197
|
|
|
198
198
|
Optional session hooks (MCP works without them):
|
|
@@ -233,7 +233,7 @@ If the tool can launch a local process, register the same `npx` command. If it h
|
|
|
233
233
|
}
|
|
234
234
|
```
|
|
235
235
|
|
|
236
|
-
No MCP support yet? Capture in the [xkg app](https://
|
|
236
|
+
No MCP support yet? Capture in the [xkg app](https://xkg.xmu.sh) and connect later.
|
|
237
237
|
|
|
238
238
|
## Workflow
|
|
239
239
|
|
|
@@ -249,7 +249,7 @@ No MCP support yet? Capture in the [xkg app](https://mnemos-capture.vercel.app)
|
|
|
249
249
|
capture "The Mom Test: don't ask if your idea is good. Ask about the person's real behavior, current workflow, and past spending."
|
|
250
250
|
```
|
|
251
251
|
|
|
252
|
-
2. **Brief** — At the start of a work session, ask your worker for a briefing. xkg
|
|
252
|
+
2. **Brief** — At the start of a work session, ask your worker for a briefing. xkg uses your project name, branch, and recent commit messages to rank captures that could help now: **why** it matters, **what** applying it could achieve, **where** it could land. Local agent instruction files are not read or uploaded by the CLI hooks. You decide what to apply.
|
|
253
253
|
|
|
254
254
|
3. **Plan** — Select the captures you want and ask your worker to call `generate_plan`. Each plan is Markdown: codebase mapping, implementation steps with effort tiers (`simple`, `complex`, `architectural`), and a verification checklist.
|
|
255
255
|
|
|
@@ -428,12 +428,12 @@ Working on the code? See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
|
428
428
|
If you use xkg in published work:
|
|
429
429
|
|
|
430
430
|
```bibtex
|
|
431
|
-
@misc{
|
|
431
|
+
@misc{2026xkg,
|
|
432
432
|
title = {xkg: A Knowledge Graph for AI workers},
|
|
433
433
|
author = {Sofia Padron Valdez},
|
|
434
434
|
year = 2026,
|
|
435
435
|
journal = {GitHub repository},
|
|
436
436
|
publisher = {GitHub},
|
|
437
|
-
howpublished = {\url{https://github.com/
|
|
437
|
+
howpublished = {\url{https://github.com/xmu-labs/xkg}}
|
|
438
438
|
}
|
|
439
439
|
```
|
package/dist/cli/hooks.js
CHANGED
|
@@ -2,14 +2,14 @@ import { homedir, tmpdir } from "os";
|
|
|
2
2
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
3
3
|
import { join } from "path";
|
|
4
4
|
import { execSync } from "child_process";
|
|
5
|
-
const HOSTED_URL = "https://
|
|
5
|
+
const HOSTED_URL = "https://xkg.xmu.sh/api/mcp";
|
|
6
6
|
const CLAUDE_SETTINGS_PATH = join(homedir(), ".claude", "settings.json");
|
|
7
7
|
// Matches both legacy ("mnemos-capture inbox-check") and modern
|
|
8
8
|
// ("mnemos-capture@latest inbox-check") hook command forms.
|
|
9
|
-
function
|
|
9
|
+
function isXkgHook(cmd) {
|
|
10
10
|
return cmd.includes("mnemos-capture") && cmd.includes("inbox-check");
|
|
11
11
|
}
|
|
12
|
-
function
|
|
12
|
+
function isXkgPreToolHook(cmd) {
|
|
13
13
|
return cmd.includes("mnemos-capture") && cmd.includes("vault-check");
|
|
14
14
|
}
|
|
15
15
|
function readSettings() {
|
|
@@ -73,11 +73,11 @@ export function setupHooks(apiKey, opts = {}) {
|
|
|
73
73
|
const settings = readSettings();
|
|
74
74
|
const hooks = settings.hooks ?? {};
|
|
75
75
|
const sessionStart = hooks.SessionStart ?? [];
|
|
76
|
-
// Inspect any existing
|
|
76
|
+
// Inspect any existing xkg hook so we can either skip, migrate, or replace
|
|
77
77
|
let existingCmd = null;
|
|
78
78
|
for (const group of sessionStart) {
|
|
79
79
|
for (const h of group.hooks ?? []) {
|
|
80
|
-
if (typeof h.command === "string" &&
|
|
80
|
+
if (typeof h.command === "string" && isXkgHook(h.command)) {
|
|
81
81
|
existingCmd = h.command;
|
|
82
82
|
break;
|
|
83
83
|
}
|
|
@@ -97,11 +97,11 @@ export function setupHooks(apiKey, opts = {}) {
|
|
|
97
97
|
const command = opts.briefing
|
|
98
98
|
? `npx -y mnemos-capture@latest inbox-check --key ${apiKey} --briefing`
|
|
99
99
|
: `npx -y mnemos-capture@latest inbox-check --key ${apiKey}`;
|
|
100
|
-
// Remove any existing
|
|
100
|
+
// Remove any existing xkg inbox-check hook (handles key rotation too)
|
|
101
101
|
const filtered = sessionStart
|
|
102
102
|
.map((group) => ({
|
|
103
103
|
...group,
|
|
104
|
-
hooks: (group.hooks ?? []).filter((h) => !(typeof h.command === "string" &&
|
|
104
|
+
hooks: (group.hooks ?? []).filter((h) => !(typeof h.command === "string" && isXkgHook(h.command))),
|
|
105
105
|
}))
|
|
106
106
|
.filter((group) => (group.hooks ?? []).length > 0);
|
|
107
107
|
filtered.push({ hooks: [{ type: "command", command }] });
|
|
@@ -128,7 +128,7 @@ export function setupPreToolHook(apiKey, opts = {}) {
|
|
|
128
128
|
let existingCmd = null;
|
|
129
129
|
for (const group of preToolCall) {
|
|
130
130
|
for (const h of group.hooks ?? []) {
|
|
131
|
-
if (typeof h.command === "string" &&
|
|
131
|
+
if (typeof h.command === "string" && isXkgPreToolHook(h.command)) {
|
|
132
132
|
existingCmd = h.command;
|
|
133
133
|
break;
|
|
134
134
|
}
|
|
@@ -144,7 +144,7 @@ export function setupPreToolHook(apiKey, opts = {}) {
|
|
|
144
144
|
const filtered = preToolCall
|
|
145
145
|
.map((group) => ({
|
|
146
146
|
...group,
|
|
147
|
-
hooks: (group.hooks ?? []).filter((h) => !(typeof h.command === "string" &&
|
|
147
|
+
hooks: (group.hooks ?? []).filter((h) => !(typeof h.command === "string" && isXkgPreToolHook(h.command))),
|
|
148
148
|
}))
|
|
149
149
|
.filter((group) => (group.hooks ?? []).length > 0);
|
|
150
150
|
filtered.push({ hooks: [{ type: "command", command }] });
|
|
@@ -187,14 +187,7 @@ function detectProjectContext() {
|
|
|
187
187
|
parts.push(`Recent commits:\n${log}`);
|
|
188
188
|
}
|
|
189
189
|
catch { }
|
|
190
|
-
//
|
|
191
|
-
try {
|
|
192
|
-
const root = run("git rev-parse --show-toplevel");
|
|
193
|
-
const claudeMd = readFileSync(join(root, "CLAUDE.md"), "utf-8").slice(0, 800).trim();
|
|
194
|
-
if (claudeMd)
|
|
195
|
-
parts.push(`Project instructions (CLAUDE.md excerpt):\n${claudeMd}`);
|
|
196
|
-
}
|
|
197
|
-
catch { }
|
|
190
|
+
// Local agent instructions may contain private maintainer notes; do not upload them.
|
|
198
191
|
return parts.length > 0 ? parts.join("\n\n") : "current project";
|
|
199
192
|
}
|
|
200
193
|
export async function callMcp(apiKey, toolName, toolArgs, timeoutMs = 15000) {
|
package/dist/cli/index.js
CHANGED
package/dist/cli/kos.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* kos —
|
|
2
|
+
* kos — xkg's Knowledge Operations orchestrator.
|
|
3
3
|
*
|
|
4
4
|
* Drives whatever AI assistant the user configured (`xkg config set agent ...`)
|
|
5
|
-
* to implement a generated plan in an isolated git worktree.
|
|
5
|
+
* to implement a generated plan in an isolated git worktree. xkg owns the
|
|
6
6
|
* harness-independent parts: fetching the plan, the worktree, and reporting the
|
|
7
7
|
* Verification Checklist. The assistant is a black box — model-agnostic by design.
|
|
8
8
|
*/
|
|
9
9
|
import { tmpdir } from "os";
|
|
10
|
-
import { join } from "path";
|
|
11
|
-
import { writeFileSync, existsSync,
|
|
10
|
+
import { dirname, join, resolve } from "path";
|
|
11
|
+
import { writeFileSync, existsSync, mkdirSync, readFileSync } from "fs";
|
|
12
12
|
import { execSync } from "child_process";
|
|
13
13
|
import { callMcp } from "./hooks.js";
|
|
14
14
|
import { readConfig } from "./config.js";
|
|
@@ -39,14 +39,53 @@ export function parseChecklist(planText) {
|
|
|
39
39
|
/** Build a unique, sortable branch name for a kos run. */
|
|
40
40
|
export function buildKosBranch(now = new Date()) {
|
|
41
41
|
const stamp = now.toISOString().replace(/[:.]/g, "-").replace("T", "-").slice(0, 19);
|
|
42
|
-
return `
|
|
42
|
+
return `xkg/kos-${stamp}`;
|
|
43
43
|
}
|
|
44
|
+
/** Where kos drops the plan inside the worktree. Never committed — see excludePlanFiles. */
|
|
45
|
+
export const PLAN_FILE = "XKG_PLAN.md";
|
|
46
|
+
/** Plan filenames written by earlier releases; still excluded so an old worktree can't leak one. */
|
|
47
|
+
const LEGACY_PLAN_FILES = ["MNEMOS_PLAN.md"];
|
|
44
48
|
/** The instruction handed to the assistant. The plan file is the real contract. */
|
|
45
|
-
export const KOS_PROMPT =
|
|
49
|
+
export const KOS_PROMPT = `Implement the plan in ${PLAN_FILE} in this repository. ` +
|
|
46
50
|
"Follow the Codebase Mapping table exactly — change only the files it lists. " +
|
|
47
51
|
"For each step apply the thinking effort named in its Effort column " +
|
|
48
52
|
"(low = quick/mechanical, medium = careful, high = deep reasoning). " +
|
|
49
|
-
"When finished, make sure every item in the Verification Checklist is satisfied."
|
|
53
|
+
"When finished, make sure every item in the Verification Checklist is satisfied. " +
|
|
54
|
+
`${PLAN_FILE} is private: never commit, push, or copy it into another file.`;
|
|
55
|
+
/**
|
|
56
|
+
* Return the exclude-file contents with every plan filename present, or null if
|
|
57
|
+
* nothing needs adding. Pure so the matching can be tested without a repo.
|
|
58
|
+
*/
|
|
59
|
+
export function withPlanExcludes(current) {
|
|
60
|
+
const lines = new Set(current.split(/\r?\n/).map((l) => l.trim()));
|
|
61
|
+
const missing = [PLAN_FILE, ...LEGACY_PLAN_FILES].filter((f) => !lines.has(f) && !lines.has(`/${f}`));
|
|
62
|
+
if (missing.length === 0)
|
|
63
|
+
return null;
|
|
64
|
+
const sep = current === "" || current.endsWith("\n") ? "" : "\n";
|
|
65
|
+
return `${current}${sep}${missing.join("\n")}\n`;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Keep plan files out of git for this repository and all its worktrees.
|
|
69
|
+
*
|
|
70
|
+
* Asks git for the exclude path instead of assuming `<root>/.git/info/exclude`:
|
|
71
|
+
* in a linked worktree or a submodule `.git` is a file, so the assumed path does
|
|
72
|
+
* not exist and the plan would be silently committed by the agent's `git add`.
|
|
73
|
+
* Throws rather than continuing unprotected — a plan can carry private context.
|
|
74
|
+
*/
|
|
75
|
+
export function excludePlanFiles(worktreePath) {
|
|
76
|
+
const excludePath = resolve(worktreePath, run("git rev-parse --git-path info/exclude", worktreePath));
|
|
77
|
+
mkdirSync(dirname(excludePath), { recursive: true });
|
|
78
|
+
const current = existsSync(excludePath) ? readFileSync(excludePath, "utf-8") : "";
|
|
79
|
+
const next = withPlanExcludes(current);
|
|
80
|
+
if (next !== null)
|
|
81
|
+
writeFileSync(excludePath, next);
|
|
82
|
+
try {
|
|
83
|
+
run(`git check-ignore -q ${PLAN_FILE}`, worktreePath);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
throw new Error(`git would track ${PLAN_FILE} (exclude file: ${excludePath})`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
50
89
|
// ── Orchestrator ──
|
|
51
90
|
function run(cmd, cwd) {
|
|
52
91
|
return execSync(cmd, { cwd, stdio: ["pipe", "pipe", "pipe"] }).toString().trim();
|
|
@@ -86,19 +125,18 @@ export async function kos(apiKey, opts = {}) {
|
|
|
86
125
|
const worktreePath = join(tmpdir(), branch.replace(/\//g, "-"));
|
|
87
126
|
console.log(`Creating isolated worktree on branch ${branch}...`);
|
|
88
127
|
run(`git worktree add -b ${branch} "${worktreePath}"`, repoRoot);
|
|
89
|
-
// 4.
|
|
90
|
-
|
|
128
|
+
// 4. Keep git from tracking the plan (local exclude, not committed), then drop it in.
|
|
129
|
+
// Exclude first: if that fails, the plan is never written where git can see it.
|
|
91
130
|
try {
|
|
92
|
-
|
|
93
|
-
if (existsSync(excludePath)) {
|
|
94
|
-
const current = readFileSync(excludePath, "utf-8");
|
|
95
|
-
if (!current.includes("MNEMOS_PLAN.md"))
|
|
96
|
-
appendFileSync(excludePath, "\nMNEMOS_PLAN.md\n");
|
|
97
|
-
}
|
|
131
|
+
excludePlanFiles(worktreePath);
|
|
98
132
|
}
|
|
99
|
-
catch {
|
|
100
|
-
|
|
133
|
+
catch (err) {
|
|
134
|
+
console.error(`Could not keep ${PLAN_FILE} out of git, so kos stopped before writing it.`);
|
|
135
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
136
|
+
console.error(`The empty worktree is at ${worktreePath}.`);
|
|
137
|
+
process.exit(1);
|
|
101
138
|
}
|
|
139
|
+
writeFileSync(join(worktreePath, PLAN_FILE), planText);
|
|
102
140
|
// 5. Hand off to the user's assistant, running inside the worktree
|
|
103
141
|
console.log(`Launching: ${cfg.agent}\n`);
|
|
104
142
|
try {
|
package/dist/cli/mcp-server.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// MCP server that runs locally via stdio and proxies to the hosted API.
|
|
2
2
|
// Used by Claude Code: claude mcp add xkg -- npx mnemos-capture serve-mcp --key <api-key>
|
|
3
|
-
const DEFAULT_HOSTED_URL = "https://
|
|
3
|
+
const DEFAULT_HOSTED_URL = "https://xkg.xmu.sh/api/mcp";
|
|
4
4
|
/** Override for pointing the proxy at a local instance during development. */
|
|
5
5
|
const HOSTED_URL = process.env.XKG_API_URL ?? process.env.XMU_API_URL ?? process.env.MNEMOS_API_URL ?? DEFAULT_HOSTED_URL;
|
|
6
6
|
function sendMessage(msg) {
|
|
@@ -74,7 +74,7 @@ export async function serveMcp() {
|
|
|
74
74
|
if (!apiKey) {
|
|
75
75
|
process.stderr.write("\nxkg MCP server requires an API key.\n");
|
|
76
76
|
process.stderr.write("Usage: npx -y mnemos-capture@latest serve-mcp --key <your-api-key>\n\n");
|
|
77
|
-
process.stderr.write("Get your API key at: https://
|
|
77
|
+
process.stderr.write("Get your API key at: https://xkg.xmu.sh/onboard\n\n");
|
|
78
78
|
process.exit(1);
|
|
79
79
|
}
|
|
80
80
|
// Self-upgrade: if a newer version exists on npm, respawn via npx @latest.
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
// Self-update enforcement: ensures users always run the latest
|
|
1
|
+
// Self-update enforcement: ensures users always run the latest xkg CLI.
|
|
2
2
|
//
|
|
3
3
|
// Strategy: on serve-mcp startup, query npm for the latest published version.
|
|
4
4
|
// If behind, respawn the process via `npx -y mnemos-capture@latest` and proxy
|
|
5
|
-
// stdio.
|
|
5
|
+
// stdio. An XKG_UPGRADED=1 env var (MNEMOS_UPGRADED=1 from releases before
|
|
6
|
+
// 1.4.1) prevents infinite recursion.
|
|
6
7
|
import { readFileSync } from "fs";
|
|
7
8
|
import { fileURLToPath } from "url";
|
|
8
9
|
import { dirname, join } from "path";
|
|
@@ -52,8 +53,9 @@ async function getLatestVersion() {
|
|
|
52
53
|
* continue with normal startup.
|
|
53
54
|
*/
|
|
54
55
|
export async function maybeSelfUpgrade() {
|
|
55
|
-
// Recursion guard: the child spawned below will inherit this env var.
|
|
56
|
-
|
|
56
|
+
// Recursion guard: the child spawned below will inherit this env var. Older
|
|
57
|
+
// releases set MNEMOS_UPGRADED, and may be the parent that spawned this one.
|
|
58
|
+
if (process.env.XKG_UPGRADED === "1" || process.env.MNEMOS_UPGRADED === "1")
|
|
57
59
|
return false;
|
|
58
60
|
const current = getCurrentVersion();
|
|
59
61
|
const latest = await getLatestVersion();
|
|
@@ -62,7 +64,7 @@ export async function maybeSelfUpgrade() {
|
|
|
62
64
|
process.stderr.write(`xkg: upgrading to v${latest} (was v${current})...\n`);
|
|
63
65
|
const child = spawn("npx", ["-y", `mnemos-capture@${latest}`, ...process.argv.slice(2)], {
|
|
64
66
|
stdio: "inherit",
|
|
65
|
-
env: { ...process.env,
|
|
67
|
+
env: { ...process.env, XKG_UPGRADED: "1" },
|
|
66
68
|
});
|
|
67
69
|
// Keep parent alive until the child exits, then exit with its code.
|
|
68
70
|
await new Promise((resolve) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mnemos-capture",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "xkg — Turn what you discover into context your AI workers can use. Capture once, then brief, plan, and execute with any MCP-compatible tool.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -38,16 +38,16 @@
|
|
|
38
38
|
"license": "MIT",
|
|
39
39
|
"repository": {
|
|
40
40
|
"type": "git",
|
|
41
|
-
"url": "https://github.com/
|
|
41
|
+
"url": "https://github.com/xmu-labs/xkg.git"
|
|
42
42
|
},
|
|
43
|
-
"homepage": "https://github.com/
|
|
43
|
+
"homepage": "https://github.com/xmu-labs/xkg",
|
|
44
44
|
"files": [
|
|
45
45
|
"dist/cli/",
|
|
46
46
|
"LICENSE",
|
|
47
47
|
"README.md"
|
|
48
48
|
],
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@anthropic-ai/sdk": "^0.
|
|
50
|
+
"@anthropic-ai/sdk": "^0.133.0",
|
|
51
51
|
"@vercel/postgres": "^0.10.0",
|
|
52
52
|
"next": "^16.3.5",
|
|
53
53
|
"react": "^19.3.0",
|