clay-server 2.47.0-beta.3 → 2.47.0-beta.4
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/lib/claude-hook-installer.js +0 -1
- package/lib/project-session-spawn.js +366 -0
- package/lib/project.js +36 -26
- package/lib/public/app.js +0 -2
- package/lib/public/css/mates.css +0 -196
- package/lib/public/modules/app-messages.js +0 -21
- package/lib/public/modules/mate-sidebar.js +0 -3
- package/lib/sdk-bridge.js +5 -10
- package/lib/session-spawn-mcp-server.js +56 -0
- package/lib/sessions.js +3 -0
- package/lib/ws-schema.js +0 -14
- package/package.json +1 -1
- package/lib/mate-datastore.js +0 -359
- package/lib/project-mate-datastore.js +0 -232
- package/lib/public/modules/mate-datastore-ui.js +0 -280
package/lib/public/css/mates.css
CHANGED
|
@@ -2011,202 +2011,6 @@ body.mate-dm-active #layout.sidebar-collapsed .mate-collapsed-info {
|
|
|
2011
2011
|
color: var(--accent);
|
|
2012
2012
|
}
|
|
2013
2013
|
|
|
2014
|
-
/* Mate datastore inspector */
|
|
2015
|
-
#mate-datastore-panel {
|
|
2016
|
-
position: absolute;
|
|
2017
|
-
inset: 0;
|
|
2018
|
-
z-index: 40;
|
|
2019
|
-
background: var(--bg);
|
|
2020
|
-
display: flex;
|
|
2021
|
-
flex-direction: column;
|
|
2022
|
-
overflow: hidden;
|
|
2023
|
-
}
|
|
2024
|
-
|
|
2025
|
-
#mate-datastore-panel.hidden {
|
|
2026
|
-
display: none !important;
|
|
2027
|
-
}
|
|
2028
|
-
|
|
2029
|
-
#main-column.mate-datastore-open > .title-bar-content,
|
|
2030
|
-
#main-column.mate-datastore-open > .dm-header-bar,
|
|
2031
|
-
#main-column.mate-datastore-open > #main-panels {
|
|
2032
|
-
display: none !important;
|
|
2033
|
-
}
|
|
2034
|
-
|
|
2035
|
-
.mate-datastore-top-bar {
|
|
2036
|
-
display: flex;
|
|
2037
|
-
align-items: center;
|
|
2038
|
-
justify-content: space-between;
|
|
2039
|
-
height: 48px;
|
|
2040
|
-
padding: 0 16px;
|
|
2041
|
-
border-bottom: 1px solid var(--border-subtle);
|
|
2042
|
-
flex-shrink: 0;
|
|
2043
|
-
}
|
|
2044
|
-
|
|
2045
|
-
.mate-datastore-top-title {
|
|
2046
|
-
display: flex;
|
|
2047
|
-
align-items: center;
|
|
2048
|
-
gap: 6px;
|
|
2049
|
-
font-weight: 700;
|
|
2050
|
-
font-size: 15px;
|
|
2051
|
-
color: var(--text);
|
|
2052
|
-
}
|
|
2053
|
-
|
|
2054
|
-
.mate-datastore-top-title .lucide {
|
|
2055
|
-
width: 14px;
|
|
2056
|
-
height: 14px;
|
|
2057
|
-
color: var(--accent);
|
|
2058
|
-
opacity: 0.85;
|
|
2059
|
-
}
|
|
2060
|
-
|
|
2061
|
-
.mate-datastore-top-actions {
|
|
2062
|
-
display: flex;
|
|
2063
|
-
align-items: center;
|
|
2064
|
-
gap: 8px;
|
|
2065
|
-
}
|
|
2066
|
-
|
|
2067
|
-
.mate-db-status {
|
|
2068
|
-
padding: 10px 14px 0;
|
|
2069
|
-
font-size: 12px;
|
|
2070
|
-
color: var(--text-secondary, #8e8e8e);
|
|
2071
|
-
}
|
|
2072
|
-
|
|
2073
|
-
.mate-db-status[data-kind="error"] {
|
|
2074
|
-
color: var(--error, #ff6b6b);
|
|
2075
|
-
}
|
|
2076
|
-
|
|
2077
|
-
.mate-db-status[data-kind="warn"] {
|
|
2078
|
-
color: var(--warning, #f5a524);
|
|
2079
|
-
}
|
|
2080
|
-
|
|
2081
|
-
.mate-db-status[data-kind="ok"] {
|
|
2082
|
-
color: var(--success, #36b37e);
|
|
2083
|
-
}
|
|
2084
|
-
|
|
2085
|
-
.mate-db-layout {
|
|
2086
|
-
display: grid;
|
|
2087
|
-
grid-template-columns: 220px minmax(0, 1fr);
|
|
2088
|
-
gap: 10px;
|
|
2089
|
-
padding: 12px 10px 10px;
|
|
2090
|
-
min-height: 0;
|
|
2091
|
-
flex: 1;
|
|
2092
|
-
}
|
|
2093
|
-
|
|
2094
|
-
.mate-db-table-column,
|
|
2095
|
-
.mate-db-detail {
|
|
2096
|
-
min-height: 0;
|
|
2097
|
-
display: flex;
|
|
2098
|
-
flex-direction: column;
|
|
2099
|
-
}
|
|
2100
|
-
|
|
2101
|
-
.mate-db-table-list {
|
|
2102
|
-
overflow-y: auto;
|
|
2103
|
-
border: 1px solid var(--border-subtle, rgba(255,255,255,0.06));
|
|
2104
|
-
border-radius: 12px;
|
|
2105
|
-
background: var(--sidebar-bg, rgba(255,255,255,0.03));
|
|
2106
|
-
padding: 6px;
|
|
2107
|
-
flex: 1;
|
|
2108
|
-
}
|
|
2109
|
-
|
|
2110
|
-
.mate-db-table-item {
|
|
2111
|
-
width: 100%;
|
|
2112
|
-
display: flex;
|
|
2113
|
-
justify-content: space-between;
|
|
2114
|
-
gap: 6px;
|
|
2115
|
-
padding: 8px 10px;
|
|
2116
|
-
border: none;
|
|
2117
|
-
background: transparent;
|
|
2118
|
-
color: var(--text-secondary, #aaa);
|
|
2119
|
-
border-radius: 8px;
|
|
2120
|
-
text-align: left;
|
|
2121
|
-
cursor: pointer;
|
|
2122
|
-
}
|
|
2123
|
-
|
|
2124
|
-
.mate-db-table-item:hover,
|
|
2125
|
-
.mate-db-table-item.active {
|
|
2126
|
-
background: var(--sidebar-active, rgba(255,255,255,0.08));
|
|
2127
|
-
color: var(--text, #fff);
|
|
2128
|
-
}
|
|
2129
|
-
|
|
2130
|
-
.mate-db-table-item-name {
|
|
2131
|
-
overflow: hidden;
|
|
2132
|
-
text-overflow: ellipsis;
|
|
2133
|
-
white-space: nowrap;
|
|
2134
|
-
min-width: 0;
|
|
2135
|
-
}
|
|
2136
|
-
|
|
2137
|
-
.mate-db-table-item-type {
|
|
2138
|
-
font-size: 10px;
|
|
2139
|
-
text-transform: uppercase;
|
|
2140
|
-
letter-spacing: 0.05em;
|
|
2141
|
-
opacity: 0.7;
|
|
2142
|
-
flex-shrink: 0;
|
|
2143
|
-
}
|
|
2144
|
-
|
|
2145
|
-
.mate-db-empty {
|
|
2146
|
-
padding: 16px 10px;
|
|
2147
|
-
color: var(--text-secondary, #8e8e8e);
|
|
2148
|
-
font-size: 12px;
|
|
2149
|
-
}
|
|
2150
|
-
|
|
2151
|
-
.mate-db-section-title {
|
|
2152
|
-
font-size: 11px;
|
|
2153
|
-
font-weight: 700;
|
|
2154
|
-
text-transform: uppercase;
|
|
2155
|
-
letter-spacing: 0.08em;
|
|
2156
|
-
color: var(--text-muted, #9aa0a6);
|
|
2157
|
-
margin: 0 0 6px;
|
|
2158
|
-
}
|
|
2159
|
-
|
|
2160
|
-
.mate-db-detail {
|
|
2161
|
-
gap: 8px;
|
|
2162
|
-
min-width: 0;
|
|
2163
|
-
}
|
|
2164
|
-
|
|
2165
|
-
.mate-db-table-schema,
|
|
2166
|
-
.mate-db-result {
|
|
2167
|
-
margin: 0;
|
|
2168
|
-
padding: 10px;
|
|
2169
|
-
border-radius: 10px;
|
|
2170
|
-
border: 1px solid var(--border-subtle, rgba(255,255,255,0.08));
|
|
2171
|
-
background: var(--bg-alt, rgba(255,255,255,0.03));
|
|
2172
|
-
color: var(--text-secondary, #b8b8b8);
|
|
2173
|
-
font-size: 11px;
|
|
2174
|
-
line-height: 1.5;
|
|
2175
|
-
overflow: auto;
|
|
2176
|
-
white-space: pre-wrap;
|
|
2177
|
-
word-break: break-word;
|
|
2178
|
-
min-height: 0;
|
|
2179
|
-
}
|
|
2180
|
-
|
|
2181
|
-
.mate-db-table-schema {
|
|
2182
|
-
max-height: 180px;
|
|
2183
|
-
}
|
|
2184
|
-
|
|
2185
|
-
@media (max-width: 900px) {
|
|
2186
|
-
.mate-db-layout {
|
|
2187
|
-
grid-template-columns: 1fr;
|
|
2188
|
-
}
|
|
2189
|
-
}
|
|
2190
|
-
|
|
2191
|
-
body.mate-dm-active .mate-datastore-top-bar {
|
|
2192
|
-
background: var(--mate-color);
|
|
2193
|
-
color: #fff;
|
|
2194
|
-
}
|
|
2195
|
-
|
|
2196
|
-
body.mate-dm-active .mate-datastore-top-title,
|
|
2197
|
-
body.mate-dm-active .mate-datastore-top-title .lucide {
|
|
2198
|
-
color: #fff;
|
|
2199
|
-
}
|
|
2200
|
-
|
|
2201
|
-
body.mate-dm-active .mate-datastore-top-bar .scheduler-close-btn {
|
|
2202
|
-
color: rgba(255, 255, 255, 0.85);
|
|
2203
|
-
}
|
|
2204
|
-
|
|
2205
|
-
body.mate-dm-active .mate-datastore-top-bar .scheduler-close-btn:hover {
|
|
2206
|
-
color: #fff;
|
|
2207
|
-
background: rgba(255, 255, 255, 0.15);
|
|
2208
|
-
}
|
|
2209
|
-
|
|
2210
2014
|
.mate-session-item.search-match {
|
|
2211
2015
|
background: var(--accent-12, rgba(108, 92, 231, 0.12));
|
|
2212
2016
|
}
|
|
@@ -14,7 +14,6 @@ import { renderSessionList, updateSessionPresence, handleSearchResults, updateSe
|
|
|
14
14
|
import { updateDmBadge, renderSidebarPresence, setMentionActive, renderUserStrip } from './sidebar-mates.js';
|
|
15
15
|
import { refreshMobileChatSheet } from './sidebar-mobile.js';
|
|
16
16
|
import { renderMateSessionList, handleMateSearchResults, updateMateSidebarProfile } from './mate-sidebar.js';
|
|
17
|
-
import { handleMateDatastoreTablesResult, handleMateDatastoreDescribeResult, handleMateDatastoreQueryResult, handleMateDatastoreError, handleMateDatastoreChange } from './mate-datastore-ui.js';
|
|
18
17
|
import { handleHomeClayHistory, handleHomeClayDelta, handleHomeClayDone, handleHomeClayError } from './home-chat.js';
|
|
19
18
|
import { renderKnowledgeList, handleKnowledgeContent } from './mate-knowledge.js';
|
|
20
19
|
import { renderMemoryList } from './mate-memory.js';
|
|
@@ -327,26 +326,6 @@ export function processMessage(msg) {
|
|
|
327
326
|
updateProjectList(msg);
|
|
328
327
|
break;
|
|
329
328
|
|
|
330
|
-
case "mate_db_tables_result":
|
|
331
|
-
handleMateDatastoreTablesResult(msg);
|
|
332
|
-
break;
|
|
333
|
-
|
|
334
|
-
case "mate_db_describe_result":
|
|
335
|
-
handleMateDatastoreDescribeResult(msg);
|
|
336
|
-
break;
|
|
337
|
-
|
|
338
|
-
case "mate_db_query_result":
|
|
339
|
-
handleMateDatastoreQueryResult(msg);
|
|
340
|
-
break;
|
|
341
|
-
|
|
342
|
-
case "mate_db_error":
|
|
343
|
-
handleMateDatastoreError(msg);
|
|
344
|
-
break;
|
|
345
|
-
|
|
346
|
-
case "mate_db_change":
|
|
347
|
-
handleMateDatastoreChange(msg);
|
|
348
|
-
break;
|
|
349
|
-
|
|
350
329
|
case "update_available":
|
|
351
330
|
// In multi-user mode, only show update UI to admins
|
|
352
331
|
if (store.get('isMultiUserMode')) {
|
|
@@ -3,7 +3,6 @@ import { escapeHtml } from './utils.js';
|
|
|
3
3
|
import { iconHtml, refreshIcons } from './icons.js';
|
|
4
4
|
import { store } from './store.js';
|
|
5
5
|
import { hideKnowledge } from './mate-knowledge.js';
|
|
6
|
-
import { hideMateDatastorePanel } from './mate-datastore-ui.js';
|
|
7
6
|
import { isSchedulerOpen, closeScheduler } from './scheduler.js';
|
|
8
7
|
import { hideNotes } from './sticky-notes.js';
|
|
9
8
|
import { openSearch as openSessionSearch } from './session-search.js';
|
|
@@ -135,7 +134,6 @@ export function initMateSidebar(wsGetter) {
|
|
|
135
134
|
}
|
|
136
135
|
|
|
137
136
|
export function showMateSidebar(mateId, mateData) {
|
|
138
|
-
if (hideMateDatastorePanel) hideMateDatastorePanel();
|
|
139
137
|
currentMateId = mateId;
|
|
140
138
|
currentMate = mateData;
|
|
141
139
|
cachedSessions = [];
|
|
@@ -359,7 +357,6 @@ export function getMateSessions() {
|
|
|
359
357
|
}
|
|
360
358
|
|
|
361
359
|
export function hideMateSidebar() {
|
|
362
|
-
if (hideMateDatastorePanel) hideMateDatastorePanel();
|
|
363
360
|
currentMateId = null;
|
|
364
361
|
currentMate = null;
|
|
365
362
|
cachedSessions = [];
|
package/lib/sdk-bridge.js
CHANGED
|
@@ -113,10 +113,11 @@ function createSDKBridge(opts) {
|
|
|
113
113
|
var dangerouslySkipPermissions = opts.dangerouslySkipPermissions || false;
|
|
114
114
|
// mcpServers may be either a static object or a getter function. The
|
|
115
115
|
// getter form lets callers gate individual servers at call time (e.g.
|
|
116
|
-
// clay-browser is only exposed while the Chrome extension is connected)
|
|
116
|
+
// clay-browser is only exposed while the Chrome extension is connected)
|
|
117
|
+
// and bind session-scoped servers (clay-sessions) to the querying session.
|
|
117
118
|
var _mcpServersSrc = opts.mcpServers || null;
|
|
118
|
-
function getMcpServers() {
|
|
119
|
-
if (typeof _mcpServersSrc === "function") return _mcpServersSrc() || null;
|
|
119
|
+
function getMcpServers(forSession) {
|
|
120
|
+
if (typeof _mcpServersSrc === "function") return _mcpServersSrc(forSession) || null;
|
|
120
121
|
return _mcpServersSrc;
|
|
121
122
|
}
|
|
122
123
|
var getRemoteMcpServers = opts.getRemoteMcpServers || null;
|
|
@@ -547,12 +548,6 @@ function createSDKBridge(opts) {
|
|
|
547
548
|
}
|
|
548
549
|
}
|
|
549
550
|
|
|
550
|
-
// Auto-approve Mate datastore tools. These are scoped to the active Mate
|
|
551
|
-
// project and already enforce SQL policy server-side.
|
|
552
|
-
if (toolName.indexOf("mcp__clay-datastore__") === 0) {
|
|
553
|
-
return { behavior: "allow", updatedInput: input };
|
|
554
|
-
}
|
|
555
|
-
|
|
556
551
|
// Auto-approve clay-history tools. Mounted only on Clay (host agent)
|
|
557
552
|
// sessions and strictly read-only by design — search and read across
|
|
558
553
|
// the user's own workspace data.
|
|
@@ -1337,7 +1332,7 @@ function createSDKBridge(opts) {
|
|
|
1337
1332
|
|
|
1338
1333
|
var codexConfig = getCodexConfig(sm);
|
|
1339
1334
|
var kiroConfig = getKiroConfig(sm);
|
|
1340
|
-
var mergedMcpServers = mergeMcpServers(getMcpServers(), getRemoteMcpServers) || undefined;
|
|
1335
|
+
var mergedMcpServers = mergeMcpServers(getMcpServers(session), getRemoteMcpServers) || undefined;
|
|
1341
1336
|
|
|
1342
1337
|
// Derive an explicit session title for fresh queries so the SDK records
|
|
1343
1338
|
// it at session creation and skips its own auto-generation. This also
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Session Spawn MCP Server for Clay
|
|
2
|
+
// Provides SDK-free tool definitions for agent-driven session fan-out.
|
|
3
|
+
|
|
4
|
+
var z;
|
|
5
|
+
try { z = require("zod"); } catch (e) { z = null; }
|
|
6
|
+
|
|
7
|
+
function buildShape(props, required) {
|
|
8
|
+
if (!z) return {};
|
|
9
|
+
var shape = {};
|
|
10
|
+
var keys = Object.keys(props);
|
|
11
|
+
for (var i = 0; i < keys.length; i++) {
|
|
12
|
+
var key = keys[i];
|
|
13
|
+
var prop = props[key];
|
|
14
|
+
var field;
|
|
15
|
+
if (prop.type === "number") field = z.number();
|
|
16
|
+
else if (prop.type === "boolean") field = z.boolean();
|
|
17
|
+
else if (prop.enum) field = z.enum(prop.enum);
|
|
18
|
+
else field = z.string();
|
|
19
|
+
if (prop.description) field = field.describe(prop.description);
|
|
20
|
+
if (!required || required.indexOf(key) === -1) field = field.optional();
|
|
21
|
+
shape[key] = field;
|
|
22
|
+
}
|
|
23
|
+
return shape;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getToolDefs(handlers) {
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
name: "spawn_sessions",
|
|
30
|
+
description: "Create sibling work sessions in this project. Set forkFromCurrent to copy this session's full conversation context into every child. Children share the project's working directory, so prefer parallel analysis or other non-conflicting work over concurrent edits. Results can be polled with check_spawned_sessions; spawned children cannot spawn further sessions.",
|
|
31
|
+
inputSchema: buildShape({
|
|
32
|
+
sessions: { type: "string", description: "JSON array of objects: [{\"title\":\"Task title\",\"prompt\":\"Task instructions\"}]" },
|
|
33
|
+
vendor: { type: "string", description: "Optional vendor id. Defaults to the parent session vendor, then the project default." },
|
|
34
|
+
forkFromCurrent: { type: "boolean", description: "Children start with a copy of this session's full conversation context. Defaults to false." },
|
|
35
|
+
}, ["sessions"]),
|
|
36
|
+
handler: function (args) {
|
|
37
|
+
return handlers.spawn(args || {});
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: "check_spawned_sessions",
|
|
42
|
+
description: "Check the status of sessions spawned by this session. By default only direct children of the calling session are returned.",
|
|
43
|
+
inputSchema: buildShape({
|
|
44
|
+
parentOnly: { type: "boolean", description: "When false, return all spawned sessions in this project. Defaults to true." },
|
|
45
|
+
}),
|
|
46
|
+
handler: function (args) {
|
|
47
|
+
return handlers.check(args || {});
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
module.exports = {
|
|
54
|
+
buildShape: buildShape,
|
|
55
|
+
getToolDefs: getToolDefs,
|
|
56
|
+
};
|
package/lib/sessions.js
CHANGED
|
@@ -108,6 +108,7 @@ function createSessionManager(opts) {
|
|
|
108
108
|
if (typeof session.favoriteOrder === "number") metaObj.favoriteOrder = session.favoriteOrder;
|
|
109
109
|
if (session.lastRewindUuid) metaObj.lastRewindUuid = session.lastRewindUuid;
|
|
110
110
|
if (session.loop) metaObj.loop = session.loop;
|
|
111
|
+
if (session.spawn) metaObj.spawn = session.spawn;
|
|
111
112
|
if (session.debateState) metaObj.debateState = session.debateState;
|
|
112
113
|
if (session.debateSetupMode) metaObj.debateSetupMode = true;
|
|
113
114
|
var meta = JSON.stringify(metaObj);
|
|
@@ -207,6 +208,7 @@ function createSessionManager(opts) {
|
|
|
207
208
|
};
|
|
208
209
|
if (m.vendor) session.vendor = m.vendor;
|
|
209
210
|
if (m.loop) session.loop = m.loop;
|
|
211
|
+
if (m.spawn) session.spawn = m.spawn;
|
|
210
212
|
if (m.debateState) session.debateState = m.debateState;
|
|
211
213
|
if (m.debateSetupMode) session.debateSetupMode = true;
|
|
212
214
|
if (m.ownerId) session.ownerId = m.ownerId;
|
|
@@ -394,6 +396,7 @@ function createSessionManager(opts) {
|
|
|
394
396
|
isProcessing: s.isProcessing,
|
|
395
397
|
lastActivity: s.lastActivity || s.createdAt || 0,
|
|
396
398
|
loop: loop,
|
|
399
|
+
spawn: s.spawn || null,
|
|
397
400
|
ownerId: s.ownerId || null,
|
|
398
401
|
sessionVisibility: s.sessionVisibility || "shared",
|
|
399
402
|
bookmarked: !!s.bookmarked,
|
package/lib/ws-schema.js
CHANGED
|
@@ -473,20 +473,6 @@ var schema = {
|
|
|
473
473
|
"memory_delete": { direction: "c2s", handler: "lib/project.js", description: "Delete a memory entry by index" },
|
|
474
474
|
"memory_deleted": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Memory entry was deleted" },
|
|
475
475
|
|
|
476
|
-
// -----------------------------------------------------------------------
|
|
477
|
-
// Mate datastore
|
|
478
|
-
// -----------------------------------------------------------------------
|
|
479
|
-
"mate_db_tables": { direction: "c2s", handler: "lib/project-mate-datastore.js", description: "List schema objects in the current Mate datastore" },
|
|
480
|
-
"mate_db_describe": { direction: "c2s", handler: "lib/project-mate-datastore.js", description: "Describe a table or view in the current Mate datastore" },
|
|
481
|
-
"mate_db_query": { direction: "c2s", handler: "lib/project-mate-datastore.js", description: "Run read-only SQL against the current Mate datastore" },
|
|
482
|
-
"mate_db_exec": { direction: "c2s", handler: "lib/project-mate-datastore.js", description: "Run schema or write SQL against the current Mate datastore" },
|
|
483
|
-
"mate_db_tables_result": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Schema objects returned from a Mate datastore" },
|
|
484
|
-
"mate_db_describe_result": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Table description returned from a Mate datastore" },
|
|
485
|
-
"mate_db_query_result": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Query results from a Mate datastore" },
|
|
486
|
-
"mate_db_exec_result": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Execution summary from a Mate datastore" },
|
|
487
|
-
"mate_db_error": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Mate datastore error" },
|
|
488
|
-
"mate_db_change": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Mate datastore changed" },
|
|
489
|
-
|
|
490
476
|
// -----------------------------------------------------------------------
|
|
491
477
|
// Loop (automated task runner)
|
|
492
478
|
// -----------------------------------------------------------------------
|
package/package.json
CHANGED