mirror of
https://github.com/murashit/codex-panel.git
synced 2026-07-22 06:57:10 +00:00
Refine settings descriptions
This commit is contained in:
parent
e87035ab04
commit
a2c359ea04
5 changed files with 25 additions and 43 deletions
|
|
@ -19,19 +19,11 @@ export function ArchivedThreadSection({ state }: { state: ArchivedThreadSectionS
|
|||
return (
|
||||
<>
|
||||
<SettingsGroup className="codex-panel-settings__dynamic-section codex-panel-settings__archived-section">
|
||||
<SettingsHeading
|
||||
dynamic
|
||||
name="Thread archiving"
|
||||
desc="Choose the default archive behavior and configure saved thread notes. Thread lists offer both archive choices; slash commands use the default."
|
||||
/>
|
||||
<SettingsHeading dynamic name="Thread archiving" desc="Set the default archive action and saved-note templates." />
|
||||
<ArchiveExportSettings state={state} />
|
||||
</SettingsGroup>
|
||||
<SettingsGroup className="codex-panel-settings__dynamic-section codex-panel-settings__archived-threads-section">
|
||||
<SettingsHeading
|
||||
dynamic
|
||||
name="Archived threads"
|
||||
desc="Restore archived threads, or permanently delete archived threads you no longer need."
|
||||
/>
|
||||
<SettingsHeading dynamic name="Archived threads" desc="Restore or permanently delete archived Codex threads." />
|
||||
{state.contentAvailable ? (
|
||||
<ArchivedThreadList state={state} />
|
||||
) : !state.loading && state.status ? (
|
||||
|
|
@ -45,10 +37,7 @@ export function ArchivedThreadSection({ state }: { state: ArchivedThreadSectionS
|
|||
function ArchiveExportSettings({ state }: { state: ArchivedThreadSectionState }): UiNode {
|
||||
return (
|
||||
<SettingsItems>
|
||||
<SettingRow
|
||||
name="Save note by default"
|
||||
desc="When on, the default archive action saves a markdown note before archiving. When off, the default archives without saving. If saving fails, the thread stays active. Frontmatter includes title, thread_id, created, and optional tags."
|
||||
>
|
||||
<SettingRow name="Save note by default" desc="Save a Markdown note during the default archive action.">
|
||||
<ToggleControl
|
||||
checked={state.exportEnabled}
|
||||
onChange={(checked) => {
|
||||
|
|
@ -56,7 +45,7 @@ function ArchiveExportSettings({ state }: { state: ArchivedThreadSectionState })
|
|||
}}
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow name="Saved note folder" desc="Vault-relative folder for saved thread notes. The folder is created when needed.">
|
||||
<SettingRow name="Saved note folder" desc="Vault folder for saved thread notes.">
|
||||
<TextControl
|
||||
placeholder="Codex archives"
|
||||
value={state.exportFolderTemplate}
|
||||
|
|
@ -65,10 +54,7 @@ function ArchiveExportSettings({ state }: { state: ArchivedThreadSectionState })
|
|||
}}
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
name="Saved note filename"
|
||||
desc="Filename template. Variables: {{date}}, {{time}}, {{title}}, {{id}}, {{shortId}}. Existing files get a numeric suffix."
|
||||
>
|
||||
<SettingRow name="Saved note filename" desc="Filename template. Supports {{date}}, {{time}}, {{title}}, {{id}}, and {{shortId}}.">
|
||||
<TextControl
|
||||
placeholder="{{date}} {{time}} {{title}} {{shortId}}.md"
|
||||
value={state.exportFilenameTemplate}
|
||||
|
|
@ -77,7 +63,7 @@ function ArchiveExportSettings({ state }: { state: ArchivedThreadSectionState })
|
|||
}}
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow name="Saved note tags" desc="Comma-separated fixed tags for saved notes. Leave empty to omit tags.">
|
||||
<SettingRow name="Saved note tags" desc="Tags added to saved notes, separated by commas.">
|
||||
<TextControl
|
||||
placeholder="Codex, archive"
|
||||
value={state.exportTags}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export function HelperSettingsSection({ state }: { state: HelperSettingsState })
|
|||
<SettingsItems>
|
||||
<ModelEffortSetting
|
||||
name="Automatic thread naming"
|
||||
desc="Choose the model and reasoning effort used to suggest thread names."
|
||||
desc="Model and effort for generated thread names."
|
||||
modelValue={state.threadNamingModel}
|
||||
effortValue={state.threadNamingEffort}
|
||||
models={state.models}
|
||||
|
|
@ -23,7 +23,7 @@ export function HelperSettingsSection({ state }: { state: HelperSettingsState })
|
|||
/>
|
||||
<ModelEffortSetting
|
||||
name="Selection rewrite"
|
||||
desc="Choose the model and reasoning effort used by rewrite selection."
|
||||
desc="Model and effort for rewriting selected note text."
|
||||
modelValue={state.rewriteSelectionModel}
|
||||
effortValue={state.rewriteSelectionEffort}
|
||||
models={state.models}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { SettingRow, SettingsGroup, SettingsHeading, SettingsItems, SettingsStat
|
|||
export function HookSection({ state }: { state: HookSectionState }): UiNode {
|
||||
return (
|
||||
<SettingsGroup className="codex-panel-settings__dynamic-section codex-panel-settings__hook-section">
|
||||
<SettingsHeading dynamic name="Hook status" desc="Review discovered hooks, trust changes, and turn hooks on or off." />
|
||||
<SettingsHeading dynamic name="Hook status" desc="Trust, enable, or disable discovered Codex hooks." />
|
||||
{state.contentAvailable ? (
|
||||
<Hooks state={state} />
|
||||
) : !state.loading && state.status ? (
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ import type { CodexPanelSettingTabHost } from "./host";
|
|||
import { HookSection } from "./hook-section";
|
||||
import type { SettingsSectionsState } from "./section-state";
|
||||
|
||||
const SETTINGS_INTRO_TEXT =
|
||||
"Codex Panel stores only panel preferences. Models, sandboxing, approvals, MCP servers, hooks, and network access still come from Codex config.";
|
||||
const SETTINGS_INTRO_TEXT = "Codex Panel stores panel preferences only. Runtime settings still come from Codex.";
|
||||
const SEND_SHORTCUT_LABELS = {
|
||||
enter: "Enter",
|
||||
"mod-enter": "Cmd/Ctrl+Enter",
|
||||
|
|
@ -103,7 +102,7 @@ export class CodexPanelSettingTab extends PluginSettingTab {
|
|||
|
||||
new Setting(configItems)
|
||||
.setName("Codex executable")
|
||||
.setDesc("Path used to start `codex app-server`. Use an absolute path if Obsidian cannot find `codex`.")
|
||||
.setDesc("Command used to start `codex app-server`; use an absolute path if needed.")
|
||||
.addText((text) => {
|
||||
text.setPlaceholder(DEFAULT_CODEX_PATH).setValue(this.plugin.settings.codexPath);
|
||||
const commitCodexPath = () => {
|
||||
|
|
@ -119,7 +118,7 @@ export class CodexPanelSettingTab extends PluginSettingTab {
|
|||
});
|
||||
new Setting(configItems)
|
||||
.setName("Show chat toolbar")
|
||||
.setDesc("Show the chat panel toolbar. Slash commands, composer status controls, and the threads view remain available when hidden.")
|
||||
.setDesc("Show the toolbar above the chat panel.")
|
||||
.addToggle((toggle) => {
|
||||
toggle.setValue(this.plugin.settings.showToolbar).onChange(async (value) => {
|
||||
this.plugin.settings.showToolbar = value;
|
||||
|
|
@ -133,9 +132,7 @@ export class CodexPanelSettingTab extends PluginSettingTab {
|
|||
const composerItems = createSettingsItems(composerSection);
|
||||
new Setting(composerItems)
|
||||
.setName("Send shortcut")
|
||||
.setDesc(
|
||||
"Choose how the composer sends messages. Shift+Enter inserts a newline when Enter sends. Obsidian hotkeys may intercept Cmd/Ctrl+Enter.",
|
||||
)
|
||||
.setDesc("Pick Enter or Cmd/Ctrl+Enter. Shift+Enter adds a newline when Enter sends.")
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown.addOption("enter", SEND_SHORTCUT_LABELS.enter);
|
||||
dropdown.addOption("mod-enter", SEND_SHORTCUT_LABELS["mod-enter"]);
|
||||
|
|
@ -147,7 +144,7 @@ export class CodexPanelSettingTab extends PluginSettingTab {
|
|||
});
|
||||
new Setting(composerItems)
|
||||
.setName("Scroll thread from composer edges")
|
||||
.setDesc("When enabled, Up/Ctrl+P on the first composer line and Down/Ctrl+N on the last line scroll the thread.")
|
||||
.setDesc("Use Up/Ctrl+P and Down/Ctrl+N at composer edges to scroll the thread.")
|
||||
.addToggle((toggle) => {
|
||||
toggle.setValue(this.plugin.settings.scrollThreadFromComposerEdges).onChange(async (value) => {
|
||||
this.plugin.settings.scrollThreadFromComposerEdges = value;
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ describe("settings tab", () => {
|
|||
expect(buttonTexts(tab)).not.toContain("Load archive list");
|
||||
expect(
|
||||
tab.containerEl.querySelector(".codex-panel-settings__header.setting-item-heading .setting-item-description")?.textContent,
|
||||
).toContain("Codex Panel stores only panel preferences");
|
||||
).toContain("Codex Panel stores panel preferences only");
|
||||
expect(tab.containerEl.querySelector(".codex-panel-settings__header button")?.getAttribute("data-icon")).toBe("refresh-cw");
|
||||
expect(tab.containerEl.querySelector("h2")).toBeNull();
|
||||
expect(tab.containerEl.querySelector(".codex-panel-settings__general-section.setting-group > .setting-items")?.children).toHaveLength(
|
||||
|
|
@ -85,14 +85,14 @@ describe("settings tab", () => {
|
|||
expect(
|
||||
tab.containerEl.querySelector(".codex-panel-settings__archived-section > .setting-item-heading .setting-item-description")
|
||||
?.textContent,
|
||||
).toContain("Choose the default archive behavior");
|
||||
).toContain("Set the default archive action");
|
||||
expect(
|
||||
tab.containerEl.querySelector(".codex-panel-settings__archived-threads-section > .setting-item-heading .setting-item-description")
|
||||
?.textContent,
|
||||
).toContain("Restore archived threads");
|
||||
).toContain("Restore or permanently delete");
|
||||
expect(
|
||||
tab.containerEl.querySelector(".codex-panel-settings__hook-section > .setting-item-heading .setting-item-description")?.textContent,
|
||||
).toContain("Review discovered hooks");
|
||||
).toContain("Trust, enable, or disable");
|
||||
expect(
|
||||
tab.containerEl.querySelector(
|
||||
".codex-panel-settings__archived-section.setting-group > .setting-items:not(.codex-panel-settings__dynamic-list)",
|
||||
|
|
@ -117,7 +117,7 @@ describe("settings tab", () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it("saves the send shortcut setting and warns about Obsidian hotkeys", async () => {
|
||||
it("saves the send shortcut setting and describes newline behavior", async () => {
|
||||
const saveSettings = vi.fn().mockResolvedValue(undefined);
|
||||
const tab = newSettingsTab({ saveSettings });
|
||||
|
||||
|
|
@ -131,8 +131,8 @@ describe("settings tab", () => {
|
|||
await flushPromises();
|
||||
|
||||
expect(saveSettings).toHaveBeenCalledOnce();
|
||||
expect(settingDesc(tab, "Send shortcut")).toContain("Obsidian hotkeys");
|
||||
expect(tab.containerEl.querySelector(".codex-panel-settings__section-status")?.textContent ?? "").not.toContain("Obsidian hotkeys");
|
||||
expect(settingDesc(tab, "Send shortcut")).toContain("Shift+Enter adds a newline");
|
||||
expect(tab.containerEl.querySelector(".codex-panel-settings__section-status")?.textContent ?? "").not.toContain("Shift+Enter");
|
||||
});
|
||||
|
||||
it("saves the toolbar visibility setting and refreshes open panels", async () => {
|
||||
|
|
@ -150,7 +150,7 @@ describe("settings tab", () => {
|
|||
|
||||
expect(saveSettings).toHaveBeenCalledOnce();
|
||||
expect(refreshOpenViews).toHaveBeenCalledOnce();
|
||||
expect(settingDesc(tab, "Show chat toolbar")).toContain("Slash commands");
|
||||
expect(settingDesc(tab, "Show chat toolbar")).toContain("toolbar above the chat panel");
|
||||
});
|
||||
|
||||
it("saves the composer edge scroll setting", async () => {
|
||||
|
|
@ -198,10 +198,9 @@ describe("settings tab", () => {
|
|||
await flushPromises();
|
||||
|
||||
expect(saveSettings).toHaveBeenCalledTimes(4);
|
||||
expect(tab.containerEl.textContent).toContain("title, thread_id, created, and optional tags");
|
||||
expect(settingDesc(tab, "Save note by default")).toContain("default archive action");
|
||||
expect(settingDesc(tab, "Save note by default")).toContain("If saving fails");
|
||||
expect(settingDesc(tab, "Saved note tags")).toContain("Leave empty to omit tags");
|
||||
expect(settingDesc(tab, "Saved note filename")).toContain("{{shortId}}");
|
||||
expect(settingDesc(tab, "Saved note tags")).toContain("separated by commas");
|
||||
});
|
||||
|
||||
it("refreshes models, hooks, and archived threads from the global refresh button", async () => {
|
||||
|
|
@ -730,7 +729,7 @@ describe("settings tab", () => {
|
|||
tab.display();
|
||||
await flushPromises();
|
||||
|
||||
expect(tab.containerEl.textContent).toContain("Restore archived threads, or permanently delete archived threads you no longer need.");
|
||||
expect(tab.containerEl.textContent).toContain("Restore or permanently delete archived Codex threads.");
|
||||
expect(tab.containerEl.textContent).not.toContain("Loaded 1 hook from Codex app server.");
|
||||
expect(tab.containerEl.textContent).not.toContain("Loaded 1 archived thread from Codex app server.");
|
||||
expect(tab.containerEl.querySelector(".codex-panel-settings__hook-section .setting-item-heading")?.textContent).toContain(
|
||||
|
|
|
|||
Loading…
Reference in a new issue