Skip to content
Merged
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
104 changes: 104 additions & 0 deletions plugins/notion-cli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Notion CLI Plugin Harness

This plugin integrates [4ier/notion-cli](https://github.com/4ier/notion-cli) into dcli. It wraps the most agent-friendly Notion commands and provides a full namespace passthrough for the upstream CLI.

## Prerequisites

A Notion integration token is required. Create one at https://www.notion.so/profile/integrations and authenticate:

```bash
echo "ntn_xxxxx" | notion auth login --with-token
# or
export NOTION_TOKEN=ntn_xxxxx
```

Verify the binary is available:

```bash
notion --version
```

## Installation

`go install` builds a binary named `notion-cli`. Symlink or rename it to `notion`:

```bash
go install github.com/4ier/notion-cli@latest
GOBIN=$(go env GOBIN); GOPATH=$(go env GOPATH); ln -sf "${GOBIN:-$GOPATH/bin}/notion-cli" "${GOBIN:-$GOPATH/bin}/notion"
```

Other install methods include Homebrew (`brew install 4ier/tap/notion-cli`), npm (`npm install -g @4ier/notion-cli`), GitHub Releases, or Scoop on Windows.

## Available Commands

### Version

```bash
dcli notion self version --json
```

### Auth

```bash
dcli notion auth status --json
```

### Search

```bash
dcli notion search run "meeting notes" --json
```

### Pages

```bash
dcli notion page list --json
dcli notion page view <pageId> --json
dcli notion page create <dbId> --db "Name=Task" --db "Status=Todo" --json

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== repo files =="
git ls-files | rg '(^|/)plugins/notion-cli/(README\.md|plugin\.json|.*\.(js|ts|zig|mfl|sh))$|(^|/)notion-cli/README\.md$|notion.*README' || true

echo
echo "== notion plugin README around line 57 =="
if [ -f plugins/notion-cli/README.md ]; then
  nl -ba plugins/notion-cli/README.md | sed -n '45,70p'
fi

echo
echo "== local references to notion_cli/notion/page create/db =="
rg -n "notion|dbId|page create|--db|Status=Todo|Name=Task" . --glob '*.{md,js,ts,jsx,tsx,zig,mfl,sh,json}' || true

echo
echo "== plugin metadata =="
if [ -f plugins/notion-cli/plugin.json ]; then
  cat plugins/notion-cli/plugin.json
fi

Repository: javimosch/supercli

Length of output: 317


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== check local package availability without executing repo code =="
python3 - <<'PY'
import importlib.util, subprocess, sys
specs = ["notion_cli", "notion"]
for name in specs:
    spec = importlib.util.find_spec(name)
    print(f"{name}: {spec.origin if spec else 'not found'}")
PY

echo
echo "== inspect installed package docs/help if present =="
python3 - <<'PY'
import subprocess
for cmd in [
    ["python", "-m", "justcode.notion_cli", "-h"],
    ["python", "-m", "justcode.notion_cli", "--help"],
]:
    try:
        r = subprocess.run(cmd, text=True, capture_output=True, timeout=10)
        print("CMD:", " ".join(cmd), "EXIT", r.returncode)
        out = (r.stdout + r.stderr).strip()
        for line in out.splitlines()[:120]:
            print(line)
    except Exception as e:
        print("CMD:", " ".join(cmd), "ERROR", repr(e))
PY

echo
echo "== search for --db in installed files if package present =="
python3 - <<'PY'
import importlib.util, glob, os
spec = importlib.util.find_spec("justcode.notion_cli")
if spec and spec.submodule_search_locations:
    roots = spec.submodule_search_locations
    for root in roots:
        files = glob.glob(os.path.join(root, "**", "*.py"), recursive=True)
        matches = []
        for f in files:
            txt = open(f, encoding="utf-8", errors="replace").read()
            if "--db" in txt or "db argument" in txt.lower():
                matches.append(f)
        print("MATCHES:", "\n".join(matches))
        for f in matches:
            txt = open(f, encoding="utf-8", errors="replace").read().splitlines()
            for i,line in enumerate(txt,1):
                if "--db" in line or "db argument" in line.lower():
                    start=max(1,i-5); end=min(len(txt),i+15)
                    print(f"\n## {f}:{start}-{end}")
                    for j in range(start,end+1):
                        print(f"{j}: {txt[j-1]}")
PY

Repository: javimosch/supercli

Length of output: 992


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== repo files =="
git ls-files | rg '(^|/)plugins/notion-cli/(README\.md|plugin\.json|.*\.(js|ts|zig|mfl|sh))$|(^|/)notion-cli/README\.md$|notion.*README' || true

echo
echo "== notion plugin README around line 57 =="
if [ -f plugins/notion-cli/README.md ]; then
  nl -ba plugins/notion-cli/README.md | sed -n '45,70p'
fi

echo
echo "== local references to notion_cli/notion/page create/db =="
rg -n "notion|dbId|page create|--db|Status=Todo|Name=Task" . --glob '*.{md,js,ts,jsx,tsx,zig,mfl,sh,json}' || true

echo
echo "== plugin metadata =="
if [ -f plugins/notion-cli/plugin.json ]; then
  cat plugins/notion-cli/plugin.json
fi

echo
echo "== check local package availability without executing repo code =="
python3 - <<'PY'
import importlib.util
specs = ["justcode.notion_cli", "notion_cli", "notion"]
for name in specs:
    spec = importlib.util.find_spec(name)
    print(f"{name}: {spec.origin if spec else 'not found'}")
PY

echo
echo "== inspect installed package docs/help if present =="
python3 - <<'PY'
import subprocess
for cmd in [
    ["python", "-m", "justcode.notion_cli", "-h"],
    ["python", "-m", "justcode.notion_cli", "--help"],
]:
    try:
        r = subprocess.run(cmd, text=True, capture_output=True, timeout=10)
        print("CMD:", " ".join(cmd), "EXIT", r.returncode)
        out = (r.stdout + r.stderr).strip()
        for line in out.splitlines()[:120]:
            print(line)
    except Exception as e:
        print("CMD:", " ".join(cmd), "ERROR", repr(e))
PY

echo
echo "== search for --db in installed files =="
python3 - <<'PY'
import importlib.util, glob, os
spec = importlib.util.find_spec("justcode.notion_cli")
if spec and spec.submodule_search_locations:
    for root in spec.submodule_search_locations:
        for f in glob.glob(os.path.join(root, "**", "*.py"), recursive=True):
            txt = open(f, encoding="utf-8", errors="replace").read()
            if "--db" in txt or "db argument" in txt.lower():
                lines = txt.splitlines()
                for i,line in enumerate(lines,1):
                    if "--db" in line or "db argument" in line.lower():
                        start=max(1,i-5); end=min(len(lines),i+15)
                        print(f"\n## {f}:{start}-{end}")
                        for j in range(start,end+1):
                            print(f"{j}: {lines[j-1]}")
PY

Repository: javimosch/supercli

Length of output: 317


🌐 Web query:

github 4ier notion-cli README page create --db properties syntax

💡 Result:

For the notion-cli developed by 4ier (available at github.com/4ier/notion-cli), page creation in a database involves two primary methods for handling properties: the standard Notion API JSON format and a simplified key-value syntax [1][2][3]. Standard API Syntax To create a page with full control over the Notion API structure, you pass a JSON object to the --properties flag [4]. This requires following the official Notion API schema, where each property is explicitly defined by its type [4]: notion page create --properties '{"Name": {"title": [{"text": {"content": "New Page"}}]}, "Status": {"select": {"name": "Done"}}}' Simplified Property Syntax The tool supports a simplified property mode using the -S or --simple-properties flag [5][6]. This mode allows you to pass a flat JSON object, which the CLI maps to the database schema automatically, significantly reducing the complexity of the command [5][6]. Usage with simple properties: notion page create -S --properties '{"Name": "Task Title", "Status": "Done", "Priority": 5}' [2][6] Key advantages of simple properties: - Flat Structure: Uses straightforward key-value pairs (e.g., string, number, boolean) instead of nested API objects [5][6]. - Type Detection: The CLI fetches the database schema to automatically validate and map property types [3][5]. - AI-Friendly: This format is designed for programmatic access and AI agents, minimizing errors associated with the verbose standard API structure [5][6]. For additional context, you can use the notion db schema command to inspect the available property names and types in your target database before creating pages [5][4].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== notion README section using sed =="
sed -n '45,70p' plugins/notion-cli/README.md | cat -n

echo
echo "== plugin manifest =="
cat plugins/notion-cli/plugin.json | sed -n '1,160p'

echo
echo "== local references to notion "--db" syntax =="
rg -n "notion|page create|--db|-- properties|properties|simple-properties|simple_properties|Status=Todo|Name=Task" . --glob '*.{md,js,ts,jsx,tsx,zig,mfl,sh,json}' || true

echo
echo "== inspect upstream notion-cli command docs via git URL =="
python3 - <<'PY'
import urllib.request
urls = [
    "https://raw.githubusercontent.com/4ier/notion-cli/main/README.md",
    "https://raw.githubusercontent.com/4ier/notion-cli/main/commands/page.go",
    "https://raw.githubusercontent.com/4ier/notion-cli/main/commands/page_create.go",
    "https://raw.githubusercontent.com/4ier/notion-cli/main/commands/page.go",
]
for url in urls:
    print(f"\n## {url}")
    try:
        data = urllib.request.urlopen(url, timeout=15, data=None).read().decode("utf-8", "replace")
    except Exception as e:
        print("FETCH_ERROR", repr(e))
        continue
    hits = [i for i,line in enumerate(data.splitlines(),1) if ("page create" in line or "--db" in line or "db" in line.lower())][:240]
    for i,line in enumerate(data.splitlines(),1):
        if i in hits:
            print(f"{i}: {line}")
        if len(hits) > 30:
            hit_set = set(hits)
            nearby = sorted(set(range(1, len(data.splitlines())+1)) & set(t for i in hits for t in range(max(1,i-20), i+21)))
            hit_set = set(nearby)
            if i in hit_set and i not in hits:
                continue
PY

Repository: javimosch/supercli

Length of output: 50376


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== notion README section =="
sed -n '45,70p' plugins/notion-cli/README.md

echo
echo "== plugin manifest =="
cat plugins/notion-cli/plugin.json

echo
echo "== local references to notion command syntax =="
rg -n "notion|page create|--db|--properties|-S|simple-properties|Status=Todo|Name=Task" . --glob '*.{md,js,ts,jsx,tsx,zig,mfl,sh,json}' || true

Repository: javimosch/supercli

Length of output: 50376


🌐 Web query:

github.com/4ier/notion-cli page create --db command

💡 Result:

In the 4ier/notion-cli package, the command to create a page within a database is executed using the notion page create command followed by the database ID and the --db flag [1][2]. The syntax is: notion page create --db "PropertyName=Value" "PropertyName2=Value2" For example, to create a row in a database with specific property values: notion page create --db "Name=Sprint Review" "Date=2026-03-01" "Points=8" "Done=true" Key details: - The is the unique identifier of the target database [1][3]. - The --db flag is used specifically for database page creation, allowing you to define property values in a key=value format [1][4]. - This CLI tool automatically handles schema awareness, detecting property types based on the target database schema [5]. Be sure to distinguish this tool from others with similar names (e.g., notion-cli by henryreith or FroeMic), as their command syntax differs [6][7][8]. The 4ier/notion-cli documentation consistently specifies the command structure above [1][2][9].

Citations:


Use one --db option for multiple properties.

Line 57 repeats --db, but the notion page create syntax accepts one --db followed by additional Name=Value values.

Proposed correction
-dcli notion page create <dbId> --db "Name=Task" --db "Status=Todo" --json
+dcli notion page create <dbId> --db "Name=Task" "Status=Todo" --json
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
dcli notion page create <dbId> --db "Name=Task" --db "Status=Todo" --json
dcli notion page create <dbId> --db "Name=Task" "Status=Todo" --json
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/notion-cli/README.md` at line 57, Update the notion page create
example to use a single --db option followed by both Name=Task and Status=Todo
property values, matching the command’s accepted syntax.

```

### Databases

```bash
dcli notion db list --json
dcli notion db query <dbId> --filter "Status=Done" --sort "Date:desc" --json
```

### Blocks

```bash
dcli notion block list <pageId> --md --depth 3 --json
dcli notion block append <pageId> --file document.md --json
```

### Users

```bash
dcli notion user list --json
```

### Raw API Requests

```bash
dcli notion api request GET /v1/users/me --json
```

### Full Passthrough

Run any upstream notion command through the `notion` namespace:

```bash
dcli notion _ _ -- --help
```

## Output

Wrapped commands return a dcli JSON envelope when `--json` is used. The upstream CLI auto-detects JSON output when piped.

## Key Features

- Full Notion API coverage in a single binary
- JSON output when piped, colored tables in terminal
- Schema-aware database queries with human-friendly filters
- Markdown I/O for reading and writing page content
- URL or ID support for pages and databases
Loading