@miphamai/cli 0.5.9 → 0.5.11

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 CHANGED
@@ -1,6 +1,6 @@
1
- # Mipham Code
1
+ # Mipham Code v0.5.9
2
2
 
3
- **Multi-model open-core intelligent coding terminal** — AI-assisted code generation, security auditing, MCP protocol integration, and extensible skills system in a single CLI.
3
+ **Multi-model open-core intelligent coding terminal** — 9 AI providers, 66 commands, 16 tools, 14 skills + marketplace, self-update. AI-assisted code generation, security auditing, MCP protocol, and extensible skills in a single CLI.
4
4
 
5
5
  Built by [One Mipham Corporation](https://onemipham.com) (北京华安麦逄科技有限公司) | Brand: MiphamAI
6
6
 
@@ -11,27 +11,21 @@ npm install -g @miphamai/cli
11
11
  mipham
12
12
  ```
13
13
 
14
- Or via curl:
15
-
16
- ```bash
17
- # International
18
- curl -fsSL https://mipham.ai/install.sh | bash
19
-
20
- # China mainland
21
- curl -fsSL https://onemipham.com/install.sh | bash
22
- ```
23
-
24
14
  Requirements: **Bun 1.2+** (recommended) or **Node.js 22+**
25
15
 
26
16
  ## Features
27
17
 
28
- - **7 AI Providers** — Anthropic Claude · OpenAI GPT · DeepSeek · Google Gemini · Doubao 豆包 · Tencent Hunyuan 混元 · Qwen 通义千问
18
+ - **9 AI Providers** — Anthropic Claude · OpenAI GPT · DeepSeek · Kimi (Moonshot) · Google Gemini · Doubao 豆包 · Tencent Hunyuan 混元 · Qwen 通义千问 · MiphamAI
19
+ - **66 Slash Commands** — Interactive command picker (↑↓ Enter Esc), Claude Code-compatible, zero re-learning
29
20
  - **16 Built-in Tools** — File ops, shell execution, agent dispatch, MCP integration, web search
30
- - **60 Slash Commands** — Claude Code-compatible, zero re-learning
31
- - **14 Skills** — 12 standard + 2 Mipham-exclusive, dual-runtime architecture
21
+ - **14 Skills + Marketplace** — 11 standard + 3 Mipham-exclusive skills. `/browse-skills` `/install-skill` community marketplace
22
+ - **Self-Update** — `mipham update` / `/upgrade` — one command to check, backup config, upgrade, restore. API keys preserved
23
+ - **Smart Recommendations** — `/recommend` analyzes your project, suggests skills, providers, and config
24
+ - **One-Click Config** — `/init` generates config.yml with all 9 providers pre-populated (just replace API keys)
32
25
  - **MCP Protocol** — Full JSON-RPC 2.0 stdio transport for external server integration
33
- - **Security Hardened** — Path sandbox · SSRF protection · Bash blacklist · Permission gating · Parameter validation
34
- - **Session Persistence** — Auto-save/restore across CLI restarts
26
+ - **Security Hardened** — Path sandbox · SSRF protection · Bash blacklist · Permission gating · Parameter validation · command injection prevention · API key redaction
27
+ - **Config Resilience** — YAML error recovery, deep merge providers, auto-backup (5 copies), corruption auto-restore
28
+ - **Session Persistence** — Auto-save/restore across CLI restarts, named sessions, checkpoint/rewind
35
29
  - **Cross-Platform** — macOS · Linux · Windows
36
30
 
37
31
  ## Quick Start
@@ -39,37 +33,48 @@ Requirements: **Bun 1.2+** (recommended) or **Node.js 22+**
39
33
  ```bash
40
34
  mipham
41
35
 
42
- # Set API keys
36
+ # First run auto-initializes config. Or:
37
+ /init # Generate ~/.mipham/config.yml with 9 providers pre-configured
38
+
39
+ # Set API keys (env vars or config.yml)
40
+ export DEEPSEEK_API_KEY="sk-..."
43
41
  export ANTHROPIC_API_KEY="sk-ant-..."
44
- export OPENAI_API_KEY="sk-..."
45
42
 
46
- # Switch model
47
- /switch deepseek deepseek-v4-pro
43
+ # Interactive model picker
44
+ Ctrl+P
45
+
46
+ # Browse and install community skills
47
+ /browse-skills
48
+ /install-skill systematic-debugging
49
+
50
+ # Get project-specific recommendations
51
+ /recommend
48
52
 
49
- # Show commands
50
- /help
53
+ # Self-update
54
+ mipham update
51
55
  ```
52
56
 
53
57
  ## Commands
54
58
 
55
- | Category | Commands |
56
- | -------- | --------------------------------------------------------------------------------------------------------- |
57
- | Session | `/help` `/clear` `/compact` `/context` `/status` `/rename` `/goal` `/recap` `/export` `/doctor` `/resume` |
58
- | Model | `/pick` `/model` `/models` `/provider` `/providers` `/switch` `/fast` `/effort` |
59
- | Tools | `/tools` `/skills` `/reload-skills` `/mcp` |
60
- | Workflow | `/plan` `/review` `/diff` `/todos` `/tasks` `/workflows` |
61
- | Security | `/security` `/audit` `/permissions` `/add-dir` |
62
- | Setup | `/setup` `/init` `/config` `/theme` `/ide` `/terminal-setup` |
59
+ | Category | Commands |
60
+ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
61
+ | Session | `/help` `/version` `/clear` `/exit` `/quit` `/compact` `/context` `/status` `/cost` `/rename` `/goal` `/recap` `/export` `/doctor` `/resume` |
62
+ | Model | `/pick` `/model` `/models` `/provider` `/providers` `/switch` `/fast` `/effort` `/theme` `/upgrade` |
63
+ | Skills | `/skills` `/browse-skills` `/install-skill` `/remove-skill` `/reload-skills` |
64
+ | Tools | `/tools` `/commands` `/mcp` |
65
+ | Workflow | `/plan` `/no-plan` `/review` `/diff` `/todos` `/tasks` `/workflows` `/loop` `/agents` |
66
+ | Project | `/init` `/setup` `/recommend` `/security` `/audit` `/permissions` `/add-dir` |
67
+ | History | `/rewind` `/undo` `/copy` `/focus` |
63
68
 
64
- Press **Ctrl+P** for interactive model picker · **Shift+Tab** to cycle permission mode
69
+ Press **Ctrl+P** for model picker · **Shift+Tab** to cycle permission mode · **/** for command picker
65
70
 
66
- ## Documentation
71
+ ## Resources
67
72
 
68
- - [Product Specification](https://github.com/One-Mipham/mipham-code/blob/main/PRODUCT.md)
69
- - [Install Guide](https://mipham.ai/code/install) (International)
70
- - [国内站](https://onemipham.com/mipham-code) (China mainland)
73
+ - [Website (International)](https://mipham.ai/mipham-code)
74
+ - [国内站](https://onemipham.com/mipham-code)
71
75
  - [GitHub](https://github.com/One-Mipham/mipham-code)
72
- - [Issues & Feedback](https://github.com/One-Mipham/mipham-code/issues)
76
+ - [Product Specification](https://github.com/One-Mipham/mipham-code/blob/main/PRODUCT.md)
77
+ - [npm](https://www.npmjs.com/package/@miphamai/cli)
73
78
 
74
79
  ## License
75
80
 
package/dist/mipham ADDED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miphamai/cli",
3
- "version": "0.5.9",
3
+ "version": "0.5.11",
4
4
  "description": "Mipham Code — Multi-model open-core intelligent coding terminal by MiphamAI",
5
5
  "keywords": [
6
6
  "ai",
package/src/ui/app.tsx CHANGED
@@ -205,26 +205,34 @@ export function App({
205
205
  abortRef.current = controller
206
206
 
207
207
  let assistantContent = ''
208
+ // Track whether we've started a new assistant turn — reset accumulator per turn
209
+ let turnContent = ''
210
+ let isNewTurn = true
208
211
 
209
212
  try {
210
213
  for await (const chunk of engine.process(input, controller.signal)) {
211
214
  if (chunk.type === 'text' && chunk.content) {
215
+ // New turn: reset per-turn accumulator and push a fresh assistant message
216
+ if (isNewTurn) {
217
+ turnContent = chunk.content
218
+ isNewTurn = false
219
+ setMessages((prev) => [...prev, { role: 'assistant', content: turnContent }])
220
+ } else {
221
+ turnContent += chunk.content
222
+ setMessages((prev) => {
223
+ const updated = [...prev]
224
+ const last = updated[updated.length - 1]
225
+ if (last?.role === 'assistant') {
226
+ last.content = turnContent
227
+ }
228
+ return updated
229
+ })
230
+ }
212
231
  assistantContent += chunk.content
213
- setMessages((prev) => {
214
- const updated = [...prev]
215
- const last = updated[updated.length - 1]
216
- if (last?.role === 'assistant') {
217
- last.content = assistantContent
218
- } else {
219
- updated.push({ role: 'assistant', content: assistantContent })
220
- }
221
- return updated
222
- })
223
232
  }
224
233
 
225
234
  if (chunk.type === 'tool_use' && chunk.toolUse) {
226
235
  const toolName = chunk.toolUse.name
227
- const inputStr = JSON.stringify(chunk.toolUse.input)
228
236
  const isAgent = toolName === 'Agent' || toolName === 'Task'
229
237
 
230
238
  if (isAgent) {
@@ -237,38 +245,14 @@ export function App({
237
245
  startTime: Date.now(),
238
246
  })
239
247
  }
240
-
241
- const collapsed = toolName !== 'Agent' // agents always expanded
242
- setMessages((prev) => [
243
- ...prev,
244
- {
245
- role: 'system',
246
- content: collapsed
247
- ? `⏺ ${toolName} · ${inputStr.slice(0, 50)}${inputStr.length > 50 ? '...' : ''} (Ctrl+O to expand)`
248
- : `🔧 ${toolName}: ${inputStr.slice(0, 200)}`,
249
- toolMeta: { name: toolName, input: inputStr, collapsed },
250
- },
251
- ])
248
+ // Silent tools: don't show Bash/Glob/Read/etc lines — just the spinner
249
+ // Mark that next text chunk starts a new turn
250
+ isNewTurn = true
252
251
  }
253
252
 
254
253
  if (chunk.type === 'tool_result') {
255
254
  setAgentProgress(null)
256
- setMessages((prev) => {
257
- const updated = [...prev]
258
- for (let i = updated.length - 1; i >= 0; i--) {
259
- if (updated[i]?.toolMeta && !updated[i]!.toolMeta!.output) {
260
- updated[i] = {
261
- ...updated[i]!,
262
- content: updated[i]!.toolMeta!.collapsed
263
- ? updated[i]!.content
264
- : `📋 ${updated[i]!.toolMeta!.name} result: ${(chunk.content || '(empty)').slice(0, 200)}`,
265
- toolMeta: { ...updated[i]!.toolMeta!, output: chunk.content || '' },
266
- }
267
- break
268
- }
269
- }
270
- return updated
271
- })
255
+ // Silent: tool results don't need visible lines
272
256
  }
273
257
 
274
258
  if (chunk.type === 'error') {
package/src/ui/chat.tsx CHANGED
@@ -56,7 +56,12 @@ export function ChatPanel({ messages, focusMode }: ChatPanelProps) {
56
56
  </Box>
57
57
  )}
58
58
  {displayMessages.map((msg, i) => (
59
- <Box key={i} flexDirection="column" marginY={1}>
59
+ <Box
60
+ key={i}
61
+ flexDirection="column"
62
+ marginTop={msg.toolMeta ? 0 : 1}
63
+ marginBottom={msg.toolMeta ? 0 : 1}
64
+ >
60
65
  {msg.toolMeta ? (
61
66
  <Box flexDirection="column">
62
67
  <Text color="yellow">