Skip to content

Commit 4bf4b26

Browse files
committed
Implemented aiPersona search focus
1 parent 0e80b6c commit 4bf4b26

16 files changed

Lines changed: 195 additions & 99 deletions

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,26 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [2.0.6] - 2026-04-04
6+
7+
### Added
8+
- Six new specialized AI personas for focused system administration and command help:
9+
- `/ubuntu` — Focused on Ubuntu Linux specific commands, patches, and fixes.
10+
- `/debian` — Focused on Debian and derived distributions.
11+
- `/fedora` — Focused on Fedora ecosystem and DNF administration.
12+
- `/windows` — Focused on standard Windows management and CMD tools.
13+
- `/powershell` — Focused on PowerShell cmdlets, scripting, and automation.
14+
- `/archlinux` — Focused on Arch Linux, Pacman, and rolling release maintenance.
15+
- Interactive feedback for persona-based queries (saves AI answers to database).
16+
17+
### Changed
18+
- Rebalanced the interactive help menu layout for better readability.
19+
- Consolidated slash commands to prioritize utility and core features.
20+
21+
### Removed
22+
- `/help next` — Simplified help menu navigation.
23+
- `/count` — Integrated database state visibility into standard list commands.
24+
525
## [2.0.5] - 2026-03-24
626

