aimeat 1.20.3 → 1.20.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/dist/locales/en.json +50 -1
- package/dist/locales/fi.json +50 -1
- package/dist/public/css/views/profile.css +9 -0
- package/dist/public/css/views/public-workspace-viewer.css +23 -3
- package/dist/public/js/services/organisms.js +77 -6
- package/dist/public/views/profile/organisms-tab.js +308 -54
- package/dist/public/views/public-workspace-viewer.js +74 -11
- package/dist/src/cli/connect/mcp/tools/index.d.ts.map +1 -1
- package/dist/src/cli/connect/mcp/tools/index.js +2 -0
- package/dist/src/cli/connect/mcp/tools/index.js.map +1 -1
- package/dist/src/cli/connect/mcp/tools/organisms.d.ts.map +1 -1
- package/dist/src/cli/connect/mcp/tools/organisms.js +57 -0
- package/dist/src/cli/connect/mcp/tools/organisms.js.map +1 -1
- package/dist/src/cli/connect/mcp/tools/schedules.d.ts +15 -0
- package/dist/src/cli/connect/mcp/tools/schedules.d.ts.map +1 -0
- package/dist/src/cli/connect/mcp/tools/schedules.js +66 -0
- package/dist/src/cli/connect/mcp/tools/schedules.js.map +1 -0
- package/dist/src/cli/connect/tool-call.d.ts.map +1 -1
- package/dist/src/cli/connect/tool-call.js +79 -0
- package/dist/src/cli/connect/tool-call.js.map +1 -1
- package/dist/src/cli/init-wizard.d.ts.map +1 -1
- package/dist/src/cli/init-wizard.js +11 -3
- package/dist/src/cli/init-wizard.js.map +1 -1
- package/dist/src/generated/api-types.d.ts +499 -1
- package/dist/src/generated/api-types.d.ts.map +1 -1
- package/dist/src/mcp/annotations.d.ts.map +1 -1
- package/dist/src/mcp/annotations.js +6 -0
- package/dist/src/mcp/annotations.js.map +1 -1
- package/dist/src/mcp/catalog/definitions.d.ts.map +1 -1
- package/dist/src/mcp/catalog/definitions.js +65 -0
- package/dist/src/mcp/catalog/definitions.js.map +1 -1
- package/dist/src/mcp/catalog/surfaces.js +6 -6
- package/dist/src/mcp/catalog/surfaces.js.map +1 -1
- package/dist/src/mcp/organisms.d.ts.map +1 -1
- package/dist/src/mcp/organisms.js +145 -0
- package/dist/src/mcp/organisms.js.map +1 -1
- package/dist/src/routes/organisms.d.ts.map +1 -1
- package/dist/src/routes/organisms.js +406 -5
- package/dist/src/routes/organisms.js.map +1 -1
- package/dist/src/services/organism-comments.d.ts +30 -0
- package/dist/src/services/organism-comments.d.ts.map +1 -0
- package/dist/src/services/organism-comments.js +74 -0
- package/dist/src/services/organism-comments.js.map +1 -0
- package/dist/src/services/organism-search.d.ts +27 -0
- package/dist/src/services/organism-search.d.ts.map +1 -0
- package/dist/src/services/organism-search.js +84 -0
- package/dist/src/services/organism-search.js.map +1 -0
- package/dist/src/storage/interface.d.ts +7 -1
- package/dist/src/storage/interface.d.ts.map +1 -1
- package/dist/src/storage/interface.js.map +1 -1
- package/package.json +1 -1
|
@@ -82,24 +82,128 @@ import { Markdown, slugifyHeading } from '/components/Markdown.js';
|
|
|
82
82
|
import { Mermaid } from '/components/Mermaid.js';
|
|
83
83
|
|
|
84
84
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* expanded org card for users who can edit; refreshes the parent list via onChanged.
|
|
85
|
+
* Content search inside an organism — case-insensitive substring over the records + documents of
|
|
86
|
+
* every workspace the member can read. Backend: GET /v1/organisms/:id/search. Rendered in the
|
|
87
|
+
* expanded card for members; opening a hit takes the user to that workspace.
|
|
89
88
|
*/
|
|
90
|
-
function
|
|
89
|
+
function OrgSearch({ orgId, onOpenWorkspace }) {
|
|
90
|
+
const [q, setQ] = useState('');
|
|
91
|
+
const [results, setResults] = useState(null);
|
|
92
|
+
const [busy, setBusy] = useState(false);
|
|
93
|
+
|
|
94
|
+
const doSearch = async () => {
|
|
95
|
+
const query = q.trim();
|
|
96
|
+
if (query.length < 2) return;
|
|
97
|
+
setBusy(true);
|
|
98
|
+
try {
|
|
99
|
+
const r = await orgService.searchOrganism(orgId, query);
|
|
100
|
+
setResults(r?.data?.results || []);
|
|
101
|
+
} catch { setResults([]); }
|
|
102
|
+
finally { setBusy(false); }
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
return html`
|
|
106
|
+
<div class="card-detail">
|
|
107
|
+
<div class="section-title">${t('organisms.searchContent') || 'Search content'}</div>
|
|
108
|
+
<div class="flex-row-wrap">
|
|
109
|
+
<input class="input-field input-sm" placeholder=${t('organisms.searchPlaceholder') || 'Find records & documents…'} value=${q}
|
|
110
|
+
onInput=${(e) => setQ(e.target.value)} onKeyDown=${(e) => { if (e.key === 'Enter') doSearch(); }} />
|
|
111
|
+
<button class="btn-outline btn-sm" disabled=${busy || q.trim().length < 2} onClick=${doSearch}>${t('organisms.search') || 'Search'}</button>
|
|
112
|
+
</div>
|
|
113
|
+
${results !== null && results.length === 0 ? html`<div class="section-desc">${t('organisms.searchNoResults') || 'No matches.'}</div>` : null}
|
|
114
|
+
${(results || []).map(r => html`
|
|
115
|
+
<div class="pj-access-row card-clickable" key=${r.ws + '/' + r.space + '/' + r.id} role="button" onClick=${() => onOpenWorkspace?.(r.ws)}>
|
|
116
|
+
<span>
|
|
117
|
+
<b>${escHtml(r.title)}</b>
|
|
118
|
+
<span class="pj-mini"> — ${escHtml(r.wsName || r.ws)} · ${escHtml(r.space)}</span>
|
|
119
|
+
<div class="pj-mini">${escHtml(r.snippet)}</div>
|
|
120
|
+
</span>
|
|
121
|
+
</div>
|
|
122
|
+
`)}
|
|
123
|
+
</div>
|
|
124
|
+
`;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Banner listing the caller's pending organism invitations (status `invited`) across all
|
|
129
|
+
* organisms, with Accept / Decline. Invited organisms are not in the member's active list, so
|
|
130
|
+
* this is how an invitee discovers them. Backend: GET /v1/organisms/invitations/mine.
|
|
131
|
+
*/
|
|
132
|
+
function IncomingInvitations({ showToast, onChanged }) {
|
|
133
|
+
const [invites, setInvites] = useState([]);
|
|
134
|
+
const [busy, setBusy] = useState(false);
|
|
135
|
+
const load = useCallback(async () => {
|
|
136
|
+
const r = await orgService.listMyInvitations().catch(() => null);
|
|
137
|
+
setInvites(r?.data?.invitations || []);
|
|
138
|
+
}, []);
|
|
139
|
+
useEffect(() => { load(); }, [load]);
|
|
140
|
+
const liveRef = useRef(load); liveRef.current = load;
|
|
141
|
+
useEffect(() => {
|
|
142
|
+
const h = () => liveRef.current();
|
|
143
|
+
window.addEventListener('aimeat-live-update', h);
|
|
144
|
+
return () => window.removeEventListener('aimeat-live-update', h);
|
|
145
|
+
}, []);
|
|
146
|
+
const act = async (id, accept) => {
|
|
147
|
+
setBusy(true);
|
|
148
|
+
try {
|
|
149
|
+
const r = accept ? await orgService.acceptInvitation(id) : await orgService.declineInvitation(id);
|
|
150
|
+
if (r?.ok === false) showToast(r?.error?.message || (t('organisms.inviteActionFailed') || 'Failed'));
|
|
151
|
+
else showToast(accept ? (t('organisms.invitationAccepted') || 'Joined') : (t('organisms.invitationDeclined') || 'Declined'));
|
|
152
|
+
await load(); onChanged?.();
|
|
153
|
+
} catch (e) { showToast((e && e.message) || (t('organisms.inviteActionFailed') || 'Failed')); }
|
|
154
|
+
finally { setBusy(false); }
|
|
155
|
+
};
|
|
156
|
+
if (!invites.length) return null;
|
|
157
|
+
return html`
|
|
158
|
+
<div class="card">
|
|
159
|
+
<div class="section-title">${t('organisms.youAreInvited') || 'You’re invited'}</div>
|
|
160
|
+
${invites.map(({ membership, organism }) => html`
|
|
161
|
+
<div class="pj-access-row" key=${organism.id}>
|
|
162
|
+
<span><b>${escHtml(organism.name)}</b>${membership.invitedBy ? html` <span class="pj-mini">— ${(t('organisms.invitedByLabel') || 'invited by {who}').replace('{who}', escHtml(membership.invitedBy))}</span>` : null}</span>
|
|
163
|
+
<span class="flex-row-wrap">
|
|
164
|
+
<button class="btn-success btn-sm" disabled=${busy} onClick=${() => act(organism.id, true)}>${t('organisms.acceptInvite') || 'Accept'}</button>
|
|
165
|
+
<button class="btn-ghost btn-sm" disabled=${busy} onClick=${() => act(organism.id, false)}>${t('organisms.declineInvite') || 'Decline'}</button>
|
|
166
|
+
</span>
|
|
167
|
+
</div>
|
|
168
|
+
`)}
|
|
169
|
+
</div>
|
|
170
|
+
`;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Organism member panel. For creator/admin (`canManage`) it is a full manager: approve/reject
|
|
175
|
+
* join requests, invite by name, remove/block members, lift bans, transfer ownership (creator
|
|
176
|
+
* only), and attach/detach agents. For a regular member it renders a read-only roster + agent
|
|
177
|
+
* list (#6). Backend: /:id/{join-requests,invitations,members,transfer,agents}. Refreshes the
|
|
178
|
+
* parent list via onChanged so member counts stay current.
|
|
179
|
+
*/
|
|
180
|
+
function OrgMemberManager({ org, ghii, canManage, isCreator, showToast, confirm, onChanged }) {
|
|
181
|
+
const orgId = org.id;
|
|
91
182
|
const [requests, setRequests] = useState(null);
|
|
92
183
|
const [members, setMembers] = useState(null);
|
|
184
|
+
const [banned, setBanned] = useState([]);
|
|
185
|
+
const [invitations, setInvitations] = useState([]);
|
|
186
|
+
const [inviteName, setInviteName] = useState('');
|
|
187
|
+
const [agentName, setAgentName] = useState('');
|
|
93
188
|
const [busy, setBusy] = useState(false);
|
|
94
189
|
|
|
95
190
|
const load = useCallback(async () => {
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
191
|
+
const tasks = [orgService.listMembers(orgId).catch(() => null)];
|
|
192
|
+
if (canManage) {
|
|
193
|
+
tasks.push(
|
|
194
|
+
orgService.listJoinRequests(orgId).catch(() => null),
|
|
195
|
+
orgService.listMembers(orgId, 'banned').catch(() => null),
|
|
196
|
+
orgService.listInvitations(orgId).catch(() => null),
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
const [mb, rq, bn, inv] = await Promise.all(tasks);
|
|
101
200
|
setMembers(mb?.data?.members || []);
|
|
102
|
-
|
|
201
|
+
if (canManage) {
|
|
202
|
+
setRequests(rq?.data?.join_requests || []);
|
|
203
|
+
setBanned(bn?.data?.members || []);
|
|
204
|
+
setInvitations(inv?.data?.invitations || []);
|
|
205
|
+
}
|
|
206
|
+
}, [orgId, canManage]);
|
|
103
207
|
|
|
104
208
|
useEffect(() => { load(); }, [load]);
|
|
105
209
|
const liveRef = useRef(load); liveRef.current = load;
|
|
@@ -109,65 +213,123 @@ function OrgMemberManager({ orgId, ghii, showToast, confirm, onChanged }) {
|
|
|
109
213
|
return () => window.removeEventListener('aimeat-live-update', handler);
|
|
110
214
|
}, []);
|
|
111
215
|
|
|
112
|
-
const
|
|
216
|
+
const run = async (fn, okMsg, failKey) => {
|
|
113
217
|
setBusy(true);
|
|
114
218
|
try {
|
|
115
|
-
const r = await
|
|
116
|
-
if (r?.ok === false) showToast(r?.error?.message || (t(
|
|
117
|
-
else
|
|
219
|
+
const r = await fn();
|
|
220
|
+
if (r?.ok === false) showToast(r?.error?.message || (t(failKey) || 'Failed'));
|
|
221
|
+
else if (okMsg) showToast(okMsg);
|
|
118
222
|
await load(); onChanged?.();
|
|
119
|
-
} catch (e) { showToast((e && e.message) || (t(
|
|
223
|
+
} catch (e) { showToast((e && e.message) || (t(failKey) || 'Failed')); }
|
|
120
224
|
finally { setBusy(false); }
|
|
121
225
|
};
|
|
122
226
|
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
} catch (e) { showToast((e && e.message) || (t('organisms.removeFailed') || 'Remove failed')); }
|
|
134
|
-
finally { setBusy(false); }
|
|
135
|
-
},
|
|
136
|
-
{ danger: true },
|
|
137
|
-
);
|
|
227
|
+
const review = (rid, decision) => run(
|
|
228
|
+
() => orgService.reviewJoinRequest(orgId, rid, decision),
|
|
229
|
+
decision === 'approved' ? (t('organisms.joinApproved') || 'Request approved') : (t('organisms.joinRejected') || 'Request declined'),
|
|
230
|
+
'organisms.reviewFailed');
|
|
231
|
+
|
|
232
|
+
const invite = () => {
|
|
233
|
+
const name = inviteName.trim();
|
|
234
|
+
if (!name) return;
|
|
235
|
+
setInviteName('');
|
|
236
|
+
run(() => orgService.inviteMember(orgId, name), (t('organisms.invitationSent') || 'Invitation sent'), 'organisms.inviteFailed');
|
|
138
237
|
};
|
|
139
238
|
|
|
239
|
+
const remove = (memberGhii, ban) => confirm(
|
|
240
|
+
(ban ? (t('organisms.confirmBlockMember') || 'Block {member} and remove them from this organism?') : (t('organisms.confirmRemoveMember') || 'Revoke {member}’s access to this organism?')).replace('{member}', memberGhii),
|
|
241
|
+
() => run(() => orgService.removeMember(orgId, memberGhii, ban), ban ? (t('organisms.memberBlocked') || 'Member blocked') : (t('organisms.memberRemoved') || 'Member removed'), 'organisms.removeFailed'),
|
|
242
|
+
{ danger: true });
|
|
243
|
+
|
|
244
|
+
const unban = (memberGhii) => run(() => orgService.unbanMember(orgId, memberGhii), (t('organisms.banLifted') || 'Block lifted'), 'organisms.removeFailed');
|
|
245
|
+
|
|
246
|
+
const transfer = (toGhii) => confirm(
|
|
247
|
+
(t('organisms.confirmTransfer') || 'Make {member} the creator? You will become an admin.').replace('{member}', toGhii),
|
|
248
|
+
() => run(() => orgService.transferOwnership(orgId, toGhii), (t('organisms.ownershipTransferred') || 'Ownership transferred'), 'organisms.transferFailed'),
|
|
249
|
+
{ danger: true });
|
|
250
|
+
|
|
251
|
+
const attachAgent = () => {
|
|
252
|
+
const g = agentName.trim();
|
|
253
|
+
if (!g) return;
|
|
254
|
+
setAgentName('');
|
|
255
|
+
run(() => orgService.attachAgent(orgId, g), (t('organisms.agentAttached') || 'Agent attached'), 'organisms.agentFailed');
|
|
256
|
+
};
|
|
257
|
+
const detachAgent = (g) => run(() => orgService.detachAgent(orgId, g), (t('organisms.agentDetached') || 'Agent detached'), 'organisms.agentFailed');
|
|
258
|
+
|
|
140
259
|
const pending = (requests || []).filter(r => r.status === 'pending');
|
|
260
|
+
const agents = org.agentGaiis || [];
|
|
141
261
|
|
|
142
262
|
return html`
|
|
143
263
|
<div class="card-detail">
|
|
144
|
-
<div class="section-title">${t('organisms.manageMembers') || 'Manage members'}</div>
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
264
|
+
<div class="section-title">${canManage ? (t('organisms.manageMembers') || 'Manage members') : (t('organisms.membersRoster') || 'Members')}</div>
|
|
265
|
+
${canManage ? html`<div class="section-desc">${t('organisms.manageMembersDesc') || 'Invite, approve, block and revoke member access.'}</div>` : null}
|
|
266
|
+
|
|
267
|
+
${canManage ? html`
|
|
268
|
+
<div class="detail-label">${t('organisms.inviteMember') || 'Invite a member'}</div>
|
|
269
|
+
<div class="flex-row-wrap">
|
|
270
|
+
<input class="input-field input-sm" placeholder=${t('organisms.inviteePlaceholder') || 'owner name'} value=${inviteName}
|
|
271
|
+
onInput=${(e) => setInviteName(e.target.value)} onKeyDown=${(e) => { if (e.key === 'Enter') invite(); }} />
|
|
272
|
+
<button class="btn-primary btn-sm" disabled=${busy || !inviteName.trim()} onClick=${invite}>${t('organisms.invite') || 'Invite'}</button>
|
|
273
|
+
</div>
|
|
274
|
+
${invitations.length > 0 ? html`
|
|
275
|
+
<div class="section-desc">${t('organisms.outstandingInvites') || 'Awaiting acceptance'}: ${invitations.map(m => escHtml(m.ghii)).join(', ')}</div>
|
|
276
|
+
` : null}
|
|
277
|
+
|
|
278
|
+
<div class="detail-label">${t('organisms.pendingRequests') || 'Pending join requests'}</div>
|
|
279
|
+
${requests === null
|
|
280
|
+
? html`<div class="section-desc">…</div>`
|
|
281
|
+
: pending.length === 0
|
|
282
|
+
? html`<div class="section-desc">${t('organisms.noPendingRequests') || 'No pending requests.'}</div>`
|
|
283
|
+
: pending.map(r => html`
|
|
284
|
+
<div class="pj-access-row" key=${r.id}>
|
|
285
|
+
<span>${escHtml(r.ghii)}${r.message ? html` <span class="pj-mini">— ${escHtml(r.message)}</span>` : null}</span>
|
|
286
|
+
<span class="flex-row-wrap">
|
|
287
|
+
<button class="btn-success btn-sm" disabled=${busy} onClick=${() => review(r.id, 'approved')}>${t('organisms.approve') || 'Approve'}</button>
|
|
288
|
+
<button class="btn-ghost btn-sm" disabled=${busy} onClick=${() => review(r.id, 'rejected')}>${t('organisms.reject') || 'Reject'}</button>
|
|
289
|
+
</span>
|
|
290
|
+
</div>
|
|
291
|
+
`)}
|
|
292
|
+
` : null}
|
|
161
293
|
|
|
162
294
|
<div class="detail-label">${t('organisms.members') || 'Members'}</div>
|
|
163
295
|
${(members || []).map(m => html`
|
|
164
296
|
<div class="pj-access-row" key=${m.ghii}>
|
|
165
297
|
<span>${escHtml(m.ghii)} <span class="badge ${m.role === 'creator' ? 'badge-success' : 'badge-info'} pj-mini">${escHtml(m.role || 'member')}</span></span>
|
|
166
|
-
${
|
|
167
|
-
|
|
298
|
+
${canManage && m.role !== 'creator' && m.ghii !== ghii ? html`
|
|
299
|
+
<span class="flex-row-wrap">
|
|
300
|
+
${isCreator ? html`<button class="btn-ghost btn-sm" disabled=${busy} onClick=${() => transfer(m.ghii)}>${t('organisms.makeCreator') || 'Make creator'}</button>` : null}
|
|
301
|
+
<button class="btn-outline btn-sm" disabled=${busy} onClick=${() => remove(m.ghii, false)}>${t('organisms.remove') || 'Remove'}</button>
|
|
302
|
+
<button class="btn-danger btn-sm" disabled=${busy} onClick=${() => remove(m.ghii, true)}>${t('organisms.block') || 'Block'}</button>
|
|
303
|
+
</span>
|
|
304
|
+
` : null}
|
|
305
|
+
</div>
|
|
306
|
+
`)}
|
|
307
|
+
|
|
308
|
+
${canManage && banned.length > 0 ? html`
|
|
309
|
+
<div class="detail-label">${t('organisms.blockedMembers') || 'Blocked'}</div>
|
|
310
|
+
${banned.map(m => html`
|
|
311
|
+
<div class="pj-access-row" key=${'ban-' + m.ghii}>
|
|
312
|
+
<span>${escHtml(m.ghii)}</span>
|
|
313
|
+
<button class="btn-ghost btn-sm" disabled=${busy} onClick=${() => unban(m.ghii)}>${t('organisms.unblock') || 'Unblock'}</button>
|
|
314
|
+
</div>
|
|
315
|
+
`)}
|
|
316
|
+
` : null}
|
|
317
|
+
|
|
318
|
+
<div class="detail-label">${t('organisms.attachedAgents') || 'Attached agents'}</div>
|
|
319
|
+
${agents.length === 0 ? html`<div class="section-desc">${t('organisms.noAgents') || 'No agents attached.'}</div>` : null}
|
|
320
|
+
${agents.map(g => html`
|
|
321
|
+
<div class="pj-access-row" key=${'ag-' + g}>
|
|
322
|
+
<span class="mono">${escHtml(g)}</span>
|
|
323
|
+
${(canManage || g.includes('#' + ghii + '@'))
|
|
324
|
+
? html`<button class="btn-ghost btn-sm" disabled=${busy} onClick=${() => detachAgent(g)}>${t('organisms.detach') || 'Detach'}</button>`
|
|
168
325
|
: null}
|
|
169
326
|
</div>
|
|
170
327
|
`)}
|
|
328
|
+
<div class="flex-row-wrap">
|
|
329
|
+
<input class="input-field input-sm" placeholder=${t('organisms.agentGaiiPlaceholder') || 'agent#you@node'} value=${agentName}
|
|
330
|
+
onInput=${(e) => setAgentName(e.target.value)} onKeyDown=${(e) => { if (e.key === 'Enter') attachAgent(); }} />
|
|
331
|
+
<button class="btn-outline btn-sm" disabled=${busy || !agentName.trim()} onClick=${attachAgent}>${t('organisms.attachAgent') || 'Attach agent'}</button>
|
|
332
|
+
</div>
|
|
171
333
|
</div>
|
|
172
334
|
`;
|
|
173
335
|
}
|
|
@@ -508,9 +670,15 @@ export default function OrganismsTab({ session, showToast, onStats }) {
|
|
|
508
670
|
` : null}
|
|
509
671
|
</div>
|
|
510
672
|
|
|
511
|
-
${canEdit ? html`<${
|
|
673
|
+
${(canEdit || isMember) ? html`<${OrgSearch}
|
|
512
674
|
orgId=${org.id}
|
|
675
|
+
onOpenWorkspace=${(ws) => { setOpenWs(ws); setOpenId(org.id); }} />` : null}
|
|
676
|
+
|
|
677
|
+
${(canEdit || isMember) ? html`<${OrgMemberManager}
|
|
678
|
+
org=${org}
|
|
513
679
|
ghii=${ghii}
|
|
680
|
+
canManage=${canEdit}
|
|
681
|
+
isCreator=${isCreator}
|
|
514
682
|
showToast=${showToast}
|
|
515
683
|
confirm=${confirm}
|
|
516
684
|
onChanged=${loadData} />` : null}
|
|
@@ -590,6 +758,9 @@ export default function OrganismsTab({ session, showToast, onStats }) {
|
|
|
590
758
|
`}
|
|
591
759
|
</div>
|
|
592
760
|
|
|
761
|
+
<!-- Incoming invitations -->
|
|
762
|
+
<${IncomingInvitations} showToast=${showToast} onChanged=${loadData} />
|
|
763
|
+
|
|
593
764
|
<!-- My Organisms -->
|
|
594
765
|
<input type="file" accept=".zip,application/zip" ref=${orgFileRef} style="display:none" onChange=${(e) => { const f = e.target.files && e.target.files[0]; e.target.value = ''; doImportOrg(f); }} />
|
|
595
766
|
<div class="pj-ws-topbar">
|
|
@@ -1013,6 +1184,88 @@ function ParticipantsPanel({ orgId, wsId }) {
|
|
|
1013
1184
|
</div>`;
|
|
1014
1185
|
}
|
|
1015
1186
|
|
|
1187
|
+
/**
|
|
1188
|
+
* Comment thread on one workspace object (record or document). Targeted by orgId+ws+space+instanceId.
|
|
1189
|
+
* Members read + add comments; an author (or org admin) deletes. Supports an optional quote anchor
|
|
1190
|
+
* (comment on a specific passage) and threaded replies (parentId). Backend: /v1/organisms/:id/comments.
|
|
1191
|
+
* Agents use the same endpoints via aimeat_workspace_comment(s).
|
|
1192
|
+
*/
|
|
1193
|
+
function WorkspaceComments({ orgId, ws, space, instanceId, showToast }) {
|
|
1194
|
+
const [comments, setComments] = useState(null);
|
|
1195
|
+
const [body, setBody] = useState('');
|
|
1196
|
+
const [anchorQuote, setAnchorQuote] = useState('');
|
|
1197
|
+
const [replyTo, setReplyTo] = useState(null); // { id, body } of the comment being replied to
|
|
1198
|
+
const [busy, setBusy] = useState(false);
|
|
1199
|
+
const me = (() => { try { return window.AIMEAT?.auth?.getSession?.() || {}; } catch { return {}; } })();
|
|
1200
|
+
const mine = (author) => author && (author === me.gaii || author === me.ghii);
|
|
1201
|
+
|
|
1202
|
+
const load = useCallback(async () => {
|
|
1203
|
+
if (!ws || !space || !instanceId) return;
|
|
1204
|
+
const r = await orgService.listComments(orgId, ws, space, instanceId).catch(() => null);
|
|
1205
|
+
setComments(r?.data?.comments || []);
|
|
1206
|
+
}, [orgId, ws, space, instanceId]);
|
|
1207
|
+
useEffect(() => { load(); }, [load]);
|
|
1208
|
+
const liveRef = useRef(load); liveRef.current = load;
|
|
1209
|
+
useEffect(() => {
|
|
1210
|
+
const h = () => liveRef.current();
|
|
1211
|
+
window.addEventListener('aimeat-live-update', h);
|
|
1212
|
+
return () => window.removeEventListener('aimeat-live-update', h);
|
|
1213
|
+
}, []);
|
|
1214
|
+
|
|
1215
|
+
const submit = async () => {
|
|
1216
|
+
const text = body.trim();
|
|
1217
|
+
if (!text) return;
|
|
1218
|
+
setBusy(true);
|
|
1219
|
+
try {
|
|
1220
|
+
const anchor = anchorQuote.trim() ? { quote: anchorQuote.trim() } : undefined;
|
|
1221
|
+
const r = await orgService.addComment(orgId, { ws, space, instanceId, body: text, anchor, parentId: replyTo?.id });
|
|
1222
|
+
if (r?.ok === false) showToast(r?.error?.message || (t('organisms.commentFailed') || 'Could not post comment'));
|
|
1223
|
+
else { setBody(''); setAnchorQuote(''); setReplyTo(null); await load(); }
|
|
1224
|
+
} catch (e) { showToast((e && e.message) || (t('organisms.commentFailed') || 'Could not post comment')); }
|
|
1225
|
+
finally { setBusy(false); }
|
|
1226
|
+
};
|
|
1227
|
+
const remove = async (c) => {
|
|
1228
|
+
setBusy(true);
|
|
1229
|
+
try {
|
|
1230
|
+
const r = await orgService.deleteComment(orgId, c.id, ws, space, instanceId);
|
|
1231
|
+
if (r?.ok === false) showToast(r?.error?.message || (t('organisms.commentDeleteFailed') || 'Could not delete'));
|
|
1232
|
+
else await load();
|
|
1233
|
+
} catch (e) { showToast((e && e.message) || (t('organisms.commentDeleteFailed') || 'Could not delete')); }
|
|
1234
|
+
finally { setBusy(false); }
|
|
1235
|
+
};
|
|
1236
|
+
|
|
1237
|
+
const list = comments || [];
|
|
1238
|
+
return html`
|
|
1239
|
+
<div class="pj-comments">
|
|
1240
|
+
<div class="detail-label">${(t('organisms.commentsHeading') || 'Comments') + (list.length ? ` (${list.length})` : '')}</div>
|
|
1241
|
+
${comments === null ? html`<div class="section-desc">…</div>` : null}
|
|
1242
|
+
${comments !== null && list.length === 0 ? html`<div class="section-desc">${t('organisms.noComments') || 'No comments yet.'}</div>` : null}
|
|
1243
|
+
${list.map(c => html`
|
|
1244
|
+
<div class="pj-comment ${c.parentId ? 'pj-comment-reply' : ''}" key=${c.id}>
|
|
1245
|
+
<div class="pj-comment-head">
|
|
1246
|
+
<b>${escHtml(c.author || '?')}</b>
|
|
1247
|
+
${c.parentId ? html`<span class="pj-mini"> · ${t('organisms.inReply') || 'reply'}</span>` : null}
|
|
1248
|
+
${c.anchor?.quote ? html`<span class="pj-mini"> · “${escHtml(String(c.anchor.quote).slice(0, 80))}”</span>` : null}
|
|
1249
|
+
${c.anchor?.section ? html`<span class="pj-mini"> · §${escHtml(c.anchor.section)}</span>` : null}
|
|
1250
|
+
<span class="pj-mini"> · ${c.createdAt ? dt(c.createdAt) : ''}</span>
|
|
1251
|
+
</div>
|
|
1252
|
+
<div class="pj-comment-body">${escHtml(c.body || '')}</div>
|
|
1253
|
+
<div class="pj-comment-actions">
|
|
1254
|
+
<button class="btn-ghost btn-sm" disabled=${busy} onClick=${() => setReplyTo({ id: c.id, body: c.body })}>${t('organisms.reply') || 'Reply'}</button>
|
|
1255
|
+
${mine(c.author) ? html`<button class="btn-ghost btn-sm" disabled=${busy} onClick=${() => remove(c)}>${t('organisms.delete') || 'Delete'}</button>` : null}
|
|
1256
|
+
</div>
|
|
1257
|
+
</div>
|
|
1258
|
+
`)}
|
|
1259
|
+
<div class="pj-comment-compose">
|
|
1260
|
+
${replyTo ? html`<div class="pj-mini">${t('organisms.replyingTo') || 'Replying to'}: “${escHtml(String(replyTo.body || '').slice(0, 60))}” <button class="btn-ghost btn-sm" onClick=${() => setReplyTo(null)}>${t('organisms.cancel') || 'Cancel'}</button></div>` : null}
|
|
1261
|
+
<input class="input-field input-sm" placeholder=${t('organisms.anchorQuotePlaceholder') || 'Optional: quote a passage to anchor the comment'} value=${anchorQuote} onInput=${(e) => setAnchorQuote(e.target.value)} />
|
|
1262
|
+
<textarea class="input-field input-sm" rows="2" placeholder=${t('organisms.commentPlaceholder') || 'Add a comment…'} value=${body} onInput=${(e) => setBody(e.target.value)}></textarea>
|
|
1263
|
+
<button class="btn-primary btn-sm" disabled=${busy || !body.trim()} onClick=${submit}>${t('organisms.postComment') || 'Comment'}</button>
|
|
1264
|
+
</div>
|
|
1265
|
+
</div>
|
|
1266
|
+
`;
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1016
1269
|
function Workspace({ org, wsId, showToast, onBack }) {
|
|
1017
1270
|
const orgId = org.id;
|
|
1018
1271
|
// Pop a document out into its own window (served by doc-solo.js) so several can sit side by side,
|
|
@@ -1579,7 +1832,8 @@ function Workspace({ org, wsId, showToast, onBack }) {
|
|
|
1579
1832
|
const target = docs.find(d => (d.title || '').toLowerCase() === title.toLowerCase());
|
|
1580
1833
|
if (target) { setActiveDoc({ type: ot.name, mode: 'view', page: target }); scrollToAnchor(); }
|
|
1581
1834
|
else showToast((t('organisms.docNotFound') || 'No document titled “{title}”').replace('{title}', title));
|
|
1582
|
-
}}
|
|
1835
|
+
}} />
|
|
1836
|
+
<${WorkspaceComments} orgId=${orgId} ws=${wsId} space=${ot.name} instanceId=${livePage.id} showToast=${showToast} />`;
|
|
1583
1837
|
})()}
|
|
1584
1838
|
</div>
|
|
1585
1839
|
</div>
|
|
@@ -1774,7 +2028,7 @@ function Workspace({ org, wsId, showToast, onBack }) {
|
|
|
1774
2028
|
<button class="btn-primary btn-sm" onClick=${() => publish(ot, d.id)} disabled=${busy}>${t('organisms.publish') || 'Publish'}</button>
|
|
1775
2029
|
<button class="pj-icon-btn" title=${t('organisms.delete') || 'Delete'} disabled=${busy} onClick=${() => removeObject(ot.namespace, d.id, String(d[PRIMARY_FIELD[ot.name] || 'title'] || d.id))}>🗑</button>
|
|
1776
2030
|
</div>
|
|
1777
|
-
${expandedRec[ot.name + ':' + d.id] ? html`<div class="pj-rec-fields">${recordFields(d)}</div
|
|
2031
|
+
${expandedRec[ot.name + ':' + d.id] ? html`<div class="pj-rec-fields">${recordFields(d)}</div><${WorkspaceComments} orgId=${orgId} ws=${wsId} space=${ot.name} instanceId=${d.id} showToast=${showToast} />` : null}
|
|
1778
2032
|
</div>
|
|
1779
2033
|
`)}
|
|
1780
2034
|
|
|
@@ -1787,7 +2041,7 @@ function Workspace({ org, wsId, showToast, onBack }) {
|
|
|
1787
2041
|
${o.status ? html`<span class="badge badge-info">${escHtml(o.status)}</span>` : null}
|
|
1788
2042
|
<button class="pj-icon-btn" title=${t('organisms.delete') || 'Delete'} disabled=${busy} onClick=${() => removeObject(ot.namespace, o.id, String(o[PRIMARY_FIELD[ot.name] || 'title'] || o.id))}>🗑</button>
|
|
1789
2043
|
</div>
|
|
1790
|
-
${expandedRec[ot.name + ':' + o.id] ? html`<div class="pj-rec-fields">${recordFields(o)}</div
|
|
2044
|
+
${expandedRec[ot.name + ':' + o.id] ? html`<div class="pj-rec-fields">${recordFields(o)}</div><${WorkspaceComments} orgId=${orgId} ws=${wsId} space=${ot.name} instanceId=${o.id} showToast=${showToast} />` : null}
|
|
1791
2045
|
</div>
|
|
1792
2046
|
`)
|
|
1793
2047
|
}
|
|
@@ -4,15 +4,20 @@
|
|
|
4
4
|
* Reads the no-auth endpoint GET /v1/organisms/:id/workspace/public/documents?ws=… (which serves
|
|
5
5
|
* only PUBLISHED docs the workspace's meta.share marks public) and renders each page's markdown with
|
|
6
6
|
* the safe Markdown component. A table-of-contents lists the shared pages; [[Wiki links]] jump
|
|
7
|
-
* between them.
|
|
8
|
-
*
|
|
7
|
+
* between them. The whole-space view renders EVERY shared page stacked in one continuous document
|
|
8
|
+
* (the TOC scroll-spies + scrolls), so "Print / Save as PDF" captures all pages in one go — there is
|
|
9
|
+
* no server-side PDF. A single page can still be deep-linked (and isolated) with &type=…&id=….
|
|
10
|
+
* "Copy AI link" copies the no-auth Markdown-bundle API URL (?format=md) so an agent can read the
|
|
11
|
+
* raw content directly; drop &format=md for the JSON form.
|
|
9
12
|
* @structure PublicWorkspaceViewer (default export)
|
|
10
13
|
* @usage route /v1/publicworkspaceviewer?org=<id>&ws=<ws>[&type=<space>&id=<docId>]
|
|
11
14
|
* @version-history
|
|
12
15
|
* v1.0.0 — 2026-06-09 — Initial: slice 2 of the workspace public-sharing plan.
|
|
16
|
+
* v1.1.0 — 2026-06-09 — Continuous whole-space render (all pages stacked → print captures everything)
|
|
17
|
+
* with scroll-spy TOC; "Copy AI link" button exposing the ?format=md Markdown-bundle API URL.
|
|
13
18
|
*/
|
|
14
19
|
import { h } from 'preact';
|
|
15
|
-
import { useState, useEffect, useCallback } from 'preact/hooks';
|
|
20
|
+
import { useState, useEffect, useCallback, useRef } from 'preact/hooks';
|
|
16
21
|
import htm from 'htm';
|
|
17
22
|
import { t } from '/js/i18n.js';
|
|
18
23
|
import { Markdown } from '/components/Markdown.js';
|
|
@@ -21,6 +26,8 @@ import { useViewCSS } from '/components/useViewCSS.js';
|
|
|
21
26
|
const html = htm.bind(h);
|
|
22
27
|
|
|
23
28
|
const docKey = (d) => `${d.type}/${d.id}`;
|
|
29
|
+
// A DOM-id-safe anchor for each stacked page so the TOC can scroll to it.
|
|
30
|
+
const anchorId = (d) => `pwv-doc-${docKey(d).replace(/[^a-zA-Z0-9_-]/g, '-')}`;
|
|
24
31
|
|
|
25
32
|
function parseParams() {
|
|
26
33
|
const p = new URLSearchParams(window.location.search);
|
|
@@ -64,18 +71,65 @@ export default function PublicWorkspaceViewer() {
|
|
|
64
71
|
return () => document.body.classList.remove('pwv-active');
|
|
65
72
|
}, []);
|
|
66
73
|
|
|
74
|
+
// A doc is "isolated" (single-page mode) only when the link explicitly deep-links one page via
|
|
75
|
+
// &type=&id=. The plain whole-space link renders EVERY page stacked (continuous document) so the
|
|
76
|
+
// browser print captures all of them at once.
|
|
77
|
+
const isSingle = Array.isArray(docs) && !!type && !!id && docs.some(d => docKey(d) === `${type}/${id}`);
|
|
78
|
+
const visibleDocs = Array.isArray(docs) ? (isSingle ? docs.filter(d => docKey(d) === `${type}/${id}`) : docs) : [];
|
|
67
79
|
const current = Array.isArray(docs) ? docs.find(d => docKey(d) === selected) : null;
|
|
68
80
|
useEffect(() => {
|
|
69
81
|
if (current?.title) document.title = `${current.title} — AIMEAT`;
|
|
70
82
|
}, [current?.title]);
|
|
71
83
|
|
|
84
|
+
// Scroll a page into view and mark it active (TOC click + initial deep-link land).
|
|
85
|
+
const goTo = useCallback((d) => {
|
|
86
|
+
setSelected(docKey(d));
|
|
87
|
+
const el = document.getElementById(anchorId(d));
|
|
88
|
+
if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
89
|
+
}, []);
|
|
90
|
+
|
|
91
|
+
// On first load of the whole-space view, if a page was deep-linked, scroll to it.
|
|
92
|
+
const didLand = useRef(false);
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
if (didLand.current || isSingle || !Array.isArray(docs) || docs.length === 0) return;
|
|
95
|
+
if (type && id) {
|
|
96
|
+
const hit = docs.find(d => docKey(d) === `${type}/${id}`);
|
|
97
|
+
if (hit) { didLand.current = true; setTimeout(() => goTo(hit), 0); }
|
|
98
|
+
}
|
|
99
|
+
}, [docs, isSingle, type, id, goTo]);
|
|
100
|
+
|
|
101
|
+
// Scroll-spy: highlight the TOC entry for the page currently in view (whole-space mode only).
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
if (isSingle || !Array.isArray(docs) || docs.length === 0) return;
|
|
104
|
+
const obs = new IntersectionObserver((entries) => {
|
|
105
|
+
const top = entries.filter(e => e.isIntersecting).sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top)[0];
|
|
106
|
+
if (top) setSelected(top.target.dataset.pwvKey);
|
|
107
|
+
}, { rootMargin: '-10% 0px -75% 0px', threshold: 0 });
|
|
108
|
+
docs.forEach(d => { const el = document.getElementById(anchorId(d)); if (el) obs.observe(el); });
|
|
109
|
+
return () => obs.disconnect();
|
|
110
|
+
}, [docs, isSingle]);
|
|
111
|
+
|
|
72
112
|
// [[Wiki links]] jump to another shared page by (case-insensitive) title.
|
|
73
113
|
const onWikiLink = useCallback((title) => {
|
|
74
114
|
if (!Array.isArray(docs)) return;
|
|
75
115
|
const want = String(title).split('#')[0].trim().toLowerCase();
|
|
76
116
|
const hit = docs.find(d => String(d.title).trim().toLowerCase() === want);
|
|
77
|
-
if (hit)
|
|
78
|
-
}, [docs]);
|
|
117
|
+
if (hit) goTo(hit);
|
|
118
|
+
}, [docs, goTo]);
|
|
119
|
+
|
|
120
|
+
// The no-auth Markdown-bundle API URL — paste it to an AI agent to read the raw content directly.
|
|
121
|
+
// Single-page link when isolated, whole-space bundle otherwise; drop &format=md for the JSON form.
|
|
122
|
+
const aiLink = isSingle
|
|
123
|
+
? `${window.location.origin}/v1/organisms/${encodeURIComponent(org)}/workspace/public/document?ws=${encodeURIComponent(ws)}&type=${encodeURIComponent(type)}&id=${encodeURIComponent(id)}&format=md`
|
|
124
|
+
: `${window.location.origin}/v1/organisms/${encodeURIComponent(org)}/workspace/public/documents?ws=${encodeURIComponent(ws)}&format=md`;
|
|
125
|
+
const [copied, setCopied] = useState(false);
|
|
126
|
+
const copyAiLink = useCallback(async () => {
|
|
127
|
+
try {
|
|
128
|
+
await navigator.clipboard.writeText(aiLink);
|
|
129
|
+
setCopied(true);
|
|
130
|
+
setTimeout(() => setCopied(false), 1800);
|
|
131
|
+
} catch { /* clipboard unavailable — ignore */ }
|
|
132
|
+
}, [aiLink]);
|
|
79
133
|
|
|
80
134
|
if (docs === undefined) {
|
|
81
135
|
return html`<div class="pwv-container"><div class="pwv-state">${t('pwv.loading') || 'Loading…'}</div></div>`;
|
|
@@ -105,7 +159,7 @@ export default function PublicWorkspaceViewer() {
|
|
|
105
159
|
${docs.map(d => html`
|
|
106
160
|
<button
|
|
107
161
|
class="pwv-toc-item ${docKey(d) === selected ? 'pwv-active' : ''}"
|
|
108
|
-
onClick=${() =>
|
|
162
|
+
onClick=${() => goTo(d)}
|
|
109
163
|
>${d.title || d.id}</button>
|
|
110
164
|
`)}
|
|
111
165
|
</nav>
|
|
@@ -114,12 +168,21 @@ export default function PublicWorkspaceViewer() {
|
|
|
114
168
|
<main class="pwv-main">
|
|
115
169
|
<div class="pwv-bar">
|
|
116
170
|
<span class="pwv-badge">${t('pwv.publicBadge') || 'Public document'}</span>
|
|
117
|
-
<
|
|
118
|
-
|
|
119
|
-
|
|
171
|
+
<div class="pwv-bar-actions">
|
|
172
|
+
<button class="btn-outline btn-sm pwv-action" onClick=${copyAiLink}>
|
|
173
|
+
${copied ? (t('pwv.copied') || 'Copied!') : (t('pwv.copyAiLink') || 'Copy AI link (Markdown)')}
|
|
174
|
+
</button>
|
|
175
|
+
<button class="btn-outline btn-sm pwv-action" onClick=${() => window.print()}>
|
|
176
|
+
${t('pwv.print') || 'Print / Save as PDF'}
|
|
177
|
+
</button>
|
|
178
|
+
</div>
|
|
120
179
|
</div>
|
|
121
|
-
${
|
|
122
|
-
?
|
|
180
|
+
${visibleDocs.length > 0
|
|
181
|
+
? visibleDocs.map(d => html`
|
|
182
|
+
<article class="pwv-doc" id=${anchorId(d)} data-pwv-key=${docKey(d)}>
|
|
183
|
+
<${Markdown} text=${d.markdown || ''} onWikiLink=${onWikiLink} />
|
|
184
|
+
</article>
|
|
185
|
+
`)
|
|
123
186
|
: html`<div class="pwv-state">${t('pwv.selectDocument') || 'Select a document.'}</div>`
|
|
124
187
|
}
|
|
125
188
|
</main>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/connect/mcp/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/connect/mcp/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AA2B7D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,CAyB9E"}
|
|
@@ -13,6 +13,7 @@ import { registerAppsTools } from './apps.js';
|
|
|
13
13
|
import { registerKnowledgeTools } from './knowledge.js';
|
|
14
14
|
import { registerOrganismsTools } from './organisms.js';
|
|
15
15
|
import { registerWorkspaceTools } from './workspaces.js';
|
|
16
|
+
import { registerSchedulesTools } from './schedules.js';
|
|
16
17
|
import { registerConsentTools } from './consent.js';
|
|
17
18
|
import { registerGroupsTools } from './groups.js';
|
|
18
19
|
import { registerInstancesTools } from './instances.js';
|
|
@@ -37,6 +38,7 @@ export function registerAllTools(mcp, registry) {
|
|
|
37
38
|
registerKnowledgeTools(mcp, registry);
|
|
38
39
|
registerOrganismsTools(mcp, registry);
|
|
39
40
|
registerWorkspaceTools(mcp, registry);
|
|
41
|
+
registerSchedulesTools(mcp, registry);
|
|
40
42
|
registerConsentTools(mcp, registry);
|
|
41
43
|
registerGroupsTools(mcp, registry);
|
|
42
44
|
registerInstancesTools(mcp, registry);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/cli/connect/mcp/tools/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/cli/connect/mcp/tools/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organisms.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/connect/mcp/tools/organisms.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAI7D,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"organisms.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/connect/mcp/tools/organisms.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAI7D,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,CAsIpF"}
|