Token导航 LogoToken导航

Agent Skill · 待分类

phoenix-liveview-essentials(Phoenix liveview 基础)

phoenix-liveview-essentials 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

phoenix-liveview-essentials 是待分类类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描已通过,按安装量在待分类类的 11,209 个 Skill 里排第 9,348。

总安装 245周安装 10GitHub Stars 119下载 78核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:phoenix-liveview-essentials(Phoenix liveview 基础)
来源仓库:https://github.com/j-morgan6/elixir-claude-optimization
仓库路径:skills/phoenix-liveview-essentials
安装命令:
npx skills add https://github.com/j-morgan6/elixir-claude-optimization --skill phoenix-liveview-essentials
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/j-morgan6/elixir-claude-optimization --skill phoenix-liveview-essentials

这个 Skill 是做什么的

这个 Skill 的分类还没最终确定,用法以来源仓库的说明为准。

用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息。适合在 Codex、Claude、Cursor、Gemini CLI 中围绕仓库状态、代码变更或协作事项进行整理。通过 npx 命令从指定 GitHub 仓库安装,需确认权限范围和维护状态。

使用前建议核实是否会触发联网、命令执行或文件读写操作。phoenix-liveview-essentials 属于待分类类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/phoenix-liveview-essentials

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/j-morgan6/elixir-claude-optimization --skill p…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

phoenix-liveview-essentials 怎么安装?

在终端执行 npx skills add https://github.com/j-morgan6/elixir-claude-optimization --skill phoenix-liv…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

phoenix-liveview-essentials 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

phoenix-liveview-essentials 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

phoenix-liveview-essentials 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

phoenix-liveview-essentials 用的人多吗?

公开数据是累计安装 245 次,近一周安装 10 次,下载 78 次,GitHub 119 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

phoenix-liveview-essentials 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理待分类类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

待分类类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
infsh-cli

infsh CLI · Codex、Claude

4,374,576382权限未标注未明确未收录
ai-video-generation

AI 视频生成 · Codex、Claude

4,313,376382调用外部服务未明确有提醒
lark-openapi-explorer

云雀 OpenAPI 浏览器 · Codex、Claude

2,064,1209,011需要联网未明确有提醒
lark-workflow-standup-report

Lark 工作流程站立报告 · Codex、Claude

2,041,6328,978需要联网未明确通过
use-my-browser

使用我的浏览器 · Codex、Claude

1,848,49140操作浏览器未明确未通过
phoenix-liveview-essentials

Phoenix liveview 基础 · 本页

245119需要联网未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Phoenix LiveView Essentials

RULES — Follow these with no exceptions

  1. Always add @impl true before every callback (mount, handle_event, handle_info, render)
  2. Initialize assigns before they're accessed in render/1 — use mount/3 for static defaults, handle_params/3 for URL-dependent assigns (pagination, filters, sorting)
  3. Check connected?(socket) before PubSub subscriptions, timers, or side effects
  4. Use Map.get(assigns,:key, default) for optional assigns in helper functions
  5. Return proper tuples — {:ok, socket} from mount, {:noreply, socket} from handle_event
  6. Use with for error handling in event handlers — assign errors to socket, don't crash
  7. Never use auto_upload: true with form submission — use manual uploads instead
  8. Check core_components.ex for existing components before creating custom ones
  9. Never query the database directly from LiveViews — call context functions instead

Critical Concept: Two-Phase Rendering

LiveView renders happen in TWO phases:

  1. Static/Disconnected Render - Initial HTTP request

- No WebSocket connection - connected?(socket) returns false - Side effects (PubSub, timers) won't work

  1. Connected Render - WebSocket established

- Full live functionality active - connected?(socket) returns true - Events and live updates work

Common Bug: Accessing uninitialized assigns during static render crashes with KeyError.

Solution: Initialize assigns before render — use mount/3 for static defaults, handle_params/3 for URL-dependent state.


LiveView Lifecycle

Mount Callback

@impl true
def mount(_params, _session, socket) do
  # Initialize static defaults here; URL-dependent assigns go in handle_params
  socket =
    socket
    |> assign(:user, nil)
    |> assign(:loading, false)
    |> assign(:data, [])

  # Only subscribe when connected
  if connected?(socket) do
    Phoenix.PubSub.subscribe(MyApp.PubSub, "topic")
  end

  {:ok, socket}
end

Why check connected? PubSub subscriptions and timers only work with WebSocket connection.

Handle Event

Use pattern matching for different actions.

@impl true
def handle_event("save", %{"post" => post_params}, socket) do
  case Posts.create_post(post_params) do
    {:ok, post} ->
      socket =
        socket
        |> put_flash(:info, "Created!")
        |> assign(:post, post)

      {:noreply, socket}

    {:error, changeset} ->
      {:noreply, assign(socket, :changeset, changeset)}
  end
