
Multica Mentioning
- 17 installs
- 44k repo stars
- Updated August 5, 2026
- multica-ai/multica
Helps with ai & agent building tasks during AI-assisted development.
About
multica-mentioning is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- multica-mentioning
- AI & Agent Building
- AI-coding skill
Multica Mentioning by the numbers
- 17 all-time installs (skills.sh)
- +9 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #10,886 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/multica-ai/multica --skill multica-mentioningAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 17 |
|---|---|
| repo stars | ★ 44k |
| Last updated | August 5, 2026 |
| Repository | multica-ai/multica ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
Mentioning & Delegating
This skill states WHAT a mention link does in the Multica backend, traced to source. WHETHER to mention at all — loop avoidance, staying silent on acknowledgements — is in your runtime brief's Mentions section; follow that and do not repeat it here.
Every claim below is pinned to source in references/mentioning-source-map.md. If behavior ever differs from this document, the source map is where to re-check it.
A mention link is built from a real UUID
The backend recognizes a mention only through this Markdown shape:
@Label
The parser (util.MentionRe in server/internal/util/mention.go) accepts exactly four <type> values plus the all sentinel, and the <id> group accepts only hex characters and dashes, OR the literal string all:
(member|agent|squad|issue|all)/([0-9a-fA-F-]+|all)
So the link target is a real entity UUID (or all), never a display name. The label between the brackets is free text — that is where the human-readable name goes.
Step 1 — look up the UUID with --output json
A name is not a UUID. Look the UUID up first, from the matching list command:
- a person →
multica workspace member list --output json→ useuser_id - an agent →
multica agent list --output json→ useid - a squad →
multica squad list --output json→ useid
For a person the mention id is the user_id, NOT the membership-row id — the backend's own roster formatter uses user_id for member mentions. Match by display name. If the name is ambiguous or absent, do not guess — say so in your comment instead of emitting a broken link.
Step 2 — the four types and exactly what each enqueues
Format: [@Name](mention://<type>/<uuid>). The <type> and the id source must match, or the link resolves to the wrong entity (or to nothing).
| To… | type | uuid from | What the backend does |
|---|---|---|---|
| trigger an agent | agent | agent.id | enqueues a run for that agent (EnqueueTaskForMention) |
| hand work to a squad | squad | squad.id | resolves the squad's leader_id and enqueues a run for the LEADER agent |
| link a person | member | member.user_id | renders a link; enqueues NOTHING — no agent run |
| reference an issue | issue | issue.id | renders a link; enqueues NOTHING — always safe |
The mention trigger set is computed by computeMentionedAgentCommentTriggers (server/internal/handler/comment.go); the comment path folds that result into computeCommentAgentTriggers and enqueues it via enqueueCommentAgentTriggers. It acts on two types only: the squad branch resolves the squad and adds its leader to the trigger set; everything that is not agent after that is skipped (if m.Type != "agent" { continue }), then the agent branch adds that agent. A member or issue mention reaches neither branch, so it enqueues no task.
A member mention therefore does NOT make a person "run", and this skill does NOT claim it delivers a notification through the Go comment handler — there is no such code path in that handler (see the source map). What is verified is the contract above: only agent and squad mentions enqueue work.
Preview and per-comment suppression
Newer clients can call POST /api/issues/{id}/comments/trigger-preview before creating or editing a comment. The preview endpoint uses the same computeCommentAgentTriggers function as create and edit re-triggering, so the displayed agent chips come from backend rules, not from a client-side reimplementation.
When previewing an edit, clients may send editing_comment_id. The server validates that the comment belongs to the same workspace and issue, derives or checks the edit's parent comment context, and excludes only pending tasks whose trigger_comment_id is that same comment. Pending tasks from any other comment on the issue still dedupe the preview.
When creating or editing a comment, clients may send an optional suppress_agent_ids array. The server still computes the full trigger set first, then removes those agent IDs as a post-filter. A missing or empty field preserves the old behavior. A valid UUID that is not in the computed trigger set is a no-op; a malformed UUID is rejected at the request boundary.
@all is the broadcast type
@all uses the literal all, never a UUID:
@all
It addresses everyone on the issue. It does NOT make any specific agent run. And it is special at trigger time: in commentMentionsOthersButNotAssignee (server/internal/handler/comment.go), a comment that carries an @all mention is treated as a broadcast that SUPPRESSES the issue assignee's automatic on-comment trigger. Use @all to announce, not to request work from the assignee.
What does NOT happen (so the result doesn't surprise you)
These are all silent no-ops — no error, no run:
- A name where a UUID belongs.
mention://member/Aliceis dead. The id
group accepts only hex+dashes or all; the non-hex letters in a typical name make the whole pattern fail to match, so the parser returns nothing.
- A hex-ish but wrong UUID. A well-formed-looking UUID that no entity owns
DOES parse, then no-ops at lookup: the workspace-scoped query finds no agent and the loop continues. Same agent-visible result (nothing fires), but the mechanism is the lookup miss, not a parse failure.
- An already-pending task. Even a correct
@agent/@squadis skipped when
the target already has a pending task on this issue (HasPendingTaskForIssueAndAgent → continue). Edit preview is the only exception: editing_comment_id ignores pending tasks from the same comment being edited, because save cancels those old tasks before it re-computes triggers. It is still comment-scoped, not an agent-wide bypass.
- An archived agent, or a squad whose leader is archived: skipped
(RuntimeID invalid or ArchivedAt set).
- A private agent you cannot access: skipped — the mention path gates on
canAccessPrivateAgent directly for both @agent and @squad (the canEnqueueSquadLeader wrapper is the assignment/child-done path, not this one).
Incorrect → Correct
Incorrect: @alice please review → plain text, no link, parses to nothing, nobody is reached.
Incorrect: [@Alice](mention://member/Alice) please review → "Alice" is not a UUID; the id group rejects the non-hex letters, the pattern does not match, the link is silently dead.
Correct: 1. multica workspace member list --output json → Alice's user_id = 7f3a… 2. [@Alice](mention://member/7f3a…) please review → a real user_id parses; the link renders and resolves to Alice.
@all broadcast: [@all](mention://all/all) heads up — addresses everyone, runs no specific agent, and suppresses the assignee auto-trigger.
These exact shapes are pinned by a Go behavior test (TestMentioningSkillTeachesTheParserContract) that feeds them through util.ParseMentions: the name form parses to nothing, the real-UUID form parses, @all parses to {all, all}, and a wrong type with a real UUID still parses (which is why the type must match the id source).
References
references/mentioning-source-map.md — file:line evidence for the regex, the enqueue branches, the @all suppression, and the CLI id-source mapping, plus the explicit note that no member-notification delivery path exists in the Go comment handler.
Mentioning — source map
Every claim in SKILL.md traces to a line below. Re-derive against the current tree before trusting any line number; the behavior is the contract, the line is a pointer.
The mention grammar (what parses)
| Fact | Source |
|---|---|
MentionRe — the only recognizer of a mention link | server/internal/util/mention.go:16 |
Pattern: ` \[@?(.+?)\]\(mention://(member\ | agent\ |
<type> group = `member \ | agent \ |
<id> group = [0-9a-fA-F-]+ (hex + dashes) or the literal all — so a typical name with non-hex letters never matches | server/internal/util/mention.go:16 |
ParseMentions extracts and dedups {Type, ID} from m[2]/m[3] | server/internal/util/mention.go:24-37 |
Mention.Type doc enum = "member", "agent", "issue", or "all" (squad added in regex) | server/internal/util/mention.go:7 |
HasMentionAll reports whether any parsed mention is all | server/internal/util/mention.go:40-47 |
Parser behavior tests (pin the example shapes the skill uses)
| Case proven | Source |
|---|---|
mention://member/<real-uuid> parses to {member, uuid} | server/internal/util/mention_test.go:42-45 |
mention://all/all parses to {all, all} | server/internal/util/mention_test.go:47-50 |
mention://agent/<uuid> parses; label may contain [brackets] | server/internal/util/mention_test.go:13-35 |
plain text with no mention:// parses to nil | server/internal/util/mention_test.go:57-60 |
Skill eval: a name where a UUID belongs (mention://member/Alice) parses to nil; a bare @name parses to nil; a real UUID parses; @all → {all, all}; a wrong type with a real UUID still parses (points at the wrong entity) | server/internal/service/builtin_skills_test.go:101-157 |
What each mention type enqueues
| Fact | Source |
|---|---|
computeCommentAgentTriggers is the shared comment trigger computation used by preview and enqueueing | server/internal/handler/comment.go:1159-1195 |
computeMentionedAgentCommentTriggers builds the mention trigger set; enqueueCommentAgentTriggers is the shared enqueue helper | server/internal/handler/comment.go:1381-1467,1124-1157 |
Comment creation runs triggerTasksForComment, which computes triggers, applies suppressions, then enqueues | server/internal/handler/comment.go:1069,1092-1098 |
Comment edit re-triggering also runs triggerTasksForComment after cancelling old tasks for the edited comment | server/internal/handler/comment.go:1577-1594 |
squad branch: resolve squad in workspace, read LeaderID, add the leader trigger | server/internal/handler/comment.go:1397-1435 |
squad → shared enqueue helper calls EnqueueTaskForSquadLeader | server/internal/handler/comment.go:1141-1147 |
Everything not agent after the squad branch is skipped: if m.Type != "agent" { continue } | server/internal/handler/comment.go:1437-1439 |
agent branch: load agent in workspace, then add the agent trigger | server/internal/handler/comment.go:1440-1464 |
agent → shared enqueue helper calls EnqueueTaskForMention (a run for that agent) | server/internal/handler/comment.go:1148-1154 |
`member` and `issue` mentions reach neither branch — they enqueue NOTHING. A member mention fails the != "agent" skip at lines 1437-1439 (the squad branch above it only matches squad); an issue mention does the same. | server/internal/handler/comment.go:1397,1437-1439 |
Preview and suppression
| Fact | Source |
|---|---|
Preview route: POST /api/issues/{id}/comments/trigger-preview | server/cmd/server/router.go:707 |
Preview handler loads the issue, expands issue identifiers, then calls computeCommentAgentTriggers | server/internal/handler/comment.go:837-911 |
Preview request accepts content, optional parent_id, and optional editing_comment_id | server/internal/handler/comment.go:778-782 |
Preview response returns agent id, name, optional avatar_url, source, and reason | server/internal/handler/comment.go:784-793 |
editing_comment_id is parsed as UUID input, scoped to the same workspace and issue, and used as ExcludeTriggerCommentID | server/internal/handler/comment.go:855-872 |
| Preview validates or derives the parent context for an edit | server/internal/handler/comment.go:874-897 |
CreateCommentRequest accepts optional suppress_agent_ids | server/internal/handler/comment.go:770-776 |
UpdateComment accepts optional suppress_agent_ids | server/internal/handler/comment.go:1509-1513 |
Create-comment suppress_agent_ids is parsed as request-boundary UUID input | server/internal/handler/comment.go:957-964 |
Update-comment suppress_agent_ids is parsed as request-boundary UUID input | server/internal/handler/comment.go:1523-1535 |
Create and edit trigger paths compute the full trigger set, then apply filterSuppressedCommentAgentTriggers before enqueueing | server/internal/handler/comment.go:1092-1122,1594 |
Frontend API sends editing_comment_id for preview and suppress_agent_ids for update when present | packages/core/api/client.ts:664-700 |
Edit UI calls preview with editingCommentId, renders trigger chips, tracks suppressed agents, and submits suppressions on save | packages/views/issues/components/comment-card.tsx:269-274,300-315,359-367,578-582,858-862 |
Preview hook includes editingCommentId in its query key and sends it to the API | packages/views/issues/hooks/use-comment-trigger-preview.ts:58-80 |
| Timeline edit mutation passes suppressed agent IDs through to the API layer | packages/views/issues/hooks/use-issue-timeline.ts:299-302 |
Edit-preview pending-task dedup
| Fact | Source |
|---|---|
| Default dedup query skips any queued or dispatched task for the issue and agent | server/pkg/db/queries/agent.sql:544-548 |
Edit-preview dedup query excludes only tasks whose trigger_comment_id equals the edited comment | server/pkg/db/queries/agent.sql:550-558 |
hasPendingTaskForIssueAndAgent selects the comment-scoped exclusion only when ExcludeTriggerCommentID is valid | server/internal/handler/comment.go:1232-1244 |
| Agent-assignee on-comment dedup uses the shared helper | server/internal/handler/issue.go:2576-2594 |
| Assigned squad leader on-comment dedup uses the shared helper | server/internal/handler/comment.go:1197-1229 |
| Mentioned squad leader dedup uses the shared helper | server/internal/handler/comment.go:1397-1435 |
| Direct agent mention dedup uses the shared helper | server/internal/handler/comment.go:1440-1464 |
| Positive regression test covers all four edit-preview trigger sources | server/internal/handler/comment_trigger_preview_test.go:179-265 |
| Negative regression test proves another comment's pending task still dedupes the preview | server/internal/handler/comment_trigger_preview_test.go:267-290 |
Edit-submit regression test proves suppress_agent_ids filters update-triggered tasks | server/internal/handler/comment_trigger_preview_test.go:292-316 |
Guards that make a valid mention a silent no-op
| Guard | Source |
|---|---|
agent archived / no runtime → continue (RuntimeID invalid or ArchivedAt set) | server/internal/handler/comment.go:1451-1452 |
squad leader archived / no runtime → continue | server/internal/handler/comment.go:1417-1423 |
private agent the actor cannot access → continue (canAccessPrivateAgent) | server/internal/handler/comment.go:1454-1458 |
private squad leader the actor cannot trigger → continue (canAccessPrivateAgent) | server/internal/handler/comment.go:1425-1428 |
already-pending dedup (agent) → shared pending-task helper → continue | server/internal/handler/comment.go:1459-1463 |
already-pending dedup (squad leader) → shared pending-task helper → continue | server/internal/handler/comment.go:1429-1433 |
canAccessPrivateAgent definition | server/internal/handler/agent_access.go (search func (h *Handler) canAccessPrivateAgent) |
canEnqueueSquadLeader (loads leader, delegates to canAccessPrivateAgent) | server/internal/handler/agent_access.go:82-91 |
@all broadcast and assignee-trigger suppression
| Fact | Source |
|---|---|
commentMentionsOthersButNotAssignee — decides whether to suppress the assignee's on-comment trigger | server/internal/handler/comment.go:1246-1288 |
@all is treated as a broadcast → returns true → assignee auto-trigger suppressed | server/internal/handler/comment.go:1257-1261 |
| Comment-flow computation that consults it | server/internal/handler/comment.go:1175-1177 |
@all never enqueues a specific agent: it is neither squad nor agent, so it is skipped in the mention trigger computation | server/internal/handler/comment.go:1437-1439 |
CLI id sources (where the UUID comes from)
| List command | Field used as mention id | Source |
|---|---|---|
workspace member list | user_id (NOT the membership-row id) | server/cmd/multica/cmd_workspace.go:465 |
agent list | id | server/cmd/multica/cmd_agent.go:365 |
squad list | id | server/cmd/multica/cmd_squad.go:57 |
Member mention uses user_id, confirmed by the backend roster formatter: formatMention(user.Name, "member", userID) where userID = UUIDToString(m.MemberID) | server/internal/handler/squad_briefing.go:189-190 | |
formatMention emits [@<name>](mention://<type>/<id>) | server/internal/handler/squad_briefing.go:216-218 |
Explicit non-claim: no member-notification path in the Go comment handler
The skill deliberately does not assert that a member mention "sends a notification." server/internal/handler/comment.go has no notification delivery path for member (or issue) mentions: computeMentionedAgentCommentTriggers branches only on squad and agent (server/internal/handler/comment.go:1397,1437-1439), and a grep of the file for notif returns only an unrelated comment about avoiding "log spam" on unchanged threads — no member-notification call. The verified contract is narrow: a member or issue mention renders as a link and enqueues no agent run; only agent and squad mentions enqueue work. If a notification UX exists, it is not in this handler, so this skill makes no claim about it.