@company-semantics/contracts 86.0.0 → 87.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +8 -8
- package/src/api/generated-spec-hash.ts +2 -2
- package/src/api/generated.ts +50 -262
- package/src/chat/README.md +8 -20
- package/src/chat/__tests__/compaction-boundary.test.ts +1 -0
- package/src/chat/__tests__/continuity.test.ts +1 -0
- package/src/chat/__tests__/discussion-scope.test.ts +0 -7
- package/src/chat/__tests__/message-mentions.test.ts +1 -12
- package/src/chat/__tests__/multi-party.test.ts +15 -6
- package/src/chat/__tests__/page-context.test.ts +3 -3
- package/src/chat/enums.ts +24 -11
- package/src/chat/index.ts +4 -16
- package/src/chat/schemas.ts +9 -71
- package/src/chat/types.ts +25 -77
- package/src/generated/openapi-routes.ts +1 -4
- package/src/guards/config.ts +1 -1
- package/src/index.ts +4 -6
- package/src/mcp/__tests__/README.md +29 -0
- package/src/mcp/__tests__/resource-types-fixture.ts +50 -0
- package/src/mcp/__tests__/resources.test.ts +39 -0
- package/src/mcp/resources.ts +16 -1
- package/src/notifications/__tests__/__snapshots__/monospace-budget.test.ts.snap +4 -4
- package/src/notifications/__tests__/__snapshots__/render-snapshot.test.ts.snap +50 -49
- package/src/notifications/__tests__/fixtures.ts +7 -7
- package/src/notifications/__tests__/render-snapshot.test.ts +7 -7
- package/src/notifications/kinds/chat-shared.ts +11 -5
- package/src/notifications/payloads.ts +5 -5
- package/src/org/__tests__/view-scopes.test.ts +0 -2
- package/src/org/view-scopes.ts +0 -1
package/src/chat/types.ts
CHANGED
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
|
|
9
9
|
import { z } from "zod";
|
|
10
10
|
import {
|
|
11
|
-
ChatVisibilitySchema,
|
|
12
11
|
TitleSourceSchema,
|
|
13
12
|
InvalidationReasonSchema,
|
|
14
13
|
ChatChangedFieldSchema,
|
|
@@ -17,9 +16,6 @@ import {
|
|
|
17
16
|
ChatSummaryExtendedSchema,
|
|
18
17
|
ProactiveChatResolutionSchema,
|
|
19
18
|
TitleGenerationResponseSchema,
|
|
20
|
-
ChatShareInfoSchema,
|
|
21
|
-
SharedChatViewSchema,
|
|
22
|
-
SharedChatMessageSchema,
|
|
23
19
|
BaseEventSchema,
|
|
24
20
|
ChatCreatedEventSchema,
|
|
25
21
|
ChatUpdatedEventSchema,
|
|
@@ -33,13 +29,11 @@ import {
|
|
|
33
29
|
ChatByInteractionResponseSchema,
|
|
34
30
|
ChatListResponseSchema,
|
|
35
31
|
CreateChatResponseSchema,
|
|
36
|
-
CreateShareResponseSchema,
|
|
37
|
-
ListSharesResponseSchema,
|
|
38
|
-
UpdateShareResponseSchema,
|
|
39
32
|
ChatMessageSchema,
|
|
40
33
|
ChatMessageMentionSchema,
|
|
41
34
|
ChatMentionableResponseSchema,
|
|
42
35
|
ChatParticipantRoleSchema,
|
|
36
|
+
ChatGrantableRoleSchema,
|
|
43
37
|
ChatParticipantSchema,
|
|
44
38
|
ChatParticipantsResponseSchema,
|
|
45
39
|
ChatDetailSchema,
|
|
@@ -48,17 +42,6 @@ import {
|
|
|
48
42
|
ChatPageContextSchema,
|
|
49
43
|
} from "./schemas";
|
|
50
44
|
|
|
51
|
-
// =============================================================================
|
|
52
|
-
// Visibility
|
|
53
|
-
// =============================================================================
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Chat share visibility.
|
|
57
|
-
* - private: Token exists but access requires authentication as chat owner
|
|
58
|
-
* - public: Token grants anonymous access to anyone with the link
|
|
59
|
-
*/
|
|
60
|
-
export type ChatVisibility = z.infer<typeof ChatVisibilitySchema>;
|
|
61
|
-
|
|
62
45
|
// =============================================================================
|
|
63
46
|
// Chat Summary
|
|
64
47
|
// =============================================================================
|
|
@@ -68,53 +51,6 @@ export type ChatVisibility = z.infer<typeof ChatVisibilitySchema>;
|
|
|
68
51
|
*/
|
|
69
52
|
export type ChatSummary = z.infer<typeof ChatSummarySchema>;
|
|
70
53
|
|
|
71
|
-
// =============================================================================
|
|
72
|
-
// Share Types
|
|
73
|
-
// =============================================================================
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Chat share record with snapshot metadata.
|
|
77
|
-
*
|
|
78
|
-
* CRITICAL INVARIANT (SNAPSHOT-1):
|
|
79
|
-
* A chat share must never expose messages with sequenceNumber > messageCountAtShare.
|
|
80
|
-
* Enforced in ChatShareService.viewSharedChat() only.
|
|
81
|
-
*/
|
|
82
|
-
export type ChatShareInfo = z.infer<typeof ChatShareInfoSchema>;
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Shared chat view returned to viewers.
|
|
86
|
-
* Messages are limited by the snapshot boundary.
|
|
87
|
-
*/
|
|
88
|
-
export type SharedChatView = z.infer<typeof SharedChatViewSchema>;
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Individual message in a shared chat view.
|
|
92
|
-
*/
|
|
93
|
-
export type SharedChatMessage = z.infer<typeof SharedChatMessageSchema>;
|
|
94
|
-
|
|
95
|
-
// =============================================================================
|
|
96
|
-
// API Request/Response Types
|
|
97
|
-
// =============================================================================
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Request to create a new share for a chat.
|
|
101
|
-
*/
|
|
102
|
-
export interface CreateShareRequest {
|
|
103
|
-
chatId: string;
|
|
104
|
-
visibility: ChatVisibility;
|
|
105
|
-
/** Optional: send email notification to this address */
|
|
106
|
-
recipientEmail?: string;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Request to update an existing share.
|
|
111
|
-
*/
|
|
112
|
-
export interface UpdateShareRequest {
|
|
113
|
-
visibility?: ChatVisibility;
|
|
114
|
-
/** If true, update snapshot to include new messages added since share creation */
|
|
115
|
-
updateSnapshot?: boolean;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
54
|
// =============================================================================
|
|
119
55
|
// Chat Lifecycle Types
|
|
120
56
|
// =============================================================================
|
|
@@ -288,15 +224,6 @@ export type ChatListResponse = z.infer<typeof ChatListResponseSchema>;
|
|
|
288
224
|
/** Response for POST /api/chats */
|
|
289
225
|
export type CreateChatResponse = z.infer<typeof CreateChatResponseSchema>;
|
|
290
226
|
|
|
291
|
-
/** Response for POST /api/chats/:chatId/shares */
|
|
292
|
-
export type CreateShareResponse = z.infer<typeof CreateShareResponseSchema>;
|
|
293
|
-
|
|
294
|
-
/** Response for GET /api/chats/:chatId/shares */
|
|
295
|
-
export type ListSharesResponse = z.infer<typeof ListSharesResponseSchema>;
|
|
296
|
-
|
|
297
|
-
/** Response for PATCH /api/shares/:shareId */
|
|
298
|
-
export type UpdateShareResponse = z.infer<typeof UpdateShareResponseSchema>;
|
|
299
|
-
|
|
300
227
|
/** Individual message in a chat response (GET /api/chats/:id). */
|
|
301
228
|
export type ChatMessage = z.infer<typeof ChatMessageSchema>;
|
|
302
229
|
|
|
@@ -316,12 +243,33 @@ export type ChatMentionableResponse = z.infer<
|
|
|
316
243
|
// =============================================================================
|
|
317
244
|
|
|
318
245
|
/**
|
|
319
|
-
* What one person is to a chat: `owner
|
|
320
|
-
*
|
|
321
|
-
*
|
|
246
|
+
* What one person is to a chat: `owner`, `participant` (Collaborate) or
|
|
247
|
+
* `viewer` (Read only). Whole-chat access, never a per-participant scope
|
|
248
|
+
* (ADR-CONTRACTS-206).
|
|
322
249
|
*/
|
|
323
250
|
export type ChatParticipantRole = z.infer<typeof ChatParticipantRoleSchema>;
|
|
324
251
|
|
|
252
|
+
/** A role a share can grant: `participant` (Collaborate) or `viewer` (Read only). */
|
|
253
|
+
export type ChatGrantableRole = z.infer<typeof ChatGrantableRoleSchema>;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Request for POST /api/chats/:chatId/participants — sharing the chat with one
|
|
257
|
+
* org member at a grantable role. A request-only type (no runtime schema), like
|
|
258
|
+
* the other chat requests.
|
|
259
|
+
*/
|
|
260
|
+
export interface AddChatParticipantRequest {
|
|
261
|
+
userId: string;
|
|
262
|
+
role: ChatGrantableRole;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Request for PATCH /api/chats/:chatId/participants/:userId — the owner moving
|
|
267
|
+
* someone between Read only and Collaborate.
|
|
268
|
+
*/
|
|
269
|
+
export interface UpdateChatParticipantRequest {
|
|
270
|
+
role: ChatGrantableRole;
|
|
271
|
+
}
|
|
272
|
+
|
|
325
273
|
/**
|
|
326
274
|
* One ACTIVE participant of a chat — a user id, a role, a read-time display
|
|
327
275
|
* name and when they joined. Never a `PrincipalRef`: the agent takes part in
|
|
@@ -21,13 +21,12 @@ export const openApiRoutes = {
|
|
|
21
21
|
'/api/chats/mentionable': ['GET'],
|
|
22
22
|
'/api/chats/proactive/{eventId}': ['GET'],
|
|
23
23
|
'/api/chats/resolve-launch': ['POST'],
|
|
24
|
-
'/api/chats/{chatId}/shares': ['GET', 'POST'],
|
|
25
24
|
'/api/chats/{id}': ['DELETE', 'GET', 'PATCH'],
|
|
26
25
|
'/api/chats/{id}/generate-title': ['POST'],
|
|
27
26
|
'/api/chats/{id}/messages': ['POST'],
|
|
28
27
|
'/api/chats/{id}/messages/{messageId}': ['DELETE'],
|
|
29
28
|
'/api/chats/{id}/participants': ['GET', 'POST'],
|
|
30
|
-
'/api/chats/{id}/participants/{userId}': ['DELETE'],
|
|
29
|
+
'/api/chats/{id}/participants/{userId}': ['DELETE', 'PATCH'],
|
|
31
30
|
'/api/chats/{id}/pin': ['DELETE', 'POST'],
|
|
32
31
|
'/api/chats/{id}/start-fresh': ['POST'],
|
|
33
32
|
'/api/comments': ['GET'],
|
|
@@ -186,8 +185,6 @@ export const openApiRoutes = {
|
|
|
186
185
|
'/api/reporting/positions/{positionId}/manager': ['PUT'],
|
|
187
186
|
'/api/scope/check': ['GET'],
|
|
188
187
|
'/api/scope/check-batch': ['POST'],
|
|
189
|
-
'/api/shared/{token}': ['GET'],
|
|
190
|
-
'/api/shares/{shareId}': ['DELETE', 'PATCH'],
|
|
191
188
|
'/api/source-sync/candidate-sets/current': ['GET'],
|
|
192
189
|
'/api/source-sync/candidate-sets/{setId}/approve': ['POST'],
|
|
193
190
|
'/api/source-sync/candidate-sets/{setId}/items': ['POST'],
|
package/src/guards/config.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -587,13 +587,7 @@ export type {
|
|
|
587
587
|
// Chat domain types
|
|
588
588
|
// @see PRD-00142 for share chat design rationale
|
|
589
589
|
export type {
|
|
590
|
-
ChatVisibility,
|
|
591
590
|
ChatSummary,
|
|
592
|
-
ChatShareInfo,
|
|
593
|
-
SharedChatView,
|
|
594
|
-
SharedChatMessage,
|
|
595
|
-
CreateShareRequest,
|
|
596
|
-
UpdateShareRequest,
|
|
597
591
|
// Chat lifecycle types
|
|
598
592
|
TitleSource,
|
|
599
593
|
ChatListFilters,
|
|
@@ -637,6 +631,9 @@ export type {
|
|
|
637
631
|
// Participation, not an ACL entity — two roles, one owner, and the agent is
|
|
638
632
|
// mentionable but never a member.
|
|
639
633
|
ChatParticipantRole,
|
|
634
|
+
ChatGrantableRole,
|
|
635
|
+
AddChatParticipantRequest,
|
|
636
|
+
UpdateChatParticipantRequest,
|
|
640
637
|
ChatParticipant,
|
|
641
638
|
ChatParticipantsResponse,
|
|
642
639
|
// Chat continuity (chat-continuity-wire-vocabulary): the subject a chat
|
|
@@ -675,6 +672,7 @@ export {
|
|
|
675
672
|
// Multi-party chat: the role vocabulary, one participant row, and the list
|
|
676
673
|
// envelope for GET /api/chats/:chatId/participants.
|
|
677
674
|
ChatParticipantRoleSchema,
|
|
675
|
+
ChatGrantableRoleSchema,
|
|
678
676
|
ChatParticipantSchema,
|
|
679
677
|
ChatParticipantsResponseSchema,
|
|
680
678
|
// Chat continuity: the closed subject-kind and continuation-reason
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# mcp/\_\_tests\_\_/
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Locks the MCP vocabulary claims the compiler alone does not.
|
|
6
|
+
|
|
7
|
+
- `capability-graph.test.ts` — `buildCapabilityGraph` derives edges from
|
|
8
|
+
`produces`/`consumes` resource flow.
|
|
9
|
+
- `resource-types-fixture.ts` — a COMPILED module, not a `*.test.ts`:
|
|
10
|
+
`src/tsconfig.json` excludes test files and vitest does not typecheck, so a
|
|
11
|
+
`satisfies ResourceType[]` written in a test would never be checked. Here
|
|
12
|
+
`tsc -b` checks that the nine original members and the five agent-reference
|
|
13
|
+
members (`company_md.doc`, `company_md.thread`, `org.member`, `org.unit`,
|
|
14
|
+
`work.item`) are all `ResourceType` members, and that no union member is
|
|
15
|
+
left unlisted.
|
|
16
|
+
- `resources.test.ts` — the runtime half: fourteen distinct members, each
|
|
17
|
+
`<domain>.<kind>`.
|
|
18
|
+
|
|
19
|
+
## Invariants
|
|
20
|
+
|
|
21
|
+
- These assert VOCABULARY and SHAPE, never behavior.
|
|
22
|
+
|
|
23
|
+
## Public API
|
|
24
|
+
|
|
25
|
+
None — test-only.
|
|
26
|
+
|
|
27
|
+
## Dependencies
|
|
28
|
+
|
|
29
|
+
`vitest` and the sibling modules under test.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compile-time fixture for the `ResourceType` union (ADR slug
|
|
3
|
+
* mcp-resource-types-cover-agent-references).
|
|
4
|
+
*
|
|
5
|
+
* WHY A COMPILED MODULE AND NOT `resources.test.ts`. `src/tsconfig.json`
|
|
6
|
+
* excludes every `*.test.ts` file and vitest does not typecheck, so a
|
|
7
|
+
* `satisfies` written inside a test file is never checked. This file is not a
|
|
8
|
+
* `*.test.ts`, so `tsc -b` compiles it: a literal that stops being a
|
|
9
|
+
* `ResourceType` member fails `pnpm typecheck`. `resources.test.ts` imports the
|
|
10
|
+
* arrays to prove the runtime half (count, uniqueness).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { ResourceType } from "../resources";
|
|
14
|
+
|
|
15
|
+
/** The nine members the union carried before agent-reference kinds were added. */
|
|
16
|
+
export const ORIGINAL_RESOURCE_TYPES = [
|
|
17
|
+
"integration.connection",
|
|
18
|
+
"slack.channel",
|
|
19
|
+
"slack.channel_scope",
|
|
20
|
+
"slack.coverage",
|
|
21
|
+
"ingestion.job",
|
|
22
|
+
"knowledge.fingerprint",
|
|
23
|
+
"org.status",
|
|
24
|
+
"system.status",
|
|
25
|
+
"system.runtime",
|
|
26
|
+
] as const satisfies readonly ResourceType[];
|
|
27
|
+
|
|
28
|
+
/** The resource kinds the agent is handed a reference to (control INV-AGENT-GROUND-3). */
|
|
29
|
+
export const AGENT_REFERENCE_RESOURCE_TYPES = [
|
|
30
|
+
"company_md.doc",
|
|
31
|
+
"company_md.thread",
|
|
32
|
+
"org.member",
|
|
33
|
+
"org.unit",
|
|
34
|
+
"work.item",
|
|
35
|
+
] as const satisfies readonly ResourceType[];
|
|
36
|
+
|
|
37
|
+
/** All fourteen members. */
|
|
38
|
+
export const ALL_RESOURCE_TYPES = [
|
|
39
|
+
...ORIGINAL_RESOURCE_TYPES,
|
|
40
|
+
...AGENT_REFERENCE_RESOURCE_TYPES,
|
|
41
|
+
] as const satisfies readonly ResourceType[];
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Exhaustiveness: every `ResourceType` member is listed above. If a member is
|
|
45
|
+
* added to the union without being listed here, this assignment fails.
|
|
46
|
+
*/
|
|
47
|
+
type Unlisted = Exclude<ResourceType, (typeof ALL_RESOURCE_TYPES)[number]>;
|
|
48
|
+
export const NO_UNLISTED_RESOURCE_TYPES: [Unlisted] extends [never]
|
|
49
|
+
? true
|
|
50
|
+
: never = true;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import type { ResourceType } from "../resources";
|
|
3
|
+
import {
|
|
4
|
+
AGENT_REFERENCE_RESOURCE_TYPES,
|
|
5
|
+
ALL_RESOURCE_TYPES,
|
|
6
|
+
NO_UNLISTED_RESOURCE_TYPES,
|
|
7
|
+
ORIGINAL_RESOURCE_TYPES,
|
|
8
|
+
} from "./resource-types-fixture";
|
|
9
|
+
|
|
10
|
+
describe("ResourceType", () => {
|
|
11
|
+
it("keeps the nine original members", () => {
|
|
12
|
+
expect(ORIGINAL_RESOURCE_TYPES).toHaveLength(9);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("covers every resource kind the agent is handed a reference to", () => {
|
|
16
|
+
// Checked by the editor only (test files are not typechecked); the
|
|
17
|
+
// compiled twin is AGENT_REFERENCE_RESOURCE_TYPES in the fixture.
|
|
18
|
+
const agentReferences = [
|
|
19
|
+
"company_md.doc",
|
|
20
|
+
"company_md.thread",
|
|
21
|
+
"org.member",
|
|
22
|
+
"org.unit",
|
|
23
|
+
"work.item",
|
|
24
|
+
] satisfies ResourceType[];
|
|
25
|
+
expect([...AGENT_REFERENCE_RESOURCE_TYPES]).toEqual(agentReferences);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("has fourteen distinct members, all listed", () => {
|
|
29
|
+
expect(ALL_RESOURCE_TYPES).toHaveLength(14);
|
|
30
|
+
expect(new Set(ALL_RESOURCE_TYPES).size).toBe(14);
|
|
31
|
+
expect(NO_UNLISTED_RESOURCE_TYPES).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("namespaces every member as <domain>.<kind>", () => {
|
|
35
|
+
for (const resource of ALL_RESOURCE_TYPES) {
|
|
36
|
+
expect(resource).toMatch(/^[a-z_]+\.[a-z_]+$/);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
});
|
package/src/mcp/resources.ts
CHANGED
|
@@ -8,6 +8,11 @@
|
|
|
8
8
|
* This is a CLOSED union — new resource types represent architectural
|
|
9
9
|
* additions that require a contracts release and downstream consumer updates.
|
|
10
10
|
* Unlike ToolIntegration, resource types are not extensible via (string & {}).
|
|
11
|
+
*
|
|
12
|
+
* Since the ADR with slug mcp-resource-types-cover-agent-references, a member
|
|
13
|
+
* also exists for every resource kind the agent is handed a reference to (page
|
|
14
|
+
* context entity, citation entityId), so backend tool meta `consumes` can serve
|
|
15
|
+
* as the dereference registry (control INV-AGENT-GROUND-3).
|
|
11
16
|
*/
|
|
12
17
|
export type ResourceType =
|
|
13
18
|
| "integration.connection"
|
|
@@ -18,4 +23,14 @@ export type ResourceType =
|
|
|
18
23
|
| "knowledge.fingerprint"
|
|
19
24
|
| "org.status"
|
|
20
25
|
| "system.status"
|
|
21
|
-
| "system.runtime"
|
|
26
|
+
| "system.runtime"
|
|
27
|
+
/** A company-md document; consumed by id (uuid), or by company-md path for page context. */
|
|
28
|
+
| "company_md.doc"
|
|
29
|
+
/** A company-md comment thread; consumed by id (uuid). */
|
|
30
|
+
| "company_md.thread"
|
|
31
|
+
/** An org member; consumed by users.id (uuid). */
|
|
32
|
+
| "org.member"
|
|
33
|
+
/** An org unit; consumed by org_units.id (uuid). */
|
|
34
|
+
| "org.unit"
|
|
35
|
+
/** A work item; consumed by id (uuid). */
|
|
36
|
+
| "work.item";
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
exports[`monospace budget > overhangs only where content is atomic 1`] = `
|
|
4
4
|
[
|
|
5
5
|
"Device: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
|
|
6
|
+
"https://app.companysemantics.ai/chat/abc123",
|
|
7
|
+
"https://app.companysemantics.ai/chat/long456",
|
|
8
|
+
"https://app.companysemantics.ai/chat/preview789",
|
|
9
|
+
"https://app.companysemantics.ai/chat/short123",
|
|
6
10
|
"https://app.companysemantics.ai/doc/handbook",
|
|
7
11
|
"https://app.companysemantics.ai/doc/handbook?request=req_123",
|
|
8
12
|
"https://app.companysemantics.ai/doc/handbook?request=req_456",
|
|
@@ -16,9 +20,5 @@ exports[`monospace budget > overhangs only where content is atomic 1`] = `
|
|
|
16
20
|
"https://app.companysemantics.ai/org/unit/42",
|
|
17
21
|
"https://app.companysemantics.ai/owner-transfer/accept/tok123",
|
|
18
22
|
"https://app.companysemantics.ai/owner-transfer/accept/tok456",
|
|
19
|
-
"https://app.companysemantics.ai/share/abc123",
|
|
20
|
-
"https://app.companysemantics.ai/share/long456",
|
|
21
|
-
"https://app.companysemantics.ai/share/preview789",
|
|
22
|
-
"https://app.companysemantics.ai/share/short123",
|
|
23
23
|
]
|
|
24
24
|
`;
|