release: 0.1.5 — hide IM adapter UI (out of product scope)

Per product-package design docs, IM integration (Lark / Feishu /
Telegram) is not a Heicode surface. Hide UI without ripping out
plumbing — keep AdapterSettings.tsx + adapterStore + types in the
source tree so re-enabling is a one-flag flip.

- Settings.tsx: drop the "IM 接入" tab button (`'adapters'` route
  still resolves internally if someone forces it, but no nav).
- NewTaskModal.tsx: remove the IM notification channel pickers
  (Feishu / Telegram checkboxes + "no channel configured" warning).
  Existing task `notification` config is preserved on edit; it's
  just no longer mutable from this UI.
- Unused imports (useEffect, useAdapterStore) cleaned to satisfy
  TS strict mode.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-13 16:13:05 +08:00
co-authored by Claude Opus 4.7
parent 6c477881c4
commit da80b97f54
5 changed files with 20 additions and 80 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "heicode-desktop",
"private": true,
"version": "0.1.4",
"version": "0.1.5",
"type": "module",
"scripts": {
"dev": "vite",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "heicode-desktop"
version = "0.1.4"
version = "0.1.5"
edition = "2021"
[lib]
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://raw.githubusercontent.com/nicegui/nicegui/main/nicegui/static/tauri-schema-v2.json",
"productName": "HeiCode",
"version": "0.1.4",
"version": "0.1.5",
"identifier": "com.heicode.desktop",
"build": {
"frontendDist": "../dist",
@@ -1,7 +1,6 @@
import { useState, useEffect } from 'react'
import { useState } from 'react'
import { useTaskStore } from '../../stores/taskStore'
import { useSessionStore } from '../../stores/sessionStore'
import { useAdapterStore } from '../../stores/adapterStore'
import { Modal } from '../shared/Modal'
import { Input } from '../shared/Input'
import { Button } from '../shared/Button'
@@ -60,17 +59,11 @@ export function NewTaskModal({ open, onClose, editTask }: Props) {
const activeSessionId = useSessionStore((s) => s.activeSessionId)
const activeSession = sessions.find((s) => s.id === activeSessionId)
const defaultWorkDir = activeSession?.workDir || ''
const adapterConfig = useAdapterStore((s) => s.config)
const fetchAdapterConfig = useAdapterStore((s) => s.fetchConfig)
useEffect(() => {
if (open) fetchAdapterConfig()
}, [open])
const isFeishuConfigured = !!(adapterConfig.feishu?.appId && adapterConfig.feishu?.appSecret
&& ((adapterConfig.feishu?.pairedUsers?.length ?? 0) > 0 || (adapterConfig.feishu?.allowedUsers?.length ?? 0) > 0))
const isTelegramConfigured = !!(adapterConfig.telegram?.botToken
&& ((adapterConfig.telegram?.pairedUsers?.length ?? 0) > 0 || (adapterConfig.telegram?.allowedUsers?.length ?? 0) > 0))
// IM adapter config previously used here for the "notify on complete"
// channel pickers. UI hidden — adapter integration is out of scope per
// product-package docs. Keeping the imports/state removed to keep TS
// strict-mode happy; the adapterStore itself stays in tree for any
// future re-enable.
const isEdit = !!editTask
const parsed = editTask ? parseCron(editTask.cron) : null
@@ -94,8 +87,10 @@ export function NewTaskModal({ open, onClose, editTask }: Props) {
const [permissionMode, setPermissionMode] = useState<PermissionMode>((editTask?.permissionMode as PermissionMode) || 'default')
const [folderPath, setFolderPath] = useState(editTask?.folderPath || defaultWorkDir)
const [useWorktree, setUseWorktree] = useState(editTask?.useWorktree || false)
const [notifyEnabled, setNotifyEnabled] = useState(editTask?.notification?.enabled || false)
const [notifyChannels, setNotifyChannels] = useState<('telegram' | 'feishu')[]>(editTask?.notification?.channels || [])
// Preserve any existing IM notification config on edit, but the UI no
// longer exposes a way to change these — they pass through unchanged.
const [notifyEnabled] = useState(editTask?.notification?.enabled || false)
const [notifyChannels] = useState<('telegram' | 'feishu')[]>(editTask?.notification?.channels || [])
const [isSubmitting, setIsSubmitting] = useState(false)
// Enhanced scheduling state
@@ -325,67 +320,9 @@ export function NewTaskModal({ open, onClose, editTask }: Props) {
</div>
)}
{/* Notification */}
<div className="flex flex-col gap-3 rounded-[var(--radius-md)] border border-[var(--color-border)] p-3">
<label className="flex items-center gap-3 cursor-pointer">
<input
type="checkbox"
checked={notifyEnabled}
onChange={(e) => setNotifyEnabled(e.target.checked)}
className="w-4 h-4 rounded border-[var(--color-border)] accent-[var(--color-brand)]"
/>
<div>
<span className="text-sm font-medium text-[var(--color-text-primary)]">{t('newTask.notifyOnComplete')}</span>
<p className="text-xs text-[var(--color-text-tertiary)]">{t('newTask.notifyHint')}</p>
</div>
</label>
{notifyEnabled && (
<div className="flex flex-col gap-2 pl-7">
<div className="flex items-center gap-4">
<label className={`flex items-center gap-2 ${isFeishuConfigured ? 'cursor-pointer' : 'opacity-50 cursor-not-allowed'}`}>
<input
type="checkbox"
checked={notifyChannels.includes('feishu')}
disabled={!isFeishuConfigured}
onChange={(e) => {
setNotifyChannels((prev) =>
e.target.checked ? [...prev, 'feishu'] : prev.filter((c) => c !== 'feishu'),
)
}}
className="w-3.5 h-3.5 rounded border-[var(--color-border)] accent-[var(--color-brand)]"
/>
<span className="text-sm text-[var(--color-text-primary)]">{t('settings.adapters.feishu')}</span>
{!isFeishuConfigured && (
<span className="text-[10px] text-[var(--color-warning)]">{t('newTask.notConfigured')}</span>
)}
</label>
<label className={`flex items-center gap-2 ${isTelegramConfigured ? 'cursor-pointer' : 'opacity-50 cursor-not-allowed'}`}>
<input
type="checkbox"
checked={notifyChannels.includes('telegram')}
disabled={!isTelegramConfigured}
onChange={(e) => {
setNotifyChannels((prev) =>
e.target.checked ? [...prev, 'telegram'] : prev.filter((c) => c !== 'telegram'),
)
}}
className="w-3.5 h-3.5 rounded border-[var(--color-border)] accent-[var(--color-brand)]"
/>
<span className="text-sm text-[var(--color-text-primary)]">{t('settings.adapters.telegram')}</span>
{!isTelegramConfigured && (
<span className="text-[10px] text-[var(--color-warning)]">{t('newTask.notConfigured')}</span>
)}
</label>
</div>
{!isFeishuConfigured && !isTelegramConfigured && (
<p className="text-xs text-[var(--color-warning)]">
<span className="material-symbols-outlined text-[12px] align-middle mr-1">warning</span>
{t('newTask.noChannelConfigured')}
</p>
)}
</div>
)}
</div>
{/* IM notification channel UI removed — product-package design docs
do not include Lark/Feishu/Telegram as a Heicode surface. Underlying
adapter store + types stay in tree; just the UI is hidden. */}
{/* Cron preview */}
<div className="flex items-center gap-2 px-3 py-2 rounded-[var(--radius-md)] bg-[var(--color-surface-container)] text-xs text-[var(--color-text-secondary)]">
+4 -1
View File
@@ -49,7 +49,10 @@ export function Settings() {
<div className="flex-1">
<TabButton icon="shield" label={t('settings.tab.permissions')} active={activeTab === 'permissions'} onClick={() => setActiveTab('permissions')} />
<TabButton icon="tune" label={t('settings.tab.general')} active={activeTab === 'general'} onClick={() => setActiveTab('general')} />
<TabButton icon="chat" label={t('settings.tab.adapters')} active={activeTab === 'adapters'} onClick={() => setActiveTab('adapters')} />
{/* IM 接入 (Lark / Feishu / Telegram adapter settings) is hidden —
the product-package design docs do not include IM as a Heicode
surface. Underlying AdapterSettings.tsx + adapterStore stay in
the source tree so we can bring it back if product reverses. */}
<TabButton icon="dns" label={t('settings.tab.mcp')} active={activeTab === 'mcp'} onClick={() => setActiveTab('mcp')} />
<TabButton icon="smart_toy" label={t('settings.tab.agents')} active={activeTab === 'agents'} onClick={() => setActiveTab('agents')} />
<TabButton icon="auto_awesome" label={t('settings.tab.skills')} active={activeTab === 'skills'} onClick={() => setActiveTab('skills')} />