Token导航 LogoToken导航TokenDH.com
研究检索敏感数据github未标认证来源可访问许可证需确认审计异常

spa-reverse-engineer水疗中心逆向工程师

Agent Skill

spa-reverse-engineer 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

465

周安装

19

GitHub Stars

公开资料未说明

下载量

149
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

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

请帮我安装这个 Agent Skill:spa-reverse-engineer(水疗中心逆向工程师)
来源仓库:https://github.com/pv-udpv/pplx-sdk
仓库路径:skills/spa-reverse-engineer
安装命令:
npx skills add https://github.com/pv-udpv/pplx-sdk --skill spa-reverse-engineer
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

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

skills.shnpx skills
npx skills add https://github.com/pv-udpv/pplx-sdk --skill spa-reverse-engineer

简介

用于单页应用(SPA)逆向分析与技术研究。

  • 适合解析前端框架路由、状态管理和数据流。
  • 可通过 GitHub 安装,需确认是否触发网络请求。
  • 涉及商业软件时应遵守版权和使用协议。
  • 建议仅用于学习目的和技术原理研究。spa-reverse-engineer 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

SPA Reverse Engineering — React + Vite + Workbox + CDP

Reverse engineer modern SPAs to extract APIs, intercept service workers, debug runtime state, and build tooling.

When to use

Use this skill when:

  • Analyzing perplexity.ai SPA internals (React component tree, state, hooks)
  • Intercepting Workbox service worker caching and request strategies
  • Using Chrome DevTools Protocol (CDP) to automate browser interactions
  • Building Chrome extensions for traffic interception or state extraction
  • Debugging Vite-bundled source maps and module graph
  • Extracting GraphQL/REST schemas from SPA network layer
  • Writing Puppeteer/Playwright scripts for automated API discovery

Instructions

Step 1: Identify SPA Stack

Detect the technology stack of the target SPA:

// In DevTools Console:

// React detection
window.__REACT_DEVTOOLS_GLOBAL_HOOK__  // React DevTools presence
document.querySelector('#__next')  // Next.js
document.querySelector('#root')    // Vite/CRA
document.querySelector('#app')     // Vue (for comparison)

// Vite detection
document.querySelector('script[type="module"]')  // ESM modules
// Check source for /@vite/client or /.vite/ paths

// Workbox / Service Worker
navigator.serviceWorker.getRegistrations()  // List SWs
// Check Application → Service Workers in DevTools

// State management
window.__REDUX_DEVTOOLS_EXTENSION__  // Redux
// React DevTools → Components → hooks for Zustand/Jotai/Recoil

Step 2: React Internals Analysis

Component Tree Extraction

// Get React fiber tree from any DOM element
function getFiber(element) {
    const key = Object.keys(element).find(k =>
        k.startsWith('__reactFiber$') || k.startsWith('__reactInternalInstance$')
    );
    return element[key];
}

// Walk fiber tree
function walkFiber(fiber, depth = 0) {
    if (!fiber) return;
    const name = fiber.type?.displayName || fiber.type?.name || fiber.type;
    if (typeof name === 'string') {
        console.log('  '.repeat(depth) + name);
    }
    walkFiber(fiber.child, depth + 1);
    walkFiber(fiber.sibling, depth);
}

// Start from root
const root = document.getElementById('root');
walkFiber(getFiber(root));

State & Props Extraction

// Extract component state via fiber
function getComponentState(fiber) {
    const state = [];
    let hook = fiber.memoizedState;
    while (hook) {
        state.push(hook.memoizedState);
        hook = hook.next;
    }
    return state;
}

// Find specific component by name
function findComponent(fiber, name) {
    if (!fiber) return null;
    if (fiber.type?.name === name || fiber.type?.displayName === name) {
        return fiber;
    }
    return findComponent(fiber.child, name) || findComponent(fiber.sibling, name);
}

Step 3: Vite Bundle Analysis

Source Map Extraction

# Find source maps from bundled assets
curl -s https://www.perplexity.ai/ | grep -oP 'src="[^"]*\.js"' | while read src; do
    url=$(echo $src | grep -oP '"[^"]*"' | tr -d '"')
    echo "Checking: $url"
    curl -sI "https://www.perplexity.ai${url}.map" | head -5
done

Module Graph

// In Vite dev mode (if accessible):
// /__vite_module_graph shows dependency graph

// In production — analyze chunks:
// Performance → Network → JS files → Initiator chain
// Sources → Webpack/Vite tree → module paths

Step 4: Service Worker & Workbox Interception

Analyze Caching Strategy

// List all cached URLs
async function listCaches() {
    const names = await caches.keys();
    for (const name of names) {
        const cache = await caches.open(name);
        const keys = await cache.keys();
        console.log(`Cache: ${name} (${keys.length} entries)`);
        keys.forEach(k => console.log(`  ${k.url}`));
    }
}

// Intercept SW fetch events (from SW scope)
self.addEventListener('fetch', event => {
    console.log('[SW Intercept]', event.request.method, event.request.url);
});

Workbox Strategy Detection

// Common Workbox strategies to look for in SW source:
// - CacheFirst       → Static assets (fonts, images)
// - NetworkFirst     → API calls (dynamic data)
// - StaleWhileRevalidate → Frequently updated content
// - NetworkOnly      → Always fresh (auth endpoints)
// - CacheOnly        → Offline-only content

// Check SW source for workbox patterns:
// workbox.strategies.CacheFirst
// workbox.routing.registerRoute
// workbox.precaching.precacheAndRoute

Step 5: Chrome DevTools Protocol (CDP)

Automated Interception via CDP

import asyncio
from playwright.async_api import async_playwright

async def intercept_with_cdp():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        context = await browser.new_context()
        page = await context.new_page()

        # Enable CDP domains
        cdp = await page.context.new_cdp_session(page)

        # Intercept network at CDP level
        await cdp.send('Network.enable')
        cdp.on('Network.requestWillBeSent', lambda params:
            print(f"[CDP] {params['request']['method']} {params['request']['url']}")
        )
        cdp.on('Network.responseReceived', lambda params:
            print(f"[CDP] {params['response']['status']} {params['response']['url']}")
        )

        # Intercept WebSocket frames
        await cdp.send('Network.enable')
        cdp.on('Network.webSocketFrameSent', lambda params:
            print(f"[WS→] {params['response']['payloadData'][:200]}")
        )
        cdp.on('Network.webSocketFrameReceived', lambda params:
            print(f"[←WS] {params['response']['payloadData'][:200]}")
        )

        await page.goto('https://www.perplexity.ai/')
        await page.wait_for_timeout(60000)

Runtime JS Evaluation via CDP

# Execute JS in page context
result = await cdp.send('Runtime.evaluate', {
    'expression': 'JSON.stringify(window.__NEXT_DATA__)',
    'returnByValue': True,
})
next_data = json.loads(result['result']['value'])

Step 6: Chrome Extension Development

Manifest v3 Extension for Traffic Capture

{
    "manifest_version": 3,
    "name": "pplx-sdk Traffic Capture",
    "version": "1.0",
    "permissions": [
        "webRequest", "activeTab", "storage", "debugger"
    ],
    "host_permissions": ["https://www.perplexity.ai/*"],
    "background": {
        "service_worker": "background.js"
    },
    "content_scripts": [{
        "matches": ["https://www.perplexity.ai/*"],
        "js": ["content.js"],
        "run_at": "document_start"
    }]
}

Background Script — Request Interception

// background.js
chrome.webRequest.onBeforeRequest.addListener(
    (details) => {
        if (details.url.includes('/rest/')) {
            console.log('[pplx-capture]', details.method, details.url);
            if (details.requestBody?.raw) {
                const body = new TextDecoder().decode(
                    new Uint8Array(details.requestBody.raw[0].bytes)
                );
                chrome.storage.local.set({
                    [`req_${Date.now()}`]: {
                        url: details.url,
                        method: details.method,
                        body: JSON.parse(body),
                        timestamp: Date.now()
                    }
                });
            }
        }
    },
    { urls: ["https://www.perplexity.ai/rest/*"] },
    ["requestBody"]
);

Content Script — React State Extraction

// content.js — inject into page context
const script = document.createElement('script');
script.textContent = `
    // Hook into React state updates
    const origSetState = React.Component.prototype.setState;
    React.Component.prototype.setState = function(state, cb) {
        window.postMessage({
            type: 'PPLX_STATE_UPDATE',
            component: this.constructor.name,
            state: JSON.parse(JSON.stringify(state))
        }, '*');
        return origSetState.call(this, state, cb);
    };
`;
document.documentElement.appendChild(script);

// Listen for state updates
window.addEventListener('message', (event) => {
    if (event.data.type === 'PPLX_STATE_UPDATE') {
        chrome.runtime.sendMessage(event.data);
    }
});

Step 7: Map Discoveries to SDK

SPA DiscoverySDK TargetAction
React component statedomain/models.pyModel the state shape
API fetch callstransport/http.pyAdd endpoint methods
SSE event handlerstransport/sse.pyMap event types
Service worker cacheshared/Understand caching behavior
Auth token flowshared/auth.pyToken refresh logic
WebSocket framestransport/New WebSocket transport
GraphQL queriesdomain/Query/mutation services

Step 8: SPA Source Code Graph

After runtime analysis, build a static code graph of the SPA source. Delegate to codegraph for structural analysis.

Source Map Recovery

# Extract original source paths from source maps
curl -s https://www.perplexity.ai/ | grep -oP 'src="(/[^"]*\.js)"' | while read -r url; do
    echo "Checking: $url"
    curl -s "https://www.perplexity.ai${url}.map" 2>/dev/null | \
        python3 -c "import sys,json; d=json.load(sys.stdin); print('\n'.join(d.get('sources',[])))" 2>/dev/null
done | sort -u

Static Analysis (from recovered source or public repo)

# Component tree from source
grep -rn "export \(default \)\?function \|export const .* = (" src/ --include="*.tsx" --include="*.jsx"

# Import graph
grep -rn "import .* from " src/ --include="*.ts" --include="*.tsx" | \
    awk -F: '{print $1 " → " $NF}' | sort -u

# Hook usage map
grep -rn "use[A-Z][a-zA-Z]*(" src/ --include="*.tsx" | \
    grep -oP 'use[A-Z][a-zA-Z]*' | sort | uniq -c | sort -rn

# API call sites (fetch, axios, etc.)
grep -rn "fetch(\|axios\.\|api\.\|apiClient\." src/ --include="*.ts" --include="*.tsx"

Cross-Reference: Runtime ↔ Static

Runtime Discovery (spa-expert)Static Discovery (codegraph)Cross-Reference
Fiber tree component namesSource component definitionsMatch names to source files
Hook state valuesHook implementationsMap state shape to hook logic
Network API callsfetch()/axios call sitesConfirm endpoints in source
Context provider valuescreateContext() definitionsMap runtime state to types
Service worker routesWorkbox config in sourceValidate caching strategy

Perplexity.ai SPA Notes

Known Stack

  • Framework: Next.js (React 18+)
  • Bundler: Webpack (via Next.js, not raw Vite — skill covers both for broader SPA RE)
  • State: React hooks + context (observed patterns)
  • Streaming: SSE via fetch() with ReadableStream
  • Auth: Cookie-based (pplx.session-id)

Key DOM Selectors

// Query input
document.querySelector('textarea[placeholder*="Ask"]')
// Response area
document.querySelector('[class*="prose"]')
// Thread list
document.querySelector('[class*="thread"]')

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

38.44%
按下载量换算57

Claude

29.92%
按下载量换算45

Cursor

20.17%
按下载量换算30

Gemini CLI

8.89%
按下载量换算13

安全审计

Gen Agent Trust Hub

未通过

Socket

可疑

Snyk

未通过

权限和风险

敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills