@rubytech/create-maxy-code 0.1.144 → 0.1.147
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/package.json +1 -1
- package/payload/platform/neo4j/schema.cypher +154 -4
- package/payload/platform/plugins/admin/PLUGIN.md +1 -1
- package/payload/platform/plugins/admin/hooks/post-turn-graph-pass.sh +251 -0
- package/payload/platform/plugins/admin/skills/datetime/SKILL.md +63 -5
- package/payload/platform/plugins/docs/references/internals.md +16 -0
- package/payload/platform/plugins/docs/references/memory-guide.md +10 -0
- package/payload/platform/plugins/docs/references/platform.md +1 -1
- package/payload/platform/plugins/memory/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/memory/PLUGIN.md +25 -3
- package/payload/platform/plugins/memory/mcp/dist/index.js +309 -11
- package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.js +33 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-gate-label.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-gate-label.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-gate-label.test.js +30 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-gate-label.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/phase-prune-revisions.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/phase-prune-revisions.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/phase-prune-revisions.test.js +51 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/phase-prune-revisions.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/relative-date.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/relative-date.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/relative-date.test.js +68 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/relative-date.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/timeline-extractor.test.js +41 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/timeline-extractor.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-revision.d.ts +43 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-revision.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-revision.js +33 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-revision.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-rewriter.d.ts +18 -5
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-rewriter.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-rewriter.js +64 -17
- package/payload/platform/plugins/memory/mcp/dist/lib/compiled-truth-rewriter.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/index.d.ts +44 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/index.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/index.js +14 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/index.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-citation-audit.d.ts +26 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-citation-audit.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-citation-audit.js +219 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-citation-audit.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-dead-edges.d.ts +19 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-dead-edges.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-dead-edges.js +39 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-dead-edges.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-orphans.d.ts +19 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-orphans.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-orphans.js +42 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-orphans.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-prune-revisions.d.ts +21 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-prune-revisions.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-prune-revisions.js +27 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-prune-revisions.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-stale-truth.d.ts +18 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-stale-truth.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-stale-truth.js +60 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/dream-cycle/phase-stale-truth.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/graph-write-gate.d.ts +20 -3
- package/payload/platform/plugins/memory/mcp/dist/lib/graph-write-gate.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/graph-write-gate.js +47 -12
- package/payload/platform/plugins/memory/mcp/dist/lib/graph-write-gate.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/relative-date.d.ts +13 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/relative-date.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/relative-date.js +191 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/relative-date.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/timeline-extractor.d.ts +7 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/timeline-extractor.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/timeline-extractor.js +37 -9
- package/payload/platform/plugins/memory/mcp/dist/lib/timeline-extractor.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-compiled-truth-history.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-compiled-truth-history.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-compiled-truth-history.test.js +81 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-compiled-truth-history.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-report-tools.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-report-tools.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-report-tools.test.js +115 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-report-tools.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-emit.test.js +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-emit.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-write-emit.test.js +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-write-emit.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.d.ts +19 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.js +50 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-compiled-truth-history.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-dream-run.d.ts +45 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-dream-run.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-dream-run.js +170 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-dream-run.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-list.d.ts +28 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-list.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-list.js +64 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-list.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-read-latest.d.ts +24 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-read-latest.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-read-latest.js +49 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-read-latest.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-write.d.ts +34 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-write.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-write.js +99 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-report-write.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-review-queue.d.ts +29 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-review-queue.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-review-queue.js +66 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-review-queue.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js +122 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.d.ts +49 -13
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js +184 -16
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js +53 -10
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/vitest.config.ts +6 -0
- package/payload/platform/plugins/memory/references/schema-base.md +4 -0
- package/payload/platform/plugins/memory/skills/conversation-archive/SKILL.md +3 -4
- package/payload/platform/plugins/scheduling/skills/briefing/SKILL.md +13 -2
- package/payload/platform/scripts/seed-neo4j.sh +1 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +9 -1
- package/payload/platform/templates/specialists/agents/database-operator.md +30 -2
- package/payload/server/server.js +195 -91
- package/payload/platform/plugins/admin/hooks/signal-detector-stop.sh +0 -309
- package/payload/platform/templates/specialists/agents/signal-detector.md +0 -129
|
@@ -36,6 +36,14 @@ When the conversation produces something worth writing to memory (a new person,
|
|
|
36
36
|
|
|
37
37
|
Call `memory-write` or `memory-update` directly only when the write is a one-line update against a node whose `elementId` is already in your context (e.g. setting a single property on an existing Person you just found by id) AND the schema choice is unambiguous. Delegate in every other case: new nodes, batched writes, multi-row archive ingest, schema-classification work, anything whose label or edge type requires consulting `schema-base.md` or a vertical schema.
|
|
38
38
|
|
|
39
|
+
## Recalling reports
|
|
40
|
+
|
|
41
|
+
Workflow output that the operator may want back later (daily briefing, dream cycle, ad-hoc analyses) lives as `:Report` nodes — keyword-routed, append-only, embedded for hybrid search. When the operator says "latest <X>", "last night's <X>", "show me <X> report", "what was this morning's briefing", or any other phrasing that names a known report kind, the first tool call is `memory-report-read-latest` with the matching keyword (`daily-briefing`, `dream-cycle`, etc.). Use `memory-report-list` to browse the catalogue (metadata only) when the operator wants a date range or to compare multiple. Reach for `memory-search` instead only when the question is about the contents of a report (e.g. "which briefing mentioned the Cohen offer"), not about the report itself.
|
|
42
|
+
|
|
43
|
+
## Compiled-truth revision history
|
|
44
|
+
|
|
45
|
+
Every `compiledTruth` on a :Person, :Organization, or :Concept is captured as a `:CompiledTruthRevision` row each time the rewriter writes it. When the operator asks "how has my understanding of X changed over time?", "when did you start saying X about Y?", or "show me the history of what we know about Z", first resolve the entity's `elementId` (via `memory-search`), then call `memory-compiled-truth-history` with that id. Render the rows as a chronological list and surface the delta between adjacent revisions in your own reply — there is no server-side diff.
|
|
46
|
+
|
|
39
47
|
## Session-end retrospective
|
|
40
48
|
|
|
41
49
|
When the operator signals end-of-session (`/end`, `/archive`, `end session`, or `archive this session`), the Stop hook blocks this session from closing until you have done three things and called one tool. The hook's instruction block names the three passes verbatim every time it fires; this section is the doctrine behind it.
|
|
@@ -63,7 +71,7 @@ When you receive a turn beginning with `[system: <name>-stop-hook]`:
|
|
|
63
71
|
2. Execute that single `Task` dispatch. Do not paraphrase the prompt, do not respond conversationally, do not ask the operator for clarification, do not surface the dispatch in chat.
|
|
64
72
|
3. When the subagent returns its one-line summary, emit a single space character and stop. The Stop hook's next fire will inspect the transcript, see the dispatch you just performed, and allow the stop.
|
|
65
73
|
|
|
66
|
-
These directives are never operator-driven. The `
|
|
74
|
+
These directives are never operator-driven. The `database-operator` specialist in particular, when dispatched via `post-turn-graph-pass.sh` (Task 412), runs as a background graph pass that the operator does not see; the dispatch prompt carries the conversation and prior-writes blocks and you must forward both verbatim.
|
|
67
75
|
|
|
68
76
|
## SOUL.md
|
|
69
77
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: database-operator
|
|
3
|
-
description: "Graph-write executor reachable from admin via the Task tool. Admin names what should land in the graph; database-operator reads the schema, decides operations, executes them against the memory graph, and reports `{label, elementId}` back. (
|
|
4
|
-
summary: "Executes graph writes on admin's behalf when delegated via the Task tool."
|
|
3
|
+
description: "Graph-write executor reachable from admin via the Task tool. Admin names what should land in the graph; database-operator reads the schema, decides operations, executes them against the memory graph, and reports `{label, elementId}` back. Two invocation modes: (1) **discretionary inline** — admin dispatches synchronously when a write must complete before the assistant response ends; (2) **background post-turn pass** — fired once per admin-agent end_turn by `platform/plugins/admin/hooks/post-turn-graph-pass.sh` with the full conversation and the list of nodes already written under this conversationId, so any new graph rows the conversation supports get derived and written without the admin agent having to remember every turn (Task 412)."
|
|
4
|
+
summary: "Executes graph writes on admin's behalf when delegated via the Task tool — both inline at admin discretion and as a once-per-turn background pass."
|
|
5
5
|
model: claude-sonnet-4-6
|
|
6
6
|
tools: Read, mcp__plugin_memory_memory__memory-write, mcp__plugin_memory_memory__memory-update, mcp__plugin_memory_memory__memory-search, mcp__plugin_memory_memory__memory-archive-write, mcp__plugin_memory_memory__memory-typed-edge-pass, mcp__plugin_memory_memory__session-retrospective-skip-rate, mcp__plugin_memory_memory__profile-update, mcp__plugin_memory_memory__profile-read, mcp__plugin_memory_memory__obsidian-vault-import, mcp__plugin_scheduling_scheduling__schedule-archive-ics, mcp__plugin_contacts_contacts__contact-create, mcp__plugin_contacts_contacts__contact-update, mcp__plugin_work_work__work-create, mcp__plugin_work_work__work-update, mcp__plugin_work_work__project-create, mcp__plugin_work_work__project-update
|
|
7
7
|
---
|
|
@@ -20,6 +20,34 @@ The `accountId` property is supplied by the writers from server-side environment
|
|
|
20
20
|
|
|
21
21
|
Decide the precise operations against the schema, execute them with the writers in your tool surface, and report each write back to admin as `{label, elementId}` so admin can confirm the outcome to the operator. If admin's brief is ambiguous about which label, which edge type, or which existing node to attach to, name the ambiguity in your reply rather than guessing.
|
|
22
22
|
|
|
23
|
+
## Background post-turn pass
|
|
24
|
+
|
|
25
|
+
When the dispatch prompt contains a `<conversation>` block and a `<prior-writes>` block, you are running as the post-turn background pass (Task 412). The hook (`platform/plugins/admin/hooks/post-turn-graph-pass.sh`) fires once per admin-agent `end_turn` and supplies:
|
|
26
|
+
|
|
27
|
+
- `accountId`, `sessionId`, `conversationId` — the scope.
|
|
28
|
+
- `<conversation>` — every assistant text turn and every non-`tool_result` user turn for this session, oldest first, formatted as `[role: text]` pairs.
|
|
29
|
+
- `<prior-writes>` — every node already written under this `conversationId` for this account, one per line as `(elementId) :Labels {properties-json}`, oldest first.
|
|
30
|
+
|
|
31
|
+
Your job: read the conversation, decide what new graph rows it supports (mentions of named entities, ideas and learnings the operator stated, contacts named for the first time, tasks the operator committed to, decisions, anything the schema admits), and write them. **Skip writes the `<prior-writes>` list already covers** — a `:MENTIONS` edge from a `:Message` to a `:Person` is already there, do not re-emit it; a `:Person {name: "Adam Langley"}` is already there, attach further edges to its `elementId` instead of creating a duplicate. The hygiene sweeps (Tasks 410, 411) clean up duplicates that slip through MERGE semantics; do not invent dedup logic here beyond the prior-writes skip.
|
|
32
|
+
|
|
33
|
+
The same prerogatives apply: precise label and edge names, evidence-based lookups (`memory-search` before creating any stub for a name that could already exist on another conversation), no synonyms, no invented edge types.
|
|
34
|
+
|
|
35
|
+
Return exactly one line on completion:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
db-op: writes=<n> ms=<n>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Where `<n>` is the count of `memory-write` / `memory-update` calls that succeeded. On error (a `memory-write` rejection, a missing tool), surface the reason and stop:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
db-op: error reason=<kebab-case-reason>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
No prose summary, no listing of names. The operator does not see this turn.
|
|
48
|
+
|
|
49
|
+
When the dispatch prompt has no `<conversation>` block, you are in discretionary inline mode — behaviour is unchanged from the rest of this document.
|
|
50
|
+
|
|
23
51
|
## Typed-edge auto-extraction pass (session-end)
|
|
24
52
|
|
|
25
53
|
When admin's brief names the typed-edge pass (Task 305) and supplies a `sinceIso` timestamp, call `memory-typed-edge-pass` with that timestamp exactly once. The tool reads prose-bearing nodes (Message/Page/Meeting/KnowledgeDocument/Idea/Note/Post/Report — `:KnowledgeDocument` covers email threads via `source:'email'` since Task 321) the account wrote since `sinceIso`, asks Haiku for typed-edge proposals against a closed allowlist, validates each one, and MERGEs accepted edges with `createdBy` provenance. Return the full counter object verbatim — admin needs `nodesProcessed` and `accepted` for the `session-retrospective-mark-complete` call. Do not reinterpret the counts or summarise them.
|
package/payload/server/server.js
CHANGED
|
@@ -9310,18 +9310,18 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
|
|
|
9310
9310
|
]);
|
|
9311
9311
|
var app17 = new Hono();
|
|
9312
9312
|
app17.post("/", async (c) => {
|
|
9313
|
-
const
|
|
9313
|
+
const TAG23 = "[admin:events]";
|
|
9314
9314
|
let body;
|
|
9315
9315
|
try {
|
|
9316
9316
|
body = await c.req.json();
|
|
9317
9317
|
} catch (err) {
|
|
9318
9318
|
const detail = err instanceof Error ? err.message : String(err);
|
|
9319
|
-
console.error(`${
|
|
9319
|
+
console.error(`${TAG23} reject reason=body-not-json detail=${detail}`);
|
|
9320
9320
|
return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
|
|
9321
9321
|
}
|
|
9322
9322
|
const event = typeof body.event === "string" ? body.event : "";
|
|
9323
9323
|
if (!ALLOWED_EVENTS.has(event)) {
|
|
9324
|
-
console.error(`${
|
|
9324
|
+
console.error(`${TAG23} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
|
|
9325
9325
|
return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
|
|
9326
9326
|
}
|
|
9327
9327
|
const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
|
|
@@ -12932,36 +12932,140 @@ app32.post("/", requireAdminSession, async (c) => {
|
|
|
12932
12932
|
});
|
|
12933
12933
|
var linkedin_ingest_default = app32;
|
|
12934
12934
|
|
|
12935
|
-
// server/routes/admin/
|
|
12935
|
+
// server/routes/admin/post-turn-context.ts
|
|
12936
|
+
import neo4j3 from "neo4j-driver";
|
|
12937
|
+
var TAG21 = "[post-turn-context]";
|
|
12938
|
+
var STRIPPED_PROPERTIES2 = /* @__PURE__ */ new Set([
|
|
12939
|
+
"embedding",
|
|
12940
|
+
"passwordHash",
|
|
12941
|
+
"magicToken",
|
|
12942
|
+
"otpCode",
|
|
12943
|
+
"cacheKey"
|
|
12944
|
+
]);
|
|
12945
|
+
function isLoopbackAddr2(addr) {
|
|
12946
|
+
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
12947
|
+
}
|
|
12948
|
+
function convertValue(value) {
|
|
12949
|
+
if (neo4j3.isDateTime(value) || neo4j3.isDate(value) || neo4j3.isLocalDateTime(value) || neo4j3.isLocalTime(value) || neo4j3.isTime(value) || neo4j3.isDuration(value)) {
|
|
12950
|
+
return value.toString();
|
|
12951
|
+
}
|
|
12952
|
+
if (neo4j3.isInt(value)) {
|
|
12953
|
+
return value.inSafeRange() ? value.toNumber() : value.toString();
|
|
12954
|
+
}
|
|
12955
|
+
if (Array.isArray(value)) {
|
|
12956
|
+
return value.map((v) => convertValue(v));
|
|
12957
|
+
}
|
|
12958
|
+
if (value !== null && typeof value === "object" && value.constructor === Object) {
|
|
12959
|
+
const out = {};
|
|
12960
|
+
for (const [k, v] of Object.entries(value)) {
|
|
12961
|
+
out[k] = convertValue(v);
|
|
12962
|
+
}
|
|
12963
|
+
return out;
|
|
12964
|
+
}
|
|
12965
|
+
return value;
|
|
12966
|
+
}
|
|
12967
|
+
function pruneProperties(raw) {
|
|
12968
|
+
const out = {};
|
|
12969
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
12970
|
+
if (STRIPPED_PROPERTIES2.has(k)) continue;
|
|
12971
|
+
out[k] = convertValue(v);
|
|
12972
|
+
}
|
|
12973
|
+
return out;
|
|
12974
|
+
}
|
|
12936
12975
|
var app33 = new Hono();
|
|
12937
|
-
app33.
|
|
12938
|
-
|
|
12939
|
-
|
|
12940
|
-
|
|
12941
|
-
|
|
12942
|
-
|
|
12943
|
-
|
|
12944
|
-
|
|
12945
|
-
|
|
12946
|
-
|
|
12947
|
-
|
|
12948
|
-
|
|
12949
|
-
|
|
12950
|
-
|
|
12951
|
-
|
|
12952
|
-
|
|
12953
|
-
|
|
12954
|
-
|
|
12955
|
-
|
|
12956
|
-
|
|
12957
|
-
|
|
12958
|
-
|
|
12959
|
-
|
|
12960
|
-
|
|
12961
|
-
|
|
12962
|
-
|
|
12963
|
-
|
|
12964
|
-
|
|
12976
|
+
app33.get("/", async (c) => {
|
|
12977
|
+
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
12978
|
+
if (!isLoopbackAddr2(remoteAddr)) {
|
|
12979
|
+
console.error(`${TAG21} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
12980
|
+
return c.json({ error: "post-turn-context-loopback-only" }, 403);
|
|
12981
|
+
}
|
|
12982
|
+
const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
|
|
12983
|
+
const xffRaw = Array.isArray(xffHeader) ? xffHeader.join(",") : typeof xffHeader === "string" ? xffHeader : "";
|
|
12984
|
+
if (xffRaw.length > 0) {
|
|
12985
|
+
const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
12986
|
+
const offender = tokens.find((t) => !isLoopbackAddr2(t));
|
|
12987
|
+
if (offender !== void 0) {
|
|
12988
|
+
console.error(`${TAG21} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
|
|
12989
|
+
return c.json({ error: "post-turn-context-loopback-only" }, 403);
|
|
12990
|
+
}
|
|
12991
|
+
}
|
|
12992
|
+
const conversationId = (c.req.query("conversationId") ?? "").trim();
|
|
12993
|
+
const accountId = (c.req.query("accountId") ?? "").trim();
|
|
12994
|
+
if (!conversationId) return c.json({ error: "conversationId required" }, 400);
|
|
12995
|
+
if (!accountId) return c.json({ error: "accountId required" }, 400);
|
|
12996
|
+
const session = getSession();
|
|
12997
|
+
const started = Date.now();
|
|
12998
|
+
try {
|
|
12999
|
+
const cypher = `
|
|
13000
|
+
MATCH (c:Conversation {conversationId: $conversationId, accountId: $accountId})
|
|
13001
|
+
MATCH (c)<-[:PRODUCED]-(n)
|
|
13002
|
+
WHERE coalesce(n.accountId, $accountId) = $accountId
|
|
13003
|
+
RETURN elementId(n) AS elementId, labels(n) AS labels, properties(n) AS properties, coalesce(n.createdAt, n.observedAt, '') AS sortKey
|
|
13004
|
+
UNION
|
|
13005
|
+
MATCH (n) WHERE n.conversationId = $conversationId AND n.accountId = $accountId
|
|
13006
|
+
RETURN elementId(n) AS elementId, labels(n) AS labels, properties(n) AS properties, coalesce(n.createdAt, n.observedAt, '') AS sortKey
|
|
13007
|
+
`;
|
|
13008
|
+
const res = await session.executeRead(
|
|
13009
|
+
(tx) => tx.run(cypher, { conversationId, accountId })
|
|
13010
|
+
);
|
|
13011
|
+
const writes = res.records.map((r) => ({
|
|
13012
|
+
elementId: r.get("elementId"),
|
|
13013
|
+
labels: r.get("labels"),
|
|
13014
|
+
properties: pruneProperties(r.get("properties")),
|
|
13015
|
+
sortKey: String(r.get("sortKey") ?? "")
|
|
13016
|
+
}));
|
|
13017
|
+
writes.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
|
|
13018
|
+
const total = Date.now() - started;
|
|
13019
|
+
console.log(
|
|
13020
|
+
`${TAG21} conversationId=${conversationId} accountId=${accountId} writes=${writes.length} ms=${total}`
|
|
13021
|
+
);
|
|
13022
|
+
return c.json({
|
|
13023
|
+
writes: writes.map(({ elementId, labels, properties }) => ({ elementId, labels, properties }))
|
|
13024
|
+
});
|
|
13025
|
+
} catch (err) {
|
|
13026
|
+
const elapsed = Date.now() - started;
|
|
13027
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
13028
|
+
console.error(
|
|
13029
|
+
`${TAG21} neo4j-unreachable conversationId=${conversationId} ms=${elapsed} err="${message}"`
|
|
13030
|
+
);
|
|
13031
|
+
return c.json({ error: `post-turn-context unavailable: ${message}` }, 503);
|
|
13032
|
+
} finally {
|
|
13033
|
+
await session.close();
|
|
13034
|
+
}
|
|
13035
|
+
});
|
|
13036
|
+
var post_turn_context_default = app33;
|
|
13037
|
+
|
|
13038
|
+
// server/routes/admin/index.ts
|
|
13039
|
+
var app34 = new Hono();
|
|
13040
|
+
app34.route("/session", session_default);
|
|
13041
|
+
app34.route("/new-session-failure", new_session_failure_default);
|
|
13042
|
+
app34.route("/new-session-submit", new_session_submit_default);
|
|
13043
|
+
app34.route("/logs", logs_default);
|
|
13044
|
+
app34.route("/claude-info", claude_info_default);
|
|
13045
|
+
app34.route("/claude-capabilities", claude_capabilities_default);
|
|
13046
|
+
app34.route("/attachment", attachment_default);
|
|
13047
|
+
app34.route("/agents", agents_default);
|
|
13048
|
+
app34.route("/sessions", sessions_default);
|
|
13049
|
+
app34.route("/claude-sessions", claude_sessions_default);
|
|
13050
|
+
app34.route("/log-ingest", log_ingest_default);
|
|
13051
|
+
app34.route("/events", events_default);
|
|
13052
|
+
app34.route("/files", files_default);
|
|
13053
|
+
app34.route("/graph-search", graph_search_default);
|
|
13054
|
+
app34.route("/graph-subgraph", graph_subgraph_default);
|
|
13055
|
+
app34.route("/graph-delete", graph_delete_default);
|
|
13056
|
+
app34.route("/graph-restore", graph_restore_default);
|
|
13057
|
+
app34.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
13058
|
+
app34.route("/graph-default-view", graph_default_view_default);
|
|
13059
|
+
app34.route("/session-defaults", session_defaults_default);
|
|
13060
|
+
app34.route("/file-attach", file_attach_default);
|
|
13061
|
+
app34.route("/sidebar-artefacts", sidebar_artefacts_default);
|
|
13062
|
+
app34.route("/sidebar-artefact-save", sidebar_artefact_save_default);
|
|
13063
|
+
app34.route("/sidebar-artefact-content", sidebar_artefact_content_default);
|
|
13064
|
+
app34.route("/system-stats", system_stats_default);
|
|
13065
|
+
app34.route("/health-brand", health_default2);
|
|
13066
|
+
app34.route("/linkedin-ingest", linkedin_ingest_default);
|
|
13067
|
+
app34.route("/post-turn-context", post_turn_context_default);
|
|
13068
|
+
var admin_default = app34;
|
|
12965
13069
|
|
|
12966
13070
|
// server/routes/sites.ts
|
|
12967
13071
|
import { existsSync as existsSync21, readFileSync as readFileSync17, realpathSync as realpathSync5, statSync as statSync7 } from "fs";
|
|
@@ -12996,8 +13100,8 @@ function getExt(p) {
|
|
|
12996
13100
|
if (idx < p.lastIndexOf("/")) return "";
|
|
12997
13101
|
return p.slice(idx).toLowerCase();
|
|
12998
13102
|
}
|
|
12999
|
-
var
|
|
13000
|
-
|
|
13103
|
+
var app35 = new Hono();
|
|
13104
|
+
app35.get("/:rel{.*}", (c) => {
|
|
13001
13105
|
const reqPath = c.req.path;
|
|
13002
13106
|
const rawRel = c.req.param("rel") ?? "";
|
|
13003
13107
|
const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
@@ -13100,7 +13204,7 @@ app34.get("/:rel{.*}", (c) => {
|
|
|
13100
13204
|
"X-Content-Type-Options": "nosniff"
|
|
13101
13205
|
});
|
|
13102
13206
|
});
|
|
13103
|
-
var sites_default =
|
|
13207
|
+
var sites_default = app35;
|
|
13104
13208
|
|
|
13105
13209
|
// app/lib/visitor-token.ts
|
|
13106
13210
|
import { createHmac, randomBytes, timingSafeEqual } from "crypto";
|
|
@@ -13200,7 +13304,7 @@ function readBrandConfig() {
|
|
|
13200
13304
|
}
|
|
13201
13305
|
|
|
13202
13306
|
// server/routes/visitor-consent.ts
|
|
13203
|
-
var
|
|
13307
|
+
var app36 = new Hono();
|
|
13204
13308
|
var CONSENT_COOKIE_NAME = "mxy_consent";
|
|
13205
13309
|
var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
|
|
13206
13310
|
var DEFAULT_CONSENT_COPY = {
|
|
@@ -13245,17 +13349,17 @@ function siteSlugFromReferer(referer) {
|
|
|
13245
13349
|
return "";
|
|
13246
13350
|
}
|
|
13247
13351
|
}
|
|
13248
|
-
|
|
13352
|
+
app36.options("/consent", (c) => {
|
|
13249
13353
|
const origin = getOrigin(c);
|
|
13250
13354
|
setCorsHeaders(c, origin);
|
|
13251
13355
|
return c.body(null, 204);
|
|
13252
13356
|
});
|
|
13253
|
-
|
|
13357
|
+
app36.options("/brand-config", (c) => {
|
|
13254
13358
|
const origin = getOrigin(c);
|
|
13255
13359
|
setCorsHeaders(c, origin);
|
|
13256
13360
|
return c.body(null, 204);
|
|
13257
13361
|
});
|
|
13258
|
-
|
|
13362
|
+
app36.post("/consent", async (c) => {
|
|
13259
13363
|
const origin = getOrigin(c);
|
|
13260
13364
|
setCorsHeaders(c, origin);
|
|
13261
13365
|
let raw;
|
|
@@ -13295,7 +13399,7 @@ app35.post("/consent", async (c) => {
|
|
|
13295
13399
|
console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
|
|
13296
13400
|
return c.body(null, 204);
|
|
13297
13401
|
});
|
|
13298
|
-
|
|
13402
|
+
app36.get("/brand-config", (c) => {
|
|
13299
13403
|
const origin = getOrigin(c);
|
|
13300
13404
|
setCorsHeaders(c, origin);
|
|
13301
13405
|
const brand = readBrandConfig();
|
|
@@ -13305,7 +13409,7 @@ app35.get("/brand-config", (c) => {
|
|
|
13305
13409
|
c.header("Cache-Control", "public, max-age=300");
|
|
13306
13410
|
return c.json({ consent: { copy, palette } });
|
|
13307
13411
|
});
|
|
13308
|
-
var visitor_consent_default =
|
|
13412
|
+
var visitor_consent_default = app36;
|
|
13309
13413
|
|
|
13310
13414
|
// server/routes/listings.ts
|
|
13311
13415
|
function getCookie(headerValue, name) {
|
|
@@ -13332,8 +13436,8 @@ function appendConsentParams(pageUrl, token) {
|
|
|
13332
13436
|
}
|
|
13333
13437
|
var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
|
|
13334
13438
|
var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
|
|
13335
|
-
var
|
|
13336
|
-
|
|
13439
|
+
var app37 = new Hono();
|
|
13440
|
+
app37.get("/:slug/click", async (c) => {
|
|
13337
13441
|
const slug = c.req.param("slug") ?? "";
|
|
13338
13442
|
const rawSession = c.req.query("session") ?? "";
|
|
13339
13443
|
const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
|
|
@@ -13397,10 +13501,10 @@ app36.get("/:slug/click", async (c) => {
|
|
|
13397
13501
|
console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
13398
13502
|
return c.redirect(redirectUrl, 302);
|
|
13399
13503
|
});
|
|
13400
|
-
var listings_default =
|
|
13504
|
+
var listings_default = app37;
|
|
13401
13505
|
|
|
13402
13506
|
// server/routes/visitor-event.ts
|
|
13403
|
-
var
|
|
13507
|
+
var app38 = new Hono();
|
|
13404
13508
|
var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
|
|
13405
13509
|
var buckets = /* @__PURE__ */ new Map();
|
|
13406
13510
|
var RATE_LIMIT = 60;
|
|
@@ -13467,12 +13571,12 @@ function originAllowed(origin, allowlist) {
|
|
|
13467
13571
|
return false;
|
|
13468
13572
|
}
|
|
13469
13573
|
}
|
|
13470
|
-
|
|
13574
|
+
app38.options("/event", (c) => {
|
|
13471
13575
|
const origin = getOrigin2(c);
|
|
13472
13576
|
setCorsHeaders2(c, origin);
|
|
13473
13577
|
return c.body(null, 204);
|
|
13474
13578
|
});
|
|
13475
|
-
|
|
13579
|
+
app38.post("/event", async (c) => {
|
|
13476
13580
|
const origin = getOrigin2(c);
|
|
13477
13581
|
setCorsHeaders2(c, origin);
|
|
13478
13582
|
const ua = c.req.header("user-agent") ?? "";
|
|
@@ -13677,7 +13781,7 @@ async function writeEvent(opts) {
|
|
|
13677
13781
|
);
|
|
13678
13782
|
}
|
|
13679
13783
|
}
|
|
13680
|
-
var visitor_event_default =
|
|
13784
|
+
var visitor_event_default = app38;
|
|
13681
13785
|
|
|
13682
13786
|
// app/lib/graph-health.ts
|
|
13683
13787
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
@@ -13761,7 +13865,7 @@ function startGraphHealthTimer() {
|
|
|
13761
13865
|
}
|
|
13762
13866
|
|
|
13763
13867
|
// app/lib/whatsapp/inbound/claude-bridge.ts
|
|
13764
|
-
var
|
|
13868
|
+
var TAG22 = "[whatsapp-adaptor]";
|
|
13765
13869
|
function whatsappTurnTimeoutMs() {
|
|
13766
13870
|
return Number(process.env.WHATSAPP_PTY_TURN_TIMEOUT_MS ?? String(5 * 6e4));
|
|
13767
13871
|
}
|
|
@@ -13784,7 +13888,7 @@ async function dispatchToClaude(input) {
|
|
|
13784
13888
|
await input.reply(result.turnText);
|
|
13785
13889
|
} catch (err) {
|
|
13786
13890
|
const m = err instanceof Error ? err.message : String(err);
|
|
13787
|
-
console.error(`${
|
|
13891
|
+
console.error(`${TAG22} reject reason=reply-failed senderId=${input.senderId} message=${m}`);
|
|
13788
13892
|
}
|
|
13789
13893
|
}
|
|
13790
13894
|
function startReaper2() {
|
|
@@ -14114,9 +14218,9 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
|
|
|
14114
14218
|
function isPublicHost(host) {
|
|
14115
14219
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
14116
14220
|
}
|
|
14117
|
-
var
|
|
14118
|
-
|
|
14119
|
-
|
|
14221
|
+
var app39 = new Hono();
|
|
14222
|
+
app39.use("*", clientIpMiddleware);
|
|
14223
|
+
app39.use("*", async (c, next) => {
|
|
14120
14224
|
await next();
|
|
14121
14225
|
c.header("X-Content-Type-Options", "nosniff");
|
|
14122
14226
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
@@ -14126,7 +14230,7 @@ app38.use("*", async (c, next) => {
|
|
|
14126
14230
|
);
|
|
14127
14231
|
});
|
|
14128
14232
|
var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
|
|
14129
|
-
|
|
14233
|
+
app39.use("*", async (c, next) => {
|
|
14130
14234
|
if (!HTTP_LOG_PATHS.has(c.req.path)) {
|
|
14131
14235
|
await next();
|
|
14132
14236
|
return;
|
|
@@ -14159,7 +14263,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
|
|
|
14159
14263
|
"/sites/"
|
|
14160
14264
|
];
|
|
14161
14265
|
var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
|
|
14162
|
-
|
|
14266
|
+
app39.use("*", async (c, next) => {
|
|
14163
14267
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14164
14268
|
if (!isPublicHost(host)) {
|
|
14165
14269
|
await next();
|
|
@@ -14199,7 +14303,7 @@ function resolveRemoteAuthOpts() {
|
|
|
14199
14303
|
return brandLoginOpts;
|
|
14200
14304
|
}
|
|
14201
14305
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
14202
|
-
|
|
14306
|
+
app39.post("/__remote-auth/login", async (c) => {
|
|
14203
14307
|
const client = clientFrom(c);
|
|
14204
14308
|
const clientIp = client.ip || "unknown";
|
|
14205
14309
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -14244,7 +14348,7 @@ app38.post("/__remote-auth/login", async (c) => {
|
|
|
14244
14348
|
}
|
|
14245
14349
|
});
|
|
14246
14350
|
});
|
|
14247
|
-
|
|
14351
|
+
app39.get("/__remote-auth/logout", (c) => {
|
|
14248
14352
|
const client = clientFrom(c);
|
|
14249
14353
|
const clientIp = client.ip || "unknown";
|
|
14250
14354
|
console.error(`[remote-auth] logout ip=${clientIp}`);
|
|
@@ -14257,7 +14361,7 @@ app38.get("/__remote-auth/logout", (c) => {
|
|
|
14257
14361
|
}
|
|
14258
14362
|
});
|
|
14259
14363
|
});
|
|
14260
|
-
|
|
14364
|
+
app39.post("/__remote-auth/change-password", async (c) => {
|
|
14261
14365
|
const client = clientFrom(c);
|
|
14262
14366
|
const clientIp = client.ip || "unknown";
|
|
14263
14367
|
const rateLimited = checkRateLimit(client);
|
|
@@ -14308,13 +14412,13 @@ app38.post("/__remote-auth/change-password", async (c) => {
|
|
|
14308
14412
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
14309
14413
|
}
|
|
14310
14414
|
});
|
|
14311
|
-
|
|
14415
|
+
app39.get("/__remote-auth/setup", (c) => {
|
|
14312
14416
|
if (isRemoteAuthConfigured()) {
|
|
14313
14417
|
return c.redirect("/");
|
|
14314
14418
|
}
|
|
14315
14419
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
|
|
14316
14420
|
});
|
|
14317
|
-
|
|
14421
|
+
app39.post("/__remote-auth/set-initial-password", async (c) => {
|
|
14318
14422
|
if (isRemoteAuthConfigured()) {
|
|
14319
14423
|
return c.redirect("/");
|
|
14320
14424
|
}
|
|
@@ -14352,10 +14456,10 @@ app38.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
14352
14456
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
14353
14457
|
}
|
|
14354
14458
|
});
|
|
14355
|
-
|
|
14459
|
+
app39.get("/api/remote-auth/status", (c) => {
|
|
14356
14460
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
14357
14461
|
});
|
|
14358
|
-
|
|
14462
|
+
app39.post("/api/remote-auth/set-password", async (c) => {
|
|
14359
14463
|
let body;
|
|
14360
14464
|
try {
|
|
14361
14465
|
body = await c.req.json();
|
|
@@ -14386,9 +14490,9 @@ app38.post("/api/remote-auth/set-password", async (c) => {
|
|
|
14386
14490
|
return c.json({ error: "Failed to save password" }, 500);
|
|
14387
14491
|
}
|
|
14388
14492
|
});
|
|
14389
|
-
|
|
14493
|
+
app39.route("/api/_client-error", client_error_default);
|
|
14390
14494
|
console.log("[client-error-route] mounted");
|
|
14391
|
-
|
|
14495
|
+
app39.use("*", async (c, next) => {
|
|
14392
14496
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14393
14497
|
const path2 = c.req.path;
|
|
14394
14498
|
if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
|
|
@@ -14421,11 +14525,11 @@ app38.use("*", async (c, next) => {
|
|
|
14421
14525
|
console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
|
|
14422
14526
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
|
|
14423
14527
|
});
|
|
14424
|
-
|
|
14425
|
-
|
|
14426
|
-
|
|
14427
|
-
|
|
14428
|
-
|
|
14528
|
+
app39.route("/api/health", health_default);
|
|
14529
|
+
app39.route("/api/chat", chat_default);
|
|
14530
|
+
app39.route("/api/whatsapp", whatsapp_default);
|
|
14531
|
+
app39.route("/api/onboarding", onboarding_default);
|
|
14532
|
+
app39.route("/api/admin", admin_default);
|
|
14429
14533
|
var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
|
|
14430
14534
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
14431
14535
|
var IMAGE_MIME = {
|
|
@@ -14437,7 +14541,7 @@ var IMAGE_MIME = {
|
|
|
14437
14541
|
".svg": "image/svg+xml",
|
|
14438
14542
|
".ico": "image/x-icon"
|
|
14439
14543
|
};
|
|
14440
|
-
|
|
14544
|
+
app39.get("/agent-assets/:slug/:filename", (c) => {
|
|
14441
14545
|
const slug = c.req.param("slug");
|
|
14442
14546
|
const filename = c.req.param("filename");
|
|
14443
14547
|
if (!SAFE_SLUG_RE2.test(slug)) {
|
|
@@ -14472,7 +14576,7 @@ app38.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
14472
14576
|
"Cache-Control": "public, max-age=3600"
|
|
14473
14577
|
});
|
|
14474
14578
|
});
|
|
14475
|
-
|
|
14579
|
+
app39.get("/generated/:filename", (c) => {
|
|
14476
14580
|
const filename = c.req.param("filename");
|
|
14477
14581
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
14478
14582
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -14502,10 +14606,10 @@ app38.get("/generated/:filename", (c) => {
|
|
|
14502
14606
|
"Cache-Control": "public, max-age=86400"
|
|
14503
14607
|
});
|
|
14504
14608
|
});
|
|
14505
|
-
|
|
14506
|
-
|
|
14507
|
-
|
|
14508
|
-
|
|
14609
|
+
app39.route("/sites", sites_default);
|
|
14610
|
+
app39.route("/listings", listings_default);
|
|
14611
|
+
app39.route("/v", visitor_event_default);
|
|
14612
|
+
app39.route("/v", visitor_consent_default);
|
|
14509
14613
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
14510
14614
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
14511
14615
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
@@ -14642,7 +14746,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
14642
14746
|
function escapeHtml(s) {
|
|
14643
14747
|
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
14644
14748
|
}
|
|
14645
|
-
|
|
14749
|
+
app39.get("/", (c) => {
|
|
14646
14750
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14647
14751
|
if (isPublicHost(host)) {
|
|
14648
14752
|
const defaultSlug = resolveDefaultSlug();
|
|
@@ -14650,12 +14754,12 @@ app38.get("/", (c) => {
|
|
|
14650
14754
|
}
|
|
14651
14755
|
return c.html(cachedHtml("index.html"));
|
|
14652
14756
|
});
|
|
14653
|
-
|
|
14757
|
+
app39.get("/public", (c) => {
|
|
14654
14758
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14655
14759
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
14656
14760
|
return c.html(cachedHtml("public.html"));
|
|
14657
14761
|
});
|
|
14658
|
-
|
|
14762
|
+
app39.get("/chat", (c) => {
|
|
14659
14763
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14660
14764
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
14661
14765
|
return c.html(cachedHtml("public.html"));
|
|
@@ -14674,9 +14778,9 @@ async function logViewerFetch(c, next) {
|
|
|
14674
14778
|
duration_ms: Date.now() - start
|
|
14675
14779
|
});
|
|
14676
14780
|
}
|
|
14677
|
-
|
|
14678
|
-
|
|
14679
|
-
|
|
14781
|
+
app39.use("/vnc-viewer.html", logViewerFetch);
|
|
14782
|
+
app39.use("/vnc-popout.html", logViewerFetch);
|
|
14783
|
+
app39.get("/vnc-popout.html", (c) => {
|
|
14680
14784
|
let html = htmlCache.get("vnc-popout.html");
|
|
14681
14785
|
if (!html) {
|
|
14682
14786
|
html = readFileSync21(resolve21(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
@@ -14689,7 +14793,7 @@ app38.get("/vnc-popout.html", (c) => {
|
|
|
14689
14793
|
}
|
|
14690
14794
|
return c.html(html);
|
|
14691
14795
|
});
|
|
14692
|
-
|
|
14796
|
+
app39.post("/api/vnc/client-event", async (c) => {
|
|
14693
14797
|
let body;
|
|
14694
14798
|
try {
|
|
14695
14799
|
body = await c.req.json();
|
|
@@ -14710,25 +14814,25 @@ app38.post("/api/vnc/client-event", async (c) => {
|
|
|
14710
14814
|
});
|
|
14711
14815
|
return c.json({ ok: true });
|
|
14712
14816
|
});
|
|
14713
|
-
|
|
14817
|
+
app39.get("/g/:slug", (c) => {
|
|
14714
14818
|
return c.html(brandedPublicHtml());
|
|
14715
14819
|
});
|
|
14716
|
-
|
|
14820
|
+
app39.get("/graph", (c) => {
|
|
14717
14821
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14718
14822
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
14719
14823
|
return c.html(cachedHtml("graph.html"));
|
|
14720
14824
|
});
|
|
14721
|
-
|
|
14825
|
+
app39.get("/sessions", (c) => {
|
|
14722
14826
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14723
14827
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
14724
14828
|
return c.html(cachedHtml("sessions.html"));
|
|
14725
14829
|
});
|
|
14726
|
-
|
|
14830
|
+
app39.get("/data", (c) => {
|
|
14727
14831
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14728
14832
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
14729
14833
|
return c.html(cachedHtml("data.html"));
|
|
14730
14834
|
});
|
|
14731
|
-
|
|
14835
|
+
app39.get("/:slug", async (c, next) => {
|
|
14732
14836
|
const slug = c.req.param("slug");
|
|
14733
14837
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
14734
14838
|
const branding = loadBrandingCache(slug);
|
|
@@ -14738,15 +14842,15 @@ app38.get("/:slug", async (c, next) => {
|
|
|
14738
14842
|
await next();
|
|
14739
14843
|
});
|
|
14740
14844
|
if (brandFaviconPath !== "/favicon.ico") {
|
|
14741
|
-
|
|
14845
|
+
app39.get("/favicon.ico", (c) => {
|
|
14742
14846
|
c.header("Cache-Control", "public, max-age=300");
|
|
14743
14847
|
return c.redirect(brandFaviconPath, 302);
|
|
14744
14848
|
});
|
|
14745
14849
|
}
|
|
14746
|
-
|
|
14850
|
+
app39.use("/*", serveStatic({ root: "./public" }));
|
|
14747
14851
|
var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
|
|
14748
14852
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
14749
|
-
var httpServer = serve({ fetch:
|
|
14853
|
+
var httpServer = serve({ fetch: app39.fetch, port, hostname });
|
|
14750
14854
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
14751
14855
|
{
|
|
14752
14856
|
const loopHist = monitorEventLoopDelay({ resolution: 50 });
|
|
@@ -14781,7 +14885,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
14781
14885
|
}
|
|
14782
14886
|
try {
|
|
14783
14887
|
const registered = [];
|
|
14784
|
-
for (const r of
|
|
14888
|
+
for (const r of app39.routes ?? []) {
|
|
14785
14889
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
14786
14890
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
14787
14891
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|