본문으로 건너뛰기
cccskills
무료GitHub에 공개

window-panel-authoring

Recipe for creating or changing a floating window. Use when adding a window, editing a window component, declaring restore or ephemeral behavior, wiring a ?panels= link or the Tools grid, or a window fails to restore after reload. NOT for drag/resize/tray internals (use window-panels).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md9.2 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Window Panel Authoring

A window is an overlay whose render module returns a WindowPanel. The engine (WindowPanel, window manager, persistence, links) is the package @ai-matrx/summon; a defect in that engine is fixed in ../aidream/apps/shared/summon in the same session, never worked around in the window. Slots, drag, tray and phone presentation: window-panels skill. Definition, render module, registry and opener rules: overlay-system skill (read it first, the file list below assumes it).

If the window is an agent-aware surface, invoke surface-authoring and its overlay-surface reference. A window resident never inherits ambient surface values; an outside helper may receive an approved snapshot under its documented integration contract.

Files you touch

FileWhen
features/window-panels/windows/[<feature>/]MyFeatureWindow.tsxThe window component.
features/overlays/definitions/<id>.overlay.tsxDefinition: id, label, instance, and the window block (windowId, mobile, preservation, restoreDefaults, ephemeral, deprecated), optional link. Holds the opener (useOpenX, XController).
features/overlays/definitions/<id>.render.tsxLazy chunk: narrows data, wires props by name (no spread).
definitions/registry.tsThe one hand line, d.<id>Overlay,; then pnpm gen:overlays (overlay-system "Add an overlay").
features/window-panels/tools-grid/toolsGridTiles.tsOptional Tools grid tile.
definitions/<id>.link.tsOptional ?panels= hydrator.

Steps

1. The window component

"use client";
import { useState } from "react";
import { WindowPanel } from "@ai-matrx/summon/window";
import { MyFeatureBody } from "@/features/my-feature/components/MyFeatureBody";

interface MyFeatureWindowProps {
  onClose: () => void;
  initialSelectedId?: string | null;   // seeded from overlay data by the render module
}

export default function MyFeatureWindow({ onClose, initialSelectedId }: MyFeatureWindowProps) {
  const [selectedId, setSelectedId] = useState<string | null>(initialSelectedId ?? null);
  const collectData = (): Record<string, unknown> => ({ selectedId });

  return (
    <WindowPanel
      title="My Feature"
      id="my-feature-window"          // stable, never random: geometry is keyed by it
      overlayId="myFeatureWindow"     // identical to the definition id; this is the close binding
      minWidth={380} minHeight={280} width={560} height={440} position="center"
      onClose={onClose}
      onCollectData={collectData}
      bodyClassName="flex min-h-0 flex-1 flex-col overflow-hidden p-0"
    >
      <MyFeatureBody selectedId={selectedId} onSelect={setSelectedId} />
    </WindowPanel>
  );
}

Rules:

  • No isOpen prop and no if (!isOpen) return null: a closed overlay is never rendered, so the render module only mounts an open window.
  • id is stable. overlayId equals the definition id. Close binding is exactly one of overlayId, boundToOverlay, onClose (type-enforced).
  • instance: "multi" windows are keyed by the render module's key={instanceId}; pass the instance id into the component so each instance gets distinct state (windowInstanceId pattern in NotesWindow).
  • onCollectData returns all keys the window preserves, read from live state; the React Compiler memoizes it, so no manual useCallback.
  • Body is content only; chrome is slots (window-panels skill). A window wraps the canonical component (FEATURE.md law), never a hand-rolled copy.
  • A window component that other code props-extends uses Omit<WindowPanelBaseProps, ...> from @ai-matrx/summon/window.

2. The definition and render module

Create <id>.overlay.tsx with a window block and <id>.render.tsx that renders MyFeatureWindow with onClose={() => close()} and initialSelectedId narrowed from data; add d.myFeatureWindowOverlay, to registry.ts and run pnpm gen:overlays (overlay-system). Do not import MyFeatureWindow from anywhere except its render module (and its own tests).

window: {
  windowId: "my-feature-window",
  mobile: "drawer",                                   // fullscreen | drawer | card | hidden
  preservation: { dataKeys: ["selectedId"] },         // opt in to refresh restore (default-deny)
  restoreDefaults: { selectedId: null },
  // ephemeral: true,                                 // never saves anything
},

3. (Optional) Tools grid tile

Tiles are declarative in tools-grid/toolsGridTiles.ts; ToolsGrid.tsx and activateToolsGridTile.ts read the definition via appOverlayDefinition(overlayId) (instance strategy comes from instance). Never add a tile in features/window-panels/components/SidebarWindowToggle.tsx.

{ id: "tile.my-feature", label: "My Feature", icon: MyFeatureIcon, category: "general",
  overlayId: "myFeatureWindow" /* seedData: (ctx) => ({ selectedId: null }) */ },

4. (Optional) ?panels= address

Three edits, all required, or the link opens an empty frame: (a) link: { key: "my_feature", hydrate } on the definition (heavy hydrator in myFeatureWindow.link.ts, loaded lazily; the hydrator must call open({ data })), (b) urlSyncKey="my_feature" on the WindowPanel when it differs from the default, (c) urlSyncId={subjectId} on the WindowPanel. Two windows may not claim one key (the package throws on a duplicate link key). features/window-panels/__tests__/everyWindowHasAnAddress.test.ts refuses a window with a durable subject (...Id, Slug, Token data) and no address, unless listed in registry/window-address-baseline.json (which only shrinks).

Persistence contract (default-deny)

A window survives a refresh only when its window.preservation.dataKeys lists what to keep and it is not ephemeral. Geometry (rect, windowState, sidebarOpen, zIndex) is captured by the package; the window supplies content via onCollectData, filtered to dataKeys, JSON only, at most maxDataBytes (32 KiB default). Saves are debounced 250 ms after any window-manager or state change and flushed on pagehide; close removes the window from the saved workspace. Storage is users.user_surface_state (details: window-panels persistence branch). Callback-group windows (callbackGroupId in data) are ephemeral: true and listed addressless with the reason.

Ephemeral windows

ephemeral: true on the definition's window block for debug panels, one-shot dialogs and callback-group windows. It governs restore only, never reachability: an ephemeral window can and should still have a link.

Updating a window

  1. Change restoreDefaults and preservation.dataKeys together (a new key missing from dataKeys is silently dropped from storage).
  2. Update onCollectData to return all current keys.
  3. Props changed: update the render module's by-name wiring and the opener's Open…Options in the .overlay file. Then run pnpm gen:overlays if label, instance or window identity moved (pnpm check:overlays fails until you do).

Sidebar layout

<div className="flex flex-col min-h-0 h-full">
  <div className="px-2 py-1 border-b type-title shrink-0">Header</div>
  <div className="flex-1 min-h-0 p-1.5 space-y-1">{items.map((item) => <Item key={item.id} />)}</div>
</div>

h-full min-h-0 flex flex-col on the root; no overflow-y-auto on the root (WindowPanel handles it); no shrink-0 on the root.

Common mistakes

MistakeSymptomFix
overlayId in the component differs from the definition idType error, or the window reads another overlay's metadataMake them identical
Definition missing from registry.tsWindow never renders; pnpm check:overlays names itAdd d.<id>Overlay, to APP_OVERLAYS
Generated index stalepnpm check:overlays failsRun pnpm gen:overlays and commit the result
Definition file lacks "use client"Production build fails collecting page data for a server pageAdd it
No window.preservationWindow reopens empty after refresh; Save does nothingDeclare dataKeys
Multi-instance window without a per-instance idWindows share state, or restore finds no instanceUse key={instanceId} and pass instanceId through
Random id on WindowPanelGeometry lost on re-renderStable string
ephemeral: true but the window needs restoreWindow does not reopenRemove ephemeral, declare preservation
Link edits skip urlSyncIdEvery instance writes the same tokenPass the subject id
Fixing package behavior in the windowDiverges from every other hostFix ../aidream/apps/shared/summon

Resources

  • Package guides: ../aidream/apps/shared/summon/README.md (WindowPanel, links, persistence, handles) and FEATURE.md (invariants).
  • App window facts and laws: features/window-panels/FEATURE.md. Definitions: features/overlays/definitions/. Host: features/overlays/host/.
  • Openers, registry, mounting: overlay-system skill. Slots, drag, tray: window-panels skill. Removal: remove-window-panel skill.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Admin debug system wiring for the floating AdminIndicator's live debug data and Copy Full Context. Use when adding debug visibility to a route or feature, wiring useDebugContext or the debug panel, capturing console errors, or enabling the copy-context workflow for a page.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 19일 업데이트

Compact two-icon Copy / Copy-for-AI controls (components/agent-copy). Use when adding copy buttons to a row, card, list, or record; merging duplicate Copy/JSON/AI controls; continuing the copy rollout; or writing a Copy-for-AI payload. NOT for markdown content actions (use rich-document-actions).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 19일 업데이트

Disclosing a surface's existing fixed AI jobs in the shell's top Agents menu. Use when a page, panel, overlay, or window already runs a mandate behind a button, assist, automatic action, or mode; when the agent-disclosure guard names a file; or during a surface check.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 19일 업데이트

The watch-fix-rerun method for making an existing platform agent or automated process efficient and correct: baseline its ledger, run one unit yourself, fix the class behind every wasted call, rerun, record. Use when asked to improve, optimize, watch, or 'make efficient' an agent, a sandbox session, a sync job, or any recurring automated process.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 19일 업데이트

Redux state for agent execution and firing agent shortcuts. Use when editing features/agents/redux/, building agent UI, creating a conversation, touching assembleRequest or NDJSON stream state, wiring agent-state selectors, adding a per-conversation capability, or triggering a shortcut from a button, menu, or code (useShortcutTrigger, launchAgentExecution).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 19일 업데이트

The provision for a call site: the exhaustive menu of values that place in the code can realistically produce. Use before creating or fixing a mandate or agent that reasons about more than its own input, when deciding whether an agent can answer at all with what it is sent, or when its output 'looks right' but nobody checked it could be. NOT for building the agent (use create-agent).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 19일 업데이트

armanisadeghi의 스킬 모두 보기

이 스킬의 문제 신고