Quark PanSou Collector
When to Use
Use this skill when the user asks to search PanSou by keyword and return one
best Quark share link. Also use it when the user asks to save, collect, archive,
sync, or transfer that selected Quark share into Quark drive. The default save
folder is /z-sync, and the user may request another Quark drive folder.
By default, this skill only returns one verified candidate link plus a compact
verification summary. It saves to /z-sync only when the user explicitly asks
to save/sync/collect/archive/transfer the result and does not name another
destination folder. If the user says where to save, pass that folder with
--save-folder. After a strong verified selected result is returned without
--save, ask the user whether to save it; tell them to reply 1 to save to
the shown folder. A reply of exactly 1 in that context is an explicit save
request for the last selected result.
Before any strong verification or save operation, rely on the helper’s Quark
environment check. It uses QUARK_CONFIG_DIR when already set; otherwise it
defaults to ~/quarkpan-config on the current computer. It installs quarkpan
with python3 -m pip install --user quarkpan if the CLI is missing, and checks
the login state. When saving is requested and login is missing, the helper
generates a QR code PNG in that config directory and waits for the user to scan
it. In Codex chat, show that local PNG with Markdown image syntax so the user
can scan it; interactive terminal QR output may be invisible to the user. In
Telegram or other gateway chats that support native media, send the PNG as a
native attachment using MEDIA:<qr_code_path> rather than only printing the
local path. Prefer starting the login/check command as a tracked background
process, record the start time, wait until qr_code_path exists with an mtime
newer than that start time, send the image immediately, and then continue
polling or ask the user to confirm after scanning; otherwise the short QR expiry
window may pass before the user can see it. If a previous login attempt timed
out, delete or ignore the stale quark-login-qr.png before sending a new QR;
never send a QR file merely because it exists.
The agent is not the content adjudicator. It must run the deterministic policy
filter first, then output only a candidate marked transferable. The agent may
explain policy results and ask for missing inputs, but it must not override the
policy gate or use subjective judgment to turn a blocked candidate into an
output link. If the user explicitly requests account bypass, captcha bypass, or
unlawful access, stop.
AI involvement is limited to: parsing the user’s keyword, reporting the selected link and explaining tool errors. Search filtering, URL handling, source allowlisting, risk labels, best-candidate selection, and link verification are programmatic.
Inputs
- Required before searching:
keyword. - Optional: PanSou endpoint, default
https://s.panhunt.com. - Optional: source mode, default
all; accepted PanSou values areall,tg, andplugin. - Optional: maximum candidates to show, default 10 and cap at 20 unless the user explicitly asks for more.
- Optional:
refresh, default false. - Optional: policy JSON path. Default to
references/policy.default.json. - Optional: save selected link into
/z-sync, default false and enabled only when the user explicitly asks to save/sync/collect/archive/transfer. - Optional: save folder, default
/z-sync. If the user says “保存到 X” or otherwise names a destination folder, pass that Quark drive folder with--save-folder. - Optional: content choice, used only after the helper returns
needs_user_selection: true. Pass the user’s selected option number with--content-choice <index>and rerun the same command. - Optional: Quark config directory. Defaults to existing
QUARK_CONFIG_DIR, then~/quarkpan-configon the current computer. - Optional:
--check-quark-envfor checking/installingquarkpanand login status without searching.
Execution
PanSou search is a public HTTP API call, not an oo package or connector. Prefer
the bundled deterministic helper over ad hoc curl/jq, because it returns
policy labels and redacts non-transferable URLs.
From the skill directory, run:
python3 scripts/pansou_collect.py \
--keyword "<keyword>" \
--endpoint "https://s.panhunt.com" \
--src all \
--limit 10 \
--policy references/policy.default.json \
--one \
--verify-link
The helper automatically sets QUARK_CONFIG_DIR from --quark-config-dir,
then any existing QUARK_CONFIG_DIR, then ~/quarkpan-config. To check the
environment only, run:
python3 scripts/pansou_collect.py --check-quark-env --login-if-needed
If the JSON output contains event: quark_login_required with
qr_code_path, display that PNG in the chat for scanning. After the user scans
and confirms login in the Quark app, the helper continues until login succeeds
or times out.
When the user explicitly asks to save/sync/collect/archive/transfer the selected
result into Quark, add --save:
python3 scripts/pansou_collect.py \
--keyword "<keyword>" \
--endpoint "https://s.panhunt.com" \
--src all \
--limit 10 \
--policy references/policy.default.json \
--one \
--verify-link \
--save
The default save path is /z-sync. After selecting a transferable
candidate with successful strong content verification, the helper resolves or
creates the target Quark drive folder, obtains its real folder id, and saves the
share with quark_client using that folder id. This avoids the ambiguous
quarkpan save -f behavior where a missing destination folder can leave items
in the root. If the user explicitly requests another Quark drive folder, pass it
with --save-folder. Do not run quarkpan manually unless the helper is
unavailable and you have already reproduced the same selection, verification,
and target-folder rules.
If the user’s quarkpan login uses a different config directory, pass it
explicitly:
python3 scripts/pansou_collect.py \
--keyword "<keyword>" \
--one \
--verify-link \
--quark-config-dir "/path/to/quarkpan/config"
The helper searches only Quark links, deduplicates by cleaned share URL, checks
title relevance, applies source/pattern policy, and returns JSON candidates with
status, risk, reasons, and link_verification. Link verification first
tries the logged-in quark_client share-detail API; this can detect expired or
unavailable shares and count files. If quarkpan is not logged in for the
current working directory/config, it falls back to a weak HTTP page check and
marks weak_verification: true.
In --one mode it returns only selected, using this rule: one
transferable candidate with successful strong content verification after
content disambiguation. Weak HTTP page checks are never enough for --one,
because expired Quark shares may still return HTTP 200.
Before selecting one result, the helper groups transferable candidates by
programmatic content variants. Seasons/parts,全集/合集/完整版 markers,
explicit year versions such as 2008 版本 and 2016 版, and obvious
same-title editions such as subtitles after : are treated as different
content variants. If more than one strongly verified variant exists, the helper
returns needs_user_selection: true plus selection_options; do not output a
link or save anything yet. Ask the user which option number they want, then
rerun the same command with --content-choice <index>.
Do not ask the user when the remaining difference is only quality/encoding, for
example 720p, 1080p, 4K, 2160p, 蓝光, WEB-DL, HDR, DV, or
H.265. Within a single content variant, the helper automatically selects the
highest-quality strongly verified candidate.
In --save mode it still uses the same --one selection rule before saving.
If there is no strongly verified selected link, stop without saving.
If the helper is unavailable, this is the raw PanSou request shape:
curl -sS -X POST 'https://s.panhunt.com/api/search' \
-H 'Content-Type: application/json' \
--data '{"kw":"<keyword>","cloud_types":["quark"],"res":"merge","src":"all"}'
Use --data @payload.json instead of inline JSON when values contain quotes,
newlines, or user-provided structured options. A minimal payload is:
{
"kw": "<keyword>",
"cloud_types": ["quark"],
"res": "merge",
"src": "all"
}
If the user asks to force a fresh lookup, add "refresh": true. For plugin-only
or Telegram-only searches, set "src": "plugin" or "src": "tg".
When using the raw request, reproduce the helper’s policy behavior before
showing anything to the user. Extract candidates from
.data.merged_by_type.quark[]. Keep these fields: note as title, url,
password, source, datetime, and images when present. Clean the list:
- Keep only URLs matching
https://pan.quark.cn/s/<id>. - Strip query strings and whitespace from share URLs.
- Deduplicate by cleaned URL.
- Remove obvious non-matches and empty titles.
- Cap the displayed list to the requested maximum.
- Mark candidates whose title does not contain the keyword as
filtered. - Mark candidates matching configured blocked title patterns as
blocked. - Redact URLs for every status except
transferable.
Default policy lives at references/policy.default.json. A project or user may
provide a stricter policy file with source allowlists or trusted internal
endpoint hosts. The default public policy treats s.panhunt.com as a public
endpoint. Public endpoint results become transferable only when they have no
blocked/filter reasons and match at least one programmatic allow condition:
trusted endpoint host, allowlisted source, or an allowed public-material title
pattern such as government reports, white papers, manuals, open data, open
source, public domain, or Creative Commons markers. Ordinary title matches from
public endpoints are needs_authorization and their URLs stay redacted.
Return exactly one selected Quark URL when selected is present. Include the
title, source, and verification summary. If --save was requested, also report
the save result from save_result.
If selected is present and save_prompt.available is true, ask the user
whether to save it after reporting the link. Use the prompt wording from
save_prompt.message when present, for example: 回复 1 保存到 /z-sync. Do not
save immediately unless the user has already asked to save/sync/collect/archive/
transfer, or unless the user’s next reply is exactly 1 in response to this
save prompt. When the user replies 1, rerun the same search command with the
same keyword, source, policy, and any previous --content-choice, adding
--save and the same --save-folder if one was used.
If the helper returns needs_user_selection: true, report the numbered
selection_options with their labels, representative titles, sources, and
candidate counts, then ask the user to choose one number. Do not show any share
URL until the user has selected an option and the rerun returns selected.
When strong verification sees an authentication failure such as not_logged_in,
认证失败, 访问被拒绝, HTTP 401, HTTP 403, or Cookie过期, the helper clears
cookies.json, emits a fresh quark_login_required QR-code event, waits for the
user to scan, and retries the same share verification once. In gateway chats,
send the emitted qr_code_path image immediately with MEDIA:<path> and then
continue after login completes; do not treat the first auth failure as a dead
share until the retry also fails or the QR login times out.
Batch / Follow-up Handling
When the user provides multiple PanSou keywords in one message, process them as a batch but keep each keyword’s deterministic helper run independent. Use the same endpoint, source mode, policy, verification mode, and save folder unless the user gives per-item overrides. Summarize each item separately with one of these states: selected link, needs content selection, no selected candidate, or save result.
If a previous response reported several verified selected links and ended with save prompts, interpret a follow-up like 保存全部, 全部保存, or save all as an explicit request to save every previously reported selected item that had save_prompt.available: true. Rerun the helper once per item with the same keyword and any prior --content-choice, adding --save and the same --save-folder if one was used. Do not include keywords that had no selected result, were only selection prompts, or were explicitly declined.
If the user gives compact choices such as 海街日记 1 and 比海更深 1, treat the trailing number as that keyword’s --content-choice and rerun each selected keyword. If the same message also includes 保存 <keyword>, add --save for that item. When reporting batch saves, include destination folder, saved item names, and any partial failures; do not claim all succeeded unless every helper result has save_result.ok: true.
Result Handling
After the search step, report the one selected link:
- title
- URL
- source
- title match status
- link verification status
Also report a short policy summary, for example: 1 selected; 16 transferable, 0 filtered, 0 blocked. Never report redacted URLs for non-transferable
candidates. If PanSou returns no .data.merged_by_type.quark, or the helper
returns no selected, say that no verified Quark link was found and suggest
refining the keyword, switching src, or adjusting the policy.
When saving was requested, report whether quarkpan saved the selected link
successfully based on save_result. Include the destination folder, number
of files, and saved item names if visible in the command output. If saving
fails, include the visible quarkpan failure message and do not invent a
replacement link.
When a prior response ended with a save prompt and the user replies 1, treat
that as a request to save the prior selected item. Do not reinterpret 1 as a
new search keyword or content-selection choice unless the active prompt was a
content selection prompt.
Failure Handling
- User shorthand: if the user says
pansou, <keyword>orPanSou,<keyword>, treat<keyword>as the search keyword and run the normal--one --verify-linkflow. Do not ask what PanSou means. - When a verified selected result has just been shown with
save_prompt.available: true, interpret a following exact1as confirmation to rerun the same keyword/content choice with--save; do not treat it as a new content-selection choice or search keyword. - Missing keyword: ask for the keyword.
- Policy helper failure: report the helper error and do not fall back to saving raw PanSou results unless policy behavior is reproduced manually.
- No
selectedcandidate: stop without outputting a link. - PanSou HTTP/network failure: report the endpoint and status/error, then ask whether to retry later or use another PanSou endpoint.
- PanSou schema changes: inspect the JSON shape, extract only Quark URLs if still obvious, otherwise stop and report the schema mismatch.
- Link verification failure: if another
transferablecandidate exists, the helper should choose it; otherwise report the failed verification and do not invent a working link. - Save failure: report
save_result.reason,stdout, orstderr. Ifquarkpancannot be installed because the helper attemptedpython3 -m pip install --user quarkpanfrom a virtualenv where user site-packages are hidden, install the missing package into the active environment instead (for examplepython3 -m pip install quarkpan) and retry the helper. If login then fails with a missing QR/image dependency such asNo module named 'PIL', install Pillow in the same environment withpython3 -m pip install Pillowand retry. If login is missing, start the login/check command as a tracked background process, send the generatedqr_code_pathPNG as native media (MEDIA:<path>in Telegram), then ask the user to scan and confirm before rerunning the search/save. Because QR codes expire quickly, do not only report the local path. - Weak verification: tell the user the URL page responded but share contents but share contents
were not confirmed. Ask them to log in with
quarkpanin the same config context if content-level validation is required. - Legal or access concerns: follow the deterministic policy gate. If the user explicitly requests bypass or unlawful access, stop and ask for user-owned, licensed, public-domain, or otherwise authorized material.