sintbot 1.4.16 → 1.4.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/CHANGELOG.en.json CHANGED
@@ -1,4 +1,66 @@
1
1
  [
2
+ {
3
+ "version": "1.4.18",
4
+ "date": "2026-11-12",
5
+ "name": "Browser setup and Claude idle compaction",
6
+ "items": [
7
+ {
8
+ "t": "Connect Feishu in the browser",
9
+ "d": "The first start opens a local setup page for project selection, phone confirmation, progress and resumable failures. Once configuration and journals are initialized, the page enters the console automatically. English and Chinese are supported."
10
+ },
11
+ {
12
+ "t": "Save explicit model and thinking-depth choices for new groups",
13
+ "d": "Before scanning, setup reads the selected executor's live recommended model and thinking depth and saves them for the new group. An unavailable live catalog stops setup before app creation; existing choices are preserved."
14
+ },
15
+ {
16
+ "t": "Safer cancellation and retries",
17
+ "d": "Cancellation stops at step boundaries. Retries reuse confirmed apps and groups, while configuration writes recheck current state to avoid overwriting another instance's setup."
18
+ },
19
+ {
20
+ "t": "Idle compaction for Claude groups (experimental)",
21
+ "d": "Claude Code versions advertising compact can compact an idle session after a task when context reaches half the configured compaction window. New work stops compaction first. Successful compaction and cache behavior still await real-model validation."
22
+ },
23
+ {
24
+ "t": "Immediate Claude quota updates from events",
25
+ "d": "Quota events from each run refresh the display promptly and reduce extra quota requests. Existing API and cache paths remain when events are unavailable."
26
+ },
27
+ {
28
+ "t": "Compaction exit protection and clearer setup guidance",
29
+ "d": "Unconfirmed process exit retains capacity and blocks further dispatch for that group. Configuration-file notices, language-specific guide links and startup instructions are also corrected."
30
+ }
31
+ ]
32
+ },
33
+ {
34
+ "version": "1.4.17",
35
+ "date": "2026-11-12",
36
+ "name": "Feishu scan-to-connect and third-party quotas",
37
+ "items": [
38
+ {
39
+ "t": "Connect Feishu with one scan",
40
+ "d": "New command sintbot connect: scan a QR code in the Feishu app to create the bot app; SintBot self-checks, opens the contact and availability scope and publishes, creates ~/Projects/<name>, creates a group with you in it, writes the configuration and initializes journals. On failure it stops at that step and tells you how to resume (--app-id, --chat); non-admins in a company organization can use --basic. The manual path remains."
41
+ },
42
+ {
43
+ "t": "Simpler Feishu settings",
44
+ "d": "Connection status and project groups come first. New users get a three-step scan setup guide; manual setup and app details are folded away. Console administrator sign-in is separate."
45
+ },
46
+ {
47
+ "t": "Third-party quota and balance",
48
+ "d": "GLM shows the 5-hour and weekly windows and falls back to the balance without a plan; MiniMax shows the 5-hour and weekly windows; DeepSeek shows the balance. Invalid credentials are shown as such; transient failures keep the last value for 10 minutes."
49
+ },
50
+ {
51
+ "t": "Claude subscription quota fallback",
52
+ "d": "When the Claude Code login token has expired, the CLI refreshes it itself and SintBot reads its cached quota instead of showing \"unverified\"; read-only, never refreshing on its own, never blocking group commands or the console."
53
+ },
54
+ {
55
+ "t": "Environment conflict check",
56
+ "d": "Preflight and the console model cards list environment variables and ~/.claude/settings.json or ~/.codex/config.toml settings that would reroute Claude Code or Codex; key names only, warnings only."
57
+ },
58
+ {
59
+ "t": "Built-in core ABI 36",
60
+ "d": "Connect decisions and wording, QR encoding, quota parsing and environment checks live in the built-in core; the core build pins its toolchain and no longer depends on the crate mirror used by the builder."
61
+ }
62
+ ]
63
+ },
2
64
  {
3
65
  "version": "1.4.16",
4
66
  "date": "2026-11-11",
package/CHANGELOG.json CHANGED
@@ -1,4 +1,66 @@
1
1
  [
2
+ {
3
+ "version": "1.4.18",
4
+ "date": "2026-11-12",
5
+ "name": "浏览器接入与 Claude 空闲整理",
6
+ "items": [
7
+ {
8
+ "t": "在浏览器完成飞书接入",
9
+ "d": "首次启动会打开本机接入页;填写项目、扫码确认、查看进度与失败续做均在页面完成。配置和日志初始化完成后自动进入控制台,支持中英文。"
10
+ },
11
+ {
12
+ "t": "为新群明确保存型号与思考深度",
13
+ "d": "扫码前读取所选执行器的实时推荐型号和思考深度,并保存为新群设置;取不到实时清单时先停止接入,已有选择不会被覆盖。"
14
+ },
15
+ {
16
+ "t": "接入取消与重试更可靠",
17
+ "d": "取消会在步骤边界停止;重试复用已确认的应用和群,写配置前再次检查已有状态,避免覆盖其他实例的配置。"
18
+ },
19
+ {
20
+ "t": "Claude 群空闲整理(实验性)",
21
+ "d": "支持 compact 的 Claude Code 可在任务结束后、上下文达到自定义压缩窗口一半时整理当前会话;有新任务时先停止整理。成功压缩和缓存效果的真实模型验收仍待补充。"
22
+ },
23
+ {
24
+ "t": "Claude 额度事件即时更新",
25
+ "d": "优先读取每轮自带的额度事件,及时更新用量显示并减少额外额度查询;没有事件时保留既有接口与缓存路径。"
26
+ },
27
+ {
28
+ "t": "整理退出保护与接入说明修正",
29
+ "d": "未确认整理进程退出时保留并发名额并阻止该群继续派发;同步修正配置文件提示、指南语言链接及启动说明。"
30
+ }
31
+ ]
32
+ },
33
+ {
34
+ "version": "1.4.17",
35
+ "date": "2026-11-12",
36
+ "name": "飞书扫码接入与第三方额度",
37
+ "items": [
38
+ {
39
+ "t": "扫码一键接入飞书",
40
+ "d": "新命令 sintbot connect:手机飞书扫码即创建机器人应用,自动自检、放开通讯录与可用范围并发版,新建项目目录 ~/Projects/<项目名>,建群并拉你进群,写入配置并初始化日志。失败时按步骤停下并给出续做方式(--app-id、--chat);公司组织里的非管理员可用 --basic。手动接入流程保留。"
41
+ },
42
+ {
43
+ "t": "飞书设置按使用流程整理",
44
+ "d": "优先查看连接状态和管理项目群;新用户按扫码、自动建群、群里发任务三步开始。手动接入与应用信息收进高级说明,管理员和控制台登录单独设置。"
45
+ },
46
+ {
47
+ "t": "第三方额度与余额",
48
+ "d": "GLM 显示 5 小时 / 周配额窗口,没有套餐时退回查余额;MiniMax 显示 5 小时与周窗口;DeepSeek 余额。凭据失效会明确显示,瞬时故障保留上次结果 10 分钟。"
49
+ },
50
+ {
51
+ "t": "Claude 登录额度兜底",
52
+ "d": "Claude Code 登录令牌过期时,由 CLI 自行刷新并读取其缓存的额度,不再显示「未验证」;只读不代刷,不阻塞群命令和控制台。"
53
+ },
54
+ {
55
+ "t": "环境冲突检查",
56
+ "d": "预检与控制台模型卡列出会改道 Claude Code / Codex 的环境变量和 ~/.claude/settings.json、~/.codex/config.toml 设置,只列键名,只提示不修改。"
57
+ },
58
+ {
59
+ "t": "内置核心 ABI 36",
60
+ "d": "扫码接入的决策与文案、二维码编码、额度解析和环境冲突判定都在内置核心中实现;核心构建锁定工具链,产物不再依赖构建机使用的 crate 镜像。"
61
+ }
62
+ ]
63
+ },
2
64
  {
3
65
  "version": "1.4.16",
4
66
  "date": "2026-11-11",
package/README.md CHANGED
@@ -45,7 +45,7 @@ curl -fsSL https://sintbot.com/install.sh | bash
45
45
 
46
46
  The script checks the environment, installs SintBot and verifies the result, without `sudo`. You can read [install.sh](./install.sh) before running it. Installation does not sign in to a model account, connect a group or start a service.
47
47
 
48
- **2. Connect your group and project.** Follow the [installation guide](https://sintbot.com/guide/install/) to prepare Codex or Claude Code, connect a Feishu app and bind the group to a local project. The guide covers the currently distributed package, its configuration and startup steps.
48
+ **2. Connect your group and project.** Run `sintbot start --ui`; the browser opens the local setup page. Enter a project name and scan the QR code with Feishu under an enterprise or team identity: it creates the app, a project folder and a group, then writes the configuration. The [installation guide](https://sintbot.com/guide/install/) covers the options, the manual route and the startup steps.
49
49
 
50
50
  Installing with an AI assistant? Use the [AI-assisted install and first-use guide](./docs/AI-ASSISTED-INSTALL.md).
51
51
 
package/README.zh-CN.md CHANGED
@@ -45,7 +45,7 @@ curl -fsSL https://sintbot.com/install.sh | bash
45
45
 
46
46
  脚本会检查环境、安装 SintBot 并验证结果,不用 `sudo`。也可以先读 [install.sh](./install.sh)。安装本身不登录模型账号、不连接群,也不启动服务。
47
47
 
48
- **2. 接入群和项目。** 按[安装指南](https://sintbot.com/zh/guide/install/)准备 Codex 或 Claude Code、连接飞书应用,并把群绑定到本机项目目录。当前安装包的配置与启动步骤以指南为准。
48
+ **2. 接入群和项目。** 运行 `sintbot start --ui`,浏览器会打开本机接入页;填项目名、用企业/团队身份的飞书扫码,它会创建应用、项目目录和群,写好配置并直接启动。终端里也可以用 `sintbot connect`。参数、手动路径和启动步骤见[安装指南](https://sintbot.com/zh/guide/install/)。
49
49
 
50
50
  想让本机 AI 助手帮忙安装并完成首次使用?先看 [AI 安装与首次使用说明](./docs/zh-CN/AI-ASSISTED-INSTALL.md)。
51
51
 
package/bin/sintbot-v2.js CHANGED
@@ -24,10 +24,22 @@ async function startService(rest) {
24
24
  'no-open': { type: 'boolean' }, 'ui-port': { type: 'string' },
25
25
  'ui-host': { type: 'string' }, preflight: { type: 'boolean' } } })
26
26
  const preflightOnly = values.preflight === true
27
- const { loadInstallation, assertPrivateDirectory, assertInstallationJournals, assertJournalScope } = require('../src/c2install')
27
+ const { loadInstallation, assertPrivateDirectory, assertInstallationJournals, assertJournalScope, installationStateDir } = require('../src/c2install')
28
+ // Setup mode: no configuration yet. With --ui, serve the local scan-to-connect
29
+ // page (src/setupserver.js) in this process; it writes the configuration and
30
+ // initializes the journals, then the normal start below continues.
31
+ const setupConfig = path.resolve(values.config || process.env.SBOT_CONFIG || path.join(installationStateDir(values['data-dir']), 'config.json'))
32
+ if (!fs.existsSync(setupConfig)) {
33
+ if (preflightOnly || values.ui !== true) {
34
+ throw new Error('No configuration yet. Run `sintbot start --ui` and connect Feishu in the browser (or `sintbot connect` in the terminal)')
35
+ }
36
+ await runSetupMode({ configFile: setupConfig, dataDir: values['data-dir'],
37
+ host: values['ui-host'] || '127.0.0.1', port: Number(values['ui-port'] || 4600),
38
+ open: values['no-open'] !== true })
39
+ }
28
40
  // Groups added to the configuration since the last start are registered
29
41
  // below, after the writer lock is held; existing journals stay as mapped.
30
- const installation = loadInstallation(values.config, { dataDir: values['data-dir'], allowAddedGroups: true })
42
+ const installation = loadInstallation(setupConfig, { dataDir: values['data-dir'], allowAddedGroups: true })
31
43
  const { stateDir, file, cfg, groups, routes, serviceChatId, provider } = installation
32
44
  const uiEnabled = values.ui === true || cfg.ui?.enabled === true
33
45
  const uiHost = values['ui-host'] || cfg.ui?.host || '127.0.0.1'
@@ -43,11 +55,47 @@ async function startService(rest) {
43
55
  throw new Error('Console options require --ui or ui.enabled:true')
44
56
  }
45
57
  assertInstallationJournals(installation)
58
+ // Settings outside this installation that can reroute a CLI (daemon env,
59
+ // ~/.claude/settings.json, ~/.codex/config.toml): warn-only, keys not values.
60
+ if (preflightOnly) require('../src/agent/envconflicts').reportEnvConflicts(installation)
46
61
  // Every installation, including one group, runs the multi-group service:
47
62
  // chat commands, the console writer and per-group fault closing live there.
48
63
  return startMultiGroupService({ installation, preflightOnly, uiEnabled, uiHost, uiPort })
49
64
  }
50
65
 
66
+ // Serve the setup page until the configuration exists. The page is local only;
67
+ // the browser is opened once. Ctrl-C cancels the scan in progress and exits.
68
+ async function runSetupMode({ configFile, dataDir, host, port, open }) {
69
+ const { createSetupServer, probeRunners } = require('../src/setupserver')
70
+ const os = require('node:os')
71
+ if (!Number.isSafeInteger(port) || port < 1 || port > 65535) throw new Error('Console port is invalid')
72
+ const setup = createSetupServer({ configFile, dataDir, home: os.homedir(), version: require('../package.json').version,
73
+ runners: probeRunners(), host, port, log: message => process.stderr.write(`Setup · ${message}\n`) })
74
+ await setup.listen()
75
+ const url = `http://${host === '::1' ? '[::1]' : host}:${port}/`
76
+ process.stderr.write(`SintBot has no Feishu configuration yet. Open ${url} to connect by scanning.\n`)
77
+ if (open && process.platform === 'darwin') {
78
+ try { require('node:child_process').spawn('open', [url], { stdio: 'ignore', detached: true }).unref() } catch {}
79
+ }
80
+ // Ctrl-C: cancel the run (runConnect stops at its next step boundary, writing
81
+ // nothing), wait for it to end, then exit.
82
+ const onSignal = () => {
83
+ setup.session.cancel()
84
+ const ended = Promise.race([Promise.resolve(setup.session.wait()).catch(() => {}), new Promise(resolve => setTimeout(resolve, 15_000))])
85
+ ended.then(() => setup.close()).finally(() => process.exit(130))
86
+ }
87
+ process.once('SIGINT', onSignal); process.once('SIGTERM', onSignal)
88
+ try {
89
+ await setup.completed
90
+ // Let the page read the final state before the console takes the port.
91
+ await new Promise(resolve => setTimeout(resolve, 3000))
92
+ } finally {
93
+ process.off('SIGINT', onSignal); process.off('SIGTERM', onSignal)
94
+ await setup.close()
95
+ }
96
+ process.stderr.write('Setup · Feishu connected; starting the service\n')
97
+ }
98
+
51
99
  // Model and depth used to live on model cards; they now belong to each group.
52
100
  // Once every group is connected (a console upgrade can no longer roll back
53
101
  // onto this configuration), copy each card's value into the groups that have
@@ -111,6 +159,7 @@ async function startMultiGroupService({ installation, preflightOnly, uiEnabled =
111
159
  const { C2DurableRuntime } = require('../src/core/c2durableruntime')
112
160
  // /hud reads the group's model quota; /issue appends to the console's log.
113
161
  const usageProbe = require('../src/usage').createUsageProbe({
162
+ bin: cfg.agent?.bin || 'claude',
114
163
  codexUsage: async () => { const status = require('../src/agent/codexstatus')
115
164
  return status.formatUsage(await status.rateLimits('codex')) } })
116
165
  const issues = require('../src/core/issues').createIssues(path.join(stateDir, 'issues.jsonl'),
@@ -305,6 +354,19 @@ async function startMultiGroupService({ installation, preflightOnly, uiEnabled =
305
354
  if (closeChecks[backend]?.(result) === true) closedResults.add(result)
306
355
  return result
307
356
  }
357
+ // Idle compaction shares the turn's close evidence so its permit is
358
+ // released only once the child is proven closed (or never started).
359
+ const compactSession = input => {
360
+ const started = runner.compactSession(input)
361
+ if (started === null) return null
362
+ return started.then(result => {
363
+ if (closeChecks.claude?.(result) === true) closedResults.add(result)
364
+ return result
365
+ }, error => {
366
+ if (closeErrorChecks.claude?.(error) === true) closedErrors.add(error)
367
+ throw error
368
+ })
369
+ }
308
370
  engine = new Engine({ ...cfg, groups: { [route.chatId]: route.group } }, {
309
371
  store, activity, log: message => process.stderr.write(`C2 v2 · ${message}\n`),
310
372
  durableV2Runtime: runtime, durableV2Payloads: handles,
@@ -314,6 +376,8 @@ async function startMultiGroupService({ installation, preflightOnly, uiEnabled =
314
376
  : !!error && typeof error === 'object' && closedErrors.has(error),
315
377
  durableV2AssertWriterLock: assertWriterLock, durableV2Journal: journal,
316
378
  durableV2AcquireCapacity: options => capacity.acquire(options),
379
+ durableV2CapacitySnapshot: () => capacity.snapshot(),
380
+ durableV2CompactSession: compactSession,
317
381
  // A route fault holds or recovers its group alone. Shared grants
318
382
  // are sealed only when the process writer lease itself is gone.
319
383
  durableV2SealCapacity: error => {
@@ -466,12 +530,20 @@ const HELP = `SintBot macOS Feishu multi-group candidate
466
530
  Usage:
467
531
  sintbot init [--config <absolute path>] [--data-dir <absolute path>]
468
532
  sintbot start [--config <absolute path>] [--data-dir <absolute path>] [--preflight] [--ui] [--ui-host <address>] [--ui-port <port>] [--no-open]
533
+ sintbot connect [--config <absolute path>] [--data-dir <absolute path>] [--workdir <absolute path>] [--name <project>] [--provider codex|claude] [--app-id <cli_…>] [--chat <oc_…>] [--basic] [--no-open]
469
534
  sintbot incident seal --group <oc_…> [--config <absolute path>] [--data-dir <absolute path>] [--reason <text>]
470
535
  sintbot feishu <action> [arguments…] [--chat <oc_…>] [--config <path>]
471
536
  sintbot version
472
537
  sintbot help
473
538
 
474
539
  Supports explicit Feishu groups using Codex or Claude Code. Start runs in the foreground.
540
+ start --ui with no configuration opens a local setup page that connects Feishu by scanning (the
541
+ browser form takes the same inputs as connect); the service starts once setup has written and
542
+ initialized the configuration.
543
+ connect scans a Feishu QR code to create the app, then creates a group (or binds --chat), the project
544
+ folder under ~/Projects, the configuration and the journals, in that order; a failed check stops before
545
+ the folder and configuration exist. It refuses existing configuration, state or a running service;
546
+ --app-id resumes only when no configuration or an empty-group one for that app exists.
475
547
  Initialization is for a new installation only; existing journals are never reset.
476
548
  Console shows live groups, binds groups and switches models or projects of idle groups;
477
549
  in a group, /model lists or switches models. Unsupported actions stay disabled.
@@ -492,7 +564,7 @@ async function main(argv = process.argv.slice(2)) {
492
564
  return
493
565
  }
494
566
  if (!sub || sub === 'help' || sub === '--help' || sub === '-h' ||
495
- ['init', 'start'].includes(sub) && rest.length === 1 && ['--help', '-h'].includes(rest[0])) {
567
+ ['init', 'start', 'connect'].includes(sub) && rest.length === 1 && ['--help', '-h'].includes(rest[0])) {
496
568
  process.stdout.write(HELP)
497
569
  return
498
570
  }
@@ -504,10 +576,16 @@ async function main(argv = process.argv.slice(2)) {
504
576
  process.exitCode = outcome === 'done' ? 0 : 1
505
577
  return
506
578
  }
507
- if (!['init', 'start', 'incident', 'feishu'].includes(sub)) {
579
+ if (!['init', 'start', 'connect', 'incident', 'feishu'].includes(sub)) {
508
580
  throw new Error(`${sub} is unavailable in this release; use sintbot help`)
509
581
  }
510
582
  if (process.platform !== 'darwin') throw new Error('this release supports macOS only')
583
+ if (sub === 'connect') {
584
+ // Operator-only onboarding; deliberately not an action of the feishu skill,
585
+ // which the agent may run from a group.
586
+ process.exitCode = await require('../src/connect').runConnect(rest)
587
+ return
588
+ }
511
589
  if (sub === 'feishu') {
512
590
  // The agent's group skills. Each call uses the app credentials directly;
513
591
  // the service need not run. Text after the action may itself start with
@@ -1,4 +1,4 @@
1
- # Install SintBot 1.4.16 with an AI assistant
1
+ # Install SintBot 1.4.18 with an AI assistant
2
2
 
3
3
  English · [简体中文](./zh-CN/AI-ASSISTED-INSTALL.md)
4
4
 
@@ -7,13 +7,13 @@ Use the terminal on the Mac that will run SintBot. A cloud shell cannot install
7
7
  1. Check macOS, Node 22+, the actual Codex or Claude Code executable and login, and any existing SintBot process. Do not print credentials. Preserve existing installations, configuration and state.
8
8
  2. Run the one-line installation command in the guide; `--dry-run` is optional. Continue within the user's authorization; ask only for missing decisions. The installer does not change Node, Codex, Claude Code, shell profiles or services.
9
9
  3. The installer verifies the version and core at `~/.local/share/sintbot/bin/sintbot`. A successful package install is not a successful group test.
10
- 4. Prepare the group configuration in the install guide. Let the user enter secrets locally or use already authorized credential references without revealing them. Use an existing authorized Feishu app only when another process is not connected to it. If app setup or login requires the user, finish other independent preparation first.
11
- 5. For fresh state only, run `init`, then `start --preflight`. Refusal due to an existing journal or unresolved receipts is a stop condition: never delete files, fabricate a new authority or alter receipts to bypass it.
10
+ 4. Prefer the browser setup: `sintbot start --ui` opens the local setup page when no configuration exists; from the terminal `sintbot connect` does the same flow, printing the scan link and opening a local QR page; only the user can scan and confirm on the phone, after which it creates the project folder and group, writes the configuration and initializes, so no secret passes through the assistant. It refuses when a Feishu configuration exists or the service is running; do not delete files to get past that. If the scan is not possible, prepare the configuration by the manual route in the install guide: let the user enter secrets locally or use already authorized credential references without revealing them. Use an existing authorized Feishu app only when another process is not connected to it.
11
+ 5. On the manual route, run `init` for fresh state only (never again after `connect` has initialized), then `start --preflight`. Refusal due to an existing journal or unresolved receipts is a stop condition: never delete files, fabricate a new authority or alter receipts to bypass it.
12
12
  6. Run the foreground service, send an authorized read-only group request and compare its response with the file. Stop cleanly and verify a restart. If no person is available, use an authorized test account to send the request; document the sender and do not call it independent human acceptance. A bot's own API message may be ignored and is not a substitute for an incoming user message.
13
13
  7. Stop temporary processes before ending the task. Report what was installed, what actually ran and any remaining setup. Do not register an automatic background service for this release.
14
14
 
15
15
  ## Copyable request
16
16
 
17
17
  ```text
18
- Install SintBot 1.4.16 on this Mac using the one-line installation guide. Preserve existing services, configuration, state and Codex or Claude Code account data. Do not expose credentials. Verify the actual installed executable and binary core, configure the Feishu groups with their runners, and initialize only clean new state. Run the foreground preflight and an authorized read-only group test, check the result, then verify clean stop/restart. Stop temporary processes when finished, and distinguish package installation from successful group acceptance.
18
+ Install SintBot 1.4.18 on this Mac using the one-line installation guide. Preserve existing services, configuration, state and Codex or Claude Code account data. Do not expose credentials. Verify the actual installed executable and binary core, configure the Feishu groups with their runners, and initialize only clean new state. Run the foreground preflight and an authorized read-only group test, check the result, then verify clean stop/restart. Stop temporary processes when finished, and distinguish package installation from successful group acceptance.
19
19
  ```
package/docs/install.md CHANGED
@@ -1,4 +1,4 @@
1
- # Install SintBot 1.4.16
1
+ # Install SintBot 1.4.18
2
2
 
3
3
  English · [简体中文](./zh-CN/install.md)
4
4
 
@@ -10,13 +10,61 @@ You need a Mac, Node.js 22 or newer, and projects stored on that Mac. Install an
10
10
  curl -fsSL https://sintbot.com/install.sh | bash
11
11
  ```
12
12
 
13
- The installer checks the environment, installs `sintbot@1.4.16` into `~/.local/share/sintbot`, and verifies the entry, built-in core and Feishu module. Continue when you see `Installed and verified SintBot 1.4.16`. No sudo is needed.
13
+ The installer checks the environment, installs `sintbot@1.4.18` into `~/.local/share/sintbot`, and verifies the entry, built-in core and Feishu module. Continue when you see `Installed and verified SintBot 1.4.18`. No sudo is needed.
14
14
 
15
15
  To preview, append `-s -- --dry-run`. To choose another location, set `SINTBOT_INSTALL_DIR` and adjust the executable paths below.
16
16
 
17
- ## 2. Connect Feishu
17
+ ## 2. Connect Feishu in the browser (recommended)
18
18
 
19
- In the [Feishu Open Platform](https://open.feishu.cn/), create a custom app, enable the bot and the permissions to receive and reply to messages, choose long connection for event subscription and subscribe to message receipt. For callbacks, also choose long connection and subscribe to card action callbacks (the tap-to-pick `/model` card needs them). Publish the app, add the bot to the groups you will use, and copy each group's `oc_…` chat ID.
19
+ Prerequisite: the Feishu app on your phone is signed in with an enterprise or team identity; a personal identity without an organization cannot scan, so create a team first (free). The app created by the scan belongs to the scanner's organization; approval depends on its policies.
20
+
21
+ ```bash
22
+ "$HOME/.local/share/sintbot/bin/sintbot" start --ui
23
+ ```
24
+
25
+ Without a configuration file this command does not fail; it opens the local setup page (`http://127.0.0.1:4600`, reachable only from this Mac). Enter a project name (default `sintbot`, created under `~/Projects` with a `README.md`) or pick an existing folder, choose the runner if both are installed, tick the basic option if you are not an organization administrator, then click Start. Scan the QR code on the page with Feishu and confirm on the phone. It then, in order: obtains the app credentials → runs the self-check → opens the contact range and visibility and publishes a version → creates a group and adds you → creates the project folder → writes `~/.sbot/config.json` → initializes the message journals, showing each result on the page. Once the scan is confirmed, the app exists in your organization; any later failed check stops before the folder and the configuration exist and the page offers Retry (it reuses the app already created, never a second one); if the group could not be created, the page asks you to create one by hand, add the bot, paste the group ID and continue.
26
+
27
+ Before showing the QR code, setup reads the selected executor's live model catalog and displays its recommended model and thinking depth. These choices are saved explicitly for the new group. If the live list is unavailable, setup stops before creating an app; check the executor login and connection, then retry. After connecting, change the choices in the console or with `/model`. Existing group choices are preserved.
28
+
29
+ When setup completes the service starts right away and the page switches to the console a few seconds later. Keep the terminal open. In the new group, send "Read the first line of the project README and reply with only that line", then compare it with the `README.md` in the project folder.
30
+
31
+ ### Terminal route
32
+
33
+ The same flow is available without a browser; the flags map to the options on the page:
34
+
35
+ ```bash
36
+ "$HOME/.local/share/sintbot/bin/sintbot" connect
37
+ ```
38
+
39
+ In an interactive terminal it first asks for the project name (press Enter for the default `sintbot`), then prints the scan link and opens a local page with the QR code; the steps are the same as above, results are printed in the terminal, and a failure prints the rerun command with `--app-id`.
40
+
41
+ - The credentials are stored in clear text in `~/.sbot/config.json` (file 0600, directory 0700). To switch back to environment variables, change `appId` / `appSecret` to `"env:FEISHU_APP_ID"` / `"env:FEISHU_APP_SECRET"` and export both before every start.
42
+ - `--basic`: for a non-administrator in a company organization. It does not request `application:application:patch` and skips the range and publish steps; ask an administrator to finish those two in the Open Platform.
43
+ - `--app-id cli_…`: reuse an existing app (add permissions to it instead of creating one), to rerun after a stop or once a review is approved. Allowed only when there is no configuration file, or the file belongs to that app and binds no group yet; a configuration with groups is never replaced.
44
+ - `--chat oc_…`: skip group creation and bind a group you created by hand with the bot added (the notice after a failed group creation shows this command).
45
+ - `--workdir /absolute/path`: bind an existing directory instead of creating one; `--name` changes the default folder name; `--provider codex|claude` picks the runner (chosen automatically when only one is installed); `--no-open` prints the link without opening the page.
46
+ - `connect` refuses to run when a Feishu configuration already exists or the service is running. The scan requests the card callbacks used by `/model`. If the card does not respond, check the callback subscription as in section 4.
47
+
48
+ ## 3. Everyday start
49
+
50
+ After setup, every start uses the same command; with the configuration in its default location it is the same one you used to connect:
51
+
52
+ ```bash
53
+ "$HOME/.local/share/sintbot/bin/sintbot" start --ui
54
+ ```
55
+
56
+ This checks the configuration and runners, connects Feishu and opens the local console. Keep the terminal open. If you used `--config` or `--data-dir`, pass the same flags on every start. A passing preflight does not prove Feishu authentication or delivery.
57
+
58
+ ## 4. Manual setup (alternative)
59
+
60
+ Use the manual route when the scan fails, an administrator does not approve, or you prefer to manage the app yourself; it is the same procedure as before.
61
+
62
+ <details>
63
+ <summary>Show the manual steps</summary>
64
+
65
+ #### 4.1 Create the app
66
+
67
+ In the [Feishu Open Platform](https://open.feishu.cn/), create a custom app, enable the bot, grant the same permissions scan setup requests under Permissions (`im:message.group_msg`, `im:message:readonly`, `im:message:send_as_bot`, `im:resource`, `im:message.reactions:write_only`, `im:chat`, `cardkit:card:write`, `contact:contact.base:readonly`, `contact:department.base:readonly`, `contact:user.base:readonly`) and set the contact data range to all members, choose long connection for event subscription and subscribe to message receipt. For callbacks, also choose long connection and subscribe to card action callbacks (the tap-to-pick `/model` card needs them). Publish the app, add the bot to the groups you will use, and copy each group's `oc_…` chat ID.
20
68
 
21
69
  Enter the app credentials in the default macOS terminal (the secret is not echoed):
22
70
 
@@ -29,7 +77,7 @@ export FEISHU_APP_ID FEISHU_APP_SECRET
29
77
 
30
78
  Never post the secret in a group or commit it. Keep using this terminal; set both variables again in a new one.
31
79
 
32
- ## 3. Bind projects
80
+ #### 4.2 Write the configuration
33
81
 
34
82
  Create a private directory with `mkdir -p ~/.sbot && chmod 700 ~/.sbot`, then create `~/.sbot/config.json`. Replace the chat IDs and absolute project paths; each project directory must already exist. The example binds two groups, one with Codex and one with Claude Code. With one group, delete the other entry.
35
83
 
@@ -69,9 +117,9 @@ Then run `chmod 600 ~/.sbot/config.json`.
69
117
  - To pin a Claude model, add `"model"` to `providers.claude`; otherwise Claude Code's default model on this Mac is used.
70
118
  - At most 2 tasks run at once by default; add `"agent": { "maxConcurrent": 4 }` at the top level to change it (1–32).
71
119
 
72
- ## 4. First start
120
+ #### 4.3 Initialize and start
73
121
 
74
- Copy and run in the same terminal:
122
+ Copy and run in the same terminal (the manual route runs `init` itself):
75
123
 
76
124
  ```bash
77
125
  SINTBOT="$HOME/.local/share/sintbot/bin/sintbot"
@@ -84,6 +132,8 @@ This initializes the message journals, checks the configuration and runners, con
84
132
 
85
133
  In a group, send "Read the first line of the project README and reply with only that line", then compare it with the file. A passing preflight does not prove Feishu authentication or delivery.
86
134
 
135
+ </details>
136
+
87
137
  ## 5. Use it in a group
88
138
 
89
139
  Any text message is a task. Replies arrive in a card that appears once the model starts answering, or after 25 seconds if it is still working without output. While the task runs, the card shows how long it has run, what it is doing and the steps already delivered; at the end those steps fold into a Process section.
@@ -95,16 +145,18 @@ Any text message is a task. Replies arrive in a card that appears once the model
95
145
  | `/stop` | Stop the current task and cancel queued ones; the conversation is kept |
96
146
  | `/new` | Start a new conversation, forgetting the previous one (only while the group is idle) |
97
147
  | `/model` | Opens a tap-to-pick card: choose the backend, model and thinking depth, then confirm. You can also send `/model high`, `/model <model>` or `/model <backend>`. A model or depth change continues the conversation; a backend change starts a new one. Only while the group is idle |
98
- | `/hud` | Quota of the current model and usage of this conversation |
148
+ | `/hud` | Quota of the current model and usage of this conversation; Claude groups also show the idle compaction line and the last compaction time |
99
149
  | `/issue text` | Log feedback; review and close it in the console overview |
100
150
  | `/help` | List commands, with this group's project and model |
101
151
 
102
- Send a command as a message of its own; except for `/issue` and `/model`, do not add other text after it. If the Feishu app also subscribes to the message-recall event (the console's setup guide recommends it), recalling your own message cancels it: a queued message is dropped, and the running task stops if that message alone started it; recalling a follow-up handed to either runner cancels the whole task, including accepted input not yet read.
152
+ Send a command as a message of its own; except for `/issue` and `/model`, do not add other text after it. If the Feishu app also subscribes to the message-recall event (scan setup subscribes to it; add it on the manual path too), recalling your own message cancels it: a queued message is dropped, and the running task stops if that message alone started it; recalling a follow-up handed to either runner cancels the whole task, including accepted input not yet read.
103
153
 
104
154
  Busy follow-ups default on for both Codex and Claude Code. Set `steer: false` to queue them instead; an explicit `steer` value overrides the legacy Codex setting. Claude Code must advertise the required input capabilities, otherwise messages stay queued. Reading can wait until a long-running tool finishes. The reply card follows confirmed reading, and continuation answers are combined into one final reply. If a turn returns a model error or no result, only that group is asked to resend; there is no automatic retry. If a group's last result cannot be confirmed, such as a reply whose delivery is unknown, only that group is paused and answers new messages with a short notice; other groups keep working. Nothing is replayed or retried.
105
155
 
106
156
  When the reply card moves below a confirmed follow-up, its existing text is shown immediately and subsequent output continues from that point. Moving the card does not restart the task.
107
157
 
158
+ On Claude Code versions advertising compact, an idle group can compact its session after a normal turn once context reaches half the configured compaction window. New work stops compaction first. Compaction takes one concurrency slot and starts only when another slot remains free. A value of 0 leaves normal compaction to the executor and disables this idle step. Fresh quota events update usage immediately; while events remain fresh, supplemental quota requests are limited to once every 30 minutes. Idle compaction is experimental in this release: successful compaction and cache behavior still await real-model validation.
159
+
108
160
  ## 6. Console
109
161
 
110
162
  Model and thinking depth are chosen per group: on the group card, the Model row picks the backend and model and the next row picks the depth, from lists read live from the local Codex and Claude Code. Subscription model cards no longer carry a model or depth; a third-party endpoint keeps its model on the model card. After the upgrade, each model card's existing model and depth move into its groups with the same effective values and no session reset, after a configuration backup. Model cards distinguish requested settings from runtime reports; expand Capacity and runtime details for reference limits. Codex context and per-model compaction each offer Executor default or Custom. Numeric inputs appear only for Custom. Changes apply next turn without resetting the session; known catalog context limits are enforced. Compaction means a threshold for Codex and a window for Claude Code, and may start earlier. Explicit legacy global compaction values are converted into independent settings for existing models, preserving per-model overrides. New models use executor defaults. Reading does not rewrite the file; the converted settings are persisted on the next normal configuration save.
@@ -123,7 +175,7 @@ You can also add a group without the console: add it to the configuration, stop
123
175
 
124
176
  ## Stop and restart
125
177
 
126
- Press Ctrl-C and wait for exit. With the Feishu variables set, run:
178
+ Press Ctrl-C and wait for exit. If the configuration uses `env:` references, set those variables first, then run:
127
179
 
128
180
  ```bash
129
181
  "$HOME/.local/share/sintbot/bin/sintbot" start --config "$HOME/.sbot/config.json" --ui
@@ -1,4 +1,4 @@
1
- # 用 AI 助手安装 SintBot 1.4.16
1
+ # 用 AI 助手安装 SintBot 1.4.18
2
2
 
3
3
  [English](../AI-ASSISTED-INSTALL.md) · 简体中文
4
4
 
@@ -7,13 +7,13 @@
7
7
  1. 核对 macOS、Node 22 及以上、Codex 或 Claude Code 的实际程序与登录、是否已有 SintBot 进程。不输出凭据,保留已有安装、配置和状态。
8
8
  2. 运行指南中的一行安装命令;`--dry-run` 为可选预览。用户已经授权的步骤继续执行,只问缺失的决定。安装器不修改 Node、Codex、Claude Code、终端配置或服务。
9
9
  3. 安装器会验证 `~/.local/share/sintbot/bin/sintbot` 的版本和核心加载。安装程序包成功不等于群测试成功。
10
- 4. 按安装指南准备群配置。让用户在本地输入密钥,或使用已经授权的凭据引用,不显示秘密。复用授权飞书应用时,确认没有另一个进程连接该应用。应用或登录需要本人操作时,先完成其他独立准备。
11
- 5. 只有全新状态才能执行 `init`,然后执行 `start --preflight`。若已有日志或未结收据而拒绝启动,不得删文件、新造日志权威或篡改收据来绕过。
10
+ 4. 优先让用户在浏览器里接入:`sintbot start --ui` 在没有配置时打开本机接入页;助手在终端也可用 `sintbot connect`,它打印扫码链接并打开本机二维码页面,扫码和手机确认只能由用户本人完成;之后它自己建项目目录、建群、写配置并初始化,密钥不需要经过助手。已有飞书配置或服务在跑时它会拒绝,不要删文件绕过。扫码走不通再按安装指南的手动路径准备配置:让用户在本地输入密钥,或使用已经授权的凭据引用,不显示秘密。复用授权飞书应用时,确认没有另一个进程连接该应用。
11
+ 5. 手动路径下,只有全新状态才能执行 `init`(`connect` 已经初始化过的不要再执行),然后执行 `start --preflight`。若已有日志或未结收据而拒绝启动,不得删文件、新造日志权威或篡改收据来绕过。
12
12
  6. 前台运行,用已经授权的账号在群内发只读请求,把回复和文件对照,再正常停止并验证重启。没有真人协助时可用授权测试账号发送,并记录实际发送方式,不称为独立真人验收;机器人自己发的接口消息可能被忽略,不能当作用户入站消息。
13
13
  7. 本轮临时进程用完停止。说明安装了什么、实际验证了什么、还缺什么。本版不注册自动后台服务。
14
14
 
15
15
  ## 可复制的请求
16
16
 
17
17
  ```text
18
- 按一行安装指南,在这台 Mac 安装 SintBot 1.4.16。保留已有服务、配置、状态和 Codex 或 Claude Code 账号数据,不输出凭据。验证实际入口与二进制核心,配置飞书群及各群的执行器,只对全新状态初始化。运行前台预检和已授权的只读群测试,对照结果,再验证正常停止与重启。完成后停止临时进程,并区分程序包安装与群验收结果。
18
+ 按一行安装指南,在这台 Mac 安装 SintBot 1.4.18。保留已有服务、配置、状态和 Codex 或 Claude Code 账号数据,不输出凭据。验证实际入口与二进制核心,配置飞书群及各群的执行器,只对全新状态初始化。运行前台预检和已授权的只读群测试,对照结果,再验证正常停止与重启。完成后停止临时进程,并区分程序包安装与群验收结果。
19
19
  ```