@novis10813/secondbrain-cli 0.1.0 → 0.1.1
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 +74 -5
- package/dist/commands/backlinks.d.ts.map +1 -1
- package/dist/commands/backlinks.js +16 -33
- package/dist/commands/backlinks.js.map +1 -1
- package/dist/commands/capture.d.ts.map +1 -1
- package/dist/commands/capture.js +71 -57
- package/dist/commands/capture.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +5 -20
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/get.js +27 -26
- package/dist/commands/get.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +21 -4
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/migrate.d.ts +3 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +22 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/open.d.ts +3 -0
- package/dist/commands/open.d.ts.map +1 -0
- package/dist/commands/open.js +28 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/orphans.d.ts.map +1 -1
- package/dist/commands/orphans.js +9 -27
- package/dist/commands/orphans.js.map +1 -1
- package/dist/commands/outlinks.d.ts +3 -0
- package/dist/commands/outlinks.d.ts.map +1 -0
- package/dist/commands/outlinks.js +48 -0
- package/dist/commands/outlinks.js.map +1 -0
- package/dist/commands/search.d.ts +2 -0
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +57 -39
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/stats.d.ts.map +1 -1
- package/dist/commands/stats.js +4 -18
- package/dist/commands/stats.js.map +1 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +3 -17
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/template.d.ts +3 -0
- package/dist/commands/template.d.ts.map +1 -0
- package/dist/commands/template.js +63 -0
- package/dist/commands/template.js.map +1 -0
- package/dist/commands/vault.d.ts +3 -0
- package/dist/commands/vault.d.ts.map +1 -0
- package/dist/commands/vault.js +233 -0
- package/dist/commands/vault.js.map +1 -0
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +134 -10
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/config.d.ts +3 -1
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +12 -0
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/database.d.ts +58 -14
- package/dist/utils/database.d.ts.map +1 -1
- package/dist/utils/database.js +627 -207
- package/dist/utils/database.js.map +1 -1
- package/dist/utils/global-config.d.ts +53 -0
- package/dist/utils/global-config.d.ts.map +1 -0
- package/dist/utils/global-config.js +144 -0
- package/dist/utils/global-config.js.map +1 -0
- package/dist/utils/parser.d.ts +95 -2
- package/dist/utils/parser.d.ts.map +1 -1
- package/dist/utils/parser.js +436 -38
- package/dist/utils/parser.js.map +1 -1
- package/dist/utils/placeholder.d.ts +37 -0
- package/dist/utils/placeholder.d.ts.map +1 -0
- package/dist/utils/placeholder.js +113 -0
- package/dist/utils/placeholder.js.map +1 -0
- package/dist/utils/position.d.ts +10 -0
- package/dist/utils/position.d.ts.map +1 -0
- package/dist/utils/position.js +24 -0
- package/dist/utils/position.js.map +1 -0
- package/dist/utils/sqlite-adapter.d.ts +8 -0
- package/dist/utils/sqlite-adapter.d.ts.map +1 -0
- package/dist/utils/sqlite-adapter.js +14 -0
- package/dist/utils/sqlite-adapter.js.map +1 -0
- package/dist/utils/template.d.ts +2 -2
- package/dist/utils/template.d.ts.map +1 -1
- package/dist/utils/template.js +8 -3
- package/dist/utils/template.js.map +1 -1
- package/dist/utils/vault-resolve.d.ts +23 -0
- package/dist/utils/vault-resolve.d.ts.map +1 -0
- package/dist/utils/vault-resolve.js +86 -0
- package/dist/utils/vault-resolve.js.map +1 -0
- package/dist/utils/vault.d.ts +77 -10
- package/dist/utils/vault.d.ts.map +1 -1
- package/dist/utils/vault.js +253 -98
- package/dist/utils/vault.js.map +1 -1
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
npm install -g @novis10813/secondbrain-cli
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
支援 **Node.js 18+** 與 **Bun**。使用 `npm install` 安裝後,可用 `node dist/index.js` 或 `npx sb` 執行;專案開發與測試建議使用 Bun(`bun test`)。
|
|
21
21
|
|
|
22
22
|
如果你用 `bun` 從 GitHub 安裝並看到 `Blocked ... postinstall/prepare`,需要先信任再重裝一次:
|
|
23
23
|
|
|
@@ -43,7 +43,13 @@ sb capture "這是筆記內容" --title="我的筆記" --tags="idea,work"
|
|
|
43
43
|
sb search "API 設計" --tags="tech" --format=json
|
|
44
44
|
|
|
45
45
|
# 取得 backlinks
|
|
46
|
-
sb backlinks <
|
|
46
|
+
sb backlinks <path-or-id>
|
|
47
|
+
|
|
48
|
+
# 取得 outlinks(此筆記連結出去的筆記)
|
|
49
|
+
sb outlinks <path-or-id>
|
|
50
|
+
|
|
51
|
+
# 解析連結為 path:line:col(支援 note、note#heading、note#^block-id)
|
|
52
|
+
sb open "My Note#Section"
|
|
47
53
|
|
|
48
54
|
# 找孤兒筆記
|
|
49
55
|
sb orphans
|
|
@@ -57,9 +63,62 @@ sb orphans
|
|
|
57
63
|
sb init # 初始化 vault
|
|
58
64
|
sb config list # 查看設定
|
|
59
65
|
sb config get dailyNotesFolder # 取得特定設定
|
|
60
|
-
sb config set dailyNotesFolder Daily #
|
|
66
|
+
sb config set dailyNotesFolder Daily # 修改設定(可編輯:dailyNotesFolder, templatesFolder)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Vault 管理
|
|
70
|
+
|
|
71
|
+
SecondBrain 支援管理多個 vault。你可以從任何目錄使用 `sb` 指令,透過設定 active vault。
|
|
72
|
+
|
|
73
|
+
#### 初始化 vault
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# 在預設位置初始化 (~/vault/)
|
|
77
|
+
sb vault init
|
|
78
|
+
|
|
79
|
+
# 在當前目錄初始化
|
|
80
|
+
sb vault init .
|
|
81
|
+
|
|
82
|
+
# 在指定路徑初始化
|
|
83
|
+
sb vault init /path/to/my-notes
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### 切換 vault
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# 列出所有已註冊的 vault
|
|
90
|
+
sb vault list
|
|
91
|
+
|
|
92
|
+
# 設定當前 session 的 active vault(使用 eval)
|
|
93
|
+
eval $(sb vault use my-notes)
|
|
94
|
+
|
|
95
|
+
# 查看當前 active vault
|
|
96
|
+
sb vault current
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### 設定預設 vault
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# 查看預設 vault
|
|
103
|
+
sb vault default
|
|
104
|
+
|
|
105
|
+
# 設定預設 vault
|
|
106
|
+
sb vault default set my-notes
|
|
61
107
|
```
|
|
62
108
|
|
|
109
|
+
#### 移除 vault 註冊
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# 從註冊表中移除 vault(不會刪除檔案)
|
|
113
|
+
sb vault delete my-notes
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
#### Vault 解析優先順序
|
|
117
|
+
|
|
118
|
+
1. `SECONDBRAIN_VAULT` 環境變數(名稱或路徑)
|
|
119
|
+
2. 當前目錄(向上查找 `.secondbrain/`)
|
|
120
|
+
3. 預設 vault
|
|
121
|
+
|
|
63
122
|
### 筆記管理
|
|
64
123
|
|
|
65
124
|
```bash
|
|
@@ -70,11 +129,17 @@ sb capture "內容" \ # 建立筆記
|
|
|
70
129
|
|
|
71
130
|
sb search "關鍵字" \ # 搜尋
|
|
72
131
|
--tags="work" \
|
|
132
|
+
--path="Daily" \ # 路徑前綴
|
|
133
|
+
--links-to="某筆記" \ # 只顯示連結到該筆記的檔案
|
|
134
|
+
--heading="標題文字" \ # 只顯示含該標題的檔案
|
|
135
|
+
--modified-after="2024-01-01" \ # 修改時間篩選
|
|
73
136
|
--limit=10 \
|
|
74
137
|
--format=json
|
|
75
138
|
|
|
76
|
-
sb get <
|
|
77
|
-
sb backlinks <
|
|
139
|
+
sb get <path-or-id> # 取得單一筆記(路徑或檔名)
|
|
140
|
+
sb backlinks <path-or-id> # 取得 backlinks
|
|
141
|
+
sb outlinks <path-or-id> # 取得 outlinks(此筆記連結出去的筆記)
|
|
142
|
+
sb open <linkpath> # 解析連結為 path:line:col(編輯器導航)
|
|
78
143
|
```
|
|
79
144
|
|
|
80
145
|
### Vault 維護
|
|
@@ -83,6 +148,7 @@ sb backlinks <note-id> # 取得 backlinks
|
|
|
83
148
|
sb sync # 同步索引
|
|
84
149
|
sb stats # 統計資訊
|
|
85
150
|
sb orphans # 孤兒筆記
|
|
151
|
+
sb migrate # 從舊 schema 遷移至新 schema(files + content_metadata)
|
|
86
152
|
```
|
|
87
153
|
|
|
88
154
|
## 資料架構
|
|
@@ -110,6 +176,9 @@ bun run dev
|
|
|
110
176
|
# 建置
|
|
111
177
|
bun run build
|
|
112
178
|
|
|
179
|
+
# 檢查型別
|
|
180
|
+
bun run lint
|
|
181
|
+
|
|
113
182
|
# 執行測試
|
|
114
183
|
bun test
|
|
115
184
|
```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backlinks.d.ts","sourceRoot":"","sources":["../../src/commands/backlinks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"backlinks.d.ts","sourceRoot":"","sources":["../../src/commands/backlinks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,sBAAsB,IAAI,OAAO,CA0ChD"}
|
|
@@ -2,63 +2,46 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createBacklinksCommand = createBacklinksCommand;
|
|
4
4
|
const commander_1 = require("commander");
|
|
5
|
-
const
|
|
6
|
-
const vault_js_1 = require("../utils/vault.js");
|
|
5
|
+
const vault_resolve_js_1 = require("../utils/vault-resolve.js");
|
|
7
6
|
function createBacklinksCommand() {
|
|
8
7
|
const command = new commander_1.Command('backlinks')
|
|
9
8
|
.description('Get backlinks for a note')
|
|
10
|
-
.argument('<id>', '
|
|
9
|
+
.argument('<path-or-id>', 'File path or basename')
|
|
11
10
|
.option('-f, --format <format>', 'Output format (json|text)', 'json')
|
|
12
|
-
.action((
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
.action(async (pathOrId, options) => {
|
|
12
|
+
await (0, vault_resolve_js_1.withVault)((vault) => {
|
|
13
|
+
const file = vault.resolvePathOrBasename(pathOrId);
|
|
14
|
+
const resolvedPath = file?.path ?? null;
|
|
15
|
+
if (!resolvedPath) {
|
|
16
|
+
throw new Error('Note not found');
|
|
18
17
|
}
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const vault = new vault_js_1.VaultManager(config);
|
|
22
|
-
// First check if note exists
|
|
23
|
-
const note = vault.getNoteById(id);
|
|
24
|
-
if (!note) {
|
|
25
|
-
console.error('❌ Note not found');
|
|
26
|
-
process.exit(1);
|
|
27
|
-
}
|
|
28
|
-
const backlinks = vault.getBacklinks(id);
|
|
18
|
+
const backlinks = vault.getBacklinksByPath(resolvedPath);
|
|
19
|
+
const title = file?.basename ?? resolvedPath.replace(/\.md$/, '');
|
|
29
20
|
if (options.format === 'json') {
|
|
30
21
|
console.log(JSON.stringify({
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
path: resolvedPath,
|
|
23
|
+
title,
|
|
33
24
|
backlinkCount: backlinks.length,
|
|
34
25
|
backlinks: backlinks.map(b => ({
|
|
35
|
-
id: b.id,
|
|
36
|
-
title: b.title,
|
|
37
26
|
path: b.path,
|
|
38
|
-
|
|
27
|
+
basename: b.basename
|
|
39
28
|
}))
|
|
40
29
|
}, null, 2));
|
|
41
30
|
}
|
|
42
31
|
else {
|
|
43
|
-
console.log(`Backlinks for "${
|
|
32
|
+
console.log(`Backlinks for "${title}":\n`);
|
|
44
33
|
if (backlinks.length === 0) {
|
|
45
34
|
console.log('No backlinks found');
|
|
46
35
|
}
|
|
47
36
|
else {
|
|
48
37
|
backlinks.forEach((b, i) => {
|
|
49
|
-
console.log(`${i + 1}. ${b.
|
|
38
|
+
console.log(`${i + 1}. ${b.basename}`);
|
|
50
39
|
console.log(` Path: ${b.path}`);
|
|
51
|
-
console.log(` ID: ${b.id}`);
|
|
52
40
|
console.log();
|
|
53
41
|
});
|
|
54
42
|
}
|
|
55
43
|
}
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
console.error('❌ Failed to get backlinks:', error instanceof Error ? error.message : String(error));
|
|
60
|
-
process.exit(1);
|
|
61
|
-
}
|
|
44
|
+
});
|
|
62
45
|
});
|
|
63
46
|
return command;
|
|
64
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backlinks.js","sourceRoot":"","sources":["../../src/commands/backlinks.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"backlinks.js","sourceRoot":"","sources":["../../src/commands/backlinks.ts"],"names":[],"mappings":";;AAGA,wDA0CC;AA7CD,yCAAoC;AACpC,gEAAsD;AAEtD,SAAgB,sBAAsB;IACpC,MAAM,OAAO,GAAG,IAAI,mBAAO,CAAC,WAAW,CAAC;SACrC,WAAW,CAAC,0BAA0B,CAAC;SACvC,QAAQ,CAAC,cAAc,EAAE,uBAAuB,CAAC;SACjD,MAAM,CAAC,uBAAuB,EAAE,2BAA2B,EAAE,MAAM,CAAC;SACpE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;QAClC,MAAM,IAAA,4BAAS,EAAC,CAAC,KAAK,EAAE,EAAE;YACxB,MAAM,IAAI,GAAG,KAAK,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;YACnD,MAAM,YAAY,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;YACxC,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;YACpC,CAAC;YAED,MAAM,SAAS,GAAG,KAAK,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;YACvD,MAAM,KAAK,GAAG,IAAI,EAAE,QAAQ,IAAI,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAElE,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;oBACzB,IAAI,EAAE,YAAY;oBAClB,KAAK;oBACL,aAAa,EAAE,SAAS,CAAC,MAAM;oBAC/B,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;wBAC7B,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;qBACrB,CAAC,CAAC;iBACJ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACf,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,MAAM,CAAC,CAAC;gBAC3C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC3B,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;gBACpC,CAAC;qBAAM,CAAC;oBACN,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;wBACzB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;wBACvC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;wBAClC,OAAO,CAAC,GAAG,EAAE,CAAC;oBAChB,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/commands/capture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/commands/capture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,oBAAoB,IAAI,OAAO,CA6G9C"}
|
package/dist/commands/capture.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createCaptureCommand = createCaptureCommand;
|
|
4
4
|
const commander_1 = require("commander");
|
|
5
|
-
const
|
|
6
|
-
const vault_js_1 = require("../utils/vault.js");
|
|
5
|
+
const vault_resolve_js_1 = require("../utils/vault-resolve.js");
|
|
7
6
|
const parser_js_1 = require("../utils/parser.js");
|
|
7
|
+
const template_js_1 = require("../utils/template.js");
|
|
8
8
|
function createCaptureCommand() {
|
|
9
9
|
const command = new commander_1.Command('capture')
|
|
10
10
|
.description('Capture a new note')
|
|
@@ -12,78 +12,92 @@ function createCaptureCommand() {
|
|
|
12
12
|
.option('-t, --title <title>', 'Note title')
|
|
13
13
|
.option('--tags <tags>', 'Comma-separated tags')
|
|
14
14
|
.option('--template <template>', 'Template name')
|
|
15
|
-
.option('--
|
|
15
|
+
.option('--var <entries...>', 'Template variables (key=value)')
|
|
16
16
|
.action(async (content, options) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (!vaultPath) {
|
|
21
|
-
console.error('❌ Not in a SecondBrain vault. Run `sb init` first.');
|
|
22
|
-
process.exit(1);
|
|
23
|
-
}
|
|
24
|
-
const configManager = new config_js_1.ConfigManager(vaultPath);
|
|
25
|
-
const config = configManager.getConfig();
|
|
26
|
-
const vault = new vault_js_1.VaultManager(config);
|
|
27
|
-
let notePath;
|
|
17
|
+
const body = content ?? '';
|
|
18
|
+
await (0, vault_resolve_js_1.withVault)(async (vault) => {
|
|
19
|
+
let noteFolder = '';
|
|
28
20
|
let noteContent;
|
|
29
21
|
let frontmatter = {};
|
|
30
|
-
// Handle tags
|
|
31
22
|
const tags = options.tags ? options.tags.split(',').map((t) => t.trim()) : [];
|
|
32
|
-
//
|
|
23
|
+
// Parse --var key=value entries
|
|
24
|
+
const vars = {};
|
|
25
|
+
if (options.var) {
|
|
26
|
+
options.var.forEach((entry) => {
|
|
27
|
+
const [key, ...valueParts] = entry.split('=');
|
|
28
|
+
if (key) {
|
|
29
|
+
vars[key] = valueParts.join('=');
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
// 1. Resolve Template
|
|
33
34
|
if (options.template) {
|
|
34
|
-
const
|
|
35
|
-
|
|
35
|
+
const templateConfig = vault.config.templates?.[options.template];
|
|
36
|
+
if (templateConfig?.targetFolder) {
|
|
37
|
+
noteFolder = templateConfig.targetFolder;
|
|
38
|
+
}
|
|
39
|
+
const templateManager = new template_js_1.TemplateManager(vault.config);
|
|
40
|
+
const templateContent = templateManager.getTemplate(options.template);
|
|
36
41
|
if (templateContent) {
|
|
42
|
+
// Extract metadata from template for merging
|
|
37
43
|
const parsed = parser_js_1.NoteParser.parse(templateContent);
|
|
38
44
|
frontmatter = parsed.frontmatter;
|
|
39
|
-
// Merge tags
|
|
40
45
|
if (parsed.tags.length > 0) {
|
|
41
|
-
tags.push(...parsed.tags);
|
|
46
|
+
tags.push(...parsed.tags.map(t => t.name));
|
|
47
|
+
}
|
|
48
|
+
// Placeholder logic
|
|
49
|
+
const placeholders = templateManager.validateTemplate(options.template);
|
|
50
|
+
const variables = { content: body, ...vars };
|
|
51
|
+
// Check for missing variables and warn
|
|
52
|
+
placeholders.forEach(p => {
|
|
53
|
+
if (!(p in variables)) {
|
|
54
|
+
console.warn(`⚠️ Warning: Template placeholder '{{${p}}}' has no value provided, using empty string.`);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
// Check if content is provided but no {{content}} placeholder exists
|
|
58
|
+
if (body && !placeholders.includes('content')) {
|
|
59
|
+
console.warn(`⚠️ Warning: Note content was provided but no '{{content}}' placeholder exists in template '${options.template}'. Content will be ignored.`);
|
|
42
60
|
}
|
|
61
|
+
noteContent = templateManager.renderTemplate(options.template, variables);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// Fallback if template file not found
|
|
65
|
+
const title = options.title || new Date().toISOString();
|
|
66
|
+
frontmatter.tags = [...new Set(tags)];
|
|
67
|
+
noteContent = parser_js_1.NoteParser.generateNoteContent(title, body, frontmatter);
|
|
43
68
|
}
|
|
44
|
-
}
|
|
45
|
-
// Determine title
|
|
46
|
-
const title = options.title || new Date().toISOString();
|
|
47
|
-
// Determine path
|
|
48
|
-
if (options.path) {
|
|
49
|
-
notePath = options.path.endsWith('.md') ? options.path : `${options.path}.md`;
|
|
50
69
|
}
|
|
51
70
|
else {
|
|
52
|
-
//
|
|
53
|
-
const
|
|
54
|
-
|
|
71
|
+
// No template: use default generator
|
|
72
|
+
const title = options.title || new Date().toISOString();
|
|
73
|
+
frontmatter.tags = [...new Set(tags)];
|
|
74
|
+
noteContent = parser_js_1.NoteParser.generateNoteContent(title, body, frontmatter);
|
|
55
75
|
}
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// Write note
|
|
60
|
-
vault.writeNote(notePath, noteContent);
|
|
61
|
-
// Sync single note to database (optimized - no full vault scan)
|
|
62
|
-
const noteFileContent = vault.readNote(notePath);
|
|
63
|
-
if (noteFileContent) {
|
|
64
|
-
const hash = parser_js_1.NoteParser.computeHash(noteFileContent);
|
|
65
|
-
const note = await vault.createNoteFromFile(notePath, noteFileContent, hash);
|
|
66
|
-
vault.upsertNote(note);
|
|
76
|
+
// 2. Resolve Default Capture Folder if no template folder
|
|
77
|
+
if (!noteFolder && vault.config.captureFolder) {
|
|
78
|
+
noteFolder = vault.config.captureFolder;
|
|
67
79
|
}
|
|
68
|
-
const
|
|
80
|
+
const title = options.title || new Date().toISOString();
|
|
81
|
+
// Obsidian-friendly filename
|
|
82
|
+
const filename = `${title.replace(/[\/\x3a\x2a\x3f\x22\x3c\x3e\x7c]/g, '-')}.md`;
|
|
83
|
+
const notePath = noteFolder ? (noteFolder.endsWith('/') ? `${noteFolder}${filename}` : `${noteFolder}/${filename}`) : filename;
|
|
84
|
+
// If not using template, frontmatter.tags was already set.
|
|
85
|
+
// If using template, renderTemplate already produced full content.
|
|
86
|
+
// BUT we might want to update frontmatter tags for non-template case.
|
|
87
|
+
// The current logic above handles this.
|
|
88
|
+
vault.writeNote(notePath, noteContent);
|
|
89
|
+
vault.indexSingleFile(notePath);
|
|
90
|
+
const file = vault.getFileByPath(notePath);
|
|
69
91
|
console.log('✅ Note captured!');
|
|
70
92
|
console.log('Path:', notePath);
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}, null, 2));
|
|
80
|
-
}
|
|
81
|
-
vault.close();
|
|
82
|
-
}
|
|
83
|
-
catch (error) {
|
|
84
|
-
console.error('❌ Failed to capture note:', error instanceof Error ? error.message : String(error));
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
93
|
+
console.log(JSON.stringify({
|
|
94
|
+
success: true,
|
|
95
|
+
path: notePath,
|
|
96
|
+
basename: file?.basename ?? notePath.replace(/\.md$/, '').split('/').pop(),
|
|
97
|
+
title,
|
|
98
|
+
tags: [...new Set(tags)]
|
|
99
|
+
}, null, 2));
|
|
100
|
+
});
|
|
87
101
|
});
|
|
88
102
|
return command;
|
|
89
103
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/commands/capture.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/commands/capture.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,mBAAmB,IAAI,OAAO,CAgE7C"}
|
package/dist/commands/config.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createConfigCommand = createConfigCommand;
|
|
4
4
|
const commander_1 = require("commander");
|
|
5
|
+
const vault_resolve_js_1 = require("../utils/vault-resolve.js");
|
|
5
6
|
const config_js_1 = require("../utils/config.js");
|
|
6
7
|
function createConfigCommand() {
|
|
7
8
|
const command = new commander_1.Command('config')
|
|
@@ -11,13 +12,7 @@ function createConfigCommand() {
|
|
|
11
12
|
.argument('<key>', 'Configuration key')
|
|
12
13
|
.action((key) => {
|
|
13
14
|
try {
|
|
14
|
-
const
|
|
15
|
-
if (!vaultPath) {
|
|
16
|
-
console.error('❌ Not in a SecondBrain vault. Run `sb init` first.');
|
|
17
|
-
process.exit(1);
|
|
18
|
-
}
|
|
19
|
-
const configManager = new config_js_1.ConfigManager(vaultPath);
|
|
20
|
-
const config = configManager.getConfig();
|
|
15
|
+
const config = (0, vault_resolve_js_1.getConfigOrExit)();
|
|
21
16
|
if (key in config) {
|
|
22
17
|
console.log(config[key]);
|
|
23
18
|
}
|
|
@@ -38,12 +33,8 @@ function createConfigCommand() {
|
|
|
38
33
|
.argument('<value>', 'Configuration value')
|
|
39
34
|
.action((key, value) => {
|
|
40
35
|
try {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
console.error('❌ Not in a SecondBrain vault. Run `sb init` first.');
|
|
44
|
-
process.exit(1);
|
|
45
|
-
}
|
|
46
|
-
const configManager = new config_js_1.ConfigManager(vaultPath);
|
|
36
|
+
const config = (0, vault_resolve_js_1.getConfigOrExit)();
|
|
37
|
+
const configManager = new config_js_1.ConfigManager(config.vaultPath);
|
|
47
38
|
const validKeys = ['dailyNotesFolder', 'templatesFolder'];
|
|
48
39
|
if (!validKeys.includes(key)) {
|
|
49
40
|
console.error(`❌ Cannot set config key: ${key}`);
|
|
@@ -62,13 +53,7 @@ function createConfigCommand() {
|
|
|
62
53
|
.description('List all configuration')
|
|
63
54
|
.action(() => {
|
|
64
55
|
try {
|
|
65
|
-
const
|
|
66
|
-
if (!vaultPath) {
|
|
67
|
-
console.error('❌ Not in a SecondBrain vault. Run `sb init` first.');
|
|
68
|
-
process.exit(1);
|
|
69
|
-
}
|
|
70
|
-
const configManager = new config_js_1.ConfigManager(vaultPath);
|
|
71
|
-
const config = configManager.getConfig();
|
|
56
|
+
const config = (0, vault_resolve_js_1.getConfigOrExit)();
|
|
72
57
|
console.log('Configuration:\n');
|
|
73
58
|
Object.entries(config).forEach(([key, value]) => {
|
|
74
59
|
console.log(`${key}: ${value}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/get.js
CHANGED
|
@@ -2,42 +2,43 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createGetCommand = createGetCommand;
|
|
4
4
|
const commander_1 = require("commander");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
5
|
+
const vault_resolve_js_1 = require("../utils/vault-resolve.js");
|
|
6
|
+
const parser_js_1 = require("../utils/parser.js");
|
|
7
7
|
function createGetCommand() {
|
|
8
8
|
const command = new commander_1.Command('get')
|
|
9
|
-
.description('Get a note by ID')
|
|
10
|
-
.argument('<id>', '
|
|
9
|
+
.description('Get a note by path or ID')
|
|
10
|
+
.argument('<path-or-id>', 'File path (e.g. note.md or folder/note.md) or basename')
|
|
11
11
|
.option('-f, --format <format>', 'Output format (json|text)', 'json')
|
|
12
|
-
.action((
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
.action(async (pathOrId, options) => {
|
|
13
|
+
await (0, vault_resolve_js_1.withVault)((vault) => {
|
|
14
|
+
const file = vault.resolvePathOrBasename(pathOrId);
|
|
15
|
+
const resolvedPath = file?.path ?? null;
|
|
16
|
+
if (!resolvedPath) {
|
|
17
|
+
throw new Error('Note not found');
|
|
18
18
|
}
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const note = vault.getNoteById(id);
|
|
23
|
-
if (!note) {
|
|
24
|
-
console.error('❌ Note not found');
|
|
25
|
-
process.exit(1);
|
|
19
|
+
const content = vault.readNote(resolvedPath);
|
|
20
|
+
if (content === null) {
|
|
21
|
+
throw new Error('File not found on disk');
|
|
26
22
|
}
|
|
23
|
+
const parsed = parser_js_1.NoteParser.parse(content);
|
|
24
|
+
const cache = file ? vault.getFileCache(file) : null;
|
|
27
25
|
if (options.format === 'json') {
|
|
28
|
-
console.log(JSON.stringify(
|
|
26
|
+
console.log(JSON.stringify({
|
|
27
|
+
path: resolvedPath,
|
|
28
|
+
title: parsed.title,
|
|
29
|
+
content: parsed.content,
|
|
30
|
+
frontmatter: parsed.frontmatter,
|
|
31
|
+
tags: parsed.tags.map(t => t.name),
|
|
32
|
+
links: cache?.links?.map(l => l.link) ?? [],
|
|
33
|
+
headings: parsed.headings
|
|
34
|
+
}, null, 2));
|
|
29
35
|
}
|
|
30
36
|
else {
|
|
31
|
-
console.log(
|
|
37
|
+
console.log(parsed.title);
|
|
32
38
|
console.log('─'.repeat(40));
|
|
33
|
-
console.log(
|
|
39
|
+
console.log(parsed.content);
|
|
34
40
|
}
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
catch (error) {
|
|
38
|
-
console.error('❌ Failed to get note:', error instanceof Error ? error.message : String(error));
|
|
39
|
-
process.exit(1);
|
|
40
|
-
}
|
|
41
|
+
});
|
|
41
42
|
});
|
|
42
43
|
return command;
|
|
43
44
|
}
|
package/dist/commands/get.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../src/commands/get.ts"],"names":[],"mappings":";;AAIA,4CAwCC;AA5CD,yCAAoC;AACpC,
|
|
1
|
+
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../src/commands/get.ts"],"names":[],"mappings":";;AAIA,4CAwCC;AA5CD,yCAAoC;AACpC,gEAAsD;AACtD,kDAAgD;AAEhD,SAAgB,gBAAgB;IAC9B,MAAM,OAAO,GAAG,IAAI,mBAAO,CAAC,KAAK,CAAC;SAC/B,WAAW,CAAC,0BAA0B,CAAC;SACvC,QAAQ,CAAC,cAAc,EAAE,wDAAwD,CAAC;SAClF,MAAM,CAAC,uBAAuB,EAAE,2BAA2B,EAAE,MAAM,CAAC;SACpE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;QAClC,MAAM,IAAA,4BAAS,EAAC,CAAC,KAAK,EAAE,EAAE;YACxB,MAAM,IAAI,GAAG,KAAK,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;YACnD,MAAM,YAAY,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;YACxC,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;YACpC,CAAC;YAED,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC7C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;YAC5C,CAAC;YAEC,MAAM,MAAM,GAAG,sBAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAErD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;oBACzB,IAAI,EAAE,YAAY;oBAClB,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,WAAW,EAAE,MAAM,CAAC,WAAW;oBAC/B,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;oBAClC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE;oBAC3C,QAAQ,EAAE,MAAM,CAAC,QAAQ;iBAC1B,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACf,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC5B,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC9B,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,iBAAiB,IAAI,OAAO,CA6C3C"}
|
package/dist/commands/init.js
CHANGED
|
@@ -3,20 +3,34 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createInitCommand = createInitCommand;
|
|
4
4
|
const commander_1 = require("commander");
|
|
5
5
|
const config_js_1 = require("../utils/config.js");
|
|
6
|
+
const global_config_js_1 = require("../utils/global-config.js");
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
const os_1 = require("os");
|
|
9
|
+
const DEFAULT_VAULT_PATH = (0, path_1.join)((0, os_1.homedir)(), 'vault');
|
|
6
10
|
function createInitCommand() {
|
|
7
11
|
const command = new commander_1.Command('init')
|
|
8
|
-
.description('Initialize a new SecondBrain vault')
|
|
12
|
+
.description('Initialize a new SecondBrain vault (alias for `sb vault init`)')
|
|
9
13
|
.option('-p, --path <path>', 'Vault path', process.cwd())
|
|
10
|
-
.
|
|
14
|
+
.argument('[path]', 'Vault path')
|
|
15
|
+
.action((path, options) => {
|
|
11
16
|
try {
|
|
12
|
-
const
|
|
17
|
+
const vaultPath = (0, path_1.resolve)(path ?? options?.path ?? DEFAULT_VAULT_PATH);
|
|
18
|
+
const configManager = new config_js_1.ConfigManager(vaultPath);
|
|
19
|
+
const globalConfig = new global_config_js_1.GlobalConfigManager();
|
|
13
20
|
if (configManager.isInitialized()) {
|
|
14
|
-
console.log('⚠️ Vault already initialized at:',
|
|
21
|
+
console.log('⚠️ Vault already initialized at:', vaultPath);
|
|
22
|
+
// 確保已註冊到全域設定
|
|
23
|
+
const entry = globalConfig.addVault(vaultPath);
|
|
24
|
+
if (entry) {
|
|
25
|
+
console.log(`✅ Registered as "${entry.name}" in global config`);
|
|
26
|
+
}
|
|
15
27
|
return;
|
|
16
28
|
}
|
|
17
29
|
const config = configManager.init();
|
|
30
|
+
const entry = globalConfig.addVault(vaultPath);
|
|
18
31
|
console.log('✅ SecondBrain vault initialized!');
|
|
19
32
|
console.log('Vault path:', config.vaultPath);
|
|
33
|
+
console.log('Vault name:', entry?.name ?? 'unknown');
|
|
20
34
|
console.log('Daily notes:', config.dailyNotesFolder);
|
|
21
35
|
console.log('Templates:', config.templatesFolder);
|
|
22
36
|
console.log();
|
|
@@ -24,6 +38,9 @@ function createInitCommand() {
|
|
|
24
38
|
console.log(' 1. Create notes in your vault');
|
|
25
39
|
console.log(' 2. Run `sb sync` to index existing notes');
|
|
26
40
|
console.log(' 3. Use `sb capture` to create new notes');
|
|
41
|
+
console.log();
|
|
42
|
+
console.log('To use this vault:');
|
|
43
|
+
console.log(` eval $(sb vault use ${entry?.name ?? vaultPath})`);
|
|
27
44
|
}
|
|
28
45
|
catch (error) {
|
|
29
46
|
console.error('❌ Failed to initialize vault:', error instanceof Error ? error.message : String(error));
|