cli-jaw 2.2.17 → 2.2.18
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/README.md +4 -0
- package/dist/bin/cli-jaw.js +9 -1
- package/dist/bin/cli-jaw.js.map +1 -1
- package/dist/bin/commands/ask.js +245 -0
- package/dist/bin/commands/ask.js.map +1 -0
- package/dist/bin/commands/chat.js +41 -3
- package/dist/bin/commands/chat.js.map +1 -1
- package/dist/bin/commands/dispatch.js +210 -167
- package/dist/bin/commands/dispatch.js.map +1 -1
- package/dist/bin/commands/init.js +33 -4
- package/dist/bin/commands/init.js.map +1 -1
- package/dist/bin/commands/slack.js +73 -3
- package/dist/bin/commands/slack.js.map +1 -1
- package/dist/bin/commands/tui/raw-pipe-mode.js +90 -0
- package/dist/bin/commands/tui/raw-pipe-mode.js.map +1 -0
- package/dist/bin/commands/tui/simple-mode.js +11 -2
- package/dist/bin/commands/tui/simple-mode.js.map +1 -1
- package/dist/bin/postinstall.js +54 -30
- package/dist/bin/postinstall.js.map +1 -1
- package/dist/server.js +10 -0
- package/dist/server.js.map +1 -1
- package/dist/src/agent/pi-runtime.js +10 -2
- package/dist/src/agent/pi-runtime.js.map +1 -1
- package/dist/src/agent/spawn/queue.js +21 -0
- package/dist/src/agent/spawn/queue.js.map +1 -1
- package/dist/src/agent/spawn.js +19 -6
- package/dist/src/agent/spawn.js.map +1 -1
- package/dist/src/cli/cli-status.js +65 -5
- package/dist/src/cli/cli-status.js.map +1 -1
- package/dist/src/cli/handlers.js +9 -1
- package/dist/src/cli/handlers.js.map +1 -1
- package/dist/src/cli/tui/jawcode-render.js +18 -5
- package/dist/src/cli/tui/jawcode-render.js.map +1 -1
- package/dist/src/core/config.js +85 -0
- package/dist/src/core/config.js.map +1 -1
- package/dist/src/core/exec-name.js +55 -0
- package/dist/src/core/exec-name.js.map +1 -0
- package/dist/src/core/runtime-settings.js +9 -1
- package/dist/src/core/runtime-settings.js.map +1 -1
- package/dist/src/core/settings-watch.js +10 -1
- package/dist/src/core/settings-watch.js.map +1 -1
- package/dist/src/lib/tui/bun-shim.mjs +75 -0
- package/dist/src/memory/bootstrap.js +8 -1
- package/dist/src/memory/bootstrap.js.map +1 -1
- package/dist/src/messaging/channel-validate.js +11 -1
- package/dist/src/messaging/channel-validate.js.map +1 -1
- package/dist/src/orchestrator/gateway.js +23 -2
- package/dist/src/orchestrator/gateway.js.map +1 -1
- package/dist/src/orchestrator/pipeline.js +6 -0
- package/dist/src/orchestrator/pipeline.js.map +1 -1
- package/dist/src/orchestrator/request-registry.js +116 -0
- package/dist/src/orchestrator/request-registry.js.map +1 -0
- package/dist/src/prompt/templates/a1-system.md +5 -5
- package/dist/src/routes/messaging.js +94 -1
- package/dist/src/routes/messaging.js.map +1 -1
- package/dist/src/routes/settings.js +61 -4
- package/dist/src/routes/settings.js.map +1 -1
- package/dist/src/routes/system.js +23 -3
- package/dist/src/routes/system.js.map +1 -1
- package/dist/src/slack/bot.js +36 -1
- package/dist/src/slack/bot.js.map +1 -1
- package/dist/src/slack/commands.js +29 -1
- package/dist/src/slack/commands.js.map +1 -1
- package/dist/src/slack/events.js +4 -1
- package/dist/src/slack/events.js.map +1 -1
- package/dist/src/slack/history.js +10 -3
- package/dist/src/slack/history.js.map +1 -1
- package/dist/src/slack/identity.js +553 -0
- package/dist/src/slack/identity.js.map +1 -0
- package/dist/src/slack/ingress.js +42 -0
- package/dist/src/slack/ingress.js.map +1 -1
- package/dist/src/slack/manifest.js +95 -71
- package/dist/src/slack/manifest.js.map +1 -1
- package/dist/src/slack/roster.js +180 -0
- package/dist/src/slack/roster.js.map +1 -0
- package/package.json +4 -3
- package/public/css/sidebar.css +29 -51
- package/public/dist/assets/AdvancedExport-c41zCkwB.js +1 -0
- package/public/dist/assets/{Agent-CNNQ7KkJ.js → Agent-nMPZsMfN.js} +1 -1
- package/public/dist/assets/ChannelsSlack-CVNKtoo4.js +1 -0
- package/public/dist/assets/{app-Dsgp4xpU.js → app-DqSJmDwP.js} +4 -4
- package/public/dist/assets/{app-DjgGeXhJ.css → app-DuyLYRC6.css} +1 -1
- package/public/dist/assets/bgtask-badge-CjWz0F6U.js +1 -0
- package/public/dist/assets/{bgtask-badge-CpavV0Jc.js → bgtask-badge-D6XYRFI5.js} +1 -1
- package/public/dist/assets/{employees-BJyEgim7.js → employees-B_wKPfTO.js} +1 -1
- package/public/dist/assets/{iframe-renderer-B8k3AvTv.js → iframe-renderer-D1-zDg8V.js} +2 -2
- package/public/dist/assets/iframe-renderer-qRVLHPnT.js +1 -0
- package/public/dist/assets/{manager-kXYQyMhR.js → manager-Bjuh1jpq.js} +1 -1
- package/public/dist/assets/{memory-D2RbBVO-.js → memory-CNUpXWEC.js} +1 -1
- package/public/dist/assets/memory-CcWGiPy_.js +1 -0
- package/public/dist/assets/message-history-BamMPUnL.js +1 -0
- package/public/dist/assets/{message-history-Bw2E_b8L.js → message-history-DB1rynP-.js} +1 -1
- package/public/dist/assets/{render-BkGcpH7z.js → render-DXwQzjsJ.js} +1 -1
- package/public/dist/assets/{settings-B1FPORO2.js → settings-CXndjCad.js} +14 -14
- package/public/dist/assets/settings-RGpifFHy.js +1 -0
- package/public/dist/assets/settings-core-X_5UHfr3.js +1 -0
- package/public/dist/assets/settings-core-t5yYVRrv.js +162 -0
- package/public/dist/assets/{sidebar-DW78DANx.js → sidebar-DgIj-LuT.js} +3 -3
- package/public/dist/assets/skills-CbwIimit.js +1 -0
- package/public/dist/assets/{skills-lWi0ZFiV.js → skills-QqxjqDHg.js} +1 -1
- package/public/dist/assets/{slash-commands-DYOI6nKj.js → slash-commands-B2V_jngP.js} +1 -1
- package/public/dist/assets/slash-commands-tCNRlNTC.js +1 -0
- package/public/dist/assets/{trace-drawer-DBX9xzmt.js → trace-drawer-CBe9nRjS.js} +1 -1
- package/public/dist/assets/{ui-Bx7eqnXt.js → ui-CDozpEQt.js} +1 -1
- package/public/dist/assets/ui-o-VpvrSv.js +1 -0
- package/public/dist/index.html +15 -34
- package/public/dist/manager/index.html +1 -1
- package/public/index.html +13 -32
- package/public/js/features/channel-onboarding-flow.ts +25 -2
- package/public/js/features/channel-onboarding.ts +111 -8
- package/public/js/features/settings-cli-status.ts +18 -4
- package/public/js/features/settings-slack.ts +127 -29
- package/public/js/features/settings-types.ts +11 -2
- package/public/locales/en.json +17 -8
- package/public/locales/ja.json +17 -8
- package/public/locales/ko.json +17 -8
- package/public/locales/zh.json +17 -8
- package/public/manager/src/settings/pages/AdvancedExport.tsx +1 -0
- package/public/manager/src/settings/pages/Agent.tsx +10 -1
- package/public/manager/src/settings/pages/ChannelsSlack.tsx +13 -1
- package/scripts/atomic-build.sh +10 -3
- package/scripts/release-preview.sh +16 -1
- package/scripts/verify-dist-assets.sh +53 -0
- package/public/dist/assets/AdvancedExport-DYGcCAUq.js +0 -1
- package/public/dist/assets/ChannelsSlack-ybvupgdK.js +0 -1
- package/public/dist/assets/bgtask-badge-C6h5C-o4.js +0 -1
- package/public/dist/assets/iframe-renderer-BO_GgCTR.js +0 -1
- package/public/dist/assets/memory-amsvg4Ey.js +0 -1
- package/public/dist/assets/message-history-BGHZxvgV.js +0 -1
- package/public/dist/assets/settings-CMN-zN4Q.js +0 -1
- package/public/dist/assets/settings-core-B_OjGYVN.js +0 -1
- package/public/dist/assets/settings-core-CxRwqx86.js +0 -144
- package/public/dist/assets/skills-Dz-9Yrxr.js +0 -1
- package/public/dist/assets/slash-commands-xJFCdTTM.js +0 -1
- package/public/dist/assets/ui-JOcrYeG-.js +0 -1
|
@@ -1,42 +1,113 @@
|
|
|
1
1
|
// ── Slack Settings ──
|
|
2
|
-
import { api, apiJson } from '../api.js';
|
|
2
|
+
import { API_BASE, api, apiJson, getAuthToken } from '../api.js';
|
|
3
3
|
import { openSetupGuideIfUnconfigured } from './channel-setup-guide.js';
|
|
4
4
|
import { hasSlackBotTokenPrefix, hasSlackAppTokenPrefix } from './channel-setup-rules.js';
|
|
5
5
|
import { t } from './i18n.js';
|
|
6
|
+
import { refreshTransportStatusRow } from './transport-status-row.js';
|
|
6
7
|
import type { SettingsData } from './settings-types.js';
|
|
7
8
|
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// app-page shortcut, and inline token-prefix validation (error below the
|
|
11
|
-
// field, cleared once the value looks right — form-patterns on-blur timing).
|
|
9
|
+
// One-time inline token-prefix validation. Errors appear below each field on
|
|
10
|
+
// blur and clear live once the token prefix is corrected.
|
|
12
11
|
let setupGuideBound = false;
|
|
12
|
+
let slackResetting = false;
|
|
13
|
+
let slackEnvironmentVariables: string[] = [];
|
|
14
|
+
|
|
15
|
+
type SlackResetResponse = {
|
|
16
|
+
ok?: boolean;
|
|
17
|
+
error?: string;
|
|
18
|
+
environmentVariables?: string[];
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
async function requestSlackConnectionReset(): Promise<SlackResetResponse | null> {
|
|
22
|
+
try {
|
|
23
|
+
const token = await getAuthToken();
|
|
24
|
+
const response = await fetch(`${API_BASE}/api/settings/slack/reset`, {
|
|
25
|
+
method: 'POST',
|
|
26
|
+
headers: token ? { Authorization: `Bearer ${token}` } : {},
|
|
27
|
+
});
|
|
28
|
+
return await response.json().catch(() => null) as SlackResetResponse | null;
|
|
29
|
+
} catch {
|
|
30
|
+
// The write may have committed even if its response was lost. The
|
|
31
|
+
// authoritative GET below decides whether the reset actually landed.
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function slackConnectionIsCleared(snapshot: SettingsData | null): boolean {
|
|
37
|
+
const slack = snapshot?.slack;
|
|
38
|
+
return !slack?.enabled
|
|
39
|
+
&& !slack?.botToken
|
|
40
|
+
&& !slack?.appToken
|
|
41
|
+
&& !slack?.teamId
|
|
42
|
+
&& !(slack?.channelIds?.length)
|
|
43
|
+
&& !slack?.attachPort;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function slackEnvironmentMessage(): string {
|
|
47
|
+
return t('settings.slack.resetManagedByEnvironment', {
|
|
48
|
+
variables: slackEnvironmentVariables.join(', ') || 'SLACK_*',
|
|
49
|
+
});
|
|
50
|
+
}
|
|
13
51
|
|
|
14
52
|
export function initSlackSetupGuide(): void {
|
|
15
53
|
if (setupGuideBound) return;
|
|
16
54
|
setupGuideBound = true;
|
|
17
55
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const yaml = json?.yaml || '';
|
|
23
|
-
if (!yaml) throw new Error('empty manifest');
|
|
24
|
-
await navigator.clipboard.writeText(yaml);
|
|
25
|
-
const original = btn.textContent || '';
|
|
26
|
-
btn.textContent = t('settings.slack.guide.copyManifestDone');
|
|
27
|
-
setTimeout(() => { btn.textContent = original; }, 2000);
|
|
28
|
-
} catch {
|
|
29
|
-
btn.textContent = t('settings.slack.guide.copyManifestFail');
|
|
30
|
-
setTimeout(() => { btn.textContent = t('settings.slack.guide.copyManifest'); }, 2500);
|
|
31
|
-
}
|
|
56
|
+
bindPrefixValidation('slBotToken', 'slack-bot-token-error', hasSlackBotTokenPrefix);
|
|
57
|
+
bindPrefixValidation('slAppToken', 'slack-app-token-error', hasSlackAppTokenPrefix);
|
|
58
|
+
document.getElementById('slack-reset-connection')?.addEventListener('click', () => {
|
|
59
|
+
void resetSlackConnection();
|
|
32
60
|
});
|
|
61
|
+
}
|
|
33
62
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
63
|
+
export async function resetSlackConnection(): Promise<void> {
|
|
64
|
+
if (slackResetting) return;
|
|
65
|
+
if (slackEnvironmentVariables.length > 0) {
|
|
66
|
+
window.alert(slackEnvironmentMessage());
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const botToken = document.getElementById('slBotToken') as HTMLInputElement | null;
|
|
70
|
+
const appToken = document.getElementById('slAppToken') as HTMLInputElement | null;
|
|
71
|
+
if (!botToken?.value.trim() && !appToken?.value.trim()) {
|
|
72
|
+
window.alert(t('settings.slack.resetEmpty'));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (!window.confirm(t('settings.slack.resetConfirm'))) return;
|
|
37
76
|
|
|
38
|
-
|
|
39
|
-
|
|
77
|
+
const resetButton = document.getElementById('slack-reset-connection') as HTMLButtonElement | null;
|
|
78
|
+
slackResetting = true;
|
|
79
|
+
if (resetButton) resetButton.disabled = true;
|
|
80
|
+
try {
|
|
81
|
+
const result = await requestSlackConnectionReset();
|
|
82
|
+
const authoritative = await api<SettingsData>('/api/settings');
|
|
83
|
+
if (authoritative) loadSlackSettings(authoritative);
|
|
84
|
+
await refreshTransportStatusRow();
|
|
85
|
+
|
|
86
|
+
if (result?.error === 'slack_connection_managed_by_environment') {
|
|
87
|
+
const variables = Array.isArray(result.environmentVariables)
|
|
88
|
+
? result.environmentVariables.join(', ')
|
|
89
|
+
: 'SLACK_*';
|
|
90
|
+
window.alert(t('settings.slack.resetManagedByEnvironment', { variables }));
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (!slackConnectionIsCleared(authoritative)) {
|
|
94
|
+
window.alert(t('settings.slack.resetFailed'));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
for (const id of ['slBotToken', 'slAppToken', 'slTeamId', 'slChannelIds', 'slAttachPort']) {
|
|
99
|
+
document.getElementById(id)?.classList.remove('input-error');
|
|
100
|
+
}
|
|
101
|
+
for (const id of ['slack-bot-token-error', 'slack-app-token-error']) {
|
|
102
|
+
const error = document.getElementById(id);
|
|
103
|
+
if (error) error.style.display = 'none';
|
|
104
|
+
}
|
|
105
|
+
document.getElementById('slOff')?.classList.add('active');
|
|
106
|
+
document.getElementById('slOn')?.classList.remove('active');
|
|
107
|
+
} finally {
|
|
108
|
+
slackResetting = false;
|
|
109
|
+
if (resetButton) resetButton.disabled = slackEnvironmentVariables.length > 0;
|
|
110
|
+
}
|
|
40
111
|
}
|
|
41
112
|
|
|
42
113
|
function bindPrefixValidation(inputId: string, errorId: string, valid: (v: string) => boolean): void {
|
|
@@ -57,6 +128,10 @@ function bindPrefixValidation(inputId: string, errorId: string, valid: (v: strin
|
|
|
57
128
|
}
|
|
58
129
|
|
|
59
130
|
export async function saveSlackSettings(): Promise<void> {
|
|
131
|
+
if (slackEnvironmentVariables.length > 0) {
|
|
132
|
+
window.alert(slackEnvironmentMessage());
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
60
135
|
const botToken = (document.getElementById('slBotToken') as HTMLInputElement)?.value.trim() || '';
|
|
61
136
|
const appToken = (document.getElementById('slAppToken') as HTMLInputElement)?.value.trim() || '';
|
|
62
137
|
const teamId = (document.getElementById('slTeamId') as HTMLInputElement)?.value.trim() || '';
|
|
@@ -69,6 +144,10 @@ export async function saveSlackSettings(): Promise<void> {
|
|
|
69
144
|
}
|
|
70
145
|
|
|
71
146
|
export async function setSlack(enabled: boolean): Promise<void> {
|
|
147
|
+
if (slackEnvironmentVariables.length > 0) {
|
|
148
|
+
window.alert(slackEnvironmentMessage());
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
72
151
|
document.getElementById('slOn')?.classList.toggle('active', enabled);
|
|
73
152
|
document.getElementById('slOff')?.classList.toggle('active', !enabled);
|
|
74
153
|
await apiJson('/api/settings', 'PUT', { slack: { enabled } });
|
|
@@ -102,18 +181,37 @@ export async function setSlackReplyInThread(enabled: boolean): Promise<void> {
|
|
|
102
181
|
export function loadSlackSettings(s: SettingsData): void {
|
|
103
182
|
if (!s.slack) return;
|
|
104
183
|
const sc = s.slack;
|
|
184
|
+
slackEnvironmentVariables = Array.isArray(s.slackEnvironmentVariables)
|
|
185
|
+
? s.slackEnvironmentVariables
|
|
186
|
+
: [];
|
|
187
|
+
const environmentManaged = slackEnvironmentVariables.length > 0;
|
|
188
|
+
const notice = document.getElementById('slack-environment-managed');
|
|
189
|
+
if (notice) {
|
|
190
|
+
notice.style.display = environmentManaged ? '' : 'none';
|
|
191
|
+
notice.textContent = environmentManaged
|
|
192
|
+
? t('settings.slack.managedByEnvironment', { variables: slackEnvironmentVariables.join(', ') })
|
|
193
|
+
: '';
|
|
194
|
+
}
|
|
195
|
+
for (const id of ['slBotToken', 'slAppToken', 'slTeamId', 'slChannelIds', 'slAttachPort']) {
|
|
196
|
+
const input = document.getElementById(id) as HTMLInputElement | null;
|
|
197
|
+
if (input) input.disabled = environmentManaged;
|
|
198
|
+
}
|
|
199
|
+
for (const id of ['slOff', 'slOn', 'slack-reset-connection', 'slack-onboarding-trigger']) {
|
|
200
|
+
const button = document.getElementById(id) as HTMLButtonElement | null;
|
|
201
|
+
if (button) button.disabled = environmentManaged;
|
|
202
|
+
}
|
|
105
203
|
document.getElementById('slOn')?.classList.toggle('active', !!sc.enabled);
|
|
106
204
|
document.getElementById('slOff')?.classList.toggle('active', !sc.enabled);
|
|
107
205
|
const botToken = document.getElementById('slBotToken') as HTMLInputElement | null;
|
|
108
|
-
if (
|
|
206
|
+
if (botToken) botToken.value = environmentManaged ? '' : sc.botToken || '';
|
|
109
207
|
const appToken = document.getElementById('slAppToken') as HTMLInputElement | null;
|
|
110
|
-
if (
|
|
208
|
+
if (appToken) appToken.value = environmentManaged ? '' : sc.appToken || '';
|
|
111
209
|
const teamId = document.getElementById('slTeamId') as HTMLInputElement | null;
|
|
112
|
-
if (
|
|
210
|
+
if (teamId) teamId.value = environmentManaged ? '' : sc.teamId || '';
|
|
113
211
|
const channelIds = document.getElementById('slChannelIds') as HTMLInputElement | null;
|
|
114
|
-
if (
|
|
212
|
+
if (channelIds) channelIds.value = environmentManaged ? '' : sc.channelIds?.join(', ') || '';
|
|
115
213
|
const attachPort = document.getElementById('slAttachPort') as HTMLInputElement | null;
|
|
116
|
-
if (attachPort) attachPort.value = sc.attachPort || '';
|
|
214
|
+
if (attachPort) attachPort.value = environmentManaged ? '' : sc.attachPort || '';
|
|
117
215
|
const fwdOn = sc.forwardAll !== false;
|
|
118
216
|
document.getElementById('slForwardOn')?.classList.toggle('active', fwdOn);
|
|
119
217
|
document.getElementById('slForwardOff')?.classList.toggle('active', !fwdOn);
|
|
@@ -63,11 +63,19 @@ export interface CliStatusInfo {
|
|
|
63
63
|
authenticated: boolean | null;
|
|
64
64
|
path: string | null;
|
|
65
65
|
source: string;
|
|
66
|
-
probeState: 'checking' | 'fresh' | 'stale';
|
|
66
|
+
probeState: 'checking' | 'fresh' | 'stale' | 'failing';
|
|
67
67
|
reason?: string;
|
|
68
|
+
/** Underlying probe error, present only while `failing`. */
|
|
69
|
+
probeError?: string;
|
|
70
|
+
probeFailures?: number;
|
|
71
|
+
nextRetryAt?: number;
|
|
68
72
|
}
|
|
69
|
-
export function describeCliProbe(info: CliStatusInfo): 'checking' | 'capability-failed' | 'stale' | 'ready' | 'unavailable' {
|
|
73
|
+
export function describeCliProbe(info: CliStatusInfo): 'checking' | 'probe-failing' | 'capability-failed' | 'stale' | 'ready' | 'unavailable' {
|
|
70
74
|
if (info.probeState === 'checking') return 'checking';
|
|
75
|
+
// Ahead of every other branch: while probes keep failing we know nothing
|
|
76
|
+
// current about the runtime, so a preserved snapshot must not be rendered
|
|
77
|
+
// as ready or merely stale (#277).
|
|
78
|
+
if (info.probeState === 'failing') return 'probe-failing';
|
|
71
79
|
if (info.binaryInstalled === true && info.capabilityReady === false) return 'capability-failed';
|
|
72
80
|
if (info.probeState === 'stale') return 'stale';
|
|
73
81
|
return info.available === true && info.capabilityReady !== false ? 'ready' : 'unavailable';
|
|
@@ -82,6 +90,7 @@ export interface SettingsData {
|
|
|
82
90
|
telegram?: TelegramConfig;
|
|
83
91
|
discord?: DiscordConfig;
|
|
84
92
|
slack?: SlackConfig;
|
|
93
|
+
slackEnvironmentVariables?: string[];
|
|
85
94
|
channel?: 'telegram' | 'discord' | 'slack';
|
|
86
95
|
fallbackOrder?: string[];
|
|
87
96
|
memory?: { cli?: string };
|
package/public/locales/en.json
CHANGED
|
@@ -545,7 +545,7 @@
|
|
|
545
545
|
"help.slack.link.portal": "Open the Slack app dashboard",
|
|
546
546
|
"help.slack.link.docs": "Socket Mode documentation",
|
|
547
547
|
"help.slack.example.1": "@cli-jaw run the tests for this repo",
|
|
548
|
-
"help.slack.howTo.1": "Click \"Copy manifest\" in the guide card below, then create the app at api.slack.com/apps → Create
|
|
548
|
+
"help.slack.howTo.1": "Click \"Copy manifest\" in the guide card below, then create the app at api.slack.com/apps → Create New App → From a manifest.",
|
|
549
549
|
"help.slack.howTo.2": "Enable Socket Mode and generate an app-level token (xapp-) with connections:write.",
|
|
550
550
|
"help.slack.howTo.3": "Install to the workspace to obtain the bot token (xoxb-).",
|
|
551
551
|
"help.slack.howTo.4": "Paste each token into its own field below — do not swap them.",
|
|
@@ -854,10 +854,6 @@
|
|
|
854
854
|
"bgtask.title": "Background",
|
|
855
855
|
"tg.elicitationExpired": "Selection expired. Please reply with text.",
|
|
856
856
|
"settings.slack.guide.step1Title": "Create the Slack app",
|
|
857
|
-
"settings.slack.guide.step1Desc": "Create an App → From an app manifest → pick workspace → paste. For an existing app, add files:read.",
|
|
858
|
-
"settings.slack.guide.copyManifest": "Copy manifest",
|
|
859
|
-
"settings.slack.guide.copyManifestDone": "Copied — paste the files:read manifest into Slack",
|
|
860
|
-
"settings.slack.guide.copyManifestFail": "Copy failed — use jaw slack manifest",
|
|
861
857
|
"settings.slack.guide.openApps": "Open apps page",
|
|
862
858
|
"settings.slack.guide.step2Title": "Paste the bot token",
|
|
863
859
|
"settings.slack.guide.step3Title": "App-level token for inbound (optional)",
|
|
@@ -865,6 +861,12 @@
|
|
|
865
861
|
"settings.slack.guide.botTokenError": "Must be a bot token starting with xoxb- — swapped with the app token?",
|
|
866
862
|
"settings.slack.guide.appTokenError": "Must be an app-level token starting with xapp- — swapped with the bot token?",
|
|
867
863
|
"settings.slack.advanced": "Advanced settings",
|
|
864
|
+
"settings.slack.resetConnection": "Reset connection",
|
|
865
|
+
"settings.slack.resetConfirm": "The Slack app connection will be reset. Continue?",
|
|
866
|
+
"settings.slack.resetEmpty": "No Slack app is connected.",
|
|
867
|
+
"settings.slack.resetFailed": "Could not reset the Slack app connection. Try again.",
|
|
868
|
+
"settings.slack.resetManagedByEnvironment": "This Slack connection is managed by environment variables ({variables}). Remove them and restart cli-jaw before resetting the connection.",
|
|
869
|
+
"settings.slack.managedByEnvironment": "Connection settings are read-only because they are managed by environment variables: {variables}. Remove them and restart cli-jaw to edit here.",
|
|
868
870
|
"settings.slack.attachPort": "Attach instance port",
|
|
869
871
|
"settings.channel.notAttachInstanceHint": "Another instance owns this Slack connection (check the attach instance port)",
|
|
870
872
|
"settings.slack.guide.step2Desc": "App settings → OAuth & Permissions → confirm files:read → Reinstall to Workspace → copy Bot User OAuth Token",
|
|
@@ -893,9 +895,15 @@
|
|
|
893
895
|
"onboarding.title.slack": "Connect Slack",
|
|
894
896
|
"onboarding.guide.telegram": "Open @BotFather in Telegram, send /newbot, pick a name and username, and copy the bot token it returns. Paste it below and press Validate.",
|
|
895
897
|
"onboarding.guide.discord": "At discord.com/developers/applications choose New Application, then Bot, then Reset Token. Enable MESSAGE CONTENT INTENT under Privileged Gateway Intents. Get the server ID by enabling Developer Mode in Discord, then right-click the server and copy its ID.",
|
|
896
|
-
"onboarding.guide.slack": "At api.slack.com/apps
|
|
897
|
-
"onboarding.
|
|
898
|
-
"onboarding.
|
|
898
|
+
"onboarding.guide.slack": "At api.slack.com/apps, choose Create New App → From a manifest, paste the copied manifest into the JSON tab, select the workspace where you want to add the app, and create it.",
|
|
899
|
+
"onboarding.slackAppName": "App name",
|
|
900
|
+
"onboarding.slackAppNameHint": "Used for both the app and bot. Enter up to 35 lowercase letters, numbers, hyphens, underscores, or dots.",
|
|
901
|
+
"onboarding.slackGenerateManifest": "Generate manifest",
|
|
902
|
+
"onboarding.slackManifestGenerating": "Generating...",
|
|
903
|
+
"onboarding.slackManifestReady": "Copied",
|
|
904
|
+
"onboarding.slackManifestError": "Could not generate or copy the manifest. Try again.",
|
|
905
|
+
"onboarding.slackAppNameError": "Use 1–35 lowercase letters, numbers, hyphens, underscores, or dots.",
|
|
906
|
+
"onboarding.warning.missingCapabilities": "Optional scopes {capabilities} are missing, so the features they cover are turned off. Add them and reinstall the app. Text messages still work.",
|
|
899
907
|
"onboarding.token.botToken": "Bot token",
|
|
900
908
|
"onboarding.token.appToken": "App-level token",
|
|
901
909
|
"onboarding.token.guildId": "Server ID",
|
|
@@ -920,6 +928,7 @@
|
|
|
920
928
|
"onboarding.validateHint": "Press Validate to check the real connection. It must pass before saving.",
|
|
921
929
|
"onboarding.saveHint": "Validation passed. Saving applies the settings and connects the channel right away.",
|
|
922
930
|
"onboarding.error.validation_required": "Validation has to pass first.",
|
|
931
|
+
"onboarding.error.slack_setup_required": "Generate the manifest and open the issuing page before continuing.",
|
|
923
932
|
"onboarding.openIssuer": "Open the issuing page",
|
|
924
933
|
"onboarding.error.missing_scopes": "The token works, but the app is missing OAuth scopes. Add the ones below under OAuth & Permissions, then reinstall the app.",
|
|
925
934
|
"onboarding.hint.telegram.botToken": "The value @BotFather returned after /newbot.",
|
package/public/locales/ja.json
CHANGED
|
@@ -534,7 +534,7 @@
|
|
|
534
534
|
"help.slack.link.portal": "Open the Slack app dashboard",
|
|
535
535
|
"help.slack.link.docs": "Socket Mode documentation",
|
|
536
536
|
"help.slack.example.1": "@cli-jaw run the tests for this repo",
|
|
537
|
-
"help.slack.howTo.1": "下のガイドカードの「マニフェストをコピー」を押し、api.slack.com/apps → Create
|
|
537
|
+
"help.slack.howTo.1": "下のガイドカードの「マニフェストをコピー」を押し、api.slack.com/apps → Create New App → From a manifest に貼り付けてアプリを作成します。",
|
|
538
538
|
"help.slack.howTo.2": "Enable Socket Mode and generate an app-level token (xapp-) with connections:write.",
|
|
539
539
|
"help.slack.howTo.3": "Install to the workspace to obtain the bot token (xoxb-).",
|
|
540
540
|
"help.slack.howTo.4": "Paste each token into its own field below — do not swap them.",
|
|
@@ -843,10 +843,6 @@
|
|
|
843
843
|
"bgtask.title": "バックグラウンド",
|
|
844
844
|
"tg.elicitationExpired": "選択セッションの有効期限が切れました。テキストで返信してください。",
|
|
845
845
|
"settings.slack.guide.step1Title": "Slack アプリを作成",
|
|
846
|
-
"settings.slack.guide.step1Desc": "Create an App → From an app manifest → ワークスペース選択 → 貼り付け。既存アプリには files:read を追加します。",
|
|
847
|
-
"settings.slack.guide.copyManifest": "マニフェストをコピー",
|
|
848
|
-
"settings.slack.guide.copyManifestDone": "コピーしました — files:read を含むマニフェストを Slack に貼り付けてください",
|
|
849
|
-
"settings.slack.guide.copyManifestFail": "コピー失敗 — jaw slack manifest を使用",
|
|
850
846
|
"settings.slack.guide.openApps": "アプリページを開く",
|
|
851
847
|
"settings.slack.guide.step2Title": "ボットトークンを貼り付け",
|
|
852
848
|
"settings.slack.guide.step3Title": "受信用アプリトークン(任意)",
|
|
@@ -854,6 +850,12 @@
|
|
|
854
850
|
"settings.slack.guide.botTokenError": "xoxb- で始まるボットトークンが必要です — アプリトークンと入れ替わっていませんか?",
|
|
855
851
|
"settings.slack.guide.appTokenError": "xapp- で始まるアプリレベルトークンが必要です — ボットトークンと入れ替わっていませんか?",
|
|
856
852
|
"settings.slack.advanced": "詳細設定",
|
|
853
|
+
"settings.slack.resetConnection": "接続をリセット",
|
|
854
|
+
"settings.slack.resetConfirm": "Slack アプリの接続がリセットされます。続行しますか?",
|
|
855
|
+
"settings.slack.resetEmpty": "接続されている Slack アプリはありません。",
|
|
856
|
+
"settings.slack.resetFailed": "Slack アプリの接続をリセットできませんでした。もう一度お試しください。",
|
|
857
|
+
"settings.slack.resetManagedByEnvironment": "この Slack 接続は環境変数({variables})で管理されています。環境変数を削除して cli-jaw を再起動してから、接続をリセットしてください。",
|
|
858
|
+
"settings.slack.managedByEnvironment": "接続設定は環境変数({variables})で管理されているため読み取り専用です。ここで編集するには環境変数を削除し、cli-jaw を再起動してください。",
|
|
857
859
|
"settings.slack.attachPort": "接続インスタンスのポート",
|
|
858
860
|
"settings.channel.notAttachInstanceHint": "別のインスタンスがこの Slack 接続を所有しています(接続インスタンスのポートを確認)",
|
|
859
861
|
"settings.slack.guide.step2Desc": "アプリ設定 → OAuth & Permissions → files:read を確認 → Reinstall to Workspace → Bot User OAuth Token をコピー",
|
|
@@ -882,9 +884,15 @@
|
|
|
882
884
|
"onboarding.title.slack": "Slack に接続",
|
|
883
885
|
"onboarding.guide.telegram": "Open @BotFather in Telegram, send /newbot, pick a name and username, and copy the bot token it returns. Paste it below and press Validate.",
|
|
884
886
|
"onboarding.guide.discord": "At discord.com/developers/applications choose New Application, then Bot, then Reset Token. Enable MESSAGE CONTENT INTENT under Privileged Gateway Intents. Get the server ID by enabling Developer Mode in Discord, then right-click the server and copy its ID.",
|
|
885
|
-
"onboarding.guide.slack": "
|
|
886
|
-
"onboarding.
|
|
887
|
-
"onboarding.
|
|
887
|
+
"onboarding.guide.slack": "api.slack.com/apps で Create New App → From a manifest を選び、JSON タブにコピーしたマニフェストを貼り付け、アプリを追加するワークスペースを選択して作成してください。",
|
|
888
|
+
"onboarding.slackAppName": "アプリ名",
|
|
889
|
+
"onboarding.slackAppNameHint": "アプリとボットの両方に使用します。英小文字、数字、-、_、. のみで35文字以内にしてください。",
|
|
890
|
+
"onboarding.slackGenerateManifest": "マニフェストを生成",
|
|
891
|
+
"onboarding.slackManifestGenerating": "生成中...",
|
|
892
|
+
"onboarding.slackManifestReady": "コピーしました",
|
|
893
|
+
"onboarding.slackManifestError": "マニフェストを生成またはコピーできませんでした。もう一度お試しください。",
|
|
894
|
+
"onboarding.slackAppNameError": "英小文字、数字、-、_、. のみで1〜35文字入力してください。",
|
|
895
|
+
"onboarding.warning.missingCapabilities": "任意の権限 {capabilities} がないため、その機能のみ無効です。権限を追加してアプリを再インストールしてください。テキストは引き続き利用できます。",
|
|
888
896
|
"onboarding.token.botToken": "ボットトークン",
|
|
889
897
|
"onboarding.token.appToken": "アプリレベルトークン",
|
|
890
898
|
"onboarding.token.guildId": "サーバー ID",
|
|
@@ -909,6 +917,7 @@
|
|
|
909
917
|
"onboarding.validateHint": "「検証」を押して実際の接続を確認してください。通過しないと保存に進めません。",
|
|
910
918
|
"onboarding.saveHint": "検証に成功しました。保存すると設定に反映され、チャンネルがすぐ接続されます。",
|
|
911
919
|
"onboarding.error.validation_required": "先に検証を通す必要があります。",
|
|
920
|
+
"onboarding.error.slack_setup_required": "マニフェストを生成し、発行ページを開いてから次へ進んでください。",
|
|
912
921
|
"onboarding.openIssuer": "発行ページを開く",
|
|
913
922
|
"onboarding.error.missing_scopes": "トークンは有効ですが、アプリの権限(スコープ)が不足しています。OAuth & Permissions で以下を追加し、アプリを再インストールしてください。",
|
|
914
923
|
"onboarding.hint.telegram.botToken": "@BotFather が /newbot の後に返した値です。",
|
package/public/locales/ko.json
CHANGED
|
@@ -545,7 +545,7 @@
|
|
|
545
545
|
"help.slack.link.portal": "Slack 앱 관리 페이지 열기",
|
|
546
546
|
"help.slack.link.docs": "Socket Mode 문서",
|
|
547
547
|
"help.slack.example.1": "@cli-jaw 이 저장소 테스트 돌려줘",
|
|
548
|
-
"help.slack.howTo.1": "아래 가이드 카드의 \"매니페스트 복사\"를 눌러 api.slack.com/apps → Create
|
|
548
|
+
"help.slack.howTo.1": "아래 가이드 카드의 \"매니페스트 복사\"를 눌러 api.slack.com/apps → Create New App → From a manifest에 붙여넣어 앱을 만듭니다.",
|
|
549
549
|
"help.slack.howTo.2": "Socket Mode를 켜고 connections:write 범위의 app-level 토큰(xapp-)을 발급합니다.",
|
|
550
550
|
"help.slack.howTo.3": "워크스페이스에 설치해 봇 토큰(xoxb-)을 받습니다.",
|
|
551
551
|
"help.slack.howTo.4": "두 토큰을 아래 입력란에 각각 붙여넣습니다 — 서로 바꿔 넣지 않도록 주의하세요.",
|
|
@@ -854,10 +854,6 @@
|
|
|
854
854
|
"bgtask.title": "백그라운드",
|
|
855
855
|
"tg.elicitationExpired": "선택 세션이 만료되었습니다. 텍스트로 답해주세요.",
|
|
856
856
|
"settings.slack.guide.step1Title": "Slack 앱 만들기",
|
|
857
|
-
"settings.slack.guide.step1Desc": "Create an App → From an app manifest → 워크스페이스 선택 → 붙여넣기. 기존 앱은 files:read를 추가하세요.",
|
|
858
|
-
"settings.slack.guide.copyManifest": "매니페스트 복사",
|
|
859
|
-
"settings.slack.guide.copyManifestDone": "복사됨 — files:read 포함 매니페스트를 Slack에 붙여넣으세요",
|
|
860
|
-
"settings.slack.guide.copyManifestFail": "복사 실패 — jaw slack manifest 사용",
|
|
861
857
|
"settings.slack.guide.openApps": "앱 페이지 열기",
|
|
862
858
|
"settings.slack.guide.step2Title": "봇 토큰 붙여넣기",
|
|
863
859
|
"settings.slack.guide.step3Title": "수신용 앱 토큰 (선택)",
|
|
@@ -865,6 +861,12 @@
|
|
|
865
861
|
"settings.slack.guide.botTokenError": "xoxb-로 시작하는 봇 토큰이어야 합니다 — 앱 토큰과 바꿔 넣지 않았나요?",
|
|
866
862
|
"settings.slack.guide.appTokenError": "xapp-로 시작하는 앱 레벨 토큰이어야 합니다 — 봇 토큰과 바꿔 넣지 않았나요?",
|
|
867
863
|
"settings.slack.advanced": "고급 설정",
|
|
864
|
+
"settings.slack.resetConnection": "연결 초기화",
|
|
865
|
+
"settings.slack.resetConfirm": "Slack 앱 연결이 초기화됩니다. 계속하시겠습니까?",
|
|
866
|
+
"settings.slack.resetEmpty": "연결된 Slack 앱이 없습니다.",
|
|
867
|
+
"settings.slack.resetFailed": "Slack 앱 연결을 초기화하지 못했습니다. 다시 시도해주세요.",
|
|
868
|
+
"settings.slack.resetManagedByEnvironment": "이 Slack 연결은 환경변수({variables})로 관리되고 있습니다. 해당 환경변수를 제거하고 cli-jaw를 재시작한 후 연결을 초기화하세요.",
|
|
869
|
+
"settings.slack.managedByEnvironment": "연결 설정은 환경변수({variables})로 관리되어 읽기 전용입니다. 여기서 수정하려면 환경변수를 제거하고 cli-jaw를 재시작하세요.",
|
|
868
870
|
"settings.slack.attachPort": "연결 인스턴스 포트",
|
|
869
871
|
"settings.channel.notAttachInstanceHint": "다른 인스턴스가 이 Slack 연결을 소유하고 있습니다 (연결 인스턴스 포트 확인)",
|
|
870
872
|
"settings.slack.guide.step2Desc": "앱 설정 → OAuth & Permissions → files:read 확인 → Reinstall to Workspace → Bot User OAuth Token 복사",
|
|
@@ -893,9 +895,15 @@
|
|
|
893
895
|
"onboarding.title.slack": "Slack 연결",
|
|
894
896
|
"onboarding.guide.telegram": "텔레그램에서 @BotFather 를 열고 /newbot 을 보낸 뒤, 이름과 username을 정하면 봇 토큰이 나옵니다. 그 토큰을 아래에 붙여넣고 검증을 누르세요.",
|
|
895
897
|
"onboarding.guide.discord": "discord.com/developers/applications 에서 New Application → Bot → Reset Token 으로 토큰을 만들고, Privileged Gateway Intents 의 MESSAGE CONTENT INTENT 를 켜세요. 서버 ID는 Discord 설정에서 개발자 모드를 켠 뒤 서버 우클릭 → ID 복사로 얻습니다.",
|
|
896
|
-
"onboarding.guide.slack": "api.slack.com/apps
|
|
897
|
-
"onboarding.
|
|
898
|
-
"onboarding.
|
|
898
|
+
"onboarding.guide.slack": "api.slack.com/apps에서 Create New App → From a manifest의 JSON 탭에 복사된 매니페스트를 붙여넣고, 추가하려는 워크스페이스를 선택하여 앱을 생성해 주세요.",
|
|
899
|
+
"onboarding.slackAppName": "앱 이름",
|
|
900
|
+
"onboarding.slackAppNameHint": "앱과 봇에 함께 사용할 이름입니다. 영문 소문자, 숫자, -, _, .만 35자 이내로 입력하세요.",
|
|
901
|
+
"onboarding.slackGenerateManifest": "매니페스트 생성",
|
|
902
|
+
"onboarding.slackManifestGenerating": "생성 중...",
|
|
903
|
+
"onboarding.slackManifestReady": "복사되었습니다",
|
|
904
|
+
"onboarding.slackManifestError": "매니페스트를 생성하거나 복사하지 못했어요. 다시 시도해주세요.",
|
|
905
|
+
"onboarding.slackAppNameError": "영문 소문자, 숫자, -, _, .만 사용해 1~35자로 입력하세요.",
|
|
906
|
+
"onboarding.warning.missingCapabilities": "선택 권한({capabilities})이 없어 해당 기능만 꺼져 있습니다. 권한을 추가하고 앱을 재설치하세요. 텍스트 메시지는 계속 사용할 수 있습니다.",
|
|
899
907
|
"onboarding.token.botToken": "봇 토큰",
|
|
900
908
|
"onboarding.token.appToken": "앱 레벨 토큰",
|
|
901
909
|
"onboarding.token.guildId": "서버 ID",
|
|
@@ -920,6 +928,7 @@
|
|
|
920
928
|
"onboarding.validateHint": "검증을 눌러 실제 연결을 확인하세요. 통과해야 저장으로 넘어갑니다.",
|
|
921
929
|
"onboarding.saveHint": "검증을 통과했습니다. 저장을 누르면 설정에 반영되고 채널이 바로 연결됩니다.",
|
|
922
930
|
"onboarding.error.validation_required": "먼저 검증을 통과해야 합니다.",
|
|
931
|
+
"onboarding.error.slack_setup_required": "매니페스트를 생성하고 발급 페이지를 연 뒤 다음 단계로 진행하세요.",
|
|
923
932
|
"onboarding.openIssuer": "발급 페이지 열기",
|
|
924
933
|
"onboarding.error.missing_scopes": "토큰은 유효하지만 앱에 권한(스코프)이 부족합니다. OAuth & Permissions에서 아래 항목을 추가하고 앱을 재설치하세요.",
|
|
925
934
|
"onboarding.hint.telegram.botToken": "@BotFather가 /newbot 후 알려준 값입니다.",
|
package/public/locales/zh.json
CHANGED
|
@@ -534,7 +534,7 @@
|
|
|
534
534
|
"help.slack.link.portal": "Open the Slack app dashboard",
|
|
535
535
|
"help.slack.link.docs": "Socket Mode documentation",
|
|
536
536
|
"help.slack.example.1": "@cli-jaw run the tests for this repo",
|
|
537
|
-
"help.slack.howTo.1": "点击下方指南卡中的“复制清单”,然后在 api.slack.com/apps → Create
|
|
537
|
+
"help.slack.howTo.1": "点击下方指南卡中的“复制清单”,然后在 api.slack.com/apps → Create New App → From a manifest 粘贴以创建应用。",
|
|
538
538
|
"help.slack.howTo.2": "Enable Socket Mode and generate an app-level token (xapp-) with connections:write.",
|
|
539
539
|
"help.slack.howTo.3": "Install to the workspace to obtain the bot token (xoxb-).",
|
|
540
540
|
"help.slack.howTo.4": "Paste each token into its own field below — do not swap them.",
|
|
@@ -843,10 +843,6 @@
|
|
|
843
843
|
"bgtask.title": "后台任务",
|
|
844
844
|
"tg.elicitationExpired": "选择会话已过期,请用文字回复。",
|
|
845
845
|
"settings.slack.guide.step1Title": "创建 Slack 应用",
|
|
846
|
-
"settings.slack.guide.step1Desc": "Create an App → From an app manifest → 选择工作区 → 粘贴。现有应用需添加 files:read。",
|
|
847
|
-
"settings.slack.guide.copyManifest": "复制清单",
|
|
848
|
-
"settings.slack.guide.copyManifestDone": "已复制 — 请将含 files:read 的 manifest 粘贴到 Slack",
|
|
849
|
-
"settings.slack.guide.copyManifestFail": "复制失败 — 请使用 jaw slack manifest",
|
|
850
846
|
"settings.slack.guide.openApps": "打开应用页面",
|
|
851
847
|
"settings.slack.guide.step2Title": "粘贴机器人令牌",
|
|
852
848
|
"settings.slack.guide.step3Title": "接收用应用令牌(可选)",
|
|
@@ -854,6 +850,12 @@
|
|
|
854
850
|
"settings.slack.guide.botTokenError": "需要以 xoxb- 开头的机器人令牌 — 是否与应用令牌填反了?",
|
|
855
851
|
"settings.slack.guide.appTokenError": "需要以 xapp- 开头的应用级令牌 — 是否与机器人令牌填反了?",
|
|
856
852
|
"settings.slack.advanced": "高级设置",
|
|
853
|
+
"settings.slack.resetConnection": "重置连接",
|
|
854
|
+
"settings.slack.resetConfirm": "Slack 应用连接将被重置。是否继续?",
|
|
855
|
+
"settings.slack.resetEmpty": "当前没有已连接的 Slack 应用。",
|
|
856
|
+
"settings.slack.resetFailed": "无法重置 Slack 应用连接,请重试。",
|
|
857
|
+
"settings.slack.resetManagedByEnvironment": "此 Slack 连接由环境变量({variables})管理。请删除这些环境变量并重启 cli-jaw,然后再重置连接。",
|
|
858
|
+
"settings.slack.managedByEnvironment": "连接设置由环境变量({variables})管理,因此为只读。若要在此编辑,请删除这些变量并重启 cli-jaw。",
|
|
857
859
|
"settings.slack.attachPort": "连接实例端口",
|
|
858
860
|
"settings.channel.notAttachInstanceHint": "另一个实例拥有此 Slack 连接(请检查连接实例端口)",
|
|
859
861
|
"settings.slack.guide.step2Desc": "应用设置 → OAuth & Permissions → 确认 files:read → Reinstall to Workspace → 复制 Bot User OAuth Token",
|
|
@@ -882,9 +884,15 @@
|
|
|
882
884
|
"onboarding.title.slack": "连接 Slack",
|
|
883
885
|
"onboarding.guide.telegram": "Open @BotFather in Telegram, send /newbot, pick a name and username, and copy the bot token it returns. Paste it below and press Validate.",
|
|
884
886
|
"onboarding.guide.discord": "At discord.com/developers/applications choose New Application, then Bot, then Reset Token. Enable MESSAGE CONTENT INTENT under Privileged Gateway Intents. Get the server ID by enabling Developer Mode in Discord, then right-click the server and copy its ID.",
|
|
885
|
-
"onboarding.guide.slack": "
|
|
886
|
-
"onboarding.
|
|
887
|
-
"onboarding.
|
|
887
|
+
"onboarding.guide.slack": "在 api.slack.com/apps 中选择 Create New App → From a manifest,将复制的清单粘贴到 JSON 标签页,选择要添加应用的工作区,然后创建应用。",
|
|
888
|
+
"onboarding.slackAppName": "应用名称",
|
|
889
|
+
"onboarding.slackAppNameHint": "该名称同时用于应用和机器人。请使用小写英文字母、数字、-、_、.,最多35个字符。",
|
|
890
|
+
"onboarding.slackGenerateManifest": "生成清单",
|
|
891
|
+
"onboarding.slackManifestGenerating": "正在生成...",
|
|
892
|
+
"onboarding.slackManifestReady": "已复制",
|
|
893
|
+
"onboarding.slackManifestError": "无法生成或复制清单,请重试。",
|
|
894
|
+
"onboarding.slackAppNameError": "请使用小写英文字母、数字、-、_、.,输入1到35个字符。",
|
|
895
|
+
"onboarding.warning.missingCapabilities": "缺少可选权限 {capabilities},相应功能已关闭。请添加权限并重新安装应用。文本消息仍可使用。",
|
|
888
896
|
"onboarding.token.botToken": "机器人令牌",
|
|
889
897
|
"onboarding.token.appToken": "应用级令牌",
|
|
890
898
|
"onboarding.token.guildId": "服务器 ID",
|
|
@@ -909,6 +917,7 @@
|
|
|
909
917
|
"onboarding.validateHint": "点击验证以检查实际连接。通过后才能保存。",
|
|
910
918
|
"onboarding.saveHint": "验证通过。保存后将写入设置并立即连接该渠道。",
|
|
911
919
|
"onboarding.error.validation_required": "需要先通过验证。",
|
|
920
|
+
"onboarding.error.slack_setup_required": "请先生成清单并打开发放页面,然后再继续。",
|
|
912
921
|
"onboarding.openIssuer": "打开签发页面",
|
|
913
922
|
"onboarding.error.missing_scopes": "令牌有效,但应用缺少 OAuth 权限(scope)。请在 OAuth & Permissions 中添加下列项并重新安装应用。",
|
|
914
923
|
"onboarding.hint.telegram.botToken": "@BotFather 在 /newbot 之后返回的值。",
|
|
@@ -42,6 +42,7 @@ export function stripServerOwnedSettingsFields(settings: Record<string, unknown>
|
|
|
42
42
|
settingsSchemaVersion: _schema,
|
|
43
43
|
runtimeDefaultMigration: _migration,
|
|
44
44
|
multiSessionDefaultMigration: _sessionMigration,
|
|
45
|
+
slackEnvironmentVariables: _slackEnvironmentVariables,
|
|
45
46
|
...userOwned
|
|
46
47
|
} = settings;
|
|
47
48
|
return userOwned;
|
|
@@ -57,7 +57,8 @@ type AgentSnapshot = AgentSettingsSnapshot & {
|
|
|
57
57
|
type CliStatusInfo = {
|
|
58
58
|
available: boolean | null;
|
|
59
59
|
capabilityReady: boolean | null;
|
|
60
|
-
probeState: 'checking' | 'fresh' | 'stale';
|
|
60
|
+
probeState: 'checking' | 'fresh' | 'stale' | 'failing';
|
|
61
|
+
probeError?: string;
|
|
61
62
|
};
|
|
62
63
|
|
|
63
64
|
export function conflictSettingsFromError(error: unknown): AgentSnapshot | null {
|
|
@@ -333,6 +334,14 @@ export default function Agent({ port, client, dirty, registerSave }: SettingsPag
|
|
|
333
334
|
{cliStatus[draft.cli]?.probeState === 'checking' ? (
|
|
334
335
|
<div className="settings-inline-notice" role="status" aria-live="polite">상태 확인 중</div>
|
|
335
336
|
) : null}
|
|
337
|
+
{cliStatus[draft.cli]?.probeState === 'failing' ? (
|
|
338
|
+
// Without this the panel stays silent while every probe errors,
|
|
339
|
+
// which is the state #277 reported as an endless "stale".
|
|
340
|
+
<div className="settings-inline-notice" role="alert">
|
|
341
|
+
상태 확인 실패 (재시도 중)
|
|
342
|
+
{cliStatus[draft.cli]?.probeError ? `: ${cliStatus[draft.cli]!.probeError}` : ''}
|
|
343
|
+
</div>
|
|
344
|
+
) : null}
|
|
336
345
|
<RuntimeHeader
|
|
337
346
|
cli={draft.cli}
|
|
338
347
|
cliOptions={cliOptions.length > 0 ? cliOptions : [draft.cli || 'claude']}
|
|
@@ -42,6 +42,7 @@ type SlackBlock = {
|
|
|
42
42
|
type SlackSnapshot = {
|
|
43
43
|
channel?: ActiveChannel;
|
|
44
44
|
slack?: SlackBlock;
|
|
45
|
+
slackEnvironmentVariables?: string[];
|
|
45
46
|
[key: string]: unknown;
|
|
46
47
|
};
|
|
47
48
|
|
|
@@ -117,6 +118,10 @@ export default function ChannelsSlack({ port, client, dirty, registerSave }: Set
|
|
|
117
118
|
}, [state]);
|
|
118
119
|
|
|
119
120
|
const originalChannel = state.kind === 'ready' ? state.data.channel : undefined;
|
|
121
|
+
const environmentVariables = state.kind === 'ready' && Array.isArray(state.data.slackEnvironmentVariables)
|
|
122
|
+
? state.data.slackEnvironmentVariables
|
|
123
|
+
: [];
|
|
124
|
+
const environmentManaged = environmentVariables.length > 0;
|
|
120
125
|
|
|
121
126
|
const onSave = useCallback(async () => {
|
|
122
127
|
const bundle = dirty.saveBundle();
|
|
@@ -157,7 +162,9 @@ export default function ChannelsSlack({ port, client, dirty, registerSave }: Set
|
|
|
157
162
|
// Surface the outbound-only state on THIS page rather than changing the
|
|
158
163
|
// shared status chips, which are frozen for cross-channel changes.
|
|
159
164
|
const outboundOnly = Boolean(original.enabled) && Boolean(original.botToken) && !original.appToken;
|
|
160
|
-
const slackHint =
|
|
165
|
+
const slackHint = environmentManaged
|
|
166
|
+
? `Connection settings are read-only because they are managed by environment variables: ${environmentVariables.join(', ')}.`
|
|
167
|
+
: outboundOnly
|
|
161
168
|
? 'Currently OUTBOUND-ONLY: the app-level token (xapp-) is missing, so no inbound Slack events can arrive.'
|
|
162
169
|
: 'Slack needs TWO tokens: a bot token (xoxb-) for the Web API and an app-level token (xapp-) for Socket Mode.';
|
|
163
170
|
|
|
@@ -189,6 +196,7 @@ export default function ChannelsSlack({ port, client, dirty, registerSave }: Set
|
|
|
189
196
|
id="sl-enabled"
|
|
190
197
|
label="Slack enabled"
|
|
191
198
|
value={enabled}
|
|
199
|
+
disabled={environmentManaged}
|
|
192
200
|
onChange={(next) => {
|
|
193
201
|
setEnabled(next);
|
|
194
202
|
setEntry('slack.enabled', {
|
|
@@ -204,6 +212,7 @@ export default function ChannelsSlack({ port, client, dirty, registerSave }: Set
|
|
|
204
212
|
value={botToken}
|
|
205
213
|
placeholder={maskOf(original.botToken)}
|
|
206
214
|
error={botTokenError}
|
|
215
|
+
disabled={environmentManaged}
|
|
207
216
|
onChange={(next) => {
|
|
208
217
|
setBotToken(next);
|
|
209
218
|
if (next.length === 0) {
|
|
@@ -223,6 +232,7 @@ export default function ChannelsSlack({ port, client, dirty, registerSave }: Set
|
|
|
223
232
|
value={appToken}
|
|
224
233
|
placeholder={maskOf(original.appToken)}
|
|
225
234
|
error={appTokenError}
|
|
235
|
+
disabled={environmentManaged}
|
|
226
236
|
onChange={(next) => {
|
|
227
237
|
setAppToken(next);
|
|
228
238
|
if (next.length === 0) {
|
|
@@ -241,6 +251,7 @@ export default function ChannelsSlack({ port, client, dirty, registerSave }: Set
|
|
|
241
251
|
label="Team ID"
|
|
242
252
|
value={teamId}
|
|
243
253
|
placeholder="T01234567 (optional)"
|
|
254
|
+
disabled={environmentManaged}
|
|
244
255
|
onChange={(next) => {
|
|
245
256
|
setTeamId(next);
|
|
246
257
|
setEntry('slack.teamId', {
|
|
@@ -256,6 +267,7 @@ export default function ChannelsSlack({ port, client, dirty, registerSave }: Set
|
|
|
256
267
|
value={channelIds}
|
|
257
268
|
placeholder="C01234567"
|
|
258
269
|
error={channelIdsError}
|
|
270
|
+
disabled={environmentManaged}
|
|
259
271
|
onChange={(next) => {
|
|
260
272
|
setChannelIds(next);
|
|
261
273
|
setEntry('slack.channelIds', {
|
package/scripts/atomic-build.sh
CHANGED
|
@@ -18,10 +18,17 @@ cp -R src/prompt/templates/. "$STAGING/src/prompt/templates/"
|
|
|
18
18
|
cp -R prompts/. "$STAGING/prompts/"
|
|
19
19
|
cp -R src/browser/adaptive-fetch/vendor/. "$STAGING/src/browser/adaptive-fetch/vendor/"
|
|
20
20
|
|
|
21
|
-
#
|
|
21
|
+
# bun-shim.mjs is a COMMITTED source asset, unlike the jawcode bundles below
|
|
22
|
+
# which are generated and gitignored. jawcode-render.ts imports the shim
|
|
23
|
+
# unconditionally, so gating its copy on a generated artifact made every clean
|
|
24
|
+
# build (CI, release, any fresh checkout) publish a dist that cannot load its
|
|
25
|
+
# own renderer — `jaw chat --raw` then died with ERR_MODULE_NOT_FOUND (#275).
|
|
26
|
+
mkdir -p "$STAGING/src/lib/tui"
|
|
27
|
+
cp src/lib/tui/bun-shim.mjs "$STAGING/src/lib/tui/"
|
|
28
|
+
|
|
29
|
+
# jawcode TUI bundle + native addon (macOS only)
|
|
22
30
|
if [ -f src/lib/tui/jawcode-tui-bundle.mjs ]; then
|
|
23
|
-
mkdir -p "$STAGING/src/lib/
|
|
24
|
-
cp src/lib/tui/bun-shim.mjs "$STAGING/src/lib/tui/"
|
|
31
|
+
mkdir -p "$STAGING/src/lib/native"
|
|
25
32
|
cp src/lib/tui/jawcode-tui-bundle.mjs "$STAGING/src/lib/tui/"
|
|
26
33
|
[ -f src/lib/tui/jawcode-interactive-bundle.mjs ] && cp src/lib/tui/jawcode-interactive-bundle.mjs "$STAGING/src/lib/tui/"
|
|
27
34
|
NATIVE_TAG="$(node -p '`${process.platform}-${process.arch}`')"
|