Skip to content

feat(editor): let copilot narrow the API references panel during tutorials#3304

Open
Ethanlita wants to merge 1 commit into
goplus:devfrom
Ethanlita:feat/api-reference-filter
Open

feat(editor): let copilot narrow the API references panel during tutorials#3304
Ethanlita wants to merge 1 commit into
goplus:devfrom
Ethanlita:feat/api-reference-filter

Conversation

@Ethanlita

@Ethanlita Ethanlita commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

What & why

During a tutorial course, the left-side API References panel shows the full catalog of spx APIs, which can overwhelm a learner. This PR lets the copilot narrow that panel to only the APIs a course actually needs, and restores it automatically when the course ends.

The panel is filtered while the user is being guided through a course, and returns to showing everything once they leave "tutorial mode" (i.e. the copilot session ends).

How it works (data flow)

copilot emits  <api-reference-filter names="onStart, say, move">
      │  (custom element, rendered in the copilot panel)
      ▼
codeEditor.setAPIReferenceFilter(predicate)      ← generic, reactive state on CodeEditor
      ▼
APIReferenceController.filteredItems             ← synchronous derived view over loaded items
      ▼
APIReferenceUI re-renders (empty categories collapse automatically)

Clearing: the editor watches copilot.currentSession and resets the filter whenever the session ends or switches.

Changes (by layer)

Generic editor (xgo-code-editor) — no knowledge of copilot/tutorials

  • api-reference.ts: new APIReferenceFilter = (item) => boolean type.
  • code-editor.ts: reactive apiReferenceFilter + setAPIReferenceFilter() .
  • ui/api-reference/index.ts: filteredItems — a synchronous derivation over the already-loaded items, so filter changes update the UI reactively without re-running the async provider. Falls back to the full list if a filter matches nothing.
  • ui/api-reference/APIReferenceUI.vue: render filteredItems instead of items.

Editor ↔ copilot seam (editor/copilot)

  • New ApiReferenceFilter.ts: an api-reference-filter custom element that reaches the editor via useCodeEditorRef() (same mechanism as the existing CodeLink/CodeChange elements) and sets the filter on mount. APIs are matched by name (e.g. onStart, say) — the vocabulary the model already knows from the spx-project skill — so no extra catalog/tool is needed.
  • index.ts: register the element next to the other editor copilot elements; clear the filter on copilot session change.

Tutorial

  • tutorial.ts: the course prompt now instructs the copilot to narrow the panel to the union of APIs the whole course uses (not just the current step), set once at the start and kept stable. The tutorial module holds no filter state and does not depend on the editor.

Design notes

  • The generic xgo-code-editor / API Reference layer stays unaware of tutorial; the only coupling lives in the two existing connection points (editor/copilot and the tutorial prompt), bridged through copilot.
  • Filtering is a synchronous derivation, so it rides Vue reactivity rather than re-triggering the async API load.
  • The filter is a session-scoped transient: cleared on session end, so it can never persist into normal (non-tutorial) editing.

Testing

  • Manual: in the editor, asking the copilot to "show only onStart and say" narrows the panel; starting a coding course narrows it to the course's APIs; finishing/leaving the course restores the full list.
  • npm run type-check, npm run lint, Prettier — all pass.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces an API reference filtering feature to narrow down the visible APIs in the "API References" panel, helping guide users during tutorial steps. It adds an ApiReferenceFilter component, registers it as a copilot custom element, updates tutorial instructions, and integrates the filter state into the CodeEditor and APIReferenceController. Feedback on the changes highlights two key issues: first, in APIReferenceUI.vue, the computed property incorrectly expects an oldValue argument (which is not supported in Vue 3), breaking the UI stability logic; second, in ApiReferenceFilter.ts, the filter does not re-apply when the names prop changes, requiring a watch on both codeEditorRef and props.names to ensure reactivity.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread spx-gui/src/components/editor/copilot/ApiReferenceFilter.ts Outdated

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two findings in the new API reference filter code, plus a documentation mismatch from the chapter-8 renaming:

