@keystrokehq/cli 0.0.65 → 0.0.68
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/{cat-TSFMZVYS-Qzyhqpeq.mjs → cat-TSFMZVYS-Bp6ZgHzP.mjs} +2 -2
- package/dist/{cat-TSFMZVYS-Qzyhqpeq.mjs.map → cat-TSFMZVYS-Bp6ZgHzP.mjs.map} +1 -1
- package/dist/{cut-OKARJCCV-UOo5blGN.mjs → cut-OKARJCCV-DLzvnQ0X.mjs} +2 -2
- package/dist/{cut-OKARJCCV-UOo5blGN.mjs.map → cut-OKARJCCV-DLzvnQ0X.mjs.map} +1 -1
- package/dist/{dist-D2apKUWN-BDQ3166v.mjs → dist-BNJUEQuz-C9tkfUCE.mjs} +203 -9
- package/dist/dist-BNJUEQuz-C9tkfUCE.mjs.map +1 -0
- package/dist/{dist-CMxQJtOA.mjs → dist-nRx_8hnk.mjs} +6 -8
- package/dist/dist-nRx_8hnk.mjs.map +1 -0
- package/dist/{du-572XNP42-4gdN6HgU.mjs → du-572XNP42-DCcv0kSr.mjs} +2 -2
- package/dist/{du-572XNP42-4gdN6HgU.mjs.map → du-572XNP42-DCcv0kSr.mjs.map} +1 -1
- package/dist/{emit-route-manifest-DRcNXHCP-BHonsCIQ.mjs → emit-route-manifest-DRcNXHCP-BkSmGkhV.mjs} +32 -13
- package/dist/{emit-route-manifest-DRcNXHCP-BHonsCIQ.mjs.map → emit-route-manifest-DRcNXHCP-BkSmGkhV.mjs.map} +1 -1
- package/dist/index.mjs +1044 -117
- package/dist/index.mjs.map +1 -1
- package/dist/{jq-4XLYLOS5-D_rIiq4w.mjs → jq-4XLYLOS5-CgTVHGto.mjs} +2 -2
- package/dist/{jq-4XLYLOS5-D_rIiq4w.mjs.map → jq-4XLYLOS5-CgTVHGto.mjs.map} +1 -1
- package/dist/{ls-ZJGQER7M-B-eSANU2.mjs → ls-ZJGQER7M-DbHjJAJ5.mjs} +2 -2
- package/dist/{ls-ZJGQER7M-B-eSANU2.mjs.map → ls-ZJGQER7M-DbHjJAJ5.mjs.map} +1 -1
- package/dist/{mistral-CCsOaxvh-FZsMk4KR.mjs → mistral-D7a1LQ-6-CFFRHspK.mjs} +3 -3
- package/dist/{mistral-CCsOaxvh-FZsMk4KR.mjs.map → mistral-D7a1LQ-6-CFFRHspK.mjs.map} +1 -1
- package/dist/{sort-SW2YEO5B-BaN_eY3l.mjs → sort-SW2YEO5B-DM3UAdjd.mjs} +2 -2
- package/dist/{sort-SW2YEO5B-BaN_eY3l.mjs.map → sort-SW2YEO5B-DM3UAdjd.mjs.map} +1 -1
- package/dist/{tree-YLD52CNT-BZJomf0H.mjs → tree-YLD52CNT-Bv1j-DWN.mjs} +2 -2
- package/dist/{tree-YLD52CNT-BZJomf0H.mjs.map → tree-YLD52CNT-Bv1j-DWN.mjs.map} +1 -1
- package/dist/{uniq-XSIZR6PB-Ajuixkb6.mjs → uniq-XSIZR6PB-d6Kx_H64.mjs} +2 -2
- package/dist/{uniq-XSIZR6PB-Ajuixkb6.mjs.map → uniq-XSIZR6PB-d6Kx_H64.mjs.map} +1 -1
- package/dist/{wc-LF7NU4LA-DiSdKP_u.mjs → wc-LF7NU4LA-B6PXzeyp.mjs} +2 -2
- package/dist/{wc-LF7NU4LA-DiSdKP_u.mjs.map → wc-LF7NU4LA-B6PXzeyp.mjs.map} +1 -1
- package/dist/{xan-Y6WF3IRG-COQGCVSz.mjs → xan-Y6WF3IRG-CnmH45qB.mjs} +2 -2
- package/dist/{xan-Y6WF3IRG-COQGCVSz.mjs.map → xan-Y6WF3IRG-CnmH45qB.mjs.map} +1 -1
- package/package.json +21 -21
- package/dist/dist-CMxQJtOA.mjs.map +0 -1
- package/dist/dist-D2apKUWN-BDQ3166v.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1460,7 +1460,7 @@ const propertyKeyTypes = /* @__PURE__ */ new Set([
|
|
|
1460
1460
|
function escapeRegex(str) {
|
|
1461
1461
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1462
1462
|
}
|
|
1463
|
-
function clone(inst, def, params) {
|
|
1463
|
+
function clone$1(inst, def, params) {
|
|
1464
1464
|
const cl = new inst._zod.constr(def ?? inst._zod.def);
|
|
1465
1465
|
if (!def || params?.parent) cl._zod.parent = inst;
|
|
1466
1466
|
return cl;
|
|
@@ -1496,7 +1496,7 @@ function pick(schema, mask) {
|
|
|
1496
1496
|
const currDef = schema._zod.def;
|
|
1497
1497
|
const checks = currDef.checks;
|
|
1498
1498
|
if (checks && checks.length > 0) throw new Error(".pick() cannot be used on object schemas containing refinements");
|
|
1499
|
-
return clone(schema, mergeDefs(schema._zod.def, {
|
|
1499
|
+
return clone$1(schema, mergeDefs(schema._zod.def, {
|
|
1500
1500
|
get shape() {
|
|
1501
1501
|
const newShape = {};
|
|
1502
1502
|
for (const key in mask) {
|
|
@@ -1514,7 +1514,7 @@ function omit(schema, mask) {
|
|
|
1514
1514
|
const currDef = schema._zod.def;
|
|
1515
1515
|
const checks = currDef.checks;
|
|
1516
1516
|
if (checks && checks.length > 0) throw new Error(".omit() cannot be used on object schemas containing refinements");
|
|
1517
|
-
return clone(schema, mergeDefs(schema._zod.def, {
|
|
1517
|
+
return clone$1(schema, mergeDefs(schema._zod.def, {
|
|
1518
1518
|
get shape() {
|
|
1519
1519
|
const newShape = { ...schema._zod.def.shape };
|
|
1520
1520
|
for (const key in mask) {
|
|
@@ -1535,7 +1535,7 @@ function extend(schema, shape) {
|
|
|
1535
1535
|
const existingShape = schema._zod.def.shape;
|
|
1536
1536
|
for (const key in shape) if (Object.getOwnPropertyDescriptor(existingShape, key) !== void 0) throw new Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.");
|
|
1537
1537
|
}
|
|
1538
|
-
return clone(schema, mergeDefs(schema._zod.def, { get shape() {
|
|
1538
|
+
return clone$1(schema, mergeDefs(schema._zod.def, { get shape() {
|
|
1539
1539
|
const _shape = {
|
|
1540
1540
|
...schema._zod.def.shape,
|
|
1541
1541
|
...shape
|
|
@@ -1546,7 +1546,7 @@ function extend(schema, shape) {
|
|
|
1546
1546
|
}
|
|
1547
1547
|
function safeExtend(schema, shape) {
|
|
1548
1548
|
if (!isPlainObject$1(shape)) throw new Error("Invalid input to safeExtend: expected a plain object");
|
|
1549
|
-
return clone(schema, mergeDefs(schema._zod.def, { get shape() {
|
|
1549
|
+
return clone$1(schema, mergeDefs(schema._zod.def, { get shape() {
|
|
1550
1550
|
const _shape = {
|
|
1551
1551
|
...schema._zod.def.shape,
|
|
1552
1552
|
...shape
|
|
@@ -1557,7 +1557,7 @@ function safeExtend(schema, shape) {
|
|
|
1557
1557
|
}
|
|
1558
1558
|
function merge(a, b) {
|
|
1559
1559
|
if (a._zod.def.checks?.length) throw new Error(".merge() cannot be used on object schemas containing refinements. Use .safeExtend() instead.");
|
|
1560
|
-
return clone(a, mergeDefs(a._zod.def, {
|
|
1560
|
+
return clone$1(a, mergeDefs(a._zod.def, {
|
|
1561
1561
|
get shape() {
|
|
1562
1562
|
const _shape = {
|
|
1563
1563
|
...a._zod.def.shape,
|
|
@@ -1575,7 +1575,7 @@ function merge(a, b) {
|
|
|
1575
1575
|
function partial(Class, schema, mask) {
|
|
1576
1576
|
const checks = schema._zod.def.checks;
|
|
1577
1577
|
if (checks && checks.length > 0) throw new Error(".partial() cannot be used on object schemas containing refinements");
|
|
1578
|
-
return clone(schema, mergeDefs(schema._zod.def, {
|
|
1578
|
+
return clone$1(schema, mergeDefs(schema._zod.def, {
|
|
1579
1579
|
get shape() {
|
|
1580
1580
|
const oldShape = schema._zod.def.shape;
|
|
1581
1581
|
const shape = { ...oldShape };
|
|
@@ -1598,7 +1598,7 @@ function partial(Class, schema, mask) {
|
|
|
1598
1598
|
}));
|
|
1599
1599
|
}
|
|
1600
1600
|
function required(Class, schema, mask) {
|
|
1601
|
-
return clone(schema, mergeDefs(schema._zod.def, { get shape() {
|
|
1601
|
+
return clone$1(schema, mergeDefs(schema._zod.def, { get shape() {
|
|
1602
1602
|
const oldShape = schema._zod.def.shape;
|
|
1603
1603
|
const shape = { ...oldShape };
|
|
1604
1604
|
if (mask) for (const key in mask) {
|
|
@@ -5354,7 +5354,7 @@ const ZodType = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
|
|
|
5354
5354
|
return this.check(...chks);
|
|
5355
5355
|
},
|
|
5356
5356
|
clone(def, params) {
|
|
5357
|
-
return clone(this, def, params);
|
|
5357
|
+
return clone$1(this, def, params);
|
|
5358
5358
|
},
|
|
5359
5359
|
brand() {
|
|
5360
5360
|
return this;
|
|
@@ -6795,6 +6795,126 @@ function listenPortFromPublicUrl(value, fallback) {
|
|
|
6795
6795
|
return fallback;
|
|
6796
6796
|
}
|
|
6797
6797
|
}
|
|
6798
|
+
const serializedRouteManifestEntrySchema = discriminatedUnion("kind", [
|
|
6799
|
+
object({
|
|
6800
|
+
kind: literal("health"),
|
|
6801
|
+
method: literal("GET"),
|
|
6802
|
+
path: literal("/health")
|
|
6803
|
+
}),
|
|
6804
|
+
object({
|
|
6805
|
+
kind: literal("agent"),
|
|
6806
|
+
method: literal("POST"),
|
|
6807
|
+
path: string(),
|
|
6808
|
+
moduleFile: string(),
|
|
6809
|
+
requestSchema: record(string(), unknown()),
|
|
6810
|
+
responseSchema: record(string(), unknown())
|
|
6811
|
+
}),
|
|
6812
|
+
object({
|
|
6813
|
+
kind: literal("agent-sessions-list"),
|
|
6814
|
+
method: literal("GET"),
|
|
6815
|
+
path: string(),
|
|
6816
|
+
agentId: string(),
|
|
6817
|
+
moduleFile: string()
|
|
6818
|
+
}),
|
|
6819
|
+
object({
|
|
6820
|
+
kind: literal("agent-session-detail"),
|
|
6821
|
+
method: literal("GET"),
|
|
6822
|
+
path: string(),
|
|
6823
|
+
agentId: string(),
|
|
6824
|
+
moduleFile: string()
|
|
6825
|
+
}),
|
|
6826
|
+
object({
|
|
6827
|
+
kind: literal("workflow"),
|
|
6828
|
+
method: literal("POST"),
|
|
6829
|
+
path: string(),
|
|
6830
|
+
workflowId: string(),
|
|
6831
|
+
workflowName: string().optional(),
|
|
6832
|
+
moduleFile: string(),
|
|
6833
|
+
requestSchema: record(string(), unknown()),
|
|
6834
|
+
responseSchema: record(string(), unknown())
|
|
6835
|
+
}),
|
|
6836
|
+
object({
|
|
6837
|
+
kind: literal("workflow-runs-list"),
|
|
6838
|
+
method: literal("GET"),
|
|
6839
|
+
path: string(),
|
|
6840
|
+
workflowId: string(),
|
|
6841
|
+
workflowName: string().optional(),
|
|
6842
|
+
moduleFile: string()
|
|
6843
|
+
}),
|
|
6844
|
+
object({
|
|
6845
|
+
kind: literal("workflow-run-detail"),
|
|
6846
|
+
method: literal("GET"),
|
|
6847
|
+
path: string(),
|
|
6848
|
+
workflowId: string(),
|
|
6849
|
+
workflowName: string().optional(),
|
|
6850
|
+
moduleFile: string()
|
|
6851
|
+
}),
|
|
6852
|
+
object({
|
|
6853
|
+
kind: literal("trigger-webhook"),
|
|
6854
|
+
method: literal("POST"),
|
|
6855
|
+
path: string(),
|
|
6856
|
+
attachmentIds: array(string()),
|
|
6857
|
+
moduleFile: string(),
|
|
6858
|
+
requestSchema: record(string(), unknown()),
|
|
6859
|
+
responseSchema: record(string(), unknown())
|
|
6860
|
+
}),
|
|
6861
|
+
object({
|
|
6862
|
+
kind: literal("trigger-poll"),
|
|
6863
|
+
method: literal("POST"),
|
|
6864
|
+
path: string(),
|
|
6865
|
+
attachmentId: string(),
|
|
6866
|
+
moduleFile: string(),
|
|
6867
|
+
schedule: string(),
|
|
6868
|
+
responseSchema: record(string(), unknown())
|
|
6869
|
+
}),
|
|
6870
|
+
object({
|
|
6871
|
+
kind: literal("trigger-poll-group"),
|
|
6872
|
+
method: literal("POST"),
|
|
6873
|
+
path: string(),
|
|
6874
|
+
pollId: string(),
|
|
6875
|
+
attachmentIds: array(string()),
|
|
6876
|
+
moduleFile: string(),
|
|
6877
|
+
schedule: string(),
|
|
6878
|
+
responseSchema: record(string(), unknown())
|
|
6879
|
+
}),
|
|
6880
|
+
object({
|
|
6881
|
+
kind: literal("trigger-runs-list"),
|
|
6882
|
+
method: literal("GET"),
|
|
6883
|
+
path: string(),
|
|
6884
|
+
attachmentId: string(),
|
|
6885
|
+
moduleFile: string()
|
|
6886
|
+
}),
|
|
6887
|
+
object({
|
|
6888
|
+
kind: literal("trigger-run-detail"),
|
|
6889
|
+
method: literal("GET"),
|
|
6890
|
+
path: string(),
|
|
6891
|
+
attachmentId: string(),
|
|
6892
|
+
moduleFile: string()
|
|
6893
|
+
}),
|
|
6894
|
+
object({
|
|
6895
|
+
kind: literal("cron-schedule"),
|
|
6896
|
+
attachmentId: string(),
|
|
6897
|
+
moduleFile: string(),
|
|
6898
|
+
schedule: string()
|
|
6899
|
+
}),
|
|
6900
|
+
object({
|
|
6901
|
+
kind: literal("plugin"),
|
|
6902
|
+
method: _enum([
|
|
6903
|
+
"GET",
|
|
6904
|
+
"POST",
|
|
6905
|
+
"PUT",
|
|
6906
|
+
"PATCH",
|
|
6907
|
+
"DELETE"
|
|
6908
|
+
]),
|
|
6909
|
+
path: string(),
|
|
6910
|
+
plugin: string()
|
|
6911
|
+
})
|
|
6912
|
+
]);
|
|
6913
|
+
object({
|
|
6914
|
+
version: literal(1),
|
|
6915
|
+
entries: array(serializedRouteManifestEntrySchema),
|
|
6916
|
+
integrations: array(string()).optional()
|
|
6917
|
+
});
|
|
6798
6918
|
/** How a credential instance is stored (`credential_instances.auth_kind`). */
|
|
6799
6919
|
const CredentialAuthKindSchema = _enum(["api_key", "oauth_managed"]);
|
|
6800
6920
|
/** Where a credential instance is stored (`credential_instances.scope_type`). */
|
|
@@ -6872,14 +6992,18 @@ const ProjectStatusSchema = _enum([
|
|
|
6872
6992
|
"active",
|
|
6873
6993
|
"failed"
|
|
6874
6994
|
]);
|
|
6875
|
-
const OrganizationUserRoleSchema = _enum([
|
|
6876
|
-
|
|
6995
|
+
const OrganizationUserRoleSchema = _enum([
|
|
6996
|
+
"owner",
|
|
6997
|
+
"admin",
|
|
6998
|
+
"builder"
|
|
6999
|
+
]);
|
|
7000
|
+
const isoDateTime$2 = string().datetime();
|
|
6877
7001
|
const OrganizationSchema = object({
|
|
6878
7002
|
id: string(),
|
|
6879
7003
|
name: string(),
|
|
6880
7004
|
slug: OrganizationSlugSchema,
|
|
6881
|
-
createdAt: isoDateTime$
|
|
6882
|
-
updatedAt: isoDateTime$
|
|
7005
|
+
createdAt: isoDateTime$2,
|
|
7006
|
+
updatedAt: isoDateTime$2
|
|
6883
7007
|
});
|
|
6884
7008
|
const ProjectSchema = object({
|
|
6885
7009
|
id: string(),
|
|
@@ -6889,8 +7013,8 @@ const ProjectSchema = object({
|
|
|
6889
7013
|
baseUrl: string().nullable(),
|
|
6890
7014
|
runtimeId: string().nullable(),
|
|
6891
7015
|
lastError: string().nullable(),
|
|
6892
|
-
createdAt: isoDateTime$
|
|
6893
|
-
updatedAt: isoDateTime$
|
|
7016
|
+
createdAt: isoDateTime$2,
|
|
7017
|
+
updatedAt: isoDateTime$2
|
|
6894
7018
|
});
|
|
6895
7019
|
const UserOrganizationSchema = object({
|
|
6896
7020
|
organization: OrganizationSchema,
|
|
@@ -7354,6 +7478,57 @@ const TriggerListItemSchema = object({
|
|
|
7354
7478
|
const TriggerListResponseSchema = object({ triggers: array(TriggerListItemSchema) });
|
|
7355
7479
|
object({ endpoint: string().min(1).optional() });
|
|
7356
7480
|
const TriggerDetailResponseSchema = TriggerListItemSchema;
|
|
7481
|
+
const OrganizationMemberRoleSchema = _enum([
|
|
7482
|
+
"owner",
|
|
7483
|
+
"admin",
|
|
7484
|
+
"builder"
|
|
7485
|
+
]);
|
|
7486
|
+
const OrganizationMemberStatusSchema = _enum([
|
|
7487
|
+
"invited",
|
|
7488
|
+
"active",
|
|
7489
|
+
"rejected",
|
|
7490
|
+
"suspended"
|
|
7491
|
+
]);
|
|
7492
|
+
const InvitableOrganizationMemberRoleSchema = _enum(["admin", "builder"]);
|
|
7493
|
+
const isoDateTime$1 = string().datetime();
|
|
7494
|
+
const OrganizationMemberSchema = object({
|
|
7495
|
+
id: string(),
|
|
7496
|
+
name: string(),
|
|
7497
|
+
email: string().email(),
|
|
7498
|
+
role: OrganizationMemberRoleSchema,
|
|
7499
|
+
status: OrganizationMemberStatusSchema,
|
|
7500
|
+
avatarUrl: string().optional(),
|
|
7501
|
+
joinedAt: isoDateTime$1.optional(),
|
|
7502
|
+
lastActiveAt: isoDateTime$1.nullable().optional()
|
|
7503
|
+
});
|
|
7504
|
+
const ListOrganizationMembersResponseSchema = object({ members: array(OrganizationMemberSchema) });
|
|
7505
|
+
const InviteOrganizationMembersRequestSchema = object({
|
|
7506
|
+
emails: array(string().trim().email()).min(1),
|
|
7507
|
+
role: InvitableOrganizationMemberRoleSchema
|
|
7508
|
+
});
|
|
7509
|
+
const InviteOrganizationMemberResultStatusSchema = _enum([
|
|
7510
|
+
"sent",
|
|
7511
|
+
"already_member",
|
|
7512
|
+
"pending",
|
|
7513
|
+
"invalid"
|
|
7514
|
+
]);
|
|
7515
|
+
const InviteOrganizationMembersResponseSchema = object({ results: array(object({
|
|
7516
|
+
email: string(),
|
|
7517
|
+
status: InviteOrganizationMemberResultStatusSchema,
|
|
7518
|
+
invitationId: string().optional()
|
|
7519
|
+
})) });
|
|
7520
|
+
const UpdateOrganizationMemberRequestSchema = object({ role: InvitableOrganizationMemberRoleSchema });
|
|
7521
|
+
const UpdateOrganizationMemberResponseSchema = object({ member: OrganizationMemberSchema });
|
|
7522
|
+
const ListOrganizationInvitationsResponseSchema = object({ invitations: array(object({
|
|
7523
|
+
id: string(),
|
|
7524
|
+
organizationName: string(),
|
|
7525
|
+
organizationSlug: OrganizationSlugSchema,
|
|
7526
|
+
invitedByName: string().optional(),
|
|
7527
|
+
invitedByEmail: string().email().optional(),
|
|
7528
|
+
role: OrganizationMemberRoleSchema
|
|
7529
|
+
})) });
|
|
7530
|
+
const AcceptOrganizationInvitationResponseSchema = object({ organization: UserOrganizationSchema });
|
|
7531
|
+
const DeclineOrganizationInvitationResponseSchema = object({ success: literal(true) });
|
|
7357
7532
|
const ProjectArtifactStatusSchema = _enum(["pending", "ready"]);
|
|
7358
7533
|
const isoDateTime = string().datetime();
|
|
7359
7534
|
const ProjectArtifactSchema = object({
|
|
@@ -8008,8 +8183,8 @@ const DEFAULT_PROJECT_SETTINGS = {
|
|
|
8008
8183
|
defaultRole: "editor",
|
|
8009
8184
|
invitePermission: "admin"
|
|
8010
8185
|
};
|
|
8011
|
-
const MOCK_STORAGE_KEY$
|
|
8012
|
-
function getBrowserLocalStorage$
|
|
8186
|
+
const MOCK_STORAGE_KEY$4 = "keystroke:mock-project-settings:v1";
|
|
8187
|
+
function getBrowserLocalStorage$4() {
|
|
8013
8188
|
if (typeof globalThis !== "object") return null;
|
|
8014
8189
|
return globalThis.localStorage ?? null;
|
|
8015
8190
|
}
|
|
@@ -8035,10 +8210,10 @@ function mergeProjectSettings(current, patch) {
|
|
|
8035
8210
|
});
|
|
8036
8211
|
}
|
|
8037
8212
|
function readSettingsStore() {
|
|
8038
|
-
const localStorage = getBrowserLocalStorage$
|
|
8213
|
+
const localStorage = getBrowserLocalStorage$4();
|
|
8039
8214
|
if (!localStorage) return {};
|
|
8040
8215
|
try {
|
|
8041
|
-
const raw = localStorage.getItem(MOCK_STORAGE_KEY$
|
|
8216
|
+
const raw = localStorage.getItem(MOCK_STORAGE_KEY$4);
|
|
8042
8217
|
if (!raw) return {};
|
|
8043
8218
|
const parsed = JSON.parse(raw);
|
|
8044
8219
|
if (!parsed || typeof parsed !== "object") return {};
|
|
@@ -8048,10 +8223,10 @@ function readSettingsStore() {
|
|
|
8048
8223
|
}
|
|
8049
8224
|
}
|
|
8050
8225
|
function writeSettingsStore(store) {
|
|
8051
|
-
const localStorage = getBrowserLocalStorage$
|
|
8226
|
+
const localStorage = getBrowserLocalStorage$4();
|
|
8052
8227
|
if (!localStorage) return;
|
|
8053
8228
|
try {
|
|
8054
|
-
localStorage.setItem(MOCK_STORAGE_KEY$
|
|
8229
|
+
localStorage.setItem(MOCK_STORAGE_KEY$4, JSON.stringify(store));
|
|
8055
8230
|
} catch {}
|
|
8056
8231
|
}
|
|
8057
8232
|
function requireProjectId(projectId) {
|
|
@@ -8085,6 +8260,71 @@ function createProjectSettingsResource() {
|
|
|
8085
8260
|
})
|
|
8086
8261
|
};
|
|
8087
8262
|
}
|
|
8263
|
+
function createInvitationsResource(http) {
|
|
8264
|
+
return {
|
|
8265
|
+
async list() {
|
|
8266
|
+
try {
|
|
8267
|
+
const data = await http.get("/api/invitations").json();
|
|
8268
|
+
return ListOrganizationInvitationsResponseSchema.parse(data).invitations;
|
|
8269
|
+
} catch (error) {
|
|
8270
|
+
throw await toPlatformError(error);
|
|
8271
|
+
}
|
|
8272
|
+
},
|
|
8273
|
+
async accept(invitationId) {
|
|
8274
|
+
try {
|
|
8275
|
+
const data = await http.post(`/api/invitations/${encodeURIComponent(invitationId)}/accept`).json();
|
|
8276
|
+
return AcceptOrganizationInvitationResponseSchema.parse(data).organization;
|
|
8277
|
+
} catch (error) {
|
|
8278
|
+
throw await toPlatformError(error);
|
|
8279
|
+
}
|
|
8280
|
+
},
|
|
8281
|
+
async decline(invitationId) {
|
|
8282
|
+
try {
|
|
8283
|
+
const data = await http.post(`/api/invitations/${encodeURIComponent(invitationId)}/decline`).json();
|
|
8284
|
+
DeclineOrganizationInvitationResponseSchema.parse(data);
|
|
8285
|
+
} catch (error) {
|
|
8286
|
+
throw await toPlatformError(error);
|
|
8287
|
+
}
|
|
8288
|
+
}
|
|
8289
|
+
};
|
|
8290
|
+
}
|
|
8291
|
+
function createMembersResource$1(http) {
|
|
8292
|
+
return {
|
|
8293
|
+
async listOrganizationMembers() {
|
|
8294
|
+
try {
|
|
8295
|
+
const data = await http.get("/api/members").json();
|
|
8296
|
+
return ListOrganizationMembersResponseSchema.parse(data).members;
|
|
8297
|
+
} catch (error) {
|
|
8298
|
+
throw await toPlatformError(error);
|
|
8299
|
+
}
|
|
8300
|
+
},
|
|
8301
|
+
async inviteOrganizationMembers(input) {
|
|
8302
|
+
const body = InviteOrganizationMembersRequestSchema.parse(input);
|
|
8303
|
+
try {
|
|
8304
|
+
const data = await http.post("/api/members/invitations", { json: body }).json();
|
|
8305
|
+
return InviteOrganizationMembersResponseSchema.parse(data);
|
|
8306
|
+
} catch (error) {
|
|
8307
|
+
throw await toPlatformError(error);
|
|
8308
|
+
}
|
|
8309
|
+
},
|
|
8310
|
+
async updateOrganizationMember(userId, input) {
|
|
8311
|
+
const body = UpdateOrganizationMemberRequestSchema.parse(input);
|
|
8312
|
+
try {
|
|
8313
|
+
const data = await http.patch(`/api/members/${encodeURIComponent(userId)}`, { json: body }).json();
|
|
8314
|
+
return UpdateOrganizationMemberResponseSchema.parse(data).member;
|
|
8315
|
+
} catch (error) {
|
|
8316
|
+
throw await toPlatformError(error);
|
|
8317
|
+
}
|
|
8318
|
+
},
|
|
8319
|
+
async removeOrganizationMember(userId) {
|
|
8320
|
+
try {
|
|
8321
|
+
await http.delete(`/api/members/${encodeURIComponent(userId)}`);
|
|
8322
|
+
} catch (error) {
|
|
8323
|
+
throw await toPlatformError(error);
|
|
8324
|
+
}
|
|
8325
|
+
}
|
|
8326
|
+
};
|
|
8327
|
+
}
|
|
8088
8328
|
/**
|
|
8089
8329
|
* The supported-app catalog shown in the "Connect an app" picker. Mirrors the
|
|
8090
8330
|
* curated integration list from keystroke-mockups. No connected/available flag:
|
|
@@ -9090,7 +9330,6 @@ const agentSeed = [{
|
|
|
9090
9330
|
updatedAt: "2026-06-02T14:20:00Z",
|
|
9091
9331
|
description: "Triage support requests and draft helpful replies.",
|
|
9092
9332
|
sourcePath: "src/agents/support-agent.ts",
|
|
9093
|
-
mode: "sandbox",
|
|
9094
9333
|
model: "claude-4-sonnet",
|
|
9095
9334
|
toolCount: 4,
|
|
9096
9335
|
credentialCount: 2,
|
|
@@ -9102,7 +9341,6 @@ const agentSeed = [{
|
|
|
9102
9341
|
updatedAt: "2026-06-01T09:15:00Z",
|
|
9103
9342
|
description: "Summarize docs and pull answers from connected sources.",
|
|
9104
9343
|
sourcePath: "src/agents/research-agent.ts",
|
|
9105
|
-
mode: "worker",
|
|
9106
9344
|
model: "claude-4-sonnet",
|
|
9107
9345
|
toolCount: 6,
|
|
9108
9346
|
credentialCount: 3,
|
|
@@ -9115,11 +9353,8 @@ const workflowSeed = [{
|
|
|
9115
9353
|
updatedAt: "2026-06-02T11:05:00Z",
|
|
9116
9354
|
description: "Collect project updates and send a daily summary.",
|
|
9117
9355
|
sourcePath: "src/workflows/daily-digest.ts",
|
|
9118
|
-
trigger: "schedule.daily",
|
|
9119
9356
|
stepCount: 2,
|
|
9120
|
-
|
|
9121
|
-
lastRunAt: "2026-06-02T11:05:00Z",
|
|
9122
|
-
runState: "Succeeded"
|
|
9357
|
+
lastRunAt: "2026-06-02T11:05:00Z"
|
|
9123
9358
|
}, {
|
|
9124
9359
|
id: "workflow-email-triage",
|
|
9125
9360
|
name: "Email Triage",
|
|
@@ -9127,11 +9362,8 @@ const workflowSeed = [{
|
|
|
9127
9362
|
updatedAt: "2026-05-31T16:40:00Z",
|
|
9128
9363
|
description: "Label, prioritize, and draft replies for inbound email.",
|
|
9129
9364
|
sourcePath: "src/workflows/email-triage.ts",
|
|
9130
|
-
trigger: "gmail.new_message",
|
|
9131
9365
|
stepCount: 4,
|
|
9132
|
-
|
|
9133
|
-
lastRunAt: "2026-05-31T16:40:00Z",
|
|
9134
|
-
runState: "Running"
|
|
9366
|
+
lastRunAt: "2026-05-31T16:40:00Z"
|
|
9135
9367
|
}];
|
|
9136
9368
|
const skillSeed = [{
|
|
9137
9369
|
id: "skill-attio-sync",
|
|
@@ -9139,20 +9371,14 @@ const skillSeed = [{
|
|
|
9139
9371
|
projectId: "project_personal_repo",
|
|
9140
9372
|
updatedAt: "2026-06-01T18:05:00Z",
|
|
9141
9373
|
description: "Enrich company and contact records from Attio.",
|
|
9142
|
-
sourcePath: ".agents/skills/attio-sync/SKILL.md"
|
|
9143
|
-
category: "CRM",
|
|
9144
|
-
availability: "Private",
|
|
9145
|
-
lastUsedAt: "2026-06-02T08:30:00Z"
|
|
9374
|
+
sourcePath: ".agents/skills/attio-sync/SKILL.md"
|
|
9146
9375
|
}, {
|
|
9147
9376
|
id: "skill-doc-coauthor",
|
|
9148
9377
|
name: "Doc Co-author",
|
|
9149
9378
|
projectId: "project_personal_repo",
|
|
9150
9379
|
updatedAt: "2026-05-30T10:24:00Z",
|
|
9151
9380
|
description: "Collaborative writing, editing, and version tracking for docs.",
|
|
9152
|
-
sourcePath: ".agents/skills/doc-coauthor/SKILL.md"
|
|
9153
|
-
category: "Writing",
|
|
9154
|
-
availability: "Private",
|
|
9155
|
-
lastUsedAt: "2026-05-29T14:12:00Z"
|
|
9381
|
+
sourcePath: ".agents/skills/doc-coauthor/SKILL.md"
|
|
9156
9382
|
}];
|
|
9157
9383
|
const deploymentSeed = [{
|
|
9158
9384
|
id: "deployment-v002",
|
|
@@ -9163,11 +9389,7 @@ const deploymentSeed = [{
|
|
|
9163
9389
|
deployedBy: "Dallin Bentley",
|
|
9164
9390
|
deployedByEmail: "dallin@keystroke.ai",
|
|
9165
9391
|
createdAt: "2026-04-20T15:44:00Z",
|
|
9166
|
-
active: true
|
|
9167
|
-
summary: "Added support-agent and daily digest workflow.",
|
|
9168
|
-
changedFiles: 4,
|
|
9169
|
-
lineAdditions: 182,
|
|
9170
|
-
lineDeletions: 24
|
|
9392
|
+
active: true
|
|
9171
9393
|
}, {
|
|
9172
9394
|
id: "deployment-v001",
|
|
9173
9395
|
projectId: "project_personal_repo",
|
|
@@ -9177,11 +9399,7 @@ const deploymentSeed = [{
|
|
|
9177
9399
|
deployedBy: "Dallin Bentley",
|
|
9178
9400
|
deployedByEmail: "dallin@keystroke.ai",
|
|
9179
9401
|
createdAt: "2026-04-18T15:44:00Z",
|
|
9180
|
-
active: false
|
|
9181
|
-
summary: "Initial deployed project snapshot.",
|
|
9182
|
-
changedFiles: 2,
|
|
9183
|
-
lineAdditions: 96,
|
|
9184
|
-
lineDeletions: 0
|
|
9402
|
+
active: false
|
|
9185
9403
|
}];
|
|
9186
9404
|
const projectFileSeed = [
|
|
9187
9405
|
{
|
|
@@ -9258,12 +9476,13 @@ export const sendSlackMessage = defineAction({
|
|
|
9258
9476
|
`
|
|
9259
9477
|
}
|
|
9260
9478
|
];
|
|
9261
|
-
|
|
9479
|
+
/** Review personas for mocked project members and API key authors (not org membership). */
|
|
9480
|
+
const mockPersonaSeed = [
|
|
9262
9481
|
{
|
|
9263
9482
|
id: "user_blake_rouse",
|
|
9264
9483
|
name: "Blake Rouse",
|
|
9265
9484
|
email: "blake@keystroke.ai",
|
|
9266
|
-
|
|
9485
|
+
avatarUrl: "/icons/avatars/blake-rouse.png",
|
|
9267
9486
|
joinedAt: "2026-01-12T18:00:00Z",
|
|
9268
9487
|
lastActiveAt: "2026-05-31T18:00:00Z"
|
|
9269
9488
|
},
|
|
@@ -9271,7 +9490,7 @@ const organizationMemberSeed = [
|
|
|
9271
9490
|
id: "org-member-nate",
|
|
9272
9491
|
name: "Nate Wells",
|
|
9273
9492
|
email: "nate@keystroke.ai",
|
|
9274
|
-
|
|
9493
|
+
avatarUrl: "/icons/avatars/nate-kelley.png",
|
|
9275
9494
|
joinedAt: "2026-02-03T18:00:00Z",
|
|
9276
9495
|
lastActiveAt: "2026-05-31T16:00:00Z"
|
|
9277
9496
|
},
|
|
@@ -9279,7 +9498,7 @@ const organizationMemberSeed = [
|
|
|
9279
9498
|
id: "org-member-dallin",
|
|
9280
9499
|
name: "Dallin Bentley",
|
|
9281
9500
|
email: "dallin@keystroke.ai",
|
|
9282
|
-
|
|
9501
|
+
avatarUrl: "/icons/avatars/dallin-bentley.png",
|
|
9283
9502
|
joinedAt: "2026-03-18T18:00:00Z",
|
|
9284
9503
|
lastActiveAt: "2026-05-30T16:00:00Z"
|
|
9285
9504
|
},
|
|
@@ -9287,12 +9506,12 @@ const organizationMemberSeed = [
|
|
|
9287
9506
|
id: "org-member-wells",
|
|
9288
9507
|
name: "Wells Riley",
|
|
9289
9508
|
email: "wells@keystroke.ai",
|
|
9290
|
-
|
|
9509
|
+
avatarUrl: "/icons/avatars/wells-bunker.png",
|
|
9291
9510
|
joinedAt: "2026-04-09T18:00:00Z",
|
|
9292
9511
|
lastActiveAt: "2026-05-20T16:00:00Z"
|
|
9293
9512
|
}
|
|
9294
9513
|
];
|
|
9295
|
-
const projectMemberSeed =
|
|
9514
|
+
const projectMemberSeed = mockPersonaSeed.map((member, index) => ({
|
|
9296
9515
|
id: `project-member-${member.id}`,
|
|
9297
9516
|
projectId: "project_personal_repo",
|
|
9298
9517
|
name: member.name,
|
|
@@ -9309,7 +9528,7 @@ const apiKeySeed = [
|
|
|
9309
9528
|
name: "LOCAL_DEV_BLAKE",
|
|
9310
9529
|
keyPreview: "******J7Pt",
|
|
9311
9530
|
createdAt: "2026-04-20T15:44:00Z",
|
|
9312
|
-
createdBy:
|
|
9531
|
+
createdBy: mockPersonaSeed[0],
|
|
9313
9532
|
isCreatedByCurrentUser: true
|
|
9314
9533
|
},
|
|
9315
9534
|
{
|
|
@@ -9317,7 +9536,7 @@ const apiKeySeed = [
|
|
|
9317
9536
|
name: "CI deploy",
|
|
9318
9537
|
keyPreview: "******TJb7",
|
|
9319
9538
|
createdAt: "2026-03-08T15:44:00Z",
|
|
9320
|
-
createdBy:
|
|
9539
|
+
createdBy: mockPersonaSeed[1],
|
|
9321
9540
|
isCreatedByCurrentUser: false
|
|
9322
9541
|
},
|
|
9323
9542
|
{
|
|
@@ -9325,7 +9544,7 @@ const apiKeySeed = [
|
|
|
9325
9544
|
name: "partner_webhooks",
|
|
9326
9545
|
keyPreview: "******9Qzc",
|
|
9327
9546
|
createdAt: "2026-02-18T15:44:00Z",
|
|
9328
|
-
createdBy:
|
|
9547
|
+
createdBy: mockPersonaSeed[2],
|
|
9329
9548
|
isCreatedByCurrentUser: false
|
|
9330
9549
|
}
|
|
9331
9550
|
];
|
|
@@ -9374,7 +9593,7 @@ function buildRecentResourceSeed() {
|
|
|
9374
9593
|
});
|
|
9375
9594
|
const skillRecents = skillSeed.map((skill, index) => {
|
|
9376
9595
|
const lastModifiedAt = skill.updatedAt;
|
|
9377
|
-
const lastOpenedAt =
|
|
9596
|
+
const lastOpenedAt = hoursBefore(lastModifiedAt, index * 3 + 1);
|
|
9378
9597
|
return {
|
|
9379
9598
|
id: `recent-skill-${skill.id}`,
|
|
9380
9599
|
resourceKind: "skill",
|
|
@@ -9554,13 +9773,9 @@ function createProjectFilesResource() {
|
|
|
9554
9773
|
projectId
|
|
9555
9774
|
}))) };
|
|
9556
9775
|
}
|
|
9557
|
-
function createMembersResource() {
|
|
9776
|
+
function createMembersResource(http) {
|
|
9558
9777
|
return {
|
|
9559
|
-
|
|
9560
|
-
domain: "members",
|
|
9561
|
-
method: "listOrganizationMembers",
|
|
9562
|
-
plannedEndpoint: "GET /api/members"
|
|
9563
|
-
}, async () => organizationMemberSeed),
|
|
9778
|
+
...createMembersResource$1(http),
|
|
9564
9779
|
listForProject: mock({
|
|
9565
9780
|
domain: "members",
|
|
9566
9781
|
method: "listForProject",
|
|
@@ -9590,7 +9805,7 @@ function createApiKeysResource() {
|
|
|
9590
9805
|
name: input.name,
|
|
9591
9806
|
keyPreview,
|
|
9592
9807
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9593
|
-
createdBy:
|
|
9808
|
+
createdBy: mockPersonaSeed[0],
|
|
9594
9809
|
isCreatedByCurrentUser: true
|
|
9595
9810
|
};
|
|
9596
9811
|
apiKeyRecords = [created, ...apiKeyRecords];
|
|
@@ -9616,6 +9831,57 @@ function createRecentsResource() {
|
|
|
9616
9831
|
}, async () => buildRecentResourceSeed()) };
|
|
9617
9832
|
}
|
|
9618
9833
|
const historyProjectNameById = { project_personal_repo: "Blake's Project" };
|
|
9834
|
+
const MOCK_ACTOR = {
|
|
9835
|
+
userId: "user_blake",
|
|
9836
|
+
name: "Blake Rouse",
|
|
9837
|
+
avatarUrl: null
|
|
9838
|
+
};
|
|
9839
|
+
function buildCompletedUsage(durationMs) {
|
|
9840
|
+
return {
|
|
9841
|
+
runDurationMs: durationMs,
|
|
9842
|
+
lineItems: [
|
|
9843
|
+
{
|
|
9844
|
+
id: "claude-opus",
|
|
9845
|
+
label: "Claude Opus 4.8",
|
|
9846
|
+
amountUsd: .413
|
|
9847
|
+
},
|
|
9848
|
+
{
|
|
9849
|
+
id: "gemini-flash",
|
|
9850
|
+
label: "Gemini Flash 3.5",
|
|
9851
|
+
amountUsd: .001
|
|
9852
|
+
},
|
|
9853
|
+
{
|
|
9854
|
+
id: "daytona",
|
|
9855
|
+
label: "Daytona Sandbox",
|
|
9856
|
+
amountUsd: .188
|
|
9857
|
+
}
|
|
9858
|
+
],
|
|
9859
|
+
totalExcludingDurationUsd: .603
|
|
9860
|
+
};
|
|
9861
|
+
}
|
|
9862
|
+
function buildRunningUsage() {
|
|
9863
|
+
return {
|
|
9864
|
+
runDurationMs: null,
|
|
9865
|
+
lineItems: [],
|
|
9866
|
+
totalExcludingDurationUsd: null
|
|
9867
|
+
};
|
|
9868
|
+
}
|
|
9869
|
+
function buildFailedUsage(durationMs) {
|
|
9870
|
+
if (durationMs == null) return {
|
|
9871
|
+
runDurationMs: null,
|
|
9872
|
+
lineItems: [],
|
|
9873
|
+
totalExcludingDurationUsd: null
|
|
9874
|
+
};
|
|
9875
|
+
return {
|
|
9876
|
+
runDurationMs: durationMs,
|
|
9877
|
+
lineItems: [{
|
|
9878
|
+
id: "claude-opus",
|
|
9879
|
+
label: "Claude Opus 4.8",
|
|
9880
|
+
amountUsd: .021
|
|
9881
|
+
}],
|
|
9882
|
+
totalExcludingDurationUsd: .021
|
|
9883
|
+
};
|
|
9884
|
+
}
|
|
9619
9885
|
function workflowKeyFromId(workflowId) {
|
|
9620
9886
|
const row = workflowSeed.find((workflow) => workflow.id === workflowId);
|
|
9621
9887
|
if (!row?.sourcePath) return workflowId;
|
|
@@ -9637,11 +9903,17 @@ const historyRunSeed = [
|
|
|
9637
9903
|
resourceId: "agent-support",
|
|
9638
9904
|
resourceName: "Support Agent",
|
|
9639
9905
|
status: "completed",
|
|
9906
|
+
triggeredAt: "2026-04-20T15:44:00Z",
|
|
9907
|
+
timeInQueueMs: 85,
|
|
9640
9908
|
startedAt: "2026-04-20T15:44:00Z",
|
|
9641
9909
|
finishedAt: "2026-04-20T15:44:42Z",
|
|
9642
9910
|
durationMs: 42e3,
|
|
9643
9911
|
triggerLabel: "Gateway",
|
|
9644
9912
|
triggerRaw: "gateway",
|
|
9913
|
+
ranAs: MOCK_ACTOR,
|
|
9914
|
+
modelsUsed: ["Claude Opus 4.8", "Gemini Flash 3.5"],
|
|
9915
|
+
otherServicesUsed: ["Slack", "Daytona Sandbox"],
|
|
9916
|
+
totalCostUsd: .603,
|
|
9645
9917
|
messageCount: 8
|
|
9646
9918
|
},
|
|
9647
9919
|
{
|
|
@@ -9654,11 +9926,17 @@ const historyRunSeed = [
|
|
|
9654
9926
|
resourceId: "workflow-daily-digest",
|
|
9655
9927
|
resourceName: "Daily Digest",
|
|
9656
9928
|
status: "running",
|
|
9929
|
+
triggeredAt: "2026-04-20T15:12:00Z",
|
|
9930
|
+
timeInQueueMs: null,
|
|
9657
9931
|
startedAt: "2026-04-20T15:12:00Z",
|
|
9658
9932
|
finishedAt: null,
|
|
9659
9933
|
durationMs: null,
|
|
9660
9934
|
triggerLabel: "Cron",
|
|
9661
9935
|
triggerRaw: "cron",
|
|
9936
|
+
ranAs: MOCK_ACTOR,
|
|
9937
|
+
modelsUsed: [],
|
|
9938
|
+
otherServicesUsed: [],
|
|
9939
|
+
totalCostUsd: null,
|
|
9662
9940
|
stepCount: 1
|
|
9663
9941
|
},
|
|
9664
9942
|
{
|
|
@@ -9671,11 +9949,17 @@ const historyRunSeed = [
|
|
|
9671
9949
|
resourceId: "agent-support",
|
|
9672
9950
|
resourceName: "Support Agent",
|
|
9673
9951
|
status: "failed",
|
|
9952
|
+
triggeredAt: "2026-04-19T18:22:00Z",
|
|
9953
|
+
timeInQueueMs: 45,
|
|
9674
9954
|
startedAt: "2026-04-19T18:22:00Z",
|
|
9675
9955
|
finishedAt: "2026-04-19T18:22:12Z",
|
|
9676
9956
|
durationMs: 12e3,
|
|
9677
9957
|
triggerLabel: "Gateway",
|
|
9678
9958
|
triggerRaw: "gateway",
|
|
9959
|
+
ranAs: MOCK_ACTOR,
|
|
9960
|
+
modelsUsed: ["Claude Opus 4.8"],
|
|
9961
|
+
otherServicesUsed: ["Slack"],
|
|
9962
|
+
totalCostUsd: .021,
|
|
9679
9963
|
messageCount: 2
|
|
9680
9964
|
},
|
|
9681
9965
|
{
|
|
@@ -9688,11 +9972,17 @@ const historyRunSeed = [
|
|
|
9688
9972
|
resourceId: "workflow-email-triage",
|
|
9689
9973
|
resourceName: "Email Triage",
|
|
9690
9974
|
status: "failed",
|
|
9975
|
+
triggeredAt: "2026-05-31T16:40:05Z",
|
|
9976
|
+
timeInQueueMs: 120,
|
|
9691
9977
|
startedAt: "2026-05-31T16:40:05Z",
|
|
9692
9978
|
finishedAt: "2026-05-31T16:40:18Z",
|
|
9693
9979
|
durationMs: 13e3,
|
|
9694
9980
|
triggerLabel: "Webhook",
|
|
9695
9981
|
triggerRaw: "webhook",
|
|
9982
|
+
ranAs: MOCK_ACTOR,
|
|
9983
|
+
modelsUsed: ["Claude Opus 4.8"],
|
|
9984
|
+
otherServicesUsed: ["Gmail"],
|
|
9985
|
+
totalCostUsd: .021,
|
|
9696
9986
|
stepCount: 2
|
|
9697
9987
|
},
|
|
9698
9988
|
{
|
|
@@ -9705,15 +9995,59 @@ const historyRunSeed = [
|
|
|
9705
9995
|
resourceId: "agent-research",
|
|
9706
9996
|
resourceName: "Research Agent",
|
|
9707
9997
|
status: "completed",
|
|
9998
|
+
triggeredAt: "2026-06-01T09:15:00Z",
|
|
9999
|
+
timeInQueueMs: 210,
|
|
9708
10000
|
startedAt: "2026-06-01T09:15:00Z",
|
|
9709
10001
|
finishedAt: "2026-06-01T09:16:24Z",
|
|
9710
10002
|
durationMs: 84e3,
|
|
9711
10003
|
triggerLabel: "API",
|
|
9712
10004
|
triggerRaw: "api",
|
|
10005
|
+
ranAs: MOCK_ACTOR,
|
|
10006
|
+
modelsUsed: ["Claude Opus 4.8"],
|
|
10007
|
+
otherServicesUsed: ["Exa"],
|
|
10008
|
+
totalCostUsd: .603,
|
|
9713
10009
|
messageCount: 12
|
|
9714
10010
|
}
|
|
9715
10011
|
];
|
|
10012
|
+
const historyRunById = Object.fromEntries(historyRunSeed.map((run) => [run.id, run]));
|
|
10013
|
+
/** Resolve a seed run by id so fixtures stay consistent if the seed is reordered. */
|
|
10014
|
+
function runById(id) {
|
|
10015
|
+
const run = historyRunById[id];
|
|
10016
|
+
if (!run) throw new Error(`Unknown history run: ${id}`);
|
|
10017
|
+
return run;
|
|
10018
|
+
}
|
|
10019
|
+
let historyRuns = historyRunSeed.map((run) => ({ ...run }));
|
|
10020
|
+
const historyRunStatusOverrides = /* @__PURE__ */ new Map();
|
|
10021
|
+
function listHistoryRuns() {
|
|
10022
|
+
return historyRuns;
|
|
10023
|
+
}
|
|
10024
|
+
/**
|
|
10025
|
+
* Cancel a running/queued run. Terminal runs are returned unchanged. Updates the
|
|
10026
|
+
* list row and records an override so {@link getHistoryRunDetail} stays in sync.
|
|
10027
|
+
*/
|
|
10028
|
+
function cancelHistoryRun(runId) {
|
|
10029
|
+
const run = historyRuns.find((entry) => entry.id === runId);
|
|
10030
|
+
if (!run) return null;
|
|
10031
|
+
if (run.status !== "running" && run.status !== "pending") return run;
|
|
10032
|
+
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
10033
|
+
const durationMs = run.startedAt ? Math.max(0, new Date(finishedAt).getTime() - new Date(run.startedAt).getTime()) : run.durationMs;
|
|
10034
|
+
const canceled = {
|
|
10035
|
+
...run,
|
|
10036
|
+
status: "canceled",
|
|
10037
|
+
finishedAt,
|
|
10038
|
+
durationMs
|
|
10039
|
+
};
|
|
10040
|
+
historyRuns = historyRuns.map((entry) => entry.id === runId ? canceled : entry);
|
|
10041
|
+
historyRunStatusOverrides.set(runId, {
|
|
10042
|
+
status: "canceled",
|
|
10043
|
+
finishedAt
|
|
10044
|
+
});
|
|
10045
|
+
return canceled;
|
|
10046
|
+
}
|
|
9716
10047
|
function buildSupportAgentTrace(runId, failed) {
|
|
10048
|
+
const run = runById(runId);
|
|
10049
|
+
const startedAt = run.startedAt;
|
|
10050
|
+
const finishedAt = run.finishedAt ?? run.startedAt;
|
|
9717
10051
|
const sessionSpanId = `span-session-${runId}`;
|
|
9718
10052
|
return {
|
|
9719
10053
|
traceId: runId,
|
|
@@ -9721,13 +10055,17 @@ function buildSupportAgentTrace(runId, failed) {
|
|
|
9721
10055
|
triggerType: "gateway",
|
|
9722
10056
|
triggerRunId: `trigger-${runId}`,
|
|
9723
10057
|
agentKey: "support-agent",
|
|
10058
|
+
attachmentId: "attach-slack-incoming",
|
|
9724
10059
|
attachmentKey: "slack-incoming",
|
|
10060
|
+
route: "/agents/support-agent",
|
|
9725
10061
|
sourcePath: "src/triggers/slack-message.ts"
|
|
9726
10062
|
},
|
|
9727
10063
|
gateway: {
|
|
10064
|
+
gatewayAttachmentId: "attach-slack-incoming",
|
|
9728
10065
|
gatewayAttachmentKey: "slack-incoming",
|
|
9729
10066
|
threadId: "C01234567",
|
|
9730
|
-
channelId: "support-escalations"
|
|
10067
|
+
channelId: "support-escalations",
|
|
10068
|
+
mode: "thread"
|
|
9731
10069
|
},
|
|
9732
10070
|
spans: [{
|
|
9733
10071
|
id: sessionSpanId,
|
|
@@ -9737,8 +10075,8 @@ function buildSupportAgentTrace(runId, failed) {
|
|
|
9737
10075
|
refId: runId,
|
|
9738
10076
|
name: "Support Agent",
|
|
9739
10077
|
status: failed ? "error" : "ok",
|
|
9740
|
-
startedAt
|
|
9741
|
-
finishedAt
|
|
10078
|
+
startedAt,
|
|
10079
|
+
finishedAt,
|
|
9742
10080
|
metadata: { messageCount: failed ? 2 : 8 },
|
|
9743
10081
|
error: failed ? { message: "Credential expired" } : null
|
|
9744
10082
|
}, {
|
|
@@ -9749,8 +10087,8 @@ function buildSupportAgentTrace(runId, failed) {
|
|
|
9749
10087
|
refId: `tool-${runId}`,
|
|
9750
10088
|
name: "post_slack_reply",
|
|
9751
10089
|
status: failed ? "error" : "ok",
|
|
9752
|
-
startedAt
|
|
9753
|
-
finishedAt
|
|
10090
|
+
startedAt,
|
|
10091
|
+
finishedAt,
|
|
9754
10092
|
metadata: null,
|
|
9755
10093
|
error: failed ? { message: "oauth_token_expired" } : null
|
|
9756
10094
|
}],
|
|
@@ -9763,7 +10101,7 @@ function buildSupportAgentTrace(runId, failed) {
|
|
|
9763
10101
|
message: failed ? "Received Slack message" : "Session started from gateway thread",
|
|
9764
10102
|
data: null,
|
|
9765
10103
|
source: "system",
|
|
9766
|
-
createdAt:
|
|
10104
|
+
createdAt: startedAt
|
|
9767
10105
|
}, {
|
|
9768
10106
|
id: `log-${runId}-2`,
|
|
9769
10107
|
traceId: runId,
|
|
@@ -9773,7 +10111,7 @@ function buildSupportAgentTrace(runId, failed) {
|
|
|
9773
10111
|
message: failed ? "Credential expired before response could be posted." : "Drafted three support replies.",
|
|
9774
10112
|
data: null,
|
|
9775
10113
|
source: "system",
|
|
9776
|
-
createdAt:
|
|
10114
|
+
createdAt: finishedAt
|
|
9777
10115
|
}]
|
|
9778
10116
|
};
|
|
9779
10117
|
}
|
|
@@ -9784,7 +10122,9 @@ function buildDailyDigestTrace() {
|
|
|
9784
10122
|
triggerType: "cron",
|
|
9785
10123
|
triggerRunId: "trigger-daily-digest-001",
|
|
9786
10124
|
workflowKey: "daily-digest",
|
|
10125
|
+
attachmentId: "attach-schedule-daily",
|
|
9787
10126
|
attachmentKey: "schedule-daily",
|
|
10127
|
+
route: "/workflows/daily-digest",
|
|
9788
10128
|
sourcePath: "src/triggers/daily-digest.ts"
|
|
9789
10129
|
},
|
|
9790
10130
|
gateway: null,
|
|
@@ -9879,7 +10219,9 @@ function buildEmailTriageDetail() {
|
|
|
9879
10219
|
triggerType: "webhook",
|
|
9880
10220
|
triggerRunId: "trigger-email-002",
|
|
9881
10221
|
workflowKey: "email-triage",
|
|
9882
|
-
|
|
10222
|
+
attachmentId: "attach-gmail-new-message",
|
|
10223
|
+
attachmentKey: "gmail-new-message",
|
|
10224
|
+
route: "/workflows/email-triage"
|
|
9883
10225
|
},
|
|
9884
10226
|
gateway: null,
|
|
9885
10227
|
spans: [{
|
|
@@ -9906,7 +10248,9 @@ function buildEmailTriageDetail() {
|
|
|
9906
10248
|
source: "system",
|
|
9907
10249
|
createdAt: "2026-05-31T16:40:18Z"
|
|
9908
10250
|
}]
|
|
9909
|
-
}
|
|
10251
|
+
},
|
|
10252
|
+
ranAs: MOCK_ACTOR,
|
|
10253
|
+
usage: buildFailedUsage(13e3)
|
|
9910
10254
|
};
|
|
9911
10255
|
}
|
|
9912
10256
|
const historyDetailById = {
|
|
@@ -9933,7 +10277,9 @@ const historyDetailById = {
|
|
|
9933
10277
|
role: "assistant",
|
|
9934
10278
|
content: "Drafted reply with prorated credit explanation."
|
|
9935
10279
|
}],
|
|
9936
|
-
trace: buildSupportAgentTrace("run-support-agent-001", false)
|
|
10280
|
+
trace: buildSupportAgentTrace("run-support-agent-001", false),
|
|
10281
|
+
ranAs: MOCK_ACTOR,
|
|
10282
|
+
usage: buildCompletedUsage(42e3)
|
|
9937
10283
|
},
|
|
9938
10284
|
"run-support-agent-000": {
|
|
9939
10285
|
kind: "agent",
|
|
@@ -9955,7 +10301,9 @@ const historyDetailById = {
|
|
|
9955
10301
|
role: "user",
|
|
9956
10302
|
content: "Urgent refund request in #support."
|
|
9957
10303
|
}],
|
|
9958
|
-
trace: buildSupportAgentTrace("run-support-agent-000", true)
|
|
10304
|
+
trace: buildSupportAgentTrace("run-support-agent-000", true),
|
|
10305
|
+
ranAs: MOCK_ACTOR,
|
|
10306
|
+
usage: buildFailedUsage(12e3)
|
|
9959
10307
|
},
|
|
9960
10308
|
"run-daily-digest-001": {
|
|
9961
10309
|
kind: "workflow",
|
|
@@ -9985,7 +10333,9 @@ const historyDetailById = {
|
|
|
9985
10333
|
output: { projects: 3 },
|
|
9986
10334
|
completedAt: "2026-04-20T15:12:45Z"
|
|
9987
10335
|
}],
|
|
9988
|
-
trace: buildDailyDigestTrace()
|
|
10336
|
+
trace: buildDailyDigestTrace(),
|
|
10337
|
+
ranAs: MOCK_ACTOR,
|
|
10338
|
+
usage: buildRunningUsage()
|
|
9989
10339
|
},
|
|
9990
10340
|
"run-email-triage-002": buildEmailTriageDetail(),
|
|
9991
10341
|
"run-research-agent-003": {
|
|
@@ -10013,7 +10363,8 @@ const historyDetailById = {
|
|
|
10013
10363
|
trigger: {
|
|
10014
10364
|
triggerType: "api",
|
|
10015
10365
|
triggerRunId: "trigger-research-003",
|
|
10016
|
-
agentKey: "research-agent"
|
|
10366
|
+
agentKey: "research-agent",
|
|
10367
|
+
route: "/agents/research-agent"
|
|
10017
10368
|
},
|
|
10018
10369
|
gateway: null,
|
|
10019
10370
|
spans: [{
|
|
@@ -10040,11 +10391,34 @@ const historyDetailById = {
|
|
|
10040
10391
|
source: "system",
|
|
10041
10392
|
createdAt: "2026-06-01T09:16:24Z"
|
|
10042
10393
|
}]
|
|
10043
|
-
}
|
|
10394
|
+
},
|
|
10395
|
+
ranAs: MOCK_ACTOR,
|
|
10396
|
+
usage: buildCompletedUsage(84e3)
|
|
10044
10397
|
}
|
|
10045
10398
|
};
|
|
10399
|
+
function applyRunStatusOverride(detail, override) {
|
|
10400
|
+
if (detail.kind === "workflow") return {
|
|
10401
|
+
...detail,
|
|
10402
|
+
run: {
|
|
10403
|
+
...detail.run,
|
|
10404
|
+
status: override.status,
|
|
10405
|
+
finishedAt: override.finishedAt
|
|
10406
|
+
}
|
|
10407
|
+
};
|
|
10408
|
+
return {
|
|
10409
|
+
...detail,
|
|
10410
|
+
session: {
|
|
10411
|
+
...detail.session,
|
|
10412
|
+
status: override.status,
|
|
10413
|
+
updatedAt: override.finishedAt ?? detail.session.updatedAt
|
|
10414
|
+
}
|
|
10415
|
+
};
|
|
10416
|
+
}
|
|
10046
10417
|
function getHistoryRunDetail(runId) {
|
|
10047
|
-
|
|
10418
|
+
const detail = historyDetailById[runId];
|
|
10419
|
+
if (!detail) return null;
|
|
10420
|
+
const override = historyRunStatusOverrides.get(runId);
|
|
10421
|
+
return override ? applyRunStatusOverride(detail, override) : detail;
|
|
10048
10422
|
}
|
|
10049
10423
|
function createHistoryResource() {
|
|
10050
10424
|
return {
|
|
@@ -10053,16 +10427,22 @@ function createHistoryResource() {
|
|
|
10053
10427
|
domain: "history",
|
|
10054
10428
|
method: "list",
|
|
10055
10429
|
plannedEndpoint: "GET /api/orgs/:orgSlug/history"
|
|
10056
|
-
}, async () => [...
|
|
10430
|
+
}, async () => [...listHistoryRuns()].sort((a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime())),
|
|
10057
10431
|
get: mock({
|
|
10058
10432
|
domain: "history",
|
|
10059
10433
|
method: "get",
|
|
10060
10434
|
plannedEndpoint: "GET /api/orgs/:orgSlug/history/:runId"
|
|
10061
|
-
}, async (runId) => getHistoryRunDetail(runId))
|
|
10435
|
+
}, async (runId) => getHistoryRunDetail(runId)),
|
|
10436
|
+
/** Cancel a running/queued run. Returns the updated run (or null if unknown). */
|
|
10437
|
+
cancel: mock({
|
|
10438
|
+
domain: "history",
|
|
10439
|
+
method: "cancel",
|
|
10440
|
+
plannedEndpoint: "POST /api/orgs/:orgSlug/history/:runId/cancel"
|
|
10441
|
+
}, async (runId) => cancelHistoryRun(runId))
|
|
10062
10442
|
};
|
|
10063
10443
|
}
|
|
10064
|
-
const MOCK_STORAGE_KEY$
|
|
10065
|
-
function getBrowserLocalStorage$
|
|
10444
|
+
const MOCK_STORAGE_KEY$3 = "keystroke:mock-organization-sidebar-branding:v1";
|
|
10445
|
+
function getBrowserLocalStorage$3() {
|
|
10066
10446
|
if (typeof globalThis !== "object") return null;
|
|
10067
10447
|
return globalThis.localStorage ?? null;
|
|
10068
10448
|
}
|
|
@@ -10105,10 +10485,10 @@ function mergeOrganizationSidebarBranding(current, patch) {
|
|
|
10105
10485
|
});
|
|
10106
10486
|
}
|
|
10107
10487
|
function readBrandingStore() {
|
|
10108
|
-
const localStorage = getBrowserLocalStorage$
|
|
10488
|
+
const localStorage = getBrowserLocalStorage$3();
|
|
10109
10489
|
if (!localStorage) return {};
|
|
10110
10490
|
try {
|
|
10111
|
-
const raw = localStorage.getItem(MOCK_STORAGE_KEY$
|
|
10491
|
+
const raw = localStorage.getItem(MOCK_STORAGE_KEY$3);
|
|
10112
10492
|
if (!raw) return {};
|
|
10113
10493
|
const parsed = JSON.parse(raw);
|
|
10114
10494
|
if (!parsed || typeof parsed !== "object") return {};
|
|
@@ -10118,10 +10498,10 @@ function readBrandingStore() {
|
|
|
10118
10498
|
}
|
|
10119
10499
|
}
|
|
10120
10500
|
function writeBrandingStore(store) {
|
|
10121
|
-
const localStorage = getBrowserLocalStorage$
|
|
10501
|
+
const localStorage = getBrowserLocalStorage$3();
|
|
10122
10502
|
if (!localStorage) return;
|
|
10123
10503
|
try {
|
|
10124
|
-
localStorage.setItem(MOCK_STORAGE_KEY$
|
|
10504
|
+
localStorage.setItem(MOCK_STORAGE_KEY$3, JSON.stringify(store));
|
|
10125
10505
|
} catch {}
|
|
10126
10506
|
}
|
|
10127
10507
|
function resolveOrganizationId(getActiveOrganizationId) {
|
|
@@ -10155,8 +10535,8 @@ function createOrganizationSidebarBrandingResource(options) {
|
|
|
10155
10535
|
})
|
|
10156
10536
|
};
|
|
10157
10537
|
}
|
|
10158
|
-
const MOCK_STORAGE_KEY$
|
|
10159
|
-
function getBrowserLocalStorage$
|
|
10538
|
+
const MOCK_STORAGE_KEY$2 = "keystroke:mock-user-preferences:v1";
|
|
10539
|
+
function getBrowserLocalStorage$2() {
|
|
10160
10540
|
if (typeof globalThis !== "object") return null;
|
|
10161
10541
|
return globalThis.localStorage ?? null;
|
|
10162
10542
|
}
|
|
@@ -10264,10 +10644,10 @@ function mergeUserPreferences(current, patch) {
|
|
|
10264
10644
|
});
|
|
10265
10645
|
}
|
|
10266
10646
|
function readPreferencesStore() {
|
|
10267
|
-
const localStorage = getBrowserLocalStorage$
|
|
10647
|
+
const localStorage = getBrowserLocalStorage$2();
|
|
10268
10648
|
if (!localStorage) return {};
|
|
10269
10649
|
try {
|
|
10270
|
-
const raw = localStorage.getItem(MOCK_STORAGE_KEY$
|
|
10650
|
+
const raw = localStorage.getItem(MOCK_STORAGE_KEY$2);
|
|
10271
10651
|
if (!raw) return {};
|
|
10272
10652
|
const parsed = JSON.parse(raw);
|
|
10273
10653
|
if (!parsed || typeof parsed !== "object") return {};
|
|
@@ -10278,10 +10658,10 @@ function readPreferencesStore() {
|
|
|
10278
10658
|
}
|
|
10279
10659
|
}
|
|
10280
10660
|
function writePreferencesStore(store) {
|
|
10281
|
-
const localStorage = getBrowserLocalStorage$
|
|
10661
|
+
const localStorage = getBrowserLocalStorage$2();
|
|
10282
10662
|
if (!localStorage) return;
|
|
10283
10663
|
try {
|
|
10284
|
-
localStorage.setItem(MOCK_STORAGE_KEY$
|
|
10664
|
+
localStorage.setItem(MOCK_STORAGE_KEY$2, JSON.stringify(store));
|
|
10285
10665
|
} catch {}
|
|
10286
10666
|
}
|
|
10287
10667
|
function resolveUserId$1(getCurrentUserId) {
|
|
@@ -10316,8 +10696,8 @@ function createUserPreferencesResource(options) {
|
|
|
10316
10696
|
};
|
|
10317
10697
|
}
|
|
10318
10698
|
const DEFAULT_USER_AVATAR = { dataUrl: null };
|
|
10319
|
-
const MOCK_STORAGE_KEY = "keystroke:mock-user-avatar:v1";
|
|
10320
|
-
function getBrowserLocalStorage() {
|
|
10699
|
+
const MOCK_STORAGE_KEY$1 = "keystroke:mock-user-avatar:v1";
|
|
10700
|
+
function getBrowserLocalStorage$1() {
|
|
10321
10701
|
if (typeof globalThis !== "object") return null;
|
|
10322
10702
|
return globalThis.localStorage ?? null;
|
|
10323
10703
|
}
|
|
@@ -10327,10 +10707,10 @@ function normalizeUserAvatar(value) {
|
|
|
10327
10707
|
return { dataUrl: typeof dataUrl === "string" && dataUrl.length > 0 ? dataUrl : null };
|
|
10328
10708
|
}
|
|
10329
10709
|
function readAvatarStore() {
|
|
10330
|
-
const localStorage = getBrowserLocalStorage();
|
|
10710
|
+
const localStorage = getBrowserLocalStorage$1();
|
|
10331
10711
|
if (!localStorage) return {};
|
|
10332
10712
|
try {
|
|
10333
|
-
const raw = localStorage.getItem(MOCK_STORAGE_KEY);
|
|
10713
|
+
const raw = localStorage.getItem(MOCK_STORAGE_KEY$1);
|
|
10334
10714
|
if (!raw) return {};
|
|
10335
10715
|
const parsed = JSON.parse(raw);
|
|
10336
10716
|
if (!parsed || typeof parsed !== "object") return {};
|
|
@@ -10340,10 +10720,10 @@ function readAvatarStore() {
|
|
|
10340
10720
|
}
|
|
10341
10721
|
}
|
|
10342
10722
|
function writeAvatarStore(store) {
|
|
10343
|
-
const localStorage = getBrowserLocalStorage();
|
|
10723
|
+
const localStorage = getBrowserLocalStorage$1();
|
|
10344
10724
|
if (!localStorage) return;
|
|
10345
10725
|
try {
|
|
10346
|
-
localStorage.setItem(MOCK_STORAGE_KEY, JSON.stringify(store));
|
|
10726
|
+
localStorage.setItem(MOCK_STORAGE_KEY$1, JSON.stringify(store));
|
|
10347
10727
|
} catch {}
|
|
10348
10728
|
}
|
|
10349
10729
|
function resolveUserId(getCurrentUserId) {
|
|
@@ -10377,6 +10757,558 @@ function createUserAvatarResource(options) {
|
|
|
10377
10757
|
})
|
|
10378
10758
|
};
|
|
10379
10759
|
}
|
|
10760
|
+
const CHANNEL_PLATFORMS = [
|
|
10761
|
+
{
|
|
10762
|
+
key: "slack",
|
|
10763
|
+
name: "Slack",
|
|
10764
|
+
appLogoId: "slack",
|
|
10765
|
+
fallbackDomain: "slack.com",
|
|
10766
|
+
description: "Connect a Slack workspace so this agent can respond in channels, threads, and DMs.",
|
|
10767
|
+
tagline: "Respond in channels, threads, and DMs.",
|
|
10768
|
+
authKind: "oauth",
|
|
10769
|
+
credentialFields: [],
|
|
10770
|
+
capabilities: {
|
|
10771
|
+
mentions: true,
|
|
10772
|
+
reactions: "full",
|
|
10773
|
+
cards: "full",
|
|
10774
|
+
modals: true,
|
|
10775
|
+
streaming: "native",
|
|
10776
|
+
dms: true
|
|
10777
|
+
},
|
|
10778
|
+
supportedModes: [
|
|
10779
|
+
"mention",
|
|
10780
|
+
"all",
|
|
10781
|
+
"dm"
|
|
10782
|
+
],
|
|
10783
|
+
resourceNoun: {
|
|
10784
|
+
singular: "channel",
|
|
10785
|
+
plural: "channels"
|
|
10786
|
+
},
|
|
10787
|
+
webhookPathHint: "/gateways/slack",
|
|
10788
|
+
supportsChannelDirectory: true,
|
|
10789
|
+
docsUrl: "https://chat-sdk.dev/adapters/official/slack"
|
|
10790
|
+
},
|
|
10791
|
+
{
|
|
10792
|
+
key: "discord",
|
|
10793
|
+
name: "Discord",
|
|
10794
|
+
appLogoId: "discord",
|
|
10795
|
+
fallbackDomain: "discord.com",
|
|
10796
|
+
description: "Connect a Discord application so this agent can respond in servers and channels.",
|
|
10797
|
+
tagline: "Respond in servers and channels.",
|
|
10798
|
+
authKind: "credentials",
|
|
10799
|
+
credentialFields: [
|
|
10800
|
+
{
|
|
10801
|
+
key: "botToken",
|
|
10802
|
+
label: "Bot token",
|
|
10803
|
+
placeholder: "Bot token from the Discord developer portal",
|
|
10804
|
+
helpText: "Bot → Reset Token. Shown only once.",
|
|
10805
|
+
type: "password",
|
|
10806
|
+
required: true
|
|
10807
|
+
},
|
|
10808
|
+
{
|
|
10809
|
+
key: "applicationId",
|
|
10810
|
+
label: "Application ID",
|
|
10811
|
+
placeholder: "Application ID",
|
|
10812
|
+
type: "text",
|
|
10813
|
+
required: true
|
|
10814
|
+
},
|
|
10815
|
+
{
|
|
10816
|
+
key: "publicKey",
|
|
10817
|
+
label: "Public key",
|
|
10818
|
+
placeholder: "Public key",
|
|
10819
|
+
helpText: "General Information → Public Key, used to verify interactions.",
|
|
10820
|
+
type: "text",
|
|
10821
|
+
required: true
|
|
10822
|
+
}
|
|
10823
|
+
],
|
|
10824
|
+
capabilities: {
|
|
10825
|
+
mentions: true,
|
|
10826
|
+
reactions: "full",
|
|
10827
|
+
cards: "full",
|
|
10828
|
+
modals: false,
|
|
10829
|
+
streaming: "post-edit",
|
|
10830
|
+
dms: true
|
|
10831
|
+
},
|
|
10832
|
+
supportedModes: [
|
|
10833
|
+
"mention",
|
|
10834
|
+
"all",
|
|
10835
|
+
"dm"
|
|
10836
|
+
],
|
|
10837
|
+
resourceNoun: {
|
|
10838
|
+
singular: "channel",
|
|
10839
|
+
plural: "channels"
|
|
10840
|
+
},
|
|
10841
|
+
webhookPathHint: "/gateways/discord",
|
|
10842
|
+
supportsChannelDirectory: true,
|
|
10843
|
+
docsUrl: "https://chat-sdk.dev/adapters/official/discord"
|
|
10844
|
+
},
|
|
10845
|
+
{
|
|
10846
|
+
key: "telegram",
|
|
10847
|
+
name: "Telegram",
|
|
10848
|
+
appLogoId: "telegram",
|
|
10849
|
+
fallbackDomain: "telegram.org",
|
|
10850
|
+
description: "Connect a Telegram bot so this agent can respond in chats and groups.",
|
|
10851
|
+
tagline: "Respond in chats and groups.",
|
|
10852
|
+
authKind: "bot-token",
|
|
10853
|
+
credentialFields: [{
|
|
10854
|
+
key: "botToken",
|
|
10855
|
+
label: "Bot token",
|
|
10856
|
+
placeholder: "123456:ABC-DEF…",
|
|
10857
|
+
helpText: "Create a bot with @BotFather and paste its token.",
|
|
10858
|
+
type: "password",
|
|
10859
|
+
required: true
|
|
10860
|
+
}, {
|
|
10861
|
+
key: "botUsername",
|
|
10862
|
+
label: "Bot username",
|
|
10863
|
+
placeholder: "my_agent_bot",
|
|
10864
|
+
type: "text",
|
|
10865
|
+
required: false,
|
|
10866
|
+
prefix: "@"
|
|
10867
|
+
}],
|
|
10868
|
+
capabilities: {
|
|
10869
|
+
mentions: true,
|
|
10870
|
+
reactions: "full",
|
|
10871
|
+
cards: "partial",
|
|
10872
|
+
modals: false,
|
|
10873
|
+
streaming: "drafts",
|
|
10874
|
+
dms: true
|
|
10875
|
+
},
|
|
10876
|
+
supportedModes: [
|
|
10877
|
+
"mention",
|
|
10878
|
+
"all",
|
|
10879
|
+
"dm"
|
|
10880
|
+
],
|
|
10881
|
+
resourceNoun: {
|
|
10882
|
+
singular: "chat",
|
|
10883
|
+
plural: "chats"
|
|
10884
|
+
},
|
|
10885
|
+
webhookPathHint: "/gateways/telegram",
|
|
10886
|
+
supportsChannelDirectory: false,
|
|
10887
|
+
docsUrl: "https://chat-sdk.dev/adapters/official/telegram"
|
|
10888
|
+
},
|
|
10889
|
+
{
|
|
10890
|
+
key: "microsoft-teams",
|
|
10891
|
+
name: "Microsoft Teams",
|
|
10892
|
+
appLogoId: "microsoft-teams",
|
|
10893
|
+
fallbackDomain: "teams.microsoft.com",
|
|
10894
|
+
description: "Connect a Microsoft Teams app so this agent can respond in channels and chats.",
|
|
10895
|
+
tagline: "Respond in channels and chats.",
|
|
10896
|
+
authKind: "credentials",
|
|
10897
|
+
credentialFields: [
|
|
10898
|
+
{
|
|
10899
|
+
key: "appId",
|
|
10900
|
+
label: "App ID",
|
|
10901
|
+
placeholder: "Azure AD application (client) ID",
|
|
10902
|
+
type: "text",
|
|
10903
|
+
required: true
|
|
10904
|
+
},
|
|
10905
|
+
{
|
|
10906
|
+
key: "appPassword",
|
|
10907
|
+
label: "App password",
|
|
10908
|
+
placeholder: "Client secret",
|
|
10909
|
+
type: "password",
|
|
10910
|
+
required: true
|
|
10911
|
+
},
|
|
10912
|
+
{
|
|
10913
|
+
key: "tenantId",
|
|
10914
|
+
label: "Tenant ID",
|
|
10915
|
+
placeholder: "Azure AD tenant ID",
|
|
10916
|
+
type: "text",
|
|
10917
|
+
required: true
|
|
10918
|
+
}
|
|
10919
|
+
],
|
|
10920
|
+
capabilities: {
|
|
10921
|
+
mentions: true,
|
|
10922
|
+
reactions: "read-only",
|
|
10923
|
+
cards: "full",
|
|
10924
|
+
modals: true,
|
|
10925
|
+
streaming: "buffered",
|
|
10926
|
+
dms: true
|
|
10927
|
+
},
|
|
10928
|
+
supportedModes: [
|
|
10929
|
+
"mention",
|
|
10930
|
+
"all",
|
|
10931
|
+
"dm"
|
|
10932
|
+
],
|
|
10933
|
+
resourceNoun: {
|
|
10934
|
+
singular: "channel",
|
|
10935
|
+
plural: "channels"
|
|
10936
|
+
},
|
|
10937
|
+
webhookPathHint: "/gateways/teams",
|
|
10938
|
+
supportsChannelDirectory: true,
|
|
10939
|
+
docsUrl: "https://chat-sdk.dev/adapters/official/teams"
|
|
10940
|
+
},
|
|
10941
|
+
{
|
|
10942
|
+
key: "google-chat",
|
|
10943
|
+
name: "Google Chat",
|
|
10944
|
+
appLogoId: "google-chat",
|
|
10945
|
+
fallbackDomain: "chat.google.com",
|
|
10946
|
+
description: "Connect a Google Chat app so this agent can respond in spaces and direct messages.",
|
|
10947
|
+
tagline: "Respond in spaces and DMs.",
|
|
10948
|
+
authKind: "credentials",
|
|
10949
|
+
credentialFields: [{
|
|
10950
|
+
key: "serviceAccountJson",
|
|
10951
|
+
label: "Service account JSON",
|
|
10952
|
+
placeholder: "Paste the service account key JSON",
|
|
10953
|
+
helpText: "IAM → Service Accounts → Keys → Add key → JSON.",
|
|
10954
|
+
type: "textarea",
|
|
10955
|
+
required: true
|
|
10956
|
+
}, {
|
|
10957
|
+
key: "projectNumber",
|
|
10958
|
+
label: "GCP project number",
|
|
10959
|
+
placeholder: "Project number used to verify webhooks",
|
|
10960
|
+
type: "text",
|
|
10961
|
+
required: true
|
|
10962
|
+
}],
|
|
10963
|
+
capabilities: {
|
|
10964
|
+
mentions: true,
|
|
10965
|
+
reactions: "full",
|
|
10966
|
+
cards: "full",
|
|
10967
|
+
modals: false,
|
|
10968
|
+
streaming: "post-edit",
|
|
10969
|
+
dms: true
|
|
10970
|
+
},
|
|
10971
|
+
supportedModes: [
|
|
10972
|
+
"mention",
|
|
10973
|
+
"all",
|
|
10974
|
+
"dm"
|
|
10975
|
+
],
|
|
10976
|
+
resourceNoun: {
|
|
10977
|
+
singular: "space",
|
|
10978
|
+
plural: "spaces"
|
|
10979
|
+
},
|
|
10980
|
+
webhookPathHint: "/gateways/gchat",
|
|
10981
|
+
supportsChannelDirectory: true,
|
|
10982
|
+
docsUrl: "https://chat-sdk.dev/adapters/official/google-chat"
|
|
10983
|
+
}
|
|
10984
|
+
];
|
|
10985
|
+
function getChannelPlatform(key) {
|
|
10986
|
+
return CHANNEL_PLATFORMS.find((platform) => platform.key === key);
|
|
10987
|
+
}
|
|
10988
|
+
const CHANNEL_DIRECTORY = {
|
|
10989
|
+
slack: [
|
|
10990
|
+
{
|
|
10991
|
+
id: "C0SUPPORT",
|
|
10992
|
+
name: "support",
|
|
10993
|
+
kind: "public",
|
|
10994
|
+
memberCount: 48
|
|
10995
|
+
},
|
|
10996
|
+
{
|
|
10997
|
+
id: "C0GENERAL",
|
|
10998
|
+
name: "general",
|
|
10999
|
+
kind: "public",
|
|
11000
|
+
memberCount: 132
|
|
11001
|
+
},
|
|
11002
|
+
{
|
|
11003
|
+
id: "C0ENG",
|
|
11004
|
+
name: "engineering",
|
|
11005
|
+
kind: "public",
|
|
11006
|
+
memberCount: 27
|
|
11007
|
+
},
|
|
11008
|
+
{
|
|
11009
|
+
id: "C0INCIDENTS",
|
|
11010
|
+
name: "incidents",
|
|
11011
|
+
kind: "private",
|
|
11012
|
+
memberCount: 12
|
|
11013
|
+
},
|
|
11014
|
+
{
|
|
11015
|
+
id: "C0RANDOM",
|
|
11016
|
+
name: "random",
|
|
11017
|
+
kind: "public",
|
|
11018
|
+
memberCount: 118
|
|
11019
|
+
},
|
|
11020
|
+
{
|
|
11021
|
+
id: "C0ARCHIVE",
|
|
11022
|
+
name: "launch-2025",
|
|
11023
|
+
kind: "public",
|
|
11024
|
+
memberCount: 9,
|
|
11025
|
+
isArchived: true
|
|
11026
|
+
}
|
|
11027
|
+
],
|
|
11028
|
+
discord: [
|
|
11029
|
+
{
|
|
11030
|
+
id: "d-general",
|
|
11031
|
+
name: "general",
|
|
11032
|
+
kind: "public",
|
|
11033
|
+
memberCount: 540
|
|
11034
|
+
},
|
|
11035
|
+
{
|
|
11036
|
+
id: "d-help",
|
|
11037
|
+
name: "help",
|
|
11038
|
+
kind: "public",
|
|
11039
|
+
memberCount: 312
|
|
11040
|
+
},
|
|
11041
|
+
{
|
|
11042
|
+
id: "d-dev",
|
|
11043
|
+
name: "dev",
|
|
11044
|
+
kind: "public",
|
|
11045
|
+
memberCount: 76
|
|
11046
|
+
},
|
|
11047
|
+
{
|
|
11048
|
+
id: "d-staff",
|
|
11049
|
+
name: "staff",
|
|
11050
|
+
kind: "private",
|
|
11051
|
+
memberCount: 8
|
|
11052
|
+
}
|
|
11053
|
+
],
|
|
11054
|
+
telegram: [],
|
|
11055
|
+
"microsoft-teams": [
|
|
11056
|
+
{
|
|
11057
|
+
id: "t-general",
|
|
11058
|
+
name: "General",
|
|
11059
|
+
kind: "public",
|
|
11060
|
+
memberCount: 64
|
|
11061
|
+
},
|
|
11062
|
+
{
|
|
11063
|
+
id: "t-support",
|
|
11064
|
+
name: "Customer Support",
|
|
11065
|
+
kind: "public",
|
|
11066
|
+
memberCount: 22
|
|
11067
|
+
},
|
|
11068
|
+
{
|
|
11069
|
+
id: "t-leads",
|
|
11070
|
+
name: "Leadership",
|
|
11071
|
+
kind: "private",
|
|
11072
|
+
memberCount: 6
|
|
11073
|
+
}
|
|
11074
|
+
],
|
|
11075
|
+
"google-chat": [
|
|
11076
|
+
{
|
|
11077
|
+
id: "spaces/AAA-support",
|
|
11078
|
+
name: "Support",
|
|
11079
|
+
kind: "space",
|
|
11080
|
+
memberCount: 31
|
|
11081
|
+
},
|
|
11082
|
+
{
|
|
11083
|
+
id: "spaces/AAA-eng",
|
|
11084
|
+
name: "Engineering",
|
|
11085
|
+
kind: "space",
|
|
11086
|
+
memberCount: 44
|
|
11087
|
+
},
|
|
11088
|
+
{
|
|
11089
|
+
id: "spaces/AAA-ops",
|
|
11090
|
+
name: "Ops On-call",
|
|
11091
|
+
kind: "space",
|
|
11092
|
+
memberCount: 10
|
|
11093
|
+
}
|
|
11094
|
+
]
|
|
11095
|
+
};
|
|
11096
|
+
const MOCK_STORAGE_KEY = "keystroke:mock-channels:v1";
|
|
11097
|
+
function getBrowserLocalStorage() {
|
|
11098
|
+
if (typeof globalThis !== "object") return null;
|
|
11099
|
+
return globalThis.localStorage ?? null;
|
|
11100
|
+
}
|
|
11101
|
+
/** A connected Slack workspace with two bindings, so the panel is reviewable. */
|
|
11102
|
+
function seedStore() {
|
|
11103
|
+
return { "agent-support": [{
|
|
11104
|
+
id: "chan-conn-slack-support",
|
|
11105
|
+
platform: "slack",
|
|
11106
|
+
agentId: "agent-support",
|
|
11107
|
+
accountLabel: "Keystroke HQ",
|
|
11108
|
+
accountId: "T0KEYSTROKE",
|
|
11109
|
+
connectedAt: "2026-05-28T15:30:00Z",
|
|
11110
|
+
bindings: [{
|
|
11111
|
+
id: "chan-bind-support",
|
|
11112
|
+
channelId: "C0SUPPORT",
|
|
11113
|
+
channelName: "support",
|
|
11114
|
+
channelKind: "public",
|
|
11115
|
+
mode: "all",
|
|
11116
|
+
subscribeOnMention: true,
|
|
11117
|
+
createdAt: "2026-05-28T15:31:00Z",
|
|
11118
|
+
updatedAt: "2026-05-28T15:31:00Z"
|
|
11119
|
+
}, {
|
|
11120
|
+
id: "chan-bind-incidents",
|
|
11121
|
+
channelId: "C0INCIDENTS",
|
|
11122
|
+
channelName: "incidents",
|
|
11123
|
+
channelKind: "private",
|
|
11124
|
+
mode: "mention",
|
|
11125
|
+
subscribeOnMention: true,
|
|
11126
|
+
createdAt: "2026-05-29T09:05:00Z",
|
|
11127
|
+
updatedAt: "2026-05-29T09:05:00Z"
|
|
11128
|
+
}]
|
|
11129
|
+
}] };
|
|
11130
|
+
}
|
|
11131
|
+
function readStore() {
|
|
11132
|
+
const localStorage = getBrowserLocalStorage();
|
|
11133
|
+
if (!localStorage) return seedStore();
|
|
11134
|
+
try {
|
|
11135
|
+
const raw = localStorage.getItem(MOCK_STORAGE_KEY);
|
|
11136
|
+
if (!raw) {
|
|
11137
|
+
const seeded = seedStore();
|
|
11138
|
+
localStorage.setItem(MOCK_STORAGE_KEY, JSON.stringify(seeded));
|
|
11139
|
+
return seeded;
|
|
11140
|
+
}
|
|
11141
|
+
const parsed = JSON.parse(raw);
|
|
11142
|
+
if (!parsed || typeof parsed !== "object") return {};
|
|
11143
|
+
return parsed;
|
|
11144
|
+
} catch {
|
|
11145
|
+
return {};
|
|
11146
|
+
}
|
|
11147
|
+
}
|
|
11148
|
+
function writeStore(store) {
|
|
11149
|
+
const localStorage = getBrowserLocalStorage();
|
|
11150
|
+
if (!localStorage) return;
|
|
11151
|
+
try {
|
|
11152
|
+
localStorage.setItem(MOCK_STORAGE_KEY, JSON.stringify(store));
|
|
11153
|
+
} catch {}
|
|
11154
|
+
}
|
|
11155
|
+
function newId(prefix) {
|
|
11156
|
+
const cryptoRef = globalThis.crypto;
|
|
11157
|
+
if (cryptoRef?.randomUUID) return `${prefix}-${cryptoRef.randomUUID()}`;
|
|
11158
|
+
return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
11159
|
+
}
|
|
11160
|
+
function requireAgentId(agentId) {
|
|
11161
|
+
const trimmed = agentId.trim();
|
|
11162
|
+
if (!trimmed) throw new Error("Channels require an agent id");
|
|
11163
|
+
return trimmed;
|
|
11164
|
+
}
|
|
11165
|
+
function clone(value) {
|
|
11166
|
+
return JSON.parse(JSON.stringify(value));
|
|
11167
|
+
}
|
|
11168
|
+
function defaultAccountLabel(platform) {
|
|
11169
|
+
const meta = getChannelPlatform(platform);
|
|
11170
|
+
return meta ? `${meta.name} workspace` : platform;
|
|
11171
|
+
}
|
|
11172
|
+
function findConnection(connections, connectionId) {
|
|
11173
|
+
const connection = connections.find((entry) => entry.id === connectionId);
|
|
11174
|
+
if (!connection) throw new Error(`Channel connection not found: ${connectionId}`);
|
|
11175
|
+
return connection;
|
|
11176
|
+
}
|
|
11177
|
+
function toBinding(input, now) {
|
|
11178
|
+
return {
|
|
11179
|
+
id: newId("chan-bind"),
|
|
11180
|
+
channelId: input.channelId,
|
|
11181
|
+
channelName: input.channelName,
|
|
11182
|
+
channelKind: input.channelKind ?? "public",
|
|
11183
|
+
mode: input.mode ?? "mention",
|
|
11184
|
+
subscribeOnMention: input.subscribeOnMention ?? true,
|
|
11185
|
+
createdAt: now,
|
|
11186
|
+
updatedAt: now
|
|
11187
|
+
};
|
|
11188
|
+
}
|
|
11189
|
+
function createChannelsResource() {
|
|
11190
|
+
return {
|
|
11191
|
+
/** The supported-platform catalog (static; backend may derive from the adapter registry). */
|
|
11192
|
+
listPlatforms: mock({
|
|
11193
|
+
domain: "channels",
|
|
11194
|
+
method: "listPlatforms",
|
|
11195
|
+
plannedEndpoint: "GET /api/channels/platforms"
|
|
11196
|
+
}, async () => clone(CHANNEL_PLATFORMS)),
|
|
11197
|
+
/** Connections (with their channel bindings) for one agent. */
|
|
11198
|
+
listForAgent: mock({
|
|
11199
|
+
domain: "channels",
|
|
11200
|
+
method: "listForAgent",
|
|
11201
|
+
plannedEndpoint: "GET /api/agents/:agentId/channels"
|
|
11202
|
+
}, async (agentId) => {
|
|
11203
|
+
const id = requireAgentId(agentId);
|
|
11204
|
+
return clone(readStore()[id] ?? []);
|
|
11205
|
+
}),
|
|
11206
|
+
/**
|
|
11207
|
+
* Channel directory for a platform — the picker source. NET-NEW vs. the
|
|
11208
|
+
* current backend (no channel-list endpoint exists). The runtime team needs
|
|
11209
|
+
* to expose this (e.g. Slack `conversations.list`) for a real picker.
|
|
11210
|
+
*/
|
|
11211
|
+
listChannels: mock({
|
|
11212
|
+
domain: "channels",
|
|
11213
|
+
method: "listChannels",
|
|
11214
|
+
plannedEndpoint: "GET /api/channels/:platform/directory"
|
|
11215
|
+
}, async (platform) => clone(CHANNEL_DIRECTORY[platform] ?? [])),
|
|
11216
|
+
/** Connect a platform for an agent (OAuth install or credential entry), optionally with a first binding. */
|
|
11217
|
+
connect: mock({
|
|
11218
|
+
domain: "channels",
|
|
11219
|
+
method: "connect",
|
|
11220
|
+
plannedEndpoint: "POST /api/agents/:agentId/channels"
|
|
11221
|
+
}, async (input) => {
|
|
11222
|
+
const agentId = requireAgentId(input.agentId);
|
|
11223
|
+
const store = readStore();
|
|
11224
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
11225
|
+
const connection = {
|
|
11226
|
+
id: newId("chan-conn"),
|
|
11227
|
+
platform: input.platform,
|
|
11228
|
+
agentId,
|
|
11229
|
+
accountLabel: input.accountLabel ?? defaultAccountLabel(input.platform),
|
|
11230
|
+
accountId: newId("acct").toUpperCase(),
|
|
11231
|
+
connectedAt: now,
|
|
11232
|
+
bindings: input.initialBinding ? [toBinding(input.initialBinding, now)] : []
|
|
11233
|
+
};
|
|
11234
|
+
writeStore({
|
|
11235
|
+
...store,
|
|
11236
|
+
[agentId]: [...store[agentId] ?? [], connection]
|
|
11237
|
+
});
|
|
11238
|
+
return clone(connection);
|
|
11239
|
+
}),
|
|
11240
|
+
/** Add a channel binding to an existing connection. */
|
|
11241
|
+
addBinding: mock({
|
|
11242
|
+
domain: "channels",
|
|
11243
|
+
method: "addBinding",
|
|
11244
|
+
plannedEndpoint: "PUT /gateways/:platform/attachments/:channelId"
|
|
11245
|
+
}, async (input) => {
|
|
11246
|
+
const agentId = requireAgentId(input.agentId);
|
|
11247
|
+
const store = readStore();
|
|
11248
|
+
const connections = store[agentId] ?? [];
|
|
11249
|
+
const connection = findConnection(connections, input.connectionId);
|
|
11250
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
11251
|
+
connection.bindings = [...connection.bindings, toBinding(input.binding, now)];
|
|
11252
|
+
writeStore({
|
|
11253
|
+
...store,
|
|
11254
|
+
[agentId]: connections
|
|
11255
|
+
});
|
|
11256
|
+
return clone(connection);
|
|
11257
|
+
}),
|
|
11258
|
+
/** Update a binding's listen mode / subscribe flag. */
|
|
11259
|
+
updateBinding: mock({
|
|
11260
|
+
domain: "channels",
|
|
11261
|
+
method: "updateBinding",
|
|
11262
|
+
plannedEndpoint: "PUT /gateways/:platform/attachments/:channelId"
|
|
11263
|
+
}, async (input) => {
|
|
11264
|
+
const agentId = requireAgentId(input.agentId);
|
|
11265
|
+
const store = readStore();
|
|
11266
|
+
const connections = store[agentId] ?? [];
|
|
11267
|
+
const connection = findConnection(connections, input.connectionId);
|
|
11268
|
+
const binding = connection.bindings.find((entry) => entry.id === input.bindingId);
|
|
11269
|
+
if (!binding) throw new Error(`Channel binding not found: ${input.bindingId}`);
|
|
11270
|
+
if (input.patch.mode !== void 0) binding.mode = input.patch.mode;
|
|
11271
|
+
if (input.patch.subscribeOnMention !== void 0) binding.subscribeOnMention = input.patch.subscribeOnMention;
|
|
11272
|
+
binding.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
11273
|
+
writeStore({
|
|
11274
|
+
...store,
|
|
11275
|
+
[agentId]: connections
|
|
11276
|
+
});
|
|
11277
|
+
return clone(connection);
|
|
11278
|
+
}),
|
|
11279
|
+
/** Remove a channel binding. */
|
|
11280
|
+
removeBinding: mock({
|
|
11281
|
+
domain: "channels",
|
|
11282
|
+
method: "removeBinding",
|
|
11283
|
+
plannedEndpoint: "DELETE /gateways/:platform/attachments/:channelId"
|
|
11284
|
+
}, async (input) => {
|
|
11285
|
+
const agentId = requireAgentId(input.agentId);
|
|
11286
|
+
const store = readStore();
|
|
11287
|
+
const connections = store[agentId] ?? [];
|
|
11288
|
+
const connection = findConnection(connections, input.connectionId);
|
|
11289
|
+
connection.bindings = connection.bindings.filter((entry) => entry.id !== input.bindingId);
|
|
11290
|
+
writeStore({
|
|
11291
|
+
...store,
|
|
11292
|
+
[agentId]: connections
|
|
11293
|
+
});
|
|
11294
|
+
return clone(connection);
|
|
11295
|
+
}),
|
|
11296
|
+
/** Disconnect the agent from a platform (removes the connection + its bindings). */
|
|
11297
|
+
disconnect: mock({
|
|
11298
|
+
domain: "channels",
|
|
11299
|
+
method: "disconnect",
|
|
11300
|
+
plannedEndpoint: "DELETE /api/agents/:agentId/channels/:connectionId"
|
|
11301
|
+
}, async (input) => {
|
|
11302
|
+
const agentId = requireAgentId(input.agentId);
|
|
11303
|
+
const store = readStore();
|
|
11304
|
+
const next = (store[agentId] ?? []).filter((entry) => entry.id !== input.connectionId);
|
|
11305
|
+
writeStore({
|
|
11306
|
+
...store,
|
|
11307
|
+
[agentId]: next
|
|
11308
|
+
});
|
|
11309
|
+
})
|
|
11310
|
+
};
|
|
11311
|
+
}
|
|
10380
11312
|
function createPlatformClient(options) {
|
|
10381
11313
|
const auth = options.auth ?? { type: "none" };
|
|
10382
11314
|
const base = normalizeBaseUrl(options.baseUrl);
|
|
@@ -10413,7 +11345,9 @@ function createPlatformClient(options) {
|
|
|
10413
11345
|
deployments: createDeploymentsResource(),
|
|
10414
11346
|
projectMetrics: createProjectMetricsResource(),
|
|
10415
11347
|
projectFiles: createProjectFilesResource(),
|
|
10416
|
-
|
|
11348
|
+
channels: createChannelsResource(),
|
|
11349
|
+
members: createMembersResource(http),
|
|
11350
|
+
invitations: createInvitationsResource(http),
|
|
10417
11351
|
apiKeys: createApiKeysResource(),
|
|
10418
11352
|
recents: createRecentsResource(),
|
|
10419
11353
|
userPreferences: createUserPreferencesResource({ getCurrentUserId: options.getCurrentUserId }),
|
|
@@ -12739,11 +13673,8 @@ function registerBuildCommand(program) {
|
|
|
12739
13673
|
program.command("build").description("Build the keystroke project for production").option("--dir <path>", "Project directory", process.cwd()).action(async (options) => {
|
|
12740
13674
|
try {
|
|
12741
13675
|
const root = resolveProjectRoot(options.dir);
|
|
12742
|
-
const { buildApp } = await import("./dist-
|
|
12743
|
-
await buildApp({
|
|
12744
|
-
root,
|
|
12745
|
-
emitRouteManifest: false
|
|
12746
|
-
});
|
|
13676
|
+
const { buildApp } = await import("./dist-nRx_8hnk.mjs");
|
|
13677
|
+
await buildApp({ root });
|
|
12747
13678
|
process.stdout.write(`Built ${root}\n`);
|
|
12748
13679
|
} catch (error) {
|
|
12749
13680
|
const message = error instanceof Error ? error.message : "Build failed";
|
|
@@ -12798,11 +13729,8 @@ async function runDeploy(options) {
|
|
|
12798
13729
|
const config = createCliConfig();
|
|
12799
13730
|
const client = createCliPlatformClient(config);
|
|
12800
13731
|
if (!options.skipBuild) {
|
|
12801
|
-
const { buildApp } = await import("./dist-
|
|
12802
|
-
await buildApp({
|
|
12803
|
-
root,
|
|
12804
|
-
emitRouteManifest: false
|
|
12805
|
-
});
|
|
13732
|
+
const { buildApp } = await import("./dist-nRx_8hnk.mjs");
|
|
13733
|
+
await buildApp({ root });
|
|
12806
13734
|
}
|
|
12807
13735
|
const archive = packProjectArtifact(root);
|
|
12808
13736
|
let active = await client.organizations.getActive();
|
|
@@ -12892,7 +13820,7 @@ function runtimeChildEnv(parentEnv, overrides) {
|
|
|
12892
13820
|
//#region src/project/bootstrap-run.ts
|
|
12893
13821
|
/** Node args + env for `@keystrokehq/build` bootstrap (shared by start + dev). */
|
|
12894
13822
|
async function resolveBootstrapRun(options) {
|
|
12895
|
-
const { resolveRuntimeBuildArtifact } = await import("./dist-
|
|
13823
|
+
const { resolveRuntimeBuildArtifact } = await import("./dist-nRx_8hnk.mjs");
|
|
12896
13824
|
const loader = pathToFileURL(resolveRuntimeBuildArtifact(options.runtimeNodeModules, "dist/runtime-loader.mjs")).href;
|
|
12897
13825
|
const bootstrap = resolveRuntimeBuildArtifact(options.runtimeNodeModules, "dist/bootstrap.mjs");
|
|
12898
13826
|
const args = [`--import=${loader}`];
|
|
@@ -13057,7 +13985,7 @@ async function runDev(options) {
|
|
|
13057
13985
|
process.on("SIGINT", shutdown);
|
|
13058
13986
|
process.on("SIGTERM", shutdown);
|
|
13059
13987
|
try {
|
|
13060
|
-
const { watchApp } = await import("./dist-
|
|
13988
|
+
const { watchApp } = await import("./dist-nRx_8hnk.mjs");
|
|
13061
13989
|
await watchApp({
|
|
13062
13990
|
root,
|
|
13063
13991
|
clean: false,
|
|
@@ -13444,11 +14372,10 @@ async function runStart(options) {
|
|
|
13444
14372
|
const apiPort = Number(new URL(serverUrl).port || 80);
|
|
13445
14373
|
const runtimeNodeModules = resolveCliRuntimeNodeModules(resolveCliRoot(import.meta.url));
|
|
13446
14374
|
ensureNativeDeps(runtimeNodeModules);
|
|
13447
|
-
const { buildApp } = await import("./dist-
|
|
14375
|
+
const { buildApp } = await import("./dist-nRx_8hnk.mjs");
|
|
13448
14376
|
await buildApp({
|
|
13449
14377
|
root,
|
|
13450
|
-
clean: false
|
|
13451
|
-
emitRouteManifest: false
|
|
14378
|
+
clean: false
|
|
13452
14379
|
});
|
|
13453
14380
|
const processes = [{
|
|
13454
14381
|
name: "api",
|