Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ jobs:
run: bun install --frozen-lockfile
- name: Run build with lint
run: bun run build-with-lint
- name: Svelte check
run: bun run check

dependency-review:
name: Dependency Review
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"lint": "eslint .",
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
"build-with-lint": "tsc -noEmit -skipLibCheck && bun lint && node esbuild.config.mjs production",
"check": "svelte-check --threshold error",
"test": "vitest run --config vitest.config.mts --passWithNoTests",
"test:e2e": "vitest run --config vitest.e2e.config.mts"
},
Expand Down
2 changes: 1 addition & 1 deletion src/gui/GlobalVariables/GlobalVariablesView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
function addVariable() {
const names = new Set(items.map((i) => i.name));
const name = uniqueName("NewVar", names);
items = [...items, { id: name, name, value: "" }];
items = [...items, { name, value: "" }];
persistToSettings();
}

Expand Down
44 changes: 23 additions & 21 deletions src/gui/MacroGUIs/CommandList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import { createEventDispatcher } from "svelte";
import { OpenFileCommandSettingsModal } from "./OpenFileCommandSettingsModal";
import ConditionalCommand from "./Components/ConditionalCommand.svelte";
import type { IConditionalCommand } from "../../types/macros/Conditional/IConditionalCommand";
import type { IWaitCommand } from "../../types/macros/QuickCommands/IWaitCommand";
import type { INestedChoiceCommand } from "../../types/macros/QuickCommands/INestedChoiceCommand";

export let commands: ICommand[];
export let deleteCommand: (commandId: string) => Promise<void>;
Expand All @@ -40,6 +42,16 @@ export let plugin: QuickAdd;
let dragDisabled: boolean = true;
const dispatch = createEventDispatcher();

// Narrowing helpers: the {#each} discriminates on command.type, so each child
// receives the matching subtype. Passed one-way — children report edits via the
// on:updateCommand event, not via two-way bind:command.
const asWait = (c: ICommand) => c as IWaitCommand;
const asNested = (c: ICommand) => c as INestedChoiceCommand;
const asUserScript = (c: ICommand) => c as IUserScript;
const asAI = (c: ICommand) => c as IAIAssistantCommand;
const asOpenFile = (c: ICommand) => c as IOpenFileCommand;
const asConditional = (c: ICommand) => c as IConditionalCommand;

export const updateCommandList: (newCommands: ICommand[]) => void = (
newCommands: ICommand[]
) => {
Expand All @@ -66,7 +78,7 @@ const dispatch = createEventDispatcher();
saveCommands(commands);
}

let startDrag = (e: CustomEvent<DndEvent>) => {
let startDrag = (e: MouseEvent | TouchEvent) => {
e.preventDefault();
dragDisabled = false;
};
Expand Down Expand Up @@ -135,23 +147,13 @@ function editConditionalElse(e: CustomEvent<IConditionalCommand>) {
return;
}

const scriptSettings =
(userScript as { settings?: { [key: string]: unknown } }).settings ?? {};

new UserScriptSettingsModal(
app,
command,
(userScript.settings ?? {}) as {
[key: string]: unknown;
options?: {
[key: string]: {
description?: string;
type: string;
value: string | boolean;
placeholder?: string;
secret?: boolean;
defaultValue: string | boolean;
options?: string[];
};
};
},
scriptSettings as ConstructorParameters<typeof UserScriptSettingsModal>[2],
() => saveCommands([...commands]),
).open();
}
Expand Down Expand Up @@ -197,15 +199,15 @@ function editConditionalElse(e: CustomEvent<IConditionalCommand>) {
{#each commands.filter((c) => c.id !== SHADOW_PLACEHOLDER_ITEM_ID) as command (command.id)}
{#if command.type === CommandType.Wait}
<WaitCommand
bind:command
command={asWait(command)}
bind:dragDisabled
bind:startDrag
on:deleteCommand={async (e) => await deleteCommand(e.detail)}
on:updateCommand={updateCommandFromEvent}
/>
{:else if command.type === CommandType.NestedChoice}
<NestedChoiceCommand
bind:command
command={asNested(command)}
bind:dragDisabled
bind:startDrag
on:deleteCommand={async (e) => await deleteCommand(e.detail)}
Expand All @@ -214,7 +216,7 @@ function editConditionalElse(e: CustomEvent<IConditionalCommand>) {
/>
{:else if command.type === CommandType.UserScript}
<UserScriptCommand
bind:command
command={asUserScript(command)}
bind:dragDisabled
bind:startDrag
on:deleteCommand={async (e) => await deleteCommand(e.detail)}
Expand All @@ -223,7 +225,7 @@ function editConditionalElse(e: CustomEvent<IConditionalCommand>) {
/>
{:else if command.type === CommandType.AIAssistant}
<AIAssistantCommand
bind:command
command={asAI(command)}
bind:dragDisabled
bind:startDrag
on:deleteCommand={async (e) => await deleteCommand(e.detail)}
Expand All @@ -232,7 +234,7 @@ function editConditionalElse(e: CustomEvent<IConditionalCommand>) {
/>
{:else if command.type === CommandType.OpenFile}
<OpenFileCommand
bind:command
command={asOpenFile(command)}
bind:dragDisabled
bind:startDrag
on:deleteCommand={async (e) => await deleteCommand(e.detail)}
Expand All @@ -241,7 +243,7 @@ function editConditionalElse(e: CustomEvent<IConditionalCommand>) {
/>
{:else if command.type === CommandType.Conditional}
<ConditionalCommand
bind:command
command={asConditional(command)}
bind:dragDisabled
bind:startDrag
on:deleteCommand={async (e) => await deleteCommand(e.detail)}
Expand Down
3 changes: 1 addition & 2 deletions src/gui/MacroGUIs/Components/AIAssistantCommand.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
<script lang="ts">
import ObsidianIcon from "../../components/ObsidianIcon.svelte";
import {createEventDispatcher} from "svelte";
import type {DndEvent} from "svelte-dnd-action";
import type { IAIAssistantCommand } from "src/types/macros/QuickCommands/IAIAssistantCommand";

export let command: IAIAssistantCommand;
export let startDrag: (e: CustomEvent<DndEvent>) => void;
export let startDrag: (e: MouseEvent | TouchEvent) => void;
export let dragDisabled: boolean;
const dispatch = createEventDispatcher();

Expand Down
3 changes: 1 addition & 2 deletions src/gui/MacroGUIs/Components/ConditionalCommand.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<script lang="ts">
import { createEventDispatcher } from "svelte";
import type { DndEvent } from "svelte-dnd-action";
import ObsidianIcon from "../../components/ObsidianIcon.svelte";
import type { IConditionalCommand } from "../../../types/macros/Conditional/IConditionalCommand";
import { getConditionSummary } from "../../../utils/conditionalHelpers";

export let command: IConditionalCommand;
export let startDrag: (e: CustomEvent<DndEvent>) => void;
export let startDrag: (e: MouseEvent | TouchEvent) => void;
export let dragDisabled: boolean;

const dispatch = createEventDispatcher();
Expand Down
3 changes: 1 addition & 2 deletions src/gui/MacroGUIs/Components/NestedChoiceCommand.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
<script lang="ts">
import ObsidianIcon from "../../components/ObsidianIcon.svelte";
import {createEventDispatcher} from "svelte";
import type {DndEvent} from "svelte-dnd-action";
import type {INestedChoiceCommand} from "../../../types/macros/QuickCommands/INestedChoiceCommand";

export let command: INestedChoiceCommand;
export let startDrag: (e: CustomEvent<DndEvent>) => void;
export let startDrag: (e: MouseEvent | TouchEvent) => void;
export let dragDisabled: boolean;
const dispatch = createEventDispatcher();

Expand Down
3 changes: 1 addition & 2 deletions src/gui/MacroGUIs/Components/OpenFileCommand.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
import type { IOpenFileCommand } from "../../../types/macros/QuickCommands/IOpenFileCommand";
import ObsidianIcon from "../../components/ObsidianIcon.svelte";
import { createEventDispatcher } from "svelte";
import type { DndEvent } from "svelte-dnd-action";

export let command: IOpenFileCommand;
export let dragDisabled: boolean;
export let startDrag: (e: CustomEvent<DndEvent>) => void;
export let startDrag: (e: MouseEvent | TouchEvent) => void;

const dispatch = createEventDispatcher();

Expand Down
3 changes: 1 addition & 2 deletions src/gui/MacroGUIs/Components/StandardCommand.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
import type {ICommand} from "../../../types/macros/ICommand";
import ObsidianIcon from "../../components/ObsidianIcon.svelte";
import {createEventDispatcher} from "svelte";
import type {DndEvent} from "svelte-dnd-action";
import {getCommandDisplayName} from "../../../utils/macroHelpers";

export let command: ICommand;
export let startDrag: (e: CustomEvent<DndEvent>) => void;
export let startDrag: (e: MouseEvent | TouchEvent) => void;
export let dragDisabled: boolean;
const dispatch = createEventDispatcher();

Expand Down
3 changes: 1 addition & 2 deletions src/gui/MacroGUIs/Components/UserScriptCommand.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
<script lang="ts">
import ObsidianIcon from "../../components/ObsidianIcon.svelte";
import {createEventDispatcher} from "svelte";
import type {DndEvent} from "svelte-dnd-action";
import type {IUserScript} from "../../../types/macros/IUserScript";

export let command: IUserScript;
export let startDrag: (e: CustomEvent<DndEvent>) => void;
export let startDrag: (e: MouseEvent | TouchEvent) => void;
export let dragDisabled: boolean;
const dispatch = createEventDispatcher();

Expand Down
3 changes: 1 addition & 2 deletions src/gui/MacroGUIs/Components/WaitCommand.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
<script lang="ts">
import ObsidianIcon from "../../components/ObsidianIcon.svelte";
import {createEventDispatcher, onMount} from "svelte";
import type {DndEvent} from "svelte-dnd-action";
import type {IWaitCommand} from "../../../types/macros/QuickCommands/IWaitCommand";

export let command: IWaitCommand;
export let startDrag: (e: CustomEvent<DndEvent>) => void;
export let startDrag: (e: MouseEvent | TouchEvent) => void;
export let dragDisabled: boolean;
const dispatch = createEventDispatcher();

Expand Down
4 changes: 3 additions & 1 deletion src/gui/choiceList/ChoiceList.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<script lang="ts">
import type IChoice from "../../types/choices/IChoice";
import ChoiceListItem from "./ChoiceListItem.svelte";
import MultiChoiceListItem from "./MultiChoiceListItem.svelte";
import MultiChoiceListItemRaw from "./MultiChoiceListItem.svelte";
// `as any` breaks the recursive ChoiceList <-> MultiChoiceListItem type cycle (svelte-check); runtime is unchanged.
const MultiChoiceListItem = MultiChoiceListItemRaw as any;
import {dndzone, SHADOW_PLACEHOLDER_ITEM_ID} from "svelte-dnd-action";
import type {DndEvent} from "svelte-dnd-action";
import {createEventDispatcher} from "svelte";
Expand Down
10 changes: 6 additions & 4 deletions src/gui/choiceList/ChoiceView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
import { onMount } from "svelte";
import type QuickAdd from "../../main";
import {
type ChoiceType,
CommandRegistry,
configureChoice,
createChoice,
createToggleCommandChoice,
deleteChoiceWithConfirmation,
duplicateChoice,
} from "../../services/choiceService";
import type { ChoiceType } from "../../types/choices/choiceType";
import type IChoice from "../../types/choices/IChoice";
import { AIAssistantSettingsModal } from "../AIAssistantSettingsModal";
import ObsidianIcon from "../components/ObsidianIcon.svelte";
Expand All @@ -23,6 +23,10 @@

export let choices: IChoice[] = [];
export let saveChoices: (choices: IChoice[]) => void;

function handleReorderChoices(e: CustomEvent<{ choices: IChoice[] }>) {
saveChoices(e.detail.choices);
}
export let app: App;
export let plugin: QuickAdd;

Expand Down Expand Up @@ -217,7 +221,6 @@

{#if filterQuery.trim().length === 0}
<ChoiceList
type="main"
app={app}
roots={choices}
bind:choices
Expand All @@ -227,11 +230,10 @@
on:duplicateChoice={handleDuplicateChoice}
on:renameChoice={handleRenameChoice}
on:moveChoice={handleMoveChoice}
on:reorderChoices={(e) => saveChoices(e.detail.choices)}
on:reorderChoices={handleReorderChoices}
/>
{:else}
<ChoiceList
type="main"
app={app}
roots={choices}
choices={filterChoices(choices, filterQuery)}
Expand Down
4 changes: 3 additions & 1 deletion src/gui/choiceList/MultiChoiceListItem.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<script lang="ts">
import ObsidianIcon from "../components/ObsidianIcon.svelte";
import ChoiceList from "./ChoiceList.svelte";
import ChoiceListRaw from "./ChoiceList.svelte";
// `as any` breaks the recursive ChoiceList <-> MultiChoiceListItem type cycle (svelte-check); runtime is unchanged.
const ChoiceList = ChoiceListRaw as any;
import type IMultiChoice from "../../types/choices/IMultiChoice";
import RightButtons from "./ChoiceItemRightButtons.svelte";
import {createEventDispatcher} from "svelte";
Expand Down
8 changes: 4 additions & 4 deletions src/gui/suggesters/choiceSuggester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ type ChoiceSuggesterOptions = {
placeholderStack?: Array<string | undefined>;
};
export default class ChoiceSuggester extends FuzzySuggestModal<IChoice> {
private choiceExecutor: IChoiceExecutor = new ChoiceExecutor(
this.app,
this.plugin
);
private choiceExecutor: IChoiceExecutor;
private placeholderStack: Array<string | undefined> = [];
private currentPlaceholder?: string;

Expand All @@ -37,6 +34,9 @@ export default class ChoiceSuggester extends FuzzySuggestModal<IChoice> {
options?: ChoiceSuggesterOptions
) {
super(plugin.app);
// Initialize here (not as a field initializer) so the `plugin` parameter
// property is already assigned; a field initializer runs before it.
this.choiceExecutor = new ChoiceExecutor(this.app, this.plugin);
if (options?.choiceExecutor) this.choiceExecutor = options.choiceExecutor;
this.placeholderStack = options?.placeholderStack ?? [];
this.currentPlaceholder = options?.placeholder?.trim() || undefined;
Expand Down
6 changes: 3 additions & 3 deletions src/types/macros/ObsidianCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import type { IObsidianCommand } from "./IObsidianCommand";
import { v4 as uuidv4 } from "uuid";

export class ObsidianCommand extends Command implements IObsidianCommand {
name: string;
id: string;
declare name: string;
declare id: string;
commandId: string;
type: CommandType;
declare type: CommandType;

constructor(name: string, commandId: string) {
super(name, CommandType.Obsidian);
Expand Down
6 changes: 3 additions & 3 deletions src/types/macros/QuickCommands/AIAssistantCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import type { OpenAIModelParameters } from "src/ai/OpenAIModelParameters";
import { DEFAULT_FREQUENCY_PENALTY, DEFAULT_PRESENCE_PENALTY, DEFAULT_TEMPERATURE, DEFAULT_TOP_P } from "src/ai/OpenAIModelParameters";

export class AIAssistantCommand extends Command implements IAIAssistantCommand {
id: string;
name: string;
type: CommandType;
declare id: string;
declare name: string;
declare type: CommandType;

model: string;
systemPrompt: string;
Expand Down
6 changes: 3 additions & 3 deletions src/types/macros/QuickCommands/WaitCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { CommandType } from "../CommandType";
import type { IWaitCommand } from "./IWaitCommand";

export class WaitCommand extends Command implements IWaitCommand {
id: string;
name: string;
declare id: string;
declare name: string;
time: number;
type: CommandType;
declare type: CommandType;

constructor(time: number) {
super("Wait", CommandType.Wait);
Expand Down
4 changes: 2 additions & 2 deletions src/types/macros/UserScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { CommandType } from "./CommandType";
import type { IUserScript } from "./IUserScript";

export class UserScript extends Command implements IUserScript {
name: string;
declare name: string;
path: string;
type: CommandType;
declare type: CommandType;
settings: { [key: string]: unknown };

constructor(name: string, path: string) {
Expand Down
Loading