Tutorial chapters 1–7 (onStart removal) and chapter 4 scope example: content and code are consistent. No issues.

Fallback-to-full-list behavior in filteredItems: sound and well-documented.

oldValue in computed: valid on Vue 3.4+ (this project uses Vue ^3.5.25). Not an issue.

See inline comments for specifics.

Findings without inline locations

  • tutorial/codeKiko/summary.md:51: Broken TOC link — title and anchor both stale after the section was renamed in commit 3.

Comment thread spx-gui/src/components/editor/copilot/ApiReferenceFilter.ts Outdated

export type Props = {
/** Comma-separated API names to keep visible. Empty string shows all. */
names: string

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不同的 API definition 可能有相同的 name(不过 ID 是各自唯一的),比如 say wordsay word, seconds 的 name 都是 say,通过 name 控制的话这俩要么都留要么都不留,是你预期的吗?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

是预期的。
因为考虑到使用name可能会简单一点,因此采用了这种方案。
虽然id也会给copilot,但是似乎会随着API Reference的重新渲染而改变。name则是不会变的。
对于用户来说,即使误选了同名的另一个API,下一轮中copilot也会给用户使用code-change-hint提示来修改代码至正确,因此应当不至于误导用户。

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

虽然id也会给copilot,但是似乎会随着API Reference的重新渲染而改变。name则是不会变的。

都不会变的,ID 是对 API 的唯一标识,跟渲染行为无关

因为考虑到使用name可能会简单一点,因此采用了这种方案。

如果不考虑复杂度,从我们的目的看,同 name 的其他 API 也可见应该不是想要的?

那可以探索下走 ID 的方案,看是不是可以以可接受的复杂度达到目的

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed@c2e14a73


// The API reference filter is transient state scoped to a copilot session: clear it whenever the
// session ends or switches (e.g. a tutorial course finishes), so a filter never leaks past its context.
d.addDisposer(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这边是把 apiReferenceFilter 的控制放在 copilot 这里,而不是 tutorial 中,考虑的是?

我感觉放 tutorial 中可能好点,主要是暂时没想到在 tutorial 外 copilot 需要控制 apiReferenceFilter 的合理用例

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这是因为我们的Markdown-as-Course的设计理念。如果我们要在Toturial而不是copilot里实行过滤,那么我们可能就需要在Toturial那边设置这一节课需要使用的API,而不是交给LLM自动判定。这样会加重课程设计人员的负担,和我们的设计理念似乎不是很相符。

@nighca nighca Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果我们要在Toturial而不是copilot里实行过滤,那么我们可能就需要在Toturial那边设置这一节课需要使用的API,而不是交给LLM自动判定

不是这个意思,“放 tutorial 中”是指还是由 copilot 通过这个 custom-element 去控制过滤,只是这个 custom-element 是在进入课程的时候才注册到 copilot,同样是在退出课程的时候才 unregister

比如 tutorial-course-success 这个 custom-element 就是在进入某个课程的时候才会注册到 copilot

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed@c2e14a73

Comment thread spx-gui/src/components/xgo-code-editor/ui/api-reference/index.ts Outdated
…rials

Let a tutorial course focus the "API References" panel on just the APIs it
uses, so learners are not distracted by the full catalog.

- Generic editor: add an `apiReferenceFilter` predicate on CodeEditor; the API
  reference controller derives the shown items from it synchronously, so the
  panel updates reactively without re-running the async provider.
- Copilot: an `api-reference-filter` custom element narrows the panel to a set
  of API definition ids, and a `list_api_reference_items` tool lets the copilot
  look up the exact ids to use.
- Tutorial: the element is registered only while a course is active and the
  filter is reset when the course ends; the course prompt instructs the copilot
  to narrow the panel to the APIs the whole course uses.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants