Skip to content

Conversation

@greetclammy
Copy link
Contributor

@greetclammy greetclammy commented Aug 13, 2025

I am submitting a new Community Plugin

  • I attest that I have done my best to deliver a high-quality plugin, am proud of the code I have written, and would recommend it to others. I commit to maintaining the plugin and being responsive to bug reports. If I am no longer able to maintain it, I will make reasonable efforts to find a successor maintainer or withdraw the plugin from the directory.

Repo URL

Link to my plugin: https://github.com/greetclammy/first-line-is-title

Release Checklist

  • I have tested the plugin on
    • Windows
    • macOS
    • Linux
    • Android (if applicable)
    • iOS (if applicable)
  • My GitHub release contains all required files (as individual files, not just in the source.zip / source.tar.gz)
    • main.js
    • manifest.json
    • styles.css (optional)
  • GitHub release name matches the exact version number specified in my manifest.json (Note: Use the exact version number, don't include a prefix v)
  • The id in my manifest.json matches the id in the community-plugins.json file.
  • My README.md describes the plugin's purpose and provides clear usage instructions.
  • I have read the developer policies at https://docs.obsidian.md/Developer+policies, and have assessed my plugins's adherence to these policies.
  • I have read the tips in https://docs.obsidian.md/Plugins/Releasing/Plugin+guidelines and have self-reviewed my plugin to avoid these common pitfalls.
  • I have added a license in the LICENSE file.
  • My project respects and is compatible with the original license of any code from other plugins that I'm using.
    I have given proper attribution to these other projects in my README.md.

@github-actions github-actions bot changed the title Update community-plugins.json Add plugin: First Line is Title Aug 13, 2025
@ObsidianReviewBot
Copy link
Collaborator

Thank you for your submission, an automated scan of your plugin code's revealed the following issues:

Required

[1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22][23][24][25][26][27][28][29][30] and more :You should avoid assigning styles via JavaScript or in HTML and instead move all these styles into CSS so that they are more easily adaptable by themes and snippets.

[1][2]:Using innerHTML, outerHTML or similar API's is a security risk. Instead, use the DOM API or the Obsidian helper functions: https://docs.obsidian.md/Plugins/User+interface/HTML+elements


Do NOT open a new PR for re-validation.
Once you have pushed all of the required changes to your repo, the bot will update the labels on this PR within 6 hours.
If you think some of the required changes are incorrect, please comment with /skip and the reason why you think the results are incorrect.

@ObsidianReviewBot ObsidianReviewBot added Changes requested Additional review required PR needs to be reviewed by another person, after the currently requested changes have been made Ready for review and removed Ready for review Changes requested Additional review required PR needs to be reviewed by another person, after the currently requested changes have been made labels Aug 13, 2025
@ObsidianReviewBot ObsidianReviewBot removed their assignment Aug 13, 2025
@ObsidianReviewBot
Copy link
Collaborator

Changes requested by bot have been made, ready for additional review by human.
Please be aware that it might take a few weeks before your plugin is reviewed due to the high volume of submissions currently.

@Zachatoo Zachatoo self-assigned this Oct 21, 2025
@Zachatoo
Copy link
Collaborator

if (typeof window.localStorage !== 'undefined' && window.localStorage.getItem('language')) {, "minAppVersion": "1.7.0",
This should not be a setting, use the getLanguage() function from the API to get the language configured in the Obsidian settings (requires minAppVersion: "1.8.0")

const styleEl = document.createElement('style');
Do not load your plugin's styles manually, Obsidian will load and unload your plugin's styles for you when your plugin is loaded/unloaded.

callback: async () => {, callback: async () => {
These should be using conditional commands, with the condition being an active note.

callback: async () => {, callback: async () => {
This should be a editor command

if (!content.startsWith('---')) {, if (!content.startsWith('---')) {
Use getFrontMatterInfo to get information about the frontmatter of a file, including whether there is a frontmatter block, the offsets of where it starts and ends, and the frontmatter text.

for (const line of yamlLines) {
Use parseYaml and stringifyYaml to parse frontmatter.

const frontmatter = parseYaml(yaml);

Optional feedback:

"watch": "^0.13.0"
Looks like you aren't using this, may as well remove it.

if (!this.settings.enableCommandPalette) {, if (!this.settings.commandPaletteVisibility.renameCurrentFile) {
This is a strange setting to have, if a user doesn't want to use your commands they just won't use them. It is unusual for a plugin to conditionally register their commands. I recommend you remove this conditional logic.

const tagRegex = /#([a-zA-Z][\w-_/]*)/g;
This may have false positives, for example, a comment in a codeblock. Obsidian doesn't provide a way to parse tags other than through the metadata cache, which you're already falling back to. You may want to consider if it's possible to only reference the metadata cache to avoid false positives.

```yaml
key: value #comment
```

contentForRateLimit = await this.plugin.app.vault.read(file);
You're doing a lot of file reads in this method, are all of them necessary? This one specifically you aren't doing anything with.


Please note that this is an initial review, a more thorough review will occur when the above changes have been made. The bot will mark this PR as "changes made" when it has detected that you have made all the required changes. The bot checks about every 4 hours.

@Zachatoo Zachatoo added Changes requested Minor changes requested PR can be merged after some final changes have been requested and removed Ready for review labels Oct 21, 2025
@ObsidianReviewBot ObsidianReviewBot added Ready for review Changes made and removed Changes requested Minor changes requested PR can be merged after some final changes have been requested labels Oct 22, 2025
@greetclammy
Copy link
Contributor Author

I see that the bot added Changed made but leaving a comment just in case, per the docs:

Leave a comment on the PR to let us know you've addressed the feedback.

@Zachatoo
Copy link
Collaborator

Zachatoo commented Nov 6, 2025

Removed, was previously a comment from the eslint bot

@Zachatoo Zachatoo added Changes requested Minor changes requested PR can be merged after some final changes have been requested and removed Ready for review Changes made labels Nov 6, 2025
@ObsidianReviewBot
Copy link
Collaborator

Installing the dependencies in your plugin failed with the following error:

npm error code EUSAGE
npm error
npm error `npm ci` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with `npm install` before continuing.
npm error
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error Missing: @esbuild/[email protected] from lock file
npm error
npm error Clean install a project
npm error
npm error Usage:
npm error npm ci
npm error
npm error Options:
npm error [--install-strategy <hoisted|nested|shallow|linked>] [--legacy-bundling]
npm error [--global-style] [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]]
npm error [--include <prod|dev|optional|peer> [--include <prod|dev|optional|peer> ...]]
npm error [--strict-peer-deps] [--foreground-scripts] [--ignore-scripts] [--no-audit]
npm error [--no-bin-links] [--no-fund] [--dry-run]
npm error [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
npm error [--workspaces] [--include-workspace-root] [--install-links]
npm error
npm error aliases: clean-install, ic, install-clean, isntall-clean
npm error
npm error Run "npm help ci" for more info
npm error A complete log of this run can be found in: /root/.npm/_logs/2025-11-12T22_05_42_467Z-debug-0.log

@ObsidianReviewBot
Copy link
Collaborator

Thank you for your submission, an automated scan of your plugin code's revealed the following issues:

Required

[1][2]
The Function type accepts any function-like value.
Prefer explicitly defining any function parameters and return type.

[1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31][32][33][34][35][36][37][38][39][40][41][42][43][44][45][46][47][48][49][50][51][52][53][54][55][56][57][58][59][60][61][62][63][64][65][66][67][68][69][70][71][72][73][74][75][76][77][78][79][80][81][82][83][84]
Unexpected any. Specify a different type.

[1][2][3][4][5][6][7]
Unexpected console statement. Only these console methods are allowed: warn, error, debug.

[1][2][3]
Do not access Object.prototype method 'hasOwnProperty' from target object.

[1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22]
Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the void operator.

[1][2][3]
This assertion is unnecessary since it does not change the type of the expression.

[1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22][23][24][25][26][27][28]
Promise returned in function argument where a void return was expected.

[1][2][3][4][5][6][7][8][9]
Async arrow function has no 'await' expression.

[1][2]
'any' overrides all other types in this union type.

[1]
Async method 'addSafeInternalLink' has no 'await' expression.

[1]
Async method 'addSafeInternalLinkWithCaption' has no 'await' expression.

[1][2][3]
Unexpected await of a non-Promise (non-"Thenable") value.

[1][2][3][4][5][6]
Obsidian's configuration folder is not necessarily .obsidian, it can be configured by the user. Use Vault#configDir to get the current value

[1][2][3][4][5][6]
Use sentence case for UI text.

[1][2]
Expected non-Promise value in a boolean conditional.

[1]
Async method 'render' has no 'await' expression.

[1][2]
Async method 'onClick' has no 'await' expression.

[1]
A method that is not declared with this: void may cause unintentional scoping of this when separated from its object.
Consider using an arrow function or explicitly .bind()ing the method to avoid calling the method with an unintended this value.
If a function does not access this, it can be annotated with this: void.

[1]
Async function 'hasDisablePropertyInFile' has no 'await' expression.

[1]
Unnecessary escape character: /.

[1]
Unnecessary escape character: -.


Optional

[1][2]
'MarkdownView' is defined but never used.

[1]
'tp' is defined but never used.

[1]
'isFileExcluded' is defined but never used.

[1]
'shouldProcessFile' is defined but never used.

[1]
'containsSafeword' is defined but never used.

[1]
'extractTitle' is defined but never used.

[1]
'isValidHeading' is defined but never used.

[1]
'generateSafeLinkTarget' is defined but never used.

[1]
'normalizeTag' is defined but never used.

[1]
'RenameAllFilesModal' is defined but never used.

[1]
'RenameFolderModal' is defined but never used.

[1]
'RenameMultipleFoldersModal' is defined but never used.

[1]
'ClearSettingsModal' is defined but never used.

[1]
'ProcessTagModal' is defined but never used.

[1]
'InternalLinkModal' is defined but never used.

[1]
'RenameModal' is defined but never used.

[1]
'DisableEnableModal' is defined but never used.

[1][2]
'skipped' is assigned a value but never used.

[1]
'OSPreset' is defined but never used.

[1]
'FileReadMethod' is defined but never used.

[1][2]
'ExcludedProperty' is defined but never used.

[1]
'CharReplacements' is defined but never used.

[1]
'NodeError' is defined but never used.

[1][2][3][4][5][6]
'error' is defined but never used.

[1]
'firstLine' is assigned a value but never used.

[1]
'Editor' is defined but never used.

[1]
't' is defined but never used.

[1][2]
'TFile' is defined but never used.

[1][2][3][4][5]
'Notice' is defined but never used.

[1]
'parseYaml' is defined but never used.

[1][2]
'PluginSettings' is defined but never used.

[1]
'e' is defined but never used.

[1]
'TranslationStrings' is defined but never used.

[1]
'ensureList' is assigned a value but never used.

[1]
'App' is defined but never used.

[1]
'WorkspaceLeaf' is defined but never used.

[1]
'MetadataCache' is defined but never used.

[1]
'TFolder' is defined but never used.

[1]
'TITLE_CHAR_REVERSAL_MAP' is defined but never used.

[1]
'LIMITS' is defined but never used.

[1]
'processed' is assigned a value but never used.

[1]
'errors' is assigned a value but never used.

[1]
'Setting' is defined but never used.

[1]
'tabKey' is assigned a value but never used.

[1]
'tabNameEl' is assigned a value but never used.

[1]
'currentIndex' is assigned a value but never used.

[1]
'addAliasConditionalSetting' is assigned a value but never used.

[1]
'keepEmptyAliasPropertySetting' is assigned a value but never used.

[1]
'hideAliasPropertySetting' is assigned a value but never used.

[1]
'suppressMergeNotificationsSetting' is assigned a value but never used.

[1]
'li1' is assigned a value but never used.

[1]
'li3' is assigned a value but never used.

[1]
'folderModeSetting' is assigned a value but never used.

[1][2]
'textInput' is assigned a value but never used.

[1]
'childTagsSetting' is assigned a value but never used.

[1]
'tagModeSetting' is assigned a value but never used.

[1][2]
'colonSpan' is assigned a value but never used.

[1]
'DEFAULT_SETTINGS' is defined but never used.

[1]
'placeCursorSetting' is assigned a value but never used.

[1]
'debugContentSetting' is assigned a value but never used.

[1][2]
'nameEl' is assigned a value but never used.

[1]
'tagToFind' is assigned a value but never used.

[1]
'normalizePath' is defined but never used.

[1]
'UNIVERSAL_FORBIDDEN_CHARS' is defined but never used.

[1]
'WINDOWS_ANDROID_CHARS' is defined but never used.

[1]
'verboseLog' is defined but never used.

[1]
'stripFrontmatter' is defined but never used.


Do NOT open a new PR for re-validation.
Once you have pushed some changes to your repository the bot will rescan within 6 hours
If you think some of the required changes are incorrect, please comment with /skip and the reason why you think the results are incorrect.
To run these checks locally, install the eslint plugin in your project.
Do NOT rebase this PR, this will be handled by the reviewer once the plugin has been approved.

1 similar comment
@ObsidianReviewBot
Copy link
Collaborator

Thank you for your submission, an automated scan of your plugin code's revealed the following issues:

Required

[1][2]
The Function type accepts any function-like value.
Prefer explicitly defining any function parameters and return type.

[1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31][32][33][34][35][36][37][38][39][40][41][42][43][44][45][46][47][48][49][50][51][52][53][54][55][56][57][58][59][60][61][62][63][64][65][66][67][68][69][70][71][72][73][74][75][76][77][78][79][80][81][82][83][84]
Unexpected any. Specify a different type.

[1][2][3][4][5][6][7]
Unexpected console statement. Only these console methods are allowed: warn, error, debug.

[1][2][3]
Do not access Object.prototype method 'hasOwnProperty' from target object.

[1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22]
Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the void operator.

[1][2][3]
This assertion is unnecessary since it does not change the type of the expression.

[1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22][23][24][25][26][27][28]
Promise returned in function argument where a void return was expected.

[1][2][3][4][5][6][7][8][9]
Async arrow function has no 'await' expression.

[1][2]
'any' overrides all other types in this union type.

[1]
Async method 'addSafeInternalLink' has no 'await' expression.

[1]
Async method 'addSafeInternalLinkWithCaption' has no 'await' expression.

[1][2][3]
Unexpected await of a non-Promise (non-"Thenable") value.

[1][2][3][4][5][6]
Obsidian's configuration folder is not necessarily .obsidian, it can be configured by the user. Use Vault#configDir to get the current value

[1][2][3][4][5][6]
Use sentence case for UI text.

[1][2]
Expected non-Promise value in a boolean conditional.

[1]
Async method 'render' has no 'await' expression.

[1][2]
Async method 'onClick' has no 'await' expression.

[1]
A method that is not declared with this: void may cause unintentional scoping of this when separated from its object.
Consider using an arrow function or explicitly .bind()ing the method to avoid calling the method with an unintended this value.
If a function does not access this, it can be annotated with this: void.

[1]
Async function 'hasDisablePropertyInFile' has no 'await' expression.

[1]
Unnecessary escape character: /.

[1]
Unnecessary escape character: -.


Optional

[1][2]
'MarkdownView' is defined but never used.

[1]
'tp' is defined but never used.

[1]
'isFileExcluded' is defined but never used.

[1]
'shouldProcessFile' is defined but never used.

[1]
'containsSafeword' is defined but never used.

[1]
'extractTitle' is defined but never used.

[1]
'isValidHeading' is defined but never used.

[1]
'generateSafeLinkTarget' is defined but never used.

[1]
'normalizeTag' is defined but never used.

[1]
'RenameAllFilesModal' is defined but never used.

[1]
'RenameFolderModal' is defined but never used.

[1]
'RenameMultipleFoldersModal' is defined but never used.

[1]
'ClearSettingsModal' is defined but never used.

[1]
'ProcessTagModal' is defined but never used.

[1]
'InternalLinkModal' is defined but never used.

[1]
'RenameModal' is defined but never used.

[1]
'DisableEnableModal' is defined but never used.

[1][2]
'skipped' is assigned a value but never used.

[1]
'OSPreset' is defined but never used.

[1]
'FileReadMethod' is defined but never used.

[1][2]
'ExcludedProperty' is defined but never used.

[1]
'CharReplacements' is defined but never used.

[1]
'NodeError' is defined but never used.

[1][2][3][4][5][6]
'error' is defined but never used.

[1]
'firstLine' is assigned a value but never used.

[1]
'Editor' is defined but never used.

[1]
't' is defined but never used.

[1][2]
'TFile' is defined but never used.

[1][2][3][4][5]
'Notice' is defined but never used.

[1]
'parseYaml' is defined but never used.

[1][2]
'PluginSettings' is defined but never used.

[1]
'e' is defined but never used.

[1]
'TranslationStrings' is defined but never used.

[1]
'ensureList' is assigned a value but never used.

[1]
'App' is defined but never used.

[1]
'WorkspaceLeaf' is defined but never used.

[1]
'MetadataCache' is defined but never used.

[1]
'TFolder' is defined but never used.

[1]
'TITLE_CHAR_REVERSAL_MAP' is defined but never used.

[1]
'LIMITS' is defined but never used.

[1]
'processed' is assigned a value but never used.

[1]
'errors' is assigned a value but never used.

[1]
'Setting' is defined but never used.

[1]
'tabKey' is assigned a value but never used.

[1]
'tabNameEl' is assigned a value but never used.

[1]
'currentIndex' is assigned a value but never used.

[1]
'addAliasConditionalSetting' is assigned a value but never used.

[1]
'keepEmptyAliasPropertySetting' is assigned a value but never used.

[1]
'hideAliasPropertySetting' is assigned a value but never used.

[1]
'suppressMergeNotificationsSetting' is assigned a value but never used.

[1]
'li1' is assigned a value but never used.

[1]
'li3' is assigned a value but never used.

[1]
'folderModeSetting' is assigned a value but never used.

[1][2]
'textInput' is assigned a value but never used.

[1]
'childTagsSetting' is assigned a value but never used.

[1]
'tagModeSetting' is assigned a value but never used.

[1][2]
'colonSpan' is assigned a value but never used.

[1]
'DEFAULT_SETTINGS' is defined but never used.

[1]
'placeCursorSetting' is assigned a value but never used.

[1]
'debugContentSetting' is assigned a value but never used.

[1][2]
'nameEl' is assigned a value but never used.

[1]
'tagToFind' is assigned a value but never used.

[1]
'normalizePath' is defined but never used.

[1]
'UNIVERSAL_FORBIDDEN_CHARS' is defined but never used.

[1]
'WINDOWS_ANDROID_CHARS' is defined but never used.

[1]
'verboseLog' is defined but never used.

[1]
'stripFrontmatter' is defined but never used.


Do NOT open a new PR for re-validation.
Once you have pushed some changes to your repository the bot will rescan within 6 hours
If you think some of the required changes are incorrect, please comment with /skip and the reason why you think the results are incorrect.
To run these checks locally, install the eslint plugin in your project.
Do NOT rebase this PR, this will be handled by the reviewer once the plugin has been approved.

@ObsidianReviewBot
Copy link
Collaborator

Thank you for your submission, an automated scan of your plugin code's revealed the following issues:

Required

[1][2][3]
Disabling 'no-console' is not allowed.

[1][2][3][4][5][6]
Disabling 'obsidianmd/hardcoded-config-path' is not allowed.

[1]
Async method 'renderTab' has no 'await' expression.

[1][2][3][4][5]
Disabling 'obsidianmd/ui/sentence-case' is not allowed.


Optional

[1]
'_processed' is assigned a value but never used.

[1]
'_skipped' is assigned a value but never used.

[1]
'_errors' is assigned a value but never used.

[1]
'_tabKey' is assigned a value but never used.

[1]
'_tabNameEl' is assigned a value but never used.

[1]
'_currentIndex' is assigned a value but never used.

[1][2]
'_textInput' is assigned a value but never used.


Do NOT open a new PR for re-validation.
Once you have pushed some changes to your repository the bot will rescan within 6 hours
If you think some of the required changes are incorrect, please comment with /skip and the reason why you think the results are incorrect.
To run these checks locally, install the eslint plugin in your project.
Do NOT rebase this PR, this will be handled by the reviewer once the plugin has been approved.

@ObsidianReviewBot ObsidianReviewBot removed their assignment Dec 11, 2025
@ObsidianReviewBot ObsidianReviewBot added Ready for review and removed Changes requested Additional review required PR needs to be reviewed by another person, after the currently requested changes have been made labels Dec 11, 2025
@ObsidianReviewBot
Copy link
Collaborator

Changes requested by bot have been made, ready for for additional review by human.
Please be aware that it might take a few weeks before your plugin is reviewed due to the high volume of submissions currently.
Any changes you make to your repository will be automatically reviewed by the bot.

@Zachatoo
Copy link
Collaborator

this._originalDebugEnable = window.DEBUG?.enable;, saveCommand.checkCallback = (checking: boolean) => {
Overriding methods in this way is unsafe in a plugin ecosystem. Please consider if there is a way to do what you want without overriding methods.
If you must override this method, then please use a tool such as monkey-around to safely patch the method in a way that patches can be uninstalled in arbitrary order.

private registeredEvents: EventRef[] = [];, this.registeredEvents.forEach((ref) =>, this.registeredEvents.push(event);
Please don't manage references to events yourself, calling .registerEvent() is sufficient, Obsidian will manage these events for you.

state.currentLocale = moment.locale();
Use the getLanguage() function from the API to get the language configured in the Obsidian settings (requires minAppVersion: "1.8.0")

if (this.settings.core.enableRibbon) {, condition: this.settings.core.ribbonVisibility.renameCurrentFile,, condition: this.settings.core.ribbonVisibility.renameAllNotes,, condition: this.settings.core.ribbonVisibility.toggleAutomaticRenaming,
As of v1.1.0 of Obsidian, the ribbon can be customized within Obsidian. So users can choose what items to include and in what order all in one place. Because of this, we're recommending that new plugins avoid introducing their own toggles for ribbon items.

setupNotificationSuppression(): void {
Why are you suppressing these messages? If your plugin is causing these messages frequently, that is indicative of an issue with your plugin's code and should be fixed, instead of hiding these messages from the user.

if (file.stat.ctime < this.plugin.pluginLoadTime - 1000) {
Instead of waiting an arbitrary amount of time, wrap registering this event in this.app.workspace.onLayoutReady()

const view = leaf.view as MarkdownView;, const view = leaf.view as MarkdownView;
Use an instanceof check instead of casting using as.


Optional feedback:

setupCommandPaletteIcons(): void {
Your commands are going to look out of place in Obsidian if only your plugin's commands have icons. I recommend you don't add icons to your commands in the command palette.


I'm still working through your plugin, I would like to apologize for this taking so long, and say thank you for your patience. I believe we've fixed the bot, so hopefully we can go back and forth quicker and get this in for you.

@greetclammy
Copy link
Contributor Author

greetclammy commented Dec 13, 2025

if (this.settings.core.enableRibbon) {, condition: this.settings.core.ribbonVisibility.renameCurrentFile,, condition: this.settings.core.ribbonVisibility.renameAllNotes,, condition: this.settings.core.ribbonVisibility.toggleAutomaticRenaming, As of v1.1.0 of Obsidian, the ribbon can be customized within Obsidian. So users can choose what items to include and in what order all in one place. Because of this, we're recommending that new plugins avoid introducing their own toggles for ribbon items.

This is in place because Obsidian does not remember ribbon icon configuration if a plugin is lazy loaded, such as with Lazy Plugin Loader — hidden icons reappear in the ribbon when a plugin is loaded lazily. This issue seems to affect all plugins, not just this one. I would also like to keep this:

  • For consistency: all of the plugin's commands can be completely hidden in its settings — this affords maximal flexibility, avoids UI clutter, and prevents confusion around commands with similar names.
  • As self-documentation: each command toggle in the 'Commands' section in plugin settings has a clear and concise description of what it does. (Sometimes, I even refer to this myself.) This also informs users of all the available commands, which they might not know of, or have forgotten about. Offloading command descriptions to the README would be a net negative UX-wise.

setupNotificationSuppression(): void { Why are you suppressing these messages? If your plugin is causing these messages frequently, that is indicative of an issue with your plugin's code and should be fixed, instead of hiding these messages from the user.

I've not found a clean solution to this. It seems that Obsidian is at fault here, not my plugin.

I've seen at least one other plugin also plagued by this problem: https://github.com/alangrainger/obsidian-frontmatter-modified-date?tab=readme-ov-file#merging-changes-popup

I inquired about this problem in #plugin-dev on Discord. (There, I replied to manumov saying that his suggestion worked but I later discovered that it actually didn't.)

This notification is not only completely useless and very annoying but is actually misleading — files are modified from within Obsidian, not externally.

Without this option, the first line alias feature is utterly unusable. No overreach: the option to suppress the notification is OFF by default.


Optional feedback:

setupCommandPaletteIcons(): void { Your commands are going to look out of place in Obsidian if only your plugin's commands have icons. I recommend you don't add icons to your commands in the command palette.

This is only in place for the Quick Switcher++ plugin, which can show command icons in its command mode. The icons never appear in the vanilla Command palette.


Resolved all other issues.

@ObsidianReviewBot ObsidianReviewBot added Ready for review and removed Changes requested Minor changes requested PR can be merged after some final changes have been requested labels Dec 13, 2025
@Zachatoo
Copy link
Collaborator

This is in place because Obsidian does not remember ribbon icon configuration if a plugin is lazy loaded, such as with Lazy Plugin Loader.

That should be fixed on that plugin's end then. It doesn't change the Obsidian development guidelines.

I've not found a clean solution to this. It seems that Obsidian is at fault here, not my plugin.

It can be difficult to properly solve this problem, but it is possible. I recommend asking in that channel again for more help. Suppressing these notifications is not the answer.

Note to self: here's the link to mnaoumov's answer

This is only in place for the Quick Switcher++ plugin, which can show command icons in its command mode. The icons never appear in the vanilla Command palette.

Is that the recommended way to add icons to the Quick Switcher++ plugin commands? If so can you link to documentation around that? They should provide you with a better API than that.

@greetclammy
Copy link
Contributor Author

It doesn't change the Obsidian development guidelines.

A search through the docs only seems to bring up the Ribbon actions page, which doesn't prohibit ribbon toggles in plugin settings.

I recommend asking in that channel again for more help.

I just posted a new message in #plugin-dev.

Is that the recommended way to add icons to the Quick Switcher++ plugin commands?

Turns out my plugin's commands already had icons set via addCommand(). Removed redundant JavaScript injection code.

@ObsidianReviewBot ObsidianReviewBot added Changes requested Additional review required PR needs to be reviewed by another person, after the currently requested changes have been made and removed Ready for review labels Jan 1, 2026
@ObsidianReviewBot ObsidianReviewBot self-assigned this Jan 1, 2026
@ObsidianReviewBot
Copy link
Collaborator

Thank you for your submission, an automated scan of your plugin code's revealed the following issues:

Required

[1][2]
Unexpected undescribed directive comment. Include descriptions to explain why the comment is necessary.

[1][2]
Requires 'eslint-enable' directive for '@typescript-eslint/no-misused-promises'.


Optional

[1]
'markupStrippingSettings' is assigned a value but only used as a type.


Do NOT open a new PR for re-validation.
Once you have pushed some changes to your repository the bot will rescan within 6 hours
If you think some of the required changes are incorrect, please comment with /skip and the reason why you think the results are incorrect.
To run these checks locally, install the eslint plugin in your project.
Do NOT rebase this PR, this will be handled by the reviewer once the plugin has been approved.

@Zachatoo
Copy link
Collaborator

Zachatoo commented Jan 3, 2026

Thanks, created a PR to add that guideline to the docs, obsidianmd/obsidian-developer-docs#216

@greetclammy
Copy link
Contributor Author

Is 'no ribbon toggles' a requirement or suggestion?

@Zachatoo
Copy link
Collaborator

Zachatoo commented Jan 3, 2026

It's a requirement for new plugins, a suggestion for existing plugins.

@greetclammy greetclammy closed this by deleting the head repository Jan 9, 2026
@greetclammy
Copy link
Contributor Author

Accidentally deleted then restored greetclammy/obsidian-releases. Reopening.

@greetclammy greetclammy reopened this Jan 9, 2026
@github-actions
Copy link

github-actions bot commented Jan 9, 2026

Hello!

I found the following issues in your plugin submission

Errors:

❌ Unable to find a release with the tag 3.11.0. Make sure that the version in your manifest.json file in your repo points to the correct Github Release.


This check was done automatically. Do NOT open a new PR for re-validation. Instead, to trigger this check again, make a change to your PR and wait a few minutes, or close and re-open it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Additional review required PR needs to be reviewed by another person, after the currently requested changes have been made Changes requested plugin Validation failed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants