im-nobsidian 0.1.7 → 0.1.9
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/dist/index.js +137 -43
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command10 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/init.ts
|
|
7
7
|
import { Command } from "commander";
|
|
@@ -377,7 +377,7 @@ import {
|
|
|
377
377
|
NodeVaultFS as NodeVaultFS4
|
|
378
378
|
} from "@im-nobsidian/core";
|
|
379
379
|
import chalk6 from "chalk";
|
|
380
|
-
var statusCommand = new Command5("status").description("\uB3D9\uAE30\uD654 \uC0C1\uD0DC \uD655\uC778").action(async () => {
|
|
380
|
+
var statusCommand = new Command5("status").description("\uB3D9\uAE30\uD654 \uC0C1\uD0DC \uD655\uC778 (--full: \uC6D0\uACA9 \uBCC0\uACBD \uD3EC\uD568)").option("--full", "Notion \uC6D0\uACA9 \uBCC0\uACBD\uAE4C\uC9C0 \uC591\uBC29\uD5A5 \uD655\uC778 (API \uD638\uCD9C, \uB290\uB9BC)").action(async (opts) => {
|
|
381
381
|
const cwd = process.cwd();
|
|
382
382
|
const configManager = new ConfigManager5(cwd);
|
|
383
383
|
const config = await configManager.load();
|
|
@@ -389,7 +389,7 @@ var statusCommand = new Command5("status").description("\uB3D9\uAE30\uD654 \uC0C
|
|
|
389
389
|
});
|
|
390
390
|
const vaultFs = new NodeVaultFS4(cwd, config.paths);
|
|
391
391
|
const orchestrator = new SyncOrchestrator4(config, stateDb, client, vaultFs);
|
|
392
|
-
const status = await orchestrator.status();
|
|
392
|
+
const status = opts.full ? await orchestrator.status() : await orchestrator.statusLocal();
|
|
393
393
|
console.log(`
|
|
394
394
|
${header(" Sync Status")}`);
|
|
395
395
|
console.log(` ${separator(50)}`);
|
|
@@ -410,6 +410,9 @@ ${header(" Sync Status")}`);
|
|
|
410
410
|
const conflictCount = status.conflictRecords.length;
|
|
411
411
|
const createdChanges = status.localChanges.filter((c) => c.type === "created");
|
|
412
412
|
const modifiedChanges = status.localChanges.filter((c) => c.type === "modified");
|
|
413
|
+
const remoteCreated = status.remoteChanges.filter((c) => c.type === "created");
|
|
414
|
+
const remoteModified = status.remoteChanges.filter((c) => c.type === "modified");
|
|
415
|
+
const remoteDeleted = status.remoteChanges.filter((c) => c.type === "deleted");
|
|
413
416
|
console.log(`
|
|
414
417
|
${header(`Tracked files: ${total}`)}`);
|
|
415
418
|
console.log(` ${icons.synced} ${chalk6.green("synced")} ${synced}`);
|
|
@@ -444,6 +447,28 @@ ${header(" Sync Status")}`);
|
|
|
444
447
|
console.log(dimText(` ... and ${createdChanges.length - 10} more`));
|
|
445
448
|
}
|
|
446
449
|
}
|
|
450
|
+
if (status.remoteChanges.length > 0) {
|
|
451
|
+
console.log(`
|
|
452
|
+
${header(`Remote changes (Notion): ${status.remoteChanges.length}`)}`);
|
|
453
|
+
if (remoteCreated.length > 0) {
|
|
454
|
+
console.log(` ${chalk6.cyan("+")} ${chalk6.cyan("new")} ${remoteCreated.length}`);
|
|
455
|
+
}
|
|
456
|
+
if (remoteModified.length > 0) {
|
|
457
|
+
console.log(
|
|
458
|
+
` ${chalk6.yellow("~")} ${chalk6.yellow("modified")} ${remoteModified.length}`
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
if (remoteDeleted.length > 0) {
|
|
462
|
+
console.log(` ${chalk6.red("-")} ${chalk6.red("deleted")} ${remoteDeleted.length}`);
|
|
463
|
+
}
|
|
464
|
+
for (const c of status.remoteChanges.slice(0, 10)) {
|
|
465
|
+
const icon = c.type === "created" ? chalk6.cyan("+") : c.type === "modified" ? chalk6.yellow("~") : chalk6.red("-");
|
|
466
|
+
console.log(` ${icon} ${c.pageId.slice(0, 8)}... ${dimText(`(${c.type})`)}`);
|
|
467
|
+
}
|
|
468
|
+
if (status.remoteChanges.length > 10) {
|
|
469
|
+
console.log(dimText(` ... and ${status.remoteChanges.length - 10} more`));
|
|
470
|
+
}
|
|
471
|
+
}
|
|
447
472
|
if (conflictCount > 0) {
|
|
448
473
|
console.log(`
|
|
449
474
|
${header(chalk6.magenta("Conflicts:"))}`);
|
|
@@ -453,7 +478,8 @@ ${header(" Sync Status")}`);
|
|
|
453
478
|
);
|
|
454
479
|
}
|
|
455
480
|
}
|
|
456
|
-
|
|
481
|
+
const hasChanges = status.localChanges.length > 0 || status.remoteChanges.length > 0 || conflictCount > 0;
|
|
482
|
+
if (hasChanges) {
|
|
457
483
|
console.log("");
|
|
458
484
|
if (conflictCount > 0) {
|
|
459
485
|
console.log(
|
|
@@ -467,6 +493,12 @@ ${header(" Sync Status")}`);
|
|
|
467
493
|
console.log(`
|
|
468
494
|
${chalk6.green("Everything up to date")} \u2713`);
|
|
469
495
|
}
|
|
496
|
+
if (!opts.full) {
|
|
497
|
+
console.log(
|
|
498
|
+
`
|
|
499
|
+
${dimText("Run")} ${chalk6.cyan("nobsi status --full")} ${dimText("to check Notion remote changes")}`
|
|
500
|
+
);
|
|
501
|
+
}
|
|
470
502
|
} finally {
|
|
471
503
|
stateDb.close();
|
|
472
504
|
}
|
|
@@ -495,7 +527,7 @@ var diffCommand = new Command6("diff").description("\uB85C\uCEEC\uACFC Notion \u
|
|
|
495
527
|
});
|
|
496
528
|
const vaultFs = new NodeVaultFS5(cwd, config.paths);
|
|
497
529
|
const orchestrator = new SyncOrchestrator5(config, stateDb, client, vaultFs);
|
|
498
|
-
const status = await orchestrator.
|
|
530
|
+
const status = await orchestrator.statusLocal();
|
|
499
531
|
const changes = targetPath ? status.localChanges.filter((c) => c.path === targetPath || c.path.startsWith(targetPath)) : status.localChanges;
|
|
500
532
|
if (changes.length === 0) {
|
|
501
533
|
console.log("\uBCC0\uACBD\uC0AC\uD56D \uC5C6\uC74C");
|
|
@@ -505,13 +537,13 @@ var diffCommand = new Command6("diff").description("\uB85C\uCEEC\uACFC Notion \u
|
|
|
505
537
|
const record = stateDb.getByPath(change.path);
|
|
506
538
|
if (change.type === "created") {
|
|
507
539
|
const content = await vaultFs.readFile(change.path);
|
|
508
|
-
const patch = createTwoFilesPatch(
|
|
509
|
-
printPatch(patch, options.color);
|
|
540
|
+
const patch = createTwoFilesPatch("/dev/null", `b/${change.path}`, "", content);
|
|
541
|
+
printPatch(patch, options.color, "/dev/null", `b/${change.path}`);
|
|
510
542
|
} else if (change.type === "deleted") {
|
|
511
543
|
if (record?.baseSnapshot) {
|
|
512
544
|
const oldContent = record.baseSnapshot.toString("utf-8");
|
|
513
|
-
const patch = createTwoFilesPatch(`a/${change.path}`,
|
|
514
|
-
printPatch(patch, options.color);
|
|
545
|
+
const patch = createTwoFilesPatch(`a/${change.path}`, "/dev/null", oldContent, "");
|
|
546
|
+
printPatch(patch, options.color, `a/${change.path}`, "/dev/null");
|
|
515
547
|
} else {
|
|
516
548
|
console.log(`--- a/${change.path}`);
|
|
517
549
|
console.log(`+++ /dev/null`);
|
|
@@ -526,7 +558,7 @@ var diffCommand = new Command6("diff").description("\uB85C\uCEEC\uACFC Notion \u
|
|
|
526
558
|
baseContent,
|
|
527
559
|
currentContent
|
|
528
560
|
);
|
|
529
|
-
printPatch(patch, options.color);
|
|
561
|
+
printPatch(patch, options.color, `a/${change.path}`, `b/${change.path}`);
|
|
530
562
|
}
|
|
531
563
|
console.log("");
|
|
532
564
|
}
|
|
@@ -534,50 +566,111 @@ var diffCommand = new Command6("diff").description("\uB85C\uCEEC\uACFC Notion \u
|
|
|
534
566
|
stateDb.close();
|
|
535
567
|
}
|
|
536
568
|
});
|
|
537
|
-
function printPatch(patch, color) {
|
|
569
|
+
function printPatch(patch, color, oldPath, newPath) {
|
|
538
570
|
for (const line of patch.split("\n")) {
|
|
571
|
+
let output = line;
|
|
572
|
+
if (line.startsWith("===")) {
|
|
573
|
+
output = "===================================================================";
|
|
574
|
+
} else if (line.startsWith("--- ")) {
|
|
575
|
+
output = `--- ${oldPath}`;
|
|
576
|
+
} else if (line.startsWith("+++ ")) {
|
|
577
|
+
output = `+++ ${newPath}`;
|
|
578
|
+
}
|
|
539
579
|
if (!color) {
|
|
540
|
-
console.log(
|
|
580
|
+
console.log(output);
|
|
541
581
|
continue;
|
|
542
582
|
}
|
|
543
|
-
if (
|
|
544
|
-
console.log(`\x1B[1m${
|
|
545
|
-
} else if (
|
|
546
|
-
console.log(`\x1B[32m${
|
|
547
|
-
} else if (
|
|
548
|
-
console.log(`\x1B[31m${
|
|
549
|
-
} else if (
|
|
550
|
-
console.log(`\x1B[36m${
|
|
583
|
+
if (output.startsWith("+++") || output.startsWith("---")) {
|
|
584
|
+
console.log(`\x1B[1m${output}\x1B[0m`);
|
|
585
|
+
} else if (output.startsWith("+")) {
|
|
586
|
+
console.log(`\x1B[32m${output}\x1B[0m`);
|
|
587
|
+
} else if (output.startsWith("-")) {
|
|
588
|
+
console.log(`\x1B[31m${output}\x1B[0m`);
|
|
589
|
+
} else if (output.startsWith("@@")) {
|
|
590
|
+
console.log(`\x1B[36m${output}\x1B[0m`);
|
|
551
591
|
} else {
|
|
552
|
-
console.log(
|
|
592
|
+
console.log(output);
|
|
553
593
|
}
|
|
554
594
|
}
|
|
555
595
|
}
|
|
556
596
|
|
|
557
|
-
// src/commands/
|
|
597
|
+
// src/commands/fetch.ts
|
|
558
598
|
import { Command as Command7 } from "commander";
|
|
559
|
-
import { select, confirm as confirm2 } from "@inquirer/prompts";
|
|
560
599
|
import {
|
|
561
600
|
ConfigManager as ConfigManager7,
|
|
562
601
|
StateDB as StateDB6,
|
|
563
602
|
NotionClient as NotionClient7,
|
|
564
603
|
SyncOrchestrator as SyncOrchestrator6,
|
|
565
|
-
NodeVaultFS as NodeVaultFS6
|
|
566
|
-
ConflictResolver
|
|
604
|
+
NodeVaultFS as NodeVaultFS6
|
|
567
605
|
} from "@im-nobsidian/core";
|
|
568
|
-
|
|
606
|
+
import chalk7 from "chalk";
|
|
607
|
+
var fetchCommand = new Command7("fetch").description("Notion \uB9AC\uBAA8\uD2B8 \uC0C1\uD0DC \uC2A4\uCE94 (\uC0AD\uC81C \uAC10\uC9C0 \uD3EC\uD568)").action(async () => {
|
|
569
608
|
const cwd = process.cwd();
|
|
570
609
|
const configManager = new ConfigManager7(cwd);
|
|
610
|
+
const config = await configManager.load();
|
|
611
|
+
const stateDb = StateDB6.open(configManager.dbPath);
|
|
571
612
|
try {
|
|
572
|
-
const config = await configManager.load();
|
|
573
|
-
const stateDb = StateDB6.open(configManager.dbPath);
|
|
574
613
|
const client = new NotionClient7({
|
|
575
614
|
token: config.notion.token,
|
|
576
|
-
concurrency:
|
|
577
|
-
timeoutMs:
|
|
615
|
+
concurrency: config.advanced.concurrency,
|
|
616
|
+
timeoutMs: config.advanced.timeoutMs
|
|
578
617
|
});
|
|
579
618
|
const vaultFs = new NodeVaultFS6(cwd, config.paths);
|
|
580
619
|
const orchestrator = new SyncOrchestrator6(config, stateDb, client, vaultFs);
|
|
620
|
+
console.log(dimText(" Scanning remote pages..."));
|
|
621
|
+
const result = await orchestrator.fetch();
|
|
622
|
+
console.log(`
|
|
623
|
+
${header(" Remote Scan")}`);
|
|
624
|
+
console.log(` ${separator(40)}`);
|
|
625
|
+
if (result.newPages > 0) {
|
|
626
|
+
console.log(` ${chalk7.cyan("+")} New pages: ${result.newPages}`);
|
|
627
|
+
}
|
|
628
|
+
if (result.modifiedPages > 0) {
|
|
629
|
+
console.log(` ${chalk7.yellow("~")} Modified pages: ${result.modifiedPages}`);
|
|
630
|
+
}
|
|
631
|
+
if (result.deletedPages > 0) {
|
|
632
|
+
console.log(` ${chalk7.red("-")} Deleted pages: ${result.deletedPages}`);
|
|
633
|
+
}
|
|
634
|
+
const total = result.newPages + result.modifiedPages + result.deletedPages;
|
|
635
|
+
if (total === 0) {
|
|
636
|
+
console.log(` ${chalk7.green("Remote is up to date")} \u2713`);
|
|
637
|
+
} else {
|
|
638
|
+
console.log(
|
|
639
|
+
`
|
|
640
|
+
${dimText("Run")} ${chalk7.cyan("nobsi pull")} ${dimText("to apply remote changes")}`
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
console.log(dimText(`
|
|
644
|
+
Completed in ${(result.duration / 1e3).toFixed(1)}s`));
|
|
645
|
+
} finally {
|
|
646
|
+
stateDb.close();
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
// src/commands/resolve.ts
|
|
651
|
+
import { Command as Command8 } from "commander";
|
|
652
|
+
import { select, confirm as confirm2 } from "@inquirer/prompts";
|
|
653
|
+
import {
|
|
654
|
+
ConfigManager as ConfigManager8,
|
|
655
|
+
StateDB as StateDB7,
|
|
656
|
+
NotionClient as NotionClient8,
|
|
657
|
+
SyncOrchestrator as SyncOrchestrator7,
|
|
658
|
+
NodeVaultFS as NodeVaultFS7,
|
|
659
|
+
ConflictResolver
|
|
660
|
+
} from "@im-nobsidian/core";
|
|
661
|
+
var resolveCommand = new Command8("resolve").description("\uCDA9\uB3CC\uC744 \uD574\uACB0\uD569\uB2C8\uB2E4").option("-s, --strategy <strategy>", "\uC790\uB3D9 \uD574\uACB0 \uC804\uB7B5 (local-first, remote-first, duplicate)").action(async (options) => {
|
|
662
|
+
const cwd = process.cwd();
|
|
663
|
+
const configManager = new ConfigManager8(cwd);
|
|
664
|
+
try {
|
|
665
|
+
const config = await configManager.load();
|
|
666
|
+
const stateDb = StateDB7.open(configManager.dbPath);
|
|
667
|
+
const client = new NotionClient8({
|
|
668
|
+
token: config.notion.token,
|
|
669
|
+
concurrency: 3,
|
|
670
|
+
timeoutMs: 3e4
|
|
671
|
+
});
|
|
672
|
+
const vaultFs = new NodeVaultFS7(cwd, config.paths);
|
|
673
|
+
const orchestrator = new SyncOrchestrator7(config, stateDb, client, vaultFs);
|
|
581
674
|
const resolver = new ConflictResolver(stateDb, vaultFs);
|
|
582
675
|
await orchestrator.status();
|
|
583
676
|
const conflictRecords = stateDb.getByStatus("conflict");
|
|
@@ -656,13 +749,13 @@ ${"\u2500".repeat(60)}`);
|
|
|
656
749
|
}
|
|
657
750
|
|
|
658
751
|
// src/commands/watch.ts
|
|
659
|
-
import { Command as
|
|
752
|
+
import { Command as Command9 } from "commander";
|
|
660
753
|
import {
|
|
661
|
-
ConfigManager as
|
|
662
|
-
StateDB as
|
|
663
|
-
NotionClient as
|
|
664
|
-
SyncOrchestrator as
|
|
665
|
-
NodeVaultFS as
|
|
754
|
+
ConfigManager as ConfigManager9,
|
|
755
|
+
StateDB as StateDB8,
|
|
756
|
+
NotionClient as NotionClient9,
|
|
757
|
+
SyncOrchestrator as SyncOrchestrator8,
|
|
758
|
+
NodeVaultFS as NodeVaultFS8,
|
|
666
759
|
WatchSyncService
|
|
667
760
|
} from "@im-nobsidian/core";
|
|
668
761
|
function formatResult(result) {
|
|
@@ -677,18 +770,18 @@ function formatResult(result) {
|
|
|
677
770
|
function timestamp() {
|
|
678
771
|
return (/* @__PURE__ */ new Date()).toLocaleTimeString("ko-KR", { hour12: false });
|
|
679
772
|
}
|
|
680
|
-
var watchCommand = new
|
|
773
|
+
var watchCommand = new Command9("watch").description("\uD30C\uC77C \uBCC0\uACBD \uAC10\uC9C0 + \uC790\uB3D9 \uB3D9\uAE30\uD654").option("-d, --debounce <ms>", "\uB514\uBC14\uC6B4\uC2A4 \uB300\uAE30 \uC2DC\uAC04(ms)", "2000").option("-i, --interval <seconds>", "\uD480 \uB3D9\uAE30\uD654 \uC8FC\uAE30(\uCD08, 0\uC774\uBA74 \uBE44\uD65C\uC131)", "0").action(async (options) => {
|
|
681
774
|
const cwd = process.cwd();
|
|
682
|
-
const configManager = new
|
|
775
|
+
const configManager = new ConfigManager9(cwd);
|
|
683
776
|
const config = await configManager.load();
|
|
684
|
-
const stateDb =
|
|
685
|
-
const client = new
|
|
777
|
+
const stateDb = StateDB8.open(configManager.dbPath);
|
|
778
|
+
const client = new NotionClient9({
|
|
686
779
|
token: config.notion.token,
|
|
687
780
|
concurrency: config.advanced.concurrency,
|
|
688
781
|
timeoutMs: config.advanced.timeoutMs
|
|
689
782
|
});
|
|
690
|
-
const vaultFs = new
|
|
691
|
-
const orchestrator = new
|
|
783
|
+
const vaultFs = new NodeVaultFS8(cwd, config.paths);
|
|
784
|
+
const orchestrator = new SyncOrchestrator8(config, stateDb, client, vaultFs);
|
|
692
785
|
const debounceMs = parseInt(options.debounce, 10);
|
|
693
786
|
const intervalSec = parseInt(options.interval, 10);
|
|
694
787
|
const service = new WatchSyncService(cwd, orchestrator, {
|
|
@@ -739,7 +832,7 @@ var watchCommand = new Command8("watch").description("\uD30C\uC77C \uBCC0\uACBD
|
|
|
739
832
|
});
|
|
740
833
|
|
|
741
834
|
// src/index.ts
|
|
742
|
-
var program = new
|
|
835
|
+
var program = new Command10();
|
|
743
836
|
program.name("im-nobsidian").description("Im-Nobsidian: Obsidian \u2194 Notion \uC591\uBC29\uD5A5 \uB3D9\uAE30\uD654 CLI").version("0.1.1").option("--verbose", "\uC0C1\uC138 \uB85C\uADF8 \uCD9C\uB825").option("--quiet", "\uCD5C\uC18C \uCD9C\uB825");
|
|
744
837
|
program.addCommand(initCommand);
|
|
745
838
|
program.addCommand(pushCommand);
|
|
@@ -747,6 +840,7 @@ program.addCommand(pullCommand);
|
|
|
747
840
|
program.addCommand(syncCommand);
|
|
748
841
|
program.addCommand(statusCommand);
|
|
749
842
|
program.addCommand(diffCommand);
|
|
843
|
+
program.addCommand(fetchCommand);
|
|
750
844
|
program.addCommand(resolveCommand);
|
|
751
845
|
program.addCommand(watchCommand);
|
|
752
846
|
program.parseAsync().then(() => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/utils/format.ts","../src/commands/push.ts","../src/commands/pull.ts","../src/commands/sync.ts","../src/commands/status.ts","../src/commands/diff.ts","../src/commands/resolve.ts","../src/commands/watch.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { pushCommand } from \"./commands/push.js\";\nimport { pullCommand } from \"./commands/pull.js\";\nimport { syncCommand } from \"./commands/sync.js\";\nimport { statusCommand } from \"./commands/status.js\";\nimport { diffCommand } from \"./commands/diff.js\";\nimport { resolveCommand } from \"./commands/resolve.js\";\nimport { watchCommand } from \"./commands/watch.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"im-nobsidian\")\n .description(\"Im-Nobsidian: Obsidian ↔ Notion 양방향 동기화 CLI\")\n .version(\"0.1.1\")\n .option(\"--verbose\", \"상세 로그 출력\")\n .option(\"--quiet\", \"최소 출력\");\n\nprogram.addCommand(initCommand);\nprogram.addCommand(pushCommand);\nprogram.addCommand(pullCommand);\nprogram.addCommand(syncCommand);\nprogram.addCommand(statusCommand);\nprogram.addCommand(diffCommand);\nprogram.addCommand(resolveCommand);\nprogram.addCommand(watchCommand);\n\nprogram.parseAsync().then(() => {\n setTimeout(() => process.exit(0), 100);\n});\n","import { Command } from \"commander\";\nimport { ConfigManager, NotionClient } from \"@im-nobsidian/core\";\nimport { input, confirm } from \"@inquirer/prompts\";\nimport ora from \"ora\";\nimport chalk from \"chalk\";\nimport { header, separator, icons, dimText } from \"../utils/format.js\";\n\nexport const initCommand = new Command(\"init\")\n .description(\"Im-Nobsidian 초기 설정\")\n .option(\"--token <token>\", \"Notion Integration Token\")\n .option(\"--root-page-id <id>\", \"루트 페이지 ID\")\n .option(\"--non-interactive\", \"비대화형 모드\")\n .action(async (options: { token?: string; rootPageId?: string; nonInteractive?: boolean }) => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n\n console.log(`\\n${header(chalk.cyan(\" Im-Nobsidian Setup\"))}`);\n console.log(` ${separator()}`);\n\n if (options.nonInteractive) {\n if (!options.token || !options.rootPageId) {\n console.error(\"비대화형 모드에서는 --token과 --root-page-id가 필수입니다.\");\n process.exitCode = 1;\n return;\n }\n\n if (!options.token.startsWith(\"ntn_\")) {\n console.error(\"토큰은 ntn_으로 시작해야 합니다.\");\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora(\"Notion 연결 확인 중...\").start();\n try {\n const client = new NotionClient({ token: options.token });\n await client.search({ pageSize: 1, filter: { property: \"object\", value: \"page\" } });\n spinner.stop();\n console.log(` ${icons.success} Token validated`);\n\n await configManager.init({ token: options.token, rootPageId: options.rootPageId });\n console.log(`\\n ${icons.success} Config saved to ${dimText(configManager.configPath)}`);\n console.log(` ${icons.success} State DB initialized`);\n console.log(\n `\\n ${header(chalk.green(\"Ready!\"))} Run ${chalk.cyan(\"nobsi sync\")} to start syncing.`,\n );\n } catch (error) {\n spinner.fail(\"Notion 연결 실패\");\n console.error(error instanceof Error ? error.message : error);\n process.exitCode = 1;\n }\n return;\n }\n\n const isInit = await configManager.isInitialized();\n if (isInit) {\n const overwrite = await confirm({\n message: \"이미 초기화되어 있습니다. 다시 설정할까요?\",\n default: false,\n });\n if (!overwrite) return;\n }\n\n const token = await input({\n message: \"Notion Integration Token:\",\n validate: (v) => v.startsWith(\"ntn_\") || \"ntn_으로 시작하는 토큰을 입력하세요\",\n });\n\n const spinner = ora(\"Notion 연결 확인 중...\").start();\n\n try {\n const client = new NotionClient({ token });\n const result = await client.search({\n pageSize: 10,\n filter: { property: \"object\", value: \"page\" },\n });\n spinner.stop();\n console.log(` ${icons.success} Token validated`);\n\n if (result.results.length === 0) {\n console.log(\n `\\n ${chalk.yellow(\"⚠\")} 접근 가능한 페이지가 없습니다. Integration에 페이지를 공유해주세요.`,\n );\n return;\n }\n\n console.log(`\\n Select root page:`);\n for (const [i, page] of result.results.entries()) {\n const title = extractPageTitle(page);\n console.log(` ${dimText(`${i + 1}.`)} ${title}`);\n }\n\n const rootPageId = await input({\n message: \"루트 페이지 ID (위에서 선택하거나 직접 입력):\",\n default: result.results[0]?.id,\n });\n\n await configManager.init({ token, rootPageId });\n console.log(`\\n ${icons.success} Config saved to ${dimText(configManager.configPath)}`);\n console.log(` ${icons.success} State DB initialized`);\n console.log(\n `\\n ${header(chalk.green(\"Ready!\"))} Run ${chalk.cyan(\"nobsi sync\")} to start syncing.`,\n );\n } catch (error) {\n spinner.fail(\"Notion 연결 실패\");\n console.error(error instanceof Error ? error.message : error);\n process.exitCode = 1;\n }\n });\n\nfunction extractPageTitle(page: Record<string, unknown>): string {\n const properties = page[\"properties\"] as Record<string, unknown> | undefined;\n if (!properties) return \"(제목 없음)\";\n\n for (const prop of Object.values(properties)) {\n const p = prop as { type?: string; title?: Array<{ plain_text?: string }> };\n if (p.type === \"title\" && p.title?.[0]?.plain_text) {\n return p.title[0].plain_text;\n }\n }\n return \"(제목 없음)\";\n}\n","import chalk from \"chalk\";\n\nexport const icons = {\n create: chalk.green(\"+\"),\n update: chalk.yellow(\"~\"),\n delete: chalk.red(\"-\"),\n success: chalk.green(\"✓\"),\n fail: chalk.red(\"✕\"),\n conflict: chalk.magenta(\"!\"),\n synced: chalk.green(\"●\"),\n modified: chalk.yellow(\"●\"),\n newFile: chalk.cyan(\"●\"),\n conflictDot: chalk.magenta(\"●\"),\n} as const;\n\nexport function header(text: string): string {\n return chalk.bold(text);\n}\n\nexport function separator(width = 35): string {\n return chalk.dim(\"━\".repeat(width));\n}\n\nexport function operationIcon(op: \"create\" | \"update\" | \"delete\"): string {\n return icons[op];\n}\n\nexport function operationLabel(op: \"create\" | \"update\" | \"delete\"): string {\n switch (op) {\n case \"create\":\n return chalk.green(\"created\");\n case \"update\":\n return chalk.yellow(\"updated\");\n case \"delete\":\n return chalk.red(\"deleted\");\n }\n}\n\nexport function summary(created: number, updated: number, deleted: number): string {\n const parts: string[] = [];\n if (created > 0) parts.push(chalk.green(`${created} created`));\n if (updated > 0) parts.push(chalk.yellow(`${updated} updated`));\n if (deleted > 0) parts.push(chalk.red(`${deleted} deleted`));\n if (parts.length === 0) parts.push(chalk.dim(\"no changes\"));\n return parts.join(\" \");\n}\n\nexport function duration(ms: number): string {\n return chalk.dim(`Done in ${(ms / 1000).toFixed(1)}s`);\n}\n\nexport function progress(current: number, total: number): string {\n return chalk.dim(`[${current}/${total}]`);\n}\n\nexport function dimText(text: string): string {\n return chalk.dim(text);\n}\n\nexport function failedItem(path: string, error: string): void {\n console.log(` ${icons.fail} ${path}: ${chalk.red(error)}`);\n}\n","import { Command } from \"commander\";\nimport {\n ConfigManager,\n StateDB,\n NotionClient,\n SyncOrchestrator,\n NodeVaultFS,\n} from \"@im-nobsidian/core\";\nimport chalk from \"chalk\";\nimport {\n header,\n operationIcon,\n operationLabel,\n progress,\n summary,\n duration,\n failedItem,\n dimText,\n} from \"../utils/format.js\";\n\nexport const pushCommand = new Command(\"push\")\n .description(\"로컬 변경사항을 Notion에 반영\")\n .option(\"--dry-run\", \"실제 반영 없이 변경사항만 표시\")\n .option(\"-p, --path <paths...>\", \"특정 경로만 push\")\n .action(async (options) => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n const config = await configManager.load();\n const stateDb = StateDB.open(configManager.dbPath);\n\n try {\n const client = new NotionClient({\n token: config.notion.token,\n concurrency: config.advanced.concurrency,\n timeoutMs: config.advanced.timeoutMs,\n });\n const vaultFs = new NodeVaultFS(cwd, config.paths);\n const orchestrator = new SyncOrchestrator(config, stateDb, client, vaultFs);\n\n console.log(`\\n${header(\" Pushing to Notion...\")}`);\n if (options.dryRun) console.log(dimText(\" (dry-run mode)\"));\n console.log(\"\");\n\n const result = await orchestrator.push({\n dryRun: options.dryRun,\n paths: options.path,\n onProgress: (current, total, item) => {\n const icon = operationIcon(item.operation);\n const label = operationLabel(item.operation);\n const prog = progress(current, total);\n console.log(` ${icon} ${item.path} ${prog} ${label}`);\n },\n });\n\n console.log(`\\n ${header(chalk.green(\"Push complete\"))}`);\n console.log(\n ` ${summary(result.created, result.updated, result.deleted)} ${dimText(`${result.failed.length} failed`)}`,\n );\n console.log(` ${duration(result.duration)}`);\n\n if (result.failed.length > 0) {\n console.log(\"\");\n for (const f of result.failed) {\n failedItem(f.path, f.error);\n }\n }\n } finally {\n stateDb.close();\n }\n });\n","import { Command } from \"commander\";\nimport {\n ConfigManager,\n StateDB,\n NotionClient,\n SyncOrchestrator,\n NodeVaultFS,\n} from \"@im-nobsidian/core\";\nimport chalk from \"chalk\";\nimport {\n header,\n operationIcon,\n operationLabel,\n progress,\n summary,\n duration,\n icons,\n failedItem,\n dimText,\n} from \"../utils/format.js\";\n\nexport const pullCommand = new Command(\"pull\")\n .description(\"Notion 변경사항을 로컬에 반영\")\n .option(\"--dry-run\", \"실제 반영 없이 변경사항만 표시\")\n .option(\"-p, --path <paths...>\", \"특정 경로만 pull\")\n .action(async (options) => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n const config = await configManager.load();\n const stateDb = StateDB.open(configManager.dbPath);\n\n try {\n const client = new NotionClient({\n token: config.notion.token,\n concurrency: config.advanced.concurrency,\n timeoutMs: config.advanced.timeoutMs,\n });\n const vaultFs = new NodeVaultFS(cwd, config.paths);\n const orchestrator = new SyncOrchestrator(config, stateDb, client, vaultFs);\n\n console.log(`\\n${header(\" Pulling from Notion...\")}`);\n if (options.dryRun) console.log(dimText(\" (dry-run mode)\"));\n console.log(\"\");\n\n const result = await orchestrator.pull({\n dryRun: options.dryRun,\n paths: options.path,\n onProgress: (current, total, item) => {\n const icon = operationIcon(item.operation);\n const label = operationLabel(item.operation);\n const prog = progress(current, total);\n console.log(` ${icon} ${item.path} ${prog} ${label}`);\n },\n });\n\n if (result.imageCount > 0) {\n console.log(\n `\\n ${icons.success} ${result.imageCount} images → ${dimText(\"attachments/\")}`,\n );\n }\n if (result.fileCount > 0) {\n console.log(` ${icons.success} ${result.fileCount} files → ${dimText(\"attachments/\")}`);\n }\n if (result.linkCount > 0) {\n console.log(` ${icons.success} ${result.linkCount} links resolved`);\n }\n\n console.log(`\\n ${header(chalk.green(\"Pull complete\"))}`);\n console.log(\n ` ${summary(result.created, result.updated, result.deleted)} ${dimText(`${result.failed.length} failed`)}`,\n );\n console.log(` ${duration(result.duration)}`);\n\n if (result.conflicts.length > 0) {\n console.log(\n `\\n ${icons.conflict} ${chalk.magenta(`${result.conflicts.length} conflicts`)} — run ${chalk.cyan(\"nobsi resolve\")}`,\n );\n }\n\n if (result.failed.length > 0) {\n console.log(\"\");\n for (const f of result.failed) {\n failedItem(f.path, f.error);\n }\n }\n } finally {\n stateDb.close();\n }\n });\n","import { Command } from \"commander\";\nimport {\n ConfigManager,\n StateDB,\n NotionClient,\n SyncOrchestrator,\n NodeVaultFS,\n} from \"@im-nobsidian/core\";\nimport chalk from \"chalk\";\nimport {\n header,\n separator,\n operationIcon,\n operationLabel,\n summary,\n duration,\n icons,\n dimText,\n} from \"../utils/format.js\";\n\nexport const syncCommand = new Command(\"sync\")\n .description(\"양방향 동기화 (Pull → Push)\")\n .option(\"--dry-run\", \"실제 반영 없이 변경사항만 표시\")\n .action(async (options) => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n const config = await configManager.load();\n const stateDb = StateDB.open(configManager.dbPath);\n\n try {\n const client = new NotionClient({\n token: config.notion.token,\n concurrency: config.advanced.concurrency,\n timeoutMs: config.advanced.timeoutMs,\n });\n const vaultFs = new NodeVaultFS(cwd, config.paths);\n const orchestrator = new SyncOrchestrator(config, stateDb, client, vaultFs);\n\n console.log(`\\n${header(\" Bidirectional Sync\")}`);\n console.log(` ${separator()}`);\n if (options.dryRun) console.log(dimText(\" (dry-run mode)\"));\n\n // Pull phase\n console.log(`\\n ${header(chalk.blue(\"▼ Pull\"))} ${dimText(\"(Notion → Obsidian)\")}`);\n\n const pullResult = await orchestrator.pull({\n dryRun: options.dryRun,\n onProgress: (_current, _total, item) => {\n const icon = operationIcon(item.operation);\n const label = operationLabel(item.operation);\n console.log(` ${icon} ${item.path} ${label}`);\n },\n });\n\n if (pullResult.imageCount > 0) {\n console.log(` ${icons.success} ${pullResult.imageCount} images downloaded`);\n }\n if (pullResult.linkCount > 0) {\n console.log(` ${icons.success} ${pullResult.linkCount} links resolved`);\n }\n\n // Push phase\n console.log(`\\n ${header(chalk.magenta(\"▲ Push\"))} ${dimText(\"(Obsidian → Notion)\")}`);\n\n const pushResult = await orchestrator.push({\n dryRun: options.dryRun,\n onProgress: (_current, _total, item) => {\n const icon = operationIcon(item.operation);\n const label = operationLabel(item.operation);\n console.log(` ${icon} ${item.path} ${label}`);\n },\n });\n\n // Summary\n const totalDuration = pullResult.duration + pushResult.duration;\n console.log(`\\n ${header(chalk.green(\"Sync complete\"))}`);\n console.log(\n ` ${chalk.blue(\"Pull:\")} ${summary(pullResult.created, pullResult.updated, pullResult.deleted)}`,\n );\n console.log(\n ` ${chalk.magenta(\"Push:\")} ${summary(pushResult.created, pushResult.updated, pushResult.deleted)}`,\n );\n console.log(` ${duration(totalDuration)}`);\n\n if (pullResult.conflicts.length > 0) {\n console.log(\n `\\n ${icons.conflict} ${chalk.magenta(`${pullResult.conflicts.length} conflicts`)} — run ${chalk.cyan(\"nobsi resolve\")}`,\n );\n }\n } finally {\n stateDb.close();\n }\n });\n","import { Command } from \"commander\";\nimport {\n ConfigManager,\n StateDB,\n NotionClient,\n SyncOrchestrator,\n NodeVaultFS,\n} from \"@im-nobsidian/core\";\nimport chalk from \"chalk\";\nimport { header, separator, icons, dimText } from \"../utils/format.js\";\n\nexport const statusCommand = new Command(\"status\")\n .description(\"동기화 상태 확인\")\n .action(async () => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n const config = await configManager.load();\n const stateDb = StateDB.open(configManager.dbPath);\n\n try {\n const client = new NotionClient({\n token: config.notion.token,\n concurrency: config.advanced.concurrency,\n });\n const vaultFs = new NodeVaultFS(cwd, config.paths);\n const orchestrator = new SyncOrchestrator(config, stateDb, client, vaultFs);\n\n const status = await orchestrator.status();\n\n console.log(`\\n${header(\" Sync Status\")}`);\n console.log(` ${separator(50)}`);\n\n const rootId = config.notion.rootPageId;\n const direction = config.sync.direction === \"both\" ? \"bidirectional\" : config.sync.direction;\n console.log(` ${dimText(\"Root page:\")} ${rootId.slice(0, 8)}...`);\n console.log(` ${dimText(\"Direction:\")} ${direction}`);\n if (status.lastSyncAt) {\n const date = new Date(status.lastSyncAt);\n const iso =\n date.getFullYear() +\n \"-\" +\n String(date.getMonth() + 1).padStart(2, \"0\") +\n \"-\" +\n String(date.getDate()).padStart(2, \"0\") +\n \" \" +\n String(date.getHours()).padStart(2, \"0\") +\n \":\" +\n String(date.getMinutes()).padStart(2, \"0\") +\n \":\" +\n String(date.getSeconds()).padStart(2, \"0\");\n console.log(` ${dimText(\"Last sync:\")} ${iso}`);\n } else {\n console.log(` ${dimText(\"Last sync:\")} ${chalk.yellow(\"never\")}`);\n }\n\n // Tracked files summary\n const allRecords = stateDb.getAll();\n const total = allRecords.length;\n const synced = allRecords.filter((r) => r.status === \"synced\").length;\n const conflictCount = status.conflictRecords.length;\n const createdChanges = status.localChanges.filter((c) => c.type === \"created\");\n const modifiedChanges = status.localChanges.filter((c) => c.type === \"modified\");\n\n console.log(`\\n ${header(`Tracked files: ${total}`)}`);\n console.log(` ${icons.synced} ${chalk.green(\"synced\")} ${synced}`);\n if (modifiedChanges.length > 0) {\n console.log(` ${icons.modified} ${chalk.yellow(\"modified\")} ${modifiedChanges.length}`);\n }\n if (createdChanges.length > 0) {\n console.log(` ${icons.newFile} ${chalk.cyan(\"new\")} ${createdChanges.length}`);\n }\n if (conflictCount > 0) {\n console.log(` ${icons.conflictDot} ${chalk.magenta(\"conflict\")} ${conflictCount}`);\n }\n\n // Modified files\n if (modifiedChanges.length > 0) {\n console.log(`\\n ${header(\"Modified files:\")}`);\n for (const c of modifiedChanges.slice(0, 10)) {\n console.log(\n ` ${chalk.yellow(\"~\")} ${c.path.padEnd(30)} ${dimText(\"(local changed)\")}`,\n );\n }\n if (modifiedChanges.length > 10) {\n console.log(dimText(` ... and ${modifiedChanges.length - 10} more`));\n }\n }\n\n // New files\n if (createdChanges.length > 0) {\n console.log(`\\n ${header(\"New files:\")}`);\n for (const c of createdChanges.slice(0, 10)) {\n console.log(` ${chalk.cyan(\"+\")} ${c.path.padEnd(30)} ${dimText(\"(untracked)\")}`);\n }\n if (createdChanges.length > 10) {\n console.log(dimText(` ... and ${createdChanges.length - 10} more`));\n }\n }\n\n // Conflicts\n if (conflictCount > 0) {\n console.log(`\\n ${header(chalk.magenta(\"Conflicts:\"))}`);\n for (const r of status.conflictRecords) {\n console.log(\n ` ${icons.conflict} ${r.obsidianPath.padEnd(30)} ${dimText(\"(both sides changed)\")}`,\n );\n }\n }\n\n // Helpful commands\n if (status.localChanges.length > 0 || conflictCount > 0) {\n console.log(\"\");\n if (conflictCount > 0) {\n console.log(\n ` ${dimText(\"Run\")} ${chalk.cyan(\"nobsi resolve\")} ${dimText(\"to resolve conflicts\")}`,\n );\n }\n console.log(\n ` ${dimText(\"Run\")} ${chalk.cyan(\"nobsi sync\")} ${dimText(\"to push/pull changes\")}`,\n );\n } else {\n console.log(`\\n ${chalk.green(\"Everything up to date\")} ✓`);\n }\n } finally {\n stateDb.close();\n }\n });\n","import { Command } from \"commander\";\nimport {\n ConfigManager,\n StateDB,\n NotionClient,\n SyncOrchestrator,\n NodeVaultFS,\n} from \"@im-nobsidian/core\";\nimport { createTwoFilesPatch } from \"diff\";\n\nexport const diffCommand = new Command(\"diff\")\n .description(\"로컬과 Notion 간의 차이 표시\")\n .argument(\"[path]\", \"특정 파일 경로 (생략 시 변경된 모든 파일)\")\n .option(\"--color\", \"컬러 출력\", true)\n .action(async (targetPath: string | undefined, options) => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n const config = await configManager.load();\n const stateDb = StateDB.open(configManager.dbPath);\n\n try {\n const client = new NotionClient({\n token: config.notion.token,\n concurrency: config.advanced.concurrency,\n timeoutMs: config.advanced.timeoutMs,\n });\n const vaultFs = new NodeVaultFS(cwd, config.paths);\n const orchestrator = new SyncOrchestrator(config, stateDb, client, vaultFs);\n\n const status = await orchestrator.status();\n\n const changes = targetPath\n ? status.localChanges.filter((c) => c.path === targetPath || c.path.startsWith(targetPath))\n : status.localChanges;\n\n if (changes.length === 0) {\n console.log(\"변경사항 없음\");\n return;\n }\n\n for (const change of changes) {\n const record = stateDb.getByPath(change.path);\n\n if (change.type === \"created\") {\n const content = await vaultFs.readFile(change.path);\n const patch = createTwoFilesPatch(`/dev/null`, `b/${change.path}`, \"\", content);\n printPatch(patch, options.color);\n } else if (change.type === \"deleted\") {\n if (record?.baseSnapshot) {\n const oldContent = record.baseSnapshot.toString(\"utf-8\");\n const patch = createTwoFilesPatch(`a/${change.path}`, `/dev/null`, oldContent, \"\");\n printPatch(patch, options.color);\n } else {\n console.log(`--- a/${change.path}`);\n console.log(`+++ /dev/null`);\n console.log(`(이전 스냅샷 없음)`);\n }\n } else if (change.type === \"modified\" && record?.baseSnapshot) {\n const currentContent = await vaultFs.readFile(change.path);\n const baseContent = record.baseSnapshot.toString(\"utf-8\");\n const patch = createTwoFilesPatch(\n `a/${change.path}`,\n `b/${change.path}`,\n baseContent,\n currentContent,\n );\n printPatch(patch, options.color);\n }\n\n console.log(\"\");\n }\n } finally {\n stateDb.close();\n }\n });\n\nfunction printPatch(patch: string, color: boolean): void {\n for (const line of patch.split(\"\\n\")) {\n if (!color) {\n console.log(line);\n continue;\n }\n\n if (line.startsWith(\"+++\") || line.startsWith(\"---\")) {\n console.log(`\\x1b[1m${line}\\x1b[0m`);\n } else if (line.startsWith(\"+\")) {\n console.log(`\\x1b[32m${line}\\x1b[0m`);\n } else if (line.startsWith(\"-\")) {\n console.log(`\\x1b[31m${line}\\x1b[0m`);\n } else if (line.startsWith(\"@@\")) {\n console.log(`\\x1b[36m${line}\\x1b[0m`);\n } else {\n console.log(line);\n }\n }\n}\n","import { Command } from \"commander\";\nimport { select, confirm } from \"@inquirer/prompts\";\nimport {\n ConfigManager,\n StateDB,\n NotionClient,\n SyncOrchestrator,\n NodeVaultFS,\n ConflictResolver,\n} from \"@im-nobsidian/core\";\nimport type { Conflict, ResolutionChoice } from \"@im-nobsidian/core\";\n\nexport const resolveCommand = new Command(\"resolve\")\n .description(\"충돌을 해결합니다\")\n .option(\"-s, --strategy <strategy>\", \"자동 해결 전략 (local-first, remote-first, duplicate)\")\n .action(async (options: { strategy?: string }) => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n\n try {\n const config = await configManager.load();\n const stateDb = StateDB.open(configManager.dbPath);\n const client = new NotionClient({\n token: config.notion.token,\n concurrency: 3,\n timeoutMs: 30000,\n });\n const vaultFs = new NodeVaultFS(cwd, config.paths);\n\n const orchestrator = new SyncOrchestrator(config, stateDb, client, vaultFs);\n const resolver = new ConflictResolver(stateDb, vaultFs);\n\n await orchestrator.status();\n const conflictRecords = stateDb.getByStatus(\"conflict\");\n\n if (conflictRecords.length === 0) {\n console.log(\"충돌이 없습니다.\");\n stateDb.close();\n return;\n }\n\n console.log(`\\n충돌 ${conflictRecords.length}건 발견\\n`);\n\n if (options.strategy) {\n const strategy = options.strategy as \"local-first\" | \"remote-first\" | \"duplicate\";\n const shouldProceed = await confirm({\n message: `${conflictRecords.length}건의 충돌을 '${strategy}' 전략으로 일괄 해결할까요?`,\n });\n\n if (!shouldProceed) {\n stateDb.close();\n return;\n }\n\n const pullResult = await orchestrator.pull();\n const results = await resolver.resolveAll(pullResult.conflicts, strategy);\n\n for (const result of results) {\n const icon = result.success ? \"\\x1b[32m✓\\x1b[0m\" : \"\\x1b[31m✗\\x1b[0m\";\n console.log(` ${icon} ${result.path} → ${result.choice}`);\n }\n } else {\n const pullResult = await orchestrator.pull();\n\n for (const conflict of pullResult.conflicts) {\n await resolveInteractive(conflict, resolver);\n }\n }\n\n stateDb.close();\n console.log(\"\\n충돌 해결 완료\");\n } catch (error) {\n console.error(\"오류:\", error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n });\n\nasync function resolveInteractive(conflict: Conflict, resolver: ConflictResolver): Promise<void> {\n const path = conflict.syncRecord.obsidianPath;\n\n console.log(`\\n${\"─\".repeat(60)}`);\n console.log(`파일: \\x1b[1m${path}\\x1b[0m`);\n console.log(`${\"─\".repeat(60)}`);\n\n const diff = resolver.generateDiff(conflict);\n const diffLines = diff.split(\"\\n\");\n for (const line of diffLines) {\n if (line.startsWith(\"- \")) {\n console.log(`\\x1b[31m${line}\\x1b[0m`);\n } else if (line.startsWith(\"+ \")) {\n console.log(`\\x1b[32m${line}\\x1b[0m`);\n } else if (line.startsWith(\"---\") || line.startsWith(\"+++\")) {\n console.log(`\\x1b[1m${line}\\x1b[0m`);\n } else {\n console.log(line);\n }\n }\n\n const choice = await select<ResolutionChoice>({\n message: \"어떻게 해결할까요?\",\n choices: [\n { name: \"로컬 유지 (Obsidian 버전 유지)\", value: \"local\" },\n { name: \"원격 유지 (Notion 버전으로 덮어쓰기)\", value: \"remote\" },\n { name: \"자동 병합 (3-way merge)\", value: \"merge\" },\n { name: \"복제 (원본 유지 + .conflict 파일 생성)\", value: \"duplicate\" },\n ],\n });\n\n const result = await resolver.resolve(conflict, choice);\n\n if (result.success) {\n console.log(`\\x1b[32m✓ ${path} → ${choice}로 해결\\x1b[0m`);\n } else if (result.mergeHadConflicts) {\n console.log(`\\x1b[33m⚠ ${path} → 자동 병합 완료 (수동 확인 필요한 충돌 마커 있음)\\x1b[0m`);\n } else {\n console.log(`\\x1b[31m✗ ${path} → 해결 실패\\x1b[0m`);\n }\n}\n","import { Command } from \"commander\";\nimport {\n ConfigManager,\n StateDB,\n NotionClient,\n SyncOrchestrator,\n NodeVaultFS,\n WatchSyncService,\n} from \"@im-nobsidian/core\";\nimport type { SyncResult } from \"@im-nobsidian/core\";\n\nfunction formatResult(result: SyncResult): string {\n const pull = `Pull: +${result.pull.created} ~${result.pull.updated} -${result.pull.deleted}`;\n const push = `Push: +${result.push.created} ~${result.push.updated} -${result.push.deleted}`;\n const parts = [pull, push];\n\n if (result.conflicts.length > 0) {\n parts.push(`충돌 ${result.conflicts.length}건`);\n }\n\n return parts.join(\" | \");\n}\n\nfunction timestamp(): string {\n return new Date().toLocaleTimeString(\"ko-KR\", { hour12: false });\n}\n\nexport const watchCommand = new Command(\"watch\")\n .description(\"파일 변경 감지 + 자동 동기화\")\n .option(\"-d, --debounce <ms>\", \"디바운스 대기 시간(ms)\", \"2000\")\n .option(\"-i, --interval <seconds>\", \"풀 동기화 주기(초, 0이면 비활성)\", \"0\")\n .action(async (options: { debounce: string; interval: string }) => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n const config = await configManager.load();\n const stateDb = StateDB.open(configManager.dbPath);\n\n const client = new NotionClient({\n token: config.notion.token,\n concurrency: config.advanced.concurrency,\n timeoutMs: config.advanced.timeoutMs,\n });\n const vaultFs = new NodeVaultFS(cwd, config.paths);\n const orchestrator = new SyncOrchestrator(config, stateDb, client, vaultFs);\n\n const debounceMs = parseInt(options.debounce, 10);\n const intervalSec = parseInt(options.interval, 10);\n\n const service = new WatchSyncService(cwd, orchestrator, {\n debounceMs,\n onFileChange: (event, path) => {\n console.log(`[${timestamp()}] ${event}: ${path}`);\n },\n onSyncStart: () => {\n console.log(`[${timestamp()}] 동기화 시작...`);\n },\n onSyncComplete: (result) => {\n console.log(`[${timestamp()}] 동기화 완료 — ${formatResult(result)}`);\n },\n onSyncError: (error) => {\n console.error(`[${timestamp()}] 동기화 실패: ${error.message}`);\n },\n });\n\n let pullTimer: ReturnType<typeof setInterval> | null = null;\n\n const shutdown = async (): Promise<void> => {\n console.log(`\\n[${timestamp()}] 감시 종료 중...`);\n if (pullTimer) clearInterval(pullTimer);\n await service.stop();\n stateDb.close();\n console.log(`[${timestamp()}] 종료 완료`);\n process.exit(0);\n };\n\n process.on(\"SIGINT\", () => void shutdown());\n process.on(\"SIGTERM\", () => void shutdown());\n\n service.start();\n console.log(`[${timestamp()}] 파일 감시 시작 (debounce: ${debounceMs}ms)`);\n\n if (intervalSec > 0) {\n console.log(`[${timestamp()}] 풀 동기화 주기: ${intervalSec}초`);\n pullTimer = setInterval(async () => {\n if (service.isSyncing()) return;\n try {\n console.log(`[${timestamp()}] 주기적 동기화 시작...`);\n const result = await orchestrator.sync();\n console.log(`[${timestamp()}] 주기적 동기화 완료 — ${formatResult(result)}`);\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error(`[${timestamp()}] 주기적 동기화 실패: ${msg}`);\n }\n }, intervalSec * 1000);\n }\n\n await new Promise(() => {});\n });\n"],"mappings":"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","names":["Command","chalk","chalk","spinner","Command","ConfigManager","NotionClient","chalk","Command","ConfigManager","NotionClient","chalk","Command","ConfigManager","StateDB","NotionClient","SyncOrchestrator","NodeVaultFS","chalk","Command","ConfigManager","StateDB","NotionClient","NodeVaultFS","SyncOrchestrator","chalk","Command","ConfigManager","StateDB","NotionClient","SyncOrchestrator","NodeVaultFS","chalk","Command","ConfigManager","StateDB","NotionClient","NodeVaultFS","SyncOrchestrator","chalk","Command","ConfigManager","StateDB","NotionClient","SyncOrchestrator","NodeVaultFS","chalk","Command","ConfigManager","StateDB","NotionClient","NodeVaultFS","SyncOrchestrator","chalk","Command","ConfigManager","StateDB","NotionClient","SyncOrchestrator","NodeVaultFS","Command","confirm","ConfigManager","StateDB","NotionClient","SyncOrchestrator","NodeVaultFS","Command","ConfigManager","StateDB","NotionClient","SyncOrchestrator","NodeVaultFS","Command"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/utils/format.ts","../src/commands/push.ts","../src/commands/pull.ts","../src/commands/sync.ts","../src/commands/status.ts","../src/commands/diff.ts","../src/commands/fetch.ts","../src/commands/resolve.ts","../src/commands/watch.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { pushCommand } from \"./commands/push.js\";\nimport { pullCommand } from \"./commands/pull.js\";\nimport { syncCommand } from \"./commands/sync.js\";\nimport { statusCommand } from \"./commands/status.js\";\nimport { diffCommand } from \"./commands/diff.js\";\nimport { fetchCommand } from \"./commands/fetch.js\";\nimport { resolveCommand } from \"./commands/resolve.js\";\nimport { watchCommand } from \"./commands/watch.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"im-nobsidian\")\n .description(\"Im-Nobsidian: Obsidian ↔ Notion 양방향 동기화 CLI\")\n .version(\"0.1.1\")\n .option(\"--verbose\", \"상세 로그 출력\")\n .option(\"--quiet\", \"최소 출력\");\n\nprogram.addCommand(initCommand);\nprogram.addCommand(pushCommand);\nprogram.addCommand(pullCommand);\nprogram.addCommand(syncCommand);\nprogram.addCommand(statusCommand);\nprogram.addCommand(diffCommand);\nprogram.addCommand(fetchCommand);\nprogram.addCommand(resolveCommand);\nprogram.addCommand(watchCommand);\n\nprogram.parseAsync().then(() => {\n setTimeout(() => process.exit(0), 100);\n});\n","import { Command } from \"commander\";\nimport { ConfigManager, NotionClient } from \"@im-nobsidian/core\";\nimport { input, confirm } from \"@inquirer/prompts\";\nimport ora from \"ora\";\nimport chalk from \"chalk\";\nimport { header, separator, icons, dimText } from \"../utils/format.js\";\n\nexport const initCommand = new Command(\"init\")\n .description(\"Im-Nobsidian 초기 설정\")\n .option(\"--token <token>\", \"Notion Integration Token\")\n .option(\"--root-page-id <id>\", \"루트 페이지 ID\")\n .option(\"--non-interactive\", \"비대화형 모드\")\n .action(async (options: { token?: string; rootPageId?: string; nonInteractive?: boolean }) => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n\n console.log(`\\n${header(chalk.cyan(\" Im-Nobsidian Setup\"))}`);\n console.log(` ${separator()}`);\n\n if (options.nonInteractive) {\n if (!options.token || !options.rootPageId) {\n console.error(\"비대화형 모드에서는 --token과 --root-page-id가 필수입니다.\");\n process.exitCode = 1;\n return;\n }\n\n if (!options.token.startsWith(\"ntn_\")) {\n console.error(\"토큰은 ntn_으로 시작해야 합니다.\");\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora(\"Notion 연결 확인 중...\").start();\n try {\n const client = new NotionClient({ token: options.token });\n await client.search({ pageSize: 1, filter: { property: \"object\", value: \"page\" } });\n spinner.stop();\n console.log(` ${icons.success} Token validated`);\n\n await configManager.init({ token: options.token, rootPageId: options.rootPageId });\n console.log(`\\n ${icons.success} Config saved to ${dimText(configManager.configPath)}`);\n console.log(` ${icons.success} State DB initialized`);\n console.log(\n `\\n ${header(chalk.green(\"Ready!\"))} Run ${chalk.cyan(\"nobsi sync\")} to start syncing.`,\n );\n } catch (error) {\n spinner.fail(\"Notion 연결 실패\");\n console.error(error instanceof Error ? error.message : error);\n process.exitCode = 1;\n }\n return;\n }\n\n const isInit = await configManager.isInitialized();\n if (isInit) {\n const overwrite = await confirm({\n message: \"이미 초기화되어 있습니다. 다시 설정할까요?\",\n default: false,\n });\n if (!overwrite) return;\n }\n\n const token = await input({\n message: \"Notion Integration Token:\",\n validate: (v) => v.startsWith(\"ntn_\") || \"ntn_으로 시작하는 토큰을 입력하세요\",\n });\n\n const spinner = ora(\"Notion 연결 확인 중...\").start();\n\n try {\n const client = new NotionClient({ token });\n const result = await client.search({\n pageSize: 10,\n filter: { property: \"object\", value: \"page\" },\n });\n spinner.stop();\n console.log(` ${icons.success} Token validated`);\n\n if (result.results.length === 0) {\n console.log(\n `\\n ${chalk.yellow(\"⚠\")} 접근 가능한 페이지가 없습니다. Integration에 페이지를 공유해주세요.`,\n );\n return;\n }\n\n console.log(`\\n Select root page:`);\n for (const [i, page] of result.results.entries()) {\n const title = extractPageTitle(page);\n console.log(` ${dimText(`${i + 1}.`)} ${title}`);\n }\n\n const rootPageId = await input({\n message: \"루트 페이지 ID (위에서 선택하거나 직접 입력):\",\n default: result.results[0]?.id,\n });\n\n await configManager.init({ token, rootPageId });\n console.log(`\\n ${icons.success} Config saved to ${dimText(configManager.configPath)}`);\n console.log(` ${icons.success} State DB initialized`);\n console.log(\n `\\n ${header(chalk.green(\"Ready!\"))} Run ${chalk.cyan(\"nobsi sync\")} to start syncing.`,\n );\n } catch (error) {\n spinner.fail(\"Notion 연결 실패\");\n console.error(error instanceof Error ? error.message : error);\n process.exitCode = 1;\n }\n });\n\nfunction extractPageTitle(page: Record<string, unknown>): string {\n const properties = page[\"properties\"] as Record<string, unknown> | undefined;\n if (!properties) return \"(제목 없음)\";\n\n for (const prop of Object.values(properties)) {\n const p = prop as { type?: string; title?: Array<{ plain_text?: string }> };\n if (p.type === \"title\" && p.title?.[0]?.plain_text) {\n return p.title[0].plain_text;\n }\n }\n return \"(제목 없음)\";\n}\n","import chalk from \"chalk\";\n\nexport const icons = {\n create: chalk.green(\"+\"),\n update: chalk.yellow(\"~\"),\n delete: chalk.red(\"-\"),\n success: chalk.green(\"✓\"),\n fail: chalk.red(\"✕\"),\n conflict: chalk.magenta(\"!\"),\n synced: chalk.green(\"●\"),\n modified: chalk.yellow(\"●\"),\n newFile: chalk.cyan(\"●\"),\n conflictDot: chalk.magenta(\"●\"),\n} as const;\n\nexport function header(text: string): string {\n return chalk.bold(text);\n}\n\nexport function separator(width = 35): string {\n return chalk.dim(\"━\".repeat(width));\n}\n\nexport function operationIcon(op: \"create\" | \"update\" | \"delete\"): string {\n return icons[op];\n}\n\nexport function operationLabel(op: \"create\" | \"update\" | \"delete\"): string {\n switch (op) {\n case \"create\":\n return chalk.green(\"created\");\n case \"update\":\n return chalk.yellow(\"updated\");\n case \"delete\":\n return chalk.red(\"deleted\");\n }\n}\n\nexport function summary(created: number, updated: number, deleted: number): string {\n const parts: string[] = [];\n if (created > 0) parts.push(chalk.green(`${created} created`));\n if (updated > 0) parts.push(chalk.yellow(`${updated} updated`));\n if (deleted > 0) parts.push(chalk.red(`${deleted} deleted`));\n if (parts.length === 0) parts.push(chalk.dim(\"no changes\"));\n return parts.join(\" \");\n}\n\nexport function duration(ms: number): string {\n return chalk.dim(`Done in ${(ms / 1000).toFixed(1)}s`);\n}\n\nexport function progress(current: number, total: number): string {\n return chalk.dim(`[${current}/${total}]`);\n}\n\nexport function dimText(text: string): string {\n return chalk.dim(text);\n}\n\nexport function failedItem(path: string, error: string): void {\n console.log(` ${icons.fail} ${path}: ${chalk.red(error)}`);\n}\n","import { Command } from \"commander\";\nimport {\n ConfigManager,\n StateDB,\n NotionClient,\n SyncOrchestrator,\n NodeVaultFS,\n} from \"@im-nobsidian/core\";\nimport chalk from \"chalk\";\nimport {\n header,\n operationIcon,\n operationLabel,\n progress,\n summary,\n duration,\n failedItem,\n dimText,\n} from \"../utils/format.js\";\n\nexport const pushCommand = new Command(\"push\")\n .description(\"로컬 변경사항을 Notion에 반영\")\n .option(\"--dry-run\", \"실제 반영 없이 변경사항만 표시\")\n .option(\"-p, --path <paths...>\", \"특정 경로만 push\")\n .action(async (options) => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n const config = await configManager.load();\n const stateDb = StateDB.open(configManager.dbPath);\n\n try {\n const client = new NotionClient({\n token: config.notion.token,\n concurrency: config.advanced.concurrency,\n timeoutMs: config.advanced.timeoutMs,\n });\n const vaultFs = new NodeVaultFS(cwd, config.paths);\n const orchestrator = new SyncOrchestrator(config, stateDb, client, vaultFs);\n\n console.log(`\\n${header(\" Pushing to Notion...\")}`);\n if (options.dryRun) console.log(dimText(\" (dry-run mode)\"));\n console.log(\"\");\n\n const result = await orchestrator.push({\n dryRun: options.dryRun,\n paths: options.path,\n onProgress: (current, total, item) => {\n const icon = operationIcon(item.operation);\n const label = operationLabel(item.operation);\n const prog = progress(current, total);\n console.log(` ${icon} ${item.path} ${prog} ${label}`);\n },\n });\n\n console.log(`\\n ${header(chalk.green(\"Push complete\"))}`);\n console.log(\n ` ${summary(result.created, result.updated, result.deleted)} ${dimText(`${result.failed.length} failed`)}`,\n );\n console.log(` ${duration(result.duration)}`);\n\n if (result.failed.length > 0) {\n console.log(\"\");\n for (const f of result.failed) {\n failedItem(f.path, f.error);\n }\n }\n } finally {\n stateDb.close();\n }\n });\n","import { Command } from \"commander\";\nimport {\n ConfigManager,\n StateDB,\n NotionClient,\n SyncOrchestrator,\n NodeVaultFS,\n} from \"@im-nobsidian/core\";\nimport chalk from \"chalk\";\nimport {\n header,\n operationIcon,\n operationLabel,\n progress,\n summary,\n duration,\n icons,\n failedItem,\n dimText,\n} from \"../utils/format.js\";\n\nexport const pullCommand = new Command(\"pull\")\n .description(\"Notion 변경사항을 로컬에 반영\")\n .option(\"--dry-run\", \"실제 반영 없이 변경사항만 표시\")\n .option(\"-p, --path <paths...>\", \"특정 경로만 pull\")\n .action(async (options) => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n const config = await configManager.load();\n const stateDb = StateDB.open(configManager.dbPath);\n\n try {\n const client = new NotionClient({\n token: config.notion.token,\n concurrency: config.advanced.concurrency,\n timeoutMs: config.advanced.timeoutMs,\n });\n const vaultFs = new NodeVaultFS(cwd, config.paths);\n const orchestrator = new SyncOrchestrator(config, stateDb, client, vaultFs);\n\n console.log(`\\n${header(\" Pulling from Notion...\")}`);\n if (options.dryRun) console.log(dimText(\" (dry-run mode)\"));\n console.log(\"\");\n\n const result = await orchestrator.pull({\n dryRun: options.dryRun,\n paths: options.path,\n onProgress: (current, total, item) => {\n const icon = operationIcon(item.operation);\n const label = operationLabel(item.operation);\n const prog = progress(current, total);\n console.log(` ${icon} ${item.path} ${prog} ${label}`);\n },\n });\n\n if (result.imageCount > 0) {\n console.log(\n `\\n ${icons.success} ${result.imageCount} images → ${dimText(\"attachments/\")}`,\n );\n }\n if (result.fileCount > 0) {\n console.log(` ${icons.success} ${result.fileCount} files → ${dimText(\"attachments/\")}`);\n }\n if (result.linkCount > 0) {\n console.log(` ${icons.success} ${result.linkCount} links resolved`);\n }\n\n console.log(`\\n ${header(chalk.green(\"Pull complete\"))}`);\n console.log(\n ` ${summary(result.created, result.updated, result.deleted)} ${dimText(`${result.failed.length} failed`)}`,\n );\n console.log(` ${duration(result.duration)}`);\n\n if (result.conflicts.length > 0) {\n console.log(\n `\\n ${icons.conflict} ${chalk.magenta(`${result.conflicts.length} conflicts`)} — run ${chalk.cyan(\"nobsi resolve\")}`,\n );\n }\n\n if (result.failed.length > 0) {\n console.log(\"\");\n for (const f of result.failed) {\n failedItem(f.path, f.error);\n }\n }\n } finally {\n stateDb.close();\n }\n });\n","import { Command } from \"commander\";\nimport {\n ConfigManager,\n StateDB,\n NotionClient,\n SyncOrchestrator,\n NodeVaultFS,\n} from \"@im-nobsidian/core\";\nimport chalk from \"chalk\";\nimport {\n header,\n separator,\n operationIcon,\n operationLabel,\n summary,\n duration,\n icons,\n dimText,\n} from \"../utils/format.js\";\n\nexport const syncCommand = new Command(\"sync\")\n .description(\"양방향 동기화 (Pull → Push)\")\n .option(\"--dry-run\", \"실제 반영 없이 변경사항만 표시\")\n .action(async (options) => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n const config = await configManager.load();\n const stateDb = StateDB.open(configManager.dbPath);\n\n try {\n const client = new NotionClient({\n token: config.notion.token,\n concurrency: config.advanced.concurrency,\n timeoutMs: config.advanced.timeoutMs,\n });\n const vaultFs = new NodeVaultFS(cwd, config.paths);\n const orchestrator = new SyncOrchestrator(config, stateDb, client, vaultFs);\n\n console.log(`\\n${header(\" Bidirectional Sync\")}`);\n console.log(` ${separator()}`);\n if (options.dryRun) console.log(dimText(\" (dry-run mode)\"));\n\n // Pull phase\n console.log(`\\n ${header(chalk.blue(\"▼ Pull\"))} ${dimText(\"(Notion → Obsidian)\")}`);\n\n const pullResult = await orchestrator.pull({\n dryRun: options.dryRun,\n onProgress: (_current, _total, item) => {\n const icon = operationIcon(item.operation);\n const label = operationLabel(item.operation);\n console.log(` ${icon} ${item.path} ${label}`);\n },\n });\n\n if (pullResult.imageCount > 0) {\n console.log(` ${icons.success} ${pullResult.imageCount} images downloaded`);\n }\n if (pullResult.linkCount > 0) {\n console.log(` ${icons.success} ${pullResult.linkCount} links resolved`);\n }\n\n // Push phase\n console.log(`\\n ${header(chalk.magenta(\"▲ Push\"))} ${dimText(\"(Obsidian → Notion)\")}`);\n\n const pushResult = await orchestrator.push({\n dryRun: options.dryRun,\n onProgress: (_current, _total, item) => {\n const icon = operationIcon(item.operation);\n const label = operationLabel(item.operation);\n console.log(` ${icon} ${item.path} ${label}`);\n },\n });\n\n // Summary\n const totalDuration = pullResult.duration + pushResult.duration;\n console.log(`\\n ${header(chalk.green(\"Sync complete\"))}`);\n console.log(\n ` ${chalk.blue(\"Pull:\")} ${summary(pullResult.created, pullResult.updated, pullResult.deleted)}`,\n );\n console.log(\n ` ${chalk.magenta(\"Push:\")} ${summary(pushResult.created, pushResult.updated, pushResult.deleted)}`,\n );\n console.log(` ${duration(totalDuration)}`);\n\n if (pullResult.conflicts.length > 0) {\n console.log(\n `\\n ${icons.conflict} ${chalk.magenta(`${pullResult.conflicts.length} conflicts`)} — run ${chalk.cyan(\"nobsi resolve\")}`,\n );\n }\n } finally {\n stateDb.close();\n }\n });\n","import { Command } from \"commander\";\nimport {\n ConfigManager,\n StateDB,\n NotionClient,\n SyncOrchestrator,\n NodeVaultFS,\n} from \"@im-nobsidian/core\";\nimport chalk from \"chalk\";\nimport { header, separator, icons, dimText } from \"../utils/format.js\";\n\nexport const statusCommand = new Command(\"status\")\n .description(\"동기화 상태 확인 (--full: 원격 변경 포함)\")\n .option(\"--full\", \"Notion 원격 변경까지 양방향 확인 (API 호출, 느림)\")\n .action(async (opts: { full?: boolean }) => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n const config = await configManager.load();\n const stateDb = StateDB.open(configManager.dbPath);\n\n try {\n const client = new NotionClient({\n token: config.notion.token,\n concurrency: config.advanced.concurrency,\n });\n const vaultFs = new NodeVaultFS(cwd, config.paths);\n const orchestrator = new SyncOrchestrator(config, stateDb, client, vaultFs);\n\n const status = opts.full ? await orchestrator.status() : await orchestrator.statusLocal();\n\n console.log(`\\n${header(\" Sync Status\")}`);\n console.log(` ${separator(50)}`);\n\n const rootId = config.notion.rootPageId;\n const direction = config.sync.direction === \"both\" ? \"bidirectional\" : config.sync.direction;\n console.log(` ${dimText(\"Root page:\")} ${rootId.slice(0, 8)}...`);\n console.log(` ${dimText(\"Direction:\")} ${direction}`);\n if (status.lastSyncAt) {\n const date = new Date(status.lastSyncAt);\n const iso =\n date.getFullYear() +\n \"-\" +\n String(date.getMonth() + 1).padStart(2, \"0\") +\n \"-\" +\n String(date.getDate()).padStart(2, \"0\") +\n \" \" +\n String(date.getHours()).padStart(2, \"0\") +\n \":\" +\n String(date.getMinutes()).padStart(2, \"0\") +\n \":\" +\n String(date.getSeconds()).padStart(2, \"0\");\n console.log(` ${dimText(\"Last sync:\")} ${iso}`);\n } else {\n console.log(` ${dimText(\"Last sync:\")} ${chalk.yellow(\"never\")}`);\n }\n\n // Tracked files summary\n const allRecords = stateDb.getAll();\n const total = allRecords.length;\n const synced = allRecords.filter((r) => r.status === \"synced\").length;\n const conflictCount = status.conflictRecords.length;\n const createdChanges = status.localChanges.filter((c) => c.type === \"created\");\n const modifiedChanges = status.localChanges.filter((c) => c.type === \"modified\");\n const remoteCreated = status.remoteChanges.filter((c) => c.type === \"created\");\n const remoteModified = status.remoteChanges.filter((c) => c.type === \"modified\");\n const remoteDeleted = status.remoteChanges.filter((c) => c.type === \"deleted\");\n\n console.log(`\\n ${header(`Tracked files: ${total}`)}`);\n console.log(` ${icons.synced} ${chalk.green(\"synced\")} ${synced}`);\n if (modifiedChanges.length > 0) {\n console.log(` ${icons.modified} ${chalk.yellow(\"modified\")} ${modifiedChanges.length}`);\n }\n if (createdChanges.length > 0) {\n console.log(` ${icons.newFile} ${chalk.cyan(\"new\")} ${createdChanges.length}`);\n }\n if (conflictCount > 0) {\n console.log(` ${icons.conflictDot} ${chalk.magenta(\"conflict\")} ${conflictCount}`);\n }\n\n // Modified files\n if (modifiedChanges.length > 0) {\n console.log(`\\n ${header(\"Modified files:\")}`);\n for (const c of modifiedChanges.slice(0, 10)) {\n console.log(\n ` ${chalk.yellow(\"~\")} ${c.path.padEnd(30)} ${dimText(\"(local changed)\")}`,\n );\n }\n if (modifiedChanges.length > 10) {\n console.log(dimText(` ... and ${modifiedChanges.length - 10} more`));\n }\n }\n\n // New files\n if (createdChanges.length > 0) {\n console.log(`\\n ${header(\"New files:\")}`);\n for (const c of createdChanges.slice(0, 10)) {\n console.log(` ${chalk.cyan(\"+\")} ${c.path.padEnd(30)} ${dimText(\"(untracked)\")}`);\n }\n if (createdChanges.length > 10) {\n console.log(dimText(` ... and ${createdChanges.length - 10} more`));\n }\n }\n\n // Remote changes (Notion-side)\n if (status.remoteChanges.length > 0) {\n console.log(`\\n ${header(`Remote changes (Notion): ${status.remoteChanges.length}`)}`);\n if (remoteCreated.length > 0) {\n console.log(` ${chalk.cyan(\"+\")} ${chalk.cyan(\"new\")} ${remoteCreated.length}`);\n }\n if (remoteModified.length > 0) {\n console.log(\n ` ${chalk.yellow(\"~\")} ${chalk.yellow(\"modified\")} ${remoteModified.length}`,\n );\n }\n if (remoteDeleted.length > 0) {\n console.log(` ${chalk.red(\"-\")} ${chalk.red(\"deleted\")} ${remoteDeleted.length}`);\n }\n for (const c of status.remoteChanges.slice(0, 10)) {\n const icon =\n c.type === \"created\"\n ? chalk.cyan(\"+\")\n : c.type === \"modified\"\n ? chalk.yellow(\"~\")\n : chalk.red(\"-\");\n console.log(` ${icon} ${c.pageId.slice(0, 8)}... ${dimText(`(${c.type})`)}`);\n }\n if (status.remoteChanges.length > 10) {\n console.log(dimText(` ... and ${status.remoteChanges.length - 10} more`));\n }\n }\n\n // Conflicts\n if (conflictCount > 0) {\n console.log(`\\n ${header(chalk.magenta(\"Conflicts:\"))}`);\n for (const r of status.conflictRecords) {\n console.log(\n ` ${icons.conflict} ${r.obsidianPath.padEnd(30)} ${dimText(\"(both sides changed)\")}`,\n );\n }\n }\n\n // Helpful commands\n const hasChanges =\n status.localChanges.length > 0 || status.remoteChanges.length > 0 || conflictCount > 0;\n if (hasChanges) {\n console.log(\"\");\n if (conflictCount > 0) {\n console.log(\n ` ${dimText(\"Run\")} ${chalk.cyan(\"nobsi resolve\")} ${dimText(\"to resolve conflicts\")}`,\n );\n }\n console.log(\n ` ${dimText(\"Run\")} ${chalk.cyan(\"nobsi sync\")} ${dimText(\"to push/pull changes\")}`,\n );\n } else {\n console.log(`\\n ${chalk.green(\"Everything up to date\")} ✓`);\n }\n if (!opts.full) {\n console.log(\n `\\n ${dimText(\"Run\")} ${chalk.cyan(\"nobsi status --full\")} ${dimText(\"to check Notion remote changes\")}`,\n );\n }\n } finally {\n stateDb.close();\n }\n });\n","import { Command } from \"commander\";\nimport {\n ConfigManager,\n StateDB,\n NotionClient,\n SyncOrchestrator,\n NodeVaultFS,\n} from \"@im-nobsidian/core\";\nimport { createTwoFilesPatch } from \"diff\";\n\nexport const diffCommand = new Command(\"diff\")\n .description(\"로컬과 Notion 간의 차이 표시\")\n .argument(\"[path]\", \"특정 파일 경로 (생략 시 변경된 모든 파일)\")\n .option(\"--color\", \"컬러 출력\", true)\n .action(async (targetPath: string | undefined, options) => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n const config = await configManager.load();\n const stateDb = StateDB.open(configManager.dbPath);\n\n try {\n const client = new NotionClient({\n token: config.notion.token,\n concurrency: config.advanced.concurrency,\n timeoutMs: config.advanced.timeoutMs,\n });\n const vaultFs = new NodeVaultFS(cwd, config.paths);\n const orchestrator = new SyncOrchestrator(config, stateDb, client, vaultFs);\n\n const status = await orchestrator.statusLocal();\n\n const changes = targetPath\n ? status.localChanges.filter((c) => c.path === targetPath || c.path.startsWith(targetPath))\n : status.localChanges;\n\n if (changes.length === 0) {\n console.log(\"변경사항 없음\");\n return;\n }\n\n for (const change of changes) {\n const record = stateDb.getByPath(change.path);\n\n if (change.type === \"created\") {\n const content = await vaultFs.readFile(change.path);\n const patch = createTwoFilesPatch(\"/dev/null\", `b/${change.path}`, \"\", content);\n printPatch(patch, options.color, \"/dev/null\", `b/${change.path}`);\n } else if (change.type === \"deleted\") {\n if (record?.baseSnapshot) {\n const oldContent = record.baseSnapshot.toString(\"utf-8\");\n const patch = createTwoFilesPatch(`a/${change.path}`, \"/dev/null\", oldContent, \"\");\n printPatch(patch, options.color, `a/${change.path}`, \"/dev/null\");\n } else {\n console.log(`--- a/${change.path}`);\n console.log(`+++ /dev/null`);\n console.log(`(이전 스냅샷 없음)`);\n }\n } else if (change.type === \"modified\" && record?.baseSnapshot) {\n const currentContent = await vaultFs.readFile(change.path);\n const baseContent = record.baseSnapshot.toString(\"utf-8\");\n const patch = createTwoFilesPatch(\n `a/${change.path}`,\n `b/${change.path}`,\n baseContent,\n currentContent,\n );\n printPatch(patch, options.color, `a/${change.path}`, `b/${change.path}`);\n }\n\n console.log(\"\");\n }\n } finally {\n stateDb.close();\n }\n });\n\nfunction printPatch(patch: string, color: boolean, oldPath: string, newPath: string): void {\n for (const line of patch.split(\"\\n\")) {\n let output = line;\n if (line.startsWith(\"===\")) {\n output = \"===================================================================\";\n } else if (line.startsWith(\"--- \")) {\n output = `--- ${oldPath}`;\n } else if (line.startsWith(\"+++ \")) {\n output = `+++ ${newPath}`;\n }\n\n if (!color) {\n console.log(output);\n continue;\n }\n\n if (output.startsWith(\"+++\") || output.startsWith(\"---\")) {\n console.log(`\\x1b[1m${output}\\x1b[0m`);\n } else if (output.startsWith(\"+\")) {\n console.log(`\\x1b[32m${output}\\x1b[0m`);\n } else if (output.startsWith(\"-\")) {\n console.log(`\\x1b[31m${output}\\x1b[0m`);\n } else if (output.startsWith(\"@@\")) {\n console.log(`\\x1b[36m${output}\\x1b[0m`);\n } else {\n console.log(output);\n }\n }\n}\n","import { Command } from \"commander\";\nimport {\n ConfigManager,\n StateDB,\n NotionClient,\n SyncOrchestrator,\n NodeVaultFS,\n} from \"@im-nobsidian/core\";\nimport chalk from \"chalk\";\nimport { header, separator, dimText } from \"../utils/format.js\";\n\nexport const fetchCommand = new Command(\"fetch\")\n .description(\"Notion 리모트 상태 스캔 (삭제 감지 포함)\")\n .action(async () => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n const config = await configManager.load();\n const stateDb = StateDB.open(configManager.dbPath);\n\n try {\n const client = new NotionClient({\n token: config.notion.token,\n concurrency: config.advanced.concurrency,\n timeoutMs: config.advanced.timeoutMs,\n });\n const vaultFs = new NodeVaultFS(cwd, config.paths);\n const orchestrator = new SyncOrchestrator(config, stateDb, client, vaultFs);\n\n console.log(dimText(\" Scanning remote pages...\"));\n\n const result = await orchestrator.fetch();\n\n console.log(`\\n${header(\" Remote Scan\")}`);\n console.log(` ${separator(40)}`);\n\n if (result.newPages > 0) {\n console.log(` ${chalk.cyan(\"+\")} New pages: ${result.newPages}`);\n }\n if (result.modifiedPages > 0) {\n console.log(` ${chalk.yellow(\"~\")} Modified pages: ${result.modifiedPages}`);\n }\n if (result.deletedPages > 0) {\n console.log(` ${chalk.red(\"-\")} Deleted pages: ${result.deletedPages}`);\n }\n\n const total = result.newPages + result.modifiedPages + result.deletedPages;\n if (total === 0) {\n console.log(` ${chalk.green(\"Remote is up to date\")} ✓`);\n } else {\n console.log(\n `\\n ${dimText(\"Run\")} ${chalk.cyan(\"nobsi pull\")} ${dimText(\"to apply remote changes\")}`,\n );\n }\n\n console.log(dimText(`\\n Completed in ${(result.duration / 1000).toFixed(1)}s`));\n } finally {\n stateDb.close();\n }\n });\n","import { Command } from \"commander\";\nimport { select, confirm } from \"@inquirer/prompts\";\nimport {\n ConfigManager,\n StateDB,\n NotionClient,\n SyncOrchestrator,\n NodeVaultFS,\n ConflictResolver,\n} from \"@im-nobsidian/core\";\nimport type { Conflict, ResolutionChoice } from \"@im-nobsidian/core\";\n\nexport const resolveCommand = new Command(\"resolve\")\n .description(\"충돌을 해결합니다\")\n .option(\"-s, --strategy <strategy>\", \"자동 해결 전략 (local-first, remote-first, duplicate)\")\n .action(async (options: { strategy?: string }) => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n\n try {\n const config = await configManager.load();\n const stateDb = StateDB.open(configManager.dbPath);\n const client = new NotionClient({\n token: config.notion.token,\n concurrency: 3,\n timeoutMs: 30000,\n });\n const vaultFs = new NodeVaultFS(cwd, config.paths);\n\n const orchestrator = new SyncOrchestrator(config, stateDb, client, vaultFs);\n const resolver = new ConflictResolver(stateDb, vaultFs);\n\n await orchestrator.status();\n const conflictRecords = stateDb.getByStatus(\"conflict\");\n\n if (conflictRecords.length === 0) {\n console.log(\"충돌이 없습니다.\");\n stateDb.close();\n return;\n }\n\n console.log(`\\n충돌 ${conflictRecords.length}건 발견\\n`);\n\n if (options.strategy) {\n const strategy = options.strategy as \"local-first\" | \"remote-first\" | \"duplicate\";\n const shouldProceed = await confirm({\n message: `${conflictRecords.length}건의 충돌을 '${strategy}' 전략으로 일괄 해결할까요?`,\n });\n\n if (!shouldProceed) {\n stateDb.close();\n return;\n }\n\n const pullResult = await orchestrator.pull();\n const results = await resolver.resolveAll(pullResult.conflicts, strategy);\n\n for (const result of results) {\n const icon = result.success ? \"\\x1b[32m✓\\x1b[0m\" : \"\\x1b[31m✗\\x1b[0m\";\n console.log(` ${icon} ${result.path} → ${result.choice}`);\n }\n } else {\n const pullResult = await orchestrator.pull();\n\n for (const conflict of pullResult.conflicts) {\n await resolveInteractive(conflict, resolver);\n }\n }\n\n stateDb.close();\n console.log(\"\\n충돌 해결 완료\");\n } catch (error) {\n console.error(\"오류:\", error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n });\n\nasync function resolveInteractive(conflict: Conflict, resolver: ConflictResolver): Promise<void> {\n const path = conflict.syncRecord.obsidianPath;\n\n console.log(`\\n${\"─\".repeat(60)}`);\n console.log(`파일: \\x1b[1m${path}\\x1b[0m`);\n console.log(`${\"─\".repeat(60)}`);\n\n const diff = resolver.generateDiff(conflict);\n const diffLines = diff.split(\"\\n\");\n for (const line of diffLines) {\n if (line.startsWith(\"- \")) {\n console.log(`\\x1b[31m${line}\\x1b[0m`);\n } else if (line.startsWith(\"+ \")) {\n console.log(`\\x1b[32m${line}\\x1b[0m`);\n } else if (line.startsWith(\"---\") || line.startsWith(\"+++\")) {\n console.log(`\\x1b[1m${line}\\x1b[0m`);\n } else {\n console.log(line);\n }\n }\n\n const choice = await select<ResolutionChoice>({\n message: \"어떻게 해결할까요?\",\n choices: [\n { name: \"로컬 유지 (Obsidian 버전 유지)\", value: \"local\" },\n { name: \"원격 유지 (Notion 버전으로 덮어쓰기)\", value: \"remote\" },\n { name: \"자동 병합 (3-way merge)\", value: \"merge\" },\n { name: \"복제 (원본 유지 + .conflict 파일 생성)\", value: \"duplicate\" },\n ],\n });\n\n const result = await resolver.resolve(conflict, choice);\n\n if (result.success) {\n console.log(`\\x1b[32m✓ ${path} → ${choice}로 해결\\x1b[0m`);\n } else if (result.mergeHadConflicts) {\n console.log(`\\x1b[33m⚠ ${path} → 자동 병합 완료 (수동 확인 필요한 충돌 마커 있음)\\x1b[0m`);\n } else {\n console.log(`\\x1b[31m✗ ${path} → 해결 실패\\x1b[0m`);\n }\n}\n","import { Command } from \"commander\";\nimport {\n ConfigManager,\n StateDB,\n NotionClient,\n SyncOrchestrator,\n NodeVaultFS,\n WatchSyncService,\n} from \"@im-nobsidian/core\";\nimport type { SyncResult } from \"@im-nobsidian/core\";\n\nfunction formatResult(result: SyncResult): string {\n const pull = `Pull: +${result.pull.created} ~${result.pull.updated} -${result.pull.deleted}`;\n const push = `Push: +${result.push.created} ~${result.push.updated} -${result.push.deleted}`;\n const parts = [pull, push];\n\n if (result.conflicts.length > 0) {\n parts.push(`충돌 ${result.conflicts.length}건`);\n }\n\n return parts.join(\" | \");\n}\n\nfunction timestamp(): string {\n return new Date().toLocaleTimeString(\"ko-KR\", { hour12: false });\n}\n\nexport const watchCommand = new Command(\"watch\")\n .description(\"파일 변경 감지 + 자동 동기화\")\n .option(\"-d, --debounce <ms>\", \"디바운스 대기 시간(ms)\", \"2000\")\n .option(\"-i, --interval <seconds>\", \"풀 동기화 주기(초, 0이면 비활성)\", \"0\")\n .action(async (options: { debounce: string; interval: string }) => {\n const cwd = process.cwd();\n const configManager = new ConfigManager(cwd);\n const config = await configManager.load();\n const stateDb = StateDB.open(configManager.dbPath);\n\n const client = new NotionClient({\n token: config.notion.token,\n concurrency: config.advanced.concurrency,\n timeoutMs: config.advanced.timeoutMs,\n });\n const vaultFs = new NodeVaultFS(cwd, config.paths);\n const orchestrator = new SyncOrchestrator(config, stateDb, client, vaultFs);\n\n const debounceMs = parseInt(options.debounce, 10);\n const intervalSec = parseInt(options.interval, 10);\n\n const service = new WatchSyncService(cwd, orchestrator, {\n debounceMs,\n onFileChange: (event, path) => {\n console.log(`[${timestamp()}] ${event}: ${path}`);\n },\n onSyncStart: () => {\n console.log(`[${timestamp()}] 동기화 시작...`);\n },\n onSyncComplete: (result) => {\n console.log(`[${timestamp()}] 동기화 완료 — ${formatResult(result)}`);\n },\n onSyncError: (error) => {\n console.error(`[${timestamp()}] 동기화 실패: ${error.message}`);\n },\n });\n\n let pullTimer: ReturnType<typeof setInterval> | null = null;\n\n const shutdown = async (): Promise<void> => {\n console.log(`\\n[${timestamp()}] 감시 종료 중...`);\n if (pullTimer) clearInterval(pullTimer);\n await service.stop();\n stateDb.close();\n console.log(`[${timestamp()}] 종료 완료`);\n process.exit(0);\n };\n\n process.on(\"SIGINT\", () => void shutdown());\n process.on(\"SIGTERM\", () => void shutdown());\n\n service.start();\n console.log(`[${timestamp()}] 파일 감시 시작 (debounce: ${debounceMs}ms)`);\n\n if (intervalSec > 0) {\n console.log(`[${timestamp()}] 풀 동기화 주기: ${intervalSec}초`);\n pullTimer = setInterval(async () => {\n if (service.isSyncing()) return;\n try {\n console.log(`[${timestamp()}] 주기적 동기화 시작...`);\n const result = await orchestrator.sync();\n console.log(`[${timestamp()}] 주기적 동기화 완료 — ${formatResult(result)}`);\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error(`[${timestamp()}] 주기적 동기화 실패: ${msg}`);\n }\n }, intervalSec * 1000);\n }\n\n await new Promise(() => {});\n });\n"],"mappings":"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","names":["Command","chalk","chalk","spinner","Command","ConfigManager","NotionClient","chalk","Command","ConfigManager","NotionClient","chalk","Command","ConfigManager","StateDB","NotionClient","SyncOrchestrator","NodeVaultFS","chalk","Command","ConfigManager","StateDB","NotionClient","NodeVaultFS","SyncOrchestrator","chalk","Command","ConfigManager","StateDB","NotionClient","SyncOrchestrator","NodeVaultFS","chalk","Command","ConfigManager","StateDB","NotionClient","NodeVaultFS","SyncOrchestrator","chalk","Command","ConfigManager","StateDB","NotionClient","SyncOrchestrator","NodeVaultFS","chalk","Command","ConfigManager","StateDB","NotionClient","NodeVaultFS","SyncOrchestrator","chalk","Command","ConfigManager","StateDB","NotionClient","SyncOrchestrator","NodeVaultFS","Command","ConfigManager","StateDB","NotionClient","SyncOrchestrator","NodeVaultFS","chalk","Command","ConfigManager","StateDB","NotionClient","NodeVaultFS","SyncOrchestrator","chalk","Command","confirm","ConfigManager","StateDB","NotionClient","SyncOrchestrator","NodeVaultFS","Command","ConfigManager","StateDB","NotionClient","SyncOrchestrator","NodeVaultFS","Command"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "im-nobsidian",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "CLI tool for Obsidian ↔ Notion bidirectional sync",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"commander": "^12.0.0",
|
|
17
17
|
"diff": "^9.0.0",
|
|
18
18
|
"ora": "^8.0.0",
|
|
19
|
-
"@im-nobsidian/core": "0.1.
|
|
19
|
+
"@im-nobsidian/core": "0.1.9"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/diff": "^8.0.0",
|