Rename project from Gooti to Plebian Signer and add Claude Code config

- Rename all gooti-* files to plebian-signer-* across Chrome and Firefox
- Rename GootiMetaHandler to SignerMetaHandler in common library
- Update all references to use new naming convention
- Add CLAUDE.md with project build/architecture documentation
- Add Claude Code release command tailored for this npm/Angular project
- Add NWC-IMPLEMENTATION.md design document
- Add Claude skills for nostr, typescript, react, svelte, and applesauce libs
- Update README and various component templates with new branding

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-17 09:29:00 +01:00
parent e11ca7a0d2
commit 3c63e6555c
88 changed files with 19449 additions and 498 deletions

View File

@@ -14,7 +14,7 @@ export class AppComponent implements OnInit {
readonly #logger = inject(LoggerService);
ngOnInit(): void {
this.#logger.initialize('Gooti Firefox Extension');
this.#logger.initialize('Plebian Signer Firefox Extension');
this.#startup.startOver(getNewStorageServiceConfig());
}

View File

@@ -1,8 +1,8 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { GootiMetaData, GootiMetaHandler } from '@common';
import { SignerMetaData, SignerMetaHandler } from '@common';
import browser from 'webextension-polyfill';
export class FirefoxMetaHandler extends GootiMetaHandler {
export class FirefoxMetaHandler extends SignerMetaHandler {
async loadFullData(): Promise<Partial<Record<string, any>>> {
const dataWithPossibleAlienProperties = await browser.storage.local.get(
null
@@ -20,7 +20,7 @@ export class FirefoxMetaHandler extends GootiMetaHandler {
return data;
}
async saveFullData(data: GootiMetaData): Promise<void> {
async saveFullData(data: SignerMetaData): Promise<void> {
await browser.storage.local.set(data as Record<string, any>);
console.log(data);
}

View File

@@ -8,7 +8,7 @@ export const getNewStorageServiceConfig = () => {
browserSessionHandler: new FirefoxSessionHandler(),
browserSyncYesHandler: new FirefoxSyncYesHandler(),
browserSyncNoHandler: new FirefoxSyncNoHandler(),
gootiMetaHandler: new FirefoxMetaHandler(),
signerMetaHandler: new FirefoxMetaHandler(),
};
return storageConfig;

View File

@@ -1,19 +1,14 @@
<div class="sam-text-header">
<span> Gooti </span>
<span> Plebian Signer </span>
</div>
<span>Version {{ version }}</span>
<span>&nbsp;</span>
<span> Website </span>
<a href="https://getgooti.com" target="_blank">www.getgooti.com</a>
<span>&nbsp;</span>
<span> Source code</span>
<a href="https://github.com/sam-hayes-org/gooti-extension" target="_blank">
github.com/sam-hayes-org/gooti-extension
<a href="https://git.mleku.dev/mleku/plebeian-signer" target="_blank">
git.mleku.dev/mleku/plebeian-signer
</a>
<div class="sam-flex-grow"></div>

View File

@@ -27,7 +27,7 @@ export class SettingsComponent extends NavComponent implements OnInit {
);
console.log(vault.length / 1024 + ' KB');
switch (this.#storage.getGootiMetaHandler().gootiMetaData?.syncFlow) {
switch (this.#storage.getSignerMetaHandler().signerMetaData?.syncFlow) {
case BrowserSyncFlow.NO_SYNC:
this.syncFlow = 'Off';
break;
@@ -55,7 +55,7 @@ export class SettingsComponent extends NavComponent implements OnInit {
const jsonVault = this.#storage.exportVault();
const dateTimeString = DateHelper.dateToISOLikeButLocal(new Date());
const fileName = `Gooti Chrome - Vault Export - ${dateTimeString}.json`;
const fileName = `Plebian Signer Firefox - Vault Export - ${dateTimeString}.json`;
this.#downloadJson(jsonVault, fileName);
}

View File

@@ -1,5 +1,5 @@
<div class="sam-text-header">
<span>Gooti</span>
<span>Plebian Signer</span>
</div>
<div class="vertically-centered">

View File

@@ -1,5 +1,5 @@
<div class="sam-text-header">
<span>Gooti</span>
<span>Plebian Signer</span>
</div>
<div class="content">

View File

@@ -2,7 +2,7 @@ import { Component, inject, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
import {
BrowserSyncFlow,
GootiMetaData_VaultSnapshot,
SignerMetaData_VaultSnapshot,
IconButtonComponent,
NavComponent,
StartupService,
@@ -18,8 +18,8 @@ import { getNewStorageServiceConfig } from '../../common/data/get-new-storage-se
styleUrl: './vault-import.component.scss',
})
export class VaultImportComponent extends NavComponent implements OnInit {
snapshots: GootiMetaData_VaultSnapshot[] = [];
selectedSnapshot: GootiMetaData_VaultSnapshot | undefined;
snapshots: SignerMetaData_VaultSnapshot[] = [];
selectedSnapshot: SignerMetaData_VaultSnapshot | undefined;
syncText: string | undefined;
readonly #storage = inject(StorageService);
@@ -51,11 +51,11 @@ export class VaultImportComponent extends NavComponent implements OnInit {
async #loadData() {
this.snapshots = (
this.#storage.getGootiMetaHandler().gootiMetaData?.vaultSnapshots ?? []
this.#storage.getSignerMetaHandler().signerMetaData?.vaultSnapshots ?? []
).sortBy((x) => x.fileName, 'desc');
const syncFlow =
this.#storage.getGootiMetaHandler().gootiMetaData?.syncFlow;
this.#storage.getSignerMetaHandler().signerMetaData?.syncFlow;
switch (syncFlow) {
case BrowserSyncFlow.BROWSER_SYNC:

View File

@@ -1,5 +1,5 @@
<div class="sam-text-header">
<span class="brand">Gooti</span>
<span class="brand">Plebian Signer</span>
</div>
<div class="content-login-vault">

View File

@@ -1,9 +1,9 @@
<div class="sam-text-header sam-mb-2">
<span>Gooti Setup - Sync Preference</span>
<span>Plebian Signer Setup - Sync Preference</span>
</div>
<span class="sam-text-muted sam-text-md sam-text-align-center2">
Gooti always encrypts sensitive data like private keys and site permissions
Plebian Signer always encrypts sensitive data like private keys and site permissions
independent of the chosen sync mode.
</span>

View File

@@ -4,7 +4,7 @@ import {
BrowserSyncData,
BrowserSyncFlow,
CryptoHelper,
GootiMetaData,
SignerMetaData,
Identity_DECRYPTED,
Nip07Method,
Nip07MethodPolicy,
@@ -18,7 +18,7 @@ import browser from 'webextension-polyfill';
export const debug = function (message: any) {
const dateString = new Date().toISOString();
console.log(`[Gooti - ${dateString}]: ${JSON.stringify(message)}`);
console.log(`[Plebian Signer - ${dateString}]: ${JSON.stringify(message)}`);
};
export type PromptResponse =
@@ -52,17 +52,17 @@ export const getBrowserSessionData = async function (): Promise<
export const getBrowserSyncData = async function (): Promise<
BrowserSyncData | undefined
> {
const gootiMetaHandler = new FirefoxMetaHandler();
const gootiMetaData =
(await gootiMetaHandler.loadFullData()) as GootiMetaData;
const signerMetaHandler = new FirefoxMetaHandler();
const signerMetaData =
(await signerMetaHandler.loadFullData()) as SignerMetaData;
let browserSyncData: BrowserSyncData | undefined;
if (gootiMetaData.syncFlow === BrowserSyncFlow.NO_SYNC) {
if (signerMetaData.syncFlow === BrowserSyncFlow.NO_SYNC) {
browserSyncData = (await browser.storage.local.get(
null
)) as unknown as BrowserSyncData;
} else if (gootiMetaData.syncFlow === BrowserSyncFlow.BROWSER_SYNC) {
} else if (signerMetaData.syncFlow === BrowserSyncFlow.BROWSER_SYNC) {
browserSyncData = (await browser.storage.sync.get(
null
)) as unknown as BrowserSyncData;
@@ -74,13 +74,13 @@ export const getBrowserSyncData = async function (): Promise<
export const savePermissionsToBrowserSyncStorage = async function (
permissions: Permission_ENCRYPTED[]
): Promise<void> {
const gootiMetaHandler = new FirefoxMetaHandler();
const gootiMetaData =
(await gootiMetaHandler.loadFullData()) as GootiMetaData;
const signerMetaHandler = new FirefoxMetaHandler();
const signerMetaData =
(await signerMetaHandler.loadFullData()) as SignerMetaData;
if (gootiMetaData.syncFlow === BrowserSyncFlow.NO_SYNC) {
if (signerMetaData.syncFlow === BrowserSyncFlow.NO_SYNC) {
await browser.storage.local.set({ permissions });
} else if (gootiMetaData.syncFlow === BrowserSyncFlow.BROWSER_SYNC) {
} else if (signerMetaData.syncFlow === BrowserSyncFlow.BROWSER_SYNC) {
await browser.storage.sync.set({ permissions });
}
};

View File

@@ -51,7 +51,7 @@ browser.runtime.onMessage.addListener(async (message /*, sender*/) => {
const browserSessionData = await getBrowserSessionData();
if (!browserSessionData) {
throw new Error('Gooti vault not unlocked by the user.');
throw new Error('Plebian Signer vault not unlocked by the user.');
}
const currentIdentity = browserSessionData.identities.find(

View File

@@ -2,7 +2,7 @@
<html lang="en" data-bs-theme="dark">
<head>
<meta charset="utf-8">
<title>Gooti</title>
<title>Plebian Signer</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>

View File

@@ -1,7 +1,7 @@
import {
BrowserSyncData,
GOOTI_META_DATA_KEY,
GootiMetaData_VaultSnapshot,
SIGNER_META_DATA_KEY,
SignerMetaData_VaultSnapshot,
} from '@common';
import './app/common/extensions/array';
import browser from 'webextension-polyfill';
@@ -10,13 +10,13 @@ import browser from 'webextension-polyfill';
// Functions
//
async function getGootiMetaDataVaultSnapshots(): Promise<
GootiMetaData_VaultSnapshot[]
async function getSignerMetaDataVaultSnapshots(): Promise<
SignerMetaData_VaultSnapshot[]
> {
const data = (await browser.storage.local.get(
GOOTI_META_DATA_KEY.vaultSnapshots
SIGNER_META_DATA_KEY.vaultSnapshots
)) as {
vaultSnapshots?: GootiMetaData_VaultSnapshot[];
vaultSnapshots?: SignerMetaData_VaultSnapshot[];
};
return typeof data.vaultSnapshots === 'undefined'
@@ -24,15 +24,15 @@ async function getGootiMetaDataVaultSnapshots(): Promise<
: data.vaultSnapshots.sortBy((x) => x.fileName, 'desc');
}
async function setGootiMetaDataVaultSnapshots(
vaultSnapshots: GootiMetaData_VaultSnapshot[]
async function setSignerMetaDataVaultSnapshots(
vaultSnapshots: SignerMetaData_VaultSnapshot[]
): Promise<void> {
await browser.storage.local.set({
vaultSnapshots,
});
}
function rebuildSnapshotsList(snapshots: GootiMetaData_VaultSnapshot[]) {
function rebuildSnapshotsList(snapshots: SignerMetaData_VaultSnapshot[]) {
const ul = document.getElementById('snapshotsList');
if (!ul) {
return;
@@ -77,7 +77,7 @@ document.addEventListener('DOMContentLoaded', async () => {
) as HTMLInputElement;
deleteSnapshotsButton?.addEventListener('click', async () => {
await setGootiMetaDataVaultSnapshots([]);
await setSignerMetaDataVaultSnapshots([]);
rebuildSnapshotsList([]);
});
@@ -92,9 +92,9 @@ document.addEventListener('DOMContentLoaded', async () => {
}
try {
const existingSnapshots = await getGootiMetaDataVaultSnapshots();
const existingSnapshots = await getSignerMetaDataVaultSnapshots();
const newSnapshots: GootiMetaData_VaultSnapshot[] = [];
const newSnapshots: SignerMetaData_VaultSnapshot[] = [];
for (const file of files) {
const text = await file.text();
const vault = JSON.parse(text) as BrowserSyncData;
@@ -116,7 +116,7 @@ document.addEventListener('DOMContentLoaded', async () => {
);
// Persist the new snapshots to the local storage
await setGootiMetaDataVaultSnapshots(snapshots);
await setSignerMetaDataVaultSnapshots(snapshots);
//
rebuildSnapshotsList(snapshots);
@@ -125,6 +125,6 @@ document.addEventListener('DOMContentLoaded', async () => {
}
});
const snapshots = await getGootiMetaDataVaultSnapshots();
const snapshots = await getSignerMetaDataVaultSnapshots();
rebuildSnapshotsList(snapshots);
});

View File

@@ -7,7 +7,7 @@ import { BackgroundRequestMessage } from './background-common';
const script = document.createElement('script');
script.setAttribute('async', 'false');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', browser.runtime.getURL('gooti-extension.js'));
script.setAttribute('src', browser.runtime.getURL('plebian-signer-extension.js'));
(document.head || document.documentElement).appendChild(script);
// listen for messages from that script
@@ -18,7 +18,7 @@ window.addEventListener('message', async (message) => {
if (message.source !== window) return;
if (!message.data) return;
if (!message.data.params) return;
if (message.data.ext !== 'gooti') return;
if (message.data.ext !== 'plebian-signer') return;
// pass on to background
let response;
@@ -36,7 +36,7 @@ window.addEventListener('message', async (message) => {
// return response
window.postMessage(
{ id: message.data.id, ext: 'gooti', response },
{ id: message.data.id, ext: 'plebian-signer', response },
message.origin
);
});

View File

@@ -25,7 +25,7 @@ class Messenger {
window.postMessage(
{
id,
ext: 'gooti',
ext: 'plebian-signer',
method,
params,
},
@@ -41,7 +41,7 @@ class Messenger {
!message.data ||
message.data.response === null ||
message.data.response === undefined ||
message.data.ext !== 'gooti' ||
message.data.ext !== 'plebian-signer' ||
!this.#requests.has(message.data.id)
) {
return;