opensidian 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.
- package/.eslintrc.json +1 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +49 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +35 -0
- package/.github/ISSUE_TEMPLATE/question.md +23 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +45 -0
- package/.github/README.md +5 -0
- package/.github/workflows/cd.yml +44 -0
- package/.github/workflows/ci.yml +128 -0
- package/.github/workflows/qa.yml +45 -0
- package/.planning/PROJECT.md +96 -0
- package/.planning/REQUIREMENTS.md +66 -0
- package/.planning/ROADMAP.md +129 -0
- package/.planning/STATE.md +47 -0
- package/.planning/config.json +14 -0
- package/CONTRIBUTING.md +232 -0
- package/LICENSE +21 -0
- package/README.md +244 -0
- package/dist/api/auth.d.ts +5 -0
- package/dist/api/auth.d.ts.map +1 -0
- package/dist/api/auth.js +112 -0
- package/dist/api/auth.js.map +1 -0
- package/dist/api/routes.d.ts +3 -0
- package/dist/api/routes.d.ts.map +1 -0
- package/dist/api/routes.js +119 -0
- package/dist/api/routes.js.map +1 -0
- package/dist/api/themes.d.ts +3 -0
- package/dist/api/themes.d.ts.map +1 -0
- package/dist/api/themes.js +48 -0
- package/dist/api/themes.js.map +1 -0
- package/dist/core/graph.d.ts +16 -0
- package/dist/core/graph.d.ts.map +1 -0
- package/dist/core/graph.js +115 -0
- package/dist/core/graph.js.map +1 -0
- package/dist/core/markdown.d.ts +21 -0
- package/dist/core/markdown.d.ts.map +1 -0
- package/dist/core/markdown.js +77 -0
- package/dist/core/markdown.js.map +1 -0
- package/dist/core/search.d.ts +34 -0
- package/dist/core/search.d.ts.map +1 -0
- package/dist/core/search.js +159 -0
- package/dist/core/search.js.map +1 -0
- package/dist/core/sync.d.ts +30 -0
- package/dist/core/sync.d.ts.map +1 -0
- package/dist/core/sync.js +121 -0
- package/dist/core/sync.js.map +1 -0
- package/dist/core/vault.d.ts +28 -0
- package/dist/core/vault.d.ts.map +1 -0
- package/dist/core/vault.js +235 -0
- package/dist/core/vault.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/cli.d.ts +3 -0
- package/dist/mcp/cli.d.ts.map +1 -0
- package/dist/mcp/cli.js +7 -0
- package/dist/mcp/cli.js.map +1 -0
- package/dist/mcp/server.d.ts +18 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +272 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/plugins/host.d.ts +23 -0
- package/dist/plugins/host.d.ts.map +1 -0
- package/dist/plugins/host.js +104 -0
- package/dist/plugins/host.js.map +1 -0
- package/dist/plugins/sample-plugin.d.ts +10 -0
- package/dist/plugins/sample-plugin.d.ts.map +1 -0
- package/dist/plugins/sample-plugin.js +23 -0
- package/dist/plugins/sample-plugin.js.map +1 -0
- package/dist/server.d.ts +15 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +77 -0
- package/dist/server.js.map +1 -0
- package/dist/shared/types.d.ts +86 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +2 -0
- package/dist/shared/types.js.map +1 -0
- package/docker/Dockerfile +37 -0
- package/docker/docker-compose.yml +46 -0
- package/docs/ARCHITECTURE.md +321 -0
- package/futuras_implementacoes.md +0 -0
- package/package.json +65 -0
- package/scripts/fix-gitignore.ps1 +5 -0
- package/scripts/seed-notes.mjs +60 -0
- package/src/api/auth.ts +130 -0
- package/src/api/routes.ts +133 -0
- package/src/api/themes.ts +60 -0
- package/src/core/graph.ts +145 -0
- package/src/core/markdown.ts +92 -0
- package/src/core/search.ts +208 -0
- package/src/core/sync.ts +157 -0
- package/src/core/vault.ts +286 -0
- package/src/index.ts +37 -0
- package/src/mcp/cli.ts +7 -0
- package/src/mcp/server.ts +296 -0
- package/src/plugins/host.ts +120 -0
- package/src/plugins/sample-plugin.ts +29 -0
- package/src/server.ts +90 -0
- package/src/shared/types.ts +92 -0
- package/tests/api/routes.test.ts +167 -0
- package/tests/core/graph.test.ts +236 -0
- package/tests/core/markdown.test.ts +157 -0
- package/tests/core/search.test.ts +132 -0
- package/tests/core/sync.test.ts +62 -0
- package/tests/core/vault.test.ts +162 -0
- package/tests/mcp/server.test.ts +118 -0
- package/tests/plugins/host.test.ts +165 -0
- package/tests/plugins/sample-plugin.test.ts +35 -0
- package/tests/server.test.ts +76 -0
- package/tsconfig.json +27 -0
- package/vite.config.ts +27 -0
- package/vitest.config.ts +33 -0
- package/web/index.html +13 -0
- package/web/package.json +26 -0
- package/web/public/favicon.svg +4 -0
- package/web/src/App.tsx +63 -0
- package/web/src/api/auth.ts +65 -0
- package/web/src/api/client.ts +117 -0
- package/web/src/api/themes.ts +78 -0
- package/web/src/components/GraphView.tsx +139 -0
- package/web/src/components/Layout.tsx +74 -0
- package/web/src/components/LoginPage.tsx +52 -0
- package/web/src/components/NoteEditor.tsx +114 -0
- package/web/src/components/NoteList.tsx +95 -0
- package/web/src/components/RegisterPage.tsx +58 -0
- package/web/src/components/SearchBar.tsx +71 -0
- package/web/src/components/SearchPanel.tsx +152 -0
- package/web/src/components/ThemeEditor.tsx +129 -0
- package/web/src/components/ThemeSelector.tsx +41 -0
- package/web/src/components/VaultList.tsx +89 -0
- package/web/src/hooks/AuthContext.tsx +57 -0
- package/web/src/hooks/ThemeContext.tsx +77 -0
- package/web/src/hooks/useWebSocket.ts +34 -0
- package/web/src/main.tsx +10 -0
- package/web/src/styles/global.css +449 -0
- package/web/tsconfig.json +21 -0
- package/web/vite.config.ts +19 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# State: OpenSidian
|
|
2
|
+
|
|
3
|
+
**Version:** 2.0.0
|
|
4
|
+
**Status:** completed
|
|
5
|
+
**Started:** 2026-05-06
|
|
6
|
+
**Completed:** 2026-05-06
|
|
7
|
+
|
|
8
|
+
## Milestone v2.0
|
|
9
|
+
|
|
10
|
+
**Status:** Complete 🎉
|
|
11
|
+
|
|
12
|
+
All 3 phases finished:
|
|
13
|
+
|
|
14
|
+
| Phase | Status |
|
|
15
|
+
|-------|--------|
|
|
16
|
+
| 8. Indexador Full-Text (TF-IDF, stopwords, persistência) | ✅ |
|
|
17
|
+
| 9. API de Busca (REST + MCP + filtros + highlighting) | ✅ |
|
|
18
|
+
| 10. Frontend de Busca (painel avançado com filtros visuais) | ✅ |
|
|
19
|
+
|
|
20
|
+
## Project Reference
|
|
21
|
+
|
|
22
|
+
See: .planning/PROJECT.md (updated 2026-05-06)
|
|
23
|
+
|
|
24
|
+
**Core value:** Usuários podem escrever notas em Markdown, conectá-las com links, visualizar o grafo de conhecimento e sincronizar em tempo real — open-source e auto-hospedável.
|
|
25
|
+
|
|
26
|
+
## Decisions
|
|
27
|
+
|
|
28
|
+
| Decision | Rationale | Outcome |
|
|
29
|
+
|----------|-----------|---------|
|
|
30
|
+
| TypeScript + Node.js | Ecossistema maduro, tipagem segura | ✓ Good |
|
|
31
|
+
| MCP SDK oficial | Integração nativa com LLMs | ✓ Good |
|
|
32
|
+
| Markdown puro | Máxima compatibilidade | ✓ Good |
|
|
33
|
+
| Vitest | Mais rápido, nativo ESM | ✓ Good |
|
|
34
|
+
| React + Vite | Popular, tipagem forte, build rápido | ✓ Good |
|
|
35
|
+
|
|
36
|
+
## Resultados
|
|
37
|
+
|
|
38
|
+
- 79 testes unitários passando
|
|
39
|
+
- Cobertura de código >80%
|
|
40
|
+
- Busca full-text com TF-IDF e ranking por relevância
|
|
41
|
+
- Highlighting com snippets posicionais e tags `<mark>`
|
|
42
|
+
- Filtros por tag, data e backlinks
|
|
43
|
+
- Índice persistido em disco
|
|
44
|
+
- Painel de busca avançada no frontend
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
*Last updated: 2026-05-06 after milestone v2.0 completion*
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mode": "yolo",
|
|
3
|
+
"granularity": "coarse",
|
|
4
|
+
"parallelization": true,
|
|
5
|
+
"commit_docs": true,
|
|
6
|
+
"model_profile": "balanced",
|
|
7
|
+
"workflow": {
|
|
8
|
+
"research": true,
|
|
9
|
+
"plan_check": true,
|
|
10
|
+
"verifier": true,
|
|
11
|
+
"nyquist_validation": false,
|
|
12
|
+
"auto_advance": true
|
|
13
|
+
}
|
|
14
|
+
}
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# Contributing to OpenSidian
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to OpenSidian!
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
### Prerequisites
|
|
8
|
+
|
|
9
|
+
- Node.js 20.x or higher
|
|
10
|
+
- npm 10.x or higher
|
|
11
|
+
|
|
12
|
+
### Getting Started
|
|
13
|
+
|
|
14
|
+
1. **Clone the repository**
|
|
15
|
+
```bash
|
|
16
|
+
git clone https://github.com/your-username/opensidian.git
|
|
17
|
+
cd opensidian
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
2. **Install dependencies**
|
|
21
|
+
```bash
|
|
22
|
+
npm install
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
3. **Run tests**
|
|
26
|
+
```bash
|
|
27
|
+
npm test
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
4. **Build the project**
|
|
31
|
+
```bash
|
|
32
|
+
npm run build
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
5. **Start development server**
|
|
36
|
+
```bash
|
|
37
|
+
npm run dev
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Project Structure
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
opensidian/
|
|
44
|
+
├── src/
|
|
45
|
+
│ ├── index.ts # Application entry point
|
|
46
|
+
│ ├── server.ts # Express server setup
|
|
47
|
+
│ ├── api/
|
|
48
|
+
│ │ └── routes.ts # REST API routes
|
|
49
|
+
│ ├── core/
|
|
50
|
+
│ │ ├── vault.ts # Vault management
|
|
51
|
+
│ │ ├── markdown.ts # Markdown parsing
|
|
52
|
+
│ │ ├── graph.ts # Knowledge graph
|
|
53
|
+
│ │ └── sync.ts # Real-time sync
|
|
54
|
+
│ ├── mcp/
|
|
55
|
+
│ │ └── server.ts # MCP server
|
|
56
|
+
│ ├── plugins/
|
|
57
|
+
│ │ ├── host.ts # Plugin system
|
|
58
|
+
│ │ └── sample-plugin.ts
|
|
59
|
+
│ └── shared/
|
|
60
|
+
│ └── types.ts # TypeScript types
|
|
61
|
+
├── tests/ # Test files
|
|
62
|
+
├── docker/ # Docker configuration
|
|
63
|
+
└── docs/ # Documentation
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Coding Standards
|
|
67
|
+
|
|
68
|
+
### TypeScript
|
|
69
|
+
|
|
70
|
+
- Use strict mode in `tsconfig.json`
|
|
71
|
+
- Prefer interfaces over type aliases for object shapes
|
|
72
|
+
- Use explicit return types for public functions
|
|
73
|
+
- Avoid `any` type
|
|
74
|
+
|
|
75
|
+
### Code Style
|
|
76
|
+
|
|
77
|
+
- 2 spaces for indentation
|
|
78
|
+
- Single quotes for strings
|
|
79
|
+
- Trailing commas in multiline
|
|
80
|
+
- Semicolons at end of statements
|
|
81
|
+
|
|
82
|
+
### Naming Conventions
|
|
83
|
+
|
|
84
|
+
- **Classes**: PascalCase (e.g., `VaultManager`)
|
|
85
|
+
- **Functions/Methods**: camelCase (e.g., `createNote`)
|
|
86
|
+
- **Constants**: SCREAMING_SNAKE_CASE (e.g., `DEFAULT_PORT`)
|
|
87
|
+
- **Files**: kebab-case (e.g., `vault-manager.ts`)
|
|
88
|
+
|
|
89
|
+
## Testing
|
|
90
|
+
|
|
91
|
+
### Writing Tests
|
|
92
|
+
|
|
93
|
+
- Place test files in `tests/` directory
|
|
94
|
+
- Name test files matching source: `vault.test.ts` for `vault.ts`
|
|
95
|
+
- Use descriptive test names: `should create note with frontmatter`
|
|
96
|
+
- Mock external dependencies
|
|
97
|
+
|
|
98
|
+
### Test Coverage
|
|
99
|
+
|
|
100
|
+
Maintain coverage above 80%:
|
|
101
|
+
- Statements
|
|
102
|
+
- Branches
|
|
103
|
+
- Functions
|
|
104
|
+
- Lines
|
|
105
|
+
|
|
106
|
+
Run coverage report:
|
|
107
|
+
```bash
|
|
108
|
+
npm run test:coverage
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Git Workflow
|
|
112
|
+
|
|
113
|
+
### Branch Naming
|
|
114
|
+
|
|
115
|
+
- `main` - Production-ready code
|
|
116
|
+
- `develop` - Integration branch
|
|
117
|
+
- `feature/*` - New features
|
|
118
|
+
- `bugfix/*` - Bug fixes
|
|
119
|
+
- `hotfix/*` - Urgent production fixes
|
|
120
|
+
|
|
121
|
+
### Commit Messages
|
|
122
|
+
|
|
123
|
+
Follow conventional commits:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
feat: add note search functionality
|
|
127
|
+
fix: resolve vault creation error
|
|
128
|
+
docs: update API documentation
|
|
129
|
+
test: add graph engine tests
|
|
130
|
+
refactor: improve link extraction
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Pull Requests
|
|
134
|
+
|
|
135
|
+
1. Create feature branch from `develop`
|
|
136
|
+
2. Make your changes
|
|
137
|
+
3. Add tests
|
|
138
|
+
4. Ensure all tests pass
|
|
139
|
+
5. Submit PR with description
|
|
140
|
+
|
|
141
|
+
## API Development
|
|
142
|
+
|
|
143
|
+
### REST API
|
|
144
|
+
|
|
145
|
+
Add new routes in `src/api/routes.ts`:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
router.get('/resource', (req, res) => {
|
|
149
|
+
// Handle request
|
|
150
|
+
res.json({ data });
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### MCP Tools
|
|
155
|
+
|
|
156
|
+
Add new tools in `src/mcp/server.ts`:
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
{
|
|
160
|
+
name: 'tool_name',
|
|
161
|
+
description: 'What the tool does',
|
|
162
|
+
inputSchema: {
|
|
163
|
+
type: 'object',
|
|
164
|
+
properties: {
|
|
165
|
+
param: { type: 'string', description: 'Description' }
|
|
166
|
+
},
|
|
167
|
+
required: ['param']
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Plugin Development
|
|
173
|
+
|
|
174
|
+
### Creating a Plugin
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { Plugin, PluginContext } from '@opensidian/plugin-api';
|
|
178
|
+
|
|
179
|
+
const myPlugin: Plugin = {
|
|
180
|
+
name: 'my-plugin',
|
|
181
|
+
version: '1.0.0',
|
|
182
|
+
async onLoad(context: PluginContext) {
|
|
183
|
+
context.registerCommand({
|
|
184
|
+
id: 'my-plugin:command',
|
|
185
|
+
label: 'My Command',
|
|
186
|
+
execute: () => console.log('Hello!')
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
context.registerHook('note:post-save', (note) => {
|
|
190
|
+
console.log('Note saved:', note.path);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
export default myPlugin;
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Plugin Hooks
|
|
199
|
+
|
|
200
|
+
- `note:pre-save(note)` - Modify note before saving
|
|
201
|
+
- `note:post-save(note)` - Side effects after saving
|
|
202
|
+
- `vault:pre-create(vault)` - Before vault creation
|
|
203
|
+
- `vault:post-create(vault)` - After vault creation
|
|
204
|
+
|
|
205
|
+
## Documentation
|
|
206
|
+
|
|
207
|
+
- Update README.md for user-facing changes
|
|
208
|
+
- Update ARCHITECTURE.md for architectural changes
|
|
209
|
+
- Add JSDoc comments for public APIs
|
|
210
|
+
- Update type definitions in `types.ts`
|
|
211
|
+
|
|
212
|
+
## Issues
|
|
213
|
+
|
|
214
|
+
### Bug Reports
|
|
215
|
+
|
|
216
|
+
Include:
|
|
217
|
+
- Clear description
|
|
218
|
+
- Steps to reproduce
|
|
219
|
+
- Expected vs actual behavior
|
|
220
|
+
- Environment (OS, Node.js version)
|
|
221
|
+
|
|
222
|
+
### Feature Requests
|
|
223
|
+
|
|
224
|
+
Include:
|
|
225
|
+
- Problem statement
|
|
226
|
+
- Proposed solution
|
|
227
|
+
- Use cases
|
|
228
|
+
- Alternatives considered
|
|
229
|
+
|
|
230
|
+
## License
|
|
231
|
+
|
|
232
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 OpenSidian Contributors
|
|
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,244 @@
|
|
|
1
|
+
# OpenSidian
|
|
2
|
+
|
|
3
|
+
**OpenSidian** é um sistema de gerenciamento de conhecimento open-source inspirado no Obsidian. Permite criar, organizar e interconectar notas em Markdown com indexação de grafo, sincronização em tempo real e suporte a plugins.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/thiagovasconcelosti/opensidian/actions/workflows/ci.yml)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
## Funcionalidades
|
|
9
|
+
|
|
10
|
+
- **Vaults**: Gerenciar múltiplos cofres de notas
|
|
11
|
+
- **Editor Markdown**: Preview ao vivo com suporte a `[[wikilink]]`
|
|
12
|
+
- **Grafo de Conhecimento**: Visualização interativa com D3.js
|
|
13
|
+
- **Sincronização**: Tempo real via WebSocket
|
|
14
|
+
- **Autenticação**: Login com JWT e sessão persistente
|
|
15
|
+
- **Temas**: Claro, escuro e temas customizáveis via editor visual
|
|
16
|
+
- **Plugins**: API para extensões com hooks e comandos
|
|
17
|
+
- **MCP Server**: Integração com IAs via Model Context Protocol
|
|
18
|
+
- **REST API**: HTTP endpoints para integração
|
|
19
|
+
- **Docker**: Containerização multi-stage
|
|
20
|
+
|
|
21
|
+
## Stack
|
|
22
|
+
|
|
23
|
+
| Camada | Tecnologia |
|
|
24
|
+
|--------|-----------|
|
|
25
|
+
| Backend | Node.js 20+, TypeScript, Express |
|
|
26
|
+
| Frontend | React 18, Vite, React Router |
|
|
27
|
+
| Graph | D3.js (force simulation) |
|
|
28
|
+
| Markdown | marked, front-matter |
|
|
29
|
+
| Sync | WebSocket (ws) |
|
|
30
|
+
| MCP | @modelcontextprotocol/sdk |
|
|
31
|
+
| Testes | Vitest (67 testes, cobertura >80%) |
|
|
32
|
+
| CI/CD | GitHub Actions (Windows/Mac/Linux) |
|
|
33
|
+
| Container | Docker multi-stage |
|
|
34
|
+
|
|
35
|
+
## Começar
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
git clone https://github.com/thiagovasconcelosti/opensidian.git
|
|
39
|
+
cd opensidian
|
|
40
|
+
npm install
|
|
41
|
+
npm run build
|
|
42
|
+
npm test
|
|
43
|
+
npm run dev
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Acessar: http://localhost:3000
|
|
47
|
+
|
|
48
|
+
## Estrutura
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
opensidian/
|
|
52
|
+
├── src/
|
|
53
|
+
│ ├── api/ # REST + Auth + Themes
|
|
54
|
+
│ ├── core/ # Vault, Markdown, Graph, Sync
|
|
55
|
+
│ ├── mcp/ # Model Context Protocol server
|
|
56
|
+
│ └── plugins/ # Plugin host + sample
|
|
57
|
+
├── web/ # React frontend
|
|
58
|
+
│ └── src/
|
|
59
|
+
│ ├── api/ # HTTP client
|
|
60
|
+
│ ├── components/ # UI components
|
|
61
|
+
│ └── hooks/ # AuthContext, ThemeContext
|
|
62
|
+
├── tests/ # 67 testes unitários
|
|
63
|
+
├── docker/ # Dockerfile + compose
|
|
64
|
+
└── docs/ # Arquitetura
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## API REST
|
|
68
|
+
|
|
69
|
+
### Auth
|
|
70
|
+
|
|
71
|
+
| Método | Rota | Descrição |
|
|
72
|
+
|--------|------|-----------|
|
|
73
|
+
| POST | `/auth/register` | Criar conta |
|
|
74
|
+
| POST | `/auth/login` | Login |
|
|
75
|
+
| GET | `/auth/me` | Dados do usuário |
|
|
76
|
+
| POST | `/auth/logout` | Logout |
|
|
77
|
+
|
|
78
|
+
### Vaults
|
|
79
|
+
|
|
80
|
+
| Método | Rota | Descrição |
|
|
81
|
+
|--------|------|-----------|
|
|
82
|
+
| GET | `/api/vaults` | Listar vaults |
|
|
83
|
+
| POST | `/api/vaults` | Criar vault |
|
|
84
|
+
| GET | `/api/vaults/:id` | Abrir vault |
|
|
85
|
+
|
|
86
|
+
### Notas
|
|
87
|
+
|
|
88
|
+
| Método | Rota | Descrição |
|
|
89
|
+
|--------|------|-----------|
|
|
90
|
+
| GET | `/api/notes?vault=` | Listar notas |
|
|
91
|
+
| POST | `/api/notes` | Criar nota |
|
|
92
|
+
| GET | `/api/notes/:path?vault=` | Ler nota |
|
|
93
|
+
| PUT | `/api/notes/:path?vault=` | Atualizar |
|
|
94
|
+
| DELETE | `/api/notes/:path?vault=` | Deletar |
|
|
95
|
+
|
|
96
|
+
### Graph
|
|
97
|
+
|
|
98
|
+
| Método | Rota | Descrição |
|
|
99
|
+
|--------|------|-----------|
|
|
100
|
+
| GET | `/api/graph?vault=` | Grafo completo |
|
|
101
|
+
| GET | `/api/graph/neighbors/:path?vault=` | Vizinhança |
|
|
102
|
+
|
|
103
|
+
### Temas
|
|
104
|
+
|
|
105
|
+
| Método | Rota | Descrição |
|
|
106
|
+
|--------|------|-----------|
|
|
107
|
+
| GET | `/api/themes` | Listar temas |
|
|
108
|
+
| POST | `/api/themes` | Salvar tema |
|
|
109
|
+
| DELETE | `/api/themes/:name` | Deletar tema |
|
|
110
|
+
|
|
111
|
+
## Plugin API
|
|
112
|
+
|
|
113
|
+
O sistema de plugins permite estender o OpenSidian com funcionalidades customizadas.
|
|
114
|
+
|
|
115
|
+
### Interface
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
interface Plugin {
|
|
119
|
+
name: string; // Identificador único
|
|
120
|
+
version: string; // Semver
|
|
121
|
+
onLoad(ctx: PluginContext): void;
|
|
122
|
+
onUnload?(): void;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
interface PluginContext {
|
|
126
|
+
registerCommand(cmd: PluginCommand): void;
|
|
127
|
+
registerHook(hook: string, handler: Function): void;
|
|
128
|
+
getVaultManager(): VaultManager;
|
|
129
|
+
getGraphEngine(): GraphEngine;
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Hooks disponíveis
|
|
134
|
+
|
|
135
|
+
| Hook | Disparo | Uso |
|
|
136
|
+
|------|---------|-----|
|
|
137
|
+
| `note:pre-save` | Antes de salvar | Modificar conteúdo |
|
|
138
|
+
| `note:post-save` | Após salvar | Side effects |
|
|
139
|
+
|
|
140
|
+
### Exemplo
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
import { Plugin, PluginContext } from '../../shared/types';
|
|
144
|
+
|
|
145
|
+
export default {
|
|
146
|
+
name: 'meu-plugin',
|
|
147
|
+
version: '1.0.0',
|
|
148
|
+
onLoad(ctx: PluginContext) {
|
|
149
|
+
ctx.registerCommand({
|
|
150
|
+
id: 'meu-plugin:hello',
|
|
151
|
+
label: 'Dizer olá',
|
|
152
|
+
execute: () => console.log('Olá!'),
|
|
153
|
+
});
|
|
154
|
+
ctx.registerHook('note:post-save', (note) => {
|
|
155
|
+
console.log(`Nota salva: ${note.path}`);
|
|
156
|
+
});
|
|
157
|
+
},
|
|
158
|
+
} satisfies Plugin;
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Para carregar, coloque o arquivo em `./plugins/` e reinicie o servidor.
|
|
162
|
+
|
|
163
|
+
## MCP Server (Model Context Protocol)
|
|
164
|
+
|
|
165
|
+
O servidor MCP permite que IAs (Claude, etc.) interajam com o OpenSidian via stdio.
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
npx tsx src/mcp/server.ts
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Ou via pacote npm (após publicar):
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
npx opensidian-mcp
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Configuração no Claude Desktop
|
|
178
|
+
|
|
179
|
+
Adicione no `claude_desktop_config.json`:
|
|
180
|
+
|
|
181
|
+
```json
|
|
182
|
+
{
|
|
183
|
+
"mcpServers": {
|
|
184
|
+
"opensidian": {
|
|
185
|
+
"command": "npx",
|
|
186
|
+
"args": ["opensidian-mcp"]
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Ferramentas expostas
|
|
193
|
+
|
|
194
|
+
- `vault_list`, `vault_open`, `vault_create`
|
|
195
|
+
- `note_create`, `note_read`, `note_update`, `note_delete`, `note_search`
|
|
196
|
+
- `graph_get`, `graph_neighbors`
|
|
197
|
+
|
|
198
|
+
## Docker
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
docker-compose -f docker/docker-compose.yml up -d
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Ou build manual:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
docker build -f docker/Dockerfile -t opensidian .
|
|
208
|
+
docker run -p 3000:3000 -p 3001:3001 -v ./vaults:/app/vaults opensidian
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Testes
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
npm test # 67 testes
|
|
215
|
+
npm run test:coverage # Cobertura >80%
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Milestones
|
|
219
|
+
|
|
220
|
+
### v1.0 (7 fases)
|
|
221
|
+
|
|
222
|
+
| Fase | Status |
|
|
223
|
+
|------|--------|
|
|
224
|
+
| 1. Backend Core | ✅ |
|
|
225
|
+
| 2. Sync & API | ✅ |
|
|
226
|
+
| 3. Plugin System | ✅ |
|
|
227
|
+
| 4. Web UI | ✅ |
|
|
228
|
+
| 5. Authentication | ✅ |
|
|
229
|
+
| 6. Themes | ✅ |
|
|
230
|
+
| 7. Polish & Release | ✅ |
|
|
231
|
+
|
|
232
|
+
### v2.0 — Busca Full-Text (3 fases)
|
|
233
|
+
|
|
234
|
+
| Fase | Status |
|
|
235
|
+
|------|--------|
|
|
236
|
+
| 8. Indexador Full-Text (TF-IDF, stopwords, persistência) | ✅ |
|
|
237
|
+
| 9. API de Busca (REST + MCP + filtros + highlighting) | ✅ |
|
|
238
|
+
| 10. Frontend de Busca (painel avançado com filtros visuais) | ✅ |
|
|
239
|
+
|
|
240
|
+
**79 testes** | **Cobertura >80%** | **Build TypeScript** | **Docker** | **CI/CD**
|
|
241
|
+
|
|
242
|
+
## Licença
|
|
243
|
+
|
|
244
|
+
MIT. Veja [LICENSE](LICENSE).
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from 'express';
|
|
2
|
+
export declare function authMiddleware(req: Request, res: Response, next: NextFunction): void;
|
|
3
|
+
declare const router: import("express-serve-static-core").Router;
|
|
4
|
+
export default router;
|
|
5
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/api/auth.ts"],"names":[],"mappings":"AACA,OAAgB,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAmDnE,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAgBpF;AAED,QAAA,MAAM,MAAM,4CAAmB,CAAC;AA2DhC,eAAe,MAAM,CAAC"}
|
package/dist/api/auth.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
const users = [];
|
|
4
|
+
const JWT_SECRET = process.env.JWT_SECRET || crypto.randomBytes(32).toString('hex');
|
|
5
|
+
function hashPassword(password, salt) {
|
|
6
|
+
return crypto.pbkdf2Sync(password, salt, 10000, 64, 'sha256').toString('hex');
|
|
7
|
+
}
|
|
8
|
+
function generateSalt() {
|
|
9
|
+
return crypto.randomBytes(16).toString('hex');
|
|
10
|
+
}
|
|
11
|
+
function base64UrlEncode(str) {
|
|
12
|
+
return Buffer.from(str).toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
|
|
13
|
+
}
|
|
14
|
+
function base64UrlDecode(str) {
|
|
15
|
+
str = str.replace(/-/g, '+').replace(/_/g, '/');
|
|
16
|
+
while (str.length % 4)
|
|
17
|
+
str += '=';
|
|
18
|
+
return Buffer.from(str, 'base64').toString();
|
|
19
|
+
}
|
|
20
|
+
function createToken(payload) {
|
|
21
|
+
const header = base64UrlEncode(JSON.stringify({ alg: 'HS256', typ: 'JWT' }));
|
|
22
|
+
const body = base64UrlEncode(JSON.stringify({ ...payload, iat: Date.now() }));
|
|
23
|
+
const signature = crypto.createHmac('sha256', JWT_SECRET).update(`${header}.${body}`).digest('base64url');
|
|
24
|
+
return `${header}.${body}.${signature}`;
|
|
25
|
+
}
|
|
26
|
+
function verifyToken(token) {
|
|
27
|
+
const parts = token.split('.');
|
|
28
|
+
if (parts.length !== 3)
|
|
29
|
+
return null;
|
|
30
|
+
const signature = crypto.createHmac('sha256', JWT_SECRET).update(`${parts[0]}.${parts[1]}`).digest('base64url');
|
|
31
|
+
if (signature !== parts[2])
|
|
32
|
+
return null;
|
|
33
|
+
try {
|
|
34
|
+
return JSON.parse(base64UrlDecode(parts[1]));
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function authMiddleware(req, res, next) {
|
|
41
|
+
const header = req.headers.authorization;
|
|
42
|
+
if (!header?.startsWith('Bearer ')) {
|
|
43
|
+
res.status(401).json({ error: 'Token não fornecido' });
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const payload = verifyToken(header.slice(7));
|
|
47
|
+
if (!payload || !payload.userId) {
|
|
48
|
+
res.status(401).json({ error: 'Token inválido ou expirado' });
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
req.user = {
|
|
52
|
+
userId: payload.userId,
|
|
53
|
+
email: payload.email,
|
|
54
|
+
};
|
|
55
|
+
next();
|
|
56
|
+
}
|
|
57
|
+
const router = express.Router();
|
|
58
|
+
router.post('/register', (req, res) => {
|
|
59
|
+
const { email, password, name } = req.body;
|
|
60
|
+
if (!email || !password || !name) {
|
|
61
|
+
res.status(400).json({ error: 'email, password e name são obrigatórios' });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (password.length < 6) {
|
|
65
|
+
res.status(400).json({ error: 'Senha deve ter no mínimo 6 caracteres' });
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (users.find(u => u.email === email)) {
|
|
69
|
+
res.status(409).json({ error: 'Email já cadastrado' });
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const salt = generateSalt();
|
|
73
|
+
const user = {
|
|
74
|
+
id: crypto.randomUUID(),
|
|
75
|
+
email,
|
|
76
|
+
name,
|
|
77
|
+
passwordHash: hashPassword(password, salt),
|
|
78
|
+
salt,
|
|
79
|
+
createdAt: new Date().toISOString(),
|
|
80
|
+
};
|
|
81
|
+
users.push(user);
|
|
82
|
+
const token = createToken({ userId: user.id, email: user.email });
|
|
83
|
+
res.status(201).json({ token, user: { id: user.id, email: user.email, name: user.name } });
|
|
84
|
+
});
|
|
85
|
+
router.post('/login', (req, res) => {
|
|
86
|
+
const { email, password } = req.body;
|
|
87
|
+
if (!email || !password) {
|
|
88
|
+
res.status(400).json({ error: 'email e password são obrigatórios' });
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const user = users.find(u => u.email === email);
|
|
92
|
+
if (!user || user.passwordHash !== hashPassword(password, user.salt)) {
|
|
93
|
+
res.status(401).json({ error: 'Email ou senha inválidos' });
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const token = createToken({ userId: user.id, email: user.email });
|
|
97
|
+
res.json({ token, user: { id: user.id, email: user.email, name: user.name } });
|
|
98
|
+
});
|
|
99
|
+
router.get('/me', authMiddleware, (req, res) => {
|
|
100
|
+
const { userId } = req.user;
|
|
101
|
+
const user = users.find(u => u.id === userId);
|
|
102
|
+
if (!user) {
|
|
103
|
+
res.status(404).json({ error: 'Usuário não encontrado' });
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
res.json({ user: { id: user.id, email: user.email, name: user.name, createdAt: user.createdAt } });
|
|
107
|
+
});
|
|
108
|
+
router.post('/logout', (_req, res) => {
|
|
109
|
+
res.json({ message: 'Sessão encerrada' });
|
|
110
|
+
});
|
|
111
|
+
export default router;
|
|
112
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/api/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/api/routes.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,MAAM,4CAAmB,CAAC;AAgIhC,eAAe,MAAM,CAAC"}
|