aimeat 1.30.2 → 1.32.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.
Files changed (192) hide show
  1. package/dist/locales/en.json +246 -1
  2. package/dist/locales/fi.json +246 -1
  3. package/dist/public/components/InboxLink.js +29 -0
  4. package/dist/public/components/offer-card-view.js +87 -0
  5. package/dist/public/css/views/companies.css +65 -0
  6. package/dist/public/css/views/inbox.css +153 -1
  7. package/dist/public/css/views/members.css +33 -0
  8. package/dist/public/css/views/my-company.css +315 -0
  9. package/dist/public/css/views/profile.css +22 -0
  10. package/dist/public/js/services/messages.js +21 -3
  11. package/dist/public/js/services/notebook.js +16 -6
  12. package/dist/public/llms-template.txt +7 -0
  13. package/dist/public/spa.html +14 -0
  14. package/dist/public/views/companies.js +190 -0
  15. package/dist/public/views/members.js +42 -0
  16. package/dist/public/views/my-company.js +664 -0
  17. package/dist/public/views/portfolio-themes.js +77 -0
  18. package/dist/public/views/profile/agents-tab.js +4 -1
  19. package/dist/public/views/profile/discover-tab.js +118 -0
  20. package/dist/public/views/profile/inbox-tab.js +663 -16
  21. package/dist/public/views/profile/landing-page.js +2 -1
  22. package/dist/public/views/profile/notebook-card.js +11 -3
  23. package/dist/public/views/profile/offers-tab.js +5 -24
  24. package/dist/public/views/profile/organisms/home.js +5 -3
  25. package/dist/public/views/profile/organisms/mindmap.js +14 -3
  26. package/dist/public/views/profile/organisms/workspace.js +5 -2
  27. package/dist/public/views/profile/organisms-tab.js +12 -4
  28. package/dist/public/views/profile.js +2 -0
  29. package/dist/src/cli/connect/mcp/tools/core.d.ts.map +1 -1
  30. package/dist/src/cli/connect/mcp/tools/core.js +34 -0
  31. package/dist/src/cli/connect/mcp/tools/core.js.map +1 -1
  32. package/dist/src/cli/connect/mcp/tools/dm-messages.d.ts +1 -0
  33. package/dist/src/cli/connect/mcp/tools/dm-messages.d.ts.map +1 -1
  34. package/dist/src/cli/connect/mcp/tools/dm-messages.js +23 -0
  35. package/dist/src/cli/connect/mcp/tools/dm-messages.js.map +1 -1
  36. package/dist/src/cli/connect/mcp/tools/organisms.d.ts.map +1 -1
  37. package/dist/src/cli/connect/mcp/tools/organisms.js +31 -0
  38. package/dist/src/cli/connect/mcp/tools/organisms.js.map +1 -1
  39. package/dist/src/cli/connect/mcp/tools/workspaces.d.ts.map +1 -1
  40. package/dist/src/cli/connect/mcp/tools/workspaces.js +4 -0
  41. package/dist/src/cli/connect/mcp/tools/workspaces.js.map +1 -1
  42. package/dist/src/generated/api-types.d.ts +249 -0
  43. package/dist/src/generated/api-types.d.ts.map +1 -1
  44. package/dist/src/generated/prisma-postgres/edge.js +6 -3
  45. package/dist/src/generated/prisma-postgres/index-browser.js +3 -0
  46. package/dist/src/generated/prisma-postgres/index.d.ts +112 -1
  47. package/dist/src/generated/prisma-postgres/index.js +6 -3
  48. package/dist/src/generated/prisma-postgres/package.json +1 -1
  49. package/dist/src/generated/prisma-postgres/schema.prisma +4 -0
  50. package/dist/src/generated/prisma-postgres/wasm.js +6 -3
  51. package/dist/src/mcp/annotations.d.ts.map +1 -1
  52. package/dist/src/mcp/annotations.js +2 -0
  53. package/dist/src/mcp/annotations.js.map +1 -1
  54. package/dist/src/mcp/catalog/definitions.d.ts.map +1 -1
  55. package/dist/src/mcp/catalog/definitions.js +33 -1
  56. package/dist/src/mcp/catalog/definitions.js.map +1 -1
  57. package/dist/src/mcp/catalog/scopes.d.ts.map +1 -1
  58. package/dist/src/mcp/catalog/scopes.js +1 -0
  59. package/dist/src/mcp/catalog/scopes.js.map +1 -1
  60. package/dist/src/mcp/catalog/surfaces.d.ts.map +1 -1
  61. package/dist/src/mcp/catalog/surfaces.js +7 -4
  62. package/dist/src/mcp/catalog/surfaces.js.map +1 -1
  63. package/dist/src/mcp/core.d.ts.map +1 -1
  64. package/dist/src/mcp/core.js +49 -0
  65. package/dist/src/mcp/core.js.map +1 -1
  66. package/dist/src/mcp/dm-messages.d.ts +2 -0
  67. package/dist/src/mcp/dm-messages.d.ts.map +1 -1
  68. package/dist/src/mcp/dm-messages.js +45 -1
  69. package/dist/src/mcp/dm-messages.js.map +1 -1
  70. package/dist/src/models/message-schemas.d.ts +140 -2
  71. package/dist/src/models/message-schemas.d.ts.map +1 -1
  72. package/dist/src/models/message-schemas.js +60 -3
  73. package/dist/src/models/message-schemas.js.map +1 -1
  74. package/dist/src/routes/bootstrap.d.ts.map +1 -1
  75. package/dist/src/routes/bootstrap.js +3 -0
  76. package/dist/src/routes/bootstrap.js.map +1 -1
  77. package/dist/src/routes/discover.d.ts +22 -0
  78. package/dist/src/routes/discover.d.ts.map +1 -0
  79. package/dist/src/routes/discover.js +123 -0
  80. package/dist/src/routes/discover.js.map +1 -0
  81. package/dist/src/routes/federation-sync.d.ts.map +1 -1
  82. package/dist/src/routes/federation-sync.js +69 -2
  83. package/dist/src/routes/federation-sync.js.map +1 -1
  84. package/dist/src/routes/messages.d.ts.map +1 -1
  85. package/dist/src/routes/messages.js +102 -3
  86. package/dist/src/routes/messages.js.map +1 -1
  87. package/dist/src/routes/organisms.d.ts +3 -0
  88. package/dist/src/routes/organisms.d.ts.map +1 -1
  89. package/dist/src/routes/organisms.js +11 -32
  90. package/dist/src/routes/organisms.js.map +1 -1
  91. package/dist/src/routes/portal.d.ts.map +1 -1
  92. package/dist/src/routes/portal.js +3 -0
  93. package/dist/src/routes/portal.js.map +1 -1
  94. package/dist/src/routes/portfolio.d.ts.map +1 -1
  95. package/dist/src/routes/portfolio.js +30 -0
  96. package/dist/src/routes/portfolio.js.map +1 -1
  97. package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
  98. package/dist/src/server-bootstrap/routes-loader.js +2 -0
  99. package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
  100. package/dist/src/services/connect-tunnel.d.ts +3 -0
  101. package/dist/src/services/connect-tunnel.d.ts.map +1 -1
  102. package/dist/src/services/connect-tunnel.js +6 -0
  103. package/dist/src/services/connect-tunnel.js.map +1 -1
  104. package/dist/src/services/discovery/__tests__/discovery.test.d.ts +2 -0
  105. package/dist/src/services/discovery/__tests__/discovery.test.d.ts.map +1 -0
  106. package/dist/src/services/discovery/__tests__/discovery.test.js +178 -0
  107. package/dist/src/services/discovery/__tests__/discovery.test.js.map +1 -0
  108. package/dist/src/services/discovery/classify.d.ts +36 -0
  109. package/dist/src/services/discovery/classify.d.ts.map +1 -0
  110. package/dist/src/services/discovery/classify.js +61 -0
  111. package/dist/src/services/discovery/classify.js.map +1 -0
  112. package/dist/src/services/discovery/facets.d.ts +21 -0
  113. package/dist/src/services/discovery/facets.d.ts.map +1 -0
  114. package/dist/src/services/discovery/facets.js +0 -0
  115. package/dist/src/services/discovery/facets.js.map +1 -0
  116. package/dist/src/services/discovery/index.d.ts +22 -0
  117. package/dist/src/services/discovery/index.d.ts.map +1 -0
  118. package/dist/src/services/discovery/index.js +22 -0
  119. package/dist/src/services/discovery/index.js.map +1 -0
  120. package/dist/src/services/discovery/normalize.d.ts +25 -0
  121. package/dist/src/services/discovery/normalize.d.ts.map +1 -0
  122. package/dist/src/services/discovery/normalize.js +108 -0
  123. package/dist/src/services/discovery/normalize.js.map +1 -0
  124. package/dist/src/services/discovery/registry.d.ts +30 -0
  125. package/dist/src/services/discovery/registry.d.ts.map +1 -0
  126. package/dist/src/services/discovery/registry.js +31 -0
  127. package/dist/src/services/discovery/registry.js.map +1 -0
  128. package/dist/src/services/discovery/run.d.ts +23 -0
  129. package/dist/src/services/discovery/run.d.ts.map +1 -0
  130. package/dist/src/services/discovery/run.js +20 -0
  131. package/dist/src/services/discovery/run.js.map +1 -0
  132. package/dist/src/services/discovery/setup.d.ts +16 -0
  133. package/dist/src/services/discovery/setup.d.ts.map +1 -0
  134. package/dist/src/services/discovery/setup.js +12 -0
  135. package/dist/src/services/discovery/setup.js.map +1 -0
  136. package/dist/src/services/discovery/sources/memory-source.d.ts +24 -0
  137. package/dist/src/services/discovery/sources/memory-source.d.ts.map +1 -0
  138. package/dist/src/services/discovery/sources/memory-source.js +183 -0
  139. package/dist/src/services/discovery/sources/memory-source.js.map +1 -0
  140. package/dist/src/services/discovery/sources/table-sources.d.ts +27 -0
  141. package/dist/src/services/discovery/sources/table-sources.d.ts.map +1 -0
  142. package/dist/src/services/discovery/sources/table-sources.js +128 -0
  143. package/dist/src/services/discovery/sources/table-sources.js.map +1 -0
  144. package/dist/src/services/discovery/types.d.ts +117 -0
  145. package/dist/src/services/discovery/types.d.ts.map +1 -0
  146. package/dist/src/services/discovery/types.js +19 -0
  147. package/dist/src/services/discovery/types.js.map +1 -0
  148. package/dist/src/services/handbooks/agent.d.ts +1 -1
  149. package/dist/src/services/handbooks/agent.d.ts.map +1 -1
  150. package/dist/src/services/handbooks/agent.js +9 -3
  151. package/dist/src/services/handbooks/agent.js.map +1 -1
  152. package/dist/src/services/message-broadcast.d.ts +49 -0
  153. package/dist/src/services/message-broadcast.d.ts.map +1 -0
  154. package/dist/src/services/message-broadcast.js +116 -0
  155. package/dist/src/services/message-broadcast.js.map +1 -0
  156. package/dist/src/services/message-delivery.d.ts.map +1 -1
  157. package/dist/src/services/message-delivery.js +3 -0
  158. package/dist/src/services/message-delivery.js.map +1 -1
  159. package/dist/src/services/message-send.d.ts +9 -1
  160. package/dist/src/services/message-send.d.ts.map +1 -1
  161. package/dist/src/services/message-send.js +11 -5
  162. package/dist/src/services/message-send.js.map +1 -1
  163. package/dist/src/services/presence.d.ts +8 -0
  164. package/dist/src/services/presence.d.ts.map +1 -1
  165. package/dist/src/services/presence.js +38 -0
  166. package/dist/src/services/presence.js.map +1 -1
  167. package/dist/src/services/workspace-enrichment.d.ts +15 -5
  168. package/dist/src/services/workspace-enrichment.d.ts.map +1 -1
  169. package/dist/src/services/workspace-enrichment.js +52 -14
  170. package/dist/src/services/workspace-enrichment.js.map +1 -1
  171. package/dist/src/storage/interface.d.ts +49 -0
  172. package/dist/src/storage/interface.d.ts.map +1 -1
  173. package/dist/src/storage/providers/mongodb/index.d.ts +1 -0
  174. package/dist/src/storage/providers/mongodb/index.d.ts.map +1 -1
  175. package/dist/src/storage/providers/mongodb/index.js +16 -0
  176. package/dist/src/storage/providers/mongodb/index.js.map +1 -1
  177. package/dist/src/storage/providers/sqlite/index.d.ts +1 -0
  178. package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -1
  179. package/dist/src/storage/providers/sqlite/index.js +3 -0
  180. package/dist/src/storage/providers/sqlite/index.js.map +1 -1
  181. package/dist/src/storage/providers/sqlite/repos/direct-message.d.ts +3 -0
  182. package/dist/src/storage/providers/sqlite/repos/direct-message.d.ts.map +1 -1
  183. package/dist/src/storage/providers/sqlite/repos/direct-message.js +15 -2
  184. package/dist/src/storage/providers/sqlite/repos/direct-message.js.map +1 -1
  185. package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
  186. package/dist/src/storage/providers/sqlite/schema.js +10 -0
  187. package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
  188. package/dist/src/storage/repositories/direct-message.repository.d.ts +3 -0
  189. package/dist/src/storage/repositories/direct-message.repository.d.ts.map +1 -1
  190. package/package.json +1 -1
  191. package/prisma/schema.postgres.prisma +4 -0
  192. package/prisma/schema.prisma +4 -0
