profclaw 0.0.1-beta.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -38
- package/CONTRIBUTING.md +3 -5
- package/README.md +128 -63
- package/dist/chat/execution/tools/index.d.ts +1 -1
- package/dist/chat/execution/tools/index.js +41 -2
- package/dist/chat/providers/slack/index.d.ts +2 -2
- package/dist/cli/commands/models.js +39 -26
- package/dist/cli/commands/onboard.js +64 -79
- package/dist/cli/commands/setup.js +293 -90
- package/dist/cli/index.js +0 -6
- package/dist/cli/providers.d.ts +15 -0
- package/dist/cli/providers.js +41 -0
- package/dist/core/deployment.js +2 -0
- package/dist/providers/ai-sdk.js +26 -6
- package/dist/routes/channels.d.ts +12 -0
- package/dist/routes/channels.js +166 -0
- package/dist/server/route-loader.js +1 -0
- package/dist/server.js +115 -109
- package/package.json +1 -1
- package/skills/git-workflow/SKILL.md +3 -3
- package/ui/dist/assets/{ActivityView-DIPQSJ_d.js → ActivityView-BeshZXmE.js} +1 -1
- package/ui/dist/assets/{AgentList-CqyaYrcq.js → AgentList-QVHeldPi.js} +1 -1
- package/ui/dist/assets/{AnalyticsDashboard-C-mjuGHT.js → AnalyticsDashboard-C9R97dXE.js} +1 -1
- package/ui/dist/assets/{AreaChart-CfYWmbtr.js → AreaChart-B73gaiVQ.js} +1 -1
- package/ui/dist/assets/{CartesianChart-BaQ3It0c.js → CartesianChart-CXYL2R-A.js} +1 -1
- package/ui/dist/assets/{ChatView-DxxQy6pl.js → ChatView-qjZErlrp.js} +1 -1
- package/ui/dist/assets/{CostsDashboard-CDBBcGkg.js → CostsDashboard-O4DCLy1i.js} +1 -1
- package/ui/dist/assets/{EstimateSelect-CDjf5qKl.js → EstimateSelect-1hQf4Osk.js} +1 -1
- package/ui/dist/assets/{FloatingChatbot-CZHjvJIe.js → FloatingChatbot-BZBzrJxd.js} +1 -1
- package/ui/dist/assets/{InviteCodeManagement-DTm-IPTm.js → InviteCodeManagement-LEoGqYeA.js} +1 -1
- package/ui/dist/assets/{ProjectDetail-DlYUcOss.js → ProjectDetail--gPfvATB.js} +1 -1
- package/ui/dist/assets/{ProjectIcon-BMRpnM04.js → ProjectIcon-Chd_ofsw.js} +1 -1
- package/ui/dist/assets/{ProjectList-D85TN0i0.js → ProjectList-BvUfVB6c.js} +1 -1
- package/ui/dist/assets/{Settings-CgPqzUvj.js → Settings-1kaf7VHE.js} +1 -1
- package/ui/dist/assets/{StatusIndicator-yig0uZEA.js → StatusIndicator-pRfkNcdV.js} +1 -1
- package/ui/dist/assets/{SummaryDetail-CwLAfHgJ.js → SummaryDetail-DV3AmONk.js} +1 -1
- package/ui/dist/assets/{SummaryList-BvS5Idnu.js → SummaryList-B6kXiTxL.js} +1 -1
- package/ui/dist/assets/{TaskDetail-zarC1fOt.js → TaskDetail-CV6CzbOS.js} +1 -1
- package/ui/dist/assets/{TaskList-CyJq3ANE.js → TaskList-DL7brQKd.js} +1 -1
- package/ui/dist/assets/{TicketBoard-BlWr3-iH.js → TicketBoard-CrkkFj7C.js} +1 -1
- package/ui/dist/assets/{TicketDetail-DmqWKj2W.js → TicketDetail-hnnYclpD.js} +1 -1
- package/ui/dist/assets/{TicketList-Scj4pMWa.js → TicketList-CsDAyQCL.js} +1 -1
- package/ui/dist/assets/{UserManagement-BH7uG7dw.js → UserManagement-BGFQyTSr.js} +1 -1
- package/ui/dist/assets/{ViewSwitcher-3HzZUdWn.js → ViewSwitcher-CnL0OqA8.js} +1 -1
- package/ui/dist/assets/{alert-dialog-DWPb2IfQ.js → alert-dialog-SKM6Gjz4.js} +1 -1
- package/ui/dist/assets/{archive-CGck7gxR.js → archive-BsLa7brF.js} +1 -1
- package/ui/dist/assets/{badge-DEmc3Z_l.js → badge-CVHH1a-v.js} +1 -1
- package/ui/dist/assets/{brain-CfFdLVqb.js → brain-6o_RHVpe.js} +1 -1
- package/ui/dist/assets/{bug-DqSGPUUE.js → bug-CmZI7jqM.js} +1 -1
- package/ui/dist/assets/{calendar-BuZ4zbPW.js → calendar-Bf0t2B82.js} +1 -1
- package/ui/dist/assets/{chevron-up-DcJ4LL_N.js → chevron-up-CoUsOvZj.js} +1 -1
- package/ui/dist/assets/{circle-x-C78PNZjF.js → circle-x-Dgw11LgT.js} +1 -1
- package/ui/dist/assets/{constants-DhDjZe4P.js → constants-Q5Zivl-a.js} +1 -1
- package/ui/dist/assets/{cpu-Ck6AoG8c.js → cpu-DiPMQICV.js} +1 -1
- package/ui/dist/assets/{database-CA2w8Lvt.js → database-BwTfupDi.js} +1 -1
- package/ui/dist/assets/{dialog-BOdGWhgE.js → dialog-BUqN9Psj.js} +1 -1
- package/ui/dist/assets/{ellipsis-FhHKRbfl.js → ellipsis-UJx4Xnf6.js} +1 -1
- package/ui/dist/assets/{ellipsis-vertical-CO0UqE4-.js → ellipsis-vertical-DoULYEKn.js} +1 -1
- package/ui/dist/assets/{file-code-ChnhYYj1.js → file-code-B2UrJLwi.js} +1 -1
- package/ui/dist/assets/{folder-open-CHwA1-ve.js → folder-open-BJi577JH.js} +1 -1
- package/ui/dist/assets/{funnel-ByEjRFNB.js → funnel-PkaD_HSR.js} +1 -1
- package/ui/dist/assets/{git-branch-GTOPQgU4.js → git-branch-C_K30am0.js} +1 -1
- package/ui/dist/assets/{git-commit-horizontal-F5M84Kut.js → git-commit-horizontal-IT6ecxWQ.js} +1 -1
- package/ui/dist/assets/{globe-CQWfr7hT.js → globe-f-jjCa_g.js} +1 -1
- package/ui/dist/assets/{hash-nKC9gtLg.js → hash-DNEv8Elo.js} +1 -1
- package/ui/dist/assets/{history-DfFSA9xJ.js → history-BQSBo_1Q.js} +1 -1
- package/ui/dist/assets/{index-DHGvP9mp.js → index-BUmnwPQr.js} +1 -1
- package/ui/dist/assets/{index-Z4-RtZcs.js → index-BfF5G4Cw.js} +1 -1
- package/ui/dist/assets/{index-DeI8lKRR.js → index-C8N375c2.js} +1 -1
- package/ui/dist/assets/index-CuxnqVVz.css +1 -0
- package/ui/dist/assets/{index-Ca3vk7Gq.js → index-CzMM3QOk.js} +1 -1
- package/ui/dist/assets/{index--JkIxVXb.js → index-lJlNPFVJ.js} +3 -3
- package/ui/dist/assets/{index-a4Fxq0Hb.js → index-nS3EErDg.js} +1 -1
- package/ui/dist/assets/{layers-DFeLExSa.js → layers-jFqVrWMD.js} +1 -1
- package/ui/dist/assets/{layout-dashboard-WmgjMhWF.js → layout-dashboard-CcKt1hXw.js} +1 -1
- package/ui/dist/assets/{lightbulb-Bo8hEr7B.js → lightbulb-Jhp7FvbU.js} +1 -1
- package/ui/dist/assets/{link-2-YqrpQXBH.js → link-2-DdO7ostF.js} +1 -1
- package/ui/dist/assets/{markdown-renderer-Croje6Xe.js → markdown-renderer-n1ToC4XQ.js} +1 -1
- package/ui/dist/assets/{message-square-CD0H5hot.js → message-square-CBgH65X7.js} +1 -1
- package/ui/dist/assets/{pencil-DpFnj5dn.js → pencil-CYXCEPQh.js} +1 -1
- package/ui/dist/assets/{play-DVgea_jT.js → play-d1ONaH0-.js} +1 -1
- package/ui/dist/assets/{popover-JXecfWG5.js → popover-CrmZgoWu.js} +1 -1
- package/ui/dist/assets/{progress-C1ghf1Fu.js → progress-uv4SPkL5.js} +1 -1
- package/ui/dist/assets/{rocket-BFxPYGx9.js → rocket-DhvUetsk.js} +1 -1
- package/ui/dist/assets/{select-MADP8m6Q.js → select-CeQ8AHGy.js} +1 -1
- package/ui/dist/assets/{send-eYnW_7n-.js → send-P0r5D7td.js} +1 -1
- package/ui/dist/assets/{server-CPMaysH8.js → server-CVHTZB72.js} +1 -1
- package/ui/dist/assets/{settings-2-scXUOuE_.js → settings-2-ocj5uHGx.js} +1 -1
- package/ui/dist/assets/{sheet-r6NSOxi-.js → sheet-DuQExSho.js} +1 -1
- package/ui/dist/assets/{shield-check-PEr7nmVw.js → shield-check-DfVdE34l.js} +1 -1
- package/ui/dist/assets/{shield-off-CLtXio62.js → shield-off-8l0J6R-8.js} +1 -1
- package/ui/dist/assets/{skeleton-C9oEzNlU.js → skeleton-TFiFJ3nB.js} +1 -1
- package/ui/dist/assets/{smartphone-DusFfY0U.js → smartphone-77_g3SQn.js} +1 -1
- package/ui/dist/assets/{square-e1yxB2eR.js → square-Ckzsr3Rn.js} +1 -1
- package/ui/dist/assets/{switch-tNs0n-kz.js → switch-CAePkd6k.js} +1 -1
- package/ui/dist/assets/{table-CXxtLicg.js → table-ZjAZ7hkt.js} +1 -1
- package/ui/dist/assets/{tag-tAwMmQ9G.js → tag-C35mgoEv.js} +1 -1
- package/ui/dist/assets/{textarea-BjiEeIWh.js → textarea-DsVPnSgR.js} +1 -1
- package/ui/dist/assets/{timer-Vel1N3RP.js → timer-DHJBS2w1.js} +1 -1
- package/ui/dist/assets/{tooltip-ZMwtfr1J.js → tooltip-BYmQ331W.js} +1 -1
- package/ui/dist/assets/{trash-2-eM-CNwsZ.js → trash-2-keO5tKPE.js} +1 -1
- package/ui/dist/assets/{trending-up-BGafmjRo.js → trending-up-BBv8KbrY.js} +1 -1
- package/ui/dist/assets/{wand-sparkles-DPvcd9Pi.js → wand-sparkles-BusQ52ZK.js} +1 -1
- package/ui/dist/assets/{wrench-B8s3zYVV.js → wrench-02YaOSiK.js} +1 -1
- package/ui/dist/index.html +2 -2
- package/dist/chat/auto-reply.d.ts +0 -90
- package/dist/chat/auto-reply.js +0 -272
- package/dist/chat/execution/pty.d.ts +0 -92
- package/dist/chat/execution/pty.js +0 -285
- package/dist/chat/execution/tools/glinr-ops.d.ts +0 -202
- package/dist/chat/execution/tools/glinr-ops.js +0 -694
- package/dist/cli/commands/browser.d.ts +0 -3
- package/dist/cli/commands/browser.js +0 -138
- package/dist/cli/commands/canvas.d.ts +0 -3
- package/dist/cli/commands/canvas.js +0 -155
- package/dist/cli/commands/nodes.d.ts +0 -3
- package/dist/cli/commands/nodes.js +0 -193
- package/dist/diagnostics/exporters.d.ts +0 -21
- package/dist/diagnostics/exporters.js +0 -138
- package/dist/diagnostics/index.d.ts +0 -10
- package/dist/diagnostics/index.js +0 -9
- package/dist/diagnostics/middleware.d.ts +0 -12
- package/dist/diagnostics/middleware.js +0 -58
- package/dist/diagnostics/tracer.d.ts +0 -133
- package/dist/diagnostics/tracer.js +0 -257
- package/dist/discovery/index.d.ts +0 -8
- package/dist/discovery/index.js +0 -7
- package/dist/discovery/mdns.d.ts +0 -40
- package/dist/discovery/mdns.js +0 -249
- package/dist/plugins/registry.d.ts +0 -122
- package/dist/plugins/registry.js +0 -352
- package/dist/plugins/sandbox.d.ts +0 -77
- package/dist/plugins/sandbox.js +0 -287
- package/dist/plugins/search/brave.d.ts +0 -9
- package/dist/plugins/search/brave.js +0 -157
- package/dist/plugins/search/duckduckgo.d.ts +0 -9
- package/dist/plugins/search/duckduckgo.js +0 -171
- package/dist/plugins/search/index.d.ts +0 -13
- package/dist/plugins/search/index.js +0 -23
- package/dist/plugins/search/searxng.d.ts +0 -9
- package/dist/plugins/search/searxng.js +0 -170
- package/dist/plugins/search/serper.d.ts +0 -9
- package/dist/plugins/search/serper.js +0 -135
- package/dist/plugins/search/tavily.d.ts +0 -9
- package/dist/plugins/search/tavily.js +0 -146
- package/dist/providers/adapters/anthropic.d.ts +0 -26
- package/dist/providers/adapters/anthropic.js +0 -306
- package/dist/providers/adapters/base.d.ts +0 -53
- package/dist/providers/adapters/base.js +0 -99
- package/dist/providers/adapters/ollama.d.ts +0 -30
- package/dist/providers/adapters/ollama.js +0 -292
- package/dist/utils/ai-cache.d.ts +0 -72
- package/dist/utils/ai-cache.js +0 -204
- package/dist/utils/file-lock.d.ts +0 -85
- package/dist/utils/file-lock.js +0 -204
- package/ui/dist/assets/index-WclMPci1.css +0 -1
package/dist/providers/ai-sdk.js
CHANGED
|
@@ -43,6 +43,26 @@ async function withRetry(fn, maxRetries = AI_MAX_RETRIES) {
|
|
|
43
43
|
// Core types & data — single source of truth in core/
|
|
44
44
|
import { ProviderType, PROVIDER_STATUS, } from './core/types.js';
|
|
45
45
|
import { MODEL_ALIASES, MODEL_CATALOG } from './core/models.js';
|
|
46
|
+
/** Sensible default model per provider (used when no model is specified). */
|
|
47
|
+
const PROVIDER_DEFAULT_MODEL = {
|
|
48
|
+
ollama: 'llama3.2',
|
|
49
|
+
anthropic: 'claude-sonnet-4-5-20250929',
|
|
50
|
+
openai: 'gpt-4o',
|
|
51
|
+
google: 'gemini-2.0-flash',
|
|
52
|
+
azure: 'gpt-4o',
|
|
53
|
+
groq: 'llama-3.3-70b-versatile',
|
|
54
|
+
cerebras: 'llama-3.3-70b',
|
|
55
|
+
fireworks: 'accounts/fireworks/models/llama-v3p1-70b-instruct',
|
|
56
|
+
together: 'meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo',
|
|
57
|
+
deepseek: 'deepseek-chat',
|
|
58
|
+
mistral: 'mistral-large-latest',
|
|
59
|
+
xai: 'grok-2',
|
|
60
|
+
cohere: 'command-r-plus',
|
|
61
|
+
perplexity: 'sonar',
|
|
62
|
+
bedrock: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
|
|
63
|
+
replicate: 'meta/meta-llama-3-70b-instruct',
|
|
64
|
+
openrouter: 'anthropic/claude-sonnet-4-5-20250929',
|
|
65
|
+
};
|
|
46
66
|
// Re-export for consumers that import from providers/ai-sdk or providers/index
|
|
47
67
|
export { ProviderType, PROVIDER_STATUS, MODEL_ALIASES, MODEL_CATALOG, };
|
|
48
68
|
// Pre-compiled regex patterns for performance (avoid recompilation on each call)
|
|
@@ -773,7 +793,7 @@ class AIProviderManager {
|
|
|
773
793
|
// Resolve model
|
|
774
794
|
const modelRef = request.model
|
|
775
795
|
? this.resolveModel(request.model)
|
|
776
|
-
: { provider: this.defaultProvider, model: 'llama3.2' };
|
|
796
|
+
: { provider: this.defaultProvider, model: PROVIDER_DEFAULT_MODEL[this.defaultProvider] || 'llama3.2' };
|
|
777
797
|
const model = await this.getModel(modelRef.provider, modelRef.model);
|
|
778
798
|
// Convert messages to AI SDK format
|
|
779
799
|
const messages = request.messages.map((msg) => ({
|
|
@@ -831,7 +851,7 @@ class AIProviderManager {
|
|
|
831
851
|
// Resolve model
|
|
832
852
|
const modelRef = request.model
|
|
833
853
|
? this.resolveModel(request.model)
|
|
834
|
-
: { provider: this.defaultProvider, model: 'llama3.2' };
|
|
854
|
+
: { provider: this.defaultProvider, model: PROVIDER_DEFAULT_MODEL[this.defaultProvider] || 'llama3.2' };
|
|
835
855
|
const model = await this.getModel(modelRef.provider, modelRef.model);
|
|
836
856
|
// Convert messages
|
|
837
857
|
const messages = request.messages.map((msg) => ({
|
|
@@ -911,7 +931,7 @@ class AIProviderManager {
|
|
|
911
931
|
// Resolve model
|
|
912
932
|
const modelRef = request.model
|
|
913
933
|
? this.resolveModel(request.model)
|
|
914
|
-
: { provider: this.defaultProvider, model: 'llama3.2' };
|
|
934
|
+
: { provider: this.defaultProvider, model: PROVIDER_DEFAULT_MODEL[this.defaultProvider] || 'llama3.2' };
|
|
915
935
|
const model = await this.getModel(modelRef.provider, modelRef.model);
|
|
916
936
|
// Check if model supports native tools
|
|
917
937
|
const toolSupport = this.modelSupportsTools(modelRef.model || modelRef.provider + '/' + modelRef.model);
|
|
@@ -1058,7 +1078,7 @@ class AIProviderManager {
|
|
|
1058
1078
|
modelSupportsTools(modelOrAlias) {
|
|
1059
1079
|
const modelRef = modelOrAlias
|
|
1060
1080
|
? this.resolveModel(modelOrAlias)
|
|
1061
|
-
: { provider: this.defaultProvider, model: 'llama3.2' };
|
|
1081
|
+
: { provider: this.defaultProvider, model: PROVIDER_DEFAULT_MODEL[this.defaultProvider] || 'llama3.2' };
|
|
1062
1082
|
// Azure OpenAI: All GPT-4, GPT-4o, and GPT-3.5-turbo models support function calling
|
|
1063
1083
|
// We check provider first since Azure deployment names won't be in MODEL_CATALOG
|
|
1064
1084
|
if (modelRef.provider === 'azure') {
|
|
@@ -1103,7 +1123,7 @@ class AIProviderManager {
|
|
|
1103
1123
|
// Resolve model
|
|
1104
1124
|
const modelRef = request.model
|
|
1105
1125
|
? this.resolveModel(request.model)
|
|
1106
|
-
: { provider: this.defaultProvider, model: 'llama3.2' };
|
|
1126
|
+
: { provider: this.defaultProvider, model: PROVIDER_DEFAULT_MODEL[this.defaultProvider] || 'llama3.2' };
|
|
1107
1127
|
const model = await this.getModel(modelRef.provider, modelRef.model);
|
|
1108
1128
|
// Check if model supports native tool calling
|
|
1109
1129
|
const toolSupport = this.modelSupportsTools(request.model);
|
|
@@ -1277,7 +1297,7 @@ class AIProviderManager {
|
|
|
1277
1297
|
// Resolve model
|
|
1278
1298
|
const modelRef = request.model
|
|
1279
1299
|
? this.resolveModel(request.model)
|
|
1280
|
-
: { provider: this.defaultProvider, model: 'llama3.2' };
|
|
1300
|
+
: { provider: this.defaultProvider, model: PROVIDER_DEFAULT_MODEL[this.defaultProvider] || 'llama3.2' };
|
|
1281
1301
|
const model = await this.getModel(modelRef.provider, modelRef.model);
|
|
1282
1302
|
// Convert messages
|
|
1283
1303
|
const messages = toAiMessages(request.messages);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified Channel Management Routes
|
|
3
|
+
*
|
|
4
|
+
* Provides a single API for managing all chat channel providers
|
|
5
|
+
* (Telegram, Discord, WhatsApp, Slack, etc.).
|
|
6
|
+
*
|
|
7
|
+
* Delegates to individual provider modules for health checks
|
|
8
|
+
* and reads from the chat provider registry for status.
|
|
9
|
+
*/
|
|
10
|
+
import { Hono } from 'hono';
|
|
11
|
+
export declare const channelsRoutes: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
12
|
+
//# sourceMappingURL=channels.d.ts.map
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified Channel Management Routes
|
|
3
|
+
*
|
|
4
|
+
* Provides a single API for managing all chat channel providers
|
|
5
|
+
* (Telegram, Discord, WhatsApp, Slack, etc.).
|
|
6
|
+
*
|
|
7
|
+
* Delegates to individual provider modules for health checks
|
|
8
|
+
* and reads from the chat provider registry for status.
|
|
9
|
+
*/
|
|
10
|
+
import { Hono } from 'hono';
|
|
11
|
+
export const channelsRoutes = new Hono();
|
|
12
|
+
const KNOWN_PROVIDERS = [
|
|
13
|
+
'slack', 'discord', 'telegram', 'whatsapp', 'webchat',
|
|
14
|
+
'matrix', 'googlechat', 'msteams', 'mattermost',
|
|
15
|
+
];
|
|
16
|
+
function isKnownProvider(provider) {
|
|
17
|
+
return KNOWN_PROVIDERS.includes(provider);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* GET /
|
|
21
|
+
* List all channel providers with their status
|
|
22
|
+
*/
|
|
23
|
+
channelsRoutes.get('/', async (c) => {
|
|
24
|
+
const { getChatRegistry } = await import('../chat/providers/registry.js');
|
|
25
|
+
const registry = getChatRegistry();
|
|
26
|
+
const status = await registry.getStatus();
|
|
27
|
+
const channels = KNOWN_PROVIDERS.map((id) => {
|
|
28
|
+
const providerStatus = status.providers.find((p) => p.id === id);
|
|
29
|
+
const hasAccounts = providerStatus && providerStatus.accounts.length > 0;
|
|
30
|
+
const anyEnabled = providerStatus?.accounts.some((a) => a.enabled) ?? false;
|
|
31
|
+
const anyConfigured = providerStatus?.accounts.some((a) => a.configured) ?? false;
|
|
32
|
+
const anyConnected = providerStatus?.accounts.some((a) => a.connected) ?? false;
|
|
33
|
+
return {
|
|
34
|
+
provider: id,
|
|
35
|
+
registered: providerStatus?.registered ?? false,
|
|
36
|
+
enabled: anyEnabled,
|
|
37
|
+
configured: anyConfigured,
|
|
38
|
+
healthy: hasAccounts ? anyConnected : undefined,
|
|
39
|
+
accounts: providerStatus?.accounts ?? [],
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
return c.json({ channels });
|
|
43
|
+
});
|
|
44
|
+
/**
|
|
45
|
+
* POST /:provider/enable
|
|
46
|
+
* Enable a channel provider account
|
|
47
|
+
*/
|
|
48
|
+
channelsRoutes.post('/:provider/enable', async (c) => {
|
|
49
|
+
const provider = c.req.param('provider');
|
|
50
|
+
if (!isKnownProvider(provider)) {
|
|
51
|
+
return c.json({ error: `Unknown provider: ${provider}` }, 400);
|
|
52
|
+
}
|
|
53
|
+
const { getChatRegistry } = await import('../chat/providers/registry.js');
|
|
54
|
+
const registry = getChatRegistry();
|
|
55
|
+
const account = registry.getDefaultAccount(provider);
|
|
56
|
+
if (!account) {
|
|
57
|
+
return c.json({ error: `No account configured for ${provider}` }, 404);
|
|
58
|
+
}
|
|
59
|
+
account.enabled = true;
|
|
60
|
+
registry.registerAccount(account);
|
|
61
|
+
return c.json({
|
|
62
|
+
provider,
|
|
63
|
+
enabled: true,
|
|
64
|
+
message: `${provider} enabled`,
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
/**
|
|
68
|
+
* POST /:provider/disable
|
|
69
|
+
* Disable a channel provider account
|
|
70
|
+
*/
|
|
71
|
+
channelsRoutes.post('/:provider/disable', async (c) => {
|
|
72
|
+
const provider = c.req.param('provider');
|
|
73
|
+
if (!isKnownProvider(provider)) {
|
|
74
|
+
return c.json({ error: `Unknown provider: ${provider}` }, 400);
|
|
75
|
+
}
|
|
76
|
+
const { getChatRegistry } = await import('../chat/providers/registry.js');
|
|
77
|
+
const registry = getChatRegistry();
|
|
78
|
+
const account = registry.getDefaultAccount(provider);
|
|
79
|
+
if (!account) {
|
|
80
|
+
return c.json({ error: `No account configured for ${provider}` }, 404);
|
|
81
|
+
}
|
|
82
|
+
account.enabled = false;
|
|
83
|
+
registry.registerAccount(account);
|
|
84
|
+
return c.json({
|
|
85
|
+
provider,
|
|
86
|
+
enabled: false,
|
|
87
|
+
message: `${provider} disabled`,
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
/**
|
|
91
|
+
* GET /:provider/config
|
|
92
|
+
* Get provider configuration (secrets redacted)
|
|
93
|
+
*/
|
|
94
|
+
channelsRoutes.get('/:provider/config', async (c) => {
|
|
95
|
+
const provider = c.req.param('provider');
|
|
96
|
+
if (!isKnownProvider(provider)) {
|
|
97
|
+
return c.json({ error: `Unknown provider: ${provider}` }, 400);
|
|
98
|
+
}
|
|
99
|
+
const { getChatRegistry } = await import('../chat/providers/registry.js');
|
|
100
|
+
const registry = getChatRegistry();
|
|
101
|
+
const accounts = registry.listAccounts(provider);
|
|
102
|
+
if (accounts.length === 0) {
|
|
103
|
+
return c.json({ error: `No accounts configured for ${provider}` }, 404);
|
|
104
|
+
}
|
|
105
|
+
// Redact secrets from config
|
|
106
|
+
const redacted = accounts.map((account) => {
|
|
107
|
+
const safe = {
|
|
108
|
+
id: account.id,
|
|
109
|
+
name: account.name,
|
|
110
|
+
provider: account.provider,
|
|
111
|
+
enabled: account.enabled,
|
|
112
|
+
};
|
|
113
|
+
// Copy non-secret fields from config
|
|
114
|
+
if (account && typeof account === 'object') {
|
|
115
|
+
for (const [key, val] of Object.entries(account)) {
|
|
116
|
+
if (['id', 'name', 'provider', 'enabled'].includes(key))
|
|
117
|
+
continue;
|
|
118
|
+
// Redact anything that looks like a token/secret/key/password
|
|
119
|
+
if (typeof val === 'string' && /token|secret|key|password|api_key/i.test(key)) {
|
|
120
|
+
safe[key] = val.length > 4 ? `${val.slice(0, 4)}...` : '***';
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
safe[key] = val;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return safe;
|
|
128
|
+
});
|
|
129
|
+
return c.json({ provider, config: redacted });
|
|
130
|
+
});
|
|
131
|
+
/**
|
|
132
|
+
* POST /:provider/test
|
|
133
|
+
* Health check a provider connection
|
|
134
|
+
*/
|
|
135
|
+
channelsRoutes.post('/:provider/test', async (c) => {
|
|
136
|
+
const provider = c.req.param('provider');
|
|
137
|
+
if (!isKnownProvider(provider)) {
|
|
138
|
+
return c.json({ error: `Unknown provider: ${provider}` }, 400);
|
|
139
|
+
}
|
|
140
|
+
const { getChatRegistry } = await import('../chat/providers/registry.js');
|
|
141
|
+
const registry = getChatRegistry();
|
|
142
|
+
const chatProvider = registry.get(provider);
|
|
143
|
+
if (!chatProvider) {
|
|
144
|
+
return c.json({ provider, healthy: false, message: `Provider ${provider} not registered` });
|
|
145
|
+
}
|
|
146
|
+
const account = registry.getDefaultAccount(provider);
|
|
147
|
+
if (!account) {
|
|
148
|
+
return c.json({ provider, healthy: false, message: `No account configured for ${provider}` });
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
const health = await chatProvider.status.checkHealth(account);
|
|
152
|
+
return c.json({
|
|
153
|
+
provider,
|
|
154
|
+
healthy: health.connected,
|
|
155
|
+
message: health.error ?? (health.connected ? 'Connected' : 'Disconnected'),
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
return c.json({
|
|
160
|
+
provider,
|
|
161
|
+
healthy: false,
|
|
162
|
+
message: err instanceof Error ? err.message : 'Health check failed',
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
//# sourceMappingURL=channels.js.map
|
|
@@ -92,6 +92,7 @@ const SYNC_ROUTE_DEFINITIONS = [
|
|
|
92
92
|
{ id: 'backup', mountPaths: ['/api/backup'], load: namedRoute(() => import('../routes/backup.js'), 'backupRoutes') },
|
|
93
93
|
];
|
|
94
94
|
const CHAT_CHANNEL_ROUTE_DEFINITIONS = [
|
|
95
|
+
{ id: 'channels', mountPaths: ['/api/channels'], load: namedRoute(() => import('../routes/channels.js'), 'channelsRoutes') },
|
|
95
96
|
{ id: 'telegram', mountPaths: ['/api/telegram'], load: namedRoute(() => import('../routes/telegram.js'), 'telegramRoutes') },
|
|
96
97
|
{ id: 'whatsapp', mountPaths: ['/api/whatsapp'], load: namedRoute(() => import('../routes/whatsapp.js'), 'whatsappRoutes') },
|
|
97
98
|
{ id: 'discord', mountPaths: ['/api/discord'], load: namedRoute(() => import('../routes/discord.js'), 'discordRoutes') },
|
package/dist/server.js
CHANGED
|
@@ -12,8 +12,8 @@ import { initApiTokensTable, tokenAuthMiddleware } from './auth/api-tokens.js';
|
|
|
12
12
|
import { authMiddleware } from './auth/middleware.js';
|
|
13
13
|
import { rateLimit } from './middleware/rate-limit.js';
|
|
14
14
|
import { CreateTaskSchema } from './types/task.js';
|
|
15
|
-
import { getMode, getModeLabel, hasCapability } from './core/deployment.js';
|
|
16
|
-
import { registerRouteModules } from './server/route-loader.js';
|
|
15
|
+
import { getMode, getModeLabel, hasCapability, getCapabilities } from './core/deployment.js';
|
|
16
|
+
import { getRouteDefinitionsForMode, registerRouteModules } from './server/route-loader.js';
|
|
17
17
|
const VERSION = '2.0.0';
|
|
18
18
|
let cachedSettings = null;
|
|
19
19
|
function getAppSettings() {
|
|
@@ -114,117 +114,123 @@ app.get('/health', async (c) => {
|
|
|
114
114
|
agents: agentHealth,
|
|
115
115
|
});
|
|
116
116
|
});
|
|
117
|
-
// API info
|
|
117
|
+
// API info (mode-aware)
|
|
118
118
|
app.get('/', (c) => {
|
|
119
|
+
const mode = getMode();
|
|
120
|
+
const routes = getRouteDefinitionsForMode(mode);
|
|
121
|
+
const routeIds = new Set(routes.map((r) => r.id));
|
|
122
|
+
// Build endpoints dynamically based on available routes
|
|
123
|
+
const endpoints = {
|
|
124
|
+
health: 'GET /health',
|
|
125
|
+
};
|
|
126
|
+
// Core routes (always available)
|
|
127
|
+
if (routeIds.has('tasks')) {
|
|
128
|
+
endpoints.tasks = {
|
|
129
|
+
list: 'GET /api/tasks',
|
|
130
|
+
create: 'POST /api/tasks',
|
|
131
|
+
get: 'GET /api/tasks/:id',
|
|
132
|
+
cancel: 'POST /api/tasks/:id/cancel',
|
|
133
|
+
retry: 'POST /api/tasks/:id/retry',
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if (routeIds.has('agents'))
|
|
137
|
+
endpoints.agents = 'GET /api/agents';
|
|
138
|
+
if (routeIds.has('chat')) {
|
|
139
|
+
endpoints.chat = {
|
|
140
|
+
models: 'GET /api/chat/models',
|
|
141
|
+
providers: 'GET /api/chat/providers',
|
|
142
|
+
send: 'POST /api/chat/send',
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
if (routeIds.has('gateway')) {
|
|
146
|
+
endpoints.gateway = {
|
|
147
|
+
execute: 'POST /api/gateway/execute',
|
|
148
|
+
agents: 'GET /api/gateway/agents',
|
|
149
|
+
workflows: 'GET /api/gateway/workflows',
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
if (routeIds.has('hooks')) {
|
|
153
|
+
endpoints.hooks = {
|
|
154
|
+
toolUse: 'POST /api/hook/tool-use',
|
|
155
|
+
sessionEnd: 'POST /api/hook/session-end',
|
|
156
|
+
sessions: 'GET /api/hook/sessions',
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
if (routeIds.has('tools'))
|
|
160
|
+
endpoints.tools = 'GET /api/tools';
|
|
161
|
+
if (routeIds.has('settings')) {
|
|
162
|
+
endpoints.settings = {
|
|
163
|
+
get: 'GET /api/settings',
|
|
164
|
+
update: 'PATCH /api/settings',
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
if (routeIds.has('auth'))
|
|
168
|
+
endpoints.auth = 'POST /auth/login';
|
|
169
|
+
// Dashboard/web UI routes
|
|
170
|
+
if (routeIds.has('costs'))
|
|
171
|
+
endpoints.costs = 'GET /api/costs/summary';
|
|
172
|
+
if (routeIds.has('memory'))
|
|
173
|
+
endpoints.memory = 'GET /api/memory';
|
|
174
|
+
if (routeIds.has('skills'))
|
|
175
|
+
endpoints.skills = 'GET /api/skills';
|
|
176
|
+
if (routeIds.has('mcp'))
|
|
177
|
+
endpoints.mcp = 'GET /api/mcp';
|
|
178
|
+
if (routeIds.has('tunnels'))
|
|
179
|
+
endpoints.tunnels = 'GET /api/tunnels';
|
|
180
|
+
// Web UI data routes
|
|
181
|
+
if (routeIds.has('dlq'))
|
|
182
|
+
endpoints.deadLetterQueue = 'GET /api/dlq';
|
|
183
|
+
if (routeIds.has('summaries')) {
|
|
184
|
+
endpoints.summaries = {
|
|
185
|
+
list: 'GET /api/summaries',
|
|
186
|
+
search: 'GET /api/summaries/search',
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (routeIds.has('search')) {
|
|
190
|
+
endpoints.search = {
|
|
191
|
+
semantic: 'GET /api/search/semantic?q={query}',
|
|
192
|
+
text: 'GET /api/search/text?q={query}',
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
if (routeIds.has('stats'))
|
|
196
|
+
endpoints.stats = 'GET /api/stats';
|
|
197
|
+
// Integration routes
|
|
198
|
+
if (routeIds.has('tickets')) {
|
|
199
|
+
endpoints.tickets = {
|
|
200
|
+
list: 'GET /api/tickets',
|
|
201
|
+
create: 'POST /api/tickets',
|
|
202
|
+
get: 'GET /api/tickets/:id',
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
if (routeIds.has('projects')) {
|
|
206
|
+
endpoints.projects = {
|
|
207
|
+
list: 'GET /api/projects',
|
|
208
|
+
create: 'POST /api/projects',
|
|
209
|
+
get: 'GET /api/projects/:id',
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
if (routeIds.has('webhooks')) {
|
|
213
|
+
endpoints.webhooks = {
|
|
214
|
+
github: 'POST /webhooks/github',
|
|
215
|
+
jira: 'POST /webhooks/jira',
|
|
216
|
+
linear: 'POST /webhooks/linear',
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
// Cron routes
|
|
220
|
+
if (routeIds.has('cron'))
|
|
221
|
+
endpoints.cron = 'GET /api/cron';
|
|
222
|
+
// Channel routes
|
|
223
|
+
if (routeIds.has('channels'))
|
|
224
|
+
endpoints.channels = 'GET /api/channels';
|
|
225
|
+
// Sync routes
|
|
226
|
+
if (routeIds.has('sync'))
|
|
227
|
+
endpoints.sync = 'GET /api/sync';
|
|
119
228
|
return c.json({
|
|
120
229
|
name: 'profClaw',
|
|
121
230
|
version: VERSION,
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
endpoints
|
|
125
|
-
health: 'GET /health',
|
|
126
|
-
tasks: 'GET /api/tasks',
|
|
127
|
-
createTask: 'POST /api/tasks',
|
|
128
|
-
getTask: 'GET /api/tasks/:id',
|
|
129
|
-
cancelTask: 'POST /api/tasks/:id/cancel',
|
|
130
|
-
retryTask: 'POST /api/tasks/:id/retry',
|
|
131
|
-
agents: 'GET /api/agents',
|
|
132
|
-
deadLetterQueue: 'GET /api/dlq',
|
|
133
|
-
retryDlqTask: 'POST /api/dlq/:id/retry',
|
|
134
|
-
webhooks: {
|
|
135
|
-
github: 'POST /webhooks/github',
|
|
136
|
-
jira: 'POST /webhooks/jira',
|
|
137
|
-
linear: 'POST /webhooks/linear',
|
|
138
|
-
},
|
|
139
|
-
hooks: {
|
|
140
|
-
toolUse: 'POST /api/hook/tool-use',
|
|
141
|
-
sessionEnd: 'POST /api/hook/session-end',
|
|
142
|
-
promptSubmit: 'POST /api/hook/prompt-submit',
|
|
143
|
-
sessions: 'GET /api/hook/sessions',
|
|
144
|
-
sessionEvents: 'GET /api/hook/sessions/:sessionId/events',
|
|
145
|
-
sessionSummary: 'GET /api/hook/sessions/:sessionId/summary',
|
|
146
|
-
},
|
|
147
|
-
agentWebhooks: {
|
|
148
|
-
openclaw: 'POST /api/hook/webhook/openclaw',
|
|
149
|
-
generic: 'POST /api/hook/webhook/agent',
|
|
150
|
-
reports: 'GET /api/hook/webhook/reports',
|
|
151
|
-
taskReports: 'GET /api/hook/webhook/tasks/:taskId/reports',
|
|
152
|
-
},
|
|
153
|
-
costs: {
|
|
154
|
-
summary: 'GET /api/costs/summary',
|
|
155
|
-
budget: 'GET /api/costs/budget',
|
|
156
|
-
},
|
|
157
|
-
summaries: {
|
|
158
|
-
list: 'GET /api/summaries',
|
|
159
|
-
create: 'POST /api/summaries',
|
|
160
|
-
get: 'GET /api/summaries/:id',
|
|
161
|
-
delete: 'DELETE /api/summaries/:id',
|
|
162
|
-
search: 'GET /api/summaries/search',
|
|
163
|
-
stats: 'GET /api/summaries/stats',
|
|
164
|
-
recent: 'GET /api/summaries/recent',
|
|
165
|
-
byTask: 'GET /api/tasks/:taskId/summaries',
|
|
166
|
-
},
|
|
167
|
-
settings: {
|
|
168
|
-
get: 'GET /api/settings',
|
|
169
|
-
update: 'PATCH /api/settings',
|
|
170
|
-
reset: 'POST /api/settings/reset',
|
|
171
|
-
},
|
|
172
|
-
gateway: {
|
|
173
|
-
execute: 'POST /api/gateway/execute',
|
|
174
|
-
agents: 'GET /api/gateway/agents',
|
|
175
|
-
workflows: 'GET /api/gateway/workflows',
|
|
176
|
-
workflow: 'GET /api/gateway/workflows/:type',
|
|
177
|
-
config: 'GET /api/gateway/config',
|
|
178
|
-
updateConfig: 'PATCH /api/gateway/config',
|
|
179
|
-
},
|
|
180
|
-
search: {
|
|
181
|
-
semantic: 'GET /api/search/semantic?q={query}',
|
|
182
|
-
text: 'GET /api/search/text?q={query}',
|
|
183
|
-
capabilities: 'GET /api/search/capabilities',
|
|
184
|
-
},
|
|
185
|
-
tickets: {
|
|
186
|
-
list: 'GET /api/tickets',
|
|
187
|
-
create: 'POST /api/tickets',
|
|
188
|
-
get: 'GET /api/tickets/:id',
|
|
189
|
-
update: 'PATCH /api/tickets/:id',
|
|
190
|
-
delete: 'DELETE /api/tickets/:id',
|
|
191
|
-
transition: 'POST /api/tickets/:id/transition',
|
|
192
|
-
assignAgent: 'POST /api/tickets/:id/assign-agent',
|
|
193
|
-
comments: 'GET /api/tickets/:id/comments',
|
|
194
|
-
addComment: 'POST /api/tickets/:id/comments',
|
|
195
|
-
links: 'GET /api/tickets/:id/links',
|
|
196
|
-
addLink: 'POST /api/tickets/:id/links',
|
|
197
|
-
history: 'GET /api/tickets/:id/history',
|
|
198
|
-
},
|
|
199
|
-
projects: {
|
|
200
|
-
list: 'GET /api/projects',
|
|
201
|
-
create: 'POST /api/projects',
|
|
202
|
-
get: 'GET /api/projects/:id',
|
|
203
|
-
update: 'PATCH /api/projects/:id',
|
|
204
|
-
archive: 'POST /api/projects/:id/archive',
|
|
205
|
-
delete: 'DELETE /api/projects/:id',
|
|
206
|
-
byKey: 'GET /api/projects/by-key/:key',
|
|
207
|
-
default: 'GET /api/projects/default',
|
|
208
|
-
migrate: 'POST /api/projects/migrate',
|
|
209
|
-
externalLinks: 'GET /api/projects/:id/external-links',
|
|
210
|
-
addExternalLink: 'POST /api/projects/:id/external-links',
|
|
211
|
-
},
|
|
212
|
-
sprints: {
|
|
213
|
-
list: 'GET /api/projects/:projectId/sprints',
|
|
214
|
-
create: 'POST /api/projects/:projectId/sprints',
|
|
215
|
-
get: 'GET /api/projects/:projectId/sprints/:sprintId',
|
|
216
|
-
update: 'PATCH /api/projects/:projectId/sprints/:sprintId',
|
|
217
|
-
start: 'POST /api/projects/:projectId/sprints/:sprintId/start',
|
|
218
|
-
complete: 'POST /api/projects/:projectId/sprints/:sprintId/complete',
|
|
219
|
-
cancel: 'POST /api/projects/:projectId/sprints/:sprintId/cancel',
|
|
220
|
-
delete: 'DELETE /api/projects/:projectId/sprints/:sprintId',
|
|
221
|
-
active: 'GET /api/projects/:projectId/sprints/active',
|
|
222
|
-
tickets: 'GET /api/projects/:projectId/sprints/:sprintId/tickets',
|
|
223
|
-
addTickets: 'POST /api/projects/:projectId/sprints/:sprintId/tickets',
|
|
224
|
-
removeTicket: 'DELETE /api/projects/:projectId/sprints/:sprintId/tickets/:ticketId',
|
|
225
|
-
reorderTickets: 'PUT /api/projects/:projectId/sprints/:sprintId/tickets/reorder',
|
|
226
|
-
},
|
|
227
|
-
},
|
|
231
|
+
mode,
|
|
232
|
+
capabilities: getCapabilities(),
|
|
233
|
+
endpoints,
|
|
228
234
|
});
|
|
229
235
|
});
|
|
230
236
|
// Task statistics
|
package/package.json
CHANGED
|
@@ -27,7 +27,7 @@ This project uses the following format:
|
|
|
27
27
|
|
|
28
28
|
<optional body>
|
|
29
29
|
|
|
30
|
-
Co-Authored-By:
|
|
30
|
+
Co-Authored-By: profClaw <bot@profclaw.ai>
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
**Types**:
|
|
@@ -83,7 +83,7 @@ feat: add exponential backoff to task retry logic
|
|
|
83
83
|
Retry attempts now use 2^n * 1000ms delays, capped at 30s,
|
|
84
84
|
to reduce thundering herd on downstream services.
|
|
85
85
|
|
|
86
|
-
Co-Authored-By:
|
|
86
|
+
Co-Authored-By: profClaw <bot@profclaw.ai>
|
|
87
87
|
EOF
|
|
88
88
|
)"
|
|
89
89
|
```
|
|
@@ -108,7 +108,7 @@ gh pr create --title "feat: add webhook retry logic" --body "$(cat <<'EOF'
|
|
|
108
108
|
- [ ] Manually trigger a webhook with a failing endpoint
|
|
109
109
|
- [ ] Verify retry schedule in BullMQ dashboard
|
|
110
110
|
|
|
111
|
-
Co-Authored-By:
|
|
111
|
+
Co-Authored-By: profClaw <bot@profclaw.ai>
|
|
112
112
|
EOF
|
|
113
113
|
)"
|
|
114
114
|
```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as z,n as I,r as x,u as K,o as h,m as d,t as w,j as e,k as c,a1 as Q,b as f,f as j,i as p,C as A,aK as B,g as E,U as V,v as $}from"./index
|
|
1
|
+
import{c as z,n as I,r as x,u as K,o as h,m as d,t as w,j as e,k as c,a1 as Q,b as f,f as j,i as p,C as A,aK as B,g as E,U as V,v as $}from"./index-lJlNPFVJ.js";import{B as L}from"./badge-CVHH1a-v.js";import{S as g}from"./skeleton-TFiFJ3nB.js";import{S as k,a as C,b,c as S,d as a}from"./select-CeQ8AHGy.js";import{T as U}from"./trash-2-keO5tKPE.js";import"./chevron-up-CoUsOvZj.js";const _=[["path",{d:"M18 6 7 17l-5-5",key:"116fxf"}],["path",{d:"m22 10-7.5 7.5L13 16",key:"ke71qq"}]],D=z("check-check",_);function O({type:i}){switch(i){case"success":return e.jsx(A,{className:"h-4 w-4 text-green-400"});case"error":return e.jsx($,{className:"h-4 w-4 text-red-400"});case"warning":return e.jsx(V,{className:"h-4 w-4 text-amber-400"});default:return e.jsx(E,{className:"h-4 w-4 text-blue-400"})}}function P(i){const o=Date.now()-i,l=Math.floor(o/1e3);if(l<60)return"just now";const n=Math.floor(l/60);if(n<60)return`${n}m ago`;const t=Math.floor(n/60);return t<24?`${t}h ago`:`${Math.floor(t/24)}d ago`}function Z(){const i=I(),[r,o]=x.useState("all"),[l,n]=x.useState("all"),[t,u]=x.useState(!1),{data:y,isLoading:M}=K({queryKey:["notifications","activity"],queryFn:()=>d.notifications.list({limit:100}),refetchInterval:3e4}),T=h({mutationFn:s=>d.notifications.markRead(s),onSuccess:()=>{i.invalidateQueries({queryKey:["notifications"]})}}),N=h({mutationFn:()=>d.notifications.markAllRead(),onSuccess:()=>{i.invalidateQueries({queryKey:["notifications"]}),w.success("All notifications marked as read")}}),q=h({mutationFn:s=>d.notifications.delete(s),onSuccess:()=>{i.invalidateQueries({queryKey:["notifications"]}),w.success("Notification deleted")}}),F=y?.notifications??[],m=y?.unreadCount??0,v=F.filter(s=>!(r!=="all"&&s.type!==r||l!=="all"&&s.category!==l||t&&s.read));return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Activity"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:m>0?`${m} unread`:"All caught up"})]}),m>0&&e.jsxs(c,{variant:"outline",size:"sm",onClick:()=>N.mutate(),disabled:N.isPending,className:"gap-2",children:[e.jsx(D,{className:"h-4 w-4"}),"Mark all read"]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs(k,{value:r,onValueChange:s=>o(s),children:[e.jsx(C,{className:"w-[140px]",children:e.jsx(b,{placeholder:"Type"})}),e.jsxs(S,{children:[e.jsx(a,{value:"all",children:"All types"}),e.jsx(a,{value:"success",children:"Success"}),e.jsx(a,{value:"error",children:"Error"}),e.jsx(a,{value:"warning",children:"Warning"}),e.jsx(a,{value:"info",children:"Info"})]})]}),e.jsxs(k,{value:l,onValueChange:s=>n(s),children:[e.jsx(C,{className:"w-[140px]",children:e.jsx(b,{placeholder:"Category"})}),e.jsxs(S,{children:[e.jsx(a,{value:"all",children:"All categories"}),e.jsx(a,{value:"task",children:"Task"}),e.jsx(a,{value:"ticket",children:"Ticket"}),e.jsx(a,{value:"system",children:"System"}),e.jsx(a,{value:"agent",children:"Agent"}),e.jsx(a,{value:"chat",children:"Chat"}),e.jsx(a,{value:"cron",children:"Cron"})]})]}),e.jsxs(c,{variant:t?"default":"outline",size:"sm",onClick:()=>u(!t),className:"gap-2",children:[e.jsx(Q,{className:"h-4 w-4"}),"Unread only"]}),(r!=="all"||l!=="all"||t)&&e.jsx(c,{variant:"ghost",size:"sm",onClick:()=>{o("all"),n("all"),u(!1)},children:"Clear filters"})]}),M?e.jsx("div",{className:"space-y-3",children:Array.from({length:5}).map((s,R)=>e.jsx(f,{className:"glass rounded-2xl",children:e.jsx(j,{className:"p-4",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(g,{className:"h-8 w-8 rounded-xl"}),e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsx(g,{className:"h-4 w-48"}),e.jsx(g,{className:"h-3 w-32"})]})]})})},R))}):v.length>0?e.jsx("div",{className:"space-y-2",children:v.map(s=>e.jsx(f,{className:p("glass rounded-2xl overflow-hidden transition-all hover-lift",!s.read&&"border-primary/20"),children:e.jsx(j,{className:"p-4",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex items-start gap-3 flex-1 min-w-0",children:[e.jsx("div",{className:p("h-8 w-8 rounded-xl flex items-center justify-center flex-shrink-0",s.type==="success"&&"bg-green-500/10",s.type==="error"&&"bg-red-500/10",s.type==="warning"&&"bg-amber-500/10",s.type==="info"&&"bg-blue-500/10"),children:e.jsx(O,{type:s.type})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:p("text-sm font-medium truncate",!s.read&&"font-bold"),children:s.title}),!s.read&&e.jsx("span",{className:"h-2 w-2 rounded-full bg-primary flex-shrink-0"})]}),s.description&&e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5 line-clamp-2",children:s.description}),e.jsxs("div",{className:"flex items-center gap-2 mt-1.5",children:[e.jsx(L,{variant:"outline",className:"text-[10px] px-1.5 py-0",children:s.category}),e.jsx("span",{className:"text-[10px] text-muted-foreground",children:P(s.createdAt)})]})]})]}),e.jsxs("div",{className:"flex items-center gap-1 flex-shrink-0",children:[!s.read&&e.jsx(c,{variant:"ghost",size:"icon",className:"h-7 w-7 rounded-lg",onClick:()=>T.mutate(s.id),title:"Mark as read",children:e.jsx(A,{className:"h-3.5 w-3.5"})}),e.jsx(c,{variant:"ghost",size:"icon",className:"h-7 w-7 rounded-lg text-muted-foreground hover:text-destructive",onClick:()=>q.mutate(s.id),title:"Delete",children:e.jsx(U,{className:"h-3.5 w-3.5"})})]})]})})},s.id))}):e.jsx(f,{className:"glass rounded-2xl",children:e.jsxs(j,{className:"py-16 text-center",children:[e.jsx(B,{className:"h-12 w-12 mx-auto text-muted-foreground opacity-20 mb-4"}),e.jsx("h3",{className:"text-lg font-medium mb-1",children:"No notifications"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:r!=="all"||l!=="all"||t?"No notifications match your filters":"You're all caught up"})]})})]})}export{Z as ActivityView};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as o,j as e,M as r,B as d,k as i,S as x,i as c,g as m,V as h}from"./index
|
|
1
|
+
import{u as o,j as e,M as r,B as d,k as i,S as x,i as c,g as m,V as h}from"./index-lJlNPFVJ.js";import{S as u}from"./StatusIndicator-pRfkNcdV.js";import{C as p}from"./cpu-DiPMQICV.js";import{S as g}from"./shield-check-DfVdE34l.js";const j="http://localhost:3000";function f(){return o({queryKey:["agents"],queryFn:async()=>{const s=await fetch(`${j}/api/agents`);if(!s.ok)throw new Error("Failed to fetch agents");return(await s.json()).agents},refetchInterval:1e4})}function k(){const{data:s,isLoading:t,error:l}=f();return t?e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsxs("header",{children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight",children:"Agent Status"}),e.jsx("p",{className:"text-muted-foreground text-sm",children:"Monitor your active AI workforce."})]}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",children:[1,2,3].map(a=>e.jsx("div",{className:"h-48 rounded-2xl premium-card animate-pulse"},a))})]}):l?e.jsxs("div",{className:"premium-card rounded-2xl p-12 text-center",children:[e.jsx(r,{className:"h-12 w-12 mx-auto text-red-500 mb-4 opacity-50"}),e.jsx("h3",{className:"text-lg font-semibold",children:"Failed to load agents"}),e.jsx("p",{className:"text-muted-foreground text-sm",children:"Make sure the backend is running at http://localhost:3000"})]}):e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsxs("header",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight",children:"Agent Status"}),e.jsx("p",{className:"text-muted-foreground text-sm",children:"Monitor and manage your autonomous AI agents."})]}),e.jsxs("div",{className:"flex items-center gap-2 px-4 py-2 rounded-full premium-card border-primary/10",children:[e.jsx(r,{className:"h-4 w-4 text-primary"}),e.jsxs("span",{className:"text-xs font-bold uppercase tracking-wider",children:[s?.length||0," Agents Registered"]})]})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",children:[s?.map(a=>e.jsx(N,{agent:a},a.type)),s?.length===0&&e.jsxs("div",{className:"col-span-full glass-heavy rounded-[24px] p-12 text-center border-dashed border-2 border-white/5",children:[e.jsx(d,{className:"h-16 w-16 mx-auto text-muted-foreground mb-4 opacity-20"}),e.jsx("h3",{className:"text-xl font-bold",children:"No agents active"}),e.jsx("p",{className:"text-muted-foreground max-w-md mx-auto mb-6",children:"Connect an agent adapter like OpenClaw or Claude Code to start orchestrating tasks."}),e.jsx(i,{variant:"black",className:"px-6 h-10 rounded-full",onClick:()=>{},children:"Go to Settings"})]})]})]})}function N({agent:s}){const t=s.type==="openclaw"?x:s.type==="claude-code"?d:p;return e.jsxs("div",{className:"group relative premium-card rounded-2xl p-6 hover-lift transition-liquid overflow-hidden",children:[e.jsx("div",{className:c("absolute -top-12 -right-12 w-32 h-32 rounded-full blur-[60px] opacity-20 group-hover:opacity-40 transition-opacity",s.healthy.healthy?"bg-green-500":"bg-red-500")}),e.jsxs("div",{className:"flex items-start justify-between mb-8",children:[e.jsxs("div",{className:"flex gap-4",children:[e.jsx("div",{className:"h-12 w-12 rounded-xl glass-heavy flex items-center justify-center border-primary/10 shadow-lg",children:e.jsx(t,{className:"h-6 w-6 text-primary"})}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-base font-bold capitalize",children:s.name}),e.jsx("p",{className:"text-[10px] text-muted-foreground font-mono uppercase tracking-tight",children:s.type})]})]}),e.jsx(u,{status:s.healthy.healthy?"online":"error",size:"md"})]}),e.jsxs("div",{className:"space-y-4 mb-8",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(n,{label:"Success",value:s.stats.completed,className:"text-green-500/80"}),e.jsx(n,{label:"Failed",value:s.stats.failed,className:"text-red-500/80"})]}),e.jsxs("div",{className:"flex items-center justify-between px-1",children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-muted-foreground",children:[e.jsx(m,{className:"h-3.5 w-3.5"}),e.jsx("span",{className:"text-[11px] font-medium",children:"Avg duration:"})]}),e.jsxs("span",{className:"text-[11px] font-bold",children:[(s.stats.avgDuration/1e3).toFixed(1),"s"]})]}),e.jsxs("div",{className:"flex items-center justify-between px-1",children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-muted-foreground",children:[e.jsx(r,{className:"h-3.5 w-3.5"}),e.jsx("span",{className:"text-[11px] font-medium",children:"Latency:"})]}),e.jsxs("span",{className:"text-[11px] font-bold text-blue-400",children:[s.healthy.latencyMs,"ms"]})]})]}),e.jsxs("div",{className:"pt-4 border-t border-white/5 flex items-center justify-between",children:[e.jsxs("div",{className:"flex flex-col",children:[e.jsx("span",{className:"premium-label",children:"Last Active"}),e.jsx("span",{className:"text-[11px] font-medium leading-relaxed",children:s.lastActivity?new Date(s.lastActivity).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}):"Never"})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(i,{variant:"ghost",size:"icon",className:"h-8 w-8 rounded-lg",children:e.jsx(h,{className:"h-3.5 w-3.5 text-muted-foreground"})}),e.jsxs(i,{variant:"outline",size:"sm",className:"h-8 gap-2 rounded-lg",children:[e.jsx(g,{className:"h-3.5 w-3.5 text-blue-400"}),e.jsx("span",{className:"text-[10px] font-bold",children:"CONFIG"})]})]})]})]})}function n({label:s,value:t,className:l}){return e.jsxs("div",{className:"flex flex-col px-3 py-2 rounded-xl bg-primary/5 border border-primary/5",children:[e.jsx("span",{className:"premium-label",children:s}),e.jsx("span",{className:c("text-lg font-bold leading-tight",l),children:t})]})}export{k as AgentList};
|