@acedatacloud/skills 2026.703.5 → 2026.703.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acedatacloud/skills",
3
- "version": "2026.703.5",
3
+ "version": "2026.703.6",
4
4
  "description": "Agent Skills for AceDataCloud AI services — music, image, video generation, LLM chat, web search. Compatible with Claude Code, GitHub Copilot, Gemini CLI, OpenAI Codex, and 30+ AI coding agents.",
5
5
  "keywords": [
6
6
  "agent-skills",
@@ -0,0 +1,147 @@
1
+ ---
2
+ name: hashnode
3
+ description: Publish, update and read blog posts on Hashnode via its GraphQL API. Use when the user mentions Hashnode, publishing a blog post to Hashnode, cross-posting an article to their Hashnode blog, saving a Hashnode draft, updating a published Hashnode post, or listing their Hashnode publications and posts.
4
+ when_to_use: |
5
+ Trigger when the user wants to publish a Markdown article to their
6
+ Hashnode blog, save it as a draft, update a previously published
7
+ post, or list / inspect their own Hashnode publications and posts.
8
+ The connector stores a Hashnode Personal Access Token with full
9
+ account access — confirm before publishing publicly (you can save a
10
+ draft first with the createDraft mutation).
11
+ connections: [hashnode]
12
+ allowed_tools: [Bash]
13
+ license: Apache-2.0
14
+ metadata:
15
+ author: acedatacloud
16
+ version: "1.0"
17
+ ---
18
+
19
+ Call the **Hashnode Public GraphQL API** with `curl + jq`. The user's Personal
20
+ Access Token is in `$HASHNODE_TOKEN`. Single endpoint: `https://gql.hashnode.com`
21
+ (always `POST` a JSON body `{query, variables}`).
22
+
23
+ Every request needs these headers:
24
+
25
+ ```
26
+ Authorization: $HASHNODE_TOKEN # raw token — NO "Bearer " prefix
27
+ Content-Type: application/json
28
+ ```
29
+
30
+ GraphQL always returns HTTP `200`; real failures live in the JSON `errors`
31
+ array — always inspect it and show it verbatim. An `errors` entry mentioning
32
+ `Unauthorized` / `not authenticated` means the token is invalid → the user must
33
+ re-connect the Hashnode connector.
34
+
35
+ Helper — send a query/mutation (`$1` = query string, `$2` = variables JSON):
36
+
37
+ ```bash
38
+ gql() {
39
+ jq -n --arg q "$1" --argjson v "${2:-null}" '{query:$q, variables:$v}' \
40
+ | curl -sS -X POST https://gql.hashnode.com \
41
+ -H "Authorization: $HASHNODE_TOKEN" \
42
+ -H "Content-Type: application/json" \
43
+ -d @-
44
+ }
45
+ ```
46
+
47
+ ## Always start by confirming the token and finding the publication id
48
+
49
+ `publishPost` / `createDraft` need a `publicationId`. Fetch the account and its
50
+ publications first (a user can have several blogs):
51
+
52
+ ```bash
53
+ gql 'query { me { id username publications(first: 10) { edges { node { id title url } } } } }' \
54
+ | jq '{me: .data.me.username, publications: [.data.me.publications.edges[].node | {id, title, url}], errors: .errors}'
55
+ ```
56
+
57
+ Pick the target blog's `id` (that is the `publicationId`). If the user has
58
+ exactly one publication, use it; otherwise ask which blog to post to.
59
+
60
+ ## Publish a post
61
+
62
+ **Confirm with the user before publishing publicly.** If they are not sure, save
63
+ a draft first (see below). `tags` is required — supply 1–5 tags, each as
64
+ `{name, slug}` (slug lowercase, no spaces).
65
+
66
+ ```bash
67
+ PUB_ID="PUBLICATION_ID" # from the me query above
68
+ TITLE="My title"
69
+ BODY_MD="$(cat article.md)" # full Markdown body
70
+
71
+ VARS=$(jq -n --arg p "$PUB_ID" --arg t "$TITLE" --arg b "$BODY_MD" '{
72
+ input: {
73
+ publicationId: $p,
74
+ title: $t,
75
+ contentMarkdown: $b,
76
+ tags: [{name:"AI", slug:"ai"}, {name:"Web Development", slug:"web-development"}]
77
+ }
78
+ }')
79
+
80
+ gql 'mutation PublishPost($input: PublishPostInput!) {
81
+ publishPost(input: $input) { post { id slug url title } }
82
+ }' "$VARS" | jq '{post: .data.publishPost.post, errors: .errors}'
83
+ ```
84
+
85
+ Useful optional `input` fields:
86
+
87
+ - `subtitle` — post subtitle.
88
+ - `slug` — custom URL slug (otherwise derived from the title).
89
+ - `canonicalUrl` / `originalArticleURL` — when cross-posting, point SEO back to
90
+ the original source. Set this whenever the same article also lives elsewhere.
91
+ - `coverImageOptions: { coverImageURL: "https://..." }` — cover image.
92
+ - `publishedAt` — ISO-8601 timestamp to backdate; `disableComments` etc. live
93
+ under `settings`.
94
+
95
+ ## Save a draft (safe, non-public)
96
+
97
+ Use this when the user has not explicitly approved public publishing:
98
+
99
+ ```bash
100
+ VARS=$(jq -n --arg p "$PUB_ID" --arg t "$TITLE" --arg b "$BODY_MD" '{
101
+ input: { publicationId: $p, title: $t, contentMarkdown: $b }
102
+ }')
103
+
104
+ gql 'mutation CreateDraft($input: CreateDraftInput!) {
105
+ createDraft(input: $input) { draft { id slug title } }
106
+ }' "$VARS" | jq '{draft: .data.createDraft.draft, errors: .errors}'
107
+ ```
108
+
109
+ ## Update a published post
110
+
111
+ `updatePost` needs the post `id` (from `publishPost`, or the list query below):
112
+
113
+ ```bash
114
+ VARS=$(jq -n --arg id "POST_ID" --arg b "$(cat article.md)" '{
115
+ input: { id: $id, contentMarkdown: $b }
116
+ }')
117
+
118
+ gql 'mutation UpdatePost($input: UpdatePostInput!) {
119
+ updatePost(input: $input) { post { id url title } }
120
+ }' "$VARS" | jq '{post: .data.updatePost.post, errors: .errors}'
121
+ ```
122
+
123
+ ## List / inspect my posts
124
+
125
+ ```bash
126
+ gql 'query { me { posts(pageSize: 20, page: 1) { nodes { id title slug url views reactionCount responseCount publishedAt } } } }' \
127
+ | jq '[.data.me.posts.nodes[] | {id, title, url, views, reactions: .reactionCount, responses: .responseCount}]'
128
+ ```
129
+
130
+ Single post with full content + stats:
131
+
132
+ ```bash
133
+ gql 'query GetPost($id: ObjectId!) { post(id: $id) { title url views reactionCount responseCount content { markdown } } }' \
134
+ "$(jq -n --arg id "POST_ID" '{id:$id}')" | jq '.data.post | {title, url, views, reactions: .reactionCount}'
135
+ ```
136
+
137
+ ## Gotchas
138
+
139
+ - **No `Bearer` prefix** — the `Authorization` header carries the raw token.
140
+ - **`publicationId` is mandatory** for publishing/drafting — never guess it, read
141
+ it from the `me` query.
142
+ - **`tags` is required on `publishPost`** — supply at least one `{name, slug}`;
143
+ slug must be lowercase with hyphens (e.g. `machine-learning`).
144
+ - **`errors` on HTTP 200** — GraphQL reports failures in the `errors` array, not
145
+ via status codes; always surface them.
146
+ - **Idempotency** — re-running `publishPost` creates a *new* post each time; to
147
+ change an existing one use `updatePost` with its `id`.