.
This commit is contained in:
@@ -1,101 +1,136 @@
|
||||
# Nostr Publish
|
||||
|
||||
A Codium / VSCode extension to publish files to Nostr.
|
||||
A Codium / VSCode extension to publish files to [Nostr](https://github.com/nostr-protocol/nostr).
|
||||
|
||||
## Phases
|
||||
Publish markdown articles as long-form notes, broadcast raw Nostr events from JSON, and sign everything with either a local key or a remote [`n_signer`](https://laantungir.net/git/laantungir/n_signer.git) hardware signer.
|
||||
|
||||
- **Phase 0**: Publish raw unsigned Nostr events from a `.json` file.
|
||||
Generate a skeleton event, fill in the fields, validate, sign, and broadcast.
|
||||
- **Phase 1**: Publish `.md` files as NIP-23 long-form notes
|
||||
(kind `30023`) with YAML front-matter metadata.
|
||||
- **Phase 2**: Delegate signing to a running
|
||||
[`n_signer`](https://laantungir.net/git/laantungir/n_signer.git) process
|
||||
over a Linux abstract Unix socket.
|
||||
## Features
|
||||
|
||||
See [`plans/`](plans/) for the full design:
|
||||
- [`plans/phase0-raw-event-publishing.md`](plans/phase0-raw-event-publishing.md)
|
||||
- [`plans/longform-metadata-strategy.md`](plans/longform-metadata-strategy.md)
|
||||
- [`plans/implementation-plan.md`](plans/implementation-plan.md)
|
||||
- **Publish markdown as long-form notes** — Write a `.md` file with YAML front-matter (title, summary, image, tags), click one button, and it's broadcast as a NIP-23 kind-30023 event to your relays.
|
||||
- **Publish raw events from JSON** — Create a Nostr event skeleton (text note, relay list, profile, contacts, or custom kind), fill in the fields, and publish.
|
||||
- **Multiple signing backends**:
|
||||
- **Local** — enter your `nsec` or hex key; held in memory only, never written to disk.
|
||||
- **n_signer (Unix socket)** — delegate signing to a local `n_signer` process over an abstract Unix socket. Your key never leaves the signer.
|
||||
- **n_signer (Qubes qrexec)** — reach `n_signer` in another qube via Qubes OS secure IPC.
|
||||
- **n_signer (TCP)** — reach `n_signer` over TCP (FIPS mesh, remote machine). Requires a caller key for auth envelopes.
|
||||
- **Sidebar GUI** — sign in, manage relays, create events, and publish — all from the Nostr sidebar in the Activity Bar.
|
||||
- **NIP-65 relay auto-discovery** — on sign-in, fetches your kind 10002 relay list and uses your own relays for publishing.
|
||||
- **Avatar display** — fetches your kind 0 profile and shows your avatar + name in the sidebar.
|
||||
- **`published_at` tracking** — first-publish timestamps are stored per-workspace so updates preserve the original timestamp (NIP-23).
|
||||
|
||||
## Prerequisites
|
||||
## Install
|
||||
|
||||
1. **Node.js** ≥ 18.
|
||||
2. **The laantungir fork of `nostr-tools`** must be cloned as a sibling
|
||||
directory and built:
|
||||
### Prerequisites
|
||||
|
||||
- **Codium** or **VSCode** (≥ 1.85).
|
||||
- **Node.js** ≥ 18 (for building only — not needed at runtime).
|
||||
- **The laantungir fork of `nostr-tools`** cloned as a sibling directory and built:
|
||||
|
||||
```bash
|
||||
git clone git@laantungir.net:laantungir/nostr-tools.git ../nostr-tools
|
||||
cd ../nostr-tools
|
||||
npm install --ignore-scripts # the prepublish hook needs `just`, which we skip
|
||||
npm install --ignore-scripts
|
||||
rm -rf lib && bun run build.js # or: node build.js
|
||||
npx tsc # produces lib/types/*.d.ts
|
||||
```
|
||||
|
||||
The extension depends on it via `"nostr-tools": "file:../nostr-tools"`.
|
||||
- **For n_signer backends** (optional): the [`nsigner`](https://laantungir.net/git/laantungir/n_signer.git) binary installed and running. See the n_signer README for build instructions.
|
||||
|
||||
## Install (development)
|
||||
### Build and install
|
||||
|
||||
```bash
|
||||
git clone git@laantungir.net:laantungir/nostr-publish.git
|
||||
cd nostr-publish
|
||||
npm install
|
||||
npm run compile # esbuild -> dist/extension.js
|
||||
./install_upgrade.sh
|
||||
```
|
||||
|
||||
Press `F5` in Codium/VSCode to launch an Extension Development Host with the
|
||||
extension loaded, or package and install:
|
||||
The `install_upgrade.sh` script compiles the extension, packages it into a `.vsix`, and installs it into Codium (or VSCode) with `--force`. Restart your editor after it finishes.
|
||||
|
||||
Alternatively, build and install manually:
|
||||
|
||||
```bash
|
||||
npx vsce package # produces nostr-publish-0.1.0.vsix
|
||||
code --install-extension nostr-publish-0.1.0.vsix
|
||||
npm run compile
|
||||
npx vsce package --no-dependencies
|
||||
codium --install-extension nostr-publish-0.1.0.vsix --force
|
||||
```
|
||||
|
||||
## Phase 0 usage
|
||||
### Updating after code changes
|
||||
|
||||
### 1. Sign in
|
||||
|
||||
Run **Nostr: Sign In** from the command palette. Enter your secret key as
|
||||
`nsec1...` or 64-char hex. The key is held in memory only for the session —
|
||||
it is never written to disk. The status bar shows your `npub1...`.
|
||||
|
||||
Run **Nostr: Sign Out** to clear the key (the buffer is zeroed).
|
||||
|
||||
### 2. Create an unsigned event
|
||||
|
||||
Run **Nostr: Create Unsigned Event**. Pick a kind (1 = short text note,
|
||||
30023 = long-form article, 10002 = relay list, 0 = metadata, 3 = contacts,
|
||||
or Custom…). A skeleton JSON document opens in an untitled editor:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": 1,
|
||||
"created_at": 1721329200,
|
||||
"tags": [],
|
||||
"content": ""
|
||||
}
|
||||
```bash
|
||||
./install_upgrade.sh
|
||||
# restart Codium
|
||||
```
|
||||
|
||||
Fill in `tags` and `content`. Save it as a `.json` file if you want to reuse
|
||||
it, or publish directly from the untitled buffer.
|
||||
The script handles everything — rebuild, repackage, reinstall.
|
||||
|
||||
### 3. Validate
|
||||
## Usage
|
||||
|
||||
Run **Nostr: Validate Event File** (or right-click in a JSON editor →
|
||||
Nostr: Validate Event File). Checks the shape of the event and reports any
|
||||
errors or warnings (e.g. unknown fields, or `pubkey`/`id`/`sig` left over
|
||||
from a previously signed event).
|
||||
### 1. Open the Nostr sidebar
|
||||
|
||||
### 4. Publish
|
||||
Click the **Nostr** icon (broadcast glyph) in the Activity Bar on the left side of Codium. The sidebar has three sections:
|
||||
|
||||
Run **Nostr: Publish Event from JSON File** (or right-click → Nostr: Publish
|
||||
Event from JSON File). The extension:
|
||||
- **Actions** — create events, publish files, validate.
|
||||
- **Relays** — toggle which relays to publish to, fetch your NIP-65 relay list.
|
||||
- **Identity** — sign in, view your avatar/npub, sign out.
|
||||
|
||||
1. Validates the JSON.
|
||||
2. Signs the event with your session key (injects `pubkey`, `id`, `sig`).
|
||||
3. Shows a confirmation dialog with a preview and relay checkboxes.
|
||||
4. Broadcasts to the selected relays via WebSocket.
|
||||
5. Reports per-relay OK/failed results and the event id.
|
||||
### 2. Sign in
|
||||
|
||||
If the JSON contains `pubkey`/`id`/`sig`, they are stripped and the event is
|
||||
re-signed with your active key (useful for re-signing an event as yourself).
|
||||
In the **Identity** section, choose a sign-in method from the dropdown:
|
||||
|
||||
- **Local (nsec / hex key)** — paste your `nsec1...` or 64-char hex secret key. The key is held in memory only for the session — it's never written to disk. Sign out to clear it.
|
||||
|
||||
- **n_signer (Unix socket)** — enter the abstract socket name (default `nsigner`) and key index. Requires `nsigner --listen unix --socket-name nsigner` running on the same machine.
|
||||
|
||||
- **n_signer (Qubes qrexec)** — enter the target qube name (e.g. `nostr_signer`) and key index. Requires the `qubes.NsignerRpc` service installed in the target qube and dom0 policy allowing your qube to call it.
|
||||
|
||||
- **n_signer (TCP)** — enter host, port, your caller `nsec` (for auth envelopes), and key index. Requires `nsigner --listen tcp:<host>:<port>` running on the target machine.
|
||||
|
||||
Click **Sign In**. The extension connects to the signer, fetches your public key, displays your avatar + npub, and auto-loads your NIP-65 relay list.
|
||||
|
||||
### 3. Publish a markdown article
|
||||
|
||||
1. Click **+ New Event** → pick **30023 — Long-Form Article**. A markdown file opens with a YAML front-matter skeleton:
|
||||
|
||||
```markdown
|
||||
---
|
||||
slug: my-article-slug
|
||||
title: My Article Title
|
||||
summary: A one-sentence abstract for feeds.
|
||||
image: https://example.com/cover.png
|
||||
tags: [nostr, writing]
|
||||
---
|
||||
|
||||
# My Article Title
|
||||
|
||||
Write your article in Markdown here.
|
||||
```
|
||||
|
||||
2. Edit the front-matter (metadata) and write your article body in Markdown below the `---` line.
|
||||
|
||||
3. Click **Validate Front-Matter** to preview the metadata that will be published (dry run — nothing is sent).
|
||||
|
||||
4. Click **Publish Current File as Long-Form Note**. A confirmation dialog shows the event preview (slug, title, summary, image, tags, `published_at`, body length, pubkey, relays). Toggle relays on/off, then click **Publish**.
|
||||
|
||||
The front-matter block is stripped before publishing — readers on Nostr see only the markdown body. The file on disk keeps the front-matter for re-publishing.
|
||||
|
||||
**Re-publishing an update**: edit the file and publish again. The same `slug` (d-tag) means it's a parameterized-replaceable update — relays replace the old version. The `published_at` timestamp is preserved from the first publish (tracked per-workspace).
|
||||
|
||||
### 4. Publish a raw event from JSON
|
||||
|
||||
1. Click **+ New Event** → pick a kind (Short Text Note, Relay List, Profile, Contacts, or Custom).
|
||||
2. A JSON skeleton opens with the expected tags and placeholder content for that kind.
|
||||
3. Fill in the `content` and `tags` fields.
|
||||
4. Click **Publish Current JSON File** (or right-click in the JSON editor → Nostr: Publish Event from JSON File).
|
||||
5. Confirm in the dialog, then broadcast.
|
||||
|
||||
The JSON file is a plain Nostr `EventTemplate` — interoperable with any other Nostr tooling that accepts `EventTemplate` JSON.
|
||||
|
||||
### 5. Manage relays
|
||||
|
||||
- The **Relays** section shows your configured relays with checkboxes. Toggle individual relays on/off for the next publish.
|
||||
- Click **Fetch My Relays (NIP-65)** to load your kind 10002 relay list from the network and replace the sidebar's relay set with it.
|
||||
- Default relays: `wss://relay.damus.io`, `wss://relay.primal.net`, `wss://laantungir.net/relay`. Change them in Codium Settings → `nostr.relays`.
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -104,103 +139,68 @@ re-signed with your active key (useful for re-signing an event as yourself).
|
||||
| `nostr.relays` | `["wss://relay.damus.io", "wss://relay.primal.net", "wss://laantungir.net/relay"]` | Relays to publish to. |
|
||||
| `nostr.publish.confirm` | `true` | Show a confirmation dialog before broadcasting. |
|
||||
| `nostr.publish.timeoutMs` | `10000` | Per-relay publish timeout in milliseconds. |
|
||||
| `nostr.signerBackend` | `"local"` | `"local"` or `"nsigner"`. |
|
||||
| `nostr.nsigner.transport` | `"unix"` | `"unix"`, `"qrexec"`, or `"tcp"`. |
|
||||
| `nostr.nsigner.socketName` | `"nsigner"` | Abstract socket name (without `@`). Used when transport=unix. |
|
||||
| `nostr.nsigner.nostrIndex` | `0` | Key index (NIP-06 `m/44'/1237'/N'/0/0`). |
|
||||
| `nostr.nsigner.qrexecQube` | `"nostr_signer"` | Target qube name. Used when transport=qrexec. |
|
||||
| `nostr.nsigner.qrexecService` | `"qubes.NsignerRpc"` | Qrexec service name. |
|
||||
| `nostr.nsigner.tcpHost` | `"127.0.0.1"` | TCP host. Used when transport=tcp. |
|
||||
| `nostr.nsigner.tcpPort` | `8080` | TCP port. Used when transport=tcp. |
|
||||
| `nostr.nsigner.callerNsec` | `""` | Caller nsec for TCP auth envelopes. Required for transport=tcp if not signed in locally. |
|
||||
|
||||
## File format
|
||||
## Commands
|
||||
|
||||
The `.json` file is a plain Nostr `EventTemplate` — no extension-specific
|
||||
wrapper. It is interoperable with any other Nostr tooling that accepts
|
||||
`EventTemplate` JSON:
|
||||
| Command | Description |
|
||||
|---|---|
|
||||
| **Nostr: Sign In** | Sign in with a local nsec/hex key (InputBox prompt). |
|
||||
| **Nostr: Sign Out** | Clear the session key. |
|
||||
| **Nostr: Create Unsigned Event** | Generate a kind-specific event skeleton (JSON or markdown). |
|
||||
| **Nostr: Validate Event File** | Validate the active JSON file as a Nostr event. |
|
||||
| **Nostr: Publish Event from JSON File** | Sign and publish the active JSON file. |
|
||||
| **Nostr: Publish Current File as Long-Form Note** | Parse front-matter, build a NIP-23 event, sign, and publish. |
|
||||
| **Nostr: Validate Front-Matter** | Dry-run preview of the front-matter metadata. |
|
||||
| **Nostr: Fetch My Relays (NIP-65)** | Fetch your kind 10002 relay list. |
|
||||
| **Nostr: Select Signer Backend** | Switch between local and n_signer backends (command-palette flow). |
|
||||
| **Nostr: Reset Published Timestamps** | Clear the local `published_at` tracking map. |
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": 30023,
|
||||
"created_at": 1721329200,
|
||||
"tags": [
|
||||
["d", "my-post"],
|
||||
["title", "My Post"]
|
||||
],
|
||||
"content": "# My Post\n\nBody text..."
|
||||
}
|
||||
```
|
||||
## n_signer setup
|
||||
|
||||
## Architecture
|
||||
For the n_signer backends, you need a running `nsigner` process. The extension connects to it; it doesn't bundle the binary.
|
||||
|
||||
- **`Signer` interface**: reuses `nostr-tools`' `Signer`
|
||||
([`nostr-tools/signer.ts`](https://laantungir.net/git/laantungir/nostr-tools.git)).
|
||||
`LocalSigner` wraps `PlainKeySigner`; Phase 2's `NsignerBackend` will
|
||||
implement the same interface.
|
||||
- **`LongFormArticle = 30023`** constant from `nostr-tools/kinds` (Phase 1).
|
||||
- **Relay publishing**: `ws` WebSocket, `["EVENT", signed]`, waits for
|
||||
`["OK", id, true|false, reason]`.
|
||||
- **Bundling**: esbuild → single `dist/extension.js`, `vscode` external.
|
||||
|
||||
## Phase 2: n_signer signing backend
|
||||
|
||||
Phase 2 delegates signing to a running
|
||||
[`n_signer`](https://laantungir.net/git/laantungir/n_signer.git) process over
|
||||
a Linux abstract Unix socket. The key material stays in `n_signer`'s
|
||||
mlock'd RAM — the extension never sees it.
|
||||
|
||||
### Setup
|
||||
|
||||
1. Build and run `n_signer` (see its README for build instructions):
|
||||
**Unix socket** (local, same machine):
|
||||
```bash
|
||||
nsigner --listen unix --socket-name nsigner
|
||||
```
|
||||
Enter your mnemonic at the prompt. `n_signer` binds the abstract socket
|
||||
`@nsigner` and shows its status TUI.
|
||||
|
||||
2. In the extension, run **Nostr: Select Signer Backend** (command palette):
|
||||
- Pick **n_signer (remote signing)**.
|
||||
- The extension discovers running `n_signer` sockets via `/proc/net/unix`
|
||||
and lists them. Pick `@nsigner` (or enter a custom socket name).
|
||||
- The extension calls `get_public_key` to verify reachability and shows
|
||||
your npub. If it can't connect, it shows an error with the command to
|
||||
start `n_signer`.
|
||||
**Qubes qrexec** (inter-qube):
|
||||
- Install the `qubes.NsignerRpc` service in the target qube.
|
||||
- Install dom0 qrexec policy allowing your qube to call it.
|
||||
- The extension spawns `qrexec-client-vm <qube> qubes.NsignerRpc` per call.
|
||||
|
||||
3. Publish as usual — the extension calls `sign_event` on `n_signer` for each
|
||||
publish. The first sign from a new caller may prompt for approval at the
|
||||
`n_signer` terminal (per its deny-by-default policy).
|
||||
**TCP** (remote / FIPS mesh):
|
||||
```bash
|
||||
nsigner --listen tcp:[::]:8080
|
||||
```
|
||||
The extension signs a kind-27235 auth envelope per request with your caller key. The first request from a new caller prompts for approval at the n_signer terminal.
|
||||
|
||||
### Wire contract
|
||||
|
||||
- Transport: Node `net.createConnection({ path: "\u0000nsigner" })` (abstract
|
||||
socket, the `\u0000` prefix is the Linux abstract-namespace marker).
|
||||
- Framing: 4-byte big-endian length prefix + UTF-8 JSON payload.
|
||||
- Verbs: `get_public_key` (params `[{nostr_index: <n>}]`), `sign_event`
|
||||
(params `[JSON.stringify(event), {nostr_index: <n>}]`).
|
||||
- No auth envelope needed for unix sockets — identity is UID-based via
|
||||
`SO_PEERCRED`.
|
||||
|
||||
### Configuration
|
||||
|
||||
| Setting | Default | Description |
|
||||
|---|---|---|
|
||||
| `nostr.signerBackend` | `"local"` | `"local"` or `"nsigner"`. |
|
||||
| `nostr.nsigner.socketName` | `"nsigner"` | Abstract socket name (without `@`). |
|
||||
| `nostr.nsigner.nostrIndex` | `0` | `nostr_index` for key derivation. |
|
||||
|
||||
## Sidebar
|
||||
|
||||
The Nostr sidebar (Activity Bar icon) shows:
|
||||
|
||||
- **Identity**: signed-in state + npub + signer backend label + Sign In/Out.
|
||||
- **Relays**: checkboxes to toggle which relays to publish to, plus a
|
||||
**Fetch My Relays (NIP-65)** button that loads your kind 10002 relay list.
|
||||
- **Actions**: + New Event, Publish Current File as Long-Form Note,
|
||||
Validate Front-Matter, Publish Current JSON File, Validate Current File.
|
||||
|
||||
Buttons enable/disable based on the active editor's language (markdown vs
|
||||
JSON). The sidebar refreshes on sign-in/out and when switching editors.
|
||||
See the [n_signer README](https://laantungir.net/git/laantungir/n_signer.git) for full build and setup instructions.
|
||||
|
||||
## Known limitations
|
||||
|
||||
- No key persistence for the local backend — the secret key must be
|
||||
re-entered each session (by design; Phase 2's `n_signer` backend holds the
|
||||
key material instead).
|
||||
- No image upload — `image` URLs in front-matter must be hosted externally
|
||||
(future Blossom/NIP-96 phase).
|
||||
- `n_signer` backend is Linux-only (abstract Unix sockets are a Linux
|
||||
primitive).
|
||||
- The `published_at` workspace-state map is per-workspace; switching
|
||||
workspaces loses the first-publish timestamps.
|
||||
- No key persistence for the local backend — the secret key must be re-entered each session (by design; n_signer backends hold the key material instead).
|
||||
- No image upload — `image` URLs in front-matter must be hosted externally (future Blossom/NIP-96 phase).
|
||||
- n_signer backends are Linux-only (abstract Unix sockets, qrexec, and TCP auth envelopes are Linux/Qubes primitives).
|
||||
- The `published_at` workspace-state map is per-workspace; switching workspaces loses the first-publish timestamps.
|
||||
- Serial transport (USB CDC) is not supported — needs a native `serialport` module. Use unix, qrexec, or tcp instead.
|
||||
|
||||
## Design docs
|
||||
|
||||
Detailed design documents are in [`plans/`](plans/):
|
||||
- [`plans/phase0-raw-event-publishing.md`](plans/phase0-raw-event-publishing.md) — raw event publishing.
|
||||
- [`plans/longform-metadata-strategy.md`](plans/longform-metadata-strategy.md) — YAML front-matter + NIP-23 metadata.
|
||||
- [`plans/implementation-plan.md`](plans/implementation-plan.md) — full implementation plan with code sketches.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
Executable
+111
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# install_upgrade.sh — build and install/upgrade the nostr-publish extension
|
||||
# into Codium (or VSCode).
|
||||
#
|
||||
# Usage:
|
||||
# ./install_upgrade.sh # build + install (auto-detect codium/code)
|
||||
# ./install_upgrade.sh codium # force codium
|
||||
# ./install_upgrade.sh code # force code (VSCode)
|
||||
#
|
||||
# What it does:
|
||||
# 1. Ensures ../nostr-tools is built (lib/cjs exists).
|
||||
# 2. npm install (if node_modules is missing).
|
||||
# 3. npm run compile (esbuild -> dist/extension.js).
|
||||
# 4. npx vsce package (produces nostr-publish-<version>.vsix).
|
||||
# 5. Installs the VSIX with --force (upgrades in place).
|
||||
#
|
||||
# After running, restart Codium/VSCode to load the new version.
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# --- Detect the editor binary ------------------------------------------------
|
||||
EDITOR_BIN="${1:-}"
|
||||
if [[ -z "$EDITOR_BIN" ]]; then
|
||||
if command -v codium &>/dev/null; then
|
||||
EDITOR_BIN="codium"
|
||||
elif command -v code &>/dev/null; then
|
||||
EDITOR_BIN="code"
|
||||
else
|
||||
echo "ERROR: neither 'codium' nor 'code' found in PATH." >&2
|
||||
echo "Pass the binary name explicitly: ./install_upgrade.sh codium" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! command -v "$EDITOR_BIN" &>/dev/null; then
|
||||
echo "ERROR: '$EDITOR_BIN' not found in PATH." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== nostr-publish install/upgrade ==="
|
||||
echo "Editor: $EDITOR_BIN"
|
||||
echo "Source: $SCRIPT_DIR"
|
||||
echo ""
|
||||
|
||||
# --- Ensure nostr-tools is built ---------------------------------------------
|
||||
NOSTR_TOOLS_DIR="$SCRIPT_DIR/../nostr-tools"
|
||||
if [[ ! -d "$NOSTR_TOOLS_DIR" ]]; then
|
||||
echo "ERROR: $NOSTR_TOOLS_DIR not found." >&2
|
||||
echo "Clone the laantungir nostr-tools fork as a sibling directory:" >&2
|
||||
echo " git clone git@laantungir.net:laantungir/nostr-tools.git ../nostr-tools" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -d "$NOSTR_TOOLS_DIR/lib/cjs" ]]; then
|
||||
echo "Building nostr-tools (lib/cjs missing)..."
|
||||
pushd "$NOSTR_TOOLS_DIR" >/dev/null
|
||||
if [[ ! -d node_modules ]]; then
|
||||
npm install --ignore-scripts
|
||||
fi
|
||||
rm -rf lib
|
||||
if command -v bun &>/dev/null; then
|
||||
bun run build.js
|
||||
else
|
||||
node build.js
|
||||
fi
|
||||
npx tsc
|
||||
popd >/dev/null
|
||||
echo "nostr-tools built."
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# --- npm install if needed ---------------------------------------------------
|
||||
if [[ ! -d node_modules ]]; then
|
||||
echo "Running npm install..."
|
||||
npm install
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# --- Compile -----------------------------------------------------------------
|
||||
echo "Compiling (esbuild)..."
|
||||
npm run compile
|
||||
echo ""
|
||||
|
||||
# --- Package -----------------------------------------------------------------
|
||||
echo "Packaging VSIX..."
|
||||
VSIX=$(npx vsce package --no-dependencies --baseContentUrl https://laantungir.net/git/laantungir/nostr-publish.git 2>&1 | grep -oP 'Packaged: \K[^ ]+')
|
||||
if [[ -z "$VSIX" ]]; then
|
||||
# Fallback: find the vsix in the current directory
|
||||
VSIX=$(ls -1 nostr-publish-*.vsix 2>/dev/null | head -1)
|
||||
fi
|
||||
if [[ -z "$VSIX" || ! -f "$VSIX" ]]; then
|
||||
echo "ERROR: VSIX packaging failed." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "VSIX: $VSIX"
|
||||
echo ""
|
||||
|
||||
# --- Install / Upgrade -------------------------------------------------------
|
||||
echo "Installing into $EDITOR_BIN (--force)..."
|
||||
"$EDITOR_BIN" --install-extension "$VSIX" --force
|
||||
echo ""
|
||||
|
||||
# --- Done --------------------------------------------------------------------
|
||||
VERSION=$(node -p "require('./package.json').version")
|
||||
echo "=== Done ==="
|
||||
echo "Installed nostr-publish v$VERSION."
|
||||
echo "Restart $EDITOR_BIN to load the new version."
|
||||
Reference in New Issue
Block a user