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
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ openclaw plugins install npm:@ssntpl/openclaw-otper

## Configure

Two ways — either works, plugin config takes precedence:
Generate a personal access token at **https://otper.com/settings/tokens**, then provide it via any one of these (resolved in order):

**1. Plugin config** (preferred):
**1. Plugin config**:

```json
{
Expand All @@ -34,14 +34,21 @@ Two ways — either works, plugin config takes precedence:
}
```

**2. Environment variables** (handy for CI / one-off runs):
**2. Environment variables**:

```sh
export OTPER_TOKEN="238|..."
export OTPER_BASE_URL="https://otper.com" # optional, defaults to https://otper.com
```

Generate a token from your Otper account settings.
**3. Reuse [`otper-cli`](https://github.com/ssntpl/otper-cli)'s saved login**:

```sh
npm install -g @ssntpl/otper-cli
otper auth:login # writes ~/.otper-cli/default/config.json
```

If you already use `otper-cli`, no extra setup is needed — the plugin reads the same config file.

## Tools

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ssntpl/openclaw-otper",
"version": "0.1.1",
"version": "0.1.2",
"description": "OpenClaw plugin for Otper boards (https://otper.com) — exposes Otper boards, lists, cards, labels, comments, and today's priorities as agent tools.",
"author": "SSNTPL <info@ssntpl.com>",
"license": "MIT",
Expand Down
30 changes: 21 additions & 9 deletions tools/shared.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
import { OtperClient, DEFAULT_BASE_URL } from "@ssntpl/otper-cli";
import { OtperClient, resolveConfig } from "@ssntpl/otper-cli";

export interface PluginConfig {
token?: string;
baseUrl?: string;
}

/**
* Build an OtperClient from the openclaw plugin config, falling back to
* the same env vars the otper-cli uses (OTPER_TOKEN, OTPER_BASE_URL).
* Throws a clear, agent-readable error if no token can be resolved.
* Build an OtperClient using otper-cli's standard resolution chain:
* 1. Plugin config (token / baseUrl from openclaw plugin settings)
* 2. Environment vars (OTPER_TOKEN / OTPER_BASE_URL)
* 3. otper-cli's saved credentials at ~/.otper-cli/<profile>/config.json
* (created by `otper auth:login`)
*
* Sharing the resolution with otper-cli means a single login serves
* both the CLI and this plugin.
*/
export function clientFor(config: PluginConfig | undefined): OtperClient {
const token = config?.token ?? process.env.OTPER_TOKEN;
const baseUrl = config?.baseUrl ?? process.env.OTPER_BASE_URL ?? DEFAULT_BASE_URL;
if (!token) {
try {
const cfg = resolveConfig({
token: config?.token,
baseUrl: config?.baseUrl,
});
return OtperClient.fromConfig(cfg);
} catch {
throw new Error(
"Otper is not configured. Set the plugin's `token` config or the OTPER_TOKEN environment variable.",
"Otper is not configured. Provide a token via the openclaw plugin " +
"config, the OTPER_TOKEN environment variable, or by running " +
"`otper auth:login` to save credentials at " +
"~/.otper-cli/<profile>/config.json. Generate a personal access " +
"token at https://otper.com/settings/tokens.",
);
}
return new OtperClient({ baseUrl, token });
}

export type TextContent = { type: "text"; text: string };
Expand Down
Loading