end

@impl true
def handle_event("delete", %{"id" => id}, socket) do
  Posts.delete_post(id)
  {:noreply, assign(socket, :posts, Posts.list_posts())}
end

Handle Info

Handle async messages and PubSub broadcasts.

@impl true
def handle_info({:post_created, post}, socket) do
  {:noreply, update(socket, :posts, fn posts -> [post | posts] end)}
end

@impl true
def handle_info(%{event: "presence_diff"}, socket) do
  {:noreply, assign(socket, :online_users, get_presence_count())}
end

Handle Params

Respond to URL changes (called in BOTH render phases).

@impl true
def handle_params(%{"id" => id}, _uri, socket) do
  # This runs during static AND connected render
  post = Posts.get_post!(id)

  if connected?(socket) do
    # Only subscribe when connected
    Phoenix.PubSub.subscribe(MyApp.PubSub, "post:#{id}")
  end

  {:noreply, assign(socket, :post, post)}
end

@impl true
def handle_params(_params, _uri, socket) do
  {:noreply, socket}
end

Socket Assigns

Use assign/2 or assign/3 to update socket state.

# Single assign
socket = assign(socket, :count, 0)

# Multiple assigns
socket = assign(socket, count: 0, name: "User", active: true)

# Update existing assign
socket = update(socket, :count, &(&1 + 1))

Safe Assign Access

In render/1: Direct access is safe if initialized in mount.

@impl true
def mount(_params, _session, socket) do
  {:ok, assign(socket, :count, 0)}
end

@impl true
def render(assigns) do
  ~H"""
  <p>Count: <%= @count %></p>  <!-- Safe -->
  """
end

In helper functions: Use Map.get for optional assigns.

# ❌ BAD - Crashes if not a map with :name
defp format_user(%{name: name}), do: name

# ✅ GOOD - Handles nil case
defp format_user(socket) do
  case Map.get(socket.assigns, :current_user) do
    nil -> "Guest"
    user -> user.name
  end
end

Temporary Assigns

Use temporary assigns for large collections that don't need to persist.

@impl true
def mount(_params, _session, socket) do
  socket = assign(socket, :posts, [])
  {:ok, socket, temporary_assigns: [posts: []]}
end

Flash Messages

Use put_flash/3 and clear_flash/2 for user feedback.

@impl true
def handle_event("save", params, socket) do
  case save_data(params) do
    {:ok, _} ->
      socket = put_flash(socket, :info, "Saved successfully!")
      {:noreply, socket}

    {:error, _} ->
      socket = put_flash(socket, :error, "Failed to save")
      {:noreply, socket}
  end
end

Live Navigation

Use push_navigate/2 or push_patch/2 for navigation.

# Full page reload (new LiveView)
{:noreply, push_navigate(socket, to: ~p"/users")}

# Patch (same LiveView, different params)
{:noreply, push_patch(socket, to: ~p"/posts/#{post}")}

Streams

Use streams for efficient rendering of large lists.

@impl true
def mount(_params, _session, socket) do
  {:ok, stream(socket, :posts, Posts.list_posts())}
end

@impl true
def handle_event("add", %{"post" => attrs}, socket) do
  {:ok, post} = Posts.create_post(attrs)
  {:noreply, stream_insert(socket, :posts, post, at: 0)}
end

@impl true
def handle_event("delete", %{"id" => id}, socket) do
  Posts.delete_post(id)
  {:noreply, stream_delete_by_dom_id(socket, :posts, "posts-#{id}")}
end

Components

Extract reusable UI into function components.

def card(assigns) do
  ~H"""
  <div class="card">
    <h3><%= @title %></h3>
    <p><%= @content %></p>
  </div>
  """
end

# Usage in template
<.card title="Hello" content="World" />

Form Binding

Bind forms to changesets for validation.

<.simple_form for={@form} phx-change="validate" phx-submit="save">
  <.input field={@form[:title]} label="Title" />
  <.input field={@form[:body]} type="textarea" label="Body" />
  <:actions>
    <.button>Save</.button>
  </:actions>
</.simple_form>
@impl true
def mount(_params, _session, socket) do
  changeset = Post.changeset(%Post{}, %{})
  {:ok, assign(socket, form: to_form(changeset))}
end

@impl true
def handle_event("validate", %{"post" => params}, socket) do
  changeset =
    %Post{}
    |> Post.changeset(params)
    |> Map.put(:action, :validate)

  {:noreply, assign(socket, form: to_form(changeset))}
end

Error Handling

Always handle errors gracefully in LiveViews.

@impl true
def handle_event("risky_operation", _params, socket) do
  case perform_operation() do
    {:ok, result} ->
      {:noreply, assign(socket, :result, result)}

    {:error, reason} ->
      {:noreply, put_flash(socket, :error, "Operation failed: #{reason}")}
  end
end

Error Boundaries

Handle errors in handle_event to prevent LiveView crashes.

@impl true
def handle_event("save", params, socket) do
  case save_record(params) do
    {:ok, record} ->
      socket =
        socket
        |> put_flash(:info, "Saved successfully")
        |> assign(:record, record)

      {:noreply, socket}

    {:error, %Ecto.Changeset{} = changeset} ->
      socket =
        socket
        |> put_flash(:error, "Please correct the errors")
        |> assign(:changeset, changeset)

      {:noreply, socket}

    {:error, reason} ->
      socket = put_flash(socket, :error, "An error occurred: #{reason}")
      {:noreply, socket}
  end
end

PubSub Broadcasting

Use PubSub for real-time updates across LiveViews.

# Subscribe in mount
@impl true
def mount(_params, _session, socket) do
  if connected?(socket) do
    Phoenix.PubSub.subscribe(MyApp.PubSub, "posts")
  end

  {:ok, assign(socket, :posts, list_posts())}
end

# Broadcast when data changes
def create_post(attrs) do
  with {:ok, post} <- Repo.insert(changeset) do
    Phoenix.PubSub.broadcast(MyApp.PubSub, "posts", {:post_created, post})
    {:ok, post}
  end
end

# Handle broadcast
@impl true
def handle_info({:post_created, post}, socket) do
  {:noreply, update(socket, :posts, fn posts -> [post | posts] end)}
end

Testing

When writing LiveView tests, invoke elixir-phoenix-guide:testing-essentials before writing any _test.exs file.

Common Lifecycle Mistakes

❌ Mistake 1: Assuming Assigns Exist

def render(assigns) do
  ~H"""
  <p>Count: <%= @count %></p>  <!-- Crash if @count not initialized -->
  """
end

✅ Fix: Initialize before render (mount or handle_params)

@impl true
def mount(_params, _session, socket) do
  {:ok, assign(socket, :count, 0)}
end

❌ Mistake 2: Subscribing in Both Phases

@impl true
def mount(_params, _session, socket) do
  # BAD - Subscribes during static render (doesn't work)
  Phoenix.PubSub.subscribe(MyApp.PubSub, "topic")
  {:ok, socket}
end

✅ Fix: Check connected?

@impl true
def mount(_params, _session, socket) do
  if connected?(socket) do
    Phoenix.PubSub.subscribe(MyApp.PubSub, "topic")
  end

  {:ok, socket}
end

❌ Mistake 3: Expensive Operations in Both Phases

@impl true
def mount(_params, _session, socket) do
  # BAD - Runs expensive query twice (static + connected)
  data = run_expensive_query()
  {:ok, assign(socket, :data, data)}
end

✅ Fix: Defer to connected phase

@impl true
def mount(_params, _session, socket) do
  socket =
    if connected?(socket) do
      # Only run when connected
      assign(socket, :data, run_expensive_query())
    else
      # Placeholder for static render
      assign(socket, :data, [])
    end

  {:ok, socket}
end

Lifecycle Flow

1. HTTP Request arrives
   ↓
2. mount/3 called (connected? = false)
   ↓
3. handle_params/3 called (connected? = false)
   ↓
4. render/1 called (STATIC HTML generated)
   ↓
5. HTML sent to browser
   ↓
6. Browser connects WebSocket
   ↓
7. mount/3 called AGAIN (connected? = true)
   ↓
8. handle_params/3 called AGAIN (connected? = true)
   ↓
9. render/1 called (sent over WebSocket)
   ↓
10. LiveView now active and reactive

Quick Reference

Safe Patterns

# ✅ Initialize in mount
assign(socket, :key, default_value)

# ✅ Use Map.get for optional
Map.get(socket.assigns, :key, default)

# ✅ Check connected for side effects
if connected?(socket), do: subscribe()

# ✅ Pattern match with fallback
def helper(%{name: name}), do: name
def helper(_), do: "default"

# ✅ Add @impl true
@impl true
def mount(...), do: ...

Unsafe Patterns

# ❌ Direct access without initialization
socket.assigns.key

# ❌ Subscribe without checking
Phoenix.PubSub.subscribe(...)

# ❌ Expensive ops in both phases
mount(...) do
  data = expensive_query()
end

# ❌ Missing @impl true
def mount(...), do: ...

平台分布

Codex

36.76%
按下载量换算29

Claude

30.06%
按下载量换算23

Cursor

19.53%
按下载量换算15

Gemini CLI

10.81%
按下载量换算8

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills