diff --git a/README.md b/README.md
index d53cf04b..15e4533c 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
[](LICENSE)
[-3DDC84.svg)](app/build.gradle.kts)
-[](app/build.gradle.kts)
+[](app/build.gradle.kts)
[](#project-layout)
---
@@ -19,17 +19,18 @@
1. [What is LineCode Pro?](#what-is-linecode-pro)
2. [What it can do](#what-it-can-do)
3. [Highlights](#highlights)
-4. [Project layout](#project-layout)
-5. [Install](#install)
-6. [Getting started](#getting-started)
-7. [Execution modes](#execution-modes)
-8. [Model providers](#model-providers)
-9. [Tool system](#tool-system)
-10. [Extending LineCode](#extending-linecode)
-11. [Building from source](#building-from-source)
-12. [Privacy & security](#privacy--security)
-13. [Contributing](#contributing)
-14. [License](#license)
+4. [What's new in v1.2.8-max](#whats-new-in-v128-max)
+5. [Project layout](#project-layout)
+6. [Install](#install)
+7. [Getting started](#getting-started)
+8. [Execution modes](#execution-modes)
+9. [Model providers](#model-providers)
+10. [Tool system](#tool-system)
+11. [Extending LineCode](#extending-linecode)
+12. [Building from source](#building-from-source)
+13. [Privacy & security](#privacy--security)
+14. [Contributing](#contributing)
+15. [License](#license)
---
@@ -39,7 +40,7 @@
LineCode is not a thin chat client. It is a full coding workspace: the system prompt, the tool registry, the context manager, the diff store, the file tree, the project picker, the SSH / IPC plumbing, the import/export archive, the extensions framework, and the security policy all live in the app. Nothing leaves your phone unless you wire it up to a remote model.
-The application id is `cn.lineai` and the project is a multi-module Gradle project with 12 modules: `:build-logic` (composite build), `:core-model`, `:core-api`, `:core-security`, `:ui-theme`, `:markdown`, `:data`, `:feature-tool`, `:feature-model`, `:feature-ssh`, `:feature-share`, `:app`, plus the reusable `:ipc` library and the sample `:terminal-provider` app.
+The application id is `cn.lineai` and the project is a multi-module Gradle project with 14 included modules: `:core-model`, `:core-api`, `:core-security`, `:ui-theme`, `:markdown`, `:data`, `:feature-tool`, `:feature-model`, `:feature-ssh`, `:feature-share`, `:tool-ui`, `:app`, the reusable `:ipc` library, and the sample `:terminal-provider` app. `:build-logic` is included as a composite build.
---
@@ -49,6 +50,7 @@ The application id is `cn.lineai` and the project is a multi-module Gradle proje
- Streaming chat with **multiple model protocols** in the same UI: OpenAI-compatible HTTP APIs, Anthropic Messages, OpenAI Codex Responses, and a local GGUF runtime.
- Reasoning blocks (`…`) are extracted and rendered separately from the final answer.
+- Each assistant turn is rendered as an expandable processing timeline: reasoning, grouped tool calls, retries, errors, and Agent progress stay in order while the final answer remains separate. Completed processing duration is persisted with the message.
- Tool-call text inside a stream is parsed and dispatched by `ToolCallTextParser`; everything the model asks to do is shown to you before it runs.
- System prompts are assembled from `feature-model/src/main/assets/prompts/*.txt` — tone variants (chat / coding), context-compaction, work-directory, learning-context, and model-identity templates. You can override the tone, the work directory, the identity block, and the prompt template from settings.
- Long conversations are summarised in the background by `ContextCompactionService` with **dynamic compaction** (50% soft trigger + 80% hard trigger) using the active model itself; durable knowledge saved via the `memory_update` tool or the memory screen is reinjected next session by `LearningContextRepository`.
@@ -64,10 +66,10 @@ The model has access to a registry of tools (`ToolRegistry`) with session-scoped
| Shell | `shell_execute` (Termux or via IPC) |
| Web | `web_search`, `web_fetch` |
| Media | `image_understanding`, `image_generation` |
-| Sub-agents | `agent`, `agent_pipeline` (delegate work to another LLM loop) |
+| Sub-agents | `agent`, `agent_pipeline`, `agent_output` (delegate work to another LLM loop) |
| Productivity| `todo_update` |
-Every file-touching tool routes paths through `FileToolPathPolicy` so the model can only act inside the workspace you opened. Shell calls go through Termux or an IPC provider — never the app process itself.
+Every file-touching tool routes paths through `FileToolPathPolicy` so the model can only act inside the workspace you opened. Shell calls go through Termux or an IPC provider — never the app process itself. Confirmation mode supports one-time approval and persistent, exact-match command permissions scoped by execution mode, tool, command, and working directory.
### Context protection
@@ -112,6 +114,17 @@ Every file-touching tool routes paths through `FileToolPathPolicy` so the model
- **Private by default.** URL allow-list, strict `network_security_config.xml`, secrets redacted from exports, in-app browser keeps JavaScript off.
- **Java-only, on purpose.** No Kotlin runtime, no XML layouts — the app is built entirely in Java 11 for transparency and reviewability.
+## What's new in v1.2.8-max
+
+The current release focuses on a denser native Android UI and a clearer model-workflow surface:
+
+- **Native UI refresh.** Chat, settings, drawers, sheets, tool cards, themes, Markdown, wide-screen layouts, large text, and narrow-screen actions were rebuilt around shared adaptive View components.
+- **Processing timeline.** Reasoning, tool groups, Agent cards, retries, errors, work status, and final answers are presented in the order they happen, with compact expandable summaries and persisted processing duration.
+- **Safer execution approvals.** Automatic, confirmation, and read-only modes are aligned across the main flow and Agents. Permanent approvals match the full execution scope, tool, command, and working directory.
+- **Skill Hub.** Browse and search community Skills, inspect files, versions, comments, evaluations, previews, and security hints, then sign in, install, publish, and manage community Skills from the app.
+- **Prompt and context stability.** Stable system prefixes, deterministic tool/extension ordering, canonical JSON serialization, attachment-local context, and corrected post-compaction token baselines improve cache reuse and prevent repeated compaction.
+- **Release verification.** Robolectric 4.16 native View tests cover layouts, timelines, permissions, prompts, Skill Hub flows, and diff rendering; the v1.2.8-max release notes record 528 passing unit tests plus successful Debug/DebugUserCert builds and lint.
+
---
## Project layout
@@ -152,6 +165,7 @@ LineCode/
│ └── ai/message/ # SystemModelMessage, UserModelMessage, etc.
├── feature-ssh/ # :feature-ssh — SshService, SshConnectionPool, TermuxHelper
├── feature-share/ # :feature-share — export/share/PDF
+├── tool-ui/ # :tool-ui — reusable tool-call cards and view registry
├── app/ # :app — MainActivity, MainCoordinator, controllers, UI components
│ ├── build.gradle.kts
│ ├── lint.xml
@@ -276,10 +290,10 @@ Built-in tools live in `feature-tool/src/main/java/cn/lineai/tool/builtin/`:
FileReadTool FileWriteTool FileEditTool FileDeleteTool
GlobTool ListDirectoryTool ShellExecuteTool
ImageUnderstandingTool ImageGenerationTool WebSearchTool WebFetchTool
-AgentTool AgentPipelineTool TodoUpdateTool
+AgentTool AgentPipelineTool AgentOutputTool TodoUpdateTool
```
-Execution is driven by `ToolExecutionCoordinator` + `ToolExecutor`. Every call goes through `PermissionModeController` + `ToolReviewListener`; the user can confirm per-call or auto-confirm for the session. The list of auto-confirmed tools is tracked on the coordinator (`MainCoordinator.sessionAutoConfirmedTools`).
+Execution is driven by `ToolExecutionCoordinator` + `ToolExecutor`. Every call goes through `PermissionModeController` + `ToolReviewListener`; automatic, confirmation, and read-only modes are supported. Confirmation mode offers one-time approval or persistent exact-match permissions scoped by execution mode, tool, command, and working directory.
Tool results are truncated at 50KB by `ToolResult.truncateContent()` before entering the context. File reads use KB-based parameters with a 50KB range limit; files over 1MB are rejected. Shell outputs exceeding 50KB are middle-truncated.
@@ -297,6 +311,8 @@ Three extension points are first-class:
All three are persisted via `ExtensionRepository` and hot-reloaded by `ToolRegistry.reloadExtensions()`.
+The built-in **Skill Hub** in the Extensions area lets you discover, review, install, and manage community Skills. URI, GitHub, and Skill Hub installs share the same temporary-source cleanup and file-management path.
+
---
## Building from source
@@ -320,7 +336,7 @@ All Gradle commands go through the wrapper. The settings file forces `FAIL_ON_PR
./gradlew :app:assembleDebugUserCert
# → app/build/outputs/apk/debugUserCert/export/LineCode-user-cert-debug.apk
-# Run the unit test suite (JUnit 4 only, no Robolectric)
+# Run the unit test suite (JUnit 4 + Robolectric 4.16 where Android resources are needed)
./gradlew :app:testDebugUnitTest
# Run a single test class
@@ -400,7 +416,7 @@ Bug reports, ideas and patches are welcome. A few notes if you plan to send code
* **Views in Java, not XML.** `lint.xml` silences `ViewConstructor` and `IconDuplicates` deliberately.
* **Choose the lowest-level module.** When adding code, pick the lowest-level module that fits: DTOs → `:core-model`; interfaces → `:core-api`; UI infrastructure → `:ui-theme`; a new tool → `:feature-tool`; a new protocol → `:feature-model`. Do not reach back into `:app` from a library module.
* **Extend the controllers.** When adding chat or tool behaviour, extend the matching controller in `cn.lineai.mvp.*` and thread state through `ChatUiStateAssembler` → `ChatUiState` → `MainContract.View.render(...)`. Do not reach into views from new code.
-* **Tests mirror the package layout.** `app/src/test/java/cn/lineai/...` mirrors production. JUnit 4 + `org.json` only (no Robolectric, no Mockito). When testing repository or controller logic, prefer the in-memory fakes that already exist in sibling tests. Feature modules have their own tests under `feature-*/src/test/java`.
+* **Tests mirror the package layout.** `app/src/test/java/cn/lineai/...` mirrors production. Tests use JUnit 4, `org.json`, and Robolectric 4.16 for Android resource/View behavior (no Mockito). When testing repository or controller logic, prefer the in-memory fakes that already exist in sibling tests. Feature modules have their own tests under `feature-*/src/test/java`.
* **Run the gates before sending a PR:**
```bash
@@ -429,4 +445,4 @@ GNU General Public License for more details.
Full text in [`LICENSE`](LICENSE). Online copy at .
-Third-party libraries shipped with the APK keep their own licenses: commonmark (BSD-2), JSch (BSD-style), org.json (JSON License).
\ No newline at end of file
+Third-party libraries shipped with the APK keep their own licenses: commonmark (BSD-2), JSch (BSD-style), org.json (JSON License).
diff --git a/README_CN.md b/README_CN.md
index 8a115e9c..269df289 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -9,7 +9,7 @@
[](LICENSE)
[-3DDC84.svg)](app/build.gradle.kts)
-[](app/build.gradle.kts)
+[](app/build.gradle.kts)
[](#项目结构)
---
@@ -19,17 +19,18 @@
1. [LineCode Pro 是什么?](#linecode-pro-是什么)
2. [它能做什么](#它能做什么)
3. [功能亮点](#功能亮点)
-4. [项目结构](#项目结构)
-5. [安装](#安装)
-6. [上手指南](#上手指南)
-7. [执行模式](#执行模式)
-8. [支持的模型协议](#支持的模型协议)
-9. [工具系统](#工具系统)
-10. [扩展 LineCode](#扩展-linecode)
-11. [从源码构建](#从源码构建)
-12. [隐私与安全](#隐私与安全)
-13. [参与贡献](#参与贡献)
-14. [许可证](#许可证)
+4. [v1.2.8-max 更新内容](#v128-max-更新内容)
+5. [项目结构](#项目结构)
+6. [安装](#安装)
+7. [上手指南](#上手指南)
+8. [执行模式](#执行模式)
+9. [支持的模型协议](#支持的模型协议)
+10. [工具系统](#工具系统)
+11. [扩展 LineCode](#扩展-linecode)
+12. [从源码构建](#从源码构建)
+13. [隐私与安全](#隐私与安全)
+14. [参与贡献](#参与贡献)
+15. [许可证](#许可证)
---
@@ -39,7 +40,7 @@
LineCode 不是一个轻量聊天客户端,它是一个**完整的编程工作台**:系统提示、工具注册表、上下文管理、Diff 存档、文件树、项目选择器、SSH / IPC 管道、导入导出归档、扩展框架、安全策略……全部跑在 App 内部。除非你自己接到远程模型,否则项目文件不会离开你的手机。
-应用包名是 `cn.lineai`,仓库采用 12 模块 Gradle 结构:`:build-logic`(composite build)、`:core-model`、`:core-api`、`:core-security`、`:ui-theme`、`:markdown`、`:data`、`:feature-tool`、`:feature-model`、`:feature-ssh`、`:feature-share`、`:app`,外加可复用库 `:ipc` 与示例 Provider `:terminal-provider`。
+应用包名是 `cn.lineai`,仓库采用 14 个 Gradle 模块:`:core-model`、`:core-api`、`:core-security`、`:ui-theme`、`:markdown`、`:data`、`:feature-tool`、`:feature-model`、`:feature-ssh`、`:feature-share`、`:tool-ui`、`:app`、可复用库 `:ipc` 与示例 Provider `:terminal-provider`;`:build-logic` 作为 composite build 引入。
---
@@ -49,6 +50,7 @@ LineCode 不是一个轻量聊天客户端,它是一个**完整的编程工作
- 同一个聊天界面下支持**多种模型协议**:OpenAI 兼容 HTTP API、Anthropic Messages、OpenAI Codex Responses、本地 GGUF 推理。
- 推理块(`…`)会被 `ThinkTagParser` 单独抽出来,和最终回答分块渲染。
+- 每轮助手消息都按发生顺序渲染为可展开的处理时间线:思考、工具分组、重试、错误和 Agent 进度集中展示,最终答复保持独立;处理耗时会随消息持久化。
- 流中的工具调用文本由 `ToolCallTextParser` 解析并派发;模型请求做的每件事,在真正执行前都会先展示给你看。
- 系统提示由 `feature-model/src/main/assets/prompts/*.txt` 中的模板拼装:语气(聊天 / 编程)变体、上下文压缩、工作目录、学习上下文、模型身份。你可以在设置里覆盖语气、工作目录、身份块、提示模板。
- 长对话由 `ContextCompactionService` 后台用**当前模型本身**做**动态压缩**(50% 软触发 + 80% 硬触发);通过 `memory_update` 工具或记忆管理界面保存的长期知识,由 `LearningContextRepository` 在下一次会话中喂回上下文。
@@ -56,7 +58,7 @@ LineCode 不是一个轻量聊天客户端,它是一个**完整的编程工作
### 工具执行
-模型可以调用 `ToolRegistry` 里的全部工具,并支持会话级自动确认:
+模型可以调用 `ToolRegistry` 里的全部工具,并支持自动、确认和只读执行模式:
| 分类 | 内置工具 |
| ---- | -------- |
@@ -64,10 +66,10 @@ LineCode 不是一个轻量聊天客户端,它是一个**完整的编程工作
| Shell | `shell_execute`(经 Termux 或 IPC Provider) |
| 网络 | `web_search`、`web_fetch` |
| 媒体 | `image_understanding`、`image_generation` |
-| 子任务 | `agent`、`agent_pipeline`(分派给另一个 LLM 循环) |
+| 子任务 | `agent`、`agent_pipeline`、`agent_output`(分派给另一个 LLM 循环) |
| 效率 | `todo_update` |
-每个会触碰文件的工具都走 `FileToolPathPolicy` 路径校验,模型只能动你授权的目录里的内容。Shell 调用走 Termux 或 IPC Provider —— **永远不在 App 自身进程里跑命令**。
+每个会触碰文件的工具都走 `FileToolPathPolicy` 路径校验,模型只能动你授权的目录里的内容。Shell 调用走 Termux 或 IPC Provider —— **永远不在 App 自身进程里跑命令**。确认模式支持单次允许和永久精确匹配授权,范围包含执行模式、工具、完整命令和工作目录。
### 上下文保护
@@ -102,7 +104,7 @@ LineCode 不是一个轻量聊天客户端,它是一个**完整的编程工作
## 功能亮点
- **一个聊天,多家后端。** OpenAI 兼容、Anthropic Messages、Codex Responses、本地 GGUF 在同一 UI 内任意切换。
-- **真正能干活的工具循环。** 模型能读、改、glob、新建、删除文件,能跑 Shell,能抓取和搜索网页,能看图,能生图,能递归调子任务 —— 全部由你逐条审批或会话级自动确认。
+- **真正能干活的工具循环。** 模型能读、改、glob、新建、删除文件,能跑 Shell,能抓取和搜索网页,能看图,能生图,能递归调子任务 —— 全部受自动、确认或只读模式控制。
- **可在任意目录工作。** 本地(SAF + 可选 `MANAGE_EXTERNAL_STORAGE`)、远程(jsch SSH)、或第三方 IPC Provider。
- **支持自定义扩展。** 自定义 Agent(`agentx_*`)和 MCP-HTTP 工具(`mcpx_*`)即配即用。
- **可插拔 IPC Provider。** 把 Shell 和文件操作放到独立进程里以做安全隔离。可以把 Provider 当成普通 Android App 上架,详见 [`ipc/README.md`](ipc/README.md)。
@@ -112,6 +114,17 @@ LineCode 不是一个轻量聊天客户端,它是一个**完整的编程工作
- **默认隐私优先。** URL 白名单、严格 `network_security_config.xml`、导出文件去敏、内置浏览器默认关闭 JavaScript。
- **纯 Java 写在骨子里。** 无 Kotlin 运行时、无 XML 布局 —— App 全部由 Java 11 写成,便于审计。
+## v1.2.8-max 更新内容
+
+当前版本重点更新了更紧凑的 Android 原生界面和更清晰的模型工作流:
+
+- **原生 UI 重写。** 聊天、设置、抽屉、底部弹窗、工具卡片、主题、Markdown、宽屏布局、大字体和窄屏操作统一使用共享的自适应 View 组件。
+- **处理时间线。** 思考、工具组、Agent 卡片、重试、错误、工作状态和最终答复按实际发生顺序展示,过程默认紧凑折叠,处理耗时会持久化。
+- **更安全的执行授权。** 自动、确认、只读模式在主流程与 Agent 内统一生效;永久授权精确匹配完整的执行范围、工具、命令和工作目录。
+- **Skill Hub。** 可在应用内搜索和浏览社区 Skills,查看文件、版本、评论、评测、预览和安全提示,并完成登录、安装、发布与管理。
+- **提示词与上下文稳定性。** 固定系统前缀、稳定的工具 / 扩展排序、规范化 JSON、附件归属原消息,以及压缩后的用量基线修复,改善缓存复用并避免重复压缩。
+- **发版验证。** Robolectric 4.16 原生 View 测试覆盖布局、时间线、权限、提示词、Skill Hub 流程和 Diff;v1.2.8-max 更新日志记录相关模块单元测试 **528 项通过**,主应用 Debug / DebugUserCert 构建和 Lint 也已通过。
+
---
## 项目结构
@@ -152,6 +165,7 @@ LineCode/
│ └── ai/message/ # SystemModelMessage、UserModelMessage 等
├── feature-ssh/ # :feature-ssh — SshService、SshConnectionPool、TermuxHelper
├── feature-share/ # :feature-share — 导出 / 分享 / PDF
+├── tool-ui/ # :tool-ui — 可复用工具调用卡片和 View 注册表
├── app/ # :app — MainActivity、MainCoordinator、控制器、UI 组件
│ ├── build.gradle.kts
│ ├── lint.xml
@@ -274,10 +288,10 @@ LineCode 在 **设置 → MCP execution mode** 里提供三种 Shell / 文件工
FileReadTool FileWriteTool FileEditTool FileDeleteTool
GlobTool ListDirectoryTool ShellExecuteTool
ImageUnderstandingTool ImageGenerationTool WebSearchTool WebFetchTool
-AgentTool AgentPipelineTool TodoUpdateTool
+AgentTool AgentPipelineTool AgentOutputTool TodoUpdateTool
```
-执行由 `ToolExecutionCoordinator` + `ToolExecutor` 驱动;每次调用都要过 `PermissionModeController` + `ToolReviewListener`,用户可逐条确认或会话级自动确认。自动确认列表由 `MainCoordinator.sessionAutoConfirmedTools` 跟踪。
+执行由 `ToolExecutionCoordinator` + `ToolExecutor` 驱动;每次调用都要过 `PermissionModeController` + `ToolReviewListener`,支持自动、确认和只读模式。确认模式提供单次允许或永久精确匹配授权,授权范围包含执行模式、工具、命令和工作目录。
工具结果由 `ToolResult.truncateContent()` 在 50KB 处截断(首尾各 25KB)后进入上下文。文件读取使用 KB 参数,50KB 范围上限;超过 1MB 的文件直接拒绝。Shell 输出超过 50KB 同样中间截断。
@@ -295,6 +309,8 @@ AgentTool AgentPipelineTool TodoUpdateTool
以上三类都通过 `ExtensionRepository` 持久化,由 `ToolRegistry.reloadExtensions()` 热加载。
+扩展页面内置 **Skill Hub**,可以发现、审查、安装和管理社区 Skills。URI、GitHub 与 Skill Hub 安装共用临时来源清理和文件管理流程。
+
---
## 从源码构建
@@ -318,7 +334,7 @@ AgentTool AgentPipelineTool TodoUpdateTool
./gradlew :app:assembleDebugUserCert
# → app/build/outputs/apk/debugUserCert/export/LineCode-user-cert-debug.apk
-# 单元测试
+# 单元测试(需要 Android 资源 / View 行为时使用 JUnit 4 + Robolectric 4.16)
./gradlew :app:testDebugUnitTest
# 单个测试类
@@ -398,7 +414,7 @@ Release 流水线刻意加强:
* **视图用 Java 写,不用 XML。** `lint.xml` 故意屏蔽 `ViewConstructor` 与 `IconDuplicates`。
* **选择最低层模块。** 加新代码时挑能容纳它的最低层模块:DTO → `:core-model`;接口 → `:core-api`;UI 基础设施 → `:ui-theme`;新工具 → `:feature-tool`;新协议 → `:feature-model`。库模块不要回头引用 `:app`。
* **通过控制器扩展。** 新增聊天或工具行为时,扩展 `cn.lineai.mvp.*` 下对应的控制器,状态走 `ChatUiStateAssembler` → `ChatUiState` → `MainContract.View.render(...)`。不要绕过控制器去直接动 View。
-* **测试镜像包路径。** `app/src/test/java/cn/lineai/...` 与生产代码同包名。仅用 JUnit 4 + `org.json`(无 Robolectric、无 Mockito)。仓库或控制器单测优先用 sibling test 里已有的内存 fake。Feature 模块有各自独立的 `feature-*/src/test/java`。
+* **测试镜像包路径。** `app/src/test/java/cn/lineai/...` 与生产代码同包名。测试使用 JUnit 4、`org.json`,并在需要 Android 资源 / View 行为时使用 Robolectric 4.16(无 Mockito)。仓库或控制器单测优先用 sibling test 里已有的内存 fake。Feature 模块有各自独立的 `feature-*/src/test/java`。
* **发 PR 前跑门禁:**
```bash
@@ -427,4 +443,4 @@ GNU General Public License for more details.
许可证全文见 [`LICENSE`](LICENSE),在线副本:。
-随 APK 一起分发的第三方库各自遵循自己的许可证:commonmark(BSD-2)、JSch(BSD 风格)、org.json(JSON License)。
\ No newline at end of file
+随 APK 一起分发的第三方库各自遵循自己的许可证:commonmark(BSD-2)、JSch(BSD 风格)、org.json(JSON License)。