neotoma 0.4.0 → 0.4.1

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.
Files changed (37) hide show
  1. package/README.md +1 -1
  2. package/dist/actions.d.ts +1 -4
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +37 -4
  5. package/dist/actions.js.map +1 -1
  6. package/dist/cli/config.d.ts +9 -9
  7. package/dist/cli/config.d.ts.map +1 -1
  8. package/dist/cli/index.d.ts +2 -1
  9. package/dist/cli/index.d.ts.map +1 -1
  10. package/dist/cli/index.js +210 -1
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/config.d.ts +18 -18
  13. package/dist/server.d.ts +1 -0
  14. package/dist/server.d.ts.map +1 -1
  15. package/dist/server.js +47 -2
  16. package/dist/server.js.map +1 -1
  17. package/dist/services/entity_queries.d.ts +3 -3
  18. package/dist/services/entity_queries.d.ts.map +1 -1
  19. package/dist/services/mcp_oauth_errors.d.ts +2 -2
  20. package/dist/services/mcp_oauth_errors.d.ts.map +1 -1
  21. package/dist/services/raw_storage.d.ts +1 -1
  22. package/dist/services/raw_storage.d.ts.map +1 -1
  23. package/dist/shared/action_schemas.d.ts +29 -762
  24. package/dist/shared/action_schemas.d.ts.map +1 -1
  25. package/dist/shared/action_schemas.js +1 -0
  26. package/dist/shared/action_schemas.js.map +1 -1
  27. package/dist/shared/api_client.d.ts +1 -14
  28. package/dist/shared/api_client.d.ts.map +1 -1
  29. package/dist/shared/contract_mappings.d.ts.map +1 -1
  30. package/dist/shared/contract_mappings.js +1 -0
  31. package/dist/shared/contract_mappings.js.map +1 -1
  32. package/dist/shared/openapi_types.d.ts +379 -7
  33. package/dist/shared/openapi_types.d.ts.map +1 -1
  34. package/dist/utils/lucide_icons.d.ts +1 -1
  35. package/dist/utils/lucide_icons.d.ts.map +1 -1
  36. package/openapi.yaml +20 -0
  37. package/package.json +5 -3
package/README.md CHANGED
@@ -256,7 +256,7 @@ Full documentation is organized at [neotoma.io/docs](https://neotoma.io/docs) an
256
256
 
257
257
  **Foundational:** [Core identity](docs/foundation/core_identity.md), [Philosophy](docs/foundation/philosophy.md), [Problem statement](docs/foundation/problem_statement.md)
258
258
 
259
- **Operations:** [Runbook](docs/operations/runbook.md), [Health check](docs/operations/health_check.md) (`npm run doctor`), [Troubleshooting](https://neotoma.io/troubleshooting)
259
+ **Operations:** [Runbook](docs/operations/runbook.md), [Health check](docs/operations/health_check.md) (`npm run doctor`), SQLite salvage (`neotoma storage recover-db`, `npm run recover:db`, `npm run recover:db:prod`), [Troubleshooting](https://neotoma.io/troubleshooting)
260
260
 
261
261
  ## Contributing
262
262
 
package/dist/actions.d.ts CHANGED
@@ -2,8 +2,5 @@ import express from "express";
2
2
  export declare const app: any;
3
3
  /** True when request is to localhost/127.0.0.1 (local access). Tunnel requests have a non-local Host. */
4
4
  export declare function isLocalRequest(req: express.Request): boolean;
5
- export declare function startHTTPServer(): Promise<{
6
- server: any;
7
- port: number;
8
- } | undefined>;
5
+ export declare function startHTTPServer(): unknown;
9
6
  //# sourceMappingURL=actions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AA8E9B,eAAO,MAAM,GAAG,KAAY,CAAC;AAwL7B,yGAAyG;AACzG,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAK5D;AAk5ID,wBAAsB,eAAe;;;eAgCpC"}
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AA8E9B,eAAO,MAAM,GAAG,KAAY,CAAC;AAwL7B,yGAAyG;AACzG,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAK5D;AAw7ID,wBAAsB,eAAe,YAgCpC"}
package/dist/actions.js CHANGED
@@ -1599,7 +1599,8 @@ app.get("/entities/:id", async (req, res) => {
1599
1599
  if (!entityWithProvenance) {
1600
1600
  return sendError(res, 404, "RESOURCE_NOT_FOUND", "Entity not found");
1601
1601
  }
1602
- return res.json({ entity: entityWithProvenance });
1602
+ // OpenAPI + clients expect `EntitySnapshot` at the root (not `{ entity: ... }`).
1603
+ return res.json(entityWithProvenance);
1603
1604
  }
1604
1605
  catch (error) {
1605
1606
  if (error instanceof Error && error.message.includes("Not authenticated")) {
@@ -2032,6 +2033,10 @@ app.get("/timeline", async (req, res) => {
2032
2033
  const entityId = req.query.entity_id;
2033
2034
  const limit = parseInt(req.query.limit) || 100;
2034
2035
  const offset = parseInt(req.query.offset) || 0;
2036
+ const rawOrderBy = String(req.query.order_by ?? "event_timestamp")
2037
+ .trim()
2038
+ .toLowerCase();
2039
+ const orderByColumn = rawOrderBy === "created_at" ? "created_at" : "event_timestamp";
2035
2040
  // Get source IDs for this user first (timeline_events doesn't have user_id)
2036
2041
  const { data: userSources, error: sourcesError } = await db
2037
2042
  .from("sources")
@@ -2070,8 +2075,8 @@ app.get("/timeline", async (req, res) => {
2070
2075
  if (entityId) {
2071
2076
  query = query.eq("entity_id", entityId);
2072
2077
  }
2073
- // Sort by event timestamp (chronological)
2074
- query = query.order("event_timestamp", { ascending: false });
2078
+ // Default: sort by event_timestamp (document dates). Use order_by=created_at for "what changed recently".
2079
+ query = query.order(orderByColumn, { ascending: false });
2075
2080
  // Pagination
2076
2081
  query = query.range(offset, offset + limit - 1);
2077
2082
  const { data, error, count } = await query;
@@ -2096,8 +2101,36 @@ app.get("/timeline", async (req, res) => {
2096
2101
  hint: errorHint,
2097
2102
  });
2098
2103
  }
2104
+ // Enrich events with entity canonical names and types
2105
+ const events = data || [];
2106
+ const entityIds = [
2107
+ ...new Set(events.map((e) => e.entity_id).filter(Boolean)),
2108
+ ];
2109
+ const entityLookup = new Map();
2110
+ if (entityIds.length > 0) {
2111
+ const { data: entities } = await db
2112
+ .from("entities")
2113
+ .select("id, canonical_name, entity_type")
2114
+ .in("id", entityIds);
2115
+ if (entities) {
2116
+ for (const ent of entities) {
2117
+ entityLookup.set(ent.id, {
2118
+ canonical_name: ent.canonical_name,
2119
+ entity_type: ent.entity_type,
2120
+ });
2121
+ }
2122
+ }
2123
+ }
2124
+ const enrichedEvents = events.map((ev) => {
2125
+ const entity = ev.entity_id ? entityLookup.get(ev.entity_id) : undefined;
2126
+ return {
2127
+ ...ev,
2128
+ entity_name: entity?.canonical_name || undefined,
2129
+ entity_type: entity?.entity_type || undefined,
2130
+ };
2131
+ });
2099
2132
  return res.json({
2100
- events: data || [],
2133
+ events: enrichedEvents,
2101
2134
  total: count || 0,
2102
2135
  limit,
2103
2136
  offset,