@agent-native/dispatch 0.40.30-nightly-20261021064625 → 0.40.30
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/CHANGELOG.md +7 -47
- package/dist/actions/connect-external-agent.d.ts.map +1 -1
- package/dist/actions/connect-external-agent.js +12 -13
- package/dist/actions/connect-external-agent.js.map +1 -1
- package/dist/actions/create-workspace-resource.d.ts +13 -13
- package/dist/actions/delete-destination.d.ts +12 -12
- package/dist/actions/delete-workspace-resource.d.ts +13 -13
- package/dist/actions/import-agent.d.ts +13 -13
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +8 -0
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/inspect-connect-agent-card.d.ts +5 -0
- package/dist/actions/inspect-connect-agent-card.d.ts.map +1 -0
- package/dist/actions/inspect-connect-agent-card.js +15 -0
- package/dist/actions/inspect-connect-agent-card.js.map +1 -0
- package/dist/actions/install-curated-community-app.d.ts +36 -0
- package/dist/actions/install-curated-community-app.d.ts.map +1 -0
- package/dist/actions/install-curated-community-app.js +26 -0
- package/dist/actions/install-curated-community-app.js.map +1 -0
- package/dist/actions/list-connect-marketplace-apps.d.ts +3 -0
- package/dist/actions/list-connect-marketplace-apps.d.ts.map +1 -0
- package/dist/actions/list-connect-marketplace-apps.js +15 -0
- package/dist/actions/list-connect-marketplace-apps.js.map +1 -0
- package/dist/actions/list-connected-agents.d.ts +2 -0
- package/dist/actions/list-curated-community-apps.d.ts +3 -0
- package/dist/actions/list-curated-community-apps.d.ts.map +1 -0
- package/dist/actions/list-curated-community-apps.js +10 -0
- package/dist/actions/list-curated-community-apps.js.map +1 -0
- package/dist/actions/provider-api-register.d.ts +14 -14
- package/dist/actions/remix-workspace-template.d.ts +6 -0
- package/dist/actions/update-workspace-app-metadata.d.ts +1 -0
- package/dist/actions/update-workspace-app-metadata.js +26 -5
- package/dist/actions/update-workspace-app-metadata.js.map +1 -1
- package/dist/components/community-apps-section.d.ts +2 -0
- package/dist/components/community-apps-section.d.ts.map +1 -0
- package/dist/components/community-apps-section.js +90 -0
- package/dist/components/community-apps-section.js.map +1 -0
- package/dist/components/workspace-app-card.d.ts.map +1 -1
- package/dist/components/workspace-app-card.js +63 -9
- package/dist/components/workspace-app-card.js.map +1 -1
- package/dist/lib/connect-apps.d.ts +1 -2
- package/dist/lib/connect-apps.d.ts.map +1 -1
- package/dist/lib/connect-apps.js +41 -65
- package/dist/lib/connect-apps.js.map +1 -1
- package/dist/lib/workspace-apps.d.ts +1 -0
- package/dist/lib/workspace-apps.d.ts.map +1 -1
- package/dist/lib/workspace-apps.js.map +1 -1
- package/dist/routes/pages/apps.d.ts.map +1 -1
- package/dist/routes/pages/apps.js +2 -1
- package/dist/routes/pages/apps.js.map +1 -1
- package/dist/routes/pages/connect.d.ts.map +1 -1
- package/dist/routes/pages/connect.js +5 -7
- package/dist/routes/pages/connect.js.map +1 -1
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/app-creation-store.d.ts +11 -1
- package/dist/server/lib/app-creation-store.d.ts.map +1 -1
- package/dist/server/lib/app-creation-store.js +258 -39
- package/dist/server/lib/app-creation-store.js.map +1 -1
- package/dist/server/lib/community-apps.d.ts +45 -0
- package/dist/server/lib/community-apps.d.ts.map +1 -0
- package/dist/server/lib/community-apps.js +267 -0
- package/dist/server/lib/community-apps.js.map +1 -0
- package/dist/server/lib/community-source.d.ts +19 -0
- package/dist/server/lib/community-source.d.ts.map +1 -0
- package/dist/server/lib/community-source.js +118 -0
- package/dist/server/lib/community-source.js.map +1 -0
- package/dist/server/lib/connect-apps.d.ts +4 -0
- package/dist/server/lib/connect-apps.d.ts.map +1 -0
- package/dist/server/lib/connect-apps.js +99 -0
- package/dist/server/lib/connect-apps.js.map +1 -0
- package/dist/server/lib/org-apps-directory-cache.d.ts +20 -0
- package/dist/server/lib/org-apps-directory-cache.d.ts.map +1 -0
- package/dist/server/lib/org-apps-directory-cache.js +44 -0
- package/dist/server/lib/org-apps-directory-cache.js.map +1 -0
- package/dist/server/plugins/integrations.js +3 -3
- package/dist/server/plugins/integrations.js.map +1 -1
- package/dist/shared/labs.d.ts +2 -0
- package/dist/shared/labs.d.ts.map +1 -0
- package/dist/shared/labs.js +8 -0
- package/dist/shared/labs.js.map +1 -0
- package/package.json +5 -4
- package/src/actions/connect-external-agent.spec.ts +101 -3
- package/src/actions/connect-external-agent.ts +12 -11
- package/src/actions/index.spec.ts +13 -0
- package/src/actions/index.ts +8 -0
- package/src/actions/inspect-connect-agent-card.ts +17 -0
- package/src/actions/install-curated-community-app.ts +32 -0
- package/src/actions/list-connect-marketplace-apps.ts +17 -0
- package/src/actions/list-curated-community-apps.ts +12 -0
- package/src/actions/update-workspace-app-metadata.spec.ts +25 -0
- package/src/actions/update-workspace-app-metadata.ts +48 -24
- package/src/components/community-apps-section.tsx +224 -0
- package/src/components/workspace-app-card.spec.tsx +226 -1
- package/src/components/workspace-app-card.tsx +115 -12
- package/src/lib/connect-apps.spec.ts +118 -66
- package/src/lib/connect-apps.ts +47 -82
- package/src/lib/workspace-apps.ts +1 -0
- package/src/routes/pages/apps.spec.tsx +201 -1
- package/src/routes/pages/apps.tsx +3 -0
- package/src/routes/pages/connect.spec.tsx +53 -6
- package/src/routes/pages/connect.tsx +14 -11
- package/src/server/index.ts +9 -0
- package/src/server/lib/app-creation-store.spec.ts +539 -11
- package/src/server/lib/app-creation-store.ts +332 -41
- package/src/server/lib/community-apps.spec.ts +367 -0
- package/src/server/lib/community-apps.ts +372 -0
- package/src/server/lib/community-source.spec.ts +151 -0
- package/src/server/lib/community-source.ts +186 -0
- package/src/server/lib/connect-apps.ts +149 -0
- package/src/server/lib/org-apps-directory-cache.spec.ts +71 -0
- package/src/server/lib/org-apps-directory-cache.ts +66 -0
- package/src/server/plugins/integrations.spec.ts +60 -0
- package/src/server/plugins/integrations.ts +3 -3
- package/src/shared/labs.ts +9 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core/action";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { listCuratedCommunityApps } from "../server/lib/community-apps.js";
|
|
4
|
+
export default defineAction({
|
|
5
|
+
description: "List reviewed, pinned community app templates that can be installed in the associated workspace. This catalog is separate from deployed agents in Connect.",
|
|
6
|
+
schema: z.object({}),
|
|
7
|
+
http: { method: "GET" },
|
|
8
|
+
run: async () => listCuratedCommunityApps(),
|
|
9
|
+
});
|
|
10
|
+
//# sourceMappingURL=list-curated-community-apps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-curated-community-apps.js","sourceRoot":"","sources":["../../src/actions/list-curated-community-apps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAE3E,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,4JAA4J;IAC9J,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;IACpB,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;IACvB,GAAG,EAAE,KAAK,IAAI,EAAE,CAAC,wBAAwB,EAAE;CAC5C,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core/action\";\nimport { z } from \"zod\";\n\nimport { listCuratedCommunityApps } from \"../server/lib/community-apps.js\";\n\nexport default defineAction({\n description:\n \"List reviewed, pinned community app templates that can be installed in the associated workspace. This catalog is separate from deployed agents in Connect.\",\n schema: z.object({}),\n http: { method: \"GET\" },\n run: async () => listCuratedCommunityApps(),\n});\n"]}
|
|
@@ -47,10 +47,7 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
47
47
|
notes?: string | undefined;
|
|
48
48
|
scope?: "org" | "user" | undefined;
|
|
49
49
|
}, {
|
|
50
|
-
message?: undefined;
|
|
51
50
|
provider?: undefined;
|
|
52
|
-
id?: undefined;
|
|
53
|
-
deleted?: undefined;
|
|
54
51
|
providers: {
|
|
55
52
|
id: string;
|
|
56
53
|
label: string;
|
|
@@ -62,44 +59,47 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
62
59
|
}[];
|
|
63
60
|
count: number;
|
|
64
61
|
found?: undefined;
|
|
62
|
+
deleted?: undefined;
|
|
65
63
|
registered?: undefined;
|
|
64
|
+
id?: undefined;
|
|
66
65
|
label?: undefined;
|
|
67
|
-
} | {
|
|
68
66
|
message?: undefined;
|
|
69
|
-
|
|
70
|
-
count?: undefined;
|
|
71
|
-
deleted?: undefined;
|
|
67
|
+
} | {
|
|
72
68
|
providers?: undefined;
|
|
69
|
+
count?: undefined;
|
|
73
70
|
found: boolean;
|
|
74
71
|
provider: import("node_modules/@agent-native/core/dist/provider-api").CustomProviderConfig;
|
|
72
|
+
deleted?: undefined;
|
|
75
73
|
registered?: undefined;
|
|
74
|
+
id?: undefined;
|
|
76
75
|
label?: undefined;
|
|
77
|
-
} | {
|
|
78
76
|
message?: undefined;
|
|
77
|
+
} | {
|
|
79
78
|
provider?: undefined;
|
|
80
|
-
count?: undefined;
|
|
81
|
-
deleted?: undefined;
|
|
82
79
|
providers?: undefined;
|
|
80
|
+
count?: undefined;
|
|
83
81
|
found: boolean;
|
|
84
82
|
id: string;
|
|
83
|
+
deleted?: undefined;
|
|
85
84
|
registered?: undefined;
|
|
86
85
|
label?: undefined;
|
|
87
|
-
} | {
|
|
88
86
|
message?: undefined;
|
|
87
|
+
} | {
|
|
89
88
|
provider?: undefined;
|
|
90
|
-
count?: undefined;
|
|
91
89
|
providers?: undefined;
|
|
90
|
+
count?: undefined;
|
|
92
91
|
found?: undefined;
|
|
93
92
|
deleted: boolean;
|
|
94
93
|
id: string;
|
|
95
94
|
registered?: undefined;
|
|
96
95
|
label?: undefined;
|
|
96
|
+
message?: undefined;
|
|
97
97
|
} | {
|
|
98
98
|
provider?: undefined;
|
|
99
|
-
count?: undefined;
|
|
100
|
-
deleted?: undefined;
|
|
101
99
|
providers?: undefined;
|
|
100
|
+
count?: undefined;
|
|
102
101
|
found?: undefined;
|
|
102
|
+
deleted?: undefined;
|
|
103
103
|
registered: boolean;
|
|
104
104
|
id: string;
|
|
105
105
|
label: string;
|
|
@@ -50,6 +50,12 @@ declare const _default: import("@agent-native/core/action").ActionDefinition<{
|
|
|
50
50
|
appId: string;
|
|
51
51
|
prompt: string;
|
|
52
52
|
message: string;
|
|
53
|
+
attachments?: Array<{
|
|
54
|
+
type: "file";
|
|
55
|
+
name: string;
|
|
56
|
+
contentType: string;
|
|
57
|
+
text: string;
|
|
58
|
+
}>;
|
|
53
59
|
sourceTemplate: import("../server/lib/curated-workspace-templates.js").CuratedWorkspaceTemplate;
|
|
54
60
|
}>;
|
|
55
61
|
export default _default;
|
|
@@ -2,6 +2,7 @@ declare const _default: import("@agent-native/core/action").ActionDefinition<{
|
|
|
2
2
|
appId: string;
|
|
3
3
|
name?: string | null | undefined;
|
|
4
4
|
description?: string | null | undefined;
|
|
5
|
+
whenToUse?: string[] | null | undefined;
|
|
5
6
|
}, import("../server/lib/app-creation-store.js").WorkspaceAppSummary>;
|
|
6
7
|
export default _default;
|
|
7
8
|
//# sourceMappingURL=update-workspace-app-metadata.d.ts.map
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core/action";
|
|
2
|
-
import { getWorkspaceAppIdValidationError } from "@agent-native/core/shared";
|
|
2
|
+
import { getWorkspaceAppIdValidationError, parseAgentProfileMetadata, } from "@agent-native/core/shared";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { updateWorkspaceAppMetadata } from "../server/lib/app-creation-store.js";
|
|
5
5
|
export default defineAction({
|
|
6
|
-
description: "Update
|
|
7
|
-
schema: z
|
|
6
|
+
description: "Update a workspace app's display name, description, and when-to-use profile. Only organization owners and admins can edit these shared details.",
|
|
7
|
+
schema: z
|
|
8
|
+
.object({
|
|
8
9
|
appId: z
|
|
9
10
|
.string()
|
|
10
11
|
.max(64)
|
|
@@ -20,10 +21,30 @@ export default defineAction({
|
|
|
20
21
|
.describe("Human-readable app name"),
|
|
21
22
|
description: z
|
|
22
23
|
.string()
|
|
23
|
-
.max(
|
|
24
|
+
.max(1000)
|
|
24
25
|
.optional()
|
|
25
26
|
.nullable()
|
|
26
|
-
.describe("Human-readable app description"),
|
|
27
|
+
.describe("Human-readable app description, up to 1,000 characters"),
|
|
28
|
+
whenToUse: z
|
|
29
|
+
.array(z.string())
|
|
30
|
+
.max(6)
|
|
31
|
+
.optional()
|
|
32
|
+
.nullable()
|
|
33
|
+
.describe("Example requests that indicate when this app is useful"),
|
|
34
|
+
})
|
|
35
|
+
.superRefine(({ description, whenToUse }, context) => {
|
|
36
|
+
if (description == null && whenToUse == null)
|
|
37
|
+
return;
|
|
38
|
+
const profile = parseAgentProfileMetadata({
|
|
39
|
+
...(description != null ? { description } : {}),
|
|
40
|
+
...(whenToUse != null ? { whenToUse } : {}),
|
|
41
|
+
});
|
|
42
|
+
if (!profile) {
|
|
43
|
+
context.addIssue({
|
|
44
|
+
code: "custom",
|
|
45
|
+
message: "Use a description up to 1,000 characters and up to 6 non-empty examples, each no longer than 140 characters.",
|
|
46
|
+
});
|
|
47
|
+
}
|
|
27
48
|
}),
|
|
28
49
|
run: async (args) => updateWorkspaceAppMetadata(args),
|
|
29
50
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-workspace-app-metadata.js","sourceRoot":"","sources":["../../src/actions/update-workspace-app-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,
|
|
1
|
+
{"version":3,"file":"update-workspace-app-metadata.js","sourceRoot":"","sources":["../../src/actions/update-workspace-app-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EACL,gCAAgC,EAChC,yBAAyB,GAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AAEjF,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,iJAAiJ;IACnJ,MAAM,EAAE,CAAC;SACN,MAAM,CAAC;QACN,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,GAAG,CAAC,EAAE,CAAC;aACP,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,gCAAgC,CAAC,KAAK,CAAC,EAAE;YAC3D,OAAO,EACL,yEAAyE;SAC5E,CAAC;aACD,QAAQ,CAAC,iDAAiD,CAAC;QAC9D,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,GAAG,CAAC,GAAG,CAAC;aACR,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CAAC,yBAAyB,CAAC;QACtC,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,GAAG,CAAC,IAAI,CAAC;aACT,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CAAC,wDAAwD,CAAC;QACrE,SAAS,EAAE,CAAC;aACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CAAC,wDAAwD,CAAC;KACtE,CAAC;SACD,WAAW,CAAC,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE;QACnD,IAAI,WAAW,IAAI,IAAI,IAAI,SAAS,IAAI,IAAI;YAAE,OAAO;QACrD,MAAM,OAAO,GAAG,yBAAyB,CAAC;YACxC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5C,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,QAAQ,CAAC;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EACL,8GAA8G;aACjH,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;IACJ,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC;CACtD,CAAC,CAAC","sourcesContent":["import { defineAction } from \"@agent-native/core/action\";\nimport {\n getWorkspaceAppIdValidationError,\n parseAgentProfileMetadata,\n} from \"@agent-native/core/shared\";\nimport { z } from \"zod\";\n\nimport { updateWorkspaceAppMetadata } from \"../server/lib/app-creation-store.js\";\n\nexport default defineAction({\n description:\n \"Update a workspace app's display name, description, and when-to-use profile. Only organization owners and admins can edit these shared details.\",\n schema: z\n .object({\n appId: z\n .string()\n .max(64)\n .refine((appId) => !getWorkspaceAppIdValidationError(appId), {\n message:\n \"Use a non-reserved app id with lowercase letters, numbers, and hyphens.\",\n })\n .describe(\"Workspace app id, matching the apps/<id> folder\"),\n name: z\n .string()\n .max(120)\n .optional()\n .nullable()\n .describe(\"Human-readable app name\"),\n description: z\n .string()\n .max(1000)\n .optional()\n .nullable()\n .describe(\"Human-readable app description, up to 1,000 characters\"),\n whenToUse: z\n .array(z.string())\n .max(6)\n .optional()\n .nullable()\n .describe(\"Example requests that indicate when this app is useful\"),\n })\n .superRefine(({ description, whenToUse }, context) => {\n if (description == null && whenToUse == null) return;\n const profile = parseAgentProfileMetadata({\n ...(description != null ? { description } : {}),\n ...(whenToUse != null ? { whenToUse } : {}),\n });\n if (!profile) {\n context.addIssue({\n code: \"custom\",\n message:\n \"Use a description up to 1,000 characters and up to 6 non-empty examples, each no longer than 140 characters.\",\n });\n }\n }),\n run: async (args) => updateWorkspaceAppMetadata(args),\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"community-apps-section.d.ts","sourceRoot":"","sources":["../../src/components/community-apps-section.tsx"],"names":[],"mappings":"AAsDA,wBAAgB,oBAAoB,oEAyKnC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { sendToAgentChat } from "@agent-native/core/client/agent-chat";
|
|
3
|
+
import { useActionMutation, useActionQuery, } from "@agent-native/core/client/hooks";
|
|
4
|
+
import { useT } from "@agent-native/core/client/i18n";
|
|
5
|
+
import { useLab } from "@agent-native/core/client/labs";
|
|
6
|
+
import { IconArrowUpRight, IconCircleCheck, IconPlus, } from "@tabler/icons-react";
|
|
7
|
+
import { useState } from "react";
|
|
8
|
+
import { toast } from "sonner";
|
|
9
|
+
import { COMMUNITY_APPS_LAB } from "../shared/labs.js";
|
|
10
|
+
import { ActionQueryError } from "./action-query-error.js";
|
|
11
|
+
import { AppIcon } from "./app-icon.js";
|
|
12
|
+
import { AppList, AppListRow } from "./app-list-row.js";
|
|
13
|
+
import { Badge } from "./ui/badge.js";
|
|
14
|
+
import { Button } from "./ui/button.js";
|
|
15
|
+
import { Skeleton } from "./ui/skeleton.js";
|
|
16
|
+
import { Spinner } from "./ui/spinner.js";
|
|
17
|
+
function pinnedSourceUrl(source) {
|
|
18
|
+
return ("https://github.com/" +
|
|
19
|
+
source.repo +
|
|
20
|
+
"/tree/" +
|
|
21
|
+
source.ref +
|
|
22
|
+
"/" +
|
|
23
|
+
source.templatePath);
|
|
24
|
+
}
|
|
25
|
+
export function CommunityAppsSection() {
|
|
26
|
+
const t = useT();
|
|
27
|
+
const enabled = useLab(COMMUNITY_APPS_LAB);
|
|
28
|
+
const [installingId, setInstallingId] = useState(null);
|
|
29
|
+
const catalogQuery = useActionQuery("list-curated-community-apps", {}, { enabled });
|
|
30
|
+
const workspaceAppsQuery = useActionQuery("list-workspace-apps", {
|
|
31
|
+
includeAgentCards: false,
|
|
32
|
+
includeArchived: true,
|
|
33
|
+
});
|
|
34
|
+
const install = useActionMutation("install-curated-community-app", {
|
|
35
|
+
onSuccess: (result) => {
|
|
36
|
+
const mode = result?.mode;
|
|
37
|
+
const message = result?.message;
|
|
38
|
+
if (mode === "builder") {
|
|
39
|
+
toast.success(t("dispatch.pages.communityAppsInstallStarted"));
|
|
40
|
+
}
|
|
41
|
+
else if (mode === "pending") {
|
|
42
|
+
toast.info(t("dispatch.pages.communityAppsPending"));
|
|
43
|
+
}
|
|
44
|
+
else if (mode === "already-installed") {
|
|
45
|
+
toast.success(t("dispatch.pages.communityAppsAlreadyInstalled"));
|
|
46
|
+
}
|
|
47
|
+
else if (mode === "builder-unavailable" || mode === "app-id-taken") {
|
|
48
|
+
toast.error(message || t("dispatch.pages.communityAppsInstallFailed"));
|
|
49
|
+
}
|
|
50
|
+
else if (mode === "local-agent") {
|
|
51
|
+
sendToAgentChat({
|
|
52
|
+
message: result?.prompt ||
|
|
53
|
+
t("dispatch.pages.communityAppsLocalRequestReady"),
|
|
54
|
+
attachments: result?.attachments,
|
|
55
|
+
submit: true,
|
|
56
|
+
type: "code",
|
|
57
|
+
newTab: true,
|
|
58
|
+
reuseEmptyTab: true,
|
|
59
|
+
});
|
|
60
|
+
toast.info(t("dispatch.pages.communityAppsLocalRequestReady"));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
toast.error(t("dispatch.pages.communityAppsInstallFailed"));
|
|
64
|
+
}
|
|
65
|
+
setInstallingId(null);
|
|
66
|
+
void catalogQuery.refetch();
|
|
67
|
+
void workspaceAppsQuery.refetch();
|
|
68
|
+
},
|
|
69
|
+
onError: () => {
|
|
70
|
+
setInstallingId(null);
|
|
71
|
+
toast.error(t("dispatch.pages.communityAppsInstallFailed"));
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
if (!enabled)
|
|
75
|
+
return null;
|
|
76
|
+
return (_jsxs("section", { className: "space-y-3 border-t pt-6", children: [_jsx("h2", { className: "text-sm font-semibold text-foreground", children: t("dispatch.pages.communityApps") }), catalogQuery.isError ? (_jsx(ActionQueryError, { error: catalogQuery.error, onRetry: () => void catalogQuery.refetch() })) : catalogQuery.isLoading ? (_jsx(AppList, { className: "divide-y rounded-xl border", children: _jsxs("div", { className: "flex items-center gap-3 px-4 py-3.5", children: [_jsx(Skeleton, { className: "size-8 rounded-lg" }), _jsx(Skeleton, { className: "h-4 w-40" })] }) })) : catalogQuery.data?.length ? (_jsx(AppList, { className: "divide-y rounded-xl border", children: catalogQuery.data.map((source) => (_jsxs(AppListRow, { className: "border-b-0", children: [_jsx(AppIcon, { id: source.id, name: source.name, size: "sm" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2", children: [_jsx("h3", { className: "truncate text-sm font-semibold text-foreground", children: source.name }), source.installed ? (_jsxs(Badge, { variant: "secondary", className: "gap-1", children: [_jsx(IconCircleCheck, { size: 13 }), t("dispatch.pages.communityAppsInstalled")] })) : source.pending ? (_jsx(Badge, { variant: "secondary", children: t("dispatch.pages.communityAppsPending") })) : null] }), source.description ? (_jsx("p", { className: "mt-0.5 truncate text-xs text-muted-foreground", children: source.description })) : null, _jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-x-2 text-xs text-muted-foreground", children: [_jsxs("span", { children: [t("dispatch.pages.communityAppsLicense"), ": ", source.license] }), _jsxs("a", { href: pinnedSourceUrl(source), target: "_blank", rel: "noreferrer", className: "inline-flex items-center gap-1 underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: [t("dispatch.pages.communityAppsTemplateSource"), _jsx(IconArrowUpRight, { size: 12, "aria-hidden": "true" })] })] })] }), source.installable ? (_jsxs(Button, { type: "button", size: "sm", variant: "outline", disabled: install.isPending, onClick: () => {
|
|
77
|
+
setInstallingId(source.id);
|
|
78
|
+
install.mutate({ sourceId: source.id });
|
|
79
|
+
}, children: [install.isPending && installingId === source.id ? (_jsx(Spinner, { className: "mr-1.5" })) : (_jsx(IconPlus, { size: 14, className: "mr-1.5" })), install.isPending && installingId === source.id
|
|
80
|
+
? t("dispatch.pages.communityAppsInstalling")
|
|
81
|
+
: t("dispatch.pages.communityAppsInstall")] })) : !source.installed &&
|
|
82
|
+
!source.pending &&
|
|
83
|
+
source.installUnavailableReason === "workspace-required" ? (_jsx("span", { className: "max-w-48 text-right text-xs text-muted-foreground", children: t("dispatch.pages.communityAppsWorkspaceRequired") })) : !source.installed &&
|
|
84
|
+
!source.pending &&
|
|
85
|
+
source.installUnavailableReason === "app-id-conflict" ? (_jsx("span", { className: "max-w-48 text-right text-xs text-muted-foreground", children: t("dispatch.pages.communityAppsIdConflict") })) : !source.installed &&
|
|
86
|
+
!source.pending &&
|
|
87
|
+
source.installUnavailableReason ===
|
|
88
|
+
"builder-install-unverified" ? (_jsx("span", { className: "max-w-48 text-right text-xs text-muted-foreground", children: t("dispatch.pages.communityAppsBuilderInstallUnavailable") })) : null] }, source.id))) })) : (_jsx("p", { className: "text-sm text-muted-foreground", children: t("dispatch.pages.communityAppsEmpty") }))] }));
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=community-apps-section.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"community-apps-section.js","sourceRoot":"","sources":["../../src/components/community-apps-section.tsx"],"names":[],"mappings":"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","sourcesContent":["import { sendToAgentChat } from \"@agent-native/core/client/agent-chat\";\nimport {\n useActionMutation,\n useActionQuery,\n} from \"@agent-native/core/client/hooks\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport { useLab } from \"@agent-native/core/client/labs\";\nimport {\n IconArrowUpRight,\n IconCircleCheck,\n IconPlus,\n} from \"@tabler/icons-react\";\nimport { useState } from \"react\";\nimport { toast } from \"sonner\";\n\nimport { COMMUNITY_APPS_LAB } from \"../shared/labs.js\";\nimport { ActionQueryError } from \"./action-query-error\";\nimport { AppIcon } from \"./app-icon\";\nimport { AppList, AppListRow } from \"./app-list-row\";\nimport { Badge } from \"./ui/badge\";\nimport { Button } from \"./ui/button\";\nimport { Skeleton } from \"./ui/skeleton\";\nimport { Spinner } from \"./ui/spinner\";\n\ninterface CommunityAppSource {\n id: string;\n name: string;\n description?: string;\n appId: string;\n repo: string;\n ref: string;\n license: string;\n provenance: string;\n templatePath: string;\n installed: boolean;\n pending: boolean;\n installable: boolean;\n installUnavailableReason?:\n | \"workspace-required\"\n | \"app-id-conflict\"\n | \"builder-install-unverified\";\n}\n\nfunction pinnedSourceUrl(source: CommunityAppSource): string {\n return (\n \"https://github.com/\" +\n source.repo +\n \"/tree/\" +\n source.ref +\n \"/\" +\n source.templatePath\n );\n}\n\nexport function CommunityAppsSection() {\n const t = useT();\n const enabled = useLab(COMMUNITY_APPS_LAB);\n const [installingId, setInstallingId] = useState<string | null>(null);\n const catalogQuery = useActionQuery<CommunityAppSource[]>(\n \"list-curated-community-apps\" as never,\n {},\n { enabled },\n );\n const workspaceAppsQuery = useActionQuery(\"list-workspace-apps\", {\n includeAgentCards: false,\n includeArchived: true,\n });\n const install = useActionMutation(\"install-curated-community-app\", {\n onSuccess: (result) => {\n const mode = (result as { mode?: string } | null)?.mode;\n const message = (result as { message?: string } | null)?.message;\n if (mode === \"builder\") {\n toast.success(t(\"dispatch.pages.communityAppsInstallStarted\"));\n } else if (mode === \"pending\") {\n toast.info(t(\"dispatch.pages.communityAppsPending\"));\n } else if (mode === \"already-installed\") {\n toast.success(t(\"dispatch.pages.communityAppsAlreadyInstalled\"));\n } else if (mode === \"builder-unavailable\" || mode === \"app-id-taken\") {\n toast.error(message || t(\"dispatch.pages.communityAppsInstallFailed\"));\n } else if (mode === \"local-agent\") {\n sendToAgentChat({\n message:\n (result as { prompt?: string } | null)?.prompt ||\n t(\"dispatch.pages.communityAppsLocalRequestReady\"),\n attachments: (\n result as {\n attachments?: Array<{\n type: \"file\";\n name: string;\n contentType: string;\n text: string;\n }>;\n } | null\n )?.attachments,\n submit: true,\n type: \"code\",\n newTab: true,\n reuseEmptyTab: true,\n });\n toast.info(t(\"dispatch.pages.communityAppsLocalRequestReady\"));\n } else {\n toast.error(t(\"dispatch.pages.communityAppsInstallFailed\"));\n }\n setInstallingId(null);\n void catalogQuery.refetch();\n void workspaceAppsQuery.refetch();\n },\n onError: () => {\n setInstallingId(null);\n toast.error(t(\"dispatch.pages.communityAppsInstallFailed\"));\n },\n });\n\n if (!enabled) return null;\n\n return (\n <section className=\"space-y-3 border-t pt-6\">\n <h2 className=\"text-sm font-semibold text-foreground\">\n {t(\"dispatch.pages.communityApps\")}\n </h2>\n {catalogQuery.isError ? (\n <ActionQueryError\n error={catalogQuery.error}\n onRetry={() => void catalogQuery.refetch()}\n />\n ) : catalogQuery.isLoading ? (\n <AppList className=\"divide-y rounded-xl border\">\n <div className=\"flex items-center gap-3 px-4 py-3.5\">\n <Skeleton className=\"size-8 rounded-lg\" />\n <Skeleton className=\"h-4 w-40\" />\n </div>\n </AppList>\n ) : catalogQuery.data?.length ? (\n <AppList className=\"divide-y rounded-xl border\">\n {catalogQuery.data.map((source) => (\n <AppListRow key={source.id} className=\"border-b-0\">\n <AppIcon id={source.id} name={source.name} size=\"sm\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex min-w-0 flex-wrap items-center gap-2\">\n <h3 className=\"truncate text-sm font-semibold text-foreground\">\n {source.name}\n </h3>\n {source.installed ? (\n <Badge variant=\"secondary\" className=\"gap-1\">\n <IconCircleCheck size={13} />\n {t(\"dispatch.pages.communityAppsInstalled\")}\n </Badge>\n ) : source.pending ? (\n <Badge variant=\"secondary\">\n {t(\"dispatch.pages.communityAppsPending\")}\n </Badge>\n ) : null}\n </div>\n {source.description ? (\n <p className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {source.description}\n </p>\n ) : null}\n <div className=\"mt-1 flex flex-wrap items-center gap-x-2 text-xs text-muted-foreground\">\n <span>\n {t(\"dispatch.pages.communityAppsLicense\")}: {source.license}\n </span>\n <a\n href={pinnedSourceUrl(source)}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex items-center gap-1 underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {t(\"dispatch.pages.communityAppsTemplateSource\")}\n <IconArrowUpRight size={12} aria-hidden=\"true\" />\n </a>\n </div>\n </div>\n {source.installable ? (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n disabled={install.isPending}\n onClick={() => {\n setInstallingId(source.id);\n install.mutate({ sourceId: source.id });\n }}\n >\n {install.isPending && installingId === source.id ? (\n <Spinner className=\"mr-1.5\" />\n ) : (\n <IconPlus size={14} className=\"mr-1.5\" />\n )}\n {install.isPending && installingId === source.id\n ? t(\"dispatch.pages.communityAppsInstalling\")\n : t(\"dispatch.pages.communityAppsInstall\")}\n </Button>\n ) : !source.installed &&\n !source.pending &&\n source.installUnavailableReason === \"workspace-required\" ? (\n <span className=\"max-w-48 text-right text-xs text-muted-foreground\">\n {t(\"dispatch.pages.communityAppsWorkspaceRequired\")}\n </span>\n ) : !source.installed &&\n !source.pending &&\n source.installUnavailableReason === \"app-id-conflict\" ? (\n <span className=\"max-w-48 text-right text-xs text-muted-foreground\">\n {t(\"dispatch.pages.communityAppsIdConflict\")}\n </span>\n ) : !source.installed &&\n !source.pending &&\n source.installUnavailableReason ===\n \"builder-install-unverified\" ? (\n <span className=\"max-w-48 text-right text-xs text-muted-foreground\">\n {t(\"dispatch.pages.communityAppsBuilderInstallUnavailable\")}\n </span>\n ) : null}\n </AppListRow>\n ))}\n </AppList>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t(\"dispatch.pages.communityAppsEmpty\")}\n </p>\n )}\n </section>\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-app-card.d.ts","sourceRoot":"","sources":["../../src/components/workspace-app-card.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"workspace-app-card.d.ts","sourceRoot":"","sources":["../../src/components/workspace-app-card.tsx"],"names":[],"mappings":"AA+BA,OAAO,EASL,KAAK,mBAAmB,EACzB,MAAM,uBAAuB,CAAC;AA4E/B,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,SAAS,EACT,QAAgB,EAChB,cAAc,GACf,EAAE;IACD,GAAG,EAAE,mBAAmB,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B,mDA6SA"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useActionMutation, useActionQuery, } from "@agent-native/core/client/hooks";
|
|
3
3
|
import { useT } from "@agent-native/core/client/i18n";
|
|
4
|
+
import { useOrgRole } from "@agent-native/core/client/org";
|
|
5
|
+
import { parseAgentProfileMetadata } from "@agent-native/core/shared";
|
|
4
6
|
import { APP_ACTION_MENU_CONTENT_CLASS } from "@agent-native/toolkit/app/chat/chat-first/app-open-actions";
|
|
5
7
|
import { ShareButton } from "@agent-native/toolkit/app/sharing";
|
|
6
8
|
import { IconChevronDown, IconChevronRight, IconClockHour4, IconEdit, IconEye, IconEyeOff, IconFileText, IconKey, IconPin, IconShare3, IconSettings, IconTrash, IconUser, IconUsersGroup, IconWorld, } from "@tabler/icons-react";
|
|
@@ -24,6 +26,20 @@ import { Textarea } from "./ui/textarea.js";
|
|
|
24
26
|
import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip.js";
|
|
25
27
|
import { AppResourceEffectiveStack } from "./workspace-resource-effective-stack.js";
|
|
26
28
|
const APP_CARD_ACTION_CLASS = "size-7 rounded-md p-0 text-muted-foreground transition-[background-color,color] hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-[state=open]:bg-accent data-[state=open]:text-foreground";
|
|
29
|
+
function normalizeProfileDescription(value) {
|
|
30
|
+
return value.replace(/[\r\n]+/g, " ").replace(/[\u0000-\u001f\u007f]/g, "");
|
|
31
|
+
}
|
|
32
|
+
function normalizeWhenToUseText(value) {
|
|
33
|
+
return value
|
|
34
|
+
.replace(/\r\n?/g, "\n")
|
|
35
|
+
.replace(/[\u0000-\u0009\u000b-\u001f\u007f]/g, "");
|
|
36
|
+
}
|
|
37
|
+
function parseWhenToUseText(value) {
|
|
38
|
+
return value
|
|
39
|
+
.split("\n")
|
|
40
|
+
.map((item) => item.trim())
|
|
41
|
+
.filter(Boolean);
|
|
42
|
+
}
|
|
27
43
|
function deferWorkspaceAppOverlayOpen(event, closeMenu, openOverlay) {
|
|
28
44
|
event.preventDefault();
|
|
29
45
|
closeMenu();
|
|
@@ -43,6 +59,11 @@ function consumeWorkspaceAppOverlayFocusRestore(pendingOverlayRef, event) {
|
|
|
43
59
|
}
|
|
44
60
|
export function WorkspaceAppCard({ app, className, isPinned = false, onTogglePinned, }) {
|
|
45
61
|
const t = useT();
|
|
62
|
+
const { org, role, isLoading: orgLoading, error: orgError } = useOrgRole();
|
|
63
|
+
const canEditMetadata = !orgLoading &&
|
|
64
|
+
!orgError &&
|
|
65
|
+
!!org?.orgId &&
|
|
66
|
+
(role === "owner" || role === "admin");
|
|
46
67
|
const href = workspaceAppHref(app);
|
|
47
68
|
const directHref = app.status !== "pending" &&
|
|
48
69
|
!isWorkspaceSsoApp(app) &&
|
|
@@ -60,13 +81,22 @@ export function WorkspaceAppCard({ app, className, isPinned = false, onTogglePin
|
|
|
60
81
|
const [keysOpen, setKeysOpen] = useState(false);
|
|
61
82
|
const [resourcesOpen, setResourcesOpen] = useState(false);
|
|
62
83
|
const [draftName, setDraftName] = useState(app.name);
|
|
63
|
-
const [draftDescription, setDraftDescription] = useState(app.description || "");
|
|
84
|
+
const [draftDescription, setDraftDescription] = useState(normalizeProfileDescription(app.description || ""));
|
|
85
|
+
const [draftWhenToUse, setDraftWhenToUse] = useState(app.whenToUse?.join("\n") ?? "");
|
|
86
|
+
const draftWhenToUseValues = parseWhenToUseText(draftWhenToUse);
|
|
87
|
+
const validProfile = Boolean(parseAgentProfileMetadata({
|
|
88
|
+
...(draftDescription.trim()
|
|
89
|
+
? { description: draftDescription.trim() }
|
|
90
|
+
: {}),
|
|
91
|
+
whenToUse: draftWhenToUseValues,
|
|
92
|
+
}));
|
|
64
93
|
useEffect(() => {
|
|
65
94
|
if (editOpen)
|
|
66
95
|
return;
|
|
67
96
|
setDraftName(app.name);
|
|
68
|
-
setDraftDescription(app.description || "");
|
|
69
|
-
|
|
97
|
+
setDraftDescription(normalizeProfileDescription(app.description || ""));
|
|
98
|
+
setDraftWhenToUse(app.whenToUse?.join("\n") ?? "");
|
|
99
|
+
}, [app.description, app.name, app.whenToUse, editOpen]);
|
|
70
100
|
const archive = useActionMutation("archive-workspace-app", {
|
|
71
101
|
onError: (err) => toast.error(`Could not hide ${app.name}: ${stringifyError(err)}`),
|
|
72
102
|
});
|
|
@@ -102,22 +132,46 @@ export function WorkspaceAppCard({ app, className, isPinned = false, onTogglePin
|
|
|
102
132
|
toast.error("App name is required.");
|
|
103
133
|
return;
|
|
104
134
|
}
|
|
135
|
+
const description = draftDescription.trim();
|
|
136
|
+
const currentDescription = normalizeProfileDescription(app.description || "").trim();
|
|
137
|
+
const currentWhenToUse = app.whenToUse ?? [];
|
|
138
|
+
const nameChanged = name !== app.name.trim();
|
|
139
|
+
const descriptionChanged = description !== currentDescription;
|
|
140
|
+
const whenToUseChanged = draftWhenToUseValues.length !== currentWhenToUse.length ||
|
|
141
|
+
draftWhenToUseValues.some((example, index) => example !== currentWhenToUse[index]);
|
|
142
|
+
if (!parseAgentProfileMetadata({
|
|
143
|
+
...(description ? { description } : {}),
|
|
144
|
+
whenToUse: draftWhenToUseValues,
|
|
145
|
+
})) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (!nameChanged && !descriptionChanged && !whenToUseChanged) {
|
|
149
|
+
setEditOpen(false);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
105
152
|
updateMetadata.mutate({
|
|
106
153
|
appId: app.id,
|
|
107
|
-
name,
|
|
108
|
-
description:
|
|
154
|
+
...(nameChanged ? { name } : {}),
|
|
155
|
+
...(descriptionChanged ? { description } : {}),
|
|
156
|
+
...(whenToUseChanged ? { whenToUse: draftWhenToUseValues } : {}),
|
|
109
157
|
});
|
|
110
158
|
};
|
|
111
159
|
const pinLabel = t(isPinned ? "dispatch.pages.unpinApp" : "dispatch.pages.pinApp", {
|
|
112
160
|
name: app.name,
|
|
113
161
|
defaultValue: isPinned ? "Unpin this app" : "Pin this app",
|
|
114
162
|
});
|
|
115
|
-
return (_jsxs(_Fragment, { children: [_jsxs(AppListRow, { className: cn(!href && "opacity-60", isArchived && "opacity-70", className), children: [_jsx(AppIcon, { id: app.id, name: app.name, size: "sm" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("h3", { className: "truncate text-sm font-semibold text-foreground", children: app.name }), app.description || isPending ? (_jsx("p", { className: "mt-0.5 truncate text-xs text-muted-foreground", children: app.description || pendingLabel })) : null, _jsxs("div", { className: "mt-1.5 flex min-w-0 flex-wrap items-center gap-2 text-[11px] text-muted-foreground", children: [isPending ? (_jsxs("span", { className: "inline-flex min-w-0 items-center gap-1 rounded-full bg-muted px-2 py-0.5", children: [_jsx(IconClockHour4, { size: 12 }), _jsx("span", { className: "truncate", children: pendingLabel })] })) : null, isArchived ? (_jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5", children: [_jsx(IconEyeOff, { size: 12 }), "Hidden"] })) : null, audience === "public" ? (_jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5", children: [_jsx(IconWorld, { size: 12 }), "Public"] })) : null] })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [_jsx(WorkspaceAppOpenActions, { app: app, href: directHref ?? href, openDirectly: Boolean(directHref && shouldOpenWorkspaceAppInTopWindow()), isPinned: isPinned, pinLabel: pinLabel, pendingOpenLabel: pendingOpenLabel, onTogglePinned: onTogglePinned }), _jsx(WorkspaceAppSettings, { app: app, isArchived: isArchived, isPending: isPending, onEdit: () => setEditOpen(true), onKeys: () => setKeysOpen(true), onResources: () => setResourcesOpen(true), onArchive: handleArchive, onUnarchive: handleUnarchive, onRemovePending: handleRemovePending, labels: {
|
|
163
|
+
return (_jsxs(_Fragment, { children: [_jsxs(AppListRow, { className: cn(!href && "opacity-60", isArchived && "opacity-70", className), children: [_jsx(AppIcon, { id: app.id, name: app.name, size: "sm" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("h3", { className: "truncate text-sm font-semibold text-foreground", children: app.name }), app.description || isPending ? (_jsx("p", { className: "mt-0.5 truncate text-xs text-muted-foreground", children: app.description || pendingLabel })) : null, _jsxs("div", { className: "mt-1.5 flex min-w-0 flex-wrap items-center gap-2 text-[11px] text-muted-foreground", children: [isPending ? (_jsxs("span", { className: "inline-flex min-w-0 items-center gap-1 rounded-full bg-muted px-2 py-0.5", children: [_jsx(IconClockHour4, { size: 12 }), _jsx("span", { className: "truncate", children: pendingLabel })] })) : null, isArchived ? (_jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5", children: [_jsx(IconEyeOff, { size: 12 }), "Hidden"] })) : null, audience === "public" ? (_jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5", children: [_jsx(IconWorld, { size: 12 }), "Public"] })) : null] })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [_jsx(WorkspaceAppOpenActions, { app: app, href: directHref ?? href, openDirectly: Boolean(directHref && shouldOpenWorkspaceAppInTopWindow()), isPinned: isPinned, pinLabel: pinLabel, pendingOpenLabel: pendingOpenLabel, onTogglePinned: onTogglePinned }), _jsx(WorkspaceAppSettings, { app: app, canEditMetadata: canEditMetadata, isArchived: isArchived, isPending: isPending, onEdit: () => setEditOpen(true), onKeys: () => setKeysOpen(true), onResources: () => setResourcesOpen(true), onArchive: handleArchive, onUnarchive: handleUnarchive, onRemovePending: handleRemovePending, labels: {
|
|
116
164
|
createdBy: t("agents.dashboardMetadataCreatedBy"),
|
|
117
165
|
owner: t("dispatch.pages.appMetadataOwner"),
|
|
118
166
|
teams: t("dispatch.pages.appMetadataTeams"),
|
|
119
167
|
share: t("share.share", { defaultValue: "Share" }),
|
|
120
|
-
} })] })] }), _jsx(Dialog, { open: editOpen, onOpenChange: setEditOpen, children: _jsxs(DialogContent, { children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "Edit app details" }) }), _jsxs("form", { className: "space-y-4", onSubmit: handleMetadataSubmit, children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: `app-name-${app.id}`, children: "Name" }), _jsx(Input, { id: `app-name-${app.id}`, value: draftName, maxLength: 120, onChange: (event) => setDraftName(event.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: `app-description-${app.id}`, children: "Description" }), _jsx(Textarea, { id: `app-description-${app.id}`, value: draftDescription, maxLength:
|
|
168
|
+
} })] })] }), _jsx(Dialog, { open: editOpen, onOpenChange: setEditOpen, children: _jsxs(DialogContent, { children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "Edit app details" }) }), _jsxs("form", { className: "space-y-4", onSubmit: handleMetadataSubmit, children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: `app-name-${app.id}`, children: "Name" }), _jsx(Input, { id: `app-name-${app.id}`, value: draftName, maxLength: 120, onChange: (event) => setDraftName(event.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: `app-description-${app.id}`, children: "Description" }), _jsx(Textarea, { id: `app-description-${app.id}`, value: draftDescription, maxLength: 1000, rows: 4, onChange: (event) => setDraftDescription(normalizeProfileDescription(event.target.value)) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: `app-when-to-use-${app.id}`, children: t("dispatch.pages.appProfileWhenToUse", {
|
|
169
|
+
defaultValue: "When to use",
|
|
170
|
+
}) }), _jsx(Textarea, { id: `app-when-to-use-${app.id}`, value: draftWhenToUse, "aria-invalid": !validProfile, rows: 3, placeholder: t("dispatch.pages.appProfileWhenToUsePlaceholder", {
|
|
171
|
+
defaultValue: "One example request per line",
|
|
172
|
+
}), onChange: (event) => setDraftWhenToUse(normalizeWhenToUseText(event.target.value)) }), _jsx("p", { className: "text-xs text-muted-foreground", children: t("dispatch.pages.appProfileWhenToUseHint", {
|
|
173
|
+
defaultValue: "Add up to 6 examples, with no more than 140 characters each.",
|
|
174
|
+
}) })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "outline", onClick: () => setEditOpen(false), children: "Cancel" }), _jsx(Button, { type: "submit", disabled: updateMetadata.isPending || !validProfile, children: updateMetadata.isPending ? "Saving..." : "Save" })] })] })] }) }), _jsx(Dialog, { open: keysOpen, onOpenChange: setKeysOpen, children: _jsxs(DialogContent, { className: "max-w-md", children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { children: ["Manage keys for ", app.name] }), _jsx(DialogDescription, { children: "Choose which workspace credentials this app can use." })] }), _jsx(AppKeysPanel, { appId: app.id, appName: app.name }), _jsx(DialogFooter, { children: _jsx(Button, { type: "button", onClick: () => setKeysOpen(false), children: "Done" }) })] }) }), _jsx(AppResourcesDialog, { app: app, open: resourcesOpen, onOpenChange: setResourcesOpen })] }));
|
|
121
175
|
}
|
|
122
176
|
function WorkspaceAppOpenActions({ app, href, openDirectly, isPinned, pinLabel, pendingOpenLabel, onTogglePinned, }) {
|
|
123
177
|
const navigate = useNavigate();
|
|
@@ -144,7 +198,7 @@ function WorkspaceAppOpenActions({ app, href, openDirectly, isPinned, pinLabel,
|
|
|
144
198
|
]
|
|
145
199
|
: undefined }));
|
|
146
200
|
}
|
|
147
|
-
function WorkspaceAppSettings({ app, isArchived, isPending, onEdit, onKeys, onResources, onArchive, onUnarchive, onRemovePending, labels, }) {
|
|
201
|
+
function WorkspaceAppSettings({ app, canEditMetadata, isArchived, isPending, onEdit, onKeys, onResources, onArchive, onUnarchive, onRemovePending, labels, }) {
|
|
148
202
|
const [shareOpen, setShareOpen] = useState(false);
|
|
149
203
|
const [settingsOpen, setSettingsOpen] = useState(false);
|
|
150
204
|
const settingsTriggerRef = useRef(null);
|
|
@@ -162,7 +216,7 @@ function WorkspaceAppSettings({ app, isArchived, isPending, onEdit, onKeys, onRe
|
|
|
162
216
|
setTimeout(restoreSettingsFocus, 0);
|
|
163
217
|
}
|
|
164
218
|
};
|
|
165
|
-
return (_jsxs(_Fragment, { children: [_jsxs(DropdownMenu, { open: settingsOpen, onOpenChange: setSettingsOpen, children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { type: "button", variant: "ghost", size: "sm", ref: settingsTriggerRef, "aria-label": `Settings for ${app.name}`, className: APP_CARD_ACTION_CLASS, children: _jsx(IconSettings, { size: 15 }) }) }) }), _jsx(TooltipContent, { children: "App settings" })] }), _jsxs(DropdownMenuContent, { align: "end", className: cn(APP_ACTION_MENU_CONTENT_CLASS, "min-w-max"), onCloseAutoFocus: (event) => consumeWorkspaceAppOverlayFocusRestore(pendingShareOverlayRef, event), children: [_jsxs(DropdownMenuItem, { onSelect: onEdit, children: [_jsx(IconEdit, { size: 14, "aria-hidden": "true" }), "Edit details"] }), !isPending ? (_jsxs(DropdownMenuItem, { onSelect: (event) => deferWorkspaceAppOverlayOpen(event, () => {
|
|
219
|
+
return (_jsxs(_Fragment, { children: [_jsxs(DropdownMenu, { open: settingsOpen, onOpenChange: setSettingsOpen, children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { type: "button", variant: "ghost", size: "sm", ref: settingsTriggerRef, "aria-label": `Settings for ${app.name}`, className: APP_CARD_ACTION_CLASS, children: _jsx(IconSettings, { size: 15 }) }) }) }), _jsx(TooltipContent, { children: "App settings" })] }), _jsxs(DropdownMenuContent, { align: "end", className: cn(APP_ACTION_MENU_CONTENT_CLASS, "min-w-max"), onCloseAutoFocus: (event) => consumeWorkspaceAppOverlayFocusRestore(pendingShareOverlayRef, event), children: [canEditMetadata ? (_jsxs(DropdownMenuItem, { onSelect: onEdit, children: [_jsx(IconEdit, { size: 14, "aria-hidden": "true" }), "Edit details"] })) : null, !isPending ? (_jsxs(DropdownMenuItem, { onSelect: (event) => deferWorkspaceAppOverlayOpen(event, () => {
|
|
166
220
|
pendingShareOverlayRef.current = true;
|
|
167
221
|
setSettingsOpen(false);
|
|
168
222
|
}, () => setShareOpen(true)), children: [_jsx(IconShare3, { size: 14, "aria-hidden": "true" }), labels.share] })) : null, !isPending && !isArchived ? (_jsxs(_Fragment, { children: [_jsxs(DropdownMenuItem, { onSelect: onKeys, children: [_jsx(IconKey, { size: 14, "aria-hidden": "true" }), "Manage keys"] }), _jsxs(DropdownMenuItem, { onSelect: onResources, children: [_jsx(IconFileText, { size: 14, "aria-hidden": "true" }), "Agent resources"] })] })) : null, isPending ? (_jsxs(DropdownMenuItem, { onSelect: onRemovePending, className: "text-destructive focus:text-destructive", children: [_jsx(IconTrash, { size: 14, "aria-hidden": "true" }), "Remove from list"] })) : isArchived ? (_jsxs(DropdownMenuItem, { onSelect: onUnarchive, children: [_jsx(IconEye, { size: 14, "aria-hidden": "true" }), "Restore to list"] })) : (_jsxs(DropdownMenuItem, { onSelect: onArchive, children: [_jsx(IconEyeOff, { size: 14, "aria-hidden": "true" }), "Hide from list"] })), _jsx(WorkspaceAppMetadata, { app: app, labels: labels })] })] }), !isPending && shareOpen ? (_jsx(ShareButton, { resourceType: "workspace-app", resourceId: app.id, resourceTitle: app.name, defaultOpen: true, onOpenChange: handleShareOpenChange, triggerClassName: "sr-only" })) : null] }));
|