cli-jaw 2.17.14 → 2.17.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/agent/codex-app-events.js +6 -1
- package/dist/src/agent/codex-app-events.js.map +1 -1
- package/dist/src/agent/error-classifier.js +22 -4
- package/dist/src/agent/error-classifier.js.map +1 -1
- package/dist/src/agent/events/codex.js +14 -1
- package/dist/src/agent/events/codex.js.map +1 -1
- package/dist/src/agent/events/cursor.js +16 -0
- package/dist/src/agent/events/cursor.js.map +1 -1
- package/dist/src/agent/events/index.js +6 -0
- package/dist/src/agent/events/index.js.map +1 -1
- package/dist/src/agent/lifecycle-handler.js +9 -3
- package/dist/src/agent/lifecycle-handler.js.map +1 -1
- package/dist/src/agent/spawn-env.js +13 -0
- package/dist/src/agent/spawn-env.js.map +1 -1
- package/dist/src/discord/bot.js +147 -20
- package/dist/src/discord/bot.js.map +1 -1
- package/dist/src/discord/discord-file.js +7 -0
- package/dist/src/discord/discord-file.js.map +1 -1
- package/dist/src/discord/forwarder.js +4 -2
- package/dist/src/discord/forwarder.js.map +1 -1
- package/dist/src/discord/send-only-client.js +21 -1
- package/dist/src/discord/send-only-client.js.map +1 -1
- package/dist/src/messaging/outbound-lifecycle.js +106 -0
- package/dist/src/messaging/outbound-lifecycle.js.map +1 -0
- package/dist/src/slack/api.js +7 -0
- package/dist/src/slack/api.js.map +1 -1
- package/dist/src/slack/bot.js +114 -25
- package/dist/src/slack/bot.js.map +1 -1
- package/dist/src/slack/forwarder.js +4 -2
- package/dist/src/slack/forwarder.js.map +1 -1
- package/dist/src/slack/send-only-client.js +27 -3
- package/dist/src/slack/send-only-client.js.map +1 -1
- package/dist/src/slack/slack-file.js +11 -3
- package/dist/src/slack/slack-file.js.map +1 -1
- package/dist/src/telegram/bot.js +69 -8
- package/dist/src/telegram/bot.js.map +1 -1
- package/dist/src/telegram/forwarder.js +4 -2
- package/dist/src/telegram/forwarder.js.map +1 -1
- package/dist/src/telegram/rich-message.js +20 -5
- package/dist/src/telegram/rich-message.js.map +1 -1
- package/dist/src/telegram/telegram-file.js +9 -4
- package/dist/src/telegram/telegram-file.js.map +1 -1
- package/package.json +3 -1
- package/public/dist/assets/ChannelsSlack-U0_Sfkz0.js +1 -0
- package/public/dist/assets/{manager-CBSvWXYT.js → manager-C_EnQ0Fc.js} +1 -1
- package/public/dist/manager/index.html +1 -1
- package/public/locales/en.json +1 -1
- package/public/locales/ja.json +1 -1
- package/public/locales/ko.json +1 -1
- package/public/locales/zh.json +1 -1
- package/public/manager/src/settings/pages/ChannelsSlack.tsx +20 -0
- package/scripts/check-path-length.mjs +98 -0
- package/scripts/release-gates.mjs +17 -0
- package/public/dist/assets/ChannelsSlack-BOuoCfeN.js +0 -1
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<link rel="icon" type="image/png" href="/dist/assets/icon-192-CwXPIYF5.png">
|
|
7
7
|
<title>Jaw Manager</title>
|
|
8
8
|
<script src="/manager/theme-boot.js"></script>
|
|
9
|
-
<script type="module" crossorigin src="/dist/assets/manager-
|
|
9
|
+
<script type="module" crossorigin src="/dist/assets/manager-C_EnQ0Fc.js"></script>
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/dist/assets/vendor-render-Bjnw0wQ6.css">
|
|
11
11
|
<link rel="stylesheet" crossorigin href="/dist/assets/manager-LkGs6qEJ.css">
|
|
12
12
|
</head>
|
package/public/locales/en.json
CHANGED
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"sl.settingsUnsupported": "Settings changes are not supported on Slack.",
|
|
156
156
|
"cmd.runtimeSelectionInstanceWide": "The CLI and model are shared by every session on this instance. Change them from the instance web settings.",
|
|
157
157
|
"tg.promptUnsupported": "(Not supported on Telegram)",
|
|
158
|
-
"tg.queued": "Added to queue (#{count})",
|
|
158
|
+
"tg.queued": "⏳ Added to queue (#{count})",
|
|
159
159
|
"tg.queueExpired": "The queued turn timed out",
|
|
160
160
|
"tg.imageCaption": "[📷 Image] {caption}",
|
|
161
161
|
"tg.imageFail": "Image processing failed: {msg}",
|
package/public/locales/ja.json
CHANGED
|
@@ -153,7 +153,7 @@
|
|
|
153
153
|
"sl.settingsUnsupported": "Slack では設定変更に対応していません。",
|
|
154
154
|
"cmd.runtimeSelectionInstanceWide": "CLI とモデルの選択はこのインスタンスの全セッションで共有されます。インスタンスのウェブ設定から変更してください。",
|
|
155
155
|
"tg.promptUnsupported": "(Telegram では未対応)",
|
|
156
|
-
"tg.queued": "キューに追加しました(#{count})",
|
|
156
|
+
"tg.queued": "⏳ キューに追加しました(#{count})",
|
|
157
157
|
"tg.queueExpired": "キューの待機時間が超過しました",
|
|
158
158
|
"tg.imageCaption": "[📷 画像] {caption}",
|
|
159
159
|
"tg.imageFail": "画像処理に失敗しました: {msg}",
|
package/public/locales/ko.json
CHANGED
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"sl.settingsUnsupported": "Slack에서 설정 변경은 지원하지 않습니다.",
|
|
156
156
|
"cmd.runtimeSelectionInstanceWide": "CLI와 모델 선택은 이 인스턴스의 모든 세션이 함께 씁니다. 인스턴스 웹 설정에서 바꿔주세요.",
|
|
157
157
|
"tg.promptUnsupported": "(Telegram에서 미지원)",
|
|
158
|
-
"tg.queued": "대기열에 추가됨 ({count}번째)",
|
|
158
|
+
"tg.queued": "⏳ 대기열에 추가됨 ({count}번째)",
|
|
159
159
|
"tg.queueExpired": "대기 시간이 초과되었습니다",
|
|
160
160
|
"tg.imageCaption": "[📷 이미지] {caption}",
|
|
161
161
|
"tg.imageFail": "이미지 처리 실패: {msg}",
|
package/public/locales/zh.json
CHANGED
|
@@ -153,7 +153,7 @@
|
|
|
153
153
|
"sl.settingsUnsupported": "Slack 不支持修改设置。",
|
|
154
154
|
"cmd.runtimeSelectionInstanceWide": "CLI 与模型选择由本实例的所有会话共用。请在实例网页设置中修改。",
|
|
155
155
|
"tg.promptUnsupported": "(Telegram 不支持)",
|
|
156
|
-
"tg.queued": "已加入队列(第 {count} 个)",
|
|
156
|
+
"tg.queued": "⏳ 已加入队列(第 {count} 个)",
|
|
157
157
|
"tg.queueExpired": "排队等待已超时",
|
|
158
158
|
"tg.imageCaption": "[📷 图片] {caption}",
|
|
159
159
|
"tg.imageFail": "图片处理失败:{msg}",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
// slack.allowBots
|
|
12
12
|
// slack.mentionOnly
|
|
13
13
|
// slack.replyInThread
|
|
14
|
+
// slack.ack.enabled (emoji reaction receipts on inbound messages)
|
|
14
15
|
|
|
15
16
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
16
17
|
import type { SettingsPageProps, DirtyEntry } from '../types';
|
|
@@ -37,6 +38,7 @@ type SlackBlock = {
|
|
|
37
38
|
allowBots?: boolean;
|
|
38
39
|
mentionOnly?: boolean;
|
|
39
40
|
replyInThread?: boolean;
|
|
41
|
+
ack?: { enabled?: boolean };
|
|
40
42
|
};
|
|
41
43
|
|
|
42
44
|
type SlackSnapshot = {
|
|
@@ -60,6 +62,7 @@ const SLACK_KEYS = [
|
|
|
60
62
|
'slack.allowBots',
|
|
61
63
|
'slack.mentionOnly',
|
|
62
64
|
'slack.replyInThread',
|
|
65
|
+
'slack.ack.enabled',
|
|
63
66
|
] as const;
|
|
64
67
|
|
|
65
68
|
/**
|
|
@@ -86,6 +89,7 @@ export default function ChannelsSlack({ port, client, dirty, registerSave }: Set
|
|
|
86
89
|
const [allowBots, setAllowBots] = useState(false);
|
|
87
90
|
const [mentionOnly, setMentionOnly] = useState(true);
|
|
88
91
|
const [replyInThread, setReplyInThread] = useState(true);
|
|
92
|
+
const [ackEnabled, setAckEnabled] = useState(false);
|
|
89
93
|
|
|
90
94
|
const applySnapshot = useCallback((sc: SlackBlock) => {
|
|
91
95
|
setEnabled(Boolean(sc.enabled));
|
|
@@ -99,6 +103,9 @@ export default function ChannelsSlack({ port, client, dirty, registerSave }: Set
|
|
|
99
103
|
// off on a fresh install while the backend behaves as on.
|
|
100
104
|
setMentionOnly(sc.mentionOnly !== false);
|
|
101
105
|
setReplyInThread(sc.replyInThread !== false);
|
|
106
|
+
// ACK reactions default OFF in SLACK_ACK_DEFAULTS; a plain Boolean read
|
|
107
|
+
// matches the backend default.
|
|
108
|
+
setAckEnabled(Boolean(sc.ack?.enabled));
|
|
102
109
|
}, []);
|
|
103
110
|
|
|
104
111
|
useEffect(() => {
|
|
@@ -342,6 +349,19 @@ export default function ChannelsSlack({ port, client, dirty, registerSave }: Set
|
|
|
342
349
|
});
|
|
343
350
|
}}
|
|
344
351
|
/>
|
|
352
|
+
<ToggleField
|
|
353
|
+
id="sl-ackEnabled"
|
|
354
|
+
label="Emoji reactions (👀 → ✅)"
|
|
355
|
+
value={ackEnabled}
|
|
356
|
+
onChange={(next) => {
|
|
357
|
+
setAckEnabled(next);
|
|
358
|
+
setEntry('slack.ack.enabled', {
|
|
359
|
+
value: next,
|
|
360
|
+
original: Boolean(original.ack?.enabled),
|
|
361
|
+
valid: true,
|
|
362
|
+
});
|
|
363
|
+
}}
|
|
364
|
+
/>
|
|
345
365
|
</SettingsSection>
|
|
346
366
|
</form>
|
|
347
367
|
);
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @file scripts/check-path-length.mjs
|
|
3
|
+
// Windows MAX_PATH regression gate (#430).
|
|
4
|
+
//
|
|
5
|
+
// A tracked path that is fine on Linux can make `git clone --recursive` fail on
|
|
6
|
+
// Windows, and it fails in the worst way: the clone stops midway with
|
|
7
|
+
// "Filename too long", earlier submodules are already checked out, so the tree
|
|
8
|
+
// looks healthy while one submodule is silently empty.
|
|
9
|
+
//
|
|
10
|
+
// CI runs on Linux and cannot see this condition at all, which is why it reached
|
|
11
|
+
// users twice (#422 then #430). A length check is the cheapest thing that can.
|
|
12
|
+
//
|
|
13
|
+
// The limit is NOT the failure threshold. MAX_PATH is 260, and the #430 paths
|
|
14
|
+
// were 223 with a 37-char `...\cli-jaw\devlog\` prefix — exactly on the line, so
|
|
15
|
+
// whether a clone worked depended on WHERE the user put it. Capping at the
|
|
16
|
+
// observed failure point would just move the cliff. 150 leaves room for a
|
|
17
|
+
// 74-char prefix like C:/Users/name/Documents/Projects/workspace/cli-jaw/devlog/ —
|
|
18
|
+
// the location that broke the 200 cap in practice (#432).
|
|
19
|
+
|
|
20
|
+
import { spawnSync } from 'node:child_process';
|
|
21
|
+
import { existsSync } from 'node:fs';
|
|
22
|
+
import { join, resolve } from 'node:path';
|
|
23
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
24
|
+
|
|
25
|
+
const REPO_ROOT = process.env.PATH_LENGTH_ROOT || fileURLToPath(new URL('..', import.meta.url));
|
|
26
|
+
|
|
27
|
+
/** Max tracked-path length, relative to each repo root. See the header for why 200. */
|
|
28
|
+
export const MAX_TRACKED_PATH_LENGTH = 150;
|
|
29
|
+
|
|
30
|
+
/** The main repo plus every submodule that ships in a `--recursive` clone. */
|
|
31
|
+
const SCAN_ROOTS = ['.', 'devlog', 'skills_ref', 'officecli'];
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Tracked paths for one root.
|
|
35
|
+
*
|
|
36
|
+
* `core.quotepath=false` is load-bearing: by default git C-escapes non-ASCII
|
|
37
|
+
* bytes, so a Korean filename reports roughly three times its real length and a
|
|
38
|
+
* naive check flags files that are perfectly fine.
|
|
39
|
+
*/
|
|
40
|
+
export function listTrackedPaths(root) {
|
|
41
|
+
const result = spawnSync(
|
|
42
|
+
'git', ['-C', root, '-c', 'core.quotepath=false', 'ls-files'],
|
|
43
|
+
{ encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 },
|
|
44
|
+
);
|
|
45
|
+
if (result.status !== 0) return null;
|
|
46
|
+
return result.stdout.split('\n').map(line => line.trim()).filter(Boolean);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function findLongPaths(paths, limit = MAX_TRACKED_PATH_LENGTH) {
|
|
50
|
+
return paths
|
|
51
|
+
.filter(p => p.length > limit)
|
|
52
|
+
.map(p => ({ length: p.length, path: p }))
|
|
53
|
+
.sort((a, b) => b.length - a.length);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function main() {
|
|
57
|
+
const offenders = [];
|
|
58
|
+
let scanned = 0;
|
|
59
|
+
let longest = { length: 0, path: '', root: '' };
|
|
60
|
+
|
|
61
|
+
for (const rel of SCAN_ROOTS) {
|
|
62
|
+
const root = join(REPO_ROOT, rel);
|
|
63
|
+
// A submodule that was never initialised has nothing to check. Skipping is
|
|
64
|
+
// right: this gate protects the clone, and an absent submodule cannot
|
|
65
|
+
// break one.
|
|
66
|
+
if (rel !== '.' && !existsSync(join(root, '.git'))) continue;
|
|
67
|
+
const paths = listTrackedPaths(root);
|
|
68
|
+
if (!paths) continue;
|
|
69
|
+
scanned += paths.length;
|
|
70
|
+
for (const p of paths) {
|
|
71
|
+
if (p.length > longest.length) longest = { length: p.length, path: p, root: rel };
|
|
72
|
+
}
|
|
73
|
+
for (const hit of findLongPaths(paths)) offenders.push({ ...hit, root: rel });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (offenders.length) {
|
|
77
|
+
console.error(`[path-length] ${offenders.length} tracked path(s) exceed ${MAX_TRACKED_PATH_LENGTH} chars:`);
|
|
78
|
+
for (const o of offenders.slice(0, 20)) {
|
|
79
|
+
console.error(` ${String(o.length).padStart(4)} ${o.root}/${o.path}`);
|
|
80
|
+
}
|
|
81
|
+
console.error('\nThese break `git clone --recursive` on Windows without core.longpaths,');
|
|
82
|
+
console.error('and the clone fails PARTWAY: earlier submodules look fine while this one is empty.');
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
console.log(
|
|
87
|
+
`[path-length] OK — ${scanned} tracked path(s), longest ${longest.length} `
|
|
88
|
+
+ `(${longest.root}/${longest.path}), limit ${MAX_TRACKED_PATH_LENGTH}`,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// pathToFileURL, not string surgery: argv[1] is whatever the caller typed, so a
|
|
93
|
+
// relative invocation (`node scripts/check-path-length.mjs`) produced a bogus URL
|
|
94
|
+
// and the gate exited 0 having checked nothing — a silent pass is worse than no
|
|
95
|
+
// gate at all.
|
|
96
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) {
|
|
97
|
+
main();
|
|
98
|
+
}
|
|
@@ -438,6 +438,23 @@ const GATES = {
|
|
|
438
438
|
return { ok: true, detail: 'docs:check + check-doc-drift.sh clean' };
|
|
439
439
|
},
|
|
440
440
|
},
|
|
441
|
+
'path-length': {
|
|
442
|
+
description: 'no tracked path exceeds the Windows MAX_PATH budget (main repo + submodules)',
|
|
443
|
+
check() {
|
|
444
|
+
// Runs on CI too, unlike doc-drift. The condition is platform-neutral
|
|
445
|
+
// (a string length in the index), and the failure it prevents is one
|
|
446
|
+
// Linux CI can never reproduce on its own — which is exactly how it
|
|
447
|
+
// reached users twice (#422, #430).
|
|
448
|
+
const r = run('node', ['scripts/check-path-length.mjs'], { timeout: 120_000 });
|
|
449
|
+
if (r.status !== 0) {
|
|
450
|
+
return {
|
|
451
|
+
ok: false,
|
|
452
|
+
detail: [r.stdout, r.stderr].filter(Boolean).join('\n').slice(-1500),
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
return { ok: true, detail: (r.stdout || '').trim().slice(-300) };
|
|
456
|
+
},
|
|
457
|
+
},
|
|
441
458
|
'strict-baseline': {
|
|
442
459
|
description: 'any-count ratchet: live counts must not exceed docs/migration/strict-baseline.md',
|
|
443
460
|
check() {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-XQCOJYun.js";import{n as t,t as n}from"./jsx-runtime-CYoNlHAD.js";import{a as r,i,n as a,r as o,t as s}from"./page-shell-GpE8A-FA.js";import{a as c,n as ee,o as l,s as u}from"./fields-BwOMlwS0.js";import{t as d}from"./path-utils-CHwADH-r.js";import{n as f,t as p}from"./ChannelEnablementControl-Da_t_jq6.js";var m=e(t(),1),h=n(),g=[`channel`,`slack.enabled`,`slack.botToken`,`slack.appToken`,`slack.teamId`,`slack.channelIds`,`slack.forwardAll`,`slack.allowBots`,`slack.mentionOnly`,`slack.replyInThread`];function _(e){return e?/^[CGD][A-Z0-9]{6,20}$/.test(e.trim().toUpperCase()):!1}function v({port:e,client:t,dirty:n,registerSave:v}){let{state:b,refresh:x,setData:S}=r(t,`/api/settings`),[C,w]=(0,m.useState)([]),[T,E]=(0,m.useState)(`telegram`),[D,O]=(0,m.useState)(!1),[k,A]=(0,m.useState)(``),[j,M]=(0,m.useState)(``),[N,P]=(0,m.useState)(``),[F,I]=(0,m.useState)([]),[L,R]=(0,m.useState)(!0),[z,B]=(0,m.useState)(!1),[V,H]=(0,m.useState)(!0),[U,W]=(0,m.useState)(!0),G=(0,m.useCallback)(e=>{O(!!e.enabled),A(``),M(``),P(e.teamId??``),I(Array.isArray(e.channelIds)?[...e.channelIds]:[]),R(e.forwardAll!==!1),B(!!e.allowBots),H(e.mentionOnly!==!1),W(e.replyInThread!==!1)},[]);(0,m.useEffect)(()=>{if(b.kind!==`ready`)return;let e=b.data.messaging||{};w((Array.isArray(e.enabledChannels)?e.enabledChannels:[]).filter(y)),E(y(e.homeChannel)?e.homeChannel:`telegram`),G(b.data.slack||{})},[b,G]),(0,m.useEffect)(()=>()=>{for(let e of g)n.remove(e)},[n]);let K=(0,m.useCallback)((e,t)=>n.set(e,t),[n]),q=(0,m.useMemo)(()=>b.kind===`ready`&&b.data.slack||{},[b]),J=b.kind===`ready`&&Array.isArray(b.data.slackEnvironmentVariables)?b.data.slackEnvironmentVariables:[],Y=J.length>0,X=(0,m.useCallback)(async()=>{let e=n.saveBundle();if(Object.keys(e).length===0)return;let r=d(e),i=await t.put(`/api/settings`,r),a=i&&typeof i==`object`&&`data`in i?i.data:i;n.clear(),S(a),G(a.slack||{}),await x()},[t,n,x,S,G]);if((0,m.useEffect)(()=>{if(v)return v(X),()=>v(null)},[v,X]),b.kind===`loading`)return(0,h.jsx)(a,{});if(b.kind===`offline`)return(0,h.jsx)(o,{port:e});if(b.kind===`error`)return(0,h.jsx)(s,{message:b.message});let Z=e=>e?`••••••••${e.slice(-4)}`:`(empty)`,Q=F.filter(e=>!_(e)),$=Q.length>0?`Slack conversation IDs only (C…/G…/D…) — invalid: ${Q.join(`, `)}`:null,te=k&&!k.startsWith(`xoxb-`)?`Bot tokens start with xoxb-.`:null,ne=j&&!j.startsWith(`xapp-`)?`App-level tokens start with xapp-.`:null,re=!!q.enabled&&!!q.botToken&&!q.appToken,ie=Y?`Connection settings are read-only because they are managed by environment variables: ${J.join(`, `)}.`:re?`Currently OUTBOUND-ONLY: the app-level token (xapp-) is missing, so no inbound Slack events can arrive.`:`Slack needs TWO tokens: a bot token (xoxb-) for the Web API and an app-level token (xapp-) for Socket Mode.`;return(0,h.jsxs)(`form`,{className:`settings-page-form`,onSubmit:e=>{e.preventDefault(),X()},children:[(0,h.jsxs)(i,{title:`Channels`,hint:`Choose which channels receive inbound chat. Outbound send can still work on any configured channel.`,children:[(0,h.jsx)(p,{pageChannel:`slack`,snapshot:b.kind===`ready`?b.data:{},enabledChannels:C,homeChannel:T,setEnabledChannels:w,setHomeChannel:E,dirty:n,idPrefix:`sl-channel`}),(0,h.jsx)(f,{client:t,channel:`slack`})]}),(0,h.jsxs)(i,{title:`Slack`,hint:ie,children:[(0,h.jsx)(c,{id:`sl-enabled`,label:`Slack enabled`,value:D,disabled:Y,onChange:e=>{O(e),K(`slack.enabled`,{value:e,original:!!q.enabled,valid:!0})}}),(0,h.jsx)(l,{id:`sl-botToken`,label:`Bot token`,value:k,placeholder:Z(q.botToken),error:te,disabled:Y,onChange:e=>{if(A(e),e.length===0){n.remove(`slack.botToken`);return}K(`slack.botToken`,{value:e,original:q.botToken??``,valid:e.startsWith(`xoxb-`)})}}),(0,h.jsx)(l,{id:`sl-appToken`,label:`App-level token`,value:j,placeholder:Z(q.appToken),error:ne,disabled:Y,onChange:e=>{if(M(e),e.length===0){n.remove(`slack.appToken`);return}K(`slack.appToken`,{value:e,original:q.appToken??``,valid:e.startsWith(`xapp-`)})}}),(0,h.jsx)(u,{id:`sl-teamId`,label:`Team ID`,value:N,placeholder:`T01234567 (optional)`,disabled:Y,onChange:e=>{P(e),K(`slack.teamId`,{value:e,original:q.teamId??``,valid:!0})}}),(0,h.jsx)(ee,{id:`sl-channelIds`,label:`Channel IDs`,value:F,placeholder:`C01234567`,error:$,disabled:Y,onChange:e=>{I(e),K(`slack.channelIds`,{value:e,original:q.channelIds??[],valid:e.every(_)})}}),(0,h.jsx)(c,{id:`sl-mentionOnly`,label:`Mention only`,value:V,onChange:e=>{H(e),K(`slack.mentionOnly`,{value:e,original:q.mentionOnly!==!1,valid:!0})}}),(0,h.jsx)(c,{id:`sl-replyInThread`,label:`Reply in thread`,value:U,onChange:e=>{W(e),K(`slack.replyInThread`,{value:e,original:q.replyInThread!==!1,valid:!0})}}),(0,h.jsx)(c,{id:`sl-forwardAll`,label:`Forward all`,value:L,onChange:e=>{R(e),K(`slack.forwardAll`,{value:e,original:q.forwardAll!==!1,valid:!0})}}),(0,h.jsx)(c,{id:`sl-allowBots`,label:`Allow bots`,value:z,onChange:e=>{B(e),K(`slack.allowBots`,{value:e,original:!!q.allowBots,valid:!0})}})]})]})}function y(e){return e===`telegram`||e===`discord`||e===`slack`}export{v as default,_ as isValidSlackConversationId};
|