@@ -0,0 +1,178 @@
1
+ /**
2
+ * @file discovery.test.ts
3
+ * @description Unit tests for the Phase 0 discovery building blocks: normalizer (visibility/tags/
4
+ * owner/text), classifier (key patterns + kind: tags), registry, and facet/filter helpers.
5
+ * Pure-function coverage — no server, no storage. Run with `pnpm test` (vitest).
6
+ * @version-history
7
+ * v0.1.0 — 2026-06-23 — Phase 0 initial coverage (design doc 2026-06-23-master-directory-discovery).
8
+ */
9
+ import { describe, it, expect } from 'vitest';
10
+ import { normalizeVisibility, parkedToVisibility, listedToVisibility, normalizeTags, toFullOwner, bestTitle, bestDescription, } from '../normalize.js';
11
+ import { classifyMemoryKey, kindTagType } from '../classify.js';
12
+ import { createRegistry } from '../registry.js';
13
+ import { applyFilters, computeFacets } from '../facets.js';
14
+ const NODE = 'aimeat-fi-001-genesis';
15
+ describe('normalizeVisibility', () => {
16
+ it('maps each native enum to the canonical ladder', () => {
17
+ expect(normalizeVisibility('public')).toBe('public');
18
+ expect(normalizeVisibility('listed')).toBe('unlisted'); // organism
19
+ expect(normalizeVisibility('unlisted')).toBe('unlisted'); // offer
20
+ expect(normalizeVisibility('group')).toBe('shared'); // memory
21
+ expect(normalizeVisibility('shared')).toBe('shared'); // board
22
+ expect(normalizeVisibility('owner')).toBe('owner');
23
+ expect(normalizeVisibility('private')).toBe('private');
24
+ });
25
+ it('defaults unknown / empty to the most restrictive (private)', () => {
26
+ expect(normalizeVisibility('system')).toBe('private');
27
+ expect(normalizeVisibility(undefined)).toBe('private');
28
+ expect(normalizeVisibility('')).toBe('private');
29
+ });
30
+ it('derives visibility from parked / listed flags', () => {
31
+ expect(parkedToVisibility(true)).toBe('owner');
32
+ expect(parkedToVisibility(false)).toBe('public');
33
+ expect(listedToVisibility(false)).toBe('owner');
34
+ expect(listedToVisibility(true)).toBe('public');
35
+ expect(listedToVisibility(undefined)).toBe('public'); // default listed
36
+ });
37
+ });
38
+ describe('normalizeTags', () => {
39
+ it('merges tags + interests, trims, drops empties, dedupes case-insensitively', () => {
40
+ expect(normalizeTags({ tags: ['Finance', ' legal '], interests: ['finance', 'AI', ''] })).toEqual([
41
+ 'Finance',
42
+ 'legal',
43
+ 'AI',
44
+ ]);
45
+ });
46
+ it('tolerates missing / non-array fields', () => {
47
+ expect(normalizeTags(null)).toEqual([]);
48
+ expect(normalizeTags({})).toEqual([]);
49
+ expect(normalizeTags({ tags: 'nope' })).toEqual([]);
50
+ });
51
+ });
52
+ describe('toFullOwner', () => {
53
+ it('expands a bare name to a GHII', () => {
54
+ expect(toFullOwner('alice', NODE)).toBe(`alice@${NODE}`);
55
+ });
56
+ it('passes a GHII through', () => {
57
+ expect(toFullOwner('alice@some-node', NODE)).toBe('alice@some-node');
58
+ });
59
+ it('drops the agent part of a GAII', () => {
60
+ expect(toFullOwner('claude#alice@some-node', NODE)).toBe('alice@some-node');
61
+ });
62
+ });
63
+ describe('bestTitle / bestDescription', () => {
64
+ it('picks the first present title-ish / description-ish field', () => {
65
+ expect(bestTitle({ name: 'Q3 plan' }, 'fallback')).toBe('Q3 plan');
66
+ expect(bestTitle({ nothing: 1 }, 'fallback')).toBe('fallback');
67
+ expect(bestDescription({ ask: 'do the thing' })).toBe('do the thing');
68
+ expect(bestDescription('a string')).toBe('');
69
+ });
70
+ });
71
+ describe('classifyMemoryKey', () => {
72
+ it('classifies knowledge packages with content_type as segment', () => {
73
+ expect(classifyMemoryKey('packages/abc-123/manifest', { contentType: 'research' })).toEqual({
74
+ type: 'knowledge',
75
+ segment: 'research',
76
+ });
77
+ });
78
+ it('classifies workspace decision records', () => {
79
+ expect(classifyMemoryKey('organism.org7.w.budget.decision.d1')).toEqual({
80
+ type: 'decision',
81
+ segment: 'budget',
82
+ });
83
+ });
84
+ it('classifies other workspace docs by their space (objectType)', () => {
85
+ expect(classifyMemoryKey('organism.org7.w.specs.feature.f9')).toEqual({
86
+ type: 'document',
87
+ segment: 'feature',
88
+ });
89
+ });
90
+ it('classifies workflows, companies and offerings by key', () => {
91
+ expect(classifyMemoryKey('workflows.def.wf1').type).toBe('workflow');
92
+ expect(classifyMemoryKey('org.acme.meta').type).toBe('company');
93
+ expect(classifyMemoryKey('org.acme.offerings').type).toBe('offering');
94
+ expect(classifyMemoryKey('agents.bot.offers').type).toBe('offering');
95
+ });
96
+ it('falls back to the kind: tag, then to memory', () => {
97
+ expect(classifyMemoryKey('notes.misc', { tags: ['kind:research'] }).type).toBe('research');
98
+ expect(classifyMemoryKey('notes.misc', { tags: ['kind:deliverable'] }).type).toBe('material');
99
+ expect(classifyMemoryKey('notes.misc', { tags: ['unrelated'] }).type).toBe('memory');
100
+ expect(classifyMemoryKey('notes.misc').type).toBe('memory');
101
+ });
102
+ });
103
+ describe('kindTagType', () => {
104
+ it('recognizes research/material synonyms only', () => {
105
+ expect(kindTagType(['kind:research'])).toBe('research');
106
+ expect(kindTagType(['kind:material'])).toBe('material');
107
+ expect(kindTagType(['kind:output'])).toBe('material');
108
+ expect(kindTagType(['kind:unknown'])).toBeNull();
109
+ expect(kindTagType(undefined)).toBeNull();
110
+ });
111
+ });
112
+ describe('DiscoveryRegistry', () => {
113
+ const stub = (id) => ({
114
+ id,
115
+ gating: 'none',
116
+ enumerate: async () => [],
117
+ toEntry: r => r,
118
+ });
119
+ it('registers, retrieves, and lists in order', () => {
120
+ const reg = createRegistry();
121
+ reg.register(stub('a'));
122
+ reg.register(stub('b'));
123
+ expect(reg.size).toBe(2);
124
+ expect(reg.has('a')).toBe(true);
125
+ expect(reg.all().map(s => s.id)).toEqual(['a', 'b']);
126
+ });
127
+ it('throws on duplicate id and supports unregister', () => {
128
+ const reg = createRegistry();
129
+ reg.register(stub('a'));
130
+ expect(() => reg.register(stub('a'))).toThrow(/already registered/);
131
+ expect(reg.unregister('a')).toBe(true);
132
+ expect(reg.unregister('a')).toBe(false);
133
+ });
134
+ });
135
+ describe('applyFilters + computeFacets', () => {
136
+ const entry = (over) => ({
137
+ type: 'memory',
138
+ segment: null,
139
+ id: 'x',
140
+ title: 't',
141
+ description: '',
142
+ tags: [],
143
+ visibility: 'public',
144
+ owner: `alice@${NODE}`,
145
+ node: NODE,
146
+ score: 0,
147
+ updatedAt: '2026-06-23T00:00:00Z',
148
+ href: '/v1/memory/x',
149
+ ...over,
150
+ });
151
+ const entries = [
152
+ entry({ type: 'knowledge', segment: 'research', tags: ['finance', 'ai'] }),
153
+ entry({ type: 'knowledge', segment: 'research', tags: ['finance'] }),
154
+ entry({ type: 'capability', segment: 'action', tags: ['ai'], owner: `bob@${NODE}` }),
155
+ entry({ type: 'memory', segment: null, tags: [] }),
156
+ ];
157
+ it('filters by type', () => {
158
+ expect(applyFilters(entries, { types: ['knowledge'] })).toHaveLength(2);
159
+ });
160
+ it('filters by segment', () => {
161
+ expect(applyFilters(entries, { segments: ['research'] })).toHaveLength(2);
162
+ });
163
+ it('filters by owner', () => {
164
+ expect(applyFilters(entries, { owner: `bob@${NODE}` })).toHaveLength(1);
165
+ });
166
+ it('ALL-matches tags case-insensitively', () => {
167
+ expect(applyFilters(entries, { tags: ['Finance', 'AI'] })).toHaveLength(1);
168
+ expect(applyFilters(entries, { tags: ['finance'] })).toHaveLength(2);
169
+ });
170
+ it('rolls up facets sorted by count', () => {
171
+ const f = computeFacets(entries);
172
+ expect(f.types[0]).toEqual({ value: 'knowledge', count: 2 });
173
+ expect(f.segments[0]).toEqual({ type: 'knowledge', segment: 'research', count: 2 });
174
+ expect(f.tags.find(t => t.value === 'finance')?.count).toBe(2);
175
+ expect(f.tags.find(t => t.value === 'ai')?.count).toBe(2);
176
+ });
177
+ });
178
+ //# sourceMappingURL=discovery.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.test.js","sourceRoot":"","sources":["../../../../../src/services/discovery/__tests__/discovery.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @file classify.ts
3
+ * @description The classifier — the "different perspectives" engine (design §4.2). Maps a memory key
4
+ * pattern (and, as a fallback, a `kind:` tag convention) to a `DiscoveryType` + `segment`. This is
5
+ * the single place new memory-keyed content types are taught to the directory: add a pattern here
6
+ * and the FTS adapter surfaces them automatically (design §7.2, path 1). Pure functions only.
7
+ * @structure
8
+ * - classifyMemoryKey() — key pattern → { type, segment }
9
+ * - kindTagType() — `kind:` tag → DiscoveryType | null (research/material taxonomy, §11.1)
10
+ * - key matchers (ORG / PKG / WF / ORG_META / ORG_OFFERS / AGENT_OFFERS)
11
+ * @usage
12
+ * const { type, segment } = classifyMemoryKey(key, { tags, contentType });
13
+ * @version-history
14
+ * v0.1.0 — 2026-06-23 — Phase 0: key-pattern + kind-tag classifier (design doc 2026-06-23).
15
+ */
16
+ import type { DiscoveryType } from './types.js';
17
+ export interface ClassifyHints {
18
+ /** Native tags on the record (used for the `kind:` fallback). */
19
+ tags?: string[];
20
+ /** Knowledge manifest content_type, when the caller already has it. */
21
+ contentType?: string;
22
+ }
23
+ /**
24
+ * Map a `kind:` tag to a type. Only the free-text taxonomy is tag-driven (research/material);
25
+ * everything else is key-pattern classified. Returns null when no recognized `kind:` tag is present.
26
+ */
27
+ export declare function kindTagType(tags: string[] | undefined): DiscoveryType | null;
28
+ /**
29
+ * Classify a memory record by its key (and tags as a fallback) into a type + segment.
30
+ * Key patterns win; unrecognized keys fall back to the `kind:` tag, then to plain `memory`.
31
+ */
32
+ export declare function classifyMemoryKey(key: string, hints?: ClassifyHints): {
33
+ type: DiscoveryType;
34
+ segment: string | null;
35
+ };
36
+ //# sourceMappingURL=classify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../../../src/services/discovery/classify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAShD,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,aAAa,GAAG,IAAI,CAiB5E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,KAAK,GAAE,aAAkB,GACxB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CA8BjD"}
@@ -0,0 +1,61 @@
1
+ const ORG_KEY = /^organism\.([^.]+)\.w\.([^.]+)\.([^.]+)/; // organism.{id}.w.{ws}.{space}…
2
+ const PKG_KEY = /^packages\/([^/]+)\//; // packages/{id}/…
3
+ const WF_KEY = /^workflows\.def\.([^.]+)/; // workflows.def.{id}
4
+ const ORG_META = /^org\.([^.]+)\.meta$/; // org.{slug}.meta
5
+ const ORG_OFFERS = /^org\.([^.]+)\.offerings$/; // org.{slug}.offerings
6
+ const AGENT_OFFERS = /^agents\.([^.]+)\.offers$/; // agents.{name}.offers
7
+ /**
8
+ * Map a `kind:` tag to a type. Only the free-text taxonomy is tag-driven (research/material);
9
+ * everything else is key-pattern classified. Returns null when no recognized `kind:` tag is present.
10
+ */
11
+ export function kindTagType(tags) {
12
+ if (!tags)
13
+ return null;
14
+ for (const t of tags) {
15
+ if (typeof t !== 'string' || !t.toLowerCase().startsWith('kind:'))
16
+ continue;
17
+ const suffix = t.slice(t.indexOf(':') + 1).trim().toLowerCase();
18
+ switch (suffix) {
19
+ case 'research':
20
+ return 'research';
21
+ case 'material':
22
+ case 'deliverable':
23
+ case 'output':
24
+ return 'material';
25
+ default:
26
+ return null;
27
+ }
28
+ }
29
+ return null;
30
+ }
31
+ /**
32
+ * Classify a memory record by its key (and tags as a fallback) into a type + segment.
33
+ * Key patterns win; unrecognized keys fall back to the `kind:` tag, then to plain `memory`.
34
+ */
35
+ export function classifyMemoryKey(key, hints = {}) {
36
+ let m;
37
+ if (PKG_KEY.test(key)) {
38
+ return { type: 'knowledge', segment: hints.contentType ?? null };
39
+ }
40
+ if ((m = key.match(ORG_KEY))) {
41
+ const workspace = m[2];
42
+ const space = m[3];
43
+ if (space === 'decision')
44
+ return { type: 'decision', segment: workspace };
45
+ return { type: 'document', segment: space };
46
+ }
47
+ if (WF_KEY.test(key)) {
48
+ return { type: 'workflow', segment: null };
49
+ }
50
+ if (ORG_META.test(key)) {
51
+ return { type: 'company', segment: null };
52
+ }
53
+ if (ORG_OFFERS.test(key) || AGENT_OFFERS.test(key)) {
54
+ return { type: 'offering', segment: null };
55
+ }
56
+ const kind = kindTagType(hints.tags);
57
+ if (kind)
58
+ return { type: kind, segment: null };
59
+ return { type: 'memory', segment: null };
60
+ }
61
+ //# sourceMappingURL=classify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify.js","sourceRoot":"","sources":["../../../../src/services/discovery/classify.ts"],"names":[],"mappings":"AAiBA,MAAM,OAAO,GAAG,yCAAyC,CAAC,CAAC,gCAAgC;AAC3F,MAAM,OAAO,GAAG,sBAAsB,CAAC,CAAC,kBAAkB;AAC1D,MAAM,MAAM,GAAG,0BAA0B,CAAC,CAAC,qBAAqB;AAChE,MAAM,QAAQ,GAAG,sBAAsB,CAAC,CAAC,kBAAkB;AAC3D,MAAM,UAAU,GAAG,2BAA2B,CAAC,CAAC,uBAAuB;AACvE,MAAM,YAAY,GAAG,2BAA2B,CAAC,CAAC,uBAAuB;AASzE;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAA0B;IACpD,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,SAAS;QAC5E,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAChE,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,UAAU;gBACb,OAAO,UAAU,CAAC;YACpB,KAAK,UAAU,CAAC;YAChB,KAAK,aAAa,CAAC;YACnB,KAAK,QAAQ;gBACX,OAAO,UAAU,CAAC;YACpB;gBACE,OAAO,IAAI,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAW,EACX,QAAuB,EAAE;IAEzB,IAAI,CAA0B,CAAC;IAE/B,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;IACnE,CAAC;IAED,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,KAAK,KAAK,UAAU;YAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;QAC1E,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC9C,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7C,CAAC;IAED,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC5C,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7C,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAE/C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @file facets.ts
3
+ * @description Pure entry-level operations used by both modes of `/v1/discover` (design §4.3/§4.4):
4
+ * `applyFilters` narrows a normalized entry set (type / segment / tag ALL-match / owner), and
5
+ * `computeFacets` rolls the (already access-gated) set up into the map-mode catalog-of-catalogs.
6
+ * These run AFTER gating, so counts never leak content the caller cannot read. No I/O.
7
+ * @structure
8
+ * - applyFilters() — entry[] + filters → entry[]
9
+ * - computeFacets() — entry[] → { types, segments, tags } counts
10
+ * @usage
11
+ * const visible = applyFilters(entries, ctx.filters);
12
+ * const facets = computeFacets(visible);
13
+ * @version-history
14
+ * v0.1.0 — 2026-06-23 — Phase 0: pure filter + facet roll-up (design doc 2026-06-23).
15
+ */
16
+ import type { DiscoveryEntry, DiscoveryFacets, DiscoveryFilters } from './types.js';
17
+ /** Narrow entries by the query filters. `q` is handled upstream by FTS, not here. */
18
+ export declare function applyFilters(entries: DiscoveryEntry[], filters: DiscoveryFilters): DiscoveryEntry[];
19
+ /** Roll a gated, filtered entry set up into facet counts for map mode. */
20
+ export declare function computeFacets(entries: DiscoveryEntry[]): DiscoveryFacets;
21
+ //# sourceMappingURL=facets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facets.d.ts","sourceRoot":"","sources":["../../../../src/services/discovery/facets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAA6B,MAAM,YAAY,CAAC;AAE/G,qFAAqF;AACrF,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,gBAAgB,GAAG,cAAc,EAAE,CAgBnG;AAQD,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,eAAe,CA4BxE"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facets.js","sourceRoot":"","sources":["../../../../src/services/discovery/facets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @file index.ts
3
+ * @description Barrel for the discovery (master directory) service. Re-exports the Phase 0 building
4
+ * blocks — types, normalizer, classifier, registry, facet helpers — so consumers import from one
5
+ * path. Later phases add the FTS/table source adapters and the `/v1/discover` route on top of these.
6
+ * @structure re-exports from ./types, ./normalize, ./classify, ./registry, ./facets
7
+ * @usage import { createRegistry, classifyMemoryKey, normalizeVisibility } from '../discovery/index.js';
8
+ * @version-history
9
+ * v0.1.0 — 2026-06-23 — Phase 0: barrel for pure building blocks (design doc 2026-06-23).
10
+ * v0.2.0 — 2026-06-23 — Phase 1: export orchestrator (run) + memory/FTS source adapter.
11
+ * v0.3.0 — 2026-06-23 — Phase 2: export capabilities / apps / agent-task table source adapters.
12
+ */
13
+ export * from './types.js';
14
+ export * from './normalize.js';
15
+ export * from './classify.js';
16
+ export * from './registry.js';
17
+ export * from './facets.js';
18
+ export * from './run.js';
19
+ export { createMemorySource, MEMORY_SOURCE_ID } from './sources/memory-source.js';
20
+ export { createCapabilitiesSource, createAppsSource, createAgentTasksSource, CAPABILITIES_SOURCE_ID, APPS_SOURCE_ID, AGENT_TASKS_SOURCE_ID, } from './sources/table-sources.js';
21
+ export { buildDiscoveryRegistry } from './setup.js';
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/services/discovery/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,EACL,wBAAwB,EAAE,gBAAgB,EAAE,sBAAsB,EAClE,sBAAsB,EAAE,cAAc,EAAE,qBAAqB,GAC9D,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @file index.ts
3
+ * @description Barrel for the discovery (master directory) service. Re-exports the Phase 0 building
4
+ * blocks — types, normalizer, classifier, registry, facet helpers — so consumers import from one
5
+ * path. Later phases add the FTS/table source adapters and the `/v1/discover` route on top of these.
6
+ * @structure re-exports from ./types, ./normalize, ./classify, ./registry, ./facets
7
+ * @usage import { createRegistry, classifyMemoryKey, normalizeVisibility } from '../discovery/index.js';
8
+ * @version-history
9
+ * v0.1.0 — 2026-06-23 — Phase 0: barrel for pure building blocks (design doc 2026-06-23).
10
+ * v0.2.0 — 2026-06-23 — Phase 1: export orchestrator (run) + memory/FTS source adapter.
11
+ * v0.3.0 — 2026-06-23 — Phase 2: export capabilities / apps / agent-task table source adapters.
12
+ */
13
+ export * from './types.js';
14
+ export * from './normalize.js';
15
+ export * from './classify.js';
16
+ export * from './registry.js';
17
+ export * from './facets.js';
18
+ export * from './run.js';
19
+ export { createMemorySource, MEMORY_SOURCE_ID } from './sources/memory-source.js';
20
+ export { createCapabilitiesSource, createAppsSource, createAgentTasksSource, CAPABILITIES_SOURCE_ID, APPS_SOURCE_ID, AGENT_TASKS_SOURCE_ID, } from './sources/table-sources.js';
21
+ export { buildDiscoveryRegistry } from './setup.js';
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/services/discovery/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,EACL,wBAAwB,EAAE,gBAAgB,EAAE,sBAAsB,EAClE,sBAAsB,EAAE,cAAc,EAAE,qBAAqB,GAC9D,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { CanonicalVisibility } from './types.js';
2
+ /** Map any domain's native visibility string to the canonical ladder. Unknown → 'private' (safe). */
3
+ export declare function normalizeVisibility(raw: string | null | undefined): CanonicalVisibility;
4
+ /** App visibility derives from the `parked` flag (parked = hidden from catalogue). */
5
+ export declare function parkedToVisibility(parked: boolean | undefined): CanonicalVisibility;
6
+ /** Company visibility derives from the `listed` flag (listed=false → off the public directory). */
7
+ export declare function listedToVisibility(listed: boolean | undefined): CanonicalVisibility;
8
+ /** Merge native `tags[]` and `interests[]` into one trimmed, de-duplicated, order-preserving list. */
9
+ export declare function normalizeTags(rec: {
10
+ tags?: unknown;
11
+ interests?: unknown;
12
+ } | null | undefined): string[];
13
+ /**
14
+ * Coerce any identity form to a full owner GHII `owner@node-id`:
15
+ * - bare name "alice" → "alice@<nodeId>"
16
+ * - GHII "alice@node" → "alice@node"
17
+ * - GAII "claude#alice@node" → "alice@node" (agent part dropped)
18
+ * Falls back to `<idOrName>@<nodeId>` if the string can't be parsed.
19
+ */
20
+ export declare function toFullOwner(idOrName: string, nodeId: string): string;
21
+ /** Schema-agnostic title: first non-empty of common title-ish fields, else the fallback. */
22
+ export declare function bestTitle(value: unknown, fallback: string): string;
23
+ /** Schema-agnostic description: first non-empty of common description-ish fields, else ''. */
24
+ export declare function bestDescription(value: unknown): string;
25
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../src/services/discovery/normalize.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,qGAAqG;AACrG,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,mBAAmB,CAiBvF;AAED,sFAAsF;AACtF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,mBAAmB,CAEnF;AAED,mGAAmG;AACnG,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,mBAAmB,CAEnF;AAED,sGAAsG;AACtG,wBAAgB,aAAa,CAAC,GAAG,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,EAAE,CAgBvG;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAOpE;AAED,4FAA4F;AAC5F,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CASlE;AAED,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAStD"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * @file normalize.ts
3
+ * @description Pure normalization helpers that collapse each domain's divergent fields into the
4
+ * canonical `DiscoveryEntry` vocabulary (design §5): visibility enums → one ladder, `tags[]` /
5
+ * `interests[]` → one deduped tag list, and any bare-name / GHII / GAII owner → a full
6
+ * `owner@node-id` GHII. No storage access, no side effects — trivially unit-testable.
7
+ * @structure
8
+ * - normalizeVisibility() / parkedToVisibility() / listedToVisibility() — visibility mapping
9
+ * - normalizeTags() — merge + clean tags and interests
10
+ * - toFullOwner() — any identity form → owner@node-id
11
+ * - bestDescription() / bestTitle() — schema-agnostic text extraction
12
+ * @usage
13
+ * import { normalizeVisibility, normalizeTags, toFullOwner } from '../discovery/normalize.js';
14
+ * @version-history
15
+ * v0.1.0 — 2026-06-23 — Phase 0: initial mapping tables (design doc 2026-06-23).
16
+ */
17
+ import { parseGaiiLoose } from '../../utils/gaii.js';
18
+ /** Map any domain's native visibility string to the canonical ladder. Unknown → 'private' (safe). */
19
+ export function normalizeVisibility(raw) {
20
+ switch ((raw ?? '').toLowerCase()) {
21
+ case 'public':
22
+ return 'public';
23
+ case 'unlisted':
24
+ case 'listed': // organism "listed" = discoverable-but-not-promoted
25
+ return 'unlisted';
26
+ case 'group':
27
+ case 'shared':
28
+ return 'shared';
29
+ case 'owner':
30
+ return 'owner';
31
+ case 'private':
32
+ return 'private';
33
+ default:
34
+ return 'private';
35
+ }
36
+ }
37
+ /** App visibility derives from the `parked` flag (parked = hidden from catalogue). */
38
+ export function parkedToVisibility(parked) {
39
+ return parked ? 'owner' : 'public';
40
+ }
41
+ /** Company visibility derives from the `listed` flag (listed=false → off the public directory). */
42
+ export function listedToVisibility(listed) {
43
+ return listed === false ? 'owner' : 'public';
44
+ }
45
+ /** Merge native `tags[]` and `interests[]` into one trimmed, de-duplicated, order-preserving list. */
46
+ export function normalizeTags(rec) {
47
+ const out = [];
48
+ const seen = new Set();
49
+ for (const field of [rec?.tags, rec?.interests]) {
50
+ if (!Array.isArray(field))
51
+ continue;
52
+ for (const t of field) {
53
+ if (typeof t !== 'string')
54
+ continue;
55
+ const v = t.trim();
56
+ if (!v)
57
+ continue;
58
+ const k = v.toLowerCase();
59
+ if (seen.has(k))
60
+ continue;
61
+ seen.add(k);
62
+ out.push(v);
63
+ }
64
+ }
65
+ return out;
66
+ }
67
+ /**
68
+ * Coerce any identity form to a full owner GHII `owner@node-id`:
69
+ * - bare name "alice" → "alice@<nodeId>"
70
+ * - GHII "alice@node" → "alice@node"
71
+ * - GAII "claude#alice@node" → "alice@node" (agent part dropped)
72
+ * Falls back to `<idOrName>@<nodeId>` if the string can't be parsed.
73
+ */
74
+ export function toFullOwner(idOrName, nodeId) {
75
+ if (!idOrName)
76
+ return `@${nodeId}`;
77
+ if (idOrName.includes('@')) {
78
+ const { owner, node } = parseGaiiLoose(idOrName);
79
+ if (owner)
80
+ return `${owner}@${node || nodeId}`;
81
+ }
82
+ return `${idOrName}@${nodeId}`;
83
+ }
84
+ /** Schema-agnostic title: first non-empty of common title-ish fields, else the fallback. */
85
+ export function bestTitle(value, fallback) {
86
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
87
+ const v = value;
88
+ for (const k of ['title', 'name', 'displayName', 'label', 'heading']) {
89
+ const s = v[k];
90
+ if (typeof s === 'string' && s.trim())
91
+ return s.trim();
92
+ }
93
+ }
94
+ return fallback;
95
+ }
96
+ /** Schema-agnostic description: first non-empty of common description-ish fields, else ''. */
97
+ export function bestDescription(value) {
98
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
99
+ const v = value;
100
+ for (const k of ['description', 'summary', 'ask', 'desc', 'body', 'text']) {
101
+ const s = v[k];
102
+ if (typeof s === 'string' && s.trim())
103
+ return s.trim();
104
+ }
105
+ }
106
+ return '';
107
+ }
108
+ //# sourceMappingURL=normalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../../../src/services/discovery/normalize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @file registry.ts
3
+ * @description The `DiscoverySource` registry — the backbone that makes the directory extensible
4
+ * (design §3, §7). The `/v1/discover` handler iterates this registry instead of hardcoding domains;
5
+ * adding a new content type means registering one adapter. Pure in-memory container with no I/O.
6
+ * @structure
7
+ * - DiscoveryRegistry — register / unregister / get / all
8
+ * - createRegistry() — factory (tests build isolated registries; server builds one shared)
9
+ * @usage
10
+ * const reg = createRegistry();
11
+ * reg.register(memoryFtsSource);
12
+ * for (const src of reg.all()) await src.enumerate(ctx);
13
+ * @version-history
14
+ * v0.1.0 — 2026-06-23 — Phase 0: registry + adapter seam (design doc 2026-06-23).
15
+ */
16
+ import type { DiscoverySource } from './types.js';
17
+ export declare class DiscoveryRegistry {
18
+ private readonly sources;
19
+ /** Register a source. Throws on duplicate id (a programming error — ids must be unique). */
20
+ register(source: DiscoverySource): void;
21
+ /** Remove a source by id. Returns true if it existed. */
22
+ unregister(id: string): boolean;
23
+ get(id: string): DiscoverySource | undefined;
24
+ has(id: string): boolean;
25
+ /** All registered sources, in registration order. */
26
+ all(): DiscoverySource[];
27
+ get size(): number;
28
+ }
29
+ export declare function createRegistry(): DiscoveryRegistry;
30
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../../src/services/discovery/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsC;IAE9D,4FAA4F;IAC5F,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;IAOvC,yDAAyD;IACzD,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI/B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI5C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxB,qDAAqD;IACrD,GAAG,IAAI,eAAe,EAAE;IAIxB,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF;AAED,wBAAgB,cAAc,IAAI,iBAAiB,CAElD"}
@@ -0,0 +1,31 @@
1
+ export class DiscoveryRegistry {
2
+ sources = new Map();
3
+ /** Register a source. Throws on duplicate id (a programming error — ids must be unique). */
4
+ register(source) {
5
+ if (this.sources.has(source.id)) {
6
+ throw new Error(`DiscoverySource already registered: ${source.id}`);
7
+ }
8
+ this.sources.set(source.id, source);
9
+ }
10
+ /** Remove a source by id. Returns true if it existed. */
11
+ unregister(id) {
12
+ return this.sources.delete(id);
13
+ }
14
+ get(id) {
15
+ return this.sources.get(id);
16
+ }
17
+ has(id) {
18
+ return this.sources.has(id);
19
+ }
20
+ /** All registered sources, in registration order. */
21
+ all() {
22
+ return [...this.sources.values()];
23
+ }
24
+ get size() {
25
+ return this.sources.size;
26
+ }
27
+ }
28
+ export function createRegistry() {
29
+ return new DiscoveryRegistry();
30
+ }
31
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../src/services/discovery/registry.ts"],"names":[],"mappings":"AAiBA,MAAM,OAAO,iBAAiB;IACX,OAAO,GAAG,IAAI,GAAG,EAA2B,CAAC;IAE9D,4FAA4F;IAC5F,QAAQ,CAAC,MAAuB;QAC9B,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,uCAAuC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,yDAAyD;IACzD,UAAU,CAAC,EAAU;QACnB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,qDAAqD;IACrD,GAAG;QACD,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,IAAI,iBAAiB,EAAE,CAAC;AACjC,CAAC"}