727
### Added

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
> An AI-powered command search and management tool with CLI, Interactive, and Web interfaces.
44
5-
**Version:** 2.0.5 | **Language:** Go 1.23 | **License:** MIT
5+
**Version:** 2.0.6 | **Language:** Go 1.23 | **License:** MIT
66
**Author:** Ricardo Wagemaker | **Repo:** [github.com/gcclinux/scmd](https://github.com/gcclinux/scmd)
77

88
---
@@ -18,7 +18,7 @@ For a full feature breakdown and infographic-ready reference, see [docs/SCMD_INF
1818
## Screenshots
1919

2020
### Interactive CLI — Slash Commands & AI Responses
21-
![Interactive CLI showing available commands and AI-powered search](images/smcd-2.0.5-show.png)
21+
![Interactive CLI showing available commands and AI-powered search](images/smcd-2.0.6-show.png)
2222

2323
### Web UI — Browser-Based Search Interface
2424
![Web UI with real-time search, syntax highlighting, and AI explanations](images/smcd-2.0.1-web.png)
@@ -48,7 +48,8 @@ scmd --cli
4848
```
4949

5050
- Natural language queries: `"show me postgresql replication examples"`
51-
- 13 slash commands: `/search`, `/add`, `/list`, `/count`, `/delete`, `/show`, `/help`, `/import`, `/run`, `/ai`, `/config`, `/embeddings`, `/generate`
51+
- 14 slash commands: `/search`, `/add`, `/list`, `/delete`, `/show`, `/help`, `/import`, `/run`, `/ai`, `/config`, `/embeddings`, `/generate`, `/clear`, `/exit`
52+
- 6 specialized persona commands: `/ubuntu`, `/debian`, `/fedora`, `/windows`, `/powershell`, `/archlinux`
5253
- AI-powered explanations with context-aware responses
5354
- Feedback loop — save or retry AI answers
5455
- Markdown rendering in terminal
@@ -303,7 +304,7 @@ See [AUTHENTICATION.md](docs/AUTHENTICATION.md) for setup instructions.
303304

304305
```
305306
┌─────────────────────────────────────────────────┐
306-
│ SCMD v2.0.5
307+
│ SCMD v2.0.6
307308
├─────────────┬──────────────┬────────────────────┤
308309
│ Interactive │ Traditional │ Web UI │
309310
│ CLI │ CLI │ (HTTP/HTTPS) │

docker/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ WORKDIR /app
3636
# Add Maintainer Info
3737
LABEL maintainer="Ricardo Wagemaker"
3838
LABEL app.name="SCMD"
39-
LABEL app.version="2.0.5"
39+
LABEL app.version="2.0.6"
4040
LABEL app.description="Simple Command Line or Code Search"
4141
LABEL app.license="MIT"
4242
LABEL app.repository="https://github.com/gcclinux/scmd"

docs/SCMD_INFOGRAPHIC.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
> An AI-powered command search and management tool with CLI, Interactive, and Web interfaces.
44
5-
**Version:** 2.0.5 | **Language:** Go 1.23 | **License:** MIT
5+
**Version:** 2.0.6 | **Language:** Go 1.23 | **License:** MIT
66
**Author:** Ricardo Wagemaker | **Repo:** github.com/gcclinux/scmd
77

88
---
@@ -211,7 +211,7 @@ Environment variables override config file values.
211211

212212
```
213213
┌─────────────────────────────────────────────────┐
214-
│ SCMD v2.0.5
214+
│ SCMD v2.0.6
215215
├─────────────┬──────────────┬────────────────────┤
216216
│ Interactive │ Traditional │ Web UI │
217217
│ CLI │ CLI │ (HTTP/HTTPS) │

docs/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
<section style="min-height:100vh;display:flex;align-items:center;justify-content:center;padding:6rem 1.5rem 4rem;position:relative;overflow:hidden">
4848
<div style="position:absolute;inset:0;background:radial-gradient(ellipse at 50% 0%,rgba(0,255,136,.06) 0%,transparent 60%);pointer-events:none"></div>
4949
<div style="max-width:800px;text-align:center;position:relative;z-index:1">
50-
<div style="font-family:var(--font-mono);color:var(--muted);font-size:.875rem;margin-bottom:1rem">v2.0.5 · Go · MIT License</div>
50+
<div style="font-family:var(--font-mono);color:var(--muted);font-size:.875rem;margin-bottom:1rem">v2.0.6 · Go · MIT License</div>
5151
<h1 style="font-size:clamp(2.5rem,6vw,4rem);font-weight:800;line-height:1.1;margin-bottom:1.5rem">
5252
<span style="color:var(--green)">Search</span> commands.<br>
5353
<span style="color:var(--cyan)">Ask</span> AI.<br>
@@ -448,7 +448,7 @@ <h2 style="text-align:center;font-size:2rem;margin-bottom:2.5rem">Architecture</
448448
<div style="background:var(--bg2);border:1px solid var(--border);border-radius:12px;padding:2rem;font-family:var(--font-mono);font-size:.8rem;line-height:1.7;overflow-x:auto;text-align:center">
449449
<pre style="display:inline-block;text-align:left;color:var(--text)">
450450
<span style="color:var(--border)">┌─────────────────────────────────────────────────┐</span>
451-
<span style="color:var(--border)"></span> <span style="color:var(--green);font-weight:700">SCMD v2.0.5</span> <span style="color:var(--border)"></span>
451+
<span style="color:var(--border)"></span> <span style="color:var(--green);font-weight:700">SCMD v2.0.6</span> <span style="color:var(--border)"></span>
452452
<span style="color:var(--border)">├─────────────┬──────────────┬────────────────────┤</span>
453453
<span style="color:var(--border)"></span> <span style="color:var(--green)">Interactive</span> <span style="color:var(--border)"></span> <span style="color:var(--cyan)">Traditional</span> <span style="color:var(--border)"></span> <span style="color:var(--purple)">Web UI</span> <span style="color:var(--border)"></span>
454454
<span style="color:var(--border)"></span> <span style="color:var(--green)">CLI</span> <span style="color:var(--border)"></span> <span style="color:var(--cyan)">CLI</span> <span style="color:var(--border)"></span> <span style="color:var(--purple)">(HTTP/HTTPS)</span> <span style="color:var(--border)"></span>
@@ -487,7 +487,7 @@ <h2 style="text-align:center;font-size:2rem;margin-bottom:2.5rem">Architecture</
487487
<a href="https://github.com/gcclinux/scmd/blob/main/LICENSE" target="_blank" rel="noopener">MIT License</a>
488488
</div>
489489
<p style="color:var(--muted);font-size:.8rem">
490-
Built with Go by <a href="https://github.com/gcclinux" target="_blank" rel="noopener">Ricardo Wagemaker</a> · SCMD v2.0.5
490+
Built with Go by <a href="https://github.com/gcclinux" target="_blank" rel="noopener">Ricardo Wagemaker</a> · SCMD v2.0.6
491491
</p>
492492
</div>
493493
</footer>

images/smcd-2.0.5-show.png

-64.3 KB
Binary file not shown.

images/smcd-2.0.6-show.png

166 KB
Loading

internal/ai/aiPersona.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package ai
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/gcclinux/scmd/internal/database"
8+
)
9+
10+
// AIPersona represents a specific AI personality and focus.
11+
type AIPersona struct {
12+
Name string
13+
Description string
14+
SystemPrompt string
15+
}
16+
17+
// GetPersonas returns the map of available AI personas.
18+
func GetPersonas() map[string]AIPersona {
19+
return map[string]AIPersona{
20+
"ubuntu": {
21+
Name: "Ubuntu Expert",
22+
Description: "Fully focused on commands, patches, administration, and fixes for Ubuntu.",
23+
SystemPrompt: `You are an expert Ubuntu Linux administrator.
24+
Your focus is entirely on Ubuntu-specific commands, patches, administration, and fixes.
25+
When providing help:
26+
1. Prioritize 'apt' and Ubuntu-specific tools.
27+
2. Ensure commands are compatible with Ubuntu LTS and recent releases.
28+
3. Provide advice on PPA management, snap packages, and Ubuntu-specific configurations.
29+
4. Format all commands in bash code blocks.`,
30+
},
31+
"debian": {
32+
Name: "Debian Expert",
33+
Description: "Focused on commands, patches, administration, and fixes for Debian or derived distros.",
34+
SystemPrompt: `You are an expert Debian Linux administrator.
35+
Your focus is on Debian and its derivative distributions.
36+
When providing help:
37+
1. Use 'apt', 'dpkg', and Debian standard tools.
38+
2. Focus on stability and Debian policy.
39+
3. Provide instructions for managing sources.list and Debian-specific package management.
40+
4. Format all commands in bash code blocks.`,
41+
},
42+
"fedora": {
43+
Name: "Fedora Expert",
44+
Description: "Focused on commands, patches, administration, and fixes specific to Fedora.",
45+
SystemPrompt: `You are an expert Fedora Linux administrator.
46+
Your focus is on Fedora-specific commands and administration.
47+
When providing help:
48+
1. Use 'dnf' and Fedora Ecosystem tools.
49+
2. Focus on cutting-edge features and Fedora-specific configurations (like SELinux).
50+
3. Provide advice on Copr repositories and RPM package management.
51+
4. Format all commands in bash code blocks.`,
52+
},
53+
"windows": {
54+
Name: "Windows Admin",
55+
Description: "Focused on commands, patches, and administration for Windows management.",
56+
SystemPrompt: `You are an expert Windows System Administrator.
57+
Your focus is on Windows management, including CMD, system tools, and administration patches.
58+
When providing help:
59+
1. Use standard Windows CLI tools and administrative commands.
60+
2. Focus on registry edits, system services, and administrative fixes.
61+
3. Provide guidance on Windows-specific troubleshooting.
62+
4. Format all commands in cmd or batch code blocks.`,
63+
},
64+
"powershell": {
65+
Name: "PowerShell Guru",
66+
Description: "Focused on PowerShell commands, scripts, and administration.",
67+
SystemPrompt: `You are a PowerShell Guru.
68+
Your focus is exclusively on PowerShell commands, scripts, and automation.
69+
When providing help:
70+
1. Use PowerShell cmdlets and scripting best practices.
71+
2. Focus on object-oriented pipeline usage and module management.
72+
3. Provide modern PowerShell (v7+) and Windows PowerShell compatibility advice.
73+
4. Format all commands in powershell code blocks.`,
74+
},
75+
"archlinux": {
76+
Name: "Arch Linux Master",
77+
Description: "Focused on commands, patches, and administration for Arch Linux distros.",
78+
SystemPrompt: `You are an Arch Linux Master.
79+
Your focus is on Arch Linux and its derivatives (like Manjaro, EndeavourOS).
80+
When providing help:
81+
1. Use 'pacman' and AUR helpers (like yay or paru).
82+
2. Focus on the Arch Way: simplicity, modernity, and pragmatism.
83+
3. Provide advice on Arch-specific configurations like mkinitcpio, systemd-boot, and rolling release maintenance.
84+
4. Format all commands in bash code blocks.`,
85+
},
86+
}
87+
}
88+
89+
// AskAIPersona sends a question to the AI using a specific persona.
90+
func AskAIPersona(personaKey string, question string, context []database.CommandRecord) (string, int, error) {
91+
personas := GetPersonas()
92+
persona, ok := personas[strings.ToLower(personaKey)]
93+
if !ok {
94+
return "", 0, fmt.Errorf("persona '%s' not found", personaKey)
95+
}
96+
97+
// We can prefix the system prompt to the query for now,
98+
// or better, if we update AskAI to support system prompts.
99+
// For now, let's just combine them to avoid breaking the AskAI signature if we don't want to change it yet.
100+
// But it's better to change AskAI if possible.
101+
102+
pagedQuestion := fmt.Sprintf("PERSONA: %s\n\nINSTRUCTIONS: %s\n\nUSER QUESTION: %s",
103+
persona.Name, persona.SystemPrompt, question)
104+
105+
return AskAI(pagedQuestion, context)
106+
}

internal/cli/commands.go

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
"github.com/gcclinux/scmd/internal/util"
2020
)
2121

22-
func handleSlashCommand(input string) {
22+
func handleSlashCommand(input string) string {
2323
parts := strings.SplitN(input, " ", 2)
2424
command := parts[0]
2525
args := ""
@@ -29,11 +29,7 @@ func handleSlashCommand(input string) {
2929

3030
switch command {
3131
case "/help", "/?":
32-
if args == "next" {
33-
printInteractiveHelpNext()
34-
} else {
35-
printInteractiveHelp()
36-
}
32+
printInteractiveHelp()
3733
case "/exit", "/quit", "/q":
3834
fmt.Println("Goodbye!")
3935
os.Exit(0)
@@ -42,26 +38,24 @@ func handleSlashCommand(input string) {
4238
case "/search":
4339
if args == "" {
4440
fmt.Println("Usage: /search <pattern>")
45-
return
41+
return ""
4642
}
47-
performInteractiveSearch(args)
43+
return performInteractiveSearch(args)
4844
case "/add":
4945
if args == "" {
5046
fmt.Println("Usage: /add <command> | <description>")
5147
fmt.Println("Example: /add docker ps -a | List all containers")
52-
return
48+
return ""
5349
}
5450
handleAddCommand(args)
5551
case "/delete":
5652
if args == "" {
5753
fmt.Println("Usage: /delete <id>")
58-
return
54+
return ""
5955
}
6056
handleDeleteCommand(args)
6157
case "/list":
6258
handleListCommand()
63-
case "/count":
64-
handleCountCommand()
6559
case "/ai":
6660
handleAIStatus()
6761
case "/config":
@@ -73,25 +67,57 @@ func handleSlashCommand(input string) {
7367
case "/show":
7468
if args == "" {
7569
fmt.Println("Usage: /show <id>")
76-
return
70+
return ""
7771
}
7872
handleShowCommand(args)
7973
case "/import":
8074
if args == "" {
8175
fmt.Println("Usage: /import <path>")
82-
return
76+
return ""
8377
}
8478
handleImportCommand(args)
8579
case "/run":
8680
if args == "" {
8781
fmt.Println("Usage: /run <command>")
88-
return
82+
return ""
8983
}
9084
handleRunCommand(args)
85+
case "/ubuntu", "/debian", "/fedora", "/windows", "/powershell", "/archlinux":
86+
if args == "" {
87+
fmt.Printf("Usage: %s <question>\n", command)
88+
return ""
89+
}
90+
return handlePersonaCommand(command[1:], args)
9191
default:
9292
fmt.Printf("Unknown command: %s\n", command)
9393
fmt.Println("Type '/help' for available commands")
9494
}
95+
return ""
96+
}
97+
98+
func handlePersonaCommand(persona, query string) string {
99+
fmt.Printf("🤖 Processing with %s persona...\n", persona)
100+
101+
// We'll perform a search to get context for the persona
102+
results, _, _, err := ai.SmartSearch(query, true)
103+
if err != nil {
104+
fmt.Printf("Error searching: %v\n", err)
105+
}
106+
107+
aiResp, _, err := ai.AskAIPersona(persona, query, results)
108+
if err != nil {
109+
fmt.Printf("Error from AI: %v\n", err)
110+
return ""
111+
}
112+
113+
fmt.Println()
114+
fmt.Printf("🤖 AI %s Persona:\n", strings.Title(persona))
115+
fmt.Println("══════════════════════════════════════════════════════════════")
116+
fmt.Println(aiResp)
117+
fmt.Println("══════════════════════════════════════════════════════════════")
118+
fmt.Println()
119+
120+
return aiResp
95121
}
96122

97123
func handleAddCommand(args string) {
@@ -206,23 +232,6 @@ func handleListCommand() {
206232
fmt.Println()
207233
}
208234

209-
func handleCountCommand() {
210-
received, err := database.SearchCommands("", "json")
211-
if err != nil {
212-
fmt.Printf("Error counting commands: %v\n", err)
213-
return
214-
}
215-
216-
var results []database.CommandRecord
217-
if err := json.Unmarshal(received, &results); err != nil {
218-
fmt.Printf("Error parsing results: %v\n", err)
219-
return
220-
}
221-
222-
fmt.Println()
223-
fmt.Printf("Total commands in database: %d\n", len(results))
224-
fmt.Println()
225-
}
226235

227236
func clearScreen() {
228237
fmt.Print("\033[H\033[2J")

0 commit comments

Comments
 (0)