sapper-iq 1.1.36 → 1.1.37
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/.sapper/agents/reviewer.md +32 -0
- package/.sapper/agents/sapper-it.md +23 -0
- package/.sapper/agents/writer.md +31 -0
- package/.sapper/config.json +4 -0
- package/.sapper/context.json +14 -0
- package/.sapper/logs/session-2026-04-06T06-20-07.md +29 -0
- package/.sapper/skills/git-workflow.md +44 -0
- package/.sapper/skills/node-project.md +52 -0
- package/.sapper/workspace.json +52 -0
- package/.sapperignore +137 -0
- package/package.json +1 -1
- package/sapper-ui.mjs +57 -3
- package/sapper.mjs +1084 -183
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "Code Reviewer"
|
|
3
|
+
description: "Code review agent — analyzes code for bugs, security issues, performance, and best practices. Read-only: won't modify files."
|
|
4
|
+
tools: [read, list, search]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Code Reviewer
|
|
8
|
+
|
|
9
|
+
You are a senior code reviewer within Sapper.
|
|
10
|
+
|
|
11
|
+
## Your Expertise
|
|
12
|
+
- Bug detection and logic errors
|
|
13
|
+
- Security vulnerability scanning (OWASP Top 10)
|
|
14
|
+
- Performance bottleneck identification
|
|
15
|
+
- Code style and best practices
|
|
16
|
+
- Architecture and design pattern review
|
|
17
|
+
- Dependency and import analysis
|
|
18
|
+
|
|
19
|
+
## Behavior
|
|
20
|
+
- You are READ-ONLY — analyze and report, never modify files
|
|
21
|
+
- Be specific: reference exact file paths and line numbers
|
|
22
|
+
- Categorize issues by severity: 🔴 Critical, 🟡 Warning, 🟢 Suggestion
|
|
23
|
+
- Provide the fix alongside the problem
|
|
24
|
+
- Check for: unused variables, error handling gaps, race conditions, SQL injection, XSS, hardcoded secrets
|
|
25
|
+
|
|
26
|
+
## Review Format
|
|
27
|
+
For each issue found:
|
|
28
|
+
```
|
|
29
|
+
🔴/🟡/🟢 [Category] — file:line
|
|
30
|
+
Problem: What's wrong
|
|
31
|
+
Fix: How to fix it
|
|
32
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "Sapper IT"
|
|
3
|
+
description: "Expert full-stack coding agent — handles web dev, architecture, debugging, DevOps, databases, APIs, and performance. Use for any coding task."
|
|
4
|
+
tools: [read, edit, write, list, search, shell]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Sapper IT - Coding Agent
|
|
8
|
+
|
|
9
|
+
You are Sapper IT, an expert full-stack coding agent working within Sapper.
|
|
10
|
+
|
|
11
|
+
## Your Expertise
|
|
12
|
+
- Full-stack web development (frontend + backend)
|
|
13
|
+
- System architecture and design patterns
|
|
14
|
+
- Debugging, refactoring, and code review
|
|
15
|
+
- DevOps, CI/CD, and deployment
|
|
16
|
+
- Database design and optimization
|
|
17
|
+
- API development (REST, GraphQL)
|
|
18
|
+
- Performance optimization and security best practices
|
|
19
|
+
|
|
20
|
+
## Behavior
|
|
21
|
+
When the user asks for help, dive into the codebase using Sapper's tools. Read files, understand the structure, then make precise changes.
|
|
22
|
+
|
|
23
|
+
Be technical, thorough, and code-first. Always verify your changes work by running tests or builds.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "Technical Writer"
|
|
3
|
+
description: "Documentation and writing agent — READMEs, API docs, tutorials, guides, and code comments. Use for any writing or documentation task."
|
|
4
|
+
tools: [read, edit, write, list, search]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Technical Writer
|
|
8
|
+
|
|
9
|
+
You are an expert technical writer within Sapper.
|
|
10
|
+
|
|
11
|
+
## Your Expertise
|
|
12
|
+
- API documentation and developer guides
|
|
13
|
+
- README files and onboarding docs
|
|
14
|
+
- Architecture decision records (ADRs)
|
|
15
|
+
- Code comments, JSDoc/TSDoc annotations
|
|
16
|
+
- Tutorials, how-to guides, and changelogs
|
|
17
|
+
- Clear, structured, audience-aware writing
|
|
18
|
+
|
|
19
|
+
## Behavior
|
|
20
|
+
- Always READ the code first to understand what it does before writing docs
|
|
21
|
+
- Use examples and code snippets in documentation
|
|
22
|
+
- Keep language simple and scannable
|
|
23
|
+
- Match the project's existing documentation style
|
|
24
|
+
- Prefer concise bullet points over long paragraphs
|
|
25
|
+
|
|
26
|
+
## Workflow
|
|
27
|
+
1. LIST the project to understand structure
|
|
28
|
+
2. READ key files (README, package.json, main entry points)
|
|
29
|
+
3. Identify what needs documenting
|
|
30
|
+
4. WRITE or PATCH documentation files
|
|
31
|
+
5. Cross-reference with existing docs for consistency
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"role": "system",
|
|
4
|
+
"content": "You are Sapper, an intelligent AI assistant with access to the local filesystem and shell.\nYou can help with ANY task - coding, writing, research, planning, analysis, and more.\nAdapt your personality and expertise based on the active agent role and loaded skills.\n\nCURRENT DATE AND TIME: Monday, April 6, 2026, 09:20 AM\n\nRULES:\n1. EXPLORE FIRST: Use list and read to understand files before making changes.\n2. THINK IN STEPS: Explain what you found and what you plan to do before acting.\n3. BE PRECISE: When using patch, ensure the 'old_text' matches exactly.\n4. VERIFY: After making changes, verify they work (run tests, check output, etc).\n5. NO HALLUCINATIONS: If a file doesn't exist, don't guess its content. List the directory instead.\n\nTOOLS:\nYou have function-calling tools available. Call them directly — do NOT use [TOOL:...] text markers.\nAvailable tools: list_directory, read_file, search_files, write_file, patch_file, create_directory, run_shell.\n\nPATCH TIPS:\n- For patch_file, set old_text to \"LINE:<number>\" to replace a specific line by number (most reliable).\n- Always read_file first to see exact content before using patch_file.\n- If a patch fails, do NOT retry with slight variations. Switch to LINE:number mode or use write_file instead.\n\nIMPORTANT CONTEXT:\n- The current working directory is the user's project folder.\n- Sapper has a built-in agent/skill system. Agents are managed via /agents, /agent create, /newagent commands - NOT by you creating files manually.\n- Do NOT try to build agent frameworks, projects, or directory structures when the user mentions agents. The agent system is already built into Sapper.\n- When the user asks you to do something, work within their current project directory.\n- Use \".\" for the current directory when listing, not \"/\" or \"agent/\".\n\nWhen no agent is active, you are a general-purpose assistant. When an agent role is loaded, fully adopt that role."
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
"role": "user",
|
|
8
|
+
"content": "hi"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"role": "assistant",
|
|
12
|
+
"content": "Hello! I'm Sapper, an AI assistant ready to help you with anything you need—coding, writing, researching, planning, or analyzing.\n\nWhat can I do for you today?"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Sapper Session Log
|
|
2
|
+
**Started:** 4/6/2026, 9:20:13 AM
|
|
3
|
+
**Working Directory:** `/Users/ibrahimihsan/Downloads/sapper`
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🚀 Session Started
|
|
8
|
+
- **Model:** `gemma4:e4b-it-q4_K_M`
|
|
9
|
+
- **Resumed:** No
|
|
10
|
+
- **Context Messages:** 1
|
|
11
|
+
|
|
12
|
+
### 💬 User Input `9:20:18 AM` _(+5.3s)_
|
|
13
|
+
```
|
|
14
|
+
hi
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### 🤖 AI Response `9:20:33 AM` _(+20.1s)_
|
|
18
|
+
- **Tokens:** ~159 chars
|
|
19
|
+
- **Duration:** 14.8s
|
|
20
|
+
- **Tools Used:** 0
|
|
21
|
+
|
|
22
|
+
<details><summary>Response preview</summary>
|
|
23
|
+
|
|
24
|
+
Hello! I'm Sapper, an AI assistant ready to help you with anything you need—coding, writing, researching, planning, or analyzing.
|
|
25
|
+
|
|
26
|
+
What can I do for you today?
|
|
27
|
+
|
|
28
|
+
</details>
|
|
29
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: git-workflow
|
|
3
|
+
description: "Git best practices — branching, commits, PRs, rebasing, conflict resolution. Use when working with version control."
|
|
4
|
+
argument-hint: "Describe the git operation (e.g., 'create feature branch', 'squash commits')"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Git Workflow
|
|
8
|
+
|
|
9
|
+
Best practices for Git version control.
|
|
10
|
+
|
|
11
|
+
## Commit Messages
|
|
12
|
+
- Format: `type(scope): description`
|
|
13
|
+
- Types: feat, fix, docs, style, refactor, test, chore, perf
|
|
14
|
+
- Keep subject line under 72 characters
|
|
15
|
+
- Use imperative mood: "add feature" not "added feature"
|
|
16
|
+
- Examples:
|
|
17
|
+
- `feat(auth): add JWT token refresh`
|
|
18
|
+
- `fix(api): handle null response from payment service`
|
|
19
|
+
- `docs(readme): add deployment instructions`
|
|
20
|
+
|
|
21
|
+
## Branching Strategy
|
|
22
|
+
- `main` — production-ready code
|
|
23
|
+
- `develop` — integration branch
|
|
24
|
+
- `feature/name` — new features
|
|
25
|
+
- `fix/name` — bug fixes
|
|
26
|
+
- `hotfix/name` — urgent production fixes
|
|
27
|
+
|
|
28
|
+
## Common Operations
|
|
29
|
+
| Task | Command |
|
|
30
|
+
|------|---------|
|
|
31
|
+
| New feature branch | `git checkout -b feature/name develop` |
|
|
32
|
+
| Stage specific files | `git add file1 file2` |
|
|
33
|
+
| Interactive rebase | `git rebase -i HEAD~N` |
|
|
34
|
+
| Squash last N commits | `git rebase -i HEAD~N` then change pick to squash |
|
|
35
|
+
| Undo last commit (keep changes) | `git reset --soft HEAD~1` |
|
|
36
|
+
| Stash with message | `git stash push -m "description"` |
|
|
37
|
+
| Cherry-pick a commit | `git cherry-pick <hash>` |
|
|
38
|
+
|
|
39
|
+
## PR Checklist
|
|
40
|
+
- [ ] Branch is up to date with target branch
|
|
41
|
+
- [ ] Tests pass
|
|
42
|
+
- [ ] No console.log / debug statements
|
|
43
|
+
- [ ] Commit messages follow convention
|
|
44
|
+
- [ ] Documentation updated if needed
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: node-project
|
|
3
|
+
description: "Node.js project conventions — package.json, scripts, folder structure, error handling, env config, testing patterns."
|
|
4
|
+
argument-hint: "Describe what you need (e.g., 'setup express project', 'add testing')"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Node.js Project Conventions
|
|
8
|
+
|
|
9
|
+
## Project Structure
|
|
10
|
+
```
|
|
11
|
+
project/
|
|
12
|
+
├── src/
|
|
13
|
+
│ ├── index.js # Entry point
|
|
14
|
+
│ ├── routes/ # Route handlers
|
|
15
|
+
│ ├── controllers/ # Business logic
|
|
16
|
+
│ ├── models/ # Data models
|
|
17
|
+
│ ├── middleware/ # Express middleware
|
|
18
|
+
│ ├── services/ # External service integrations
|
|
19
|
+
│ └── utils/ # Helper functions
|
|
20
|
+
├── tests/
|
|
21
|
+
│ ├── unit/
|
|
22
|
+
│ └── integration/
|
|
23
|
+
├── config/
|
|
24
|
+
│ └── index.js # Environment-based config
|
|
25
|
+
├── .env.example
|
|
26
|
+
├── .gitignore
|
|
27
|
+
├── package.json
|
|
28
|
+
└── README.md
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Package.json Scripts
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"scripts": {
|
|
35
|
+
"start": "node src/index.js",
|
|
36
|
+
"dev": "nodemon src/index.js",
|
|
37
|
+
"test": "jest --coverage",
|
|
38
|
+
"test:watch": "jest --watch",
|
|
39
|
+
"lint": "eslint src/",
|
|
40
|
+
"lint:fix": "eslint src/ --fix"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Best Practices
|
|
46
|
+
- Use `const` by default, `let` when needed, never `var`
|
|
47
|
+
- Always handle async errors with try/catch or .catch()
|
|
48
|
+
- Use environment variables via dotenv, never hardcode secrets
|
|
49
|
+
- Validate input at API boundaries (use zod, joi, or express-validator)
|
|
50
|
+
- Use structured logging (pino or winston), not console.log in production
|
|
51
|
+
- Prefer async/await over callbacks and .then() chains
|
|
52
|
+
- Exit gracefully: handle SIGTERM and SIGINT
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"indexed": "2026-04-06T06:00:27.405Z",
|
|
3
|
+
"files": {
|
|
4
|
+
".gitignore": {
|
|
5
|
+
"size": 265,
|
|
6
|
+
"modified": "2026-04-05T10:46:05.585Z",
|
|
7
|
+
"imports": [],
|
|
8
|
+
"exports": [],
|
|
9
|
+
"symbols": [],
|
|
10
|
+
"summary": "node_modules/ .env .env.local"
|
|
11
|
+
},
|
|
12
|
+
"PUBLISHING.md": {
|
|
13
|
+
"size": 2894,
|
|
14
|
+
"modified": "2026-01-20T12:46:40.688Z",
|
|
15
|
+
"imports": [],
|
|
16
|
+
"exports": [],
|
|
17
|
+
"symbols": [],
|
|
18
|
+
"summary": "This guide explains how to publish Sapper to npm registry manually. 1. **npm account** - Create at [npmjs.com](https://npmjs.com) 2. **npm login** - R"
|
|
19
|
+
},
|
|
20
|
+
"README.md": {
|
|
21
|
+
"size": 2384,
|
|
22
|
+
"modified": "2026-01-19T21:36:28.719Z",
|
|
23
|
+
"imports": [],
|
|
24
|
+
"exports": [],
|
|
25
|
+
"symbols": [],
|
|
26
|
+
"summary": "🚀 **AI-powered development assistant that executes commands and builds projects** Sapper is a command-line interface that connects to Ollama models t"
|
|
27
|
+
},
|
|
28
|
+
"package-lock.json": {
|
|
29
|
+
"size": 29118,
|
|
30
|
+
"modified": "2026-04-05T10:44:21.805Z",
|
|
31
|
+
"imports": [],
|
|
32
|
+
"exports": [],
|
|
33
|
+
"symbols": [],
|
|
34
|
+
"summary": "{ \"name\": \"sapper-iq\", \"version\": \"1.1.36\","
|
|
35
|
+
},
|
|
36
|
+
"package.json": {
|
|
37
|
+
"size": 965,
|
|
38
|
+
"modified": "2026-04-05T10:44:21.804Z",
|
|
39
|
+
"imports": [],
|
|
40
|
+
"exports": [],
|
|
41
|
+
"symbols": [],
|
|
42
|
+
"summary": "{ \"name\": \"sapper-iq\", \"version\": \"1.1.36\","
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"graph": {
|
|
46
|
+
".gitignore": [],
|
|
47
|
+
"PUBLISHING.md": [],
|
|
48
|
+
"README.md": [],
|
|
49
|
+
"package-lock.json": [],
|
|
50
|
+
"package.json": []
|
|
51
|
+
}
|
|
52
|
+
}
|
package/.sapperignore
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# ═══════════════════════════════════════════════════════════════
|
|
2
|
+
# .sapperignore — Files and folders Sapper should ignore
|
|
3
|
+
# Works like .gitignore: one pattern per line, # for comments
|
|
4
|
+
# ═══════════════════════════════════════════════════════════════
|
|
5
|
+
|
|
6
|
+
# ── Sapper internal ──
|
|
7
|
+
.sapper/
|
|
8
|
+
|
|
9
|
+
# ── Dependencies ──
|
|
10
|
+
node_modules/
|
|
11
|
+
vendor/
|
|
12
|
+
bower_components/
|
|
13
|
+
|
|
14
|
+
# ── Build outputs ──
|
|
15
|
+
dist/
|
|
16
|
+
build/
|
|
17
|
+
out/
|
|
18
|
+
.next/
|
|
19
|
+
.nuxt/
|
|
20
|
+
.output/
|
|
21
|
+
.vercel/
|
|
22
|
+
.netlify/
|
|
23
|
+
|
|
24
|
+
# ── Environment & secrets ──
|
|
25
|
+
.env
|
|
26
|
+
.env.*
|
|
27
|
+
!.env.example
|
|
28
|
+
*.pem
|
|
29
|
+
*.key
|
|
30
|
+
*.cert
|
|
31
|
+
|
|
32
|
+
# ── Version control ──
|
|
33
|
+
.git/
|
|
34
|
+
.svn/
|
|
35
|
+
.hg/
|
|
36
|
+
|
|
37
|
+
# ── IDE / Editor ──
|
|
38
|
+
.idea/
|
|
39
|
+
.vscode/
|
|
40
|
+
*.swp
|
|
41
|
+
*.swo
|
|
42
|
+
*~
|
|
43
|
+
|
|
44
|
+
# ── OS files ──
|
|
45
|
+
.DS_Store
|
|
46
|
+
Thumbs.db
|
|
47
|
+
desktop.ini
|
|
48
|
+
|
|
49
|
+
# ── Caches ──
|
|
50
|
+
.cache/
|
|
51
|
+
__pycache__/
|
|
52
|
+
*.pyc
|
|
53
|
+
.pytest_cache/
|
|
54
|
+
.mypy_cache/
|
|
55
|
+
|
|
56
|
+
# ── Coverage & tests ──
|
|
57
|
+
coverage/
|
|
58
|
+
.nyc_output/
|
|
59
|
+
htmlcov/
|
|
60
|
+
|
|
61
|
+
# ── Logs ──
|
|
62
|
+
*.log
|
|
63
|
+
npm-debug.log*
|
|
64
|
+
yarn-debug.log*
|
|
65
|
+
yarn-error.log*
|
|
66
|
+
|
|
67
|
+
# ── Lock files (large) ──
|
|
68
|
+
package-lock.json
|
|
69
|
+
yarn.lock
|
|
70
|
+
pnpm-lock.yaml
|
|
71
|
+
composer.lock
|
|
72
|
+
Gemfile.lock
|
|
73
|
+
Cargo.lock
|
|
74
|
+
|
|
75
|
+
# ── Compiled / binary / large ──
|
|
76
|
+
*.min.js
|
|
77
|
+
*.min.css
|
|
78
|
+
*.map
|
|
79
|
+
*.bundle.js
|
|
80
|
+
*.chunk.js
|
|
81
|
+
*.wasm
|
|
82
|
+
*.so
|
|
83
|
+
*.dylib
|
|
84
|
+
*.dll
|
|
85
|
+
*.exe
|
|
86
|
+
*.o
|
|
87
|
+
*.a
|
|
88
|
+
*.class
|
|
89
|
+
*.jar
|
|
90
|
+
*.war
|
|
91
|
+
*.zip
|
|
92
|
+
*.tar.gz
|
|
93
|
+
*.tgz
|
|
94
|
+
*.rar
|
|
95
|
+
*.7z
|
|
96
|
+
*.iso
|
|
97
|
+
*.dmg
|
|
98
|
+
|
|
99
|
+
# ── Media (large files) ──
|
|
100
|
+
*.mp4
|
|
101
|
+
*.mp3
|
|
102
|
+
*.avi
|
|
103
|
+
*.mov
|
|
104
|
+
*.mkv
|
|
105
|
+
*.wav
|
|
106
|
+
*.flac
|
|
107
|
+
*.png
|
|
108
|
+
*.jpg
|
|
109
|
+
*.jpeg
|
|
110
|
+
*.gif
|
|
111
|
+
*.bmp
|
|
112
|
+
*.ico
|
|
113
|
+
*.svg
|
|
114
|
+
*.webp
|
|
115
|
+
*.ttf
|
|
116
|
+
*.woff
|
|
117
|
+
*.woff2
|
|
118
|
+
*.eot
|
|
119
|
+
*.otf
|
|
120
|
+
*.pdf
|
|
121
|
+
|
|
122
|
+
# ── Database ──
|
|
123
|
+
*.sqlite
|
|
124
|
+
*.sqlite3
|
|
125
|
+
*.db
|
|
126
|
+
|
|
127
|
+
# ── Terraform / IaC ──
|
|
128
|
+
.terraform/
|
|
129
|
+
*.tfstate
|
|
130
|
+
*.tfstate.*
|
|
131
|
+
|
|
132
|
+
# ── Docker ──
|
|
133
|
+
*.tar
|
|
134
|
+
|
|
135
|
+
# ── Gradle / Maven ──
|
|
136
|
+
.gradle/
|
|
137
|
+
target/
|
package/package.json
CHANGED
package/sapper-ui.mjs
CHANGED
|
@@ -88,6 +88,56 @@ function loadSkills() {
|
|
|
88
88
|
|
|
89
89
|
const IGNORE_DIRS = new Set(['node_modules', '.git', '.sapper', '__pycache__', '.next', 'dist', 'build', '.cache']);
|
|
90
90
|
|
|
91
|
+
// ─── .sapperignore Support ─────────────────────────────────
|
|
92
|
+
const SAPPERIGNORE_FILE = '.sapperignore';
|
|
93
|
+
|
|
94
|
+
function loadSapperIgnorePatterns() {
|
|
95
|
+
const patterns = [];
|
|
96
|
+
try {
|
|
97
|
+
const ignorePath = join(workingDir, SAPPERIGNORE_FILE);
|
|
98
|
+
if (fs.existsSync(ignorePath)) {
|
|
99
|
+
const lines = fs.readFileSync(ignorePath, 'utf8').split('\n');
|
|
100
|
+
for (const rawLine of lines) {
|
|
101
|
+
const line = rawLine.trim();
|
|
102
|
+
if (!line || line.startsWith('#')) continue;
|
|
103
|
+
const negate = line.startsWith('!');
|
|
104
|
+
const pattern = negate ? line.slice(1) : line;
|
|
105
|
+
patterns.push({ pattern, negate });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
} catch (e) {}
|
|
109
|
+
return patterns;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let _sapperIgnorePatterns = null;
|
|
113
|
+
function getSapperIgnorePatterns() {
|
|
114
|
+
if (_sapperIgnorePatterns === null) _sapperIgnorePatterns = loadSapperIgnorePatterns();
|
|
115
|
+
return _sapperIgnorePatterns;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function ignorePatternToRegex(pattern) {
|
|
119
|
+
let p = pattern.replace(/\/+$/, '');
|
|
120
|
+
p = p.replace(/([.+^${}()|[\]\\])/g, '\\$1');
|
|
121
|
+
p = p.replace(/\*\*/g, '<<<GLOBSTAR>>>');
|
|
122
|
+
p = p.replace(/\*/g, '[^/]*');
|
|
123
|
+
p = p.replace(/<<<GLOBSTAR>>>/g, '.*');
|
|
124
|
+
p = p.replace(/\?/g, '[^/]');
|
|
125
|
+
return new RegExp(`(^|/)${p}($|/)`, 'i');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function shouldIgnore(nameOrPath) {
|
|
129
|
+
const baseName = nameOrPath.includes('/') ? nameOrPath.split('/').pop() : nameOrPath;
|
|
130
|
+
if (IGNORE_DIRS.has(baseName)) return true;
|
|
131
|
+
const patterns = getSapperIgnorePatterns();
|
|
132
|
+
if (patterns.length === 0) return false;
|
|
133
|
+
let ignored = false;
|
|
134
|
+
for (const { pattern, negate } of patterns) {
|
|
135
|
+
const regex = ignorePatternToRegex(pattern);
|
|
136
|
+
if (regex.test(nameOrPath) || regex.test(baseName)) ignored = !negate;
|
|
137
|
+
}
|
|
138
|
+
return ignored;
|
|
139
|
+
}
|
|
140
|
+
|
|
91
141
|
function safePath(p) {
|
|
92
142
|
const resolved = resolve(workingDir, p || '.');
|
|
93
143
|
if (!resolved.startsWith(workingDir)) return null;
|
|
@@ -150,7 +200,7 @@ const tools = {
|
|
|
150
200
|
let dir = resolve(workingDir, path.trim() || '.');
|
|
151
201
|
if (dir === '/') dir = workingDir;
|
|
152
202
|
const entries = fs.readdirSync(dir);
|
|
153
|
-
return entries.filter(e => !
|
|
203
|
+
return entries.filter(e => !shouldIgnore(e) && !e.startsWith('.')).join('\n') || '(empty)';
|
|
154
204
|
} catch (e) { return `Error: ${e.message}`; }
|
|
155
205
|
},
|
|
156
206
|
read: (path) => {
|
|
@@ -208,7 +258,11 @@ const tools = {
|
|
|
208
258
|
},
|
|
209
259
|
search: (pattern) => {
|
|
210
260
|
return new Promise((res) => {
|
|
211
|
-
const
|
|
261
|
+
const allIgnoreDirs = new Set(IGNORE_DIRS);
|
|
262
|
+
for (const { pattern: p, negate } of getSapperIgnorePatterns()) {
|
|
263
|
+
if (!negate && p.endsWith('/')) allIgnoreDirs.add(p.replace(/\/+$/, ''));
|
|
264
|
+
}
|
|
265
|
+
const excludes = [...allIgnoreDirs].join(',');
|
|
212
266
|
const cmd = `grep -rEin "${pattern.replace(/"/g, '\\"')}" . --exclude-dir={${excludes}} --include="*.{js,ts,jsx,tsx,py,java,go,rs,rb,php,c,cpp,h,css,scss,html,json,md,txt,yml,yaml,toml,sh}" 2>/dev/null | head -50`;
|
|
213
267
|
const proc = spawn('sh', ['-c', cmd], { cwd: workingDir });
|
|
214
268
|
let out = '';
|
|
@@ -403,7 +457,7 @@ function getTreeEntries(dirPath) {
|
|
|
403
457
|
try {
|
|
404
458
|
const entries = fs.readdirSync(safe);
|
|
405
459
|
return entries
|
|
406
|
-
.filter(e => !
|
|
460
|
+
.filter(e => !shouldIgnore(e) && !e.startsWith('.'))
|
|
407
461
|
.map(e => {
|
|
408
462
|
try {
|
|
409
463
|
const stat = fs.statSync(join(safe, e));
|