clay-server 4.0.0-beta.8 → 4.0.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/lib/capsule-display-floor.js +51 -0
- package/lib/capsule-frame-server.js +255 -0
- package/lib/capsule-mate-turn.js +105 -0
- package/lib/capsule-pig-logic.js +300 -0
- package/lib/capsule-server-runtimes.js +39 -0
- package/lib/capsules/pig/display.js +198 -0
- package/lib/capsules/pig/manifest.json +9 -0
- package/lib/capsules/pig/ui.json +84 -0
- package/lib/config.js +25 -1
- package/lib/daemon-projects.js +13 -8
- package/lib/daemon.js +127 -14
- package/lib/git-cli.js +95 -1
- package/lib/knowledge-import.js +436 -0
- package/lib/knowledge-record-store.js +188 -0
- package/lib/knowledge-search.js +240 -0
- package/lib/mate-knowledge-mcp-server.js +151 -0
- package/lib/mate-knowledge-migration.js +283 -0
- package/lib/mate-knowledge-service.js +488 -0
- package/lib/mate-knowledge-sync.js +482 -0
- package/lib/migrate-single-user.js +2 -0
- package/lib/notes-lifecycle.js +149 -0
- package/lib/notes.js +60 -3
- package/lib/os-users.js +3 -1
- package/lib/project-capsule-catalog.js +9 -1
- package/lib/project-capsule-turn.js +96 -0
- package/lib/project-connection.js +15 -1
- package/lib/project-file-history.js +223 -0
- package/lib/project-file-watch.js +77 -49
- package/lib/project-filesystem.js +31 -220
- package/lib/project-http.js +15 -1
- package/lib/project-knowledge.js +22 -0
- package/lib/project-log-context.js +172 -0
- package/lib/project-log-feedback-delivery.js +118 -0
- package/lib/project-logs-comments.js +137 -0
- package/lib/project-logs-context-state.js +42 -0
- package/lib/project-logs-mcp-server.js +328 -0
- package/lib/project-logs-query.js +185 -0
- package/lib/project-logs-root.js +75 -0
- package/lib/project-logs-schema.js +259 -0
- package/lib/project-logs-service.js +463 -0
- package/lib/project-logs-snapshot.js +205 -0
- package/lib/project-logs-store.js +495 -0
- package/lib/project-logs-versioning.js +132 -0
- package/lib/project-logs.js +400 -0
- package/lib/project-mate-interaction.js +14 -0
- package/lib/project-mate-knowledge.js +110 -0
- package/lib/project-memory.js +22 -0
- package/lib/project-message-delivery.js +70 -0
- package/lib/project-pair-lifecycle.js +460 -0
- package/lib/project-request-access.js +66 -0
- package/lib/project-session-handoff.js +1 -1
- package/lib/project-session-notes.js +64 -13
- package/lib/project-session-pair.js +159 -146
- package/lib/project-session-spawn.js +1 -1
- package/lib/project-sessions.js +58 -13
- package/lib/project-user-message.js +53 -4
- package/lib/project-worker-permission.js +430 -0
- package/lib/project-worker-proposal.js +208 -62
- package/lib/project.js +185 -6
- package/lib/public/app.js +63 -35
- package/lib/public/css/admin.css +2 -2
- package/lib/public/css/capsule-ui.css +38 -0
- package/lib/public/css/command-palette.css +19 -9
- package/lib/public/css/git-placard.css +154 -0
- package/lib/public/css/home-hub.css +4 -0
- package/lib/public/css/home-session-actions.css +66 -0
- package/lib/public/css/home-sidebar.css +66 -0
- package/lib/public/css/input.css +84 -3
- package/lib/public/css/messages.css +40 -1
- package/lib/public/css/mobile-nav.css +80 -0
- package/lib/public/css/notifications-center.css +67 -0
- package/lib/public/css/pane.css +97 -10
- package/lib/public/css/project-logs.css +198 -0
- package/lib/public/css/scheduler.css +1 -1
- package/lib/public/css/session-actions.css +16 -101
- package/lib/public/css/sidebar.css +103 -0
- package/lib/public/css/sticky-notes.css +237 -229
- package/lib/public/css/worker-proposal.css +36 -3
- package/lib/public/index.html +43 -11
- package/lib/public/modules/admin.js +8 -8
- package/lib/public/modules/app-connection.js +124 -6
- package/lib/public/modules/app-home-hub.js +12 -8
- package/lib/public/modules/app-message-cards.js +2 -1
- package/lib/public/modules/app-messages.js +92 -11
- package/lib/public/modules/app-misc.js +2 -14
- package/lib/public/modules/app-notifications.js +11 -7
- package/lib/public/modules/app-panels.js +3 -2
- package/lib/public/modules/app-projects.js +56 -18
- package/lib/public/modules/app-rendering.js +1 -0
- package/lib/public/modules/capsule-preference.js +44 -0
- package/lib/public/modules/chat-bubble-renderer.js +1 -1
- package/lib/public/modules/clay-log-links.js +70 -0
- package/lib/public/modules/command-palette.js +52 -15
- package/lib/public/modules/context-sources.js +0 -3
- package/lib/public/modules/git-agent-sessions.js +85 -0
- package/lib/public/modules/git-panel.js +111 -84
- package/lib/public/modules/git-placard.js +161 -0
- package/lib/public/modules/home-chat-empty-state.js +39 -0
- package/lib/public/modules/home-chat-identity.js +9 -0
- package/lib/public/modules/home-conversations-sheet.js +102 -48
- package/lib/public/modules/home-mate-chat.js +15 -35
- package/lib/public/modules/home-session-actions.js +6 -0
- package/lib/public/modules/home-sidebar-chat-list.js +101 -41
- package/lib/public/modules/home-sidebar.js +7 -0
- package/lib/public/modules/home-surface-boot.js +7 -3
- package/lib/public/modules/home-tool-frame.js +182 -0
- package/lib/public/modules/home-tools.js +138 -1
- package/lib/public/modules/input.js +38 -7
- package/lib/public/modules/markdown.js +2 -0
- package/lib/public/modules/mate-sidebar.js +0 -8
- package/lib/public/modules/message-delivery.js +97 -0
- package/lib/public/modules/paste-modal.js +84 -0
- package/lib/public/modules/project-activation.js +45 -0
- package/lib/public/modules/project-logs-render.js +405 -0
- package/lib/public/modules/project-logs.js +461 -0
- package/lib/public/modules/project-removal-target.js +26 -0
- package/lib/public/modules/scheduler.js +17 -3
- package/lib/public/modules/session-actions.js +29 -105
- package/lib/public/modules/session-hierarchy.js +54 -0
- package/lib/public/modules/sidebar-mobile.js +40 -15
- package/lib/public/modules/sidebar-session-hierarchy.js +214 -0
- package/lib/public/modules/sidebar-sessions.js +77 -11
- package/lib/public/modules/sidebar.js +17 -5
- package/lib/public/modules/split-group-helpers.js +8 -0
- package/lib/public/modules/split-pair-ui.js +15 -4
- package/lib/public/modules/split-view.js +5 -2
- package/lib/public/modules/split-worker-runtime.js +24 -0
- package/lib/public/modules/sticky-note-markdown.js +5 -0
- package/lib/public/modules/sticky-notes-browser.js +326 -0
- package/lib/public/modules/sticky-notes-card.js +360 -0
- package/lib/public/modules/sticky-notes-editor.js +291 -0
- package/lib/public/modules/sticky-notes-shared.js +90 -0
- package/lib/public/modules/sticky-notes.js +170 -946
- package/lib/public/modules/thinking-lifecycle.js +175 -0
- package/lib/public/modules/thinking-summary.js +28 -0
- package/lib/public/modules/thinking-view.js +75 -0
- package/lib/public/modules/tool-palette-order.js +143 -0
- package/lib/public/modules/tool-palette-overlays.js +159 -0
- package/lib/public/modules/tool-palette.js +21 -188
- package/lib/public/modules/tools.js +31 -123
- package/lib/public/modules/update-snooze.js +169 -0
- package/lib/public/modules/user-settings.js +4 -0
- package/lib/public/modules/worker-pane-lock.js +176 -0
- package/lib/public/modules/worker-proposal-state.js +16 -0
- package/lib/public/modules/worker-proposal.js +49 -20
- package/lib/public/style.css +3 -1
- package/lib/sdk-bridge.js +135 -46
- package/lib/sdk-message-processor.js +36 -19
- package/lib/server-experimental-settings.js +49 -0
- package/lib/server-global-ws.js +11 -0
- package/lib/server-home-chat-events.js +31 -1
- package/lib/server-home-chat.js +27 -4
- package/lib/server-home-clay-entry.js +1 -1
- package/lib/server-home-clay-session-links.js +34 -5
- package/lib/server-settings.js +5 -0
- package/lib/server-tools.js +127 -9
- package/lib/server.js +137 -22
- package/lib/session-driver-eligibility.js +38 -0
- package/lib/session-driver-orchestration.js +31 -0
- package/lib/session-hygiene.js +3 -0
- package/lib/session-notes-mcp-server.js +25 -5
- package/lib/session-pair-factory.js +247 -0
- package/lib/session-pair-mcp-server.js +46 -8
- package/lib/session-pair-prompts.js +79 -0
- package/lib/session-pair-turn-control.js +153 -0
- package/lib/session-provenance.js +119 -0
- package/lib/session-spawn-mcp-server.js +1 -1
- package/lib/session-split-groups.js +4 -1
- package/lib/session-title-policy.js +60 -0
- package/lib/session-visibility.js +41 -0
- package/lib/sessions.js +57 -10
- package/lib/tools-registry.js +89 -10
- package/lib/update-snooze.js +437 -0
- package/lib/users-experimental-preferences.js +30 -0
- package/lib/users-permissions.js +6 -6
- package/lib/users.js +22 -16
- package/lib/workspace-query-access.js +102 -0
- package/lib/workspace-query-service.js +24 -17
- package/lib/worktree.js +25 -38
- package/lib/ws-schema.js +38 -7
- package/lib/yoke/adapters/claude-worker.js +16 -6
- package/lib/yoke/adapters/claude.js +12 -0
- package/lib/yoke/adapters/codex.js +24 -14
- package/lib/yoke/vendor-registry.js +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
// Vocabulary and validation for Project Logs.
|
|
2
|
+
//
|
|
3
|
+
// Extracted from project-logs-store.js so the store stays focused on records
|
|
4
|
+
// and stays inside the module size limit.
|
|
5
|
+
//
|
|
6
|
+
// Two independent axes, deliberately:
|
|
7
|
+
// category - what kind of record this is, a project-local vocabulary
|
|
8
|
+
// priority - how much it matters, a stable global enum
|
|
9
|
+
// Conflating them is what made "an urgent decision" unrepresentable before.
|
|
10
|
+
//
|
|
11
|
+
// Category is NOT a global enum. Every project evolves its own vocabulary: an
|
|
12
|
+
// agent reuses an established category when one fits and coins a new one when
|
|
13
|
+
// the project needs a durable distinction it does not yet have. What is fixed
|
|
14
|
+
// is only the shape of a category label, not the set of labels. The seeds
|
|
15
|
+
// below are guidance for a project with no history yet, never a whitelist.
|
|
16
|
+
|
|
17
|
+
// Suggested starting points, surfaced in tool guidance only.
|
|
18
|
+
var SEED_CATEGORIES = [
|
|
19
|
+
"decision",
|
|
20
|
+
"security",
|
|
21
|
+
"idea",
|
|
22
|
+
"operations",
|
|
23
|
+
"incident",
|
|
24
|
+
"investigation",
|
|
25
|
+
"progress",
|
|
26
|
+
"reference",
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
var MAX_CATEGORY_CHARS = 32;
|
|
30
|
+
// Letters and digits in any script, so a project can keep its vocabulary in the
|
|
31
|
+
// language it actually works in. Normalization runs server-side only, so this
|
|
32
|
+
// depends on Node's Unicode property escapes and never on a browser baseline.
|
|
33
|
+
var CATEGORY_PATTERN = /^[\p{L}\p{N}]+(?:-[\p{L}\p{N}]+)*$/u;
|
|
34
|
+
var CATEGORY_STRIP = /[^\p{L}\p{N}-]/gu;
|
|
35
|
+
|
|
36
|
+
// Length is counted in code points, not UTF-16 units, so a CJK or Hangul label
|
|
37
|
+
// is bounded the same way a Latin one is.
|
|
38
|
+
function codePointLength(value) {
|
|
39
|
+
return Array.from(value).length;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Deterministic normalization to a lowercase, hyphen-separated label. Anything
|
|
43
|
+
// that cannot be reduced to a safe label is rejected rather than silently
|
|
44
|
+
// coerced, so a caller is told when its input was unusable instead of getting a
|
|
45
|
+
// surprising slug.
|
|
46
|
+
//
|
|
47
|
+
// Path and identity shapes are refused outright: a category is dry metadata and
|
|
48
|
+
// must never be able to carry a slug, a path segment, or a user id.
|
|
49
|
+
function normalizeCategory(value) {
|
|
50
|
+
if (typeof value !== "string") throw new Error("A log category must be a string.");
|
|
51
|
+
var raw = value.normalize("NFC").trim();
|
|
52
|
+
if (!raw) throw new Error("A log category is required.");
|
|
53
|
+
if (codePointLength(raw) > MAX_CATEGORY_CHARS * 2) {
|
|
54
|
+
throw new Error("A log category must be " + MAX_CATEGORY_CHARS + " characters or fewer.");
|
|
55
|
+
}
|
|
56
|
+
if (/[\/\\]/.test(raw) || raw.indexOf("..") !== -1) {
|
|
57
|
+
throw new Error("A log category cannot contain path characters.");
|
|
58
|
+
}
|
|
59
|
+
var slug = raw
|
|
60
|
+
.toLowerCase()
|
|
61
|
+
.replace(/[_\s]+/g, "-")
|
|
62
|
+
.replace(CATEGORY_STRIP, "")
|
|
63
|
+
.replace(/-+/g, "-")
|
|
64
|
+
.replace(/^-|-$/g, "");
|
|
65
|
+
if (!slug) throw new Error("A log category must contain letters or digits: " + value);
|
|
66
|
+
if (codePointLength(slug) > MAX_CATEGORY_CHARS) {
|
|
67
|
+
throw new Error("A log category must be " + MAX_CATEGORY_CHARS + " characters or fewer.");
|
|
68
|
+
}
|
|
69
|
+
if (!CATEGORY_PATTERN.test(slug)) throw new Error("Invalid log category: " + value);
|
|
70
|
+
return slug;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Non-throwing form for reading stored records, where a corrupt on-disk value
|
|
74
|
+
// should make that record unusable rather than break the whole projection.
|
|
75
|
+
// Filters deliberately do NOT use this: a caller that supplies a malformed
|
|
76
|
+
// category is told so.
|
|
77
|
+
function safeCategory(value) {
|
|
78
|
+
try {
|
|
79
|
+
return normalizeCategory(value);
|
|
80
|
+
} catch (e) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
var PRIORITIES = ["normal", "important", "urgent"];
|
|
86
|
+
var DEFAULT_PRIORITY = "normal";
|
|
87
|
+
|
|
88
|
+
var MAX_SUMMARY_CHARS = 400;
|
|
89
|
+
|
|
90
|
+
function isPriority(value) {
|
|
91
|
+
return PRIORITIES.indexOf(value) !== -1;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function normalizePriority(value) {
|
|
95
|
+
return isPriority(value) ? value : DEFAULT_PRIORITY;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// A summary for an entry written before summaries existed. Deterministic and
|
|
99
|
+
// derived from stored content only, so the same record always yields the same
|
|
100
|
+
// text and nothing is invented.
|
|
101
|
+
function fallbackSummary(entry) {
|
|
102
|
+
if (!entry) return "";
|
|
103
|
+
if (typeof entry.summary === "string" && entry.summary.trim()) {
|
|
104
|
+
return entry.summary.trim().substring(0, MAX_SUMMARY_CHARS);
|
|
105
|
+
}
|
|
106
|
+
// Prefer the first line of prose. A leading Markdown heading usually just
|
|
107
|
+
// restates the title, so it is only used when there is nothing else.
|
|
108
|
+
var body = typeof entry.body === "string" ? entry.body : "";
|
|
109
|
+
var lines = body.split("\n");
|
|
110
|
+
var heading = "";
|
|
111
|
+
var firstLine = "";
|
|
112
|
+
for (var i = 0; i < lines.length; i++) {
|
|
113
|
+
var raw = lines[i].trim();
|
|
114
|
+
if (!raw) continue;
|
|
115
|
+
var isHeading = raw.charAt(0) === "#";
|
|
116
|
+
var line = raw.replace(/^#+\s*/, "").replace(/^[-*>]\s*/, "").trim();
|
|
117
|
+
if (!line) continue;
|
|
118
|
+
if (isHeading) {
|
|
119
|
+
if (!heading) heading = line;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
firstLine = line;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
if (!firstLine) firstLine = heading;
|
|
126
|
+
if (!firstLine) return "";
|
|
127
|
+
return firstLine.length > MAX_SUMMARY_CHARS
|
|
128
|
+
? firstLine.substring(0, MAX_SUMMARY_CHARS)
|
|
129
|
+
: firstLine;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Validation for a new agent-written record. Category, title, and summary are
|
|
133
|
+
// all required: a log without a summary cannot be understood from a list, and
|
|
134
|
+
// that is the whole point of the surface.
|
|
135
|
+
function validateNewRecord(input) {
|
|
136
|
+
var data = input || {};
|
|
137
|
+
var category = normalizeCategory(data.category || data.kind);
|
|
138
|
+
if (typeof data.title !== "string" || !data.title.trim()) throw new Error("A log title is required.");
|
|
139
|
+
if (typeof data.summary !== "string" || !data.summary.trim()) {
|
|
140
|
+
throw new Error("A one or two sentence summary is required so the entry is understandable from a list.");
|
|
141
|
+
}
|
|
142
|
+
// A mistyped priority is refused rather than silently downgraded to normal:
|
|
143
|
+
// an agent that meant "urgent" must not get "normal" without being told.
|
|
144
|
+
if (data.priority !== undefined && data.priority !== null && !isPriority(data.priority)) {
|
|
145
|
+
throw new Error("Unknown log priority: " + data.priority);
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
category: category,
|
|
149
|
+
priority: normalizePriority(data.priority),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Validation for a revision. The category may move to another writable value
|
|
154
|
+
// or stay on its legacy one; nothing is required, but nothing may be emptied.
|
|
155
|
+
function validateRevision(input) {
|
|
156
|
+
var data = input || {};
|
|
157
|
+
var out = {};
|
|
158
|
+
if (data.category !== undefined || data.kind !== undefined) {
|
|
159
|
+
out.category = normalizeCategory(data.category || data.kind);
|
|
160
|
+
}
|
|
161
|
+
if (data.priority !== undefined) {
|
|
162
|
+
if (!isPriority(data.priority)) throw new Error("Unknown log priority: " + data.priority);
|
|
163
|
+
out.priority = data.priority;
|
|
164
|
+
}
|
|
165
|
+
if (data.title !== undefined) {
|
|
166
|
+
if (typeof data.title !== "string" || !data.title.trim()) throw new Error("A log title cannot be emptied.");
|
|
167
|
+
out.title = data.title;
|
|
168
|
+
}
|
|
169
|
+
if (data.summary !== undefined) {
|
|
170
|
+
if (typeof data.summary !== "string" || !data.summary.trim()) throw new Error("A log summary cannot be emptied.");
|
|
171
|
+
out.summary = data.summary;
|
|
172
|
+
}
|
|
173
|
+
return out;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
// --- Normalization -------------------------------------------------------
|
|
178
|
+
//
|
|
179
|
+
// Moved here from project-logs-store.js so the store stays inside the module
|
|
180
|
+
// size limit. These are pure text and shape helpers with no record semantics.
|
|
181
|
+
|
|
182
|
+
var MAX_TAGS = 12;
|
|
183
|
+
var MAX_TAG_CHARS = 40;
|
|
184
|
+
var MAX_LINKS = 20;
|
|
185
|
+
var MAX_LINK_CHARS = 200;
|
|
186
|
+
|
|
187
|
+
function cleanText(value, max) {
|
|
188
|
+
if (typeof value !== "string") return "";
|
|
189
|
+
var text = value.replace(/\u0000/g, "").trim();
|
|
190
|
+
return text.length > max ? text.substring(0, max) : text;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function cleanLine(value, max) {
|
|
194
|
+
return cleanText(value, max).replace(/[\u0000-\u001f\u007f]+/g, " ").replace(/\s+/g, " ").trim();
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function normalizeAuthor(author) {
|
|
198
|
+
var source = author || {};
|
|
199
|
+
var type = source.type === "user" ? "user" : "session";
|
|
200
|
+
return {
|
|
201
|
+
type: type,
|
|
202
|
+
userId: source.userId ? cleanLine(String(source.userId), 120) : null,
|
|
203
|
+
displayName: cleanLine(source.displayName || "", 120) || null,
|
|
204
|
+
sessionKey: source.sessionKey ? cleanLine(String(source.sessionKey), 200) : null,
|
|
205
|
+
vendor: cleanLine(source.vendor || "", 40) || null,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function normalizeTags(tags) {
|
|
210
|
+
if (!Array.isArray(tags)) return [];
|
|
211
|
+
var out = [];
|
|
212
|
+
for (var i = 0; i < tags.length && out.length < MAX_TAGS; i++) {
|
|
213
|
+
var tag = cleanLine(String(tags[i] == null ? "" : tags[i]), MAX_TAG_CHARS).toLowerCase();
|
|
214
|
+
if (tag && out.indexOf(tag) === -1) out.push(tag);
|
|
215
|
+
}
|
|
216
|
+
return out;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function normalizeLinks(links) {
|
|
220
|
+
if (!Array.isArray(links)) return [];
|
|
221
|
+
var out = [];
|
|
222
|
+
for (var i = 0; i < links.length && out.length < MAX_LINKS; i++) {
|
|
223
|
+
var raw = links[i];
|
|
224
|
+
var value = typeof raw === "string" ? { ref: raw } : (raw || {});
|
|
225
|
+
var ref = cleanLine(String(value.ref || value.sessionRef || ""), MAX_LINK_CHARS);
|
|
226
|
+
if (!ref) continue;
|
|
227
|
+
var label = cleanLine(value.label || "", MAX_LINK_CHARS) || null;
|
|
228
|
+
var duplicate = false;
|
|
229
|
+
for (var j = 0; j < out.length; j++) {
|
|
230
|
+
if (out[j].ref === ref) { duplicate = true; break; }
|
|
231
|
+
}
|
|
232
|
+
if (!duplicate) out.push({ ref: ref, label: label });
|
|
233
|
+
}
|
|
234
|
+
return out;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
module.exports = {
|
|
238
|
+
SEED_CATEGORIES: SEED_CATEGORIES,
|
|
239
|
+
MAX_CATEGORY_CHARS: MAX_CATEGORY_CHARS,
|
|
240
|
+
CATEGORY_PATTERN: CATEGORY_PATTERN,
|
|
241
|
+
codePointLength: codePointLength,
|
|
242
|
+
normalizeCategory: normalizeCategory,
|
|
243
|
+
safeCategory: safeCategory,
|
|
244
|
+
PRIORITIES: PRIORITIES,
|
|
245
|
+
DEFAULT_PRIORITY: DEFAULT_PRIORITY,
|
|
246
|
+
MAX_SUMMARY_CHARS: MAX_SUMMARY_CHARS,
|
|
247
|
+
isPriority: isPriority,
|
|
248
|
+
normalizePriority: normalizePriority,
|
|
249
|
+
fallbackSummary: fallbackSummary,
|
|
250
|
+
MAX_TAGS: MAX_TAGS,
|
|
251
|
+
MAX_LINKS: MAX_LINKS,
|
|
252
|
+
cleanText: cleanText,
|
|
253
|
+
cleanLine: cleanLine,
|
|
254
|
+
normalizeAuthor: normalizeAuthor,
|
|
255
|
+
normalizeTags: normalizeTags,
|
|
256
|
+
normalizeLinks: normalizeLinks,
|
|
257
|
+
validateNewRecord: validateNewRecord,
|
|
258
|
+
validateRevision: validateRevision,
|
|
259
|
+
};
|