home / skills / arcblock / agent-skills / blocklet-url-analyzer

blocklet-url-analyzer skill

/plugins/blocklet/skills/blocklet-url-analyzer

npx playbooks add skill arcblock/agent-skills --skill blocklet-url-analyzer

Review the files below or copy the command above to add this skill to your agents.

Files (5)
SKILL.md
13.8 KB
---
name: blocklet-url-analyzer
description: Analyze Blocklet Server related URLs, identify their type (daemon/service/blocklet), and locate the corresponding development repository. Supports analysis of IP DNS domains and regular domains.
---

# Blocklet URL Analyzer

Analyze URLs in the Blocklet Server ecosystem, identify request types, and locate corresponding development repositories.

## Core Philosophy

**"Bridge from URL to code."**

When issues occur in production, developers only have a URL in hand. This skill serves as the bridge: analyzing URL type (Daemon/Service/Blocklet), locating the specific repository and code path, making the "URL → code" path clear and traceable.

## Use Cases

- User provides a Blocklet Server related URL and wants to know which repository to develop in
- During debugging, need to know which component a URL corresponds to
- Reverse lookup development repository from production environment URL

## Critical Rule

> **⚠️ NEVER use Chrome browser or any interactive browser tools to analyze URLs.**
>
> **ALWAYS use terminal commands (curl, wget, etc.) to make HTTP requests directly.**
>
> This is a strict requirement - all URL analysis must be done via command line, not browser automation.

## Repository Reference Files

This skill includes local reference files for repository lookup:

- `references/org-arcblock-repos.md` - ArcBlock organization repos (core infrastructure, SDKs, mobile apps)
- `references/org-blocklet-repos.md` - Blocklet organization repos (blocklet applications, kits, tools)
- `references/org-aigne-repos.md` - AIGNE organization repos (AI agent framework, LLM adapters)

### Active Loading Policy (ALP)

> Load reference files on-demand based on context. Do not preload all files.

| Trigger Condition | Load File |
|-------------------|-----------|
| Need ArcBlock core repos (blocklet-server, ux, did-connect, SDKs) | `references/org-arcblock-repos.md` |
| Need Blocklet app repos (payment-kit, media-kit, discuss-kit, etc.) | `references/org-blocklet-repos.md` |
| Need AIGNE AI repos (aigne-framework, aigne-hub, LLM adapters) | `references/org-aigne-repos.md` |
| Uncertain which organization | First read `references/README.md` for high-density summary |

**Loading Strategy:**
1. First determine which organization the repository likely belongs to based on blocklet name/context
2. Load only the relevant reference file
3. If uncertain, read `references/README.md` first to decide which file to load
4. Prefer local reference files over `gh` commands for repository lookup

## URL Type Classification

### 1. Blocklet Server Daemon (Core Management Interface)

**Characteristics**:
- Main domain (not IP DNS domain)
- Path starts with `/admin`

**Examples**:
```
https://node-dev-1.arcblock.io/admin/blocklets
https://node-dev-1.arcblock.io/admin/blocklets/zNKWm5HBgaTLptTZBzjHo6PPFAp8X3n8pabY/components
https://example.com/admin/settings
```

**Corresponding repository**: `ArcBlock/blocklet-server`

---

### 2. Blocklet Service (Blocklet Built-in Service Interface)

**Characteristics**:
- IP DNS domain (format: `{did}-{ip}.ip.abtnet.io`)
- Path starts with `/.well-known/service/admin`

**Examples**:
```
https://bbqaqc2vvt4mte2n4mta7dlgpsoxakc2gejo3wrrx34-18-180-145-193.ip.abtnet.io/.well-known/service/admin/overview
https://bbqaqc2vvt4mte2n4mta7dlgpsoxakc2gejo3wrrx34-18-180-145-193.ip.abtnet.io/.well-known/service/admin/operations
```

**Corresponding repository**: `ArcBlock/blocklet-server` (service module)

---

### 3. Specific Blocklet (Third-party Blocklet Applications)

**Characteristics**:
- IP DNS domain
- Path starts with blocklet's mount path (not `/.well-known`)
- Or IP DNS domain root path

