Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/twenty-bugs-peel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@syncdown/cli": patch
---

Add a confirmed `syncdown reset --yes` command and expose app data reset from the TUI advanced menu while keeping synced Markdown output intact.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,18 @@ syncdown connectors
syncdown doctor
syncdown run
syncdown run --watch
syncdown reset --yes
syncdown update --check
```

Use `syncdown config set <key> <value>` and `syncdown config unset <key>` for non-interactive configuration.

Reset local app data without touching synced Markdown output:

```sh
syncdown reset --yes
```

## Connectors

`syncdown` currently supports:
Expand Down
56 changes: 56 additions & 0 deletions apps/cli/src/program.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,17 @@ function createAppStub(
options: {
inspect?: () => Promise<AppSnapshot>;
run?: (options?: RunOptions) => Promise<number>;
reset?: () => Promise<number>;
listConnectors?: () => Promise<number>;
doctor?: () => Promise<number>;
} = {},
): {
app: SyncdownApp;
runCalls: RunOptions[];
resetCalls: number;
} {
const runCalls: RunOptions[] = [];
let resetCalls = 0;

return {
app: {
Expand All @@ -206,6 +209,10 @@ function createAppStub(
runCalls.push(runOptions ?? {});
return options.run ? options.run(runOptions) : EXIT_CODES.OK;
},
async reset() {
resetCalls += 1;
return options.reset ? options.reset() : EXIT_CODES.OK;
},
async listConnectors() {
if (options.listConnectors) {
return options.listConnectors();
Expand All @@ -220,6 +227,9 @@ function createAppStub(
},
},
runCalls,
get resetCalls() {
return resetCalls;
},
};
}

Expand Down Expand Up @@ -806,6 +816,52 @@ test("run rejects an invalid watch interval", async () => {
expect(errors[0] ?? "").toMatch(/--interval must be one of/);
});

test("reset dispatches to app.reset when --yes is provided", async () => {
const { io, errors } = createIoCapture();
const stub = createAppStub();

const exitCode = await runTestCli(
["syncdown", "syncdown", "reset", "--yes"],
{
app: stub.app,
io,
secrets: createSecretsStub(),
},
);

expect(exitCode).toBe(EXIT_CODES.OK);
expect(stub.resetCalls).toBe(1);
expect(errors).toEqual([]);
});

test("reset requires --yes and rejects extra arguments", async () => {
const { io, errors } = createIoCapture();
const stub = createAppStub();

const missingConfirmationExitCode = await runTestCli(
["syncdown", "syncdown", "reset"],
{
app: stub.app,
io,
secrets: createSecretsStub(),
},
);

const extraArgumentExitCode = await runTestCli(
["syncdown", "syncdown", "reset", "--yes", "--force"],
{
app: stub.app,
io,
secrets: createSecretsStub(),
},
);

expect(missingConfirmationExitCode).toBe(EXIT_CODES.CONFIG_ERROR);
expect(extraArgumentExitCode).toBe(EXIT_CODES.CONFIG_ERROR);
expect(stub.resetCalls).toBe(0);
expect(errors).toContain("Usage: syncdown reset --yes");
});

test("run rejects --reset with --watch", async () => {
const { io, errors } = createIoCapture();
const { app, runCalls } = createAppStub();
Expand Down
20 changes: 20 additions & 0 deletions apps/cli/src/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ function getHelpLines(): string[] {
" syncdown run --integration <integration-id>",
" syncdown run --reset [--connector <notion|gmail|google-calendar>|--integration <integration-id>]",
" syncdown run --watch [--interval <5m|15m|1h|6h|24h>]",
" syncdown reset --yes",
" syncdown connectors",
" syncdown doctor",
" syncdown update",
Expand Down Expand Up @@ -191,6 +192,10 @@ function printUpdateUsage(io: AppIo): void {
io.error("Usage: syncdown update [--check]");
}

function printResetUsage(io: AppIo): void {
io.error("Usage: syncdown reset --yes");
}

function isInteractiveTerminal(): boolean {
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
}
Expand Down Expand Up @@ -874,6 +879,19 @@ async function handleUpdateCommand(
}
}

async function handleResetCommand(
io: AppIo,
args: string[],
app: SyncdownApp,
): Promise<number> {
if (args.length !== 1 || args[0] !== "--yes") {
printResetUsage(io);
return EXIT_CODES.CONFIG_ERROR;
}

return app.reset(io);
}

function shouldRunAutoUpdateCheck(command: string | undefined): boolean {
return (
command !== undefined &&
Expand Down Expand Up @@ -945,6 +963,8 @@ export async function runCli(
}
return app.run(io, runOptions);
}
case "reset":
return handleResetCommand(io, argv.slice(3), app);
case "connectors":
return app.listConnectors(io);
case "doctor":
Expand Down
19 changes: 19 additions & 0 deletions apps/docs/content/docs/cli.ja.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ syncdown run --connector <notion|gmail|google-calendar>
syncdown run --integration <integration-id>
syncdown run --reset [--connector <notion|gmail|google-calendar>|--integration <integration-id>]
syncdown run --watch [--interval <5m|15m|1h|6h|24h>]
syncdown reset --yes
syncdown connectors
syncdown doctor
syncdown update
Expand Down Expand Up @@ -111,6 +112,24 @@ syncdown run --watch
syncdown run --watch --interval 15m
```

