neotoma 0.9.0 → 0.10.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 +11 -7
- package/dist/actions.d.ts +10 -5
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +144 -15
- package/dist/actions.js.map +1 -1
- package/dist/cli/hooks.d.ts +4 -4
- package/dist/cli/hooks.js +4 -4
- package/dist/cli/hooks_detect.d.ts.map +1 -1
- package/dist/cli/hooks_detect.js +16 -9
- package/dist/cli/hooks_detect.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +87 -15
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp_config_scan.d.ts +10 -0
- package/dist/cli/mcp_config_scan.d.ts.map +1 -1
- package/dist/cli/mcp_config_scan.js +85 -5
- package/dist/cli/mcp_config_scan.js.map +1 -1
- package/dist/cli/setup.d.ts +1 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +71 -1
- package/dist/cli/setup.js.map +1 -1
- package/dist/core/operations.d.ts +9 -0
- package/dist/core/operations.d.ts.map +1 -1
- package/dist/core/operations.js +3 -0
- package/dist/core/operations.js.map +1 -1
- package/dist/inspector/assets/{Combination-CujEssa-.js → Combination-BP0-kPZX.js} +1 -1
- package/dist/inspector/assets/{agent_badge-Cy2xdM19.js → agent_badge-BZT-JO2h.js} +1 -1
- package/dist/inspector/assets/agent_detail-BGMLF8-n.js +1 -0
- package/dist/inspector/assets/{agent_filter-9Y5V9TSY.js → agent_filter-DMC4CzhM.js} +1 -1
- package/dist/inspector/assets/agent_grant_detail-Brqy5K7M.js +1 -0
- package/dist/inspector/assets/{agent_grant_form-DjoTByJj.js → agent_grant_form-BLDkUh1Y.js} +1 -1
- package/dist/inspector/assets/agent_grants-B2StunRb.js +1 -0
- package/dist/inspector/assets/agents-lYmKs-fG.js +1 -0
- package/dist/inspector/assets/{arrow-left-Bxer0ezV.js → arrow-left-D1s7DOns.js} +1 -1
- package/dist/inspector/assets/{attribution_card-C48p_bBB.js → attribution_card-D-bp008l.js} +1 -1
- package/dist/inspector/assets/attribution_summary-Cs9Ccvt3.js +1 -0
- package/dist/inspector/assets/card-Btqgzh6p.js +1 -0
- package/dist/inspector/assets/{check-DN6vjWJ7.js → check-DAyRtq63.js} +1 -1
- package/dist/inspector/assets/{checkbox-DuNHytV3.js → checkbox-BrpwHaRo.js} +1 -1
- package/dist/inspector/assets/{chevron-down-BGEwSYyI.js → chevron-down-CCk_jMPN.js} +1 -1
- package/dist/inspector/assets/{chevron-right-D5OasTAw.js → chevron-right-C9NbdZtC.js} +1 -1
- package/dist/inspector/assets/compliance-BHiHtgfg.js +1 -0
- package/dist/inspector/assets/{confirm-dialog-2InCKZky.js → confirm-dialog-BcxtVONz.js} +2 -2
- package/dist/inspector/assets/conversation_common-Dw5j3QuN.js +1 -0
- package/dist/inspector/assets/conversation_detail-BR_rBMFV.js +1 -0
- package/dist/inspector/assets/{copy_id_button-CoFHQieu.js → copy_id_button-CyjfY7dx.js} +1 -1
- package/dist/inspector/assets/{corrections-C-GqSum_.js → corrections-DFExbcsm.js} +1 -1
- package/dist/inspector/assets/{dashboard-CB0ynQ0H.js → dashboard-CxnNRphy.js} +34 -34
- package/dist/inspector/assets/{data-table-Nyryp-JO.js → data-table-CazqdSem.js} +1 -1
- package/dist/inspector/assets/{dialog-DS3fUAm1.js → dialog-X5X7rLah.js} +1 -1
- package/dist/inspector/assets/{dropdown-menu-Cypcul5-.js → dropdown-menu-CmZjxUWM.js} +1 -1
- package/dist/inspector/assets/entities-l6icu6fc.js +1 -0
- package/dist/inspector/assets/entity_detail-daoxB-h1.js +17 -0
- package/dist/inspector/assets/{entity_link-DujmD1Yr.js → entity_link-DtMv__WC.js} +1 -1
- package/dist/inspector/assets/{external-link-C4V3VgZf.js → external-link-BBoTnT-P.js} +1 -1
- package/dist/inspector/assets/feedback-DeFhdWId.js +35 -0
- package/dist/inspector/assets/graph_explorer-BvicLJEW.js +23 -0
- package/dist/inspector/assets/index-B2zHigxN.js +199 -0
- package/dist/inspector/assets/{index-Dqo226iA.js → index-Czej0Y93.js} +1 -1
- package/dist/inspector/assets/{index-ZmrnhI6W.js → index-D5i6AEXI.js} +1 -1
- package/dist/inspector/assets/{index-Bx2zn3Hd.js → index-DJuPlRtP.js} +1 -1
- package/dist/inspector/assets/index-Df569_c9.css +1 -0
- package/dist/inspector/assets/interpretations-D9gWqVhy.js +1 -0
- package/dist/inspector/assets/interpretations-E0sIBf-l.js +1 -0
- package/dist/inspector/assets/{json_viewer-BkvSv8xS.js → json_viewer-ojLDPDtf.js} +1 -1
- package/dist/inspector/assets/{label-CbDLvpxl.js → label-DWyQNl4E.js} +1 -1
- package/dist/inspector/assets/live_relative_time-DzLnsA9y.js +1 -0
- package/dist/inspector/assets/observations-Ds0kFmaM.js +1 -0
- package/dist/inspector/assets/{page_shell-_vozYBwF.js → page_shell-C-4AKr0Y.js} +1 -1
- package/dist/inspector/assets/{pagination-aHI1LrUp.js → pagination-lSg-a95h.js} +1 -1
- package/dist/inspector/assets/{plus-CPWsVXx9.js → plus-CQMoR71F.js} +1 -1
- package/dist/inspector/assets/query_loading-BFETHugg.js +1 -0
- package/dist/inspector/assets/query_refresh_indicator-Bewf0Dj1.js +1 -0
- package/dist/inspector/assets/{recent_activity-DOx6FPz3.js → recent_activity-Csh_YraY.js} +2 -2
- package/dist/inspector/assets/recent_conversations-CBengQjb.js +1 -0
- package/dist/inspector/assets/recent_conversations-MKmxYevd.js +1 -0
- package/dist/inspector/assets/recent_records_feed-CCrBRfkG.js +1 -0
- package/dist/inspector/assets/relationship_detail-CUz_GhPI.js +1 -0
- package/dist/inspector/assets/relationships-Ulajo16_.js +1 -0
- package/dist/inspector/assets/{relationships-DnfqeglP.js → relationships-Z9ALu9Oa.js} +1 -1
- package/dist/inspector/assets/{sandbox-CHH6I9Ww.js → sandbox-CfD5QvC5.js} +1 -1
- package/dist/inspector/assets/schema_detail-B1W8rbzV.js +11 -0
- package/dist/inspector/assets/schemas-DVlEFPuf.js +5 -0
- package/dist/inspector/assets/search-BccQXyTN.js +1 -0
- package/dist/inspector/assets/{select-MlFuilHt.js → select-Dv1QM6oO.js} +1 -1
- package/dist/inspector/assets/settings-B4U8tFYI.js +1 -0
- package/dist/inspector/assets/source_detail-B1JlZBBx.js +17 -0
- package/dist/inspector/assets/{source_link-B0ZU_1AG.js → source_link-p8KzI1os.js} +1 -1
- package/dist/inspector/assets/sources-B5ssCN-s.js +9 -0
- package/dist/inspector/assets/{switch-DXGlOHG4.js → switch-BPI_y_Z3.js} +1 -1
- package/dist/inspector/assets/{tabs-C0mWq9S1.js → tabs-HUG-sxc2.js} +1 -1
- package/dist/inspector/assets/{textarea-wLUG8kv6.js → textarea-DNz92WE1.js} +1 -1
- package/dist/inspector/assets/timeline-DRqxyQUF.js +1 -0
- package/dist/inspector/assets/{timeline-DXEE4O4U.js → timeline-HN2EoMGt.js} +1 -1
- package/dist/inspector/assets/timeline_event_detail-DbA5EpiN.js +1 -0
- package/dist/inspector/assets/{trash-2-DWBXKl-O.js → trash-2-BAfHKatZ.js} +1 -1
- package/dist/inspector/assets/turn_detail-BUHzIhWX.js +1 -0
- package/dist/inspector/assets/turns-ADRkuqKL.js +1 -0
- package/dist/inspector/assets/use_agents-CTZrpsvS.js +1 -0
- package/dist/inspector/assets/use_entities-BEhy6HWn.js +1 -0
- package/dist/inspector/assets/use_interpretations-CKN63UxX.js +1 -0
- package/dist/inspector/assets/{use_mutations-C-WJL341.js → use_mutations-B4y1qmV5.js} +1 -1
- package/dist/inspector/assets/use_recent_conversations-CIBgmz9B.js +1 -0
- package/dist/inspector/assets/use_relationships-Cl-o_7u6.js +1 -0
- package/dist/inspector/assets/use_schemas-Bl11WNgP.js +1 -0
- package/dist/inspector/assets/use_sources-DkJZZBDp.js +1 -0
- package/dist/inspector/assets/use_stats-Cn1a3yt-.js +1 -0
- package/dist/inspector/assets/use_timeline-DZkbwA-7.js +1 -0
- package/dist/inspector/assets/use_turns-BHfaal9v.js +1 -0
- package/dist/inspector/index.html +2 -2
- package/dist/mcp_dev_shim.d.ts +17 -0
- package/dist/mcp_dev_shim.d.ts.map +1 -0
- package/dist/mcp_dev_shim.js +324 -0
- package/dist/mcp_dev_shim.js.map +1 -0
- package/dist/mcp_server_card.js +1 -1
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +87 -16
- package/dist/server.js.map +1 -1
- package/dist/services/compliance/scorecard.d.ts +35 -73
- package/dist/services/compliance/scorecard.d.ts.map +1 -1
- package/dist/services/compliance/scorecard.js +234 -270
- package/dist/services/compliance/scorecard.js.map +1 -1
- package/dist/services/conversation_turn.d.ts +38 -0
- package/dist/services/conversation_turn.d.ts.map +1 -1
- package/dist/services/conversation_turn.js +128 -5
- package/dist/services/conversation_turn.js.map +1 -1
- package/dist/services/mcp_oauth.d.ts +9 -7
- package/dist/services/mcp_oauth.d.ts.map +1 -1
- package/dist/services/mcp_oauth.js +170 -13
- package/dist/services/mcp_oauth.js.map +1 -1
- package/dist/services/recent_conversations.d.ts +7 -0
- package/dist/services/recent_conversations.d.ts.map +1 -1
- package/dist/services/recent_conversations.js +89 -14
- package/dist/services/recent_conversations.js.map +1 -1
- package/dist/services/root_landing/site_nav.d.ts.map +1 -1
- package/dist/services/root_landing/site_nav.js +8 -3
- package/dist/services/root_landing/site_nav.js.map +1 -1
- package/dist/services/schema_definitions.d.ts.map +1 -1
- package/dist/services/schema_definitions.js +29 -4
- package/dist/services/schema_definitions.js.map +1 -1
- package/dist/services/schema_registry.d.ts.map +1 -1
- package/dist/services/schema_registry.js +28 -2
- package/dist/services/schema_registry.js.map +1 -1
- package/dist/shared/action_schemas.d.ts +163 -16
- package/dist/shared/action_schemas.d.ts.map +1 -1
- package/dist/shared/action_schemas.js +28 -10
- package/dist/shared/action_schemas.js.map +1 -1
- package/dist/shared/contract_mappings.d.ts.map +1 -1
- package/dist/shared/contract_mappings.js +23 -0
- package/dist/shared/contract_mappings.js.map +1 -1
- package/dist/shared/openapi_types.d.ts +242 -16
- package/dist/shared/openapi_types.d.ts.map +1 -1
- package/dist/tool_definitions.d.ts +1 -1
- package/dist/tool_definitions.d.ts.map +1 -1
- package/dist/tool_definitions.js +6 -0
- package/dist/tool_definitions.js.map +1 -1
- package/openapi.yaml +287 -28
- package/package.json +4 -1
- package/dist/inspector/assets/agent_detail-34_3u913.js +0 -1
- package/dist/inspector/assets/agent_grant_detail-fs0DKTd5.js +0 -1
- package/dist/inspector/assets/agent_grants-DUtqBZkK.js +0 -1
- package/dist/inspector/assets/agents-CIUBwgRT.js +0 -1
- package/dist/inspector/assets/attribution_summary-B7KAy0mn.js +0 -1
- package/dist/inspector/assets/card-Bz-JK2L1.js +0 -1
- package/dist/inspector/assets/compliance-B7gRLVKA.js +0 -1
- package/dist/inspector/assets/entities-B1ZBrker.js +0 -1
- package/dist/inspector/assets/entity_detail-DlsbmdeN.js +0 -17
- package/dist/inspector/assets/feedback-BQFBT-KP.js +0 -35
- package/dist/inspector/assets/graph_explorer-Ckir-IQl.js +0 -23
- package/dist/inspector/assets/index-ClljmJBP.js +0 -199
- package/dist/inspector/assets/index-NU89qCAK.css +0 -1
- package/dist/inspector/assets/interpretations-B7wb65mL.js +0 -1
- package/dist/inspector/assets/interpretations-CUaxEt1j.js +0 -1
- package/dist/inspector/assets/observations-lXPbAxMw.js +0 -1
- package/dist/inspector/assets/recent_conversations-CgG1tewt.js +0 -1
- package/dist/inspector/assets/recent_records_feed-CQN5zaI8.js +0 -1
- package/dist/inspector/assets/relationship_detail-LsEDdRi1.js +0 -1
- package/dist/inspector/assets/relationships-bLyNDRTv.js +0 -1
- package/dist/inspector/assets/schema_detail-DnkpfNNX.js +0 -11
- package/dist/inspector/assets/schemas-CvrYW_Oj.js +0 -5
- package/dist/inspector/assets/search-Bj5zl6Sn.js +0 -1
- package/dist/inspector/assets/settings-D5tFC9Ho.js +0 -1
- package/dist/inspector/assets/source_detail-C2OkmsHz.js +0 -17
- package/dist/inspector/assets/sources-BDnp2oAz.js +0 -9
- package/dist/inspector/assets/timeline-LjwviNGU.js +0 -1
- package/dist/inspector/assets/timeline_event_detail-C0M5GhTm.js +0 -1
- package/dist/inspector/assets/turn_detail-DXCnGJQ4.js +0 -1
- package/dist/inspector/assets/turns-C6blPs3y.js +0 -1
- package/dist/inspector/assets/use_agents-Cl-ZvBxZ.js +0 -1
- package/dist/inspector/assets/use_entities-DtfxOiM5.js +0 -1
- package/dist/inspector/assets/use_interpretations-usFKH4p9.js +0 -1
- package/dist/inspector/assets/use_recent_conversations-CcGV91zn.js +0 -1
- package/dist/inspector/assets/use_relationships-Ci7lTjAZ.js +0 -1
- package/dist/inspector/assets/use_schemas-D_uXgmEv.js +0 -1
- package/dist/inspector/assets/use_sources-CFY0i0dw.js +0 -1
- package/dist/inspector/assets/use_stats-DBERXcdx.js +0 -1
- package/dist/inspector/assets/use_timeline-BqlPwIlB.js +0 -1
- package/dist/inspector/assets/use_turns-vQjPAKeW.js +0 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Your agents forget. Neotoma makes them remember.
|
|
4
4
|
|
|
5
|
-
Versioned records — contacts, tasks, decisions, finances — that persist across Claude, Cursor, ChatGPT, OpenClaw, and every agent you run. Open-source. Local-first. Deterministic. MIT licensed.
|
|
5
|
+
Versioned records — contacts, tasks, decisions, finances — that persist across Claude, Cursor, ChatGPT, OpenClaw, IronClaw, and every agent you run. Open-source. Local-first. Deterministic. MIT licensed.
|
|
6
6
|
|
|
7
7
|
**[neotoma.io](https://neotoma.io)** · **[Evaluate](https://neotoma.io/evaluate)** · **[Install](https://neotoma.io/install)** · **[Documentation](https://neotoma.io/docs)**
|
|
8
8
|
|
|
@@ -38,6 +38,7 @@ graph LR
|
|
|
38
38
|
MCP --> ChatGPT
|
|
39
39
|
MCP --> Cursor
|
|
40
40
|
MCP --> OpenClaw
|
|
41
|
+
MCP --> IronClaw
|
|
41
42
|
```
|
|
42
43
|
|
|
43
44
|
- **Deterministic.** Same observations always produce the same versioned entity snapshots. No ordering sensitivity.
|
|
@@ -51,7 +52,7 @@ graph LR
|
|
|
51
52
|
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
53
|
| **Privacy-first** | Your data stays local. Never used for training. User-controlled storage, optional encryption at rest. Full export and deletion control. |
|
|
53
54
|
| **Deterministic** | Same input always produces same output. Schema-first extraction, hash-based entity IDs, full provenance. No silent mutation. |
|
|
54
|
-
| **Cross-platform** | One memory graph across Claude, ChatGPT, Cursor, OpenClaw, Codex, and CLI. MCP-based access. No platform lock-in. Works alongside native memory. |
|
|
55
|
+
| **Cross-platform** | One memory graph across Claude, ChatGPT, Cursor, OpenClaw, IronClaw, Codex, and CLI. MCP-based access. No platform lock-in. Works alongside native memory. |
|
|
55
56
|
|
|
56
57
|
## State guarantees
|
|
57
58
|
|
|
@@ -121,14 +122,14 @@ Three interfaces. One state invariant. Every interface provides the same determi
|
|
|
121
122
|
| Interface | Description |
|
|
122
123
|
| -------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
123
124
|
| **REST API** | Full HTTP interface for application integration. Entities, relationships, observations, schema, timeline, and version history. |
|
|
124
|
-
| **MCP Server** | Model Context Protocol for Claude, ChatGPT, Cursor, OpenClaw, Codex, and more. Agents store and retrieve state through structured tool calls. |
|
|
125
|
+
| **MCP Server** | Model Context Protocol for Claude, ChatGPT, Cursor, OpenClaw, IronClaw, Codex, and more. Agents store and retrieve state through structured tool calls. |
|
|
125
126
|
| **CLI** | Command-line for scripting and direct access. Inspect entities, replay timelines, and manage state from the terminal. |
|
|
126
127
|
|
|
127
128
|
All three map to the same OpenAPI-backed operations. MCP tool calls log the equivalent CLI invocation.
|
|
128
129
|
|
|
129
130
|
## Who this is for
|
|
130
131
|
|
|
131
|
-
People building a personal operating system with AI agents across their life — wiring together tools like Claude, Cursor, ChatGPT, OpenClaw, and custom scripts to manage contacts, tasks, finances, code, content, and other domains. The same person operates their agents, builds new pipelines, and debugs state drift. These are three operational modes, not separate personas:
|
|
132
|
+
People building a personal operating system with AI agents across their life — wiring together tools like Claude, Cursor, ChatGPT, OpenClaw, IronClaw, and custom scripts to manage contacts, tasks, finances, code, content, and other domains. The same person operates their agents, builds new pipelines, and debugs state drift. These are three operational modes, not separate personas:
|
|
132
133
|
|
|
133
134
|
| Mode | What you're doing | The tax you pay without Neotoma | What you get back |
|
|
134
135
|
| ---- | ----------------- | ------------------------------- | ----------------- |
|
|
@@ -155,7 +156,7 @@ Schema is flexible — store any entity type with whatever fields the message im
|
|
|
155
156
|
|
|
156
157
|
## Current status
|
|
157
158
|
|
|
158
|
-
**Version:** v0.
|
|
159
|
+
**Version:** v0.9.1 · **Releases:** 26 · **License:** MIT
|
|
159
160
|
|
|
160
161
|
### What is guaranteed (even in preview)
|
|
161
162
|
|
|
@@ -188,6 +189,7 @@ Neotoma stores user data and requires secure configuration.
|
|
|
188
189
|
|
|
189
190
|
```bash
|
|
190
191
|
npm run dev # MCP server (stdio)
|
|
192
|
+
npm run dev:mcp:dev-shim # stable stdio shim for MCP source iteration
|
|
191
193
|
npm run dev:ui # Frontend
|
|
192
194
|
npm run dev:server # API only (MCP at /mcp)
|
|
193
195
|
npm run dev:full # API + UI + build watch
|
|
@@ -216,9 +218,11 @@ npm test
|
|
|
216
218
|
|
|
217
219
|
Neotoma exposes state via MCP. Local storage only in preview. Local built-in auth.
|
|
218
220
|
|
|
219
|
-
**Setup guides:** [Cursor](https://neotoma.io/neotoma-with-cursor) · [Claude Code](https://neotoma.io/neotoma-with-claude-code) · [Claude](https://neotoma.io/neotoma-with-claude) · [ChatGPT](https://neotoma.io/neotoma-with-chatgpt) · [Codex](https://neotoma.io/neotoma-with-codex) · [OpenClaw](https://neotoma.io/neotoma-with-openclaw)
|
|
221
|
+
**Setup guides:** [Cursor](https://neotoma.io/neotoma-with-cursor) · [Claude Code](https://neotoma.io/neotoma-with-claude-code) · [Claude](https://neotoma.io/neotoma-with-claude) · [ChatGPT](https://neotoma.io/neotoma-with-chatgpt) · [Codex](https://neotoma.io/neotoma-with-codex) · [OpenCode](docs/integrations/hooks/opencode.md) · [OpenClaw](https://neotoma.io/neotoma-with-openclaw) · [IronClaw](https://neotoma.io/neotoma-with-ironclaw)
|
|
220
222
|
|
|
221
|
-
|
|
223
|
+
For local source iteration, use the stable dev shim (`scripts/run_neotoma_mcp_stdio_dev_shim.sh` or `npm run dev:mcp:dev-shim`) instead of pointing installed MCP clients at a `tsx watch` stdio process. The shim keeps the client-facing JSON-RPC stream stable and asks clients to refresh or reconnect when the tool interface changes.
|
|
224
|
+
|
|
225
|
+
**Agent behavior contract:** Store first, retrieve before storing, extract entities from user input, create tasks for commitments, and attach bounded host context such as repository name/root scope when available. Full instructions: [MCP instructions](docs/developer/mcp/instructions.md) and [CLI agent instructions](docs/developer/cli_agent_instructions.md).
|
|
222
226
|
|
|
223
227
|
**Representative actions:** `store`, `retrieve_entities`, `retrieve_entity_snapshot`, `merge_entities`, `list_observations`, `create_relationship`, `list_relationships`, `list_timeline_events`, `retrieve_graph_neighborhood`. Full list: [MCP spec](docs/specs/MCP_SPEC.md).
|
|
224
228
|
|
package/dist/actions.d.ts
CHANGED
|
@@ -22,6 +22,14 @@ export declare function isLocalRequest(req: express.Request): boolean;
|
|
|
22
22
|
* a different authority. See src/middleware/aauth_verify.ts.
|
|
23
23
|
*/
|
|
24
24
|
export declare function canonicalAauthAuthority(): string;
|
|
25
|
+
type StoreRelationshipRef = {
|
|
26
|
+
relationship_type: string;
|
|
27
|
+
source_index?: number;
|
|
28
|
+
target_index?: number;
|
|
29
|
+
source_entity_id?: string;
|
|
30
|
+
target_entity_id?: string;
|
|
31
|
+
metadata?: Record<string, unknown>;
|
|
32
|
+
};
|
|
25
33
|
export declare function storeStructuredForApi(params: {
|
|
26
34
|
userId: string;
|
|
27
35
|
entities: Record<string, unknown>[];
|
|
@@ -29,11 +37,7 @@ export declare function storeStructuredForApi(params: {
|
|
|
29
37
|
observationSource?: import("./shared/action_schemas.js").ObservationSource;
|
|
30
38
|
idempotencyKey: string;
|
|
31
39
|
originalFilename?: string;
|
|
32
|
-
relationships?:
|
|
33
|
-
relationship_type: string;
|
|
34
|
-
source_index: number;
|
|
35
|
-
target_index: number;
|
|
36
|
-
}>;
|
|
40
|
+
relationships?: StoreRelationshipRef[];
|
|
37
41
|
commit?: boolean;
|
|
38
42
|
strict?: boolean;
|
|
39
43
|
}): Promise<{
|
|
@@ -92,4 +96,5 @@ export declare function startHTTPServer(): Promise<{
|
|
|
92
96
|
server: import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>;
|
|
93
97
|
port: number;
|
|
94
98
|
} | undefined>;
|
|
99
|
+
export {};
|
|
95
100
|
//# sourceMappingURL=actions.d.ts.map
|
package/dist/actions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAmK9B,eAAO,MAAM,GAAG,6CAAY,CAAC;AAif7B;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAU5D;AA4PD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAmBhD;AA4sHD,KAAK,oBAAoB,GAAG;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,CAAC;AAEF,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,4BAA4B,EAAE,iBAAiB,CAAC;IAC3E,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;;;;;;;;;;;;;cA+fS,MAAM;gBACJ,MAAM;2BACK,MAAM;qBACZ,MAAM;mBACR,MAAM;wBACD,MAAM;uBACP,MAAM;;;;;;;;;mBA3JV,MAAM;qBACJ,MAAM;wBACH,MAAM,GAAG,IAAI;2BACV,MAAM;;wBAET,MAAM;uBACP,MAAM,EAAE;wBACP,MAAM;uBACP,MAAM;;kBA9NX,MAAM;oBACJ,MAAM;yBACD,MAAM;4BACH,MAAM;2BACP,MAAM;;+BA4NF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;;;2BAkFlC,MAAM;0BACP,MAAM;0BACN,MAAM;;GA2F3B;AAuhED,wBAAsB,eAAe;;;eA2FpC"}
|
package/dist/actions.js
CHANGED
|
@@ -43,7 +43,7 @@ import { resolveSandboxReportTransport } from "./services/sandbox/transport.js";
|
|
|
43
43
|
import { getSqliteDb } from "./repositories/sqlite/sqlite_client.js";
|
|
44
44
|
import { getMcpAuthToken } from "./crypto/mcp_auth_token.js";
|
|
45
45
|
import { isOauthKeyCredentialValid, normalizeOauthNextPath, OAuthKeySessionStore, } from "./services/oauth_key_gate.js";
|
|
46
|
-
import { AnalyzeSchemaCandidatesRequestSchema, CorrectEntityRequestSchema, CreateRelationshipRequestSchema, DeleteEntityRequestSchema, DeleteRelationshipRequestSchema, EntitiesQueryRequestSchema, EntitySnapshotRequestSchema, FieldProvenanceRequestSchema, GetSchemaRecommendationsRequestSchema, ListObservationsRequestSchema, ListRelationshipsRequestSchema, MergeEntitiesRequestSchema, SplitEntityRequestSchema, ObservationsQueryRequestSchema, RegisterSchemaRequestSchema, RelationshipSnapshotRequestSchema, RestoreEntityRequestSchema, RestoreRelationshipRequestSchema, RetrieveEntityByIdentifierSchema, RetrieveGraphNeighborhoodSchema, RetrieveRelatedEntitiesSchema, StoreRequestSchema, StoreUnstructuredRequestSchema, UpdateSchemaIncrementalRequestSchema, } from "./shared/action_schemas.js";
|
|
46
|
+
import { AnalyzeSchemaCandidatesRequestSchema, CorrectEntityRequestSchema, CreateRelationshipsRequestSchema, CreateRelationshipRequestSchema, DeleteEntityRequestSchema, DeleteRelationshipRequestSchema, EntitiesQueryRequestSchema, EntitySnapshotRequestSchema, FieldProvenanceRequestSchema, GetSchemaRecommendationsRequestSchema, ListObservationsRequestSchema, ListRelationshipsRequestSchema, MergeEntitiesRequestSchema, SplitEntityRequestSchema, ObservationsQueryRequestSchema, RegisterSchemaRequestSchema, RelationshipSnapshotRequestSchema, RestoreEntityRequestSchema, RestoreRelationshipRequestSchema, RetrieveEntityByIdentifierSchema, RetrieveGraphNeighborhoodSchema, RetrieveRelatedEntitiesSchema, StoreRequestSchema, StoreUnstructuredRequestSchema, UpdateSchemaIncrementalRequestSchema, } from "./shared/action_schemas.js";
|
|
47
47
|
import { getMimeTypeFromExtension } from "./services/file_text_extraction.js";
|
|
48
48
|
import { queryEntitiesWithCount } from "./shared/action_handlers/entity_handlers.js";
|
|
49
49
|
import { retrieveEntityByIdentifierWithFallback } from "./shared/action_handlers/entity_identifier_handler.js";
|
|
@@ -51,8 +51,9 @@ import { prepareEntitySnapshotWithEmbedding, upsertEntitySnapshotWithEmbedding,
|
|
|
51
51
|
import { readOpenApiActionsFile, readOpenApiFile } from "./shared/openapi_file.js";
|
|
52
52
|
import { buildSmitheryServerCard } from "./mcp_server_card.js";
|
|
53
53
|
import { listRecentRecordActivity, parseRecordActivityTypesQuery, } from "./services/recent_record_activity.js";
|
|
54
|
-
import { listRecentConversations } from "./services/recent_conversations.js";
|
|
54
|
+
import { getRecentConversationById, listRecentConversations } from "./services/recent_conversations.js";
|
|
55
55
|
import { listConversationTurns, getConversationTurn, } from "./services/conversation_turn.js";
|
|
56
|
+
import { buildComplianceScorecard } from "./services/compliance/scorecard.js";
|
|
56
57
|
import { getAgent, listAgentRecords, listAgents } from "./services/agents_directory.js";
|
|
57
58
|
export const app = express();
|
|
58
59
|
// Trust proxy headers (required for express-rate-limit when X-Forwarded-For is present)
|
|
@@ -1688,21 +1689,38 @@ app.post("/mcp/oauth/token", oauthTokenLimit, express.urlencoded({ extended: tru
|
|
|
1688
1689
|
try {
|
|
1689
1690
|
const grant_type = req.body?.grant_type;
|
|
1690
1691
|
const code = req.body?.code;
|
|
1692
|
+
const refresh_token = req.body?.refresh_token;
|
|
1691
1693
|
logger.info("[MCP OAuth] Token request received", {
|
|
1692
1694
|
grant_type: grant_type ?? null,
|
|
1693
1695
|
has_code: typeof code === "string" && code.length > 0,
|
|
1694
1696
|
code_hint: typeof code === "string" ? code.slice(0, 8) : null,
|
|
1697
|
+
has_refresh_token: typeof refresh_token === "string" && refresh_token.length > 0,
|
|
1695
1698
|
host: req.header("host") ?? null,
|
|
1696
1699
|
});
|
|
1697
|
-
if (grant_type !== "authorization_code") {
|
|
1700
|
+
if (grant_type !== "authorization_code" && grant_type !== "refresh_token") {
|
|
1698
1701
|
logger.warn("[MCP OAuth] Token rejected: unsupported grant_type", {
|
|
1699
1702
|
grant_type: grant_type ?? null,
|
|
1700
1703
|
});
|
|
1701
1704
|
return res.status(400).json({
|
|
1702
1705
|
error: "unsupported_grant_type",
|
|
1703
|
-
error_description: "Only authorization_code
|
|
1706
|
+
error_description: "Only authorization_code and refresh_token are supported",
|
|
1704
1707
|
});
|
|
1705
1708
|
}
|
|
1709
|
+
if (grant_type === "refresh_token") {
|
|
1710
|
+
if (!refresh_token || typeof refresh_token !== "string") {
|
|
1711
|
+
logger.warn("[MCP OAuth] Token refresh rejected: missing refresh_token");
|
|
1712
|
+
return res
|
|
1713
|
+
.status(400)
|
|
1714
|
+
.json({ error: "invalid_request", error_description: "refresh_token is required" });
|
|
1715
|
+
}
|
|
1716
|
+
const { refreshAccessToken } = await import("./services/mcp_oauth.js");
|
|
1717
|
+
const token = await refreshAccessToken(refresh_token);
|
|
1718
|
+
logger.info("[MCP OAuth] Token refreshed", {
|
|
1719
|
+
has_refresh_token: Boolean(token.refresh_token),
|
|
1720
|
+
});
|
|
1721
|
+
res.setHeader("Content-Type", "application/json");
|
|
1722
|
+
return res.json(token);
|
|
1723
|
+
}
|
|
1706
1724
|
if (!code || typeof code !== "string") {
|
|
1707
1725
|
logger.warn("[MCP OAuth] Token rejected: missing code");
|
|
1708
1726
|
return res
|
|
@@ -3271,6 +3289,21 @@ app.get("/agents/:key/records", async (req, res) => {
|
|
|
3271
3289
|
return handleApiError(req, res, error, "Failed to list agent records", "DB_QUERY_FAILED", "APIError:agents_records");
|
|
3272
3290
|
}
|
|
3273
3291
|
});
|
|
3292
|
+
// GET /recent_conversations/:conversation_id — Inspector: one conversation with nested messages
|
|
3293
|
+
app.get("/recent_conversations/:conversation_id", async (req, res) => {
|
|
3294
|
+
try {
|
|
3295
|
+
const userId = await getAuthenticatedUserId(req, req.query.user_id);
|
|
3296
|
+
const conversationId = String(req.params.conversation_id ?? "").trim();
|
|
3297
|
+
const item = getRecentConversationById(userId, conversationId);
|
|
3298
|
+
if (!item) {
|
|
3299
|
+
return sendError(res, 404, "RESOURCE_NOT_FOUND", "Conversation not found");
|
|
3300
|
+
}
|
|
3301
|
+
return res.json(item);
|
|
3302
|
+
}
|
|
3303
|
+
catch (error) {
|
|
3304
|
+
return handleApiError(req, res, error, "Failed to load conversation", "DB_QUERY_FAILED", "APIError:recent_conversation_detail");
|
|
3305
|
+
}
|
|
3306
|
+
});
|
|
3274
3307
|
// GET /recent_conversations — Inspector: conversations with nested messages (SQLite)
|
|
3275
3308
|
app.get("/recent_conversations", async (req, res) => {
|
|
3276
3309
|
try {
|
|
@@ -3279,7 +3312,9 @@ app.get("/recent_conversations", async (req, res) => {
|
|
|
3279
3312
|
const offset = parseInt(String(req.query.offset ?? "0"), 10) || 0;
|
|
3280
3313
|
const activity_after = typeof req.query.activity_after === "string" ? req.query.activity_after.trim() || null : null;
|
|
3281
3314
|
const activity_before = typeof req.query.activity_before === "string" ? req.query.activity_before.trim() || null : null;
|
|
3282
|
-
const
|
|
3315
|
+
const agentKeyRaw = typeof req.query.agent_key === "string" ? req.query.agent_key.trim() : "";
|
|
3316
|
+
// UI and bookmarks may send agent_key=all; never treat that as a real deriveAgentKey value.
|
|
3317
|
+
const agent_key = agentKeyRaw.length > 0 && agentKeyRaw.toLowerCase() !== "all" ? agentKeyRaw : null;
|
|
3283
3318
|
const result = listRecentConversations(userId, limit, offset, {
|
|
3284
3319
|
activity_after,
|
|
3285
3320
|
activity_before,
|
|
@@ -3328,6 +3363,32 @@ app.get("/turns/:turn_key", async (req, res) => {
|
|
|
3328
3363
|
return handleApiError(req, res, error, "Failed to get turn", "DB_QUERY_FAILED", "APIError:turn_detail");
|
|
3329
3364
|
}
|
|
3330
3365
|
});
|
|
3366
|
+
// GET /admin/compliance/scorecard — Inspector: aggregated hook compliance (SQLite)
|
|
3367
|
+
app.get("/admin/compliance/scorecard", async (req, res) => {
|
|
3368
|
+
try {
|
|
3369
|
+
const userId = await getAuthenticatedUserId(req, req.query.user_id);
|
|
3370
|
+
const since = typeof req.query.since === "string" ? req.query.since : undefined;
|
|
3371
|
+
const until = typeof req.query.until === "string" ? req.query.until : undefined;
|
|
3372
|
+
const group_by = typeof req.query.group_by === "string" ? req.query.group_by : undefined;
|
|
3373
|
+
const min_turns = parseInt(String(req.query.min_turns ?? ""), 10);
|
|
3374
|
+
const min_backfill_rate = parseFloat(String(req.query.min_backfill_rate ?? ""));
|
|
3375
|
+
const top_missed_steps = parseInt(String(req.query.top_missed_steps ?? ""), 10);
|
|
3376
|
+
const include_synthetic = req.query.include_synthetic === "1" || String(req.query.include_synthetic).toLowerCase() === "true";
|
|
3377
|
+
const result = buildComplianceScorecard(userId, {
|
|
3378
|
+
since,
|
|
3379
|
+
until,
|
|
3380
|
+
group_by,
|
|
3381
|
+
min_turns: Number.isFinite(min_turns) ? min_turns : undefined,
|
|
3382
|
+
min_backfill_rate: Number.isFinite(min_backfill_rate) ? min_backfill_rate : undefined,
|
|
3383
|
+
top_missed_steps: Number.isFinite(top_missed_steps) ? top_missed_steps : undefined,
|
|
3384
|
+
include_synthetic,
|
|
3385
|
+
});
|
|
3386
|
+
return res.json(result);
|
|
3387
|
+
}
|
|
3388
|
+
catch (error) {
|
|
3389
|
+
return handleApiError(req, res, error, "Failed to build compliance scorecard", "DB_QUERY_FAILED", "APIError:compliance_scorecard");
|
|
3390
|
+
}
|
|
3391
|
+
});
|
|
3331
3392
|
// GET /api/sources - Get source list (FU-301)
|
|
3332
3393
|
app.get("/sources", async (req, res) => {
|
|
3333
3394
|
try {
|
|
@@ -4185,30 +4246,41 @@ export async function storeStructuredForApi(params) {
|
|
|
4185
4246
|
if (commit && relationships && relationships.length > 0) {
|
|
4186
4247
|
const { relationshipsService } = await import("./services/relationships.js");
|
|
4187
4248
|
for (const rel of relationships) {
|
|
4188
|
-
const
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4249
|
+
const sourceEntityId = typeof rel.source_entity_id === "string"
|
|
4250
|
+
? rel.source_entity_id
|
|
4251
|
+
: typeof rel.source_index === "number"
|
|
4252
|
+
? resolved[rel.source_index]?.entity_id
|
|
4253
|
+
: undefined;
|
|
4254
|
+
const targetEntityId = typeof rel.target_entity_id === "string"
|
|
4255
|
+
? rel.target_entity_id
|
|
4256
|
+
: typeof rel.target_index === "number"
|
|
4257
|
+
? resolved[rel.target_index]?.entity_id
|
|
4258
|
+
: undefined;
|
|
4259
|
+
if (!sourceEntityId || !targetEntityId) {
|
|
4260
|
+
logger.warn(`[STORE] Skipping relationship: invalid source reference ` +
|
|
4261
|
+
`(source_index=${rel.source_index}, source_entity_id=${rel.source_entity_id}) ` +
|
|
4262
|
+
`or target reference (target_index=${rel.target_index}, ` +
|
|
4263
|
+
`target_entity_id=${rel.target_entity_id}); have ${resolved.length} entities.`);
|
|
4193
4264
|
continue;
|
|
4194
4265
|
}
|
|
4195
4266
|
try {
|
|
4196
4267
|
await relationshipsService.createRelationship({
|
|
4197
|
-
source_entity_id:
|
|
4198
|
-
target_entity_id:
|
|
4268
|
+
source_entity_id: sourceEntityId,
|
|
4269
|
+
target_entity_id: targetEntityId,
|
|
4199
4270
|
relationship_type: rel.relationship_type,
|
|
4200
4271
|
source_id: storageResult.sourceId,
|
|
4272
|
+
metadata: rel.metadata ?? {},
|
|
4201
4273
|
user_id: userId,
|
|
4202
4274
|
});
|
|
4203
4275
|
relationshipsCreated.push({
|
|
4204
4276
|
relationship_type: rel.relationship_type,
|
|
4205
|
-
source_entity_id:
|
|
4206
|
-
target_entity_id:
|
|
4277
|
+
source_entity_id: sourceEntityId,
|
|
4278
|
+
target_entity_id: targetEntityId,
|
|
4207
4279
|
});
|
|
4208
4280
|
}
|
|
4209
4281
|
catch (relErr) {
|
|
4210
4282
|
logger.warn(`Failed to create relationship ${rel.relationship_type} ` +
|
|
4211
|
-
`${
|
|
4283
|
+
`${sourceEntityId} -> ${targetEntityId}: ${relErr instanceof Error ? relErr.message : String(relErr)}`);
|
|
4212
4284
|
}
|
|
4213
4285
|
}
|
|
4214
4286
|
}
|
|
@@ -4776,6 +4848,63 @@ app.post("/create_relationship", async (req, res) => {
|
|
|
4776
4848
|
return sendError(res, 500, "DB_QUERY_FAILED", error instanceof Error ? error.message : "Failed to create relationship");
|
|
4777
4849
|
}
|
|
4778
4850
|
});
|
|
4851
|
+
// Create relationships in batch
|
|
4852
|
+
app.post("/create_relationships", async (req, res) => {
|
|
4853
|
+
const parsed = CreateRelationshipsRequestSchema.safeParse(req.body);
|
|
4854
|
+
if (!parsed.success) {
|
|
4855
|
+
logWarn("ValidationError:create_relationships", req, {
|
|
4856
|
+
issues: parsed.error.issues,
|
|
4857
|
+
});
|
|
4858
|
+
return sendValidationError(res, parsed.error.issues);
|
|
4859
|
+
}
|
|
4860
|
+
const { relationships, source_id, user_id } = parsed.data;
|
|
4861
|
+
const { relationshipsService } = await import("./services/relationships.js");
|
|
4862
|
+
try {
|
|
4863
|
+
const userId = await getAuthenticatedUserId(req, user_id);
|
|
4864
|
+
const created = [];
|
|
4865
|
+
const errors = [];
|
|
4866
|
+
for (const [index, relationship] of relationships.entries()) {
|
|
4867
|
+
try {
|
|
4868
|
+
const snapshot = await relationshipsService.createRelationship({
|
|
4869
|
+
relationship_type: relationship.relationship_type,
|
|
4870
|
+
source_entity_id: relationship.source_entity_id,
|
|
4871
|
+
target_entity_id: relationship.target_entity_id,
|
|
4872
|
+
source_id: relationship.source_id || source_id || null,
|
|
4873
|
+
metadata: relationship.metadata || {},
|
|
4874
|
+
user_id: userId,
|
|
4875
|
+
});
|
|
4876
|
+
created.push({
|
|
4877
|
+
index,
|
|
4878
|
+
...snapshot,
|
|
4879
|
+
});
|
|
4880
|
+
}
|
|
4881
|
+
catch (error) {
|
|
4882
|
+
errors.push({
|
|
4883
|
+
index,
|
|
4884
|
+
relationship,
|
|
4885
|
+
error: error instanceof Error ? error.message : String(error),
|
|
4886
|
+
});
|
|
4887
|
+
}
|
|
4888
|
+
}
|
|
4889
|
+
logDebug("Success:create_relationships", req, {
|
|
4890
|
+
requested: relationships.length,
|
|
4891
|
+
created: created.length,
|
|
4892
|
+
errors: errors.length,
|
|
4893
|
+
});
|
|
4894
|
+
return res.json({
|
|
4895
|
+
success: errors.length === 0,
|
|
4896
|
+
requested: relationships.length,
|
|
4897
|
+
created_count: created.length,
|
|
4898
|
+
error_count: errors.length,
|
|
4899
|
+
relationships: created,
|
|
4900
|
+
errors,
|
|
4901
|
+
});
|
|
4902
|
+
}
|
|
4903
|
+
catch (error) {
|
|
4904
|
+
logError("RelationshipCreationError:create_relationships", req, error);
|
|
4905
|
+
return sendError(res, 500, "DB_QUERY_FAILED", error instanceof Error ? error.message : "Failed to create relationships");
|
|
4906
|
+
}
|
|
4907
|
+
});
|
|
4779
4908
|
// List relationships
|
|
4780
4909
|
app.post("/list_relationships", async (req, res) => {
|
|
4781
4910
|
const parsed = ListRelationshipsRequestSchema.safeParse(req.body);
|