chore(wip): snapshot before relocating into content-farm/plugin-modules

Pre-relocation snapshot captured on development. Bundles in-flight changes
to the modal UX, logger, and plugin-config docs alongside the new
context-v/prompts/Add-New-Model-Provider.md so the move into the
content-farm pseudomonorepo doesn't leave the work behind.

Master remains untouched; merge this development branch back into master
once the relocation settles.

Also included: fast-forward of development to match master prior to the
WIP commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
mpstaton 2026-05-04 19:53:00 -05:00
parent 351e1a2400
commit 94dead1946
7 changed files with 140 additions and 16 deletions

View file

@ -144,10 +144,10 @@ ## Getting Started
## Using Symbolic Links to Test Your Plugin
If you're like us, you have a directory housing all your code projects. To use your plugin as you develop it, create a symbolic link from your dev checkout into your vault's `.obsidian/plugins/` directory. The destination folder name must match the plugin id from `manifest.json` (`image-gin-plugin`):
If you're like us, you have a directory housing all your code projects. To use your plugin as you develop it, create a symbolic link from your dev checkout into your vault's `.obsidian/plugins/` directory. The destination folder name must match the plugin id from `manifest.json` (`image-gin`):
```bash
ln -s /Users/mpstaton/code/lossless-monorepo/image-gin /Users/mpstaton/content-md/lossless/.obsidian/plugins/image-gin-plugin
ln -s /Users/mpstaton/code/lossless-monorepo/image-gin /Users/mpstaton/content-md/lossless/.obsidian/plugins/image-gin
```
Adjust both paths for your own filesystem. After linking, run `pnpm dev` in the dev checkout — esbuild will watch for changes; reload the plugin in Obsidian (toggle off/on in Community Plugins) to pick up new builds.

View file

@ -0,0 +1,4 @@
https://ai.google.dev/gemini-api/docs/imagen

View file

@ -201,8 +201,8 @@ ### For users
→ Enable.
**Manually from this release**: download `main.js`, `manifest.json`,
and `styles.css` into `<vault>/.obsidian/plugins/image-gin-plugin/`,
then enable the plugin in Settings → Community Plugins.
and `styles.css` into `<vault>/.obsidian/plugins/image-gin/`, then
enable the plugin in Settings → Community Plugins.
After installation, open **Settings → Community Plugins → Image Gin**
to add API keys for the providers you intend to use. Each provider is
@ -230,13 +230,13 @@ # or
**macOS / Linux**
```bash
ln -s /absolute/path/to/image-gin-plugin \
/absolute/path/to/your-vault/.obsidian/plugins/image-gin-plugin
/absolute/path/to/your-vault/.obsidian/plugins/image-gin
```
**Windows (PowerShell as admin)**
```powershell
New-Item -ItemType SymbolicLink `
-Path "C:\path\to\your-vault\.obsidian\plugins\image-gin-plugin" `
-Path "C:\path\to\your-vault\.obsidian\plugins\image-gin" `
-Target "C:\path\to\image-gin-plugin"
```

120
log.json
View file

@ -550,5 +550,125 @@
"level": "info",
"message": "ImageKit upload successful:",
"details": "https://ik.imagekit.io/xvpgfijuw/uploads/lossless/2025-dec/Agent_Standards_square_image_1777836523406_bjIBzfNds.webp"
},
{
"timestamp": "2026-05-04T02:28:04.749Z",
"level": "info",
"message": "Found image properties:",
"details": []
},
{
"timestamp": "2026-05-04T02:28:04.749Z",
"level": "info",
"message": "Found markdown images:",
"details": [
{
"path": "Visuals/2026-05-02_Perplexed-ask-Perplexity_3.05.02 PM.png",
"match": "![[Visuals/2026-05-02_Perplexed-ask-Perplexity_3.05.02 PM.png]]"
}
]
},
{
"timestamp": "2026-05-04T02:28:08.406Z",
"level": "info",
"message": "Uploading to ImageKit:",
"details": {
"fileName": "Perplexed-(Obsidian-Community-Plugin)_content_1777861688405.webp",
"folder": "/uploads/lossless/2025-dec",
"tags": "Perplexed-(Obsidian-Community-Plugin),markdown",
"endpoint": "https://upload.imagekit.io/api/v1/files/upload",
"contentLength": 211171
}
},
{
"timestamp": "2026-05-04T02:28:09.012Z",
"level": "info",
"message": "ImageKit upload successful:",
"details": "https://ik.imagekit.io/xvpgfijuw/uploads/lossless/2025-dec/Perplexed-_Obsidian-Community-Plugin__content_1777861688405_RwUeclHm2.webp"
},
{
"timestamp": "2026-05-04T02:28:09.012Z",
"level": "info",
"message": "Successfully converted markdown image: https://ik.imagekit.io/xvpgfijuw/uploads/lossless/2025-dec/Perplexed-_Obsidian-Community-Plugin__content_1777861688405_RwUeclHm2.webp"
},
{
"timestamp": "2026-05-04T02:30:32.775Z",
"level": "info",
"message": "Found image properties:",
"details": []
},
{
"timestamp": "2026-05-04T02:30:32.775Z",
"level": "info",
"message": "Found markdown images:",
"details": [
{
"path": "Visuals/2026-05-02_Perplexed_Commands-Available_2.48.19 PM.png",
"match": "![[Visuals/2026-05-02_Perplexed_Commands-Available_2.48.19 PM.png]]"
}
]
},
{
"timestamp": "2026-05-04T02:30:34.859Z",
"level": "info",
"message": "Uploading to ImageKit:",
"details": {
"fileName": "Perplexed-(Obsidian-Community-Plugin)_content_1777861834858.webp",
"folder": "/uploads/lossless/2025-dec",
"tags": "Perplexed-(Obsidian-Community-Plugin),markdown",
"endpoint": "https://upload.imagekit.io/api/v1/files/upload",
"contentLength": 219120
}
},
{
"timestamp": "2026-05-04T02:30:35.532Z",
"level": "info",
"message": "ImageKit upload successful:",
"details": "https://ik.imagekit.io/xvpgfijuw/uploads/lossless/2025-dec/Perplexed-_Obsidian-Community-Plugin__content_1777861834858_cVAwSGCMV.webp"
},
{
"timestamp": "2026-05-04T02:30:35.533Z",
"level": "info",
"message": "Successfully converted markdown image: https://ik.imagekit.io/xvpgfijuw/uploads/lossless/2025-dec/Perplexed-_Obsidian-Community-Plugin__content_1777861834858_cVAwSGCMV.webp"
},
{
"timestamp": "2026-05-04T03:42:14.239Z",
"level": "info",
"message": "Found image properties:",
"details": []
},
{
"timestamp": "2026-05-04T03:42:14.240Z",
"level": "info",
"message": "Found markdown images:",
"details": [
{
"path": "Visuals/2026-05-03-MemoPop-GUI_Screenshot_4.48.20 PM.png",
"match": "![[Visuals/2026-05-03-MemoPop-GUI_Screenshot_4.48.20 PM.png]]"
}
]
},
{
"timestamp": "2026-05-04T03:42:16.156Z",
"level": "info",
"message": "Uploading to ImageKit:",
"details": {
"fileName": "MemoPop AI_content_1777866136156.webp",
"folder": "/uploads/lossless/2025-dec",
"tags": "MemoPop AI,markdown",
"endpoint": "https://upload.imagekit.io/api/v1/files/upload",
"contentLength": 1670366
}
},
{
"timestamp": "2026-05-04T03:42:16.975Z",
"level": "info",
"message": "ImageKit upload successful:",
"details": "https://ik.imagekit.io/xvpgfijuw/uploads/lossless/2025-dec/MemoPop_AI_content_1777866136156_bOoHTyHzX.webp"
},
{
"timestamp": "2026-05-04T03:42:16.975Z",
"level": "info",
"message": "Successfully converted markdown image: https://ik.imagekit.io/xvpgfijuw/uploads/lossless/2025-dec/MemoPop_AI_content_1777866136156_bOoHTyHzX.webp"
}
]

View file

@ -59,7 +59,7 @@ export default class ImageGinPlugin extends Plugin {
await this.loadSettings();
// Wire up the file logger so console.* calls in services/modals
// also persist to .obsidian/plugins/image-gin-plugin/log.json.
// also persist to .obsidian/plugins/image-gin/log.json.
logger.initialize(this.app.vault);
this.addSettingTab(new ImageGinSettingTab(this.app, this));

View file

@ -3,16 +3,15 @@
plugin:
# Plugin identifiers
id: "image-gin-plugin"
id: "image-gin"
name: "Image Gin"
class_name: "ImageGin"
# Plugin metadata
version: "0.0.1"
description: "Enables users to use Generative AI to generate contextually relevant images through an [Obsidian](https://obsidian.md) plugin."
version: "0.1.1"
description: "Generate AI images, search stock images, and upload to ImageKit CDN."
author: "The Lossless Group"
author_url: "https://lossless.group"
funding_url: "https://lossless.group"
# Plugin settings
min_app_version: "1.8.10"

View file

@ -12,9 +12,10 @@ interface LogEntry {
/**
* Singleton file logger for Image Gin.
*
* Writes to `.obsidian/plugins/image-gin-plugin/log.json` (the plugin's own
* data folder, kept hidden in the vault). Also mirrors every entry to
* console.* so the existing devtools workflow keeps working.
* Writes to `.obsidian/plugins/image-gin/log.json` (the plugin's own
* data folder, matching manifest.json id, kept hidden in the vault).
* Also mirrors every entry to console.* so the existing devtools
* workflow keeps working.
*
* `initialize(vault)` MUST be called once during plugin onload before any
* log calls actually persist; pre-initialize calls fall through to console
@ -25,7 +26,7 @@ export class FileLogger {
// Plugin-folder path (matches the directory Obsidian uses for this plugin
// per manifest.json id). Kept as a constant so we never accidentally
// write a log.json to the user's vault root.
private logFile: string = '.obsidian/plugins/image-gin-plugin/log.json';
private logFile: string = '.obsidian/plugins/image-gin/log.json';
private vault: Vault | null = null;
private logEntries: LogEntry[] = [];
private isSaving = false;