## `syncdown reset --yes`

ローカルの syncdown アプリデータを一括で削除します。

```sh
syncdown reset --yes
```

削除対象:

- `config.json`
- `state.db`
- `secrets.enc`
- `master.key`
- `sync.lock`

設定済み `outputDir` 配下の同期済み Markdown 出力は削除しません。

## `syncdown connectors`

各 integration について次を一覧表示します。
Expand Down
19 changes: 19 additions & 0 deletions apps/docs/content/docs/cli.ko.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ syncdown run --connector <notion|gmail|google-calendar>
syncdown run --integration <integration-id>
syncdown run --reset [--connector <notion|gmail|google-calendar>|--integration <integration-id>]
syncdown run --watch [--interval <5m|15m|1h|6h|24h>]
syncdown reset --yes
syncdown connectors
syncdown doctor
syncdown update
Expand Down Expand Up @@ -111,6 +112,24 @@ syncdown run --watch
syncdown run --watch --interval 15m
```

## `syncdown reset --yes`

로컬 syncdown 앱 데이터를 한 번에 삭제합니다.

```sh
syncdown reset --yes
```

다음 파일이 제거됩니다.

- `config.json`
- `state.db`
- `secrets.enc`
- `master.key`
- `sync.lock`

설정된 `outputDir` 아래의 동기화된 Markdown 출력은 삭제하지 않습니다.

## `syncdown connectors`

각 integration에 대해 다음을 나열합니다.
Expand Down
19 changes: 19 additions & 0 deletions apps/docs/content/docs/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ syncdown run --connector <notion|gmail|google-calendar>
syncdown run --integration <integration-id>
syncdown run --reset [--connector <notion|gmail|google-calendar>|--integration <integration-id>]
syncdown run --watch [--interval <5m|15m|1h|6h|24h>]
syncdown reset --yes
syncdown connectors
syncdown doctor
syncdown update
Expand Down Expand Up @@ -112,6 +113,24 @@ syncdown run --watch
syncdown run --watch --interval 15m
```

## `syncdown reset --yes`

Delete local syncdown app data in one step:

```sh
syncdown reset --yes
```

This removes:

- `config.json`
- `state.db`
- `secrets.enc`
- `master.key`
- `sync.lock`

It does not remove synced Markdown output under your configured `outputDir`.

## `syncdown connectors`

Lists each integration with:
Expand Down
19 changes: 19 additions & 0 deletions apps/docs/content/docs/cli.zh-CN.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ syncdown run --connector <notion|gmail|google-calendar>
syncdown run --integration <integration-id>
syncdown run --reset [--connector <notion|gmail|google-calendar>|--integration <integration-id>]
syncdown run --watch [--interval <5m|15m|1h|6h|24h>]
syncdown reset --yes
syncdown connectors
syncdown doctor
syncdown update
Expand Down Expand Up @@ -111,6 +112,24 @@ syncdown run --watch
syncdown run --watch --interval 15m
```

## `syncdown reset --yes`

一次性删除本地 syncdown 应用数据。

```sh
syncdown reset --yes
```

会删除以下文件:

- `config.json`
- `state.db`
- `secrets.enc`
- `master.key`
- `sync.lock`

不会删除已配置 `outputDir` 下的已同步 Markdown 输出。

## `syncdown connectors`

列出每个 integration 的:
Expand Down
7 changes: 7 additions & 0 deletions docs/readme/README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,18 @@ syncdown connectors
syncdown doctor
syncdown run
syncdown run --watch
syncdown reset --yes
syncdown update --check
```

非対話型の設定には `syncdown config set <key> <value>` と `syncdown config unset <key>` を使います。

同期済み Markdown 出力はそのままにして、ローカルアプリデータだけを初期化するには:

```sh
syncdown reset --yes
```

## Connectors

現在 `syncdown` が対応しているソースは次のとおりです。
Expand Down
7 changes: 7 additions & 0 deletions docs/readme/README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,18 @@ syncdown connectors
syncdown doctor
syncdown run
syncdown run --watch
syncdown reset --yes
syncdown update --check
```

비대화형 설정에는 `syncdown config set <key> <value>` 와 `syncdown config unset <key>` 를 사용합니다.

동기화된 Markdown 출력은 그대로 둔 채 로컬 앱 데이터만 초기화하려면:

```sh
syncdown reset --yes
```

## Connectors

현재 `syncdown`이 지원하는 소스는 다음과 같습니다.
Expand Down
7 changes: 7 additions & 0 deletions docs/readme/README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,18 @@ syncdown connectors
syncdown doctor
syncdown run
syncdown run --watch
syncdown reset --yes
syncdown update --check
```

如需非交互式配置,可使用 `syncdown config set <key> <value>` 和 `syncdown config unset <key>`。

如果你想在保留已同步 Markdown 输出的同时,仅重置本地应用数据:

```sh
syncdown reset --yes
```

## Connectors

当前 `syncdown` 支持:
Expand Down
Loading
Loading