mcp-scraper 0.28.2 → 0.29.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 +1 -1
- package/dist/bin/api-server.cjs +96 -22
- package/dist/bin/api-server.cjs.map +1 -1
- package/dist/bin/api-server.js +1 -1
- package/dist/bin/mcp-scraper-cli.cjs +1 -1
- package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
- package/dist/bin/mcp-scraper-cli.js +1 -1
- package/dist/bin/mcp-scraper-install.cjs +1 -1
- package/dist/bin/mcp-scraper-install.cjs.map +1 -1
- package/dist/bin/mcp-scraper-install.js +1 -1
- package/dist/bin/mcp-stdio-server.cjs +25 -15
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +2 -2
- package/dist/{chunk-Q7VZUYRR.js → chunk-66SYKL2G.js} +26 -16
- package/dist/chunk-66SYKL2G.js.map +1 -0
- package/dist/chunk-7TNTBRQW.js +7 -0
- package/dist/chunk-7TNTBRQW.js.map +1 -0
- package/dist/{server-TB3USFGN.js → server-N4QMTJPS.js} +74 -10
- package/dist/{server-TB3USFGN.js.map → server-N4QMTJPS.js.map} +1 -1
- package/docs/mcp-tool-manifest.generated.json +13 -13
- package/package.json +2 -2
- package/dist/chunk-GOAQIV6K.js +0 -7
- package/dist/chunk-GOAQIV6K.js.map +0 -1
- package/dist/chunk-Q7VZUYRR.js.map +0 -1
package/README.md
CHANGED
|
@@ -88,7 +88,7 @@ Build the branded one-click bundle:
|
|
|
88
88
|
npm run build:mcpb
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.
|
|
91
|
+
The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.29.0`, SHA-256 `382bed0ad851500a9aada6b9d4b30d5c9a2da4c33faffa1b6415a18f14d6c7c0`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, and API-key configuration field from the bundle manifest.
|
|
92
92
|
|
|
93
93
|
The MCPB install exposes every tool — web-intelligence plus all `browser_*` tools — through the one `mcp-scraper` server.
|
|
94
94
|
|
package/dist/bin/api-server.cjs
CHANGED
|
@@ -29723,7 +29723,7 @@ var PACKAGE_VERSION;
|
|
|
29723
29723
|
var init_version = __esm({
|
|
29724
29724
|
"src/version.ts"() {
|
|
29725
29725
|
"use strict";
|
|
29726
|
-
PACKAGE_VERSION = "0.
|
|
29726
|
+
PACKAGE_VERSION = "0.29.0";
|
|
29727
29727
|
}
|
|
29728
29728
|
});
|
|
29729
29729
|
|
|
@@ -29845,12 +29845,14 @@ Multi-step orchestrations \u2014 prefer these over hand-chaining primitives when
|
|
|
29845
29845
|
|
|
29846
29846
|
## Memory
|
|
29847
29847
|
mcp-scraper also exposes persistent per-user memory tools (notes, facts, vaults,
|
|
29848
|
-
scheduled actions, tables, channels) backed by memory.mcpscraper.dev. Every account starts with
|
|
29848
|
+
scheduled actions, tables, channels) backed by memory.mcpscraper.dev. Every account starts with 15
|
|
29849
29849
|
vaults \u2014 call **list-vaults** to see what exists before creating anything new. Pick the vault whose job
|
|
29850
29850
|
matches the content: **Ideas** (unvalidated concepts), **Knowledge** (distilled lessons/how-tos),
|
|
29851
29851
|
**Library** (raw source material \u2014 articles, transcripts), **People** (one durable note per person/org),
|
|
29852
|
-
**
|
|
29853
|
-
|
|
29852
|
+
**Deals** (commercial opportunities tied to a known person or organization), **Communications** (individual
|
|
29853
|
+
conversation records and drafts), **Calendar** (time-anchored entries), **Tasks** (action items linked to a
|
|
29854
|
+
known Project), **Projects** (only codebases, known client projects, personal projects, or ongoing siloed
|
|
29855
|
+
workstreams), **Issues** (something broken),
|
|
29854
29856
|
**Improvement Log** (receipts of changes made and whether they worked), **Experiments** (hypothesis +
|
|
29855
29857
|
measured result), **Sprint** (current cycle's scope), **Inspiration** (other people's work worth
|
|
29856
29858
|
studying), **Skills** (reusable skill packages; each requires \`scripts/\` and at least one of
|
|
@@ -29864,6 +29866,14 @@ deliberate edits and migrations. Use
|
|
|
29864
29866
|
they'll filter/sort by exact value. **memory-search** is meaning-based over full content (embeds, slower);
|
|
29865
29867
|
**memory-list** filters one vault by kind/tags (fast, exact).
|
|
29866
29868
|
|
|
29869
|
+
For People, Deals, Projects, Tasks, and Communications, use the returned contract rather than guessing:
|
|
29870
|
+
People only holds a real person or organization hub; Deals need a known party; Projects need
|
|
29871
|
+
\`project_kind\`; every Task needs a verified \`project_ref\` and matching project name; and email drafts
|
|
29872
|
+
awaiting human review need \`direction:"draft"\` with \`approval_state:"pending"\`. Link a known person,
|
|
29873
|
+
project, deal, or communication when verified. If a required relationship is not clear, ask the user rather
|
|
29874
|
+
than creating a free-floating record. Overview is the review queue: editing leaves a draft pending, and
|
|
29875
|
+
approval or denial records a state only\u2014it does not send email.
|
|
29876
|
+
|
|
29867
29877
|
Treat every memory create or update as a graph operation. **prepare-memory-write** supplies the initial
|
|
29868
29878
|
shortlist; use **memory-search** when it is weak or the topic is broad, and **memory-get** to read the best
|
|
29869
29879
|
candidates in full. Add only links supported by the notes: same-
|
|
@@ -34939,7 +34949,7 @@ var init_memory_tool_schemas = __esm({
|
|
|
34939
34949
|
MemoryCaptureSchema = {
|
|
34940
34950
|
id: "memory-capture",
|
|
34941
34951
|
upstreamName: "memoryCaptureTool",
|
|
34942
|
-
description: "Strict normal-create path for durable memory. Before capture, list the complete tag vocabulary, call prepare-memory-write, run hybrid memory-search for related notes, and read the strongest link candidates. This tool refuses incomplete notes, writes through memory-put, registers canonical tags, and verifies persisted content and props. Reserve memory-put for low-level migrations or deliberate edits.",
|
|
34952
|
+
description: "Strict normal-create path for durable memory. Before capture, list the complete tag vocabulary, call prepare-memory-write, run hybrid memory-search for related notes, and read the strongest link candidates. This tool refuses incomplete notes and invalid relationship-domain writes: projects need a project kind, tasks need a verified project, deals need a known party, and draft emails need a pending approval state. It writes through memory-put, registers canonical tags, and verifies persisted content and props. Reserve memory-put for low-level migrations or deliberate edits.",
|
|
34943
34953
|
input: {
|
|
34944
34954
|
vault: import_zod37.z.string(),
|
|
34945
34955
|
folder: import_zod37.z.string().optional(),
|
|
@@ -34997,7 +35007,7 @@ var init_memory_tool_schemas = __esm({
|
|
|
34997
35007
|
PrepareMemoryWriteSchema = {
|
|
34998
35008
|
id: "prepare-memory-write",
|
|
34999
35009
|
upstreamName: "prepareMemoryWriteTool",
|
|
35000
|
-
description: "Mandatory planning pass for a normal new memory. First inspect the complete tag vocabulary with list-memory-tags; then this pass routes the note, returns the live template and natural vault relationships, resolves proposed tags, and shortlists interlinks. Use hybrid memory-search (3 focused queries, 50 fused candidates, bounded graph expansion, rerank to 30 by default) and read strong related notes before capture. This is an explicit AI workflow directive, not a claim of persisted call-order enforcement.",
|
|
35010
|
+
description: "Mandatory planning pass for a normal new memory. First inspect the complete tag vocabulary with list-memory-tags; then this pass routes the note, returns the live template and natural vault relationships, resolves proposed tags, and shortlists interlinks. For People, Deals, Projects, Tasks, and Communications, it also returns required relationship and approval guidance: search existing records first and ask rather than inventing a missing project or party. Use hybrid memory-search (3 focused queries, 50 fused candidates, bounded graph expansion, rerank to 30 by default) and read strong related notes before capture. This is an explicit AI workflow directive, not a claim of persisted call-order enforcement.",
|
|
35001
35011
|
input: {
|
|
35002
35012
|
title: import_zod37.z.string().min(1),
|
|
35003
35013
|
content: import_zod37.z.string().min(1),
|
|
@@ -35704,10 +35714,10 @@ var init_memory_tool_schemas = __esm({
|
|
|
35704
35714
|
PutSchema = {
|
|
35705
35715
|
id: "memory-put",
|
|
35706
35716
|
upstreamName: "putTool",
|
|
35707
|
-
description: "Create or edit one note at a path in a memory vault; content is persisted and indexed for search. For row-shaped datasets you'll filter/sort by exact value, use table-create/table-insert-rows/table-query instead. Ordinary vaults are indexed and shareable \u2014 never store real secrets there; use a secure vault (create-secure-vault) instead, which is never indexed or shareable and is encrypted at rest. Requires write scope.",
|
|
35717
|
+
description: "Create or deliberately edit one note at a path in a memory vault; content is persisted and indexed for search. For normal new People, Deals, Projects, Tasks, or Communications records, use prepare-memory-write then memory-capture: People must be real people or organizations, Deals need a known party, Projects need a supported kind, Tasks need a verified Project, and draft emails need pending approval. For row-shaped datasets you'll filter/sort by exact value, use table-create/table-insert-rows/table-query instead. Ordinary vaults are indexed and shareable \u2014 never store real secrets there; use a secure vault (create-secure-vault) instead, which is never indexed or shareable and is encrypted at rest. Requires write scope.",
|
|
35708
35718
|
input: {
|
|
35709
35719
|
vault: import_zod37.z.string().optional().describe(
|
|
35710
|
-
"Vault to write to. Optional; defaults to the session active vault, then the first vault the caller is entitled to. On a default-provisioned account, pick the vault whose job matches the content (see the server instructions for the full
|
|
35720
|
+
"Vault to write to. Optional; defaults to the session active vault, then the first vault the caller is entitled to. On a default-provisioned account, pick the vault whose job matches the content (see the server instructions for the full 15-vault guide) rather than defaulting blindly \u2014 e.g. a lesson learned goes in Knowledge, the raw source it came from goes in Library, a broken feature goes in Issues, a named real-world initiative goes in Projects. Do not use this low-level tool to create ordinary People, Deals, Projects, Tasks, or Communications records: first use prepare-memory-write then memory-capture so relationships and approval state are validated."
|
|
35711
35721
|
),
|
|
35712
35722
|
path: import_zod37.z.string().optional().describe("Vault-relative note path to create or overwrite, e.g. projects/q3-plan. Writing an existing path replaces it. Required unless shareId is given."),
|
|
35713
35723
|
shareId: import_zod37.z.string().optional().describe("Edit a note someone individually shared with you and you accepted (accept-share), by its shareId, instead of vault+path. Requires the share to grant edit permission, and baseRevision is mandatory (get the current revision first) since you are editing alongside the owner and possibly others."),
|
|
@@ -36494,9 +36504,9 @@ var init_memory_tool_schemas = __esm({
|
|
|
36494
36504
|
GetVaultContractSchema = {
|
|
36495
36505
|
id: "get-vault-contract",
|
|
36496
36506
|
upstreamName: "getVaultContractTool",
|
|
36497
|
-
description: "Read the machine-enforced purpose, template, statuses, types, natural neighbor vaults, and typed relationship guidance for one of the
|
|
36507
|
+
description: "Read the machine-enforced purpose, template, statuses, types, natural neighbor vaults, and typed relationship guidance for one of the 15 governed Obsidian-style vaults. Call before composing a note when the correct shape is uncertain.",
|
|
36498
36508
|
input: {
|
|
36499
|
-
vault: import_zod37.z.string().describe("One governed vault: Ideas, Inspiration, Knowledge, Library, People, Communications, Calendar, Tasks, Projects, Issues, Improvement Log, Experiments, or
|
|
36509
|
+
vault: import_zod37.z.string().describe("One governed vault: Ideas, Inspiration, Knowledge, Library, People, Deals, Communications, Calendar, Tasks, Projects, Issues, Improvement Log, Experiments, Sprint, or Skills.")
|
|
36500
36510
|
},
|
|
36501
36511
|
output: {
|
|
36502
36512
|
ok: import_zod37.z.boolean(),
|
|
@@ -36566,17 +36576,17 @@ var init_memory_tool_schemas = __esm({
|
|
|
36566
36576
|
ProvisionDefaultsSchema = {
|
|
36567
36577
|
id: "provision-defaults",
|
|
36568
36578
|
upstreamName: "provisionDefaultsTool",
|
|
36569
|
-
description: "Provision the standard
|
|
36579
|
+
description: "Provision the standard 15-vault memory structure (Ideas, Inspiration, Knowledge, Library, People, Deals, Communications, Calendar, Tasks, Projects, Issues, Improvement Log, Experiments, Sprint, Skills) for an identity. Idempotent \u2014 existing records are untouched and existing vault contracts are refreshed. Optionally issues a fresh API key entitled to all 15. Requires admin scope.",
|
|
36570
36580
|
input: {
|
|
36571
|
-
granteeIdentity: import_zod37.z.string().min(1).describe("Identity that should OWN the
|
|
36572
|
-
issueKey: import_zod37.z.boolean().optional().describe("When true, also issue a new API key for the identity entitled to all
|
|
36581
|
+
granteeIdentity: import_zod37.z.string().min(1).describe("Identity that should OWN the 15 default vaults (e.g. an email or user id)."),
|
|
36582
|
+
issueKey: import_zod37.z.boolean().optional().describe("When true, also issue a new API key for the identity entitled to all 15 vaults and return its secret once. Default false."),
|
|
36573
36583
|
plan: import_zod37.z.enum(["free", "pro", "team", "enterprise"]).optional().describe("Subscription plan carried by the issued key. Optional; defaults to free. Only used when issueKey is true.")
|
|
36574
36584
|
},
|
|
36575
36585
|
output: {
|
|
36576
36586
|
ok: import_zod37.z.boolean().describe("True when provisioning succeeded; false on auth/scope error."),
|
|
36577
36587
|
identity: import_zod37.z.string().optional().describe("Identity the vaults were provisioned for."),
|
|
36578
|
-
created: import_zod37.z.array(import_zod37.z.string()).optional().describe("Vault names newly created on this call (empty when all
|
|
36579
|
-
vaults: import_zod37.z.array(import_zod37.z.string()).optional().describe("All
|
|
36588
|
+
created: import_zod37.z.array(import_zod37.z.string()).optional().describe("Vault names newly created on this call (empty when all 15 already existed)."),
|
|
36589
|
+
vaults: import_zod37.z.array(import_zod37.z.string()).optional().describe("All 15 default vault names the identity now owns."),
|
|
36580
36590
|
keyId: import_zod37.z.string().optional().describe("Stable id of the issued key. Present only when issueKey was true."),
|
|
36581
36591
|
secret: import_zod37.z.string().optional().describe("The issued key secret \u2014 RETURNED ONCE. Present only when issueKey was true."),
|
|
36582
36592
|
plan: import_zod37.z.string().optional().describe("Plan assigned to the issued key. Present only when issueKey was true."),
|
|
@@ -41197,7 +41207,7 @@ function cors(c) {
|
|
|
41197
41207
|
const local = !!origin && /^http:\/\/localhost(?::\d+)?$/.test(origin);
|
|
41198
41208
|
if (origin && (configured.includes(origin) || local)) c.header("Access-Control-Allow-Origin", origin);
|
|
41199
41209
|
c.header("Vary", "Origin");
|
|
41200
|
-
c.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
41210
|
+
c.header("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
|
|
41201
41211
|
c.header("Access-Control-Allow-Headers", "content-type");
|
|
41202
41212
|
}
|
|
41203
41213
|
function workspaceRecord(vault, note) {
|
|
@@ -41218,16 +41228,53 @@ function workspaceRecord(vault, note) {
|
|
|
41218
41228
|
}
|
|
41219
41229
|
function defaultType(vault) {
|
|
41220
41230
|
if (vault === "People" || vault === "Communications") return "unclassified";
|
|
41231
|
+
if (vault === "Deals") return "deal";
|
|
41221
41232
|
if (vault === "Projects") return "project";
|
|
41222
41233
|
if (vault === "Tasks") return "task";
|
|
41223
41234
|
return "unclassified";
|
|
41224
41235
|
}
|
|
41225
41236
|
function defaultStatus(vault) {
|
|
41226
41237
|
if (vault === "People") return "active";
|
|
41238
|
+
if (vault === "Deals") return "lead";
|
|
41227
41239
|
if (vault === "Projects") return "active";
|
|
41228
41240
|
if (vault === "Tasks") return "to_do";
|
|
41229
41241
|
return "inbox";
|
|
41230
41242
|
}
|
|
41243
|
+
function nonEmptyStrings(value) {
|
|
41244
|
+
return Array.isArray(value) ? value.filter((entry) => typeof entry === "string" && entry.trim().length > 0) : [];
|
|
41245
|
+
}
|
|
41246
|
+
function validateNewRecord(vault, props) {
|
|
41247
|
+
const type = typeof props.type === "string" ? props.type : "";
|
|
41248
|
+
if (vault === "People" && !["person", "organization"].includes(type)) return "People records must be a person or organization";
|
|
41249
|
+
if (vault === "Deals") {
|
|
41250
|
+
if (type !== "deal") return "Deals records must have type deal";
|
|
41251
|
+
if (typeof props.organization_ref !== "string" && nonEmptyStrings(props.person_refs).length === 0) {
|
|
41252
|
+
return "Deals require a known organization or person";
|
|
41253
|
+
}
|
|
41254
|
+
}
|
|
41255
|
+
if (vault === "Projects") {
|
|
41256
|
+
if (!["project", "vault_settings"].includes(type)) return "Projects records must have type project";
|
|
41257
|
+
if (type === "project" && !["codebase", "client", "personal", "workstream"].includes(String(props.project_kind ?? ""))) {
|
|
41258
|
+
return "Projects require project_kind: codebase, client, personal, or workstream";
|
|
41259
|
+
}
|
|
41260
|
+
}
|
|
41261
|
+
if (vault === "Tasks") {
|
|
41262
|
+
if (!["task", "milestone"].includes(type)) return "Tasks records must have type task or milestone";
|
|
41263
|
+
if (typeof props.project_ref !== "string" || !props.project_ref.trim() || typeof props.project !== "string" || !props.project.trim()) {
|
|
41264
|
+
return "Tasks must be linked to an existing project";
|
|
41265
|
+
}
|
|
41266
|
+
}
|
|
41267
|
+
if (vault === "Communications") {
|
|
41268
|
+
if (!["email", "slack", "message", "call", "meeting", "social_media", "thread", "decision"].includes(type)) return "Communications records need a valid communication type";
|
|
41269
|
+
if (!["none", "needs_reply", "needs_review", "waiting"].includes(String(props.attention_state ?? ""))) {
|
|
41270
|
+
return "Communications require attention_state: none, needs_reply, needs_review, or waiting";
|
|
41271
|
+
}
|
|
41272
|
+
if (type === "email" && props.direction === "draft" && props.approval_state !== "pending") {
|
|
41273
|
+
return "Email drafts awaiting review must have approval_state pending";
|
|
41274
|
+
}
|
|
41275
|
+
}
|
|
41276
|
+
return null;
|
|
41277
|
+
}
|
|
41231
41278
|
function shouldRetryMemoryRead(error) {
|
|
41232
41279
|
return /deadlock|timeout|timed out|temporar|econnreset|fetch failed/i.test(error ?? "");
|
|
41233
41280
|
}
|
|
@@ -41274,7 +41321,7 @@ var init_vault_routes = __esm({
|
|
|
41274
41321
|
"use strict";
|
|
41275
41322
|
import_hono22 = require("hono");
|
|
41276
41323
|
init_memory();
|
|
41277
|
-
VAULTS = ["People", "Projects", "Tasks", "Communications"];
|
|
41324
|
+
VAULTS = ["People", "Deals", "Projects", "Tasks", "Communications"];
|
|
41278
41325
|
MAX_VAULT_RECORDS = 200;
|
|
41279
41326
|
MAX_MEMORY_READ_CONCURRENCY = 4;
|
|
41280
41327
|
MAX_MEMORY_READ_ATTEMPTS = 3;
|
|
@@ -41308,6 +41355,8 @@ var init_vault_routes = __esm({
|
|
|
41308
41355
|
const content = typeof body.content === "string" && body.content.length <= 1e5 ? body.content : "";
|
|
41309
41356
|
const props = propsValue(body.props) ?? {};
|
|
41310
41357
|
if (!isVault(vault) || !path6 || !title) return c.json({ ok: false, error: "vault, path, and title are required" }, 400);
|
|
41358
|
+
const validationError = validateNewRecord(vault, props);
|
|
41359
|
+
if (validationError) return c.json({ ok: false, error: validationError }, 400);
|
|
41311
41360
|
const baseRevision = typeof body.baseRevision === "number" && Number.isInteger(body.baseRevision) ? body.baseRevision : void 0;
|
|
41312
41361
|
const result = await memoryCall("putTool", { vault, path: path6, title, content: content || title, props, ...baseRevision === void 0 ? {} : { baseRevision } }, token);
|
|
41313
41362
|
return c.json(result, result.ok ? 200 : result.conflict ? 409 : 502);
|
|
@@ -41358,6 +41407,26 @@ var init_vault_routes = __esm({
|
|
|
41358
41407
|
}, token);
|
|
41359
41408
|
return c.json(result, result.ok ? 200 : result.conflict ? 409 : 502);
|
|
41360
41409
|
});
|
|
41410
|
+
vaultApp.delete("/api/records", async (c) => {
|
|
41411
|
+
const body = await c.req.json().catch(() => ({}));
|
|
41412
|
+
const token = typeof body.token === "string" ? body.token : void 0;
|
|
41413
|
+
if (!validToken(token)) return c.json({ ok: false, error: "missing or malformed Vault App link" }, 401);
|
|
41414
|
+
const vault = body.vault;
|
|
41415
|
+
const path6 = stringValue(body.path, 320);
|
|
41416
|
+
const baseRevision = typeof body.baseRevision === "number" && Number.isInteger(body.baseRevision) ? body.baseRevision : void 0;
|
|
41417
|
+
if (vault !== "Tasks" || !path6) return c.json({ ok: false, error: "only a valid task record can be deleted" }, 400);
|
|
41418
|
+
const current = await readMemory("getTool", { vault, path: path6 }, token);
|
|
41419
|
+
if (!current.ok || !current.note) return c.json(current, current.ok ? 404 : 502);
|
|
41420
|
+
if (!["task", "milestone"].includes(typeof current.note.props?.type === "string" ? current.note.props.type : defaultType("Tasks"))) {
|
|
41421
|
+
return c.json({ ok: false, error: "only task records can be deleted" }, 400);
|
|
41422
|
+
}
|
|
41423
|
+
const result = await memoryCall("deleteNoteTool", {
|
|
41424
|
+
vault,
|
|
41425
|
+
path: path6,
|
|
41426
|
+
baseRevision: baseRevision ?? current.note.revision
|
|
41427
|
+
}, token);
|
|
41428
|
+
return c.json(result, result.ok ? 200 : result.conflict ? 409 : 502);
|
|
41429
|
+
});
|
|
41361
41430
|
vaultApp.post("/api/communications/review", async (c) => {
|
|
41362
41431
|
const body = await c.req.json().catch(() => ({}));
|
|
41363
41432
|
const token = typeof body.token === "string" ? body.token : void 0;
|
|
@@ -41368,20 +41437,25 @@ var init_vault_routes = __esm({
|
|
|
41368
41437
|
const content = typeof body.content === "string" && body.content.length <= 1e5 ? body.content : void 0;
|
|
41369
41438
|
const feedback = typeof body.feedback === "string" ? body.feedback.trim().slice(0, 1e4) : void 0;
|
|
41370
41439
|
const baseRevision = typeof body.baseRevision === "number" && Number.isInteger(body.baseRevision) ? body.baseRevision : void 0;
|
|
41371
|
-
|
|
41440
|
+
const normalizedAction = action === "accept" ? "approve" : action;
|
|
41441
|
+
if (!path6 || !normalizedAction || !["approve", "deny", "edit"].includes(normalizedAction) || body.title !== void 0 && !title) {
|
|
41372
41442
|
return c.json({ ok: false, error: "valid path, action, and optional draft fields are required" }, 400);
|
|
41373
41443
|
}
|
|
41374
41444
|
const current = await readMemory("getTool", { vault: "Communications", path: path6 }, token);
|
|
41375
41445
|
if (!current.ok || !current.note) return c.json(current, current.ok ? 404 : 502);
|
|
41376
41446
|
if (current.note.props?.type !== "email") return c.json({ ok: false, error: "only email communications can be reviewed" }, 400);
|
|
41377
|
-
const reviewed =
|
|
41378
|
-
const reviewState =
|
|
41379
|
-
const
|
|
41447
|
+
const reviewed = normalizedAction === "approve" || normalizedAction === "deny";
|
|
41448
|
+
const reviewState = normalizedAction === "approve" ? "accepted" : normalizedAction === "deny" ? "denied" : "pending";
|
|
41449
|
+
const approvalState = normalizedAction === "approve" ? "approved" : normalizedAction === "deny" ? "denied" : "pending";
|
|
41450
|
+
const status = normalizedAction === "approve" ? "triaged" : normalizedAction === "deny" ? "archived" : "inbox";
|
|
41380
41451
|
const props = {
|
|
41381
41452
|
...current.note.props ?? {},
|
|
41382
41453
|
status,
|
|
41383
41454
|
review_state: reviewState,
|
|
41455
|
+
approval_state: approvalState,
|
|
41456
|
+
attention_state: normalizedAction === "edit" ? "needs_review" : "none",
|
|
41384
41457
|
...reviewed ? { reviewed_at: (/* @__PURE__ */ new Date()).toISOString() } : {},
|
|
41458
|
+
...normalizedAction === "approve" ? { approved_at: (/* @__PURE__ */ new Date()).toISOString() } : {},
|
|
41385
41459
|
...feedback ? { review_feedback: feedback } : {}
|
|
41386
41460
|
};
|
|
41387
41461
|
const result = await memoryCall("putTool", {
|
|
@@ -41408,7 +41482,7 @@ var init_vault_routes = __esm({
|
|
|
41408
41482
|
path: `Inbox/activity-${stamp}`,
|
|
41409
41483
|
title,
|
|
41410
41484
|
content: content || title,
|
|
41411
|
-
props: { status: "triaged", type: "decision", occurred_at: (/* @__PURE__ */ new Date()).toISOString(), ...props }
|
|
41485
|
+
props: { status: "triaged", type: "decision", attention_state: "none", occurred_at: (/* @__PURE__ */ new Date()).toISOString(), ...props }
|
|
41412
41486
|
}, token);
|
|
41413
41487
|
return c.json(result, result.ok ? 200 : 502);
|
|
41414
41488
|
});
|