hoomanjs 1.0.0

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.
Files changed (96) hide show
  1. package/.github/screenshot.png +0 -0
  2. package/.github/workflows/build-publish.yml +49 -0
  3. package/LICENSE +21 -0
  4. package/README.md +399 -0
  5. package/docker-compose.yml +13 -0
  6. package/package.json +78 -0
  7. package/src/acp/acp-agent.ts +803 -0
  8. package/src/acp/approvals.ts +147 -0
  9. package/src/acp/index.ts +1 -0
  10. package/src/acp/meta/system-prompt.ts +44 -0
  11. package/src/acp/meta/user-id.ts +44 -0
  12. package/src/acp/prompt-invoke.ts +149 -0
  13. package/src/acp/sessions/config-options.ts +56 -0
  14. package/src/acp/sessions/replay.ts +131 -0
  15. package/src/acp/sessions/store.ts +158 -0
  16. package/src/acp/sessions/title.ts +22 -0
  17. package/src/acp/utils/paths.ts +5 -0
  18. package/src/acp/utils/tool-kind.ts +38 -0
  19. package/src/acp/utils/tool-locations.ts +46 -0
  20. package/src/acp/utils/tool-result-content.ts +27 -0
  21. package/src/chat/app.tsx +428 -0
  22. package/src/chat/approvals.ts +96 -0
  23. package/src/chat/components/ApprovalPrompt.tsx +25 -0
  24. package/src/chat/components/ChatMessage.tsx +47 -0
  25. package/src/chat/components/Composer.tsx +39 -0
  26. package/src/chat/components/EmptyChatBanner.tsx +26 -0
  27. package/src/chat/components/ReasoningStrip.tsx +30 -0
  28. package/src/chat/components/Spinner.tsx +34 -0
  29. package/src/chat/components/StatusBar.tsx +65 -0
  30. package/src/chat/components/ThinkingStatus.tsx +128 -0
  31. package/src/chat/components/ToolEvent.tsx +34 -0
  32. package/src/chat/components/Transcript.tsx +34 -0
  33. package/src/chat/components/ascii-logo.ts +11 -0
  34. package/src/chat/components/shared.ts +70 -0
  35. package/src/chat/index.tsx +42 -0
  36. package/src/chat/types.ts +21 -0
  37. package/src/cli.ts +146 -0
  38. package/src/configure/app.tsx +911 -0
  39. package/src/configure/components/BusyScreen.tsx +22 -0
  40. package/src/configure/components/HomeScreen.tsx +43 -0
  41. package/src/configure/components/MenuScreen.tsx +44 -0
  42. package/src/configure/components/PromptForm.tsx +40 -0
  43. package/src/configure/components/SelectMenuItem.tsx +30 -0
  44. package/src/configure/index.tsx +43 -0
  45. package/src/configure/open-in-editor.ts +133 -0
  46. package/src/configure/types.ts +45 -0
  47. package/src/configure/utils.ts +113 -0
  48. package/src/core/agent/index.ts +76 -0
  49. package/src/core/config.ts +157 -0
  50. package/src/core/index.ts +54 -0
  51. package/src/core/mcp/config.ts +80 -0
  52. package/src/core/mcp/index.ts +13 -0
  53. package/src/core/mcp/manager.ts +109 -0
  54. package/src/core/mcp/prefixed-mcp-tool.ts +45 -0
  55. package/src/core/mcp/tools.ts +92 -0
  56. package/src/core/mcp/types.ts +37 -0
  57. package/src/core/memory/index.ts +17 -0
  58. package/src/core/memory/ltm/embed.ts +67 -0
  59. package/src/core/memory/ltm/index.ts +18 -0
  60. package/src/core/memory/ltm/store.ts +376 -0
  61. package/src/core/memory/ltm/tools.ts +146 -0
  62. package/src/core/memory/ltm/types.ts +111 -0
  63. package/src/core/memory/ltm/utils.ts +218 -0
  64. package/src/core/memory/stm/index.ts +17 -0
  65. package/src/core/models/anthropic.ts +53 -0
  66. package/src/core/models/bedrock.ts +54 -0
  67. package/src/core/models/google.ts +51 -0
  68. package/src/core/models/index.ts +16 -0
  69. package/src/core/models/ollama/index.ts +13 -0
  70. package/src/core/models/ollama/strands-ollama.ts +439 -0
  71. package/src/core/models/openai.ts +12 -0
  72. package/src/core/prompts/index.ts +23 -0
  73. package/src/core/prompts/skills.ts +66 -0
  74. package/src/core/prompts/static/fetch.md +33 -0
  75. package/src/core/prompts/static/filesystem.md +38 -0
  76. package/src/core/prompts/static/identity.md +22 -0
  77. package/src/core/prompts/static/ltm.md +39 -0
  78. package/src/core/prompts/static/memory.md +39 -0
  79. package/src/core/prompts/static/shell.md +34 -0
  80. package/src/core/prompts/static/skills.md +19 -0
  81. package/src/core/prompts/static/thinking.md +27 -0
  82. package/src/core/prompts/system.ts +109 -0
  83. package/src/core/skills/index.ts +2 -0
  84. package/src/core/skills/registry.ts +239 -0
  85. package/src/core/skills/tools.ts +80 -0
  86. package/src/core/toolkit.ts +13 -0
  87. package/src/core/tools/fetch.ts +288 -0
  88. package/src/core/tools/filesystem.ts +747 -0
  89. package/src/core/tools/index.ts +5 -0
  90. package/src/core/tools/shell.ts +426 -0
  91. package/src/core/tools/thinking.ts +184 -0
  92. package/src/core/tools/time.ts +121 -0
  93. package/src/core/utils/cwd-context.ts +11 -0
  94. package/src/core/utils/paths.ts +28 -0
  95. package/src/exec/approvals.ts +85 -0
  96. package/tsconfig.json +30 -0
Binary file
@@ -0,0 +1,49 @@
1
+ name: Build and publish Bun package
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ tags:
8
+ - "**"
9
+
10
+ permissions:
11
+ contents: read
12
+ id-token: write
13
+
14
+ concurrency:
15
+ group: npm-${{ github.workflow }}-${{ github.ref }}
16
+ cancel-in-progress: false
17
+
18
+ jobs:
19
+ build:
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - name: Checkout
23
+ uses: actions/checkout@v4
24
+
25
+ - name: Setup Bun
26
+ uses: oven-sh/setup-bun@v2
27
+ with:
28
+ bun-version: 1.3.12
29
+
30
+ - name: Setup Node.js
31
+ uses: actions/setup-node@v4
32
+ with:
33
+ node-version: "24"
34
+ registry-url: https://registry.npmjs.org
35
+
36
+ - name: Install dependencies
37
+ run: bun install --frozen-lockfile
38
+
39
+ - name: Verify CLI boots
40
+ run: bun run src/cli.ts --help
41
+
42
+ - name: Verify package contents
43
+ run: bun pm pack --dry-run
44
+
45
+ - name: Publish to npm
46
+ if: startsWith(github.ref, 'refs/tags/')
47
+ run: bun publish --provenance --access public
48
+ env:
49
+ NPM_CONFIG_TOKEN: ${{ secrets.NPM_TOKEN }}
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vaibhav Pandey
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,399 @@
1
+ <div align="center">
2
+ <h1>Hooman</h1>
3
+ <p>
4
+ Hooman is a Bun-powered local AI agent CLI built with TypeScript, <a href="https://www.npmjs.com/package/@strands-agents/sdk">Strands Agents SDK</a>, and <a href="https://github.com/vadimdemedes/ink">Ink</a>.
5
+ </p>
6
+ <p>
7
+ <a href="https://bun.com"><img src="https://img.shields.io/badge/runtime-Bun-f9f1e1?logo=bun&logoColor=000000" alt="Bun" /></a>
8
+ <a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/language-TypeScript-3178C6?logo=typescript&logoColor=white" alt="TypeScript" /></a>
9
+ <a href="https://github.com/vadimdemedes/ink"><img src="https://img.shields.io/badge/ui-Ink-6f42c1" alt="Ink" /></a>
10
+ <a href="https://github.com/vaibhavpandeyvpz/hooman/actions/workflows/build-publish.yml"><img src="https://img.shields.io/github/actions/workflow/status/vaibhavpandeyvpz/hooman/build-publish.yml?branch=main&label=build" alt="Build" /></a>
11
+ <a href="https://github.com/vaibhavpandeyvpz/hooman/stargazers"><img src="https://img.shields.io/github/stars/vaibhavpandeyvpz/hooman?style=flat" alt="GitHub Repo stars" /></a>
12
+ <a href="https://github.com/vaibhavpandeyvpz/hooman/commits/main"><img src="https://img.shields.io/github/last-commit/vaibhavpandeyvpz/hooman" alt="GitHub last commit" /></a>
13
+ </p>
14
+ <p>
15
+ <img src=".github/screenshot.png" alt="Hooman screenshot" />
16
+ </p>
17
+ </div>
18
+
19
+ It gives you:
20
+
21
+ - a one-shot `exec` command for single prompts
22
+ - a stateful `chat` interface for interactive sessions
23
+ - an Ink-powered `configure` workflow for editing app config, `instructions.md`, MCP servers, and installed skills
24
+ - an `acp` command for running Hooman as an Agent Client Protocol (ACP) agent over stdio
25
+
26
+ ## Features
27
+
28
+ - Multiple LLM providers: `ollama`, `openai`, `anthropic`, `google`, `bedrock`
29
+ - Local configuration under `~/.hooman`
30
+ - MCP server support via `stdio`, `streamable-http`, and `sse`
31
+ - Skill discovery / install / removal through the integrated configure flow
32
+ - Interactive terminal UI for chat and configuration
33
+
34
+ ## Requirements
35
+
36
+ - [Bun](https://bun.com) `>= 1.0.0`
37
+ - Node/npm available if you want to install skills from the public skills catalog
38
+ - Provider credentials or local model runtime depending on the LLM you choose
39
+
40
+ ## Usage
41
+
42
+ Fastest way to get started without cloning the repo:
43
+
44
+ ```bash
45
+ npx hoomanjs configure
46
+ npx hoomanjs chat
47
+ ```
48
+
49
+ Or with Bun:
50
+
51
+ ```bash
52
+ bunx hoomanjs configure
53
+ bunx hoomanjs chat
54
+ ```
55
+
56
+ Recommended first run:
57
+
58
+ 1. Run `hooman configure` to choose your LLM provider and model.
59
+ 2. Start chatting with `hooman chat`.
60
+ 3. Use `hooman exec "your prompt"` for one-off tasks.
61
+
62
+ ## Install
63
+
64
+ ```bash
65
+ bun install
66
+ ```
67
+
68
+ Run locally:
69
+
70
+ ```bash
71
+ bun run src/cli.ts --help
72
+ ```
73
+
74
+ Or use the dev alias:
75
+
76
+ ```bash
77
+ bun run dev -- --help
78
+ ```
79
+
80
+ Link the CLI locally:
81
+
82
+ ```bash
83
+ bun link
84
+ hooman --help
85
+ ```
86
+
87
+ ## Commands
88
+
89
+ ### `hooman exec`
90
+
91
+ Run a single prompt once.
92
+
93
+ ```bash
94
+ hooman exec "Summarize the current repository"
95
+ ```
96
+
97
+ Use a specific session id:
98
+
99
+ ```bash
100
+ hooman exec "What changed?" --session my-session
101
+ ```
102
+
103
+ Choose a toolkit size:
104
+
105
+ ```bash
106
+ hooman exec "Summarize this repo" --toolkit lite
107
+ ```
108
+
109
+ ### `hooman chat`
110
+
111
+ Start an interactive stateful chat session.
112
+
113
+ ```bash
114
+ hooman chat
115
+ ```
116
+
117
+ Optional initial prompt:
118
+
119
+ ```bash
120
+ hooman chat "Help me plan the next task"
121
+ ```
122
+
123
+ Resume or pin a session id:
124
+
125
+ ```bash
126
+ hooman chat --session my-session
127
+ ```
128
+
129
+ Choose a toolkit size:
130
+
131
+ ```bash
132
+ hooman chat --toolkit max
133
+ ```
134
+
135
+ ### Toolkit Levels
136
+
137
+ `exec`, `chat`, and `acp` support `-t, --toolkit <lite|full|max>`.
138
+
139
+ - `lite` - time, fetch, long-term-memory, installed skills, and configured MCP server tools
140
+ - `full` - `lite` plus filesystem, shell, and thinking tools
141
+ - `max` - `full` plus skills management tools and MCP config management tools
142
+
143
+ Prompt loading follows the same split: filesystem / shell / thinking instructions are only included from `full` upward, while skills guidance is always included.
144
+
145
+ ### `hooman configure`
146
+
147
+ Open the Ink configuration workflow.
148
+
149
+ ```bash
150
+ hooman configure
151
+ ```
152
+
153
+ The configure UI currently lets you:
154
+
155
+ - edit app configuration values
156
+ - edit `instructions.md` in your `$VISUAL` / `$EDITOR` (cross-platform fallback included)
157
+ - add, edit, and delete MCP servers with confirmation
158
+ - search, install, refresh, and remove skills
159
+
160
+ ### `hooman acp`
161
+
162
+ Run Hooman as an Agent Client Protocol (ACP) agent over stdio.
163
+
164
+ ```bash
165
+ hooman acp
166
+ ```
167
+
168
+ Choose a toolkit size for ACP-created sessions:
169
+
170
+ ```bash
171
+ hooman acp --toolkit max
172
+ ```
173
+
174
+ ACP notes:
175
+
176
+ - ACP sessions are stored under `~/.hooman/acp-sessions`
177
+ - ACP uses Hooman's local `mcp.json`; client-provided MCP servers and client workspace tools are not exposed
178
+ - ACP `session/new` and `session/load` support `_meta.userId` and `_meta.systemPrompt`
179
+ - when `_meta.systemPrompt` is provided, it is appended to the agent system prompt with a section break
180
+
181
+ ## Configuration Layout
182
+
183
+ Hooman stores its data in:
184
+
185
+ ```text
186
+ ~/.hooman/
187
+ ```
188
+
189
+ Important files and folders:
190
+
191
+ - `config.json` - app name, LLM provider/model, tool approvals, long-term memory, compaction
192
+ - `instructions.md` - system instructions used to build the agent prompt
193
+ - `mcp.json` - MCP server definitions
194
+ - `skills/` - installed skills
195
+ - `sessions/` - persisted session data
196
+ - `acp-sessions/` - persisted ACP session metadata and message snapshots
197
+
198
+ ## Example `config.json`
199
+
200
+ This is the shape managed by `hooman configure`:
201
+
202
+ ```json
203
+ {
204
+ "name": "Hooman",
205
+ "llm": {
206
+ "provider": "ollama",
207
+ "model": "gemma4:e4b",
208
+ "params": {}
209
+ },
210
+ "tools": {
211
+ "allowed": []
212
+ },
213
+ "ltm": {
214
+ "enabled": false,
215
+ "chroma": {
216
+ "url": "http://127.0.0.1:8000",
217
+ "collection": {
218
+ "memory": "memory"
219
+ }
220
+ }
221
+ },
222
+ "compaction": {
223
+ "ratio": 0.75,
224
+ "keep": 5
225
+ }
226
+ }
227
+ ```
228
+
229
+ Supported `llm.provider` values:
230
+
231
+ - `ollama`
232
+ - `openai`
233
+ - `anthropic`
234
+ - `google`
235
+ - `bedrock`
236
+
237
+ ## Provider Notes
238
+
239
+ ### Ollama
240
+
241
+ Good default for local usage. Example:
242
+
243
+ ```json
244
+ {
245
+ "provider": "ollama",
246
+ "model": "gemma4:e4b",
247
+ "params": {}
248
+ }
249
+ ```
250
+
251
+ ### OpenAI
252
+
253
+ Example:
254
+
255
+ ```json
256
+ {
257
+ "provider": "openai",
258
+ "model": "gpt-5",
259
+ "params": {
260
+ "apiKey": "..."
261
+ }
262
+ }
263
+ ```
264
+
265
+ ### Anthropic
266
+
267
+ Provider-specific settings such as `apiKey`, `authToken`, `baseURL`, and `headers` are supported. Other values are forwarded into the model config.
268
+
269
+ ```json
270
+ {
271
+ "provider": "anthropic",
272
+ "model": "claude-sonnet-4-20250514",
273
+ "params": {
274
+ "apiKey": "...",
275
+ "temperature": 0.7
276
+ }
277
+ }
278
+ ```
279
+
280
+ ### Google
281
+
282
+ Uses Strands `GoogleModel` on top of `@google/genai`. Top-level options like `apiKey`, `client`, `clientConfig`, and `builtInTools` are supported; other values go into Google generation params.
283
+
284
+ ```json
285
+ {
286
+ "provider": "google",
287
+ "model": "gemini-2.5-flash",
288
+ "params": {
289
+ "apiKey": "...",
290
+ "temperature": 0.7,
291
+ "maxOutputTokens": 2048,
292
+ "topP": 0.9,
293
+ "topK": 40
294
+ }
295
+ }
296
+ ```
297
+
298
+ ### Bedrock
299
+
300
+ Supports `region`, `clientConfig`, and optional `apiKey`, with all other values forwarded as Bedrock model options.
301
+
302
+ ## MCP Configuration
303
+
304
+ `mcp.json` is stored as:
305
+
306
+ ```json
307
+ {
308
+ "mcpServers": {}
309
+ }
310
+ ```
311
+
312
+ ### Example stdio server
313
+
314
+ ```json
315
+ {
316
+ "mcpServers": {
317
+ "filesystem": {
318
+ "type": "stdio",
319
+ "command": "npx",
320
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
321
+ "env": {
322
+ "EXAMPLE": "1"
323
+ },
324
+ "cwd": "/tmp"
325
+ }
326
+ }
327
+ }
328
+ ```
329
+
330
+ ### Example streamable HTTP server
331
+
332
+ ```json
333
+ {
334
+ "mcpServers": {
335
+ "remote": {
336
+ "type": "streamable-http",
337
+ "url": "https://example.com/mcp",
338
+ "headers": {
339
+ "Authorization": "Bearer token"
340
+ }
341
+ }
342
+ }
343
+ }
344
+ ```
345
+
346
+ ### Example SSE server
347
+
348
+ ```json
349
+ {
350
+ "mcpServers": {
351
+ "legacy": {
352
+ "type": "sse",
353
+ "url": "https://example.com/sse",
354
+ "headers": {
355
+ "Authorization": "Bearer token"
356
+ }
357
+ }
358
+ }
359
+ }
360
+ ```
361
+
362
+ ## Skills
363
+
364
+ Skills are installed under:
365
+
366
+ ```text
367
+ ~/.hooman/skills
368
+ ```
369
+
370
+ The configure workflow can:
371
+
372
+ - search the public skills catalog
373
+ - install a skill from a source string, repo, URL, or local path
374
+ - refresh installed skills
375
+ - remove installed skills with confirmation
376
+
377
+ ## Development
378
+
379
+ Install dependencies:
380
+
381
+ ```bash
382
+ bun install
383
+ ```
384
+
385
+ Run the CLI:
386
+
387
+ ```bash
388
+ bun run src/cli.ts --help
389
+ ```
390
+
391
+ Run typecheck:
392
+
393
+ ```bash
394
+ bunx tsc --noEmit
395
+ ```
396
+
397
+ ## License
398
+
399
+ MIT. See `LICENSE`.
@@ -0,0 +1,13 @@
1
+ services:
2
+ chroma:
3
+ image: chromadb/chroma
4
+ ports:
5
+ - "8000:8000"
6
+ volumes:
7
+ - chroma-data:/chroma/chroma
8
+ environment:
9
+ - IS_PERSISTENT=TRUE
10
+ - ANONYMIZED_TELEMETRY=FALSE
11
+
12
+ volumes:
13
+ chroma-data:
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "hoomanjs",
3
+ "version": "1.0.0",
4
+ "description": "Bun-powered local AI agent CLI with chat, exec, ACP, MCP, and skills support.",
5
+ "author": {
6
+ "name": "Vaibhav Pandey",
7
+ "email": "contact@vaibhavpandey.com"
8
+ },
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/vaibhavpandeyvpz/hooman.git"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/vaibhavpandeyvpz/hooman/issues"
16
+ },
17
+ "homepage": "https://github.com/vaibhavpandeyvpz/hooman#readme",
18
+ "keywords": [
19
+ "acp",
20
+ "agent",
21
+ "ai",
22
+ "bun",
23
+ "chat",
24
+ "cli",
25
+ "llm",
26
+ "mcp",
27
+ "skills",
28
+ "strands"
29
+ ],
30
+ "type": "module",
31
+ "bin": {
32
+ "hooman": "src/cli.ts"
33
+ },
34
+ "scripts": {
35
+ "dev": "bun run src/cli.ts",
36
+ "start": "bun run src/cli.ts",
37
+ "typecheck": "tsc --noEmit"
38
+ },
39
+ "devDependencies": {
40
+ "@types/bun": "latest",
41
+ "@types/jsdom": "^28.0.1",
42
+ "@types/lodash": "^4.17.24",
43
+ "@types/luxon": "^3.7.1",
44
+ "@types/react": "^19.2.14",
45
+ "@types/turndown": "^5.0.6",
46
+ "typescript": "^6.0.2"
47
+ },
48
+ "engines": {
49
+ "bun": ">=1.0.0"
50
+ },
51
+ "dependencies": {
52
+ "@agentclientprotocol/sdk": "^0.18.2",
53
+ "@ai-sdk/anthropic": "^3.0.69",
54
+ "@aws-sdk/client-bedrock-runtime": "^3.1028.0",
55
+ "@google/genai": "^1.40.0",
56
+ "@huggingface/transformers": "^4.0.1",
57
+ "@modelcontextprotocol/sdk": "^1.29.0",
58
+ "@mozilla/readability": "^0.6.0",
59
+ "@strands-agents/sdk": "^1.0.0-rc.3",
60
+ "chromadb": "^3.4.3",
61
+ "cli-spinners": "^3.4.0",
62
+ "commander": "^14.0.3",
63
+ "gray-matter": "^4.0.3",
64
+ "handlebars": "^4.7.9",
65
+ "ink": "^7.0.0",
66
+ "ink-select-input": "^6.2.0",
67
+ "ink-text-input": "^6.0.0",
68
+ "jsdom": "^29.0.2",
69
+ "lodash": "^4.18.1",
70
+ "luxon": "^3.7.2",
71
+ "ollama": "^0.6.3",
72
+ "openai": "^6.34.0",
73
+ "react": "^19.2.5",
74
+ "slugify": "^1.6.9",
75
+ "turndown": "^7.2.4",
76
+ "zod": "^4.3.6"
77
+ }
78
+ }