Migrated n_signer verb names to nostr_ prefix (get_public_key→nostr_get_public_key, sign_event→nostr_sign_event)
This commit is contained in:
@@ -1,3 +1,11 @@
|
||||
---
|
||||
slug: codium-nostr-extension
|
||||
title: Codium nostr extension
|
||||
summary: A Codium / VSCode extension to publish files to [Nostr].
|
||||
image:
|
||||
tags: [nostr, writing, codium, vscode]
|
||||
---
|
||||
|
||||
# Nostr Publish
|
||||
|
||||
A Codium / VSCode extension to publish files to [Nostr](https://github.com/nostr-protocol/nostr).
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"onCommand:nostr.fetchRelays",
|
||||
"onCommand:nostr.selectBackend",
|
||||
"onCommand:nostr.signInFromSidebar",
|
||||
"onCommand:nostr.insertNoteHeader",
|
||||
"onView:nostr.sidebar"
|
||||
],
|
||||
"contributes": {
|
||||
@@ -101,6 +102,12 @@
|
||||
"command": "nostr.selectBackend",
|
||||
"title": "Nostr: Select Signer Backend",
|
||||
"category": "Nostr"
|
||||
},
|
||||
{
|
||||
"command": "nostr.insertNoteHeader",
|
||||
"title": "Nostr: Insert Note Header",
|
||||
"category": "Nostr",
|
||||
"enablement": "editorLangId == markdown"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
@@ -124,6 +131,11 @@
|
||||
"command": "nostr.publishLongForm",
|
||||
"when": "editorLangId == markdown",
|
||||
"group": "nostr@2"
|
||||
},
|
||||
{
|
||||
"command": "nostr.insertNoteHeader",
|
||||
"when": "editorLangId == markdown",
|
||||
"group": "nostr@0"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -83,6 +83,11 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
|
||||
cmdResetTimestamps(state),
|
||||
),
|
||||
);
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("nostr.insertNoteHeader", () =>
|
||||
cmdInsertNoteHeader(),
|
||||
),
|
||||
);
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("nostr.selectBackend", () =>
|
||||
cmdSelectBackend(config, state, statusBar),
|
||||
@@ -914,6 +919,67 @@ async function cmdResetTimestamps(state: StateService): Promise<void> {
|
||||
vscode.window.showInformationMessage("Published timestamps reset.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Command: insert a YAML front-matter note header template into the active
|
||||
* markdown document.
|
||||
*
|
||||
* If the document already starts with a `---` front-matter block, the command
|
||||
* does nothing and shows a warning. Otherwise, it inserts the template at the
|
||||
* top of the document (or at the cursor if the document is empty).
|
||||
*
|
||||
* The slug defaults to the filename stem; the user can edit it after insertion.
|
||||
*/
|
||||
async function cmdInsertNoteHeader(): Promise<void> {
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
if (!editor) {
|
||||
vscode.window.showErrorMessage("No active editor.");
|
||||
return;
|
||||
}
|
||||
if (editor.document.languageId !== "markdown") {
|
||||
vscode.window.showErrorMessage("Active file is not Markdown.");
|
||||
return;
|
||||
}
|
||||
|
||||
const text = editor.document.getText();
|
||||
// Check if front-matter already exists.
|
||||
if (/^---\r?\n/.test(text)) {
|
||||
vscode.window.showWarningMessage("This document already has a front-matter block.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Derive a default slug from the filename stem.
|
||||
const stem = activeFilenameStem() ?? "my-post";
|
||||
const slug = stem
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, "-")
|
||||
.replace(/[^a-z0-9-]/g, "")
|
||||
.replace(/-+/g, "-")
|
||||
.replace(/^-|-$/g, "") || "my-post";
|
||||
|
||||
const header = `---
|
||||
slug: ${slug}
|
||||
title: ${stem ?? "Untitled"}
|
||||
summary: A one-sentence abstract for feeds.
|
||||
image: https://example.com/cover.png
|
||||
tags: [nostr, writing]
|
||||
---
|
||||
|
||||
`;
|
||||
|
||||
// Insert at position 0 (top of document).
|
||||
const position = new vscode.Position(0, 0);
|
||||
await editor.edit((editBuilder) => {
|
||||
editBuilder.insert(position, header);
|
||||
});
|
||||
|
||||
// Move cursor to the title line for easy editing.
|
||||
const titleLine = 2; // 0-based: line 0 is `---`, line 1 is `slug:`, line 2 is `title:`
|
||||
editor.selection = new vscode.Selection(titleLine, 7, titleLine, 7 + (stem?.length ?? 8));
|
||||
editor.revealRange(new vscode.Range(0, 0, titleLine, 0), vscode.TextEditorRevealType.AtTop);
|
||||
|
||||
vscode.window.showInformationMessage("Inserted note header. Edit the metadata, then write your article below the --- line.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Command: sign in from the sidebar's method dropdown.
|
||||
*
|
||||
|
||||
@@ -48,7 +48,7 @@ export class NsignerClient implements NsignerTransport {
|
||||
* Send a JSON-RPC request to n_signer and return the parsed response.
|
||||
* Throws on connection error, timeout, or frame parse failure.
|
||||
*
|
||||
* @param method RPC verb (e.g. "get_public_key", "sign_event").
|
||||
* @param method RPC verb (e.g. "nostr_get_public_key", "nostr_sign_event").
|
||||
* @param params Params array (e.g. `[{nostr_index: 0}]`).
|
||||
* @param timeoutMs Per-call timeout (default 30s — signing may need human
|
||||
* approval at the n_signer terminal, so this is deliberately long).
|
||||
|
||||
@@ -62,7 +62,7 @@ export class NsignerBackend implements NostrSigner {
|
||||
}
|
||||
|
||||
async getPublicKey(): Promise<string> {
|
||||
const res = await this.transport.call("get_public_key", [{ nostr_index: this.nostrIndex }]);
|
||||
const res = await this.transport.call("nostr_get_public_key", [{ nostr_index: this.nostrIndex }]);
|
||||
if (res.error) {
|
||||
throw new Error(`n_signer: ${res.error.message}`);
|
||||
}
|
||||
@@ -73,7 +73,7 @@ export class NsignerBackend implements NostrSigner {
|
||||
}
|
||||
|
||||
async signEvent(event: EventTemplate): Promise<VerifiedEvent> {
|
||||
const res = await this.transport.call("sign_event", [
|
||||
const res = await this.transport.call("nostr_sign_event", [
|
||||
JSON.stringify(event),
|
||||
{ nostr_index: this.nostrIndex },
|
||||
]);
|
||||
|
||||
@@ -15,6 +15,7 @@ type WebviewMessage =
|
||||
| { type: "validateCurrentFile" }
|
||||
| { type: "publishLongForm" }
|
||||
| { type: "validateFrontMatter" }
|
||||
| { type: "insertNoteHeader" }
|
||||
| { type: "fetchRelays" }
|
||||
| { type: "toggleRelay"; relay: string; enabled: boolean };
|
||||
|
||||
@@ -125,6 +126,9 @@ export class NostrSidebarProvider implements vscode.WebviewViewProvider {
|
||||
case "validateFrontMatter":
|
||||
await vscode.commands.executeCommand("nostr.validateFrontMatter");
|
||||
break;
|
||||
case "insertNoteHeader":
|
||||
await vscode.commands.executeCommand("nostr.insertNoteHeader");
|
||||
break;
|
||||
case "fetchRelays":
|
||||
await vscode.commands.executeCommand("nostr.fetchRelays");
|
||||
break;
|
||||
@@ -276,6 +280,7 @@ export class NostrSidebarProvider implements vscode.WebviewViewProvider {
|
||||
<div class="section">
|
||||
<h2>Actions</h2>
|
||||
<button id="createBtn">+ New Event</button>
|
||||
<button id="insertNoteHeaderBtn" disabled>Insert Note Header</button>
|
||||
<button id="publishLongFormBtn" disabled>Publish Current File as Long-Form Note</button>
|
||||
<button id="validateFrontMatterBtn" class="secondary" disabled>Validate Front-Matter</button>
|
||||
<button id="publishBtn" disabled>Publish Current JSON File</button>
|
||||
@@ -362,6 +367,7 @@ export class NostrSidebarProvider implements vscode.WebviewViewProvider {
|
||||
$("validateBtn").addEventListener("click", () => vscode.postMessage({ type: "validateCurrentFile" }));
|
||||
$("publishLongFormBtn").addEventListener("click", () => vscode.postMessage({ type: "publishLongForm" }));
|
||||
$("validateFrontMatterBtn").addEventListener("click", () => vscode.postMessage({ type: "validateFrontMatter" }));
|
||||
$("insertNoteHeaderBtn").addEventListener("click", () => vscode.postMessage({ type: "insertNoteHeader" }));
|
||||
$("fetchRelaysBtn").addEventListener("click", () => vscode.postMessage({ type: "fetchRelays" }));
|
||||
$("signOutBtn").addEventListener("click", () => vscode.postMessage({ type: "signOut" }));
|
||||
|
||||
@@ -410,6 +416,7 @@ export class NostrSidebarProvider implements vscode.WebviewViewProvider {
|
||||
$("validateBtn").disabled = !s.canPublish;
|
||||
$("publishLongFormBtn").disabled = !s.canPublishLongForm;
|
||||
$("validateFrontMatterBtn").disabled = !s.canPublishLongForm;
|
||||
$("insertNoteHeaderBtn").disabled = !s.canPublishLongForm;
|
||||
$("fetchRelaysBtn").disabled = !s.signedIn;
|
||||
|
||||
// Identity
|
||||
|
||||
Reference in New Issue
Block a user