**Examples**:
```
https://bbqaqc2vvt4mte2n4mta7dlgpsoxakc2gejo3wrrx34-18-180-145-193.ip.abtnet.io/image-bin/admin/images
https://bbqaqc2vvt4mte2n4mta7dlgpsoxakc2gejo3wrrx34-18-180-145-193.ip.abtnet.io/payment-kit/admin
https://bbqaqc2vvt4mte2n4mta7dlgpsoxakc2gejo3wrrx34-18-180-145-193.ip.abtnet.io
```

**Corresponding repository**: Need to request URL to analyze which specific blocklet

---

## Workflow

### Phase 1: URL Parsing

```javascript
// Parse URL to get key information
const url = new URL(inputUrl);
const host = url.hostname;
const path = url.pathname;
```

### Phase 2: Domain Type Detection

#### 2.1 Detect Domain Type

```javascript
// IP DNS domain regex
const IP_DNS_PATTERN = /^[a-z0-9]+-(\d{1,3}-){3}\d{1,3}\.ip\.abtnet\.io$/;
const DID_DNS_PATTERN = /^[a-z0-9]+\.did\.abtnet\.io$/;

const isIpDnsDomain = IP_DNS_PATTERN.test(host) || DID_DNS_PATTERN.test(host);
const isArcBlockDomain = host.endsWith('.arcblock.io') || host.endsWith('.abtnet.io');
```

| Domain Type | Detection Result |
|-------------|------------------|
| `*.ip.abtnet.io` | IP DNS domain → Possibly Blocklet |
| `*.did.abtnet.io` | DID DNS domain → Possibly Blocklet |
| `*.arcblock.io` / `*.abtnet.io` | ArcBlock domain → Check path and request API |
| Other domains | Regular domain → Check path, may also be Blocklet |

### Phase 3: Path Type Detection

```javascript
const DAEMON_ADMIN_PATH = '/admin';
const WELLKNOWN_SERVICE_PATH = '/.well-known/service';
const WELLKNOWN_PATH = '/.well-known';
```

#### 3.1 Detection Flow

```
IF not IP DNS domain AND path.startsWith('/admin')
  → Type: DAEMON
  → Repository: ArcBlock/blocklet-server

ELSE IF IP DNS domain AND path.startsWith('/.well-known/service/admin')
  → Type: BLOCKLET_SERVICE
  → Repository: ArcBlock/blocklet-server

ELSE IF IP DNS domain AND (path === '/' OR !path.startsWith('/.well-known'))
  → Type: BLOCKLET
  → Need further identification of specific blocklet

ELSE IF path.startsWith('/.well-known') AND !path.startsWith('/.well-known/service')
  → Type: WELLKNOWN
  → Repository: ArcBlock/blocklet-server

ELSE IF isArcBlockDomain OR otherDomain
  → Type: POSSIBLE_BLOCKLET
  → Try to request API to identify (proceed to Phase 4)

ELSE
  → Type: UNKNOWN
  → Need user to provide more information
```

**Important**: For non-IP DNS domains (like `spaces.staging.arcblock.io`), always try to request the Blocklet API first before marking as UNKNOWN. Many Blocklets run on regular domains.

### Phase 4: Blocklet Identification (BLOCKLET or POSSIBLE_BLOCKLET Type)

When URL type is BLOCKLET or POSSIBLE_BLOCKLET, need to request API to get specific blocklet information.

#### 4.1 Extract Mount Path

```javascript
// Extract mount path (first path segment) from path
const pathParts = path.split('/').filter(Boolean);
const mountPath = pathParts.length > 0 ? `/${pathParts[0]}` : '/';
```

#### 4.2 Request Blocklet Information

**Method A: Request __blocklet__.js (Recommended)**

This is the most reliable method. The `__blocklet__.js?type=json` endpoint returns information about the main blocklet AND all its components.

```bash
# Get full blocklet metadata (returns JSON when type=json)
BLOCKLET_DATA=$(curl -sS "${ORIGIN}/__blocklet__.js?type=json" 2>/dev/null)

# Extract main blocklet info
echo "$BLOCKLET_DATA" | jq '{appName, appId, appUrl}'

# Extract component mount points
echo "$BLOCKLET_DATA" | jq '.componentMountPoints'
```

