nextclaw 0.9.9 → 0.9.11

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.
Files changed (31) hide show
  1. package/dist/cli/index.js +99 -81
  2. package/package.json +2 -2
  3. package/ui-dist/assets/ChannelsList-Dz8AGmaQ.js +1 -0
  4. package/ui-dist/assets/{ChatPage-Def8_fbf.js → ChatPage-BXDyt7BL.js} +21 -21
  5. package/ui-dist/assets/DocBrowser-CkKvzF7m.js +1 -0
  6. package/ui-dist/assets/{LogoBadge-uiBOKAEe.js → LogoBadge-C_ygxoGB.js} +1 -1
  7. package/ui-dist/assets/{MarketplacePage-BwMsA6VY.js → MarketplacePage-DEvRs-Jc.js} +2 -2
  8. package/ui-dist/assets/ModelConfig-BGfliN2Z.js +1 -0
  9. package/ui-dist/assets/ProvidersList-BHLGLSvs.js +1 -0
  10. package/ui-dist/assets/RuntimeConfig-Clltld_h.js +1 -0
  11. package/ui-dist/assets/{SecretsConfig-BLZW7-5k.js → SecretsConfig-CaJLf7oJ.js} +2 -2
  12. package/ui-dist/assets/SessionsConfig-3QF7K9wm.js +2 -0
  13. package/ui-dist/assets/{card-BoxPL3fs.js → card-DXo3NsaB.js} +1 -1
  14. package/ui-dist/assets/index-CGo5Vnh0.js +7 -0
  15. package/ui-dist/assets/input-CzTldMKo.js +1 -0
  16. package/ui-dist/assets/{label-BdIFsV9G.js → label-De__vsU7.js} +1 -1
  17. package/ui-dist/assets/{page-layout-BdhEwv_X.js → page-layout-BOgLC2tK.js} +1 -1
  18. package/ui-dist/assets/{session-run-status-DJ7s-TnE.js → session-run-status-DQVCDxTb.js} +2 -2
  19. package/ui-dist/assets/{switch-DD9iXp2E.js → switch-pMrS4heA.js} +1 -1
  20. package/ui-dist/assets/{tabs-custom-DPMQcAvE.js → tabs-custom-DhOxWfCb.js} +1 -1
  21. package/ui-dist/assets/{useConfirmDialog-D0WoeDcH.js → useConfirmDialog-CseKBGh5.js} +2 -2
  22. package/ui-dist/assets/{vendor-CzIVZvq9.js → vendor-D33xZtEC.js} +6 -6
  23. package/ui-dist/index.html +2 -2
  24. package/ui-dist/assets/ChannelsList-CrQ3OXby.js +0 -1
  25. package/ui-dist/assets/DocBrowser-Dg-b4Atq.js +0 -1
  26. package/ui-dist/assets/ModelConfig-DVsQVvIt.js +0 -1
  27. package/ui-dist/assets/ProvidersList-BSJGEhJe.js +0 -1
  28. package/ui-dist/assets/RuntimeConfig-CZpxTqCn.js +0 -1
  29. package/ui-dist/assets/SessionsConfig-H_gq5Wtk.js +0 -2
  30. package/ui-dist/assets/index-Cwtv_w6q.js +0 -2
  31. package/ui-dist/assets/useConfig-BiE7PGOv.js +0 -6
package/dist/cli/index.js CHANGED
@@ -2252,8 +2252,9 @@ import {
2252
2252
  stopPluginChannelGateways
2253
2253
  } from "@nextclaw/openclaw-compat";
2254
2254
  import { startUiServer } from "@nextclaw/server";
2255
- import { appendFileSync, closeSync, cpSync, existsSync as existsSync8, mkdirSync as mkdirSync4, openSync, rmSync as rmSync3 } from "fs";
2255
+ import { appendFileSync, closeSync, cpSync, existsSync as existsSync8, mkdirSync as mkdirSync4, mkdtempSync, openSync, rmSync as rmSync3 } from "fs";
2256
2256
  import { dirname, isAbsolute as isAbsolute2, join as join5, relative, resolve as resolve7 } from "path";
2257
+ import { tmpdir } from "os";
2257
2258
  import { spawn as spawn2 } from "child_process";
2258
2259
  import { request as httpRequest } from "http";
2259
2260
  import { request as httpsRequest } from "https";
@@ -4226,6 +4227,7 @@ var ServiceCommands = class {
4226
4227
  host: uiConfig.host,
4227
4228
  port: uiConfig.port,
4228
4229
  configPath: getConfigPath3(),
4230
+ productVersion: getPackageVersion(),
4229
4231
  staticDir: uiStaticDir ?? void 0,
4230
4232
  cronService,
4231
4233
  marketplace: {
@@ -4366,54 +4368,107 @@ var ServiceCommands = class {
4366
4368
  if (existsSync8(destination) && params.force) {
4367
4369
  rmSync3(destination, { recursive: true, force: true });
4368
4370
  }
4369
- const skildArgs = ["--yes", "skild", "install", source, "--target", "agents", "--local", "--json", "--skill", skillName];
4370
- if (params.registry) {
4371
- skildArgs.push("--registry", params.registry);
4371
+ const materialized = await this.materializeMarketplaceGitSkillSource({ source, skillName });
4372
+ try {
4373
+ const installSkillFile = join5(materialized.skillDir, "SKILL.md");
4374
+ if (!existsSync8(installSkillFile)) {
4375
+ throw new Error(`git skill source does not contain SKILL.md for ${skillName}`);
4376
+ }
4377
+ mkdirSync4(dirname(destination), { recursive: true });
4378
+ cpSync(materialized.skillDir, destination, { recursive: true, force: true });
4379
+ return {
4380
+ message: `Installed skill: ${skillName}`,
4381
+ output: [
4382
+ `Source: ${source}`,
4383
+ `Materialized skill: ${materialized.skillDir}`,
4384
+ `Workspace target: ${destination}`,
4385
+ materialized.commandOutput
4386
+ ].filter(Boolean).join("\n")
4387
+ };
4388
+ } finally {
4389
+ rmSync3(materialized.tempRoot, { recursive: true, force: true });
4372
4390
  }
4373
- if (params.force) {
4374
- skildArgs.push("--force");
4391
+ }
4392
+ async materializeMarketplaceGitSkillSource(params) {
4393
+ const parsed = this.parseMarketplaceGitSkillSource(params.source);
4394
+ const gitPath = findExecutableOnPath("git");
4395
+ if (!gitPath) {
4396
+ throw new Error("git is required to install marketplace git skills");
4375
4397
  }
4376
- let result = await this.runCommandWithFallback(
4377
- ["npx", "/opt/homebrew/bin/npx", "/usr/local/bin/npx"],
4378
- skildArgs,
4379
- {
4380
- cwd: workspace,
4381
- timeoutMs: 18e4
4398
+ const tempRoot = mkdtempSync(join5(tmpdir(), "nextclaw-marketplace-skill-"));
4399
+ const repoDir = join5(tempRoot, "repo");
4400
+ try {
4401
+ const cloneArgs = ["clone", "--depth", "1", "--filter=blob:none", "--sparse"];
4402
+ if (parsed.ref) {
4403
+ cloneArgs.push("--branch", parsed.ref);
4382
4404
  }
4383
- );
4384
- let payload = this.parseSkildJsonOutput(result.stdout);
4385
- if (!payload) {
4386
- const forceArgs = skildArgs.includes("--force") ? skildArgs : [...skildArgs, "--force"];
4387
- result = await this.runCommandWithFallback(
4388
- ["npx", "/opt/homebrew/bin/npx", "/usr/local/bin/npx"],
4389
- forceArgs,
4390
- {
4391
- cwd: workspace,
4392
- timeoutMs: 18e4
4393
- }
4394
- );
4395
- payload = this.parseSkildJsonOutput(result.stdout);
4405
+ cloneArgs.push(parsed.repoUrl, repoDir);
4406
+ const cloneResult = await this.runCommand(gitPath, cloneArgs, {
4407
+ cwd: tempRoot,
4408
+ timeoutMs: 18e4
4409
+ });
4410
+ const sparseResult = await this.runCommand(gitPath, ["-C", repoDir, "sparse-checkout", "set", parsed.skillPath], {
4411
+ cwd: tempRoot,
4412
+ timeoutMs: 6e4
4413
+ });
4414
+ const skillDir = join5(repoDir, parsed.skillPath);
4415
+ return {
4416
+ tempRoot,
4417
+ skillDir,
4418
+ commandOutput: [
4419
+ `Git repository: ${parsed.repoUrl}`,
4420
+ `Git path: ${parsed.skillPath}`,
4421
+ this.mergeCommandOutput(cloneResult.stdout, cloneResult.stderr),
4422
+ this.mergeCommandOutput(sparseResult.stdout, sparseResult.stderr)
4423
+ ].filter(Boolean).join("\n")
4424
+ };
4425
+ } catch (error) {
4426
+ rmSync3(tempRoot, { recursive: true, force: true });
4427
+ throw error;
4428
+ }
4429
+ }
4430
+ parseMarketplaceGitSkillSource(source) {
4431
+ const trimmed = source.trim();
4432
+ if (!trimmed) {
4433
+ throw new Error("Git skill source is required");
4396
4434
  }
4397
- if (!payload) {
4398
- throw new Error("skild returned null json payload even after force reinstall");
4435
+ if (trimmed.includes("://")) {
4436
+ const parsedUrl = new URL(trimmed);
4437
+ if (parsedUrl.hostname !== "github.com") {
4438
+ throw new Error(`Unsupported git skill source host: ${parsedUrl.hostname}`);
4439
+ }
4440
+ const parts2 = parsedUrl.pathname.split("/").filter(Boolean);
4441
+ if (parts2.length < 5 || parts2[2] !== "tree" && parts2[2] !== "blob") {
4442
+ throw new Error(`Unsupported GitHub skill source URL: ${source}`);
4443
+ }
4444
+ const [owner2, repoRaw, , ref2, ...pathParts2] = parts2;
4445
+ const repo2 = repoRaw.replace(/\.git$/i, "");
4446
+ if (!owner2 || !repo2 || !ref2 || pathParts2.length === 0) {
4447
+ throw new Error(`Unsupported GitHub skill source URL: ${source}`);
4448
+ }
4449
+ return {
4450
+ repoUrl: `https://github.com/${owner2}/${repo2}.git`,
4451
+ skillPath: pathParts2.join("/"),
4452
+ ref: ref2
4453
+ };
4399
4454
  }
4400
- const installDir = typeof payload.installDir === "string" ? payload.installDir.trim() : "";
4401
- const installSkillFile = installDir ? join5(installDir, "SKILL.md") : "";
4402
- if (!installDir || !existsSync8(installSkillFile)) {
4403
- throw new Error(`skild install did not produce a valid skill directory for ${skillName}`);
4455
+ const parts = trimmed.split("/").filter(Boolean);
4456
+ if (parts.length < 3) {
4457
+ throw new Error(`Unsupported git skill source: ${source}`);
4404
4458
  }
4405
- mkdirSync4(dirname(destination), { recursive: true });
4406
- if (resolve7(installDir) !== resolve7(destination)) {
4407
- cpSync(installDir, destination, { recursive: true, force: true });
4459
+ const owner = parts[0] ?? "";
4460
+ const repoWithOptionalRef = parts[1] ?? "";
4461
+ const pathParts = parts.slice(2);
4462
+ const atIndex = repoWithOptionalRef.indexOf("@");
4463
+ const repo = (atIndex >= 0 ? repoWithOptionalRef.slice(0, atIndex) : repoWithOptionalRef).replace(/\.git$/i, "");
4464
+ const ref = atIndex >= 0 ? repoWithOptionalRef.slice(atIndex + 1) : void 0;
4465
+ if (!owner || !repo || pathParts.length === 0) {
4466
+ throw new Error(`Unsupported git skill source: ${source}`);
4408
4467
  }
4409
4468
  return {
4410
- message: `Installed skill: ${skillName}`,
4411
- output: [
4412
- `Source: ${source}`,
4413
- `Installed via skild: ${installDir}`,
4414
- `Workspace target: ${destination}`,
4415
- this.mergeCommandOutput(result.stdout, result.stderr)
4416
- ].filter(Boolean).join("\n")
4469
+ repoUrl: `https://github.com/${owner}/${repo}.git`,
4470
+ skillPath: pathParts.join("/"),
4471
+ ref: ref && ref.trim().length > 0 ? ref.trim() : void 0
4417
4472
  };
4418
4473
  }
4419
4474
  async enableMarketplacePlugin(id) {
@@ -4434,17 +4489,13 @@ var ServiceCommands = class {
4434
4489
  async uninstallMarketplaceSkill(slug) {
4435
4490
  const workspace = getWorkspacePath5(loadConfig6().agents.defaults.workspace);
4436
4491
  const targetDir = join5(workspace, "skills", slug);
4437
- const skildDir = join5(workspace, ".agents", "skills", slug);
4438
- const existingTargets = [targetDir, skildDir].filter((path) => existsSync8(path));
4439
- if (existingTargets.length === 0) {
4492
+ if (!existsSync8(targetDir)) {
4440
4493
  throw new Error(`Skill not installed in workspace: ${slug}`);
4441
4494
  }
4442
- for (const path of existingTargets) {
4443
- rmSync3(path, { recursive: true, force: true });
4444
- }
4495
+ rmSync3(targetDir, { recursive: true, force: true });
4445
4496
  return {
4446
4497
  message: `Uninstalled skill: ${slug}`,
4447
- output: existingTargets.map((path) => `Removed ${path}`).join("\n")
4498
+ output: `Removed ${targetDir}`
4448
4499
  };
4449
4500
  }
4450
4501
  installBuiltinMarketplaceSkill(slug, force) {
@@ -4506,39 +4557,6 @@ var ServiceCommands = class {
4506
4557
  }
4507
4558
  return destination;
4508
4559
  }
4509
- parseSkildJsonOutput(stdout) {
4510
- const trimmed = stdout.trim();
4511
- if (!trimmed) {
4512
- throw new Error("skild returned empty output");
4513
- }
4514
- const maybeJson = (() => {
4515
- const start = trimmed.indexOf("{");
4516
- const end = trimmed.lastIndexOf("}");
4517
- if (start >= 0 && end > start) {
4518
- return trimmed.slice(start, end + 1);
4519
- }
4520
- return trimmed;
4521
- })();
4522
- try {
4523
- const parsed = JSON.parse(maybeJson);
4524
- if (parsed === null) {
4525
- return null;
4526
- }
4527
- if (Array.isArray(parsed)) {
4528
- const firstObject = parsed.find((item) => item && typeof item === "object" && !Array.isArray(item));
4529
- if (firstObject) {
4530
- return firstObject;
4531
- }
4532
- throw new Error("skild json output array does not contain an object");
4533
- }
4534
- if (typeof parsed !== "object") {
4535
- throw new Error("skild json output is not an object");
4536
- }
4537
- return parsed;
4538
- } catch (error) {
4539
- throw new Error(`failed to parse skild --json output: ${String(error)}`);
4540
- }
4541
- }
4542
4560
  mergeCommandOutput(stdout, stderr) {
4543
4561
  return `${stdout}
4544
4562
  ${stderr}`.trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nextclaw",
3
- "version": "0.9.9",
3
+ "version": "0.9.11",
4
4
  "description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -40,7 +40,7 @@
40
40
  "commander": "^12.1.0",
41
41
  "@nextclaw/core": "^0.7.1",
42
42
  "@nextclaw/runtime": "^0.1.1",
43
- "@nextclaw/server": "^0.6.3",
43
+ "@nextclaw/server": "^0.6.4",
44
44
  "@nextclaw/openclaw-compat": "^0.2.0"
45
45
  },
46
46
  "devDependencies": {
@@ -0,0 +1 @@
1
+ import{r as v,j as a,ax as Z,z as ee,d as T,K as ae,a9 as te,aL as se,aM as ne,aN as le,w as re,a1 as oe,aw as ce,q as ie}from"./vendor-D33xZtEC.js";import{t as e,c as I,H as me,u as q,a as $,b as H,J as pe,K as de,S as be,e as ue,f as xe,g as ye,h as ge}from"./index-CGo5Vnh0.js";import{B as E,P as he,a as fe}from"./page-layout-BOgLC2tK.js";import{I as D}from"./input-CzTldMKo.js";import{L as we}from"./label-De__vsU7.js";import{S as ve}from"./switch-pMrS4heA.js";import{C as je,a as ke,L as K,S as J,c as Se,b as Ce}from"./LogoBadge-C_ygxoGB.js";import{h as _}from"./config-hints-CApS3K_7.js";import{T as Ne}from"./tabs-custom-DhOxWfCb.js";function Pe({value:t,onChange:m,className:i,placeholder:r=""}){const[o,u]=v.useState(""),d=x=>{x.key==="Enter"&&o.trim()?(x.preventDefault(),m([...t,o.trim()]),u("")):x.key==="Backspace"&&!o&&t.length>0&&m(t.slice(0,-1))},g=x=>{m(t.filter((j,h)=>h!==x))};return a.jsxs("div",{className:I("flex flex-wrap gap-2 p-2 border rounded-md min-h-[42px]",i),children:[t.map((x,j)=>a.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-1 bg-primary text-primary-foreground rounded text-sm",children:[x,a.jsx("button",{type:"button",onClick:()=>g(j),className:"hover:text-red-300 transition-colors",children:a.jsx(Z,{className:"h-3 w-3"})})]},j)),a.jsx("input",{type:"text",value:o,onChange:x=>u(x.target.value),onKeyDown:d,className:"flex-1 outline-none min-w-[100px] bg-transparent text-sm",placeholder:r||e("enterTag")})]})}function z(t){var r,o;const m=me();return((r=t.tutorialUrls)==null?void 0:r[m])||((o=t.tutorialUrls)==null?void 0:o.default)||t.tutorialUrl}const Ie={telegram:"telegram.svg",slack:"slack.svg",discord:"discord.svg",whatsapp:"whatsapp.svg",qq:"qq.svg",feishu:"feishu.svg",dingtalk:"dingtalk.svg",wecom:"wecom.svg",mochat:"mochat.svg",email:"email.svg"};function Fe(t,m){const i=m.toLowerCase(),r=t[i];return r?`/logos/${r}`:null}function Y(t){return Fe(Ie,t)}const B=[{value:"pairing",label:"pairing"},{value:"allowlist",label:"allowlist"},{value:"open",label:"open"},{value:"disabled",label:"disabled"}],R=[{value:"open",label:"open"},{value:"allowlist",label:"allowlist"},{value:"disabled",label:"disabled"}],Te=[{value:"off",label:"off"},{value:"partial",label:"partial"},{value:"block",label:"block"},{value:"progress",label:"progress"}],De=t=>t.includes("token")||t.includes("secret")||t.includes("password")?a.jsx(ae,{className:"h-3.5 w-3.5 text-gray-500"}):t.includes("url")||t.includes("host")?a.jsx(te,{className:"h-3.5 w-3.5 text-gray-500"}):t.includes("email")||t.includes("mail")?a.jsx(se,{className:"h-3.5 w-3.5 text-gray-500"}):t.includes("id")||t.includes("from")?a.jsx(ne,{className:"h-3.5 w-3.5 text-gray-500"}):t==="enabled"||t==="consentGranted"?a.jsx(le,{className:"h-3.5 w-3.5 text-gray-500"}):a.jsx(re,{className:"h-3.5 w-3.5 text-gray-500"});function G(){return{telegram:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"token",type:"password",label:e("botToken")},{name:"allowFrom",type:"tags",label:e("allowFrom")},{name:"proxy",type:"text",label:e("proxy")},{name:"accountId",type:"text",label:e("accountId")},{name:"dmPolicy",type:"select",label:e("dmPolicy"),options:B},{name:"groupPolicy",type:"select",label:e("groupPolicy"),options:R},{name:"groupAllowFrom",type:"tags",label:e("groupAllowFrom")},{name:"requireMention",type:"boolean",label:e("requireMention")},{name:"mentionPatterns",type:"tags",label:e("mentionPatterns")},{name:"groups",type:"json",label:e("groupRulesJson")}],discord:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"token",type:"password",label:e("botToken")},{name:"allowBots",type:"boolean",label:e("allowBotMessages")},{name:"allowFrom",type:"tags",label:e("allowFrom")},{name:"gatewayUrl",type:"text",label:e("gatewayUrl")},{name:"intents",type:"number",label:e("intents")},{name:"proxy",type:"text",label:e("proxy")},{name:"mediaMaxMb",type:"number",label:e("attachmentMaxSizeMb")},{name:"streaming",type:"select",label:e("streamingMode"),options:Te},{name:"draftChunk",type:"json",label:e("draftChunkingJson")},{name:"textChunkLimit",type:"number",label:e("textChunkLimit")},{name:"accountId",type:"text",label:e("accountId")},{name:"dmPolicy",type:"select",label:e("dmPolicy"),options:B},{name:"groupPolicy",type:"select",label:e("groupPolicy"),options:R},{name:"groupAllowFrom",type:"tags",label:e("groupAllowFrom")},{name:"requireMention",type:"boolean",label:e("requireMention")},{name:"mentionPatterns",type:"tags",label:e("mentionPatterns")},{name:"groups",type:"json",label:e("groupRulesJson")}],whatsapp:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"bridgeUrl",type:"text",label:e("bridgeUrl")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],feishu:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"appId",type:"text",label:e("appId")},{name:"appSecret",type:"password",label:e("appSecret")},{name:"encryptKey",type:"password",label:e("encryptKey")},{name:"verificationToken",type:"password",label:e("verificationToken")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],dingtalk:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"clientId",type:"text",label:e("clientId")},{name:"clientSecret",type:"password",label:e("clientSecret")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],wecom:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"corpId",type:"text",label:e("corpId")},{name:"agentId",type:"text",label:e("agentId")},{name:"secret",type:"password",label:e("secret")},{name:"token",type:"password",label:e("token")},{name:"callbackPort",type:"number",label:e("callbackPort")},{name:"callbackPath",type:"text",label:e("callbackPath")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],slack:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"mode",type:"text",label:e("mode")},{name:"webhookPath",type:"text",label:e("webhookPath")},{name:"allowBots",type:"boolean",label:e("allowBotMessages")},{name:"botToken",type:"password",label:e("botToken")},{name:"appToken",type:"password",label:e("appToken")}],email:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"consentGranted",type:"boolean",label:e("consentGranted")},{name:"imapHost",type:"text",label:e("imapHost")},{name:"imapPort",type:"number",label:e("imapPort")},{name:"imapUsername",type:"text",label:e("imapUsername")},{name:"imapPassword",type:"password",label:e("imapPassword")},{name:"fromAddress",type:"email",label:e("fromAddress")}],mochat:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"baseUrl",type:"text",label:e("baseUrl")},{name:"clawToken",type:"password",label:e("clawToken")},{name:"agentUserId",type:"text",label:e("agentUserId")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],qq:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"appId",type:"text",label:e("appId")},{name:"secret",type:"password",label:e("appSecret")},{name:"markdownSupport",type:"boolean",label:e("markdownSupport")},{name:"allowFrom",type:"tags",label:e("allowFrom")}]}}function A(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function V(t,m){const i={...t};for(const[r,o]of Object.entries(m)){const u=i[r];if(A(u)&&A(o)){i[r]=V(u,o);continue}i[r]=o}return i}function Ae(t,m){const i=t.split("."),r={};let o=r;for(let u=0;u<i.length-1;u+=1){const d=i[u];o[d]={},o=o[d]}return o[i[i.length-1]]=m,r}function Le({channelName:t}){var O,U;const{data:m}=q(),{data:i}=$(),{data:r}=H(),o=pe(),u=de(),[d,g]=v.useState({}),[x,j]=v.useState({}),[h,f]=v.useState(null),k=t?m==null?void 0:m.channels[t]:null,w=t?G()[t]??[]:[],c=r==null?void 0:r.uiHints,p=t?`channels.${t}`:null,S=((O=r==null?void 0:r.actions)==null?void 0:O.filter(s=>s.scope===p))??[],C=t&&(((U=_(`channels.${t}`,c))==null?void 0:U.label)??t),P=i==null?void 0:i.channels.find(s=>s.name===t),F=P?z(P):void 0;v.useEffect(()=>{if(k){g({...k});const s={};(t?G()[t]??[]:[]).filter(l=>l.type==="json").forEach(l=>{const y=k[l.name];s[l.name]=JSON.stringify(y??{},null,2)}),j(s)}else g({}),j({})},[k,t]);const N=(s,n)=>{g(l=>({...l,[s]:n}))},L=s=>{if(s.preventDefault(),!t)return;const n={...d};for(const l of w){if(l.type!=="password")continue;const y=n[l.name];(typeof y!="string"||y.length===0)&&delete n[l.name]}for(const l of w){if(l.type!=="json")continue;const y=x[l.name]??"";try{n[l.name]=y.trim()?JSON.parse(y):{}}catch{T.error(`${e("invalidJson")}: ${l.name}`);return}}o.mutate({channel:t,data:n})},Q=s=>{if(!s||!t)return;const n=s.channels;if(!A(n))return;const l=n[t];A(l)&&g(y=>V(y,l))},W=async s=>{if(!(!t||!p)){f(s.id);try{let n={...d};s.saveBeforeRun&&(n={...n,...s.savePatch??{}},g(n),await o.mutateAsync({channel:t,data:n}));const l=await u.mutateAsync({actionId:s.id,data:{scope:p,draftConfig:Ae(p,n)}});Q(l.patch),l.ok?T.success(l.message||e("success")):T.error(l.message||e("error"))}catch(n){const l=n instanceof Error?n.message:String(n);T.error(`${e("error")}: ${l}`)}finally{f(null)}}};if(!t||!P||!k)return a.jsx("div",{className:je,children:a.jsxs("div",{children:[a.jsx("h3",{className:"text-base font-semibold text-gray-900",children:e("channelsSelectTitle")}),a.jsx("p",{className:"mt-2 text-sm text-gray-500",children:e("channelsSelectDescription")})]})});const M=!!k.enabled;return a.jsxs("div",{className:ke,children:[a.jsx("div",{className:"border-b border-gray-100 px-6 py-5",children:a.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[a.jsxs("div",{className:"min-w-0",children:[a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsx(K,{name:t,src:Y(t),className:I("h-9 w-9 rounded-lg border",M?"border-primary/30 bg-white":"border-gray-200/70 bg-white"),imgClassName:"h-5 w-5 object-contain",fallback:a.jsx("span",{className:"text-sm font-semibold uppercase text-gray-500",children:t[0]})}),a.jsx("h3",{className:"truncate text-lg font-semibold text-gray-900 capitalize",children:C})]}),a.jsx("p",{className:"mt-2 text-sm text-gray-500",children:e("channelsFormDescription")}),F&&a.jsxs("a",{href:F,className:"mt-2 inline-flex items-center gap-1.5 text-xs text-primary transition-colors hover:text-primary-hover",children:[a.jsx(ee,{className:"h-3.5 w-3.5"}),e("channelsGuideTitle")]})]}),a.jsx(J,{status:M?"active":"inactive",label:M?e("statusActive"):e("statusInactive")})]})}),a.jsxs("form",{onSubmit:L,className:"flex min-h-0 flex-1 flex-col",children:[a.jsx("div",{className:"min-h-0 flex-1 space-y-6 overflow-y-auto overscroll-contain px-6 py-5",children:w.map(s=>{const n=t?_(`channels.${t}.${s.name}`,c):void 0,l=(n==null?void 0:n.label)??s.label,y=n==null?void 0:n.placeholder;return a.jsxs("div",{className:"space-y-2.5",children:[a.jsxs(we,{htmlFor:s.name,className:"flex items-center gap-2 text-sm font-medium text-gray-900",children:[De(s.name),l]}),s.type==="boolean"&&a.jsxs("div",{className:"flex items-center justify-between rounded-xl bg-gray-50 p-3",children:[a.jsx("span",{className:"text-sm text-gray-500",children:d[s.name]?e("enabled"):e("disabled")}),a.jsx(ve,{id:s.name,checked:d[s.name]||!1,onCheckedChange:b=>N(s.name,b),className:"data-[state=checked]:bg-emerald-500"})]}),(s.type==="text"||s.type==="email")&&a.jsx(D,{id:s.name,type:s.type,value:d[s.name]||"",onChange:b=>N(s.name,b.target.value),placeholder:y,className:"rounded-xl"}),s.type==="password"&&a.jsx(D,{id:s.name,type:"password",value:d[s.name]||"",onChange:b=>N(s.name,b.target.value),placeholder:y??e("leaveBlankToKeepUnchanged"),className:"rounded-xl"}),s.type==="number"&&a.jsx(D,{id:s.name,type:"number",value:d[s.name]||0,onChange:b=>N(s.name,parseInt(b.target.value,10)||0),placeholder:y,className:"rounded-xl"}),s.type==="tags"&&a.jsx(Pe,{value:d[s.name]||[],onChange:b=>N(s.name,b)}),s.type==="select"&&a.jsxs(be,{value:d[s.name]||"",onValueChange:b=>N(s.name,b),children:[a.jsx(ue,{className:"rounded-xl",children:a.jsx(xe,{})}),a.jsx(ye,{children:(s.options??[]).map(b=>a.jsx(ge,{value:b.value,children:b.label},b.value))})]}),s.type==="json"&&a.jsx("textarea",{id:s.name,value:x[s.name]??"{}",onChange:b=>j(X=>({...X,[s.name]:b.target.value})),className:"min-h-[120px] w-full resize-none rounded-lg border border-gray-200 bg-white px-3 py-2 text-xs font-mono"})]},s.name)})}),a.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 border-t border-gray-100 px-6 py-4",children:[a.jsx("div",{className:"flex flex-wrap items-center gap-2",children:S.filter(s=>s.trigger==="manual").map(s=>a.jsx(E,{type:"button",onClick:()=>W(s),disabled:o.isPending||!!h,variant:"secondary",children:h===s.id?e("connecting"):s.title},s.id))}),a.jsx(E,{type:"submit",disabled:o.isPending||!!h,children:o.isPending?e("saving"):e("save")})]})]})]})}const Me={telegram:"channelDescTelegram",slack:"channelDescSlack",email:"channelDescEmail",webhook:"channelDescWebhook",discord:"channelDescDiscord",feishu:"channelDescFeishu"};function He(){const{data:t}=q(),{data:m}=$(),{data:i}=H(),[r,o]=v.useState("enabled"),[u,d]=v.useState(),[g,x]=v.useState(""),j=i==null?void 0:i.uiHints,h=m==null?void 0:m.channels,f=t==null?void 0:t.channels,k=[{id:"enabled",label:e("channelsTabEnabled"),count:(h??[]).filter(c=>{var p;return(p=f==null?void 0:f[c.name])==null?void 0:p.enabled}).length},{id:"all",label:e("channelsTabAll"),count:(h??[]).length}],w=v.useMemo(()=>{const c=g.trim().toLowerCase();return(h??[]).filter(p=>{var C;const S=((C=f==null?void 0:f[p.name])==null?void 0:C.enabled)||!1;return r==="enabled"?S:!0}).filter(p=>c?(p.displayName||p.name).toLowerCase().includes(c)||p.name.toLowerCase().includes(c):!0)},[r,f,h,g]);return v.useEffect(()=>{if(w.length===0){d(void 0);return}w.some(p=>p.name===u)||d(w[0].name)},[w,u]),!t||!m?a.jsx("div",{className:"p-8 text-gray-400",children:e("channelsLoading")}):a.jsxs(he,{className:"xl:flex xl:h-full xl:min-h-0 xl:flex-col xl:pb-0",children:[a.jsx(fe,{title:e("channelsPageTitle"),description:e("channelsPageDescription")}),a.jsxs("div",{className:I(Ce,"xl:min-h-0 xl:flex-1"),children:[a.jsxs("section",{className:Se,children:[a.jsx("div",{className:"border-b border-gray-100 px-4 pt-4",children:a.jsx(Ne,{tabs:k,activeTab:r,onChange:o,className:"mb-0"})}),a.jsx("div",{className:"border-b border-gray-100 px-4 py-3",children:a.jsxs("div",{className:"relative",children:[a.jsx(oe,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400"}),a.jsx(D,{value:g,onChange:c=>x(c.target.value),placeholder:e("channelsFilterPlaceholder"),className:"h-10 rounded-xl pl-9"})]})}),a.jsxs("div",{className:"min-h-0 flex-1 space-y-2 overflow-y-auto overscroll-contain p-3",children:[w.map(c=>{const p=t.channels[c.name],S=(p==null?void 0:p.enabled)||!1,C=_(`channels.${c.name}`,j),P=z(c),F=(C==null?void 0:C.help)||e(Me[c.name]||"channelDescriptionDefault"),N=u===c.name;return a.jsx("button",{type:"button",onClick:()=>d(c.name),className:I("w-full rounded-xl border p-2.5 text-left transition-all",N?"border-primary/30 bg-primary-50/40 shadow-sm":"border-gray-200/70 bg-white hover:border-gray-300 hover:bg-gray-50/70"),children:a.jsxs("div",{className:"flex items-start justify-between gap-3",children:[a.jsxs("div",{className:"flex min-w-0 items-center gap-3",children:[a.jsx(K,{name:c.name,src:Y(c.name),className:I("h-10 w-10 rounded-lg border",S?"border-primary/30 bg-white":"border-gray-200/70 bg-white"),imgClassName:"h-5 w-5 object-contain",fallback:a.jsx("span",{className:"text-sm font-semibold uppercase text-gray-500",children:c.name[0]})}),a.jsxs("div",{className:"min-w-0",children:[a.jsx("p",{className:"truncate text-sm font-semibold text-gray-900",children:c.displayName||c.name}),a.jsx("p",{className:"line-clamp-1 text-[11px] text-gray-500",children:F})]})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[P&&a.jsx("a",{href:P,onClick:L=>L.stopPropagation(),className:"inline-flex h-7 w-7 items-center justify-center rounded-md text-gray-300 transition-colors hover:bg-gray-100/70 hover:text-gray-500",title:e("channelsGuideTitle"),children:a.jsx(ce,{className:"h-3.5 w-3.5"})}),a.jsx(J,{status:S?"active":"inactive",label:S?e("statusActive"):e("statusInactive"),className:"min-w-[56px] justify-center"})]})]})},c.name)}),w.length===0&&a.jsxs("div",{className:"flex h-full min-h-[220px] flex-col items-center justify-center rounded-xl border border-dashed border-gray-200 bg-gray-50/70 py-10 text-center",children:[a.jsx("div",{className:"mb-3 flex h-10 w-10 items-center justify-center rounded-lg bg-white",children:a.jsx(ie,{className:"h-5 w-5 text-gray-300"})}),a.jsx("p",{className:"text-sm font-medium text-gray-700",children:e("channelsNoMatch")})]})]})]}),a.jsx(Le,{channelName:u})]})]})}export{He as ChannelsList};