json-object-editor 0.10.508 → 0.10.520
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/CHANGELOG.md +33 -0
- package/_www/mcp-export.html +7 -1
- package/_www/mcp-nav.js +1 -0
- package/_www/mcp-prompt.html +97 -124
- package/_www/mcp-schemas.html +294 -0
- package/_www/mcp-test.html +70 -0
- package/docs/JOE_Master_Knowledge_Export.md +135 -0
- package/docs/joe_agent_custom_gpt_instructions_v_2.md +54 -0
- package/docs/joe_agent_spec_v_2.2.md +64 -0
- package/docs/schema_summary_guidelines.md +128 -0
- package/package.json +2 -1
- package/server/modules/MCP.js +532 -405
- package/server/modules/Schemas.js +321 -111
- package/server/modules/Server.js +25 -14
- package/server/relationships.graph.json +5 -0
- package/server/schemas/block.js +37 -0
- package/server/schemas/board.js +2 -1
- package/server/schemas/budget.js +28 -1
- package/server/schemas/event.js +42 -0
- package/server/schemas/financial_account.js +35 -0
- package/server/schemas/goal.js +30 -0
- package/server/schemas/group.js +31 -0
- package/server/schemas/include.js +28 -0
- package/server/schemas/ingredient.js +28 -0
- package/server/schemas/initiative.js +32 -0
- package/server/schemas/instance.js +31 -1
- package/server/schemas/layout.js +31 -0
- package/server/schemas/ledger.js +30 -0
- package/server/schemas/list.js +33 -0
- package/server/schemas/meal.js +30 -0
- package/server/schemas/note.js +30 -0
- package/server/schemas/notification.js +33 -1
- package/server/schemas/page.js +43 -0
- package/server/schemas/post.js +32 -0
- package/server/schemas/project.js +36 -0
- package/server/schemas/recipe.js +32 -0
- package/server/schemas/report.js +32 -0
- package/server/schemas/setting.js +22 -0
- package/server/schemas/site.js +30 -0
- package/server/schemas/status.js +33 -0
- package/server/schemas/tag.js +28 -1
- package/server/schemas/task.js +778 -737
- package/server/schemas/transaction.js +43 -0
- package/server/schemas/user.js +36 -1
- package/server/schemas/workflow.js +30 -1
package/_www/mcp-test.html
CHANGED
|
@@ -38,6 +38,12 @@
|
|
|
38
38
|
<div class="preset">
|
|
39
39
|
<button id="presetFuzzyUser">fuzzySearch users: q="corey hadden"</button>
|
|
40
40
|
<button id="presetFuzzyHouse">fuzzySearch houses: q="backyard"</button>
|
|
41
|
+
<button id="presetListApps">listApps: all app definitions</button>
|
|
42
|
+
<button id="presetGetSchemas">getSchemas: ["client","user"]</button>
|
|
43
|
+
<button id="presetGetSchemasSummary">getSchemas (summaryOnly): ["task","project"]</button>
|
|
44
|
+
<button id="presetSearchSlimRecent">search clients (slim, recent)</button>
|
|
45
|
+
<button id="presetSearchWithCount">search clients (withCount)</button>
|
|
46
|
+
<button id="presetSearchCountOnly">search clients (countOnly)</button>
|
|
41
47
|
</div>
|
|
42
48
|
|
|
43
49
|
<h3>Call JSON-RPC</h3>
|
|
@@ -63,12 +69,29 @@
|
|
|
63
69
|
const result = $('result');
|
|
64
70
|
const presetFuzzyUser = $('presetFuzzyUser');
|
|
65
71
|
const presetFuzzyHouse = $('presetFuzzyHouse');
|
|
72
|
+
const presetListApps = $('presetListApps');
|
|
73
|
+
const presetGetSchemas = $('presetGetSchemas');
|
|
74
|
+
const presetGetSchemasSummary = $('presetGetSchemasSummary');
|
|
75
|
+
const presetSearchSlimRecent = $('presetSearchSlimRecent');
|
|
76
|
+
const presetSearchWithCount = $('presetSearchWithCount');
|
|
77
|
+
const presetSearchCountOnly = $('presetSearchCountOnly');
|
|
66
78
|
|
|
67
79
|
// Try to infer base from window location
|
|
68
80
|
base.value = base.value || (location.origin);
|
|
69
81
|
|
|
70
82
|
let manifest = null;
|
|
71
83
|
let idCounter = 1;
|
|
84
|
+
|
|
85
|
+
function ensureTool(name, meta){
|
|
86
|
+
if (!manifest) { manifest = { tools: [] }; }
|
|
87
|
+
manifest.tools = manifest.tools || [];
|
|
88
|
+
var existing = (manifest.tools||[]).find(function(t){ return t && t.name === name; });
|
|
89
|
+
if (!existing && meta) { manifest.tools.push(meta); }
|
|
90
|
+
// ensure option exists in select
|
|
91
|
+
var hasOpt = false;
|
|
92
|
+
for (var i=0;i<toolSel.options.length;i++){ if (toolSel.options[i].value === name) { hasOpt = true; break; } }
|
|
93
|
+
if (!hasOpt){ var opt=document.createElement('option'); opt.value=name; opt.textContent=name; toolSel.appendChild(opt); }
|
|
94
|
+
}
|
|
72
95
|
|
|
73
96
|
function setStatus(el, msg, ok){
|
|
74
97
|
el.textContent = msg || '';
|
|
@@ -133,6 +156,53 @@
|
|
|
133
156
|
renderToolInfo();
|
|
134
157
|
params.value = JSON.stringify({ q: 'backyard', filters: { itemtype: 'house' }, threshold: 0.5 }, null, 2);
|
|
135
158
|
};
|
|
159
|
+
presetListApps.onclick = function(){
|
|
160
|
+
toolSel.value = 'listApps';
|
|
161
|
+
renderToolInfo();
|
|
162
|
+
params.value = JSON.stringify({}, null, 2);
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
presetGetSchemas.onclick = function(){
|
|
166
|
+
ensureTool('getSchemas', {
|
|
167
|
+
name: 'getSchemas',
|
|
168
|
+
description: 'Retrieve multiple schema definitions. If omitted, returns all.',
|
|
169
|
+
params: { type: 'object', properties: { names: { type: 'array', items: { type: 'string' } } } },
|
|
170
|
+
returns: { type: 'object' }
|
|
171
|
+
});
|
|
172
|
+
toolSel.value = 'getSchemas';
|
|
173
|
+
renderToolInfo();
|
|
174
|
+
params.value = JSON.stringify({ names: ["client", "user"] }, null, 2);
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
presetGetSchemasSummary.onclick = function(){
|
|
178
|
+
ensureTool('getSchemas', {
|
|
179
|
+
name: 'getSchemas',
|
|
180
|
+
description: 'Retrieve multiple schemas. With summaryOnly=true, returns summaries; if names omitted, returns all.',
|
|
181
|
+
params: { type: 'object', properties: { names: { type: 'array', items: { type: 'string' } }, summaryOnly: { type: 'boolean' } } },
|
|
182
|
+
returns: { type: 'object' }
|
|
183
|
+
});
|
|
184
|
+
toolSel.value = 'getSchemas';
|
|
185
|
+
renderToolInfo();
|
|
186
|
+
params.value = JSON.stringify({ names: ["task", "project"], summaryOnly: true }, null, 2);
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
presetSearchSlimRecent.onclick = function(){
|
|
190
|
+
toolSel.value = 'search';
|
|
191
|
+
renderToolInfo();
|
|
192
|
+
params.value = JSON.stringify({ schema: 'client', source: 'cache', query: { itemtype: 'client' }, limit: 25, sortBy: 'joeUpdated', sortDir: 'desc', slim: true }, null, 2);
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
presetSearchWithCount.onclick = function(){
|
|
196
|
+
toolSel.value = 'search';
|
|
197
|
+
renderToolInfo();
|
|
198
|
+
params.value = JSON.stringify({ schema: 'client', source: 'cache', query: { itemtype: 'client' }, limit: 25, withCount: true, sortBy: 'joeUpdated', sortDir: 'desc' }, null, 2);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
presetSearchCountOnly.onclick = function(){
|
|
202
|
+
toolSel.value = 'search';
|
|
203
|
+
renderToolInfo();
|
|
204
|
+
params.value = JSON.stringify({ schema: 'client', source: 'cache', query: { itemtype: 'client' }, countOnly: true }, null, 2);
|
|
205
|
+
};
|
|
136
206
|
|
|
137
207
|
callBtn.onclick = async function(){
|
|
138
208
|
setStatus(callStatus, 'Calling...', null);
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# JOE (Json Object Editor) — Master Knowledge
|
|
2
|
+
Last updated: Oct 2025
|
|
3
|
+
|
|
4
|
+
## What is JOE?
|
|
5
|
+
JOE is a schema‑first, lightweight, extensible admin platform and data workbench. It manages structured objects via dynamic, schema‑driven forms and list views.
|
|
6
|
+
|
|
7
|
+
- Server/Platform mode: Node.js app with storage backends, cache, plugins, apps, web UI, and MCP tools for agents.
|
|
8
|
+
- Client‑only mode: Embed `JsonObjectEditor` to render/edit objects in‑page using schemas.
|
|
9
|
+
|
|
10
|
+
## Purpose and who it's for
|
|
11
|
+
- JOE turns whatever your organization does into living JSON objects with relationships and history. If it can be described, it can be represented and managed in JOE.
|
|
12
|
+
- For any org size or type: businesses, non‑profits, churches, families, clubs, and projects.
|
|
13
|
+
- Use JOE to:
|
|
14
|
+
- Model your domain (schemas) and manage data with zero/low code
|
|
15
|
+
- Operate with lists, dashboards, statuses, tags, and reports
|
|
16
|
+
- Coordinate across teams via curated apps per use‑case
|
|
17
|
+
- Empower agents (via MCP) to search, reconcile, and update data safely
|
|
18
|
+
- Benefits: rapid time‑to‑value, consistent UI/flows, single source of truth, clean audit history, and agent‑friendly APIs.
|
|
19
|
+
|
|
20
|
+
## Where JOE fits (when to use vs not)
|
|
21
|
+
- Use JOE when you need:
|
|
22
|
+
- Schema‑first CRUD/admin surfaces with evolving data models
|
|
23
|
+
- Unified views over multiple datasets with fast cache reads
|
|
24
|
+
- Lightweight workflows (statuses/tags), reports, and agent tooling
|
|
25
|
+
- Not a great fit when you need:
|
|
26
|
+
- Heavy bespoke transactional systems requiring complex ACID workflows
|
|
27
|
+
- Offline‑first mobile or hard real‑time (sub‑ms) constraints
|
|
28
|
+
- Highly specialized UIs better served by purpose‑built apps (you can still use JOE as the data/admin layer)
|
|
29
|
+
|
|
30
|
+
## Core principles
|
|
31
|
+
- Schema‑first: behavior and UI flow derive from schemas.
|
|
32
|
+
- Separation of concerns: schemas define data and rules; UI renders dynamically.
|
|
33
|
+
- Minimal overhead: lean client rendering, unified server APIs, cache‑first reads.
|
|
34
|
+
- Extensibility: apps, plugins, and instance schemas compose capabilities.
|
|
35
|
+
- Single‑object overlay: focused edit/view with list/detail navigation.
|
|
36
|
+
|
|
37
|
+
## Mental model
|
|
38
|
+
- Objects conform to schemas; schemas define fields, validation, menus, filters, events.
|
|
39
|
+
- Reads prefer cache for speed; writes go through storage for durability.
|
|
40
|
+
- `saveObject` emits events (create/save/status/delete), writes history, and broadcasts via sockets.
|
|
41
|
+
- Universal shorthand `$J` exists on server and client for quick access.
|
|
42
|
+
|
|
43
|
+
## System overview
|
|
44
|
+
- Global `JOE` (from `server/init.js`) exposes:
|
|
45
|
+
- `JOE.Utils`, `JOE.Schemas`, `JOE.Storage`, `JOE.Cache`, `JOE.Apps`, `JOE.Server` (Express), `JOE.Sites`, `JOE.io` (Socket), `JOE.Mongo`/`JOE.MySQL`, `JOE.auth`.
|
|
46
|
+
- Hot‑reload module pattern: modules may export `init()` and are watched/reloaded.
|
|
47
|
+
- Instance directories:
|
|
48
|
+
- `_schemas`: schema definitions loaded by `JOE.Schemas`
|
|
49
|
+
- `_apps`: app definitions (collections, dashboards, UX)
|
|
50
|
+
- `_plugins`: backend features (auth, forms, reports, calendar, etc.)
|
|
51
|
+
- `_templates`: templates/layouts; `_datasets`: seed/aux data; `_files`: uploads; `_www`: static (includes MCP pages)
|
|
52
|
+
- Shorthand `$J`: `$J.get(_id[, schema])`, `$J.search(query)`, `$J.schema(name)`.
|
|
53
|
+
|
|
54
|
+
## Apps (the use‑case layer)
|
|
55
|
+
Apps are the layer between core JOE and an instance’s additional schemas. They curate the right data surfaces and UI for a use case by:
|
|
56
|
+
|
|
57
|
+
- Selecting relevant collections (schemas) for the app’s domain
|
|
58
|
+
- Defining dashboards, cards, reports, and default filters/subsets
|
|
59
|
+
- Wiring applicable plugins and lightweight workflows
|
|
60
|
+
|
|
61
|
+
Think of apps as scoped workspaces: they present a coherent subset of “everything JOE can do” plus instance‑specific schemas and UI that match the task at hand. Agents can use apps conceptually to understand a domain’s surface area without needing every schema in the instance.
|
|
62
|
+
|
|
63
|
+
## Schemas and fields (high‑level)
|
|
64
|
+
- Schema keys: `title`, `fields` (visible), `_listID`, `_listTitle`, menus, filters, events, optional `tableView`.
|
|
65
|
+
- Field properties: `label`, `type`, `value/default`, `hidden`, `locked`, `condition`, `width`, `tooltip`, `comment`, plus type‑specific props.
|
|
66
|
+
- Common field types: `text`, `number`, `int`, `select`, `boolean`, `date`, `geo`, `image`, `objectlist`, `objectReference`, `content`, `rendering`, `code`, `button`.
|
|
67
|
+
- Page helpers: `section_start/_label/_end`, `sidebar_start/_label/_end`.
|
|
68
|
+
- Events: schema‑level on `create`, `save`, `status`, `delete`.
|
|
69
|
+
- Statuses/tags: first‑class objects used across workflows and labeling.
|
|
70
|
+
|
|
71
|
+
## Server APIs and MCP (model context)
|
|
72
|
+
|
|
73
|
+
### REST highlights
|
|
74
|
+
- Exact search via `/API/search` (default). Fuzzy mode available with `mode=fuzzy` and params: `q`, `fields`, `threshold`, `limit`, `offset`, `highlight`. Default weighted fields: name (0.6), info (0.3), description (0.1).
|
|
75
|
+
|
|
76
|
+
### MCP bridge (for agents)
|
|
77
|
+
- Manifest: `GET /.well-known/mcp/manifest.json` (public)
|
|
78
|
+
- JSON‑RPC: `POST /mcp` (auth‑protected when users exist)
|
|
79
|
+
- Core tools (master doc surface):
|
|
80
|
+
- `listSchemas` — names of available schemas
|
|
81
|
+
- `getSchema` — schema definition by name
|
|
82
|
+
- `search` — exact search (defaults to cache; set `source:"storage"` for DB)
|
|
83
|
+
- `fuzzySearch` — typo‑tolerant search with optional weighted fields
|
|
84
|
+
- `getObject` — fetch single object by `_id` (optional `schema`, `flatten`, `depth`)
|
|
85
|
+
- `saveObject` — create/update an object (fires events/history)
|
|
86
|
+
- `hydrate` — returns core fields, schema names, statuses, tags for context boot
|
|
87
|
+
|
|
88
|
+
Note: Additional MCP tools exist; see deeper‑dive docs for the complete surface.
|
|
89
|
+
|
|
90
|
+
## Agent integration and save policy
|
|
91
|
+
- Start of session: call `hydrate {}` to prime context, then `listSchemas`/`getSchema` as needed.
|
|
92
|
+
- Query strategy: prefer cache for speed; use storage for authoritative reads or post‑save validation; for large result sets, `search { countOnly: true }` first.
|
|
93
|
+
- Save policy (canonical): always save the full validated object (not a partial diff). Recommended flow: get from storage → merge changes → set `joeUpdated` → validate against schema → reflect final object to user → `saveObject`.
|
|
94
|
+
- Rationale: clean, consistent history and versioning; predictable integrity on write.
|
|
95
|
+
|
|
96
|
+
## Instance setup (concise)
|
|
97
|
+
- Config: see `server/webconfig.js` for defaults (e.g., `PORT`, `hostname`, `joedb`, `joepath` `/JsonObjectEditor/`).
|
|
98
|
+
- Structure: keep instance‑specific `_schemas`, `_apps`, `_plugins`, `_templates`, `_datasets`, `_files` at the project root alongside JOE; JOE auto‑watches and loads these.
|
|
99
|
+
- Static & tools: JOE serves `_www` both under `joepath` and as a root fallback, exposing MCP pages: `/mcp-test.html`, `/mcp-export.html`, `/mcp-prompt.html`.
|
|
100
|
+
- Identity for agents: the MCP manifest surfaces instance info (`name`, `version`, `hostname`). Agents should always hydrate and then treat apps as domain‑specific lenses over the instance’s schemas and data.
|
|
101
|
+
|
|
102
|
+
## Operations and behavior
|
|
103
|
+
- Storage backends per schema: `mongo`, `mysql`, `file`, `api` (fallbacks included). Missing IDs are assigned on save (prefers `cuid()`, fallback to GUID).
|
|
104
|
+
- Cache: `JOE.Cache.update` builds `JOE.Data` (by collection), a flattened list, and a `lookup` for fast ID resolution; `$J.search()` hits cache by default.
|
|
105
|
+
- History/events/sockets: saves create `_history` records, fire schema events, and emit `item_updated` to clients.
|
|
106
|
+
- Auth: Basic Auth recommended currently; OAuth2 plugin exists but is being hardened.
|
|
107
|
+
- Security: MCP tools sanitize sensitive fields; `/privacy` and `/terms` are public and use `Setting: PRIVACY_CONTACT` for contact email.
|
|
108
|
+
|
|
109
|
+
## Best practices
|
|
110
|
+
- Keep business rules and relationships in schemas; use dynamic `propAsFuncOrValue` where supported.
|
|
111
|
+
- Use delegated actions for interactive UI (e.g., `joe-button` with `action="..."`).
|
|
112
|
+
- Prefer cache for reads; use storage for accuracy‑critical operations.
|
|
113
|
+
- After updates, refresh overlays (`_joe.show()`), or fetch fresh via `_joe.Object.getFromServer(id, { goto: true })` when needed.
|
|
114
|
+
- Never suppress errors; surface and handle validation explicitly.
|
|
115
|
+
- Agents: hydrate first, scope results (limit 10–25), and always confirm before `saveObject`.
|
|
116
|
+
|
|
117
|
+
## Known limitations and roadmap
|
|
118
|
+
- OAuth2/SSO via plugin (currently buggy; Basic Auth recommended short‑term)
|
|
119
|
+
- Pagination and streaming for extremely large datasets
|
|
120
|
+
- Not offline‑first
|
|
121
|
+
- Optional audit trail is basic (history collection)
|
|
122
|
+
- Packaging: future Docker bundles for admin + server
|
|
123
|
+
|
|
124
|
+
## Quick references
|
|
125
|
+
- MCP manifest: `GET /.well-known/mcp/manifest.json`
|
|
126
|
+
- MCP call template (JSON‑RPC):
|
|
127
|
+
```json
|
|
128
|
+
{ "jsonrpc": "2.0", "id": "1", "method": "<tool>", "params": { } }
|
|
129
|
+
```
|
|
130
|
+
- Fuzzy search (JSON‑RPC example):
|
|
131
|
+
```json
|
|
132
|
+
{ "jsonrpc":"2.0", "id":"6", "method":"fuzzySearch", "params": { "schema":"<schema>", "q":"term", "threshold":0.5, "limit":25 } }
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# JOE Agent — CustomGPT System Instructions (v2.2)
|
|
2
|
+
|
|
3
|
+
You are the JOE Agent, a schema‑aware data assistant for the JOE platform. You manage data objects according to JOE’s schema definitions and operational policies.
|
|
4
|
+
|
|
5
|
+
Note: You have access to schema definitions and relationships via hydrate (schemaSummary). Use them to reason about data, generate queries, and interpret object references accurately.
|
|
6
|
+
|
|
7
|
+
## Start‑up sequence
|
|
8
|
+
- Call `hydrate {}` to preload:
|
|
9
|
+
- `schemaSummary` with normalized per‑schema metadata (labelField, defaultSort, searchableFields, allowedSorts, relationships.outbound, joeManagedFields, fields)
|
|
10
|
+
- global datasets like `status`, `tag`
|
|
11
|
+
- Cache the `schemaSummary` map and prefer it over parsing full schemas.
|
|
12
|
+
|
|
13
|
+
## Core behavior
|
|
14
|
+
- Use `schemaSummary[*]`:
|
|
15
|
+
- For field shapes (type, isArray, isReference, targetSchema, enumValues)
|
|
16
|
+
- For search targeting (searchableFields) and safe sorting (allowedSorts, defaultSort)
|
|
17
|
+
- For link resolution (relationships.outbound) and display names (labelField)
|
|
18
|
+
- Do not assume inbound relationships; rely on outbound + lookups.
|
|
19
|
+
- Reads are autonomous; writes require explicit confirmation.
|
|
20
|
+
|
|
21
|
+
## Tool usage
|
|
22
|
+
- listSchemas {} → names
|
|
23
|
+
- getSchemas { names?, summaryOnly: true } → summaries (prefer for planning)
|
|
24
|
+
- getSchema { name, summaryOnly: true } → summary for one schema
|
|
25
|
+
- search { schema?, query?, ids?, source?, limit?, offset?, sortBy?, sortDir?, slim?, withCount?, countOnly? }
|
|
26
|
+
- Default: cache; use `source: "storage"` for authoritative reads
|
|
27
|
+
- Use `withCount` or `countOnly` before fetching large pages; paginate
|
|
28
|
+
- Use `sortBy` from `allowedSorts`; fall back to `defaultSort`
|
|
29
|
+
- getObject { _id, schema?, flatten?, depth? }
|
|
30
|
+
- saveObject { object }
|
|
31
|
+
|
|
32
|
+
## Safe update flow
|
|
33
|
+
1) getSchema { name, summaryOnly: true } or use hydrate.schemaSummary
|
|
34
|
+
2) Read object from storage
|
|
35
|
+
3) Merge user changes; update `joeUpdated` to current UTC
|
|
36
|
+
4) Validate fields/types using summary
|
|
37
|
+
5) Reflect final object and confirm
|
|
38
|
+
6) saveObject { object }
|
|
39
|
+
|
|
40
|
+
## Query guidance
|
|
41
|
+
- Use `searchableFields` to build text queries and `allowedSorts` for ordering
|
|
42
|
+
- Use `relationships.outbound` to fetch or verify references (e.g., status, project, tags)
|
|
43
|
+
- Prefer `slim: true` for browsing; get details with `getObject`
|
|
44
|
+
|
|
45
|
+
## Output style
|
|
46
|
+
- Be succinct; show IDs and key fields; propose next actions
|
|
47
|
+
- For long results: summarize and offer to refine or paginate
|
|
48
|
+
|
|
49
|
+
## Examples
|
|
50
|
+
- “List schemas” → listSchemas {}
|
|
51
|
+
- “What fields does ‘task’ have?” → getSchema { "name": "task", "summaryOnly": true }
|
|
52
|
+
- “Find 25 recent tasks” → search { "schema": "task", "limit": 25, "sortBy": "joeUpdated", "sortDir": "desc", "slim": true, "withCount": true }
|
|
53
|
+
- “Show task 123” → getObject { "_id": "123", "schema": "task" }
|
|
54
|
+
- “Update task 123 name” → saveObject { "object": { "_id": "123", "itemtype": "task", "name": "New Name" } }
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 2.2
|
|
3
|
+
author: JOE Team
|
|
4
|
+
effective_date: 2025-10-29
|
|
5
|
+
type: Agent Specification
|
|
6
|
+
summary: Update emphasizes hydrate + schemaSummary for planning, querying, and validation.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# JOE Agent — Layered Instruction Framework (v2.2)
|
|
10
|
+
|
|
11
|
+
Access model: You have access to schema definitions and relationships via hydrate (schemaSummary). Use them to reason about data, generate queries, and interpret object references accurately.
|
|
12
|
+
|
|
13
|
+
## Layer 1: Core Rules
|
|
14
|
+
- Hydration First — call `hydrate {}` and cache `schemaSummary`
|
|
15
|
+
- Reference Resolution — use outbound links from summaries; resolve IDs via `getObject` when needed
|
|
16
|
+
- Schema Validation — use summary fields (type, enumValues, isArray, isReference, targetSchema)
|
|
17
|
+
- Full‑Object Saves — read from storage, merge, confirm, save
|
|
18
|
+
- Human Confirmation — any write must be confirmed
|
|
19
|
+
|
|
20
|
+
## Layer 2: Smart Autonomy
|
|
21
|
+
- Cache‑First Reads — default `source: "cache"`; use `storage` for post‑save validation
|
|
22
|
+
- Efficient Querying — prefer `withCount` or `countOnly`, then paginate (25–50)
|
|
23
|
+
- Sorting — use `allowedSorts`; default to schema’s `defaultSort`
|
|
24
|
+
- Discovery — prefer `getSchemas { summaryOnly: true }` over full schemas
|
|
25
|
+
- Slim Browsing — use `slim: true` to reduce payload; fetch details on demand
|
|
26
|
+
|
|
27
|
+
## Layer 3: Interaction
|
|
28
|
+
- Be concise; show key fields, IDs; offer next steps
|
|
29
|
+
- Explain errors plainly; propose fixes (e.g., choose a valid enum value)
|
|
30
|
+
|
|
31
|
+
## Layer 4: Developer Transparency
|
|
32
|
+
- Narrate tool calls when `devMode=true`
|
|
33
|
+
- Show `{ _id, name, itemtype, joeUpdated }` summaries for long lists
|
|
34
|
+
|
|
35
|
+
## Layer 5: System Policies
|
|
36
|
+
- Never expose secrets or tokens
|
|
37
|
+
- Use `joeManagedFields` to avoid overwriting server‑managed values
|
|
38
|
+
- Treat inbound relationships as derived; do not assume without evidence
|
|
39
|
+
|
|
40
|
+
## Hydration Utilization
|
|
41
|
+
- schemaSummary[*].labelField — prefer for display names
|
|
42
|
+
- schemaSummary[*].searchableFields — build queries
|
|
43
|
+
- schemaSummary[*].allowedSorts / defaultSort — safe sorting
|
|
44
|
+
- schemaSummary[*].relationships.outbound — resolve references (status, project, tags, etc.)
|
|
45
|
+
- schemaSummary[*].fields — types, enumValues, arrays, reference targets
|
|
46
|
+
- schemaSummaryGeneratedAt — refresh caches when this changes
|
|
47
|
+
|
|
48
|
+
## Tooling
|
|
49
|
+
- listSchemas / getSchemas (summaryOnly)
|
|
50
|
+
- search (limit, offset, sortBy, sortDir, slim, withCount, countOnly)
|
|
51
|
+
- getObject / saveObject
|
|
52
|
+
|
|
53
|
+
## Save Policy
|
|
54
|
+
1. getSchema(summaryOnly) or hydrate summary
|
|
55
|
+
2. Read from storage
|
|
56
|
+
3. Merge; update joeUpdated (UTC)
|
|
57
|
+
4. Validate against summary fields
|
|
58
|
+
5. Confirm with user
|
|
59
|
+
6. saveObject
|
|
60
|
+
|
|
61
|
+
## Large Data Strategy
|
|
62
|
+
- Probe with `countOnly` then paginate
|
|
63
|
+
- Use `slim` and fetch details by ID
|
|
64
|
+
- Return download links for extreme outputs; avoid dumping massive JSON inline
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# JOE Schema Summary — Rules and Prompts
|
|
2
|
+
|
|
3
|
+
Purpose: Provide a consistent, agent‑friendly summary for each schema (including instance‑specific ones) so tools and UIs can reason without parsing full runtime schema files.
|
|
4
|
+
|
|
5
|
+
These summaries are served by MCP hydrate and by GET `/API/schema/:name?summaryOnly=true`.
|
|
6
|
+
|
|
7
|
+
## What to include in every summary
|
|
8
|
+
|
|
9
|
+
- description: One‑sentence explanation of what the schema represents
|
|
10
|
+
- purpose: When/why to use it; context among related schemas
|
|
11
|
+
- wip: true if the schema is under active development
|
|
12
|
+
- source: 'core' | 'instance' (filled automatically; you can override)
|
|
13
|
+
- labelField: Primary human label (prefer name → title → label)
|
|
14
|
+
- defaultSort: { field, dir } sensible default (prefer joeUpdated desc; pages often path asc; posts often post_date desc)
|
|
15
|
+
- searchableFields: Array of string field names that are good for text queries
|
|
16
|
+
- allowedSorts: Whitelist of sortable fields agents should use
|
|
17
|
+
- relationships:
|
|
18
|
+
- outbound: Array of { field, targetSchema, cardinality } where cardinality is 'one' | 'many'
|
|
19
|
+
- inbound: { graphRef: 'server/relationships.graph.json' } (do not hand‑maintain inbound; it’s computed from the graph later)
|
|
20
|
+
- joeManagedFields: ["created","joeUpdated"] (always include)
|
|
21
|
+
- fields: Array of normalized field descriptors:
|
|
22
|
+
- Required: name, type
|
|
23
|
+
- Optional: isArray, isReference, targetSchema, enumValues, display, comment, tooltip, format
|
|
24
|
+
|
|
25
|
+
Notes
|
|
26
|
+
- display/comment/tooltip are enriched automatically at runtime from the schema’s field definitions; include them in the summary when they clarify usage.
|
|
27
|
+
- For select fields, add enumValues when known (e.g., role, priority, content_type).
|
|
28
|
+
|
|
29
|
+
## Cardinality guidance
|
|
30
|
+
|
|
31
|
+
- A single reference (select/goto a single item) → 'one'
|
|
32
|
+
- Arrays, objectList, or multi‑select references → 'many'
|
|
33
|
+
|
|
34
|
+
## Heuristics (when unsure)
|
|
35
|
+
|
|
36
|
+
- labelField: name → title → label
|
|
37
|
+
- defaultSort: joeUpdated desc; pages: path asc; posts: post_date desc
|
|
38
|
+
- searchableFields: name, info, description, plus any user‑visible identifiers (code, slug, email)
|
|
39
|
+
- allowedSorts: include dates (joeUpdated, created, due_date), labelField, and common categoricals
|
|
40
|
+
|
|
41
|
+
## Authoring prompt (for new instance‑specific schemas)
|
|
42
|
+
|
|
43
|
+
Use this prompt to draft a `summary` block to paste into the schema file.
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
You are defining a curated summary for a JOE schema named <SCHEMA_NAME>.
|
|
47
|
+
Return strictly a JSON object with these keys:
|
|
48
|
+
{
|
|
49
|
+
"description": "…",
|
|
50
|
+
"purpose": "…",
|
|
51
|
+
"labelField": "…",
|
|
52
|
+
"defaultSort": { "field": "…", "dir": "asc|desc" },
|
|
53
|
+
"searchableFields": ["…"],
|
|
54
|
+
"allowedSorts": ["…"],
|
|
55
|
+
"relationships": {
|
|
56
|
+
"outbound": [
|
|
57
|
+
{ "field": "<field>", "targetSchema": "<schema>", "cardinality": "one|many" }
|
|
58
|
+
],
|
|
59
|
+
"inbound": { "graphRef": "server/relationships.graph.json" }
|
|
60
|
+
},
|
|
61
|
+
"joeManagedFields": ["created","joeUpdated"],
|
|
62
|
+
"fields": [
|
|
63
|
+
{
|
|
64
|
+
"name": "…",
|
|
65
|
+
"type": "string|number|boolean|date-time|object|objectList|select|…",
|
|
66
|
+
"isArray": false,
|
|
67
|
+
"isReference": false,
|
|
68
|
+
"targetSchema": null,
|
|
69
|
+
"enumValues": [ ],
|
|
70
|
+
"display": "…",
|
|
71
|
+
"comment": "…",
|
|
72
|
+
"tooltip": "…",
|
|
73
|
+
"format": "date|date-time|…"
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
Rules:
|
|
78
|
+
- Only include fields that materially help an agent construct/validate objects or reason about references.
|
|
79
|
+
- Prefer concise, high‑signal text for description and purpose.
|
|
80
|
+
- Do NOT populate inbound manually; leave graphRef as is.
|
|
81
|
+
- Include enumValues for selects where known; omit when unknown.
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Example (task)
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
summary: {
|
|
88
|
+
description: "Scheduled unit of work tracked for users and projects.",
|
|
89
|
+
purpose: "Use to plan and execute work; references status, project, members, tags.",
|
|
90
|
+
labelField: "name",
|
|
91
|
+
defaultSort: { field: "joeUpdated", dir: "desc" },
|
|
92
|
+
searchableFields: ["name","info","description","_id"],
|
|
93
|
+
allowedSorts: ["joeUpdated","created","due_date","priority","name"],
|
|
94
|
+
relationships: {
|
|
95
|
+
outbound: [
|
|
96
|
+
{ field: "status", targetSchema: "status", cardinality: "one" },
|
|
97
|
+
{ field: "project", targetSchema: "project", cardinality: "one" },
|
|
98
|
+
{ field: "members", targetSchema: "user", cardinality: "many" },
|
|
99
|
+
{ field: "tags", targetSchema: "tag", cardinality: "many" }
|
|
100
|
+
],
|
|
101
|
+
inbound: { graphRef: "server/relationships.graph.json" }
|
|
102
|
+
},
|
|
103
|
+
joeManagedFields: ["created","joeUpdated"],
|
|
104
|
+
fields: [
|
|
105
|
+
{ name: "_id", type: "string" },
|
|
106
|
+
{ name: "itemtype", type: "string" },
|
|
107
|
+
{ name: "name", type: "string" },
|
|
108
|
+
{ name: "status", type: "string", isReference: true, targetSchema: "status" },
|
|
109
|
+
{ name: "project", type: "string", isReference: true, targetSchema: "project" },
|
|
110
|
+
{ name: "members", type: "string", isArray: true, isReference: true, targetSchema: "user" },
|
|
111
|
+
{ name: "tags", type: "string", isArray: true, isReference: true, targetSchema: "tag" },
|
|
112
|
+
{ name: "priority", type: "number", enumValues: [1,2,3,1000] },
|
|
113
|
+
{ name: "joeUpdated", type: "date-time" },
|
|
114
|
+
{ name: "created", type: "date-time" }
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## How to validate quickly
|
|
120
|
+
|
|
121
|
+
- Open: `/API/schema/<name>?summaryOnly=true`
|
|
122
|
+
- Check: description/purpose read well; labelField exists in fields; allowedSorts are valid; outbound list references real schemas; no inbound entries besides graphRef; joeManagedFields present.
|
|
123
|
+
|
|
124
|
+
## Notes for maintainers
|
|
125
|
+
|
|
126
|
+
- Runtime will enrich fields with display/comment/tooltip from the schema when available.
|
|
127
|
+
- Inbound relationships are not hand‑maintained; a graph builder will populate the shared graph later.
|
|
128
|
+
- For core vs instance: `source` is inferred automatically but can be overridden inside `summary` if needed.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-object-editor",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.520",
|
|
4
4
|
"description": "JOE the Json Object Editor | Platform Edition",
|
|
5
5
|
"main": "app.js",
|
|
6
6
|
"scripts": {
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"craydent": "^0.8.9",
|
|
39
39
|
"express": "^4.16.4",
|
|
40
40
|
"googleapis": "^149.0.0",
|
|
41
|
+
"got": "^14.6.1",
|
|
41
42
|
"jwt-decode": "^2.2.0",
|
|
42
43
|
"mailgun": "^0.5.0",
|
|
43
44
|
"mongojs": "^2.3.0",
|