**Important**: The `appName` and `appId` fields are for the **main blocklet** (the service). To find the specific component for a mount path, you need to search in `componentMountPoints`:

```bash
# Find component by mount path
# Example: For URL https://team.arcblock.io/task/..., MOUNT_PATH="/task"
COMPONENT=$(echo "$BLOCKLET_DATA" | jq --arg mp "$MOUNT_PATH" '.componentMountPoints[] | select(.mountPoint == $mp)')
echo "$COMPONENT" | jq '{name, did, title, mountPoint}'
```

**Component fields**:
- `name`: Component name (may be the DID itself for some blocklets)
- `did`: Component DID (use this to identify the blocklet)
- `title`: Human-readable title (e.g., "FlowBoard", "Payment Kit")
- `mountPoint`: The URL path where this component is mounted

**Special case - root path**:
If mount path is `/`, find the component with `mountPoint: "/"`:
```bash
ROOT_COMPONENT=$(echo "$BLOCKLET_DATA" | jq '.componentMountPoints[] | select(.mountPoint == "/")')
```

**Method B: Request Page to Analyze Meta Tags**

```bash
# Request page to get HTML
curl -sS "$URL" | grep -oP '(?<=<meta name="blocklet-did" content=")[^"]*'
```

**Method C: Legacy DID API (may not work for all setups)**

```bash
# Construct API URL
API_URL="${ORIGIN}/.well-known/service/api/did/blocklet"
curl -sS "$API_URL" | jq '.name, .did, .title'
```

#### 4.3 Blocklet to Repository Mapping

**Step 1: Domain-based quick identification**

Some Blocklets can be identified by their domain pattern:

| Domain Pattern | Repository Name |
|----------------|-----------------|
| `spaces*.arcblock.io` | did-spaces |
| `store.blocklet.dev` | blocklet-store |

**Step 2: Query local reference files (following ALP)**

Based on the blocklet name, determine which organization it likely belongs to:
- Core infrastructure (blocklet-server, ux, did-connect, SDKs) → Load `references/org-arcblock-repos.md`
- Blocklet apps (payment-kit, media-kit, discuss-kit, etc.) → Load `references/org-blocklet-repos.md`
- AI-related (aigne-*, LLM adapters) → Load `references/org-aigne-repos.md`
- Uncertain → First read `references/README.md` for high-density summary

Reference file format:
```
| Name | URL | Main Branch | Branch Prefix | Description | Category |
```

Search by blocklet name or keyword in the loaded file.

**Common blocklet name/title to repository name mapping**:

| Blocklet Name/Title (from API) | Repository Name (in references) |
|--------------------------------|--------------------------------|
| `image-bin` / `Media Kit` | media-kit |
| `did-spaces` / `DID Spaces` | did-spaces |
| `payment-kit` / `Payment Kit` | payment-kit |
| `did-comments` / `Discuss Kit` | discuss-kit |
| `FlowBoard` | flow-board |
| `pages-kit` / `Pages Kit` | pages-kit |
| `vote` / `Vote` | vote |
| `ai-studio` / `AIGNE Studio` | ai-studio |
| `meilisearch` / `Search Kit` | meilisearch-kit |
| `excalidraw` / `Excalidraw` | excalidraw |
| `virtual-gift-card` / `Virtual Gift Card` | virtual-gift-card |
| `nft-blender` / `NFT Blender` | nft-blender |

**Note**: The `name` field from `componentMountPoints` may be a DID string (e.g., `z2qa4xMVAJxvA1GgfnPpMFqhdSjU9pe37NCiY`) when the blocklet uses its DID as the internal name. In such cases, use the `title` field for human-readable identification and search in reference files.

**Step 3: If no match found**

Use AskUserQuestion to let user confirm repository

### Phase 5: Output Analysis Result

