History

fix: address plugin command review findings

t3-code[bot] committed 2 months ago

Commit ceb36401 parent 12b8e9e5 files · +24 −9Browse files

Unified · Split

5 files
  1. apps/mobile/src/features/threads/NewTaskDraftScreen.tsx +3 −1
  2. apps/mobile/src/features/threads/plugin-command-menu.test.ts +7 −0
  3. apps/mobile/src/features/threads/plugin-command-menu.ts +5 −0
  4. apps/server/src/plugins/PluginCommandCatalog.ts +8 −8
  5. packages/contracts/src/pluginCommands.ts +1 −0
apps/mobile/src/features/threads/NewTaskDraftScreen.tsx+3−1
@@ -74,6 +74,7 @@ import { detectComposerTrigger, replaceTextRange } from "@t3tools/shared/compose · 73 unmodified lines
74import { ComposerCommandPopover, type ComposerCommandItem } from "./ComposerCommandPopover";74import { ComposerCommandPopover, type ComposerCommandItem } from "./ComposerCommandPopover";
75import {75import {
76 buildMobilePluginCommandItems,76 buildMobilePluginCommandItems,
77 isCollapsedComposerSelection,
77 reconcileComposerSelectionForTextChange,78 reconcileComposerSelectionForTextChange,
78} from "./plugin-command-menu";79} from "./plugin-command-menu";
79import { useMobilePluginCommands } from "./use-mobile-plugin-commands";80import { useMobilePluginCommands } from "./use-mobile-plugin-commands";
@@ -146,9 +147,10 @@ export function NewTaskDraftScreen(props: { · 66 unmodified lines
146 selectedProject?.environmentId ?? null,147 selectedProject?.environmentId ?? null,
147 );148 );
148 const pluginCommandTrigger = useMemo(() => {149 const pluginCommandTrigger = useMemo(() => {
150 if (!isCollapsedComposerSelection(composerSelection)) return null;
149 const trigger = detectComposerTrigger(flow.prompt, composerSelection.end);151 const trigger = detectComposerTrigger(flow.prompt, composerSelection.end);
150 return trigger?.kind === "slash-command" ? trigger : null;152 return trigger?.kind === "slash-command" ? trigger : null;
151 }, [composerSelection.end, flow.prompt]);153 }, [composerSelection, flow.prompt]);
152 const pluginCommandItems = useMemo<ComposerCommandItem[]>(() => {154 const pluginCommandItems = useMemo<ComposerCommandItem[]>(() => {
153 if (pluginCommandTrigger === null) return [];155 if (pluginCommandTrigger === null) return [];
154 return buildMobilePluginCommandItems(pluginCommands, pluginCommandTrigger.query);156 return buildMobilePluginCommandItems(pluginCommands, pluginCommandTrigger.query);
apps/mobile/src/features/threads/plugin-command-menu.test.ts+7−0
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vite-plus/test"; · 1 unmodified line
2 2
3import {3import {
4 buildMobilePluginCommandItems,4 buildMobilePluginCommandItems,
5 isCollapsedComposerSelection,
5 reconcileComposerSelectionForTextChange,6 reconcileComposerSelectionForTextChange,
6} from "./plugin-command-menu";7} from "./plugin-command-menu";
7 8
@@ -37,3 +38,9 @@ describe("reconcileComposerSelectionForTextChange", () => { · 29 unmodified lines
37 });38 });
38 });39 });
39});40});
41
42describe("isCollapsedComposerSelection", () => {
43 it("rejects a highlighted range", () => {
44 expect(isCollapsedComposerSelection({ start: 0, end: 7 })).toBe(false);
45 });
46});
apps/mobile/src/features/threads/plugin-command-menu.ts+5−0
@@ -2,6 +2,11 @@ import type { PluginCommand } from "@t3tools/contracts"; · 1 unmodified line
2 2
3import type { ComposerCommandItem } from "./ComposerCommandPopover";3import type { ComposerCommandItem } from "./ComposerCommandPopover";
4 4
5export const isCollapsedComposerSelection = (selection: {
6 readonly start: number;
7 readonly end: number;
8}): boolean => selection.start === selection.end;
9
5export function reconcileComposerSelectionForTextChange(10export function reconcileComposerSelectionForTextChange(
6 selection: { readonly start: number; readonly end: number },11 selection: { readonly start: number; readonly end: number },
7 previousLength: number,12 previousLength: number,
apps/server/src/plugins/PluginCommandCatalog.ts+8−8
@@ -55,8 +55,12 @@ type PluginCommandHandler = Effect.Effect< · 54 unmodified lines
55 55
56export class PluginCommandDefinitionError extends Schema.TaggedErrorClass<PluginCommandDefinitionError>()(56export class PluginCommandDefinitionError extends Schema.TaggedErrorClass<PluginCommandDefinitionError>()(
57 "PluginCommandDefinitionError",57 "PluginCommandDefinitionError",
58 { message: Schema.String },58 { cause: Schema.Defect(), id: Schema.String },
59) {}59) {
60 override get message(): string {
61 return `Plugin command ${this.id} has invalid declarative metadata.`;
62 }
63}
60 64
61export interface PluginCommandRegistration {65export interface PluginCommandRegistration {
62 readonly command: PluginCommand;66 readonly command: PluginCommand;
@@ -108,12 +112,7 @@ const catalogFromRuntime = Effect.fn("PluginCommandCatalog.catalogFromRuntime")( · 45 unmodified lines
108 const snapshot = yield* runtime.contributions(COMMAND_SLOT);112 const snapshot = yield* runtime.contributions(COMMAND_SLOT);
109 const commands = yield* Effect.forEach(snapshot.entries, (entry) =>113 const commands = yield* Effect.forEach(snapshot.entries, (entry) =>
110 decodePluginCommandEffect(commandInputFromContribution(entry)).pipe(114 decodePluginCommandEffect(commandInputFromContribution(entry)).pipe(
111 Effect.mapError(115 Effect.mapError((cause) => new PluginCommandDefinitionError({ cause, id: entry.id })),
112 () =>
113 new PluginCommandDefinitionError({
114 message: `Plugin command ${entry.id} has invalid declarative metadata.`,
115 }),
116 ),
117 ),116 ),
118 );117 );
119 const frozenCommands = commands.map((command) =>118 const frozenCommands = commands.map((command) =>
@@ -197,6 +196,7 @@ export const make = Effect.gen(function* () { · 77 unmodified lines
197 return new PluginCommandNotFoundError({ id: input.id });196 return new PluginCommandNotFoundError({ id: input.id });
198 }197 }
199 return new PluginCommandInvocationError({198 return new PluginCommandInvocationError({
199 cause: error,
200 id: input.id,200 id: input.id,
201 message: "Plugin command failed.",201 message: "Plugin command failed.",
202 });202 });
packages/contracts/src/pluginCommands.ts+1−0
@@ -58,6 +58,7 @@ export class PluginCommandCatalogChangedError extends Schema.TaggedErrorClass<Pl · 57 unmodified lines
58export class PluginCommandInvocationError extends Schema.TaggedErrorClass<PluginCommandInvocationError>()(58export class PluginCommandInvocationError extends Schema.TaggedErrorClass<PluginCommandInvocationError>()(
59 "PluginCommandInvocationError",59 "PluginCommandInvocationError",
60 {60 {
61 cause: Schema.Defect(),
61 id: PluginCommandId,62 id: PluginCommandId,
62 message: TrimmedNonEmptyString.check(Schema.isMaxLength(500)),63 message: TrimmedNonEmptyString.check(Schema.isMaxLength(500)),
63 },64 },

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t