@spilno/herald-mcp 1.34.3 → 1.34.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/README.md +97 -1
- package/dist/cli.js +91 -54
- package/dist/cli.js.map +1 -1
- package/dist/sdk.d.ts +61 -3
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +230 -16
- package/dist/sdk.js.map +1 -1
- package/dist/sdk.spec.d.ts +2 -0
- package/dist/sdk.spec.d.ts.map +1 -0
- package/dist/sdk.spec.js +147 -0
- package/dist/sdk.spec.js.map +1 -0
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -30,11 +30,31 @@ herald.gotStuck('What failed');
|
|
|
30
30
|
|
|
31
31
|
## Quick Start
|
|
32
32
|
|
|
33
|
+
### MCP Server (for AI agents like Claude)
|
|
34
|
+
|
|
33
35
|
```bash
|
|
34
36
|
cd your-project
|
|
35
37
|
npx @spilno/herald-mcp init
|
|
36
38
|
```
|
|
37
39
|
|
|
40
|
+
### SDK (for programmatic access)
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { herald } from '@spilno/herald-mcp';
|
|
44
|
+
|
|
45
|
+
// Capture a pattern (something that worked)
|
|
46
|
+
await herald.learned('Always run tests before committing');
|
|
47
|
+
|
|
48
|
+
// Capture an antipattern (something that failed)
|
|
49
|
+
await herald.gotStuck('Forgot to check existing tests before refactoring');
|
|
50
|
+
|
|
51
|
+
// Query patterns
|
|
52
|
+
const patterns = await herald.recall();
|
|
53
|
+
|
|
54
|
+
// Configure (optional - uses git context by default)
|
|
55
|
+
herald.configure({ baseUrl: 'https://custom.ceda.com', token: 'your-token' });
|
|
56
|
+
```
|
|
57
|
+
|
|
38
58
|
**What this does:**
|
|
39
59
|
1. Creates `.mcp.json` with Herald MCP configuration
|
|
40
60
|
2. Fetches learned patterns from CEDA (if any exist)
|
|
@@ -223,6 +243,82 @@ CEDA (Cognitive Event-Driven Architecture) is pattern memory for AI:
|
|
|
223
243
|
|
|
224
244
|
Unlike RAG (retrieves content), CEDA retrieves **what worked**.
|
|
225
245
|
|
|
246
|
+
## SDK API
|
|
247
|
+
|
|
248
|
+
The SDK provides programmatic access to CEDA pattern memory for use in your own applications.
|
|
249
|
+
|
|
250
|
+
### Installation
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
npm install @spilno/herald-mcp
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### API Reference
|
|
257
|
+
|
|
258
|
+
#### `herald.learned(insight, context?)`
|
|
259
|
+
|
|
260
|
+
Capture a pattern (something that worked).
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
await herald.learned('Always run tests before committing');
|
|
264
|
+
await herald.learned('Use feature flags for gradual rollouts', 'deployment pipeline');
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
#### `herald.gotStuck(insight, context?)`
|
|
268
|
+
|
|
269
|
+
Capture an antipattern (something that failed).
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
await herald.gotStuck('Forgot to check existing tests before refactoring');
|
|
273
|
+
await herald.gotStuck('Deployed without running migrations', 'production incident');
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
#### `herald.recall(topic?)`
|
|
277
|
+
|
|
278
|
+
Query learned patterns and antipatterns.
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
const patterns = await herald.recall();
|
|
282
|
+
const deployPatterns = await herald.recall('deployment');
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Returns an array of `Pattern` objects:
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
interface Pattern {
|
|
289
|
+
insight: string;
|
|
290
|
+
feeling: 'success' | 'stuck';
|
|
291
|
+
signal?: string;
|
|
292
|
+
reinforcement?: string;
|
|
293
|
+
warning?: string;
|
|
294
|
+
scope?: string;
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
#### `herald.configure(opts)`
|
|
299
|
+
|
|
300
|
+
Configure the SDK (optional - uses git context by default).
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
herald.configure({
|
|
304
|
+
baseUrl: 'https://custom.ceda.com',
|
|
305
|
+
token: 'your-api-token',
|
|
306
|
+
company: 'acme',
|
|
307
|
+
project: 'backend',
|
|
308
|
+
user: 'developer'
|
|
309
|
+
});
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Context Detection
|
|
313
|
+
|
|
314
|
+
By default, the SDK automatically derives context from:
|
|
315
|
+
|
|
316
|
+
1. **Git remote** - Organization and repository name from git origin
|
|
317
|
+
2. **Git user** - User name from git config
|
|
318
|
+
3. **Path** - Falls back to folder names if not in a git repo
|
|
319
|
+
|
|
320
|
+
This means you can use the SDK without any configuration in most projects.
|
|
321
|
+
|
|
226
322
|
## Links
|
|
227
323
|
|
|
228
324
|
- **CEDA**: https://getceda.com
|
|
@@ -235,4 +331,4 @@ MIT
|
|
|
235
331
|
|
|
236
332
|
---
|
|
237
333
|
|
|
238
|
-
*Herald v1.
|
|
334
|
+
*Herald v1.33.0 — Pattern memory for AI agents*
|
package/dist/cli.js
CHANGED
|
@@ -134,9 +134,11 @@ function hashTag(input) {
|
|
|
134
134
|
}
|
|
135
135
|
function deriveTagSet() {
|
|
136
136
|
// 1. Check env vars (explicit override)
|
|
137
|
-
|
|
137
|
+
// HERALD_ORG is primary, HERALD_COMPANY for backwards compat
|
|
138
|
+
const envOrg = process.env.HERALD_ORG || process.env.HERALD_COMPANY;
|
|
139
|
+
if (envOrg) {
|
|
138
140
|
return {
|
|
139
|
-
tags: [
|
|
141
|
+
tags: [envOrg, process.env.HERALD_PROJECT].filter(Boolean),
|
|
140
142
|
trust: 'LOW', // Env vars can be set by anyone
|
|
141
143
|
source: 'env',
|
|
142
144
|
propagates: false
|
|
@@ -213,9 +215,11 @@ function persistContext(tagSet, user) {
|
|
|
213
215
|
function loadOrDeriveContext() {
|
|
214
216
|
const user = process.env.HERALD_USER || deriveUser();
|
|
215
217
|
// 1. Check env vars (explicit override - highest priority, but LOW trust)
|
|
216
|
-
|
|
218
|
+
// HERALD_ORG is primary, HERALD_COMPANY for backwards compat
|
|
219
|
+
const envOrg = process.env.HERALD_ORG || process.env.HERALD_COMPANY;
|
|
220
|
+
if (envOrg) {
|
|
217
221
|
return {
|
|
218
|
-
tags: [
|
|
222
|
+
tags: [envOrg, process.env.HERALD_PROJECT].filter(Boolean),
|
|
219
223
|
user,
|
|
220
224
|
trust: 'LOW',
|
|
221
225
|
source: 'env',
|
|
@@ -261,7 +265,7 @@ const LOADED_CONTEXT = loadOrDeriveContext();
|
|
|
261
265
|
let HERALD_USER = LOADED_CONTEXT.user;
|
|
262
266
|
// Tags from context (env > stored > git > path) - can be refreshed
|
|
263
267
|
let HERALD_TAGS = LOADED_CONTEXT.tags;
|
|
264
|
-
let
|
|
268
|
+
let HERALD_ORG = HERALD_TAGS[0] || "";
|
|
265
269
|
let HERALD_PROJECT = HERALD_TAGS[1] || HERALD_TAGS[0] || "";
|
|
266
270
|
// ADR-001: Trust level determines pattern propagation
|
|
267
271
|
// These are mutable - verification with CEDA may upgrade/downgrade trust
|
|
@@ -307,7 +311,7 @@ const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY || "";
|
|
|
307
311
|
const OPENAI_API_KEY = process.env.OPENAI_API_KEY || "";
|
|
308
312
|
// Session persistence - context-isolated paths
|
|
309
313
|
function getHeraldDir() {
|
|
310
|
-
return join(homedir(), ".herald",
|
|
314
|
+
return join(homedir(), ".herald", HERALD_ORG, HERALD_PROJECT, HERALD_USER);
|
|
311
315
|
}
|
|
312
316
|
function getSessionFile() {
|
|
313
317
|
return join(getHeraldDir(), "session");
|
|
@@ -424,7 +428,7 @@ function clearSession() {
|
|
|
424
428
|
}
|
|
425
429
|
}
|
|
426
430
|
function getContextString() {
|
|
427
|
-
return `${
|
|
431
|
+
return `${HERALD_ORG}:${HERALD_PROJECT}:${HERALD_USER}`;
|
|
428
432
|
}
|
|
429
433
|
const HERALD_SYSTEM_PROMPT = `You are Herald, the voice of CEDA (Cognitive Event-Driven Architecture).
|
|
430
434
|
You help humans design module structures through natural conversation.
|
|
@@ -672,7 +676,7 @@ async function callCedaAPI(endpoint, method = "GET", body) {
|
|
|
672
676
|
endpoint.startsWith("/api/observations");
|
|
673
677
|
if (method === "GET" && needsTenantParams) {
|
|
674
678
|
const separator = endpoint.includes("?") ? "&" : "?";
|
|
675
|
-
url += `${separator}
|
|
679
|
+
url += `${separator}org=${HERALD_ORG}&project=${HERALD_PROJECT}&user=${HERALD_USER}`;
|
|
676
680
|
}
|
|
677
681
|
const headers = {
|
|
678
682
|
"Content-Type": "application/json",
|
|
@@ -685,7 +689,7 @@ async function callCedaAPI(endpoint, method = "GET", body) {
|
|
|
685
689
|
if (method === "POST" && body && typeof body === "object") {
|
|
686
690
|
enrichedBody = {
|
|
687
691
|
...body,
|
|
688
|
-
|
|
692
|
+
org: HERALD_ORG,
|
|
689
693
|
project: HERALD_PROJECT,
|
|
690
694
|
user: HERALD_USER,
|
|
691
695
|
};
|
|
@@ -1077,7 +1081,7 @@ Example flow:
|
|
|
1077
1081
|
inputSchema: {
|
|
1078
1082
|
type: "object",
|
|
1079
1083
|
properties: {
|
|
1080
|
-
|
|
1084
|
+
org: { type: "string", description: "Filter by org (optional, defaults to HERALD_ORG)" },
|
|
1081
1085
|
project: { type: "string", description: "Filter by project (optional)" },
|
|
1082
1086
|
user: { type: "string", description: "Filter by user (optional)" },
|
|
1083
1087
|
status: { type: "string", description: "Filter by status: active, archived, or expired (optional)" },
|
|
@@ -1412,9 +1416,9 @@ async function fetchPatternsWithCascade() {
|
|
|
1412
1416
|
const patterns = [];
|
|
1413
1417
|
const antipatterns = [];
|
|
1414
1418
|
const queries = [
|
|
1415
|
-
{ scope: "user", url: `/api/herald/reflections?
|
|
1416
|
-
{ scope: "project", url: `/api/herald/reflections?
|
|
1417
|
-
{ scope: "
|
|
1419
|
+
{ scope: "user", url: `/api/herald/reflections?org=${HERALD_ORG}&project=${HERALD_PROJECT}&user=${HERALD_USER}&limit=100` },
|
|
1420
|
+
{ scope: "project", url: `/api/herald/reflections?org=${HERALD_ORG}&project=${HERALD_PROJECT}&limit=100` },
|
|
1421
|
+
{ scope: "org", url: `/api/herald/reflections?org=${HERALD_ORG}&limit=100` },
|
|
1418
1422
|
];
|
|
1419
1423
|
for (const { scope, url } of queries) {
|
|
1420
1424
|
try {
|
|
@@ -1440,14 +1444,14 @@ async function fetchPatternsWithCascade() {
|
|
|
1440
1444
|
// Continue if a level fails
|
|
1441
1445
|
}
|
|
1442
1446
|
}
|
|
1443
|
-
return { patterns, antipatterns, context: `${HERALD_USER}→${HERALD_PROJECT}→${
|
|
1447
|
+
return { patterns, antipatterns, context: `${HERALD_USER}→${HERALD_PROJECT}→${HERALD_ORG}` };
|
|
1444
1448
|
}
|
|
1445
1449
|
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
1446
1450
|
const resources = [
|
|
1447
1451
|
{
|
|
1448
1452
|
uri: "herald://patterns",
|
|
1449
1453
|
name: "Herald Learned Patterns",
|
|
1450
|
-
description: `Patterns and antipatterns learned from past sessions for ${HERALD_USER}→${HERALD_PROJECT}→${
|
|
1454
|
+
description: `Patterns and antipatterns learned from past sessions for ${HERALD_USER}→${HERALD_PROJECT}→${HERALD_ORG}. READ THIS AT SESSION START.`,
|
|
1451
1455
|
mimeType: "text/plain",
|
|
1452
1456
|
},
|
|
1453
1457
|
{
|
|
@@ -1504,7 +1508,7 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
1504
1508
|
}
|
|
1505
1509
|
if (uri === "herald://context") {
|
|
1506
1510
|
const context = {
|
|
1507
|
-
|
|
1511
|
+
org: HERALD_ORG,
|
|
1508
1512
|
project: HERALD_PROJECT,
|
|
1509
1513
|
user: HERALD_USER,
|
|
1510
1514
|
vault: HERALD_VAULT || null,
|
|
@@ -1536,7 +1540,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1536
1540
|
Welcome to Herald - your AI-native interface to CEDA (Cognitive Event-Driven Architecture).
|
|
1537
1541
|
|
|
1538
1542
|
## Current Context
|
|
1539
|
-
- Company: ${
|
|
1543
|
+
- Company: ${HERALD_ORG}
|
|
1540
1544
|
- Project: ${HERALD_PROJECT}
|
|
1541
1545
|
- User: ${HERALD_USER}
|
|
1542
1546
|
|
|
@@ -1597,7 +1601,7 @@ Herald will:
|
|
|
1597
1601
|
const cloudAvailable = !cedaHealth.error;
|
|
1598
1602
|
const config = {
|
|
1599
1603
|
cedaUrl: CEDA_API_URL,
|
|
1600
|
-
|
|
1604
|
+
org: HERALD_ORG,
|
|
1601
1605
|
project: HERALD_PROJECT,
|
|
1602
1606
|
user: HERALD_USER,
|
|
1603
1607
|
vault: HERALD_VAULT || "(not set)",
|
|
@@ -1642,7 +1646,7 @@ Herald will:
|
|
|
1642
1646
|
// Update module-level variables directly
|
|
1643
1647
|
HERALD_USER = newContext.user;
|
|
1644
1648
|
HERALD_TAGS = newContext.tags;
|
|
1645
|
-
|
|
1649
|
+
HERALD_ORG = newContext.tags[0] || "";
|
|
1646
1650
|
HERALD_PROJECT = newContext.tags[1] || newContext.tags[0] || "";
|
|
1647
1651
|
TRUST_LEVEL = newContext.trust;
|
|
1648
1652
|
CONTEXT_SOURCE = newContext.source;
|
|
@@ -1653,7 +1657,7 @@ Herald will:
|
|
|
1653
1657
|
text: JSON.stringify({
|
|
1654
1658
|
refreshed: true,
|
|
1655
1659
|
context: {
|
|
1656
|
-
|
|
1660
|
+
org: HERALD_ORG,
|
|
1657
1661
|
project: HERALD_PROJECT,
|
|
1658
1662
|
user: HERALD_USER,
|
|
1659
1663
|
tags: HERALD_TAGS,
|
|
@@ -1675,7 +1679,7 @@ Herald will:
|
|
|
1675
1679
|
type: "text",
|
|
1676
1680
|
text: JSON.stringify({
|
|
1677
1681
|
context: {
|
|
1678
|
-
|
|
1682
|
+
org: HERALD_ORG,
|
|
1679
1683
|
project: HERALD_PROJECT,
|
|
1680
1684
|
user: HERALD_USER,
|
|
1681
1685
|
tags: HERALD_TAGS,
|
|
@@ -1823,7 +1827,7 @@ Herald will:
|
|
|
1823
1827
|
topic,
|
|
1824
1828
|
targetVault,
|
|
1825
1829
|
sourceVault: HERALD_VAULT || undefined,
|
|
1826
|
-
|
|
1830
|
+
org: HERALD_ORG,
|
|
1827
1831
|
project: HERALD_PROJECT,
|
|
1828
1832
|
user: HERALD_USER,
|
|
1829
1833
|
};
|
|
@@ -1835,7 +1839,7 @@ Herald will:
|
|
|
1835
1839
|
insight,
|
|
1836
1840
|
toContext: targetVault || "all", // Required by CEDA, default to broadcast
|
|
1837
1841
|
topic,
|
|
1838
|
-
fromContext: HERALD_VAULT || `${
|
|
1842
|
+
fromContext: HERALD_VAULT || `${HERALD_ORG}/${HERALD_PROJECT}`,
|
|
1839
1843
|
});
|
|
1840
1844
|
// Check if API returned an error
|
|
1841
1845
|
if (result.error) {
|
|
@@ -1916,12 +1920,29 @@ Herald will:
|
|
|
1916
1920
|
const failed = [];
|
|
1917
1921
|
for (const item of buffer) {
|
|
1918
1922
|
try {
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1923
|
+
let result;
|
|
1924
|
+
// CEDA-100: Route based on buffer item type
|
|
1925
|
+
if (item.type === "reflection") {
|
|
1926
|
+
// Reflections go to /api/herald/reflect (stored in PlanetScale, shown in dashboard)
|
|
1927
|
+
result = await callCedaAPI("/api/herald/reflect", "POST", {
|
|
1928
|
+
session: item.session || item.insight,
|
|
1929
|
+
feeling: item.feeling || "success",
|
|
1930
|
+
insight: item.insight,
|
|
1931
|
+
method: item.method || "direct",
|
|
1932
|
+
org: item.org,
|
|
1933
|
+
project: item.project,
|
|
1934
|
+
user: item.user,
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
else {
|
|
1938
|
+
// Insights (default) go to /api/herald/insight (legacy behavior)
|
|
1939
|
+
result = await callCedaAPI("/api/herald/insight", "POST", {
|
|
1940
|
+
insight: item.insight,
|
|
1941
|
+
topic: item.topic,
|
|
1942
|
+
toContext: item.targetVault || "all",
|
|
1943
|
+
fromContext: item.sourceVault,
|
|
1944
|
+
});
|
|
1945
|
+
}
|
|
1925
1946
|
if (result.error) {
|
|
1926
1947
|
failed.push(item);
|
|
1927
1948
|
}
|
|
@@ -1972,7 +1993,7 @@ Herald will:
|
|
|
1972
1993
|
const status = args?.status;
|
|
1973
1994
|
const limit = args?.limit;
|
|
1974
1995
|
const params = new URLSearchParams();
|
|
1975
|
-
params.set("company", company ||
|
|
1996
|
+
params.set("company", company || HERALD_ORG);
|
|
1976
1997
|
if (project)
|
|
1977
1998
|
params.set("project", project);
|
|
1978
1999
|
if (user)
|
|
@@ -2097,17 +2118,22 @@ Herald will:
|
|
|
2097
2118
|
feeling,
|
|
2098
2119
|
insight: sanitizedInsight, // Sanitized - no PII/secrets transmitted
|
|
2099
2120
|
method: "direct", // Track capture method for meta-learning
|
|
2100
|
-
|
|
2121
|
+
org: HERALD_ORG,
|
|
2101
2122
|
project: HERALD_PROJECT,
|
|
2102
2123
|
user: HERALD_USER,
|
|
2103
2124
|
vault: HERALD_VAULT || undefined,
|
|
2104
2125
|
});
|
|
2105
2126
|
if (result.error) {
|
|
2106
2127
|
// If cloud fails, store locally for later processing (also sanitized)
|
|
2128
|
+
// CEDA-100: Mark as reflection type for proper sync routing
|
|
2107
2129
|
bufferInsight({
|
|
2108
|
-
insight:
|
|
2130
|
+
insight: sanitizedInsight,
|
|
2131
|
+
session: sanitizedSession,
|
|
2132
|
+
feeling,
|
|
2133
|
+
method: "direct",
|
|
2134
|
+
type: "reflection",
|
|
2109
2135
|
topic: feeling === "stuck" ? "antipattern" : "pattern",
|
|
2110
|
-
|
|
2136
|
+
org: HERALD_ORG,
|
|
2111
2137
|
project: HERALD_PROJECT,
|
|
2112
2138
|
user: HERALD_USER,
|
|
2113
2139
|
});
|
|
@@ -2139,7 +2165,7 @@ Herald will:
|
|
|
2139
2165
|
? `Antipattern captured: "${insight}"`
|
|
2140
2166
|
: `Pattern captured: "${insight}"`,
|
|
2141
2167
|
context: {
|
|
2142
|
-
|
|
2168
|
+
org: HERALD_ORG,
|
|
2143
2169
|
project: HERALD_PROJECT,
|
|
2144
2170
|
tags: HERALD_TAGS,
|
|
2145
2171
|
trust: TRUST_LEVEL,
|
|
@@ -2152,10 +2178,15 @@ Herald will:
|
|
|
2152
2178
|
}
|
|
2153
2179
|
catch (error) {
|
|
2154
2180
|
// Network error - buffer locally (sanitized)
|
|
2181
|
+
// CEDA-100: Mark as reflection type for proper sync routing
|
|
2155
2182
|
bufferInsight({
|
|
2156
|
-
insight:
|
|
2183
|
+
insight: sanitizedInsight,
|
|
2184
|
+
session: sanitizedSession,
|
|
2185
|
+
feeling,
|
|
2186
|
+
method: "direct",
|
|
2187
|
+
type: "reflection",
|
|
2157
2188
|
topic: feeling === "stuck" ? "antipattern" : "pattern",
|
|
2158
|
-
|
|
2189
|
+
org: HERALD_ORG,
|
|
2159
2190
|
project: HERALD_PROJECT,
|
|
2160
2191
|
user: HERALD_USER,
|
|
2161
2192
|
});
|
|
@@ -2191,11 +2222,12 @@ Herald will:
|
|
|
2191
2222
|
return true;
|
|
2192
2223
|
}).map(item => ({ ...item, scope }));
|
|
2193
2224
|
};
|
|
2194
|
-
// Cascade queries
|
|
2225
|
+
// CEDA-95: Cascade queries with minLevel=1 to only return graduated patterns (not observations)
|
|
2226
|
+
// Observations (level 0) are raw captures; patterns (level 1+) are validated
|
|
2195
2227
|
const queries = [
|
|
2196
|
-
{ scope: "user", url: `/api/herald/reflections?
|
|
2197
|
-
{ scope: "project", url: `/api/herald/reflections?
|
|
2198
|
-
{ scope: "
|
|
2228
|
+
{ scope: "user", url: `/api/herald/reflections?org=${HERALD_ORG}&project=${HERALD_PROJECT}&user=${HERALD_USER}&limit=100&minLevel=1` },
|
|
2229
|
+
{ scope: "project", url: `/api/herald/reflections?org=${HERALD_ORG}&project=${HERALD_PROJECT}&limit=100&minLevel=1` },
|
|
2230
|
+
{ scope: "org", url: `/api/herald/reflections?org=${HERALD_ORG}&limit=100&minLevel=1` },
|
|
2199
2231
|
];
|
|
2200
2232
|
const patterns = [];
|
|
2201
2233
|
const antipatterns = [];
|
|
@@ -2215,7 +2247,7 @@ Herald will:
|
|
|
2215
2247
|
const metaResult = await callCedaAPI("/api/herald/meta-patterns");
|
|
2216
2248
|
const metaPatterns = metaResult.metaPatterns || [];
|
|
2217
2249
|
// Build readable summary with scope indicators
|
|
2218
|
-
let summary = `## Learned Patterns for ${HERALD_USER}→${HERALD_PROJECT}→${
|
|
2250
|
+
let summary = `## Learned Patterns for ${HERALD_USER}→${HERALD_PROJECT}→${HERALD_ORG}\n\n`;
|
|
2219
2251
|
if (antipatterns.length > 0) {
|
|
2220
2252
|
summary += `### ⚠️ Antipatterns (avoid these)\n`;
|
|
2221
2253
|
antipatterns.forEach((ap, i) => {
|
|
@@ -2244,7 +2276,7 @@ Herald will:
|
|
|
2244
2276
|
summary += `Recommended capture method: ${meta.recommendedMethod} (${(meta.confidence * 100).toFixed(0)}% confidence)\n`;
|
|
2245
2277
|
}
|
|
2246
2278
|
if (patterns.length === 0 && antipatterns.length === 0) {
|
|
2247
|
-
summary = `No patterns learned yet for ${HERALD_USER}→${HERALD_PROJECT}→${
|
|
2279
|
+
summary = `No patterns learned yet for ${HERALD_USER}→${HERALD_PROJECT}→${HERALD_ORG}.\n\nCapture patterns with "herald reflect" or "herald simulate" when you notice friction or flow.`;
|
|
2248
2280
|
}
|
|
2249
2281
|
return {
|
|
2250
2282
|
content: [{
|
|
@@ -2328,17 +2360,22 @@ Herald will:
|
|
|
2328
2360
|
outcome: extracted.outcome,
|
|
2329
2361
|
reinforcement: sanitizedReinforcement,
|
|
2330
2362
|
warning: sanitizedWarning,
|
|
2331
|
-
|
|
2363
|
+
org: HERALD_ORG,
|
|
2332
2364
|
project: HERALD_PROJECT,
|
|
2333
2365
|
user: HERALD_USER,
|
|
2334
2366
|
vault: HERALD_VAULT || undefined,
|
|
2335
2367
|
});
|
|
2336
2368
|
if (result.error) {
|
|
2337
2369
|
// Cloud failed but we have AI extraction - buffer with enriched data (sanitized)
|
|
2370
|
+
// CEDA-100: Mark as reflection type for proper sync routing
|
|
2338
2371
|
bufferInsight({
|
|
2339
|
-
insight:
|
|
2372
|
+
insight: simSanitizedInsight,
|
|
2373
|
+
session: simSanitizedSession,
|
|
2374
|
+
feeling,
|
|
2375
|
+
method: "simulation",
|
|
2376
|
+
type: "reflection",
|
|
2340
2377
|
topic: extracted.outcome,
|
|
2341
|
-
|
|
2378
|
+
org: HERALD_ORG,
|
|
2342
2379
|
project: HERALD_PROJECT,
|
|
2343
2380
|
user: HERALD_USER,
|
|
2344
2381
|
});
|
|
@@ -2446,7 +2483,7 @@ Herald will:
|
|
|
2446
2483
|
patternText,
|
|
2447
2484
|
outcome,
|
|
2448
2485
|
helped: outcome === "helped",
|
|
2449
|
-
|
|
2486
|
+
org: HERALD_ORG,
|
|
2450
2487
|
project: HERALD_PROJECT,
|
|
2451
2488
|
user: HERALD_USER,
|
|
2452
2489
|
});
|
|
@@ -2497,7 +2534,7 @@ Herald will:
|
|
|
2497
2534
|
insight,
|
|
2498
2535
|
scope,
|
|
2499
2536
|
topic,
|
|
2500
|
-
sourceCompany:
|
|
2537
|
+
sourceCompany: HERALD_ORG,
|
|
2501
2538
|
sourceProject: HERALD_PROJECT,
|
|
2502
2539
|
sourceUser: HERALD_USER,
|
|
2503
2540
|
sourceVault: HERALD_VAULT || undefined,
|
|
@@ -2568,7 +2605,7 @@ Herald will:
|
|
|
2568
2605
|
patternId,
|
|
2569
2606
|
sessionId,
|
|
2570
2607
|
all: deleteAll,
|
|
2571
|
-
|
|
2608
|
+
org: HERALD_ORG,
|
|
2572
2609
|
project: HERALD_PROJECT,
|
|
2573
2610
|
user: HERALD_USER,
|
|
2574
2611
|
});
|
|
@@ -2592,7 +2629,7 @@ Herald will:
|
|
|
2592
2629
|
message = `All patterns from session ${sessionId} deleted`;
|
|
2593
2630
|
}
|
|
2594
2631
|
else if (deleteAll) {
|
|
2595
|
-
message = `All patterns for ${
|
|
2632
|
+
message = `All patterns for ${HERALD_ORG}/${HERALD_PROJECT}/${HERALD_USER} deleted`;
|
|
2596
2633
|
}
|
|
2597
2634
|
return {
|
|
2598
2635
|
content: [{
|
|
@@ -2622,7 +2659,7 @@ Herald will:
|
|
|
2622
2659
|
case "herald_export": {
|
|
2623
2660
|
const format = args?.format || "json";
|
|
2624
2661
|
try {
|
|
2625
|
-
const result = await callCedaAPI(`/api/herald/export?
|
|
2662
|
+
const result = await callCedaAPI(`/api/herald/export?org=${HERALD_ORG}&project=${HERALD_PROJECT}&user=${HERALD_USER}&format=${format}`);
|
|
2626
2663
|
if (result.error) {
|
|
2627
2664
|
return {
|
|
2628
2665
|
content: [{
|
|
@@ -2643,7 +2680,7 @@ Herald will:
|
|
|
2643
2680
|
message: `Data exported in ${format.toUpperCase()} format (GDPR Art. 20)`,
|
|
2644
2681
|
gdprArticle: "Article 20 - Right to Data Portability",
|
|
2645
2682
|
format,
|
|
2646
|
-
context: `${
|
|
2683
|
+
context: `${HERALD_ORG}/${HERALD_PROJECT}/${HERALD_USER}`,
|
|
2647
2684
|
...result,
|
|
2648
2685
|
}, null, 2)
|
|
2649
2686
|
}],
|
|
@@ -2734,7 +2771,7 @@ async function verifyWithCeda() {
|
|
|
2734
2771
|
const ctx = result.context;
|
|
2735
2772
|
VERIFIED_CONTEXT = {
|
|
2736
2773
|
verified: true,
|
|
2737
|
-
|
|
2774
|
+
org: (ctx.org || ctx.company),
|
|
2738
2775
|
project: ctx.project,
|
|
2739
2776
|
trust: ctx.trust,
|
|
2740
2777
|
tags: ctx.tags,
|
|
@@ -2743,7 +2780,7 @@ async function verifyWithCeda() {
|
|
|
2743
2780
|
TRUST_LEVEL = VERIFIED_CONTEXT.trust || 'HIGH';
|
|
2744
2781
|
PROPAGATES = true;
|
|
2745
2782
|
CONTEXT_SOURCE = 'verified';
|
|
2746
|
-
console.error(`[Herald] Verified with CEDA: ${VERIFIED_CONTEXT.
|
|
2783
|
+
console.error(`[Herald] Verified with CEDA: ${VERIFIED_CONTEXT.org}/${VERIFIED_CONTEXT.project} (trust: HIGH)`);
|
|
2747
2784
|
}
|
|
2748
2785
|
else {
|
|
2749
2786
|
// Not verified - user not registered or no access to this repo
|
|
@@ -2794,7 +2831,7 @@ async function runMCP() {
|
|
|
2794
2831
|
console.error(`User: ${HERALD_USER} | Tags: [${HERALD_TAGS.join(", ")}]`);
|
|
2795
2832
|
console.error(`Trust: ${TRUST_LEVEL} (${CONTEXT_SOURCE})${PROPAGATES ? " | Propagates: YES" : ""}`);
|
|
2796
2833
|
if (VERIFIED_CONTEXT?.verified) {
|
|
2797
|
-
console.error(`Context: ${VERIFIED_CONTEXT.
|
|
2834
|
+
console.error(`Context: ${VERIFIED_CONTEXT.org}/${VERIFIED_CONTEXT.project} (server-verified)`);
|
|
2798
2835
|
}
|
|
2799
2836
|
// Send startup heartbeat for visibility (non-blocking)
|
|
2800
2837
|
sendStartupHeartbeat();
|