```
===== URL Analysis Result =====

Input URL: {INPUT_URL}

Type: {DAEMON | BLOCKLET_SERVICE | BLOCKLET | WELLKNOWN | UNKNOWN}
Domain: {HOST}
Path: {PATH}

{If DAEMON}
Component: Blocklet Server Daemon (Core Management Interface)
Repository: ArcBlock/blocklet-server
Path: core/daemon, core/webapp

{If BLOCKLET_SERVICE}
Component: Blocklet Service (Blocklet Built-in Service Interface)
Repository: ArcBlock/blocklet-server
Path: core/service

{If BLOCKLET}
Component: {BLOCKLET_NAME} ({BLOCKLET_TITLE})
DID: {BLOCKLET_DID}
Mount Path: {MOUNT_PATH}
Repository: {ORG}/{REPO}

{If UNKNOWN}
Cannot identify automatically, please provide more information or manually specify repository.
```

---

## Common URL Pattern Quick Reference

| URL Pattern | Type | Corresponding Repository |
|-------------|------|-------------------------|
| `*/admin/*` (not IP DNS) | DAEMON | `ArcBlock/blocklet-server` |
| `*.ip.abtnet.io/.well-known/service/admin/*` | BLOCKLET_SERVICE | `ArcBlock/blocklet-server` |
| `*.ip.abtnet.io/image-bin/*` | BLOCKLET | `ArcBlock/media-kit` |
| `*.ip.abtnet.io/payment-kit/*` | BLOCKLET | `ArcBlock/payment-kit` |
| `*.ip.abtnet.io/discuss-kit/*` | BLOCKLET | `blocklet/discuss-kit` |
| `*.ip.abtnet.io/` (root path) | BLOCKLET | Request API to identify |
| `*/.well-known/did.json` | WELLKNOWN | `ArcBlock/blocklet-server` |

---

## Integration with dev-setup Skills

When `blocklet-dev-setup` or `blocklet-server-dev-setup` receives a URL that is not a GitHub Issue, call this skill to analyze:

1. Analyze URL type
2. Identify corresponding repository
3. Return repository info to dev-setup skill to continue execution

### Output Protocol

After analysis completes, output structured data for caller to parse:

```
<<<BLOCKLET_URL_ANALYSIS>>>
{
  "type": "DAEMON | BLOCKLET_SERVICE | BLOCKLET | WELLKNOWN | UNKNOWN",
  "url": "original URL",
  "host": "domain",
  "path": "path",
  "repo": "org/repo-name",
  "repoType": "blocklet-server | blocklet",
  "blocklet": {
    "name": "blocklet name (if BLOCKLET type)",
    "did": "blocklet DID",
    "title": "blocklet title",
    "mountPath": "mount path"
  }
}
<<<END_BLOCKLET_URL_ANALYSIS>>>
```

---

## Error Handling

| Error | Handling |
|-------|----------|
| Invalid URL format | Prompt user to check URL format |
| Cannot access URL | Prompt to check network or if URL is correct |
| Cannot identify Blocklet | Use AskUserQuestion to let user manually specify |
| No repository search results | Prompt user to provide complete repository path |

---

## Examples

### Example 1: Daemon URL

**Input**: `https://node-dev-1.arcblock.io/admin/blocklets`

**Output**:
```
Type: DAEMON
Component: Blocklet Server Daemon
Repository: ArcBlock/blocklet-server
Suggestion: Use blocklet-server-dev-setup skill to configure development environment
```

### Example 2: Blocklet URL

**Input**: `https://bbqaqc2vvt4mte2n4mta7dlgpsoxakc2gejo3wrrx34-18-180-145-193.ip.abtnet.io/image-bin/admin/images`

**Output**:
```
Type: BLOCKLET
Component: Image Bin (Media Kit)
Mount Path: /image-bin
Repository: ArcBlock/media-kit
Suggestion: Use blocklet-dev-setup skill to configure development environment
```

### Example 3: Blocklet Service URL

**Input**: `https://bbqaqc2vvt4mte2n4mta7dlgpsoxakc2gejo3wrrx34-18-180-145-193.ip.abtnet.io/.well-known/service/admin/overview`

**Output**:
```
Type: BLOCKLET_SERVICE
Component: Blocklet Service (Built-in Management Interface)
Repository: ArcBlock/blocklet-server
Path: core/service
Suggestion: Use blocklet-server-dev-setup skill to configure development environment
```