@geekbeer/minion 3.49.1 → 3.50.0

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.
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Helpers for the note user-mention syntax: `@[Display Name](user:UUID)`.
3
+ *
4
+ * HQ stores notes as Markdown. When humans write `@[Yuno](user:abc-...)` in
5
+ * the note editor (via Ctrl+I), the minion needs to read it as a normal
6
+ * `@Yuno`-style attribution rather than the raw bracket form. These helpers
7
+ * normalize and parse that syntax so skills/runners do not have to reinvent it.
8
+ *
9
+ * The UUID is the stable identity; the display name is a snapshot at insertion
10
+ * time and is the human-friendly handle.
11
+ */
12
+
13
+ // Allow short test ids too (>= 8 chars) so the helper is usable in fixtures
14
+ // even when the canonical 36-char UUID is not present.
15
+ const USER_MENTION_REGEX = /@\[([^\]\n]+?)\]\(user:([0-9a-fA-F-]{8,})\)/g
16
+
17
+ /**
18
+ * Replace `@[Display Name](user:UUID)` with `@Display Name`.
19
+ * Pass minion-bound markdown through this before injecting into a prompt or
20
+ * task payload so Claude does not see the raw bracket syntax.
21
+ *
22
+ * @param {string} markdown
23
+ * @returns {string}
24
+ */
25
+ function normalizeNoteMentions(markdown) {
26
+ if (typeof markdown !== 'string' || markdown.length === 0) return markdown
27
+ return markdown.replace(USER_MENTION_REGEX, (_match, name) => `@${name}`)
28
+ }
29
+
30
+ /**
31
+ * Extract every user mention as { userId, displayName } in document order.
32
+ * Useful when a workflow step needs to know "who wrote this note" without
33
+ * round-tripping through HQ.
34
+ *
35
+ * @param {string} markdown
36
+ * @returns {Array<{ userId: string, displayName: string }>}
37
+ */
38
+ function extractNoteMentions(markdown) {
39
+ if (typeof markdown !== 'string' || markdown.length === 0) return []
40
+ const out = []
41
+ // RegExp.exec with /g maintains lastIndex on the regex itself, so use a fresh copy.
42
+ const re = new RegExp(USER_MENTION_REGEX.source, 'g')
43
+ let match
44
+ while ((match = re.exec(markdown)) !== null) {
45
+ out.push({ displayName: match[1], userId: match[2] })
46
+ }
47
+ return out
48
+ }
49
+
50
+ module.exports = {
51
+ USER_MENTION_REGEX,
52
+ normalizeNoteMentions,
53
+ extractNoteMentions,
54
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geekbeer/minion",
3
- "version": "3.49.1",
3
+ "version": "3.50.0",
4
4
  "description": "AI Agent runtime for Minion - manages status and skill deployment on VPS",
5
5
  "main": "linux/server.js",
6
6
  "bin": {
package/rules/core.md CHANGED
@@ -390,6 +390,30 @@ hq note get <project_id> <note_id>
390
390
  hq note search <project_id> "キーワード"
391
391
  ```
392
392
 
393
+ ### ノート内のユーザーメンション
394
+
395
+ 人間ユーザーがノート編集UIで `Ctrl+I` を押すと、自分の発言を示すアバター付きチップが行頭に挿入される。マークダウン上は次の形式で永続化される:
396
+
397
+ ```
398
+ @[Display Name](user:UUID)
399
+ ```
400
+
401
+ ミニオンがノートを読む場合、この記法はそのままだと冗長なので、`@/Display Name` 表記に正規化してから処理する。`packages/minion/core/lib/note-mentions.js` のヘルパを使う:
402
+
403
+ ```js
404
+ const { normalizeNoteMentions, extractNoteMentions } = require('./core/lib/note-mentions')
405
+
406
+ // 例: ノート本文を読み取って正規化
407
+ const normalized = normalizeNoteMentions(noteMarkdown)
408
+ // "@Yuno が書きました。"
409
+
410
+ // 例: 誰の発言かを抽出
411
+ const mentions = extractNoteMentions(noteMarkdown)
412
+ // [{ displayName: 'Yuno', userId: 'abc-...' }, ...]
413
+ ```
414
+
415
+ UUIDは安定IDなので、表示名が変わっても発言者の同一性を判定できる。書き戻す側のミニオンは原則この記法を生成しないこと(人間専用の発言マーカー)。
416
+
393
417
  ### `~/files/` への保存
394
418
 
395
419
  バイナリファイルやユーザーがダウンロードする必要があるファイルは `~/files/` に配置する。