@synity/bitrix-skills 1.3.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.
Files changed (77) hide show
  1. package/CHANGELOG.md +169 -0
  2. package/LICENSE +21 -0
  3. package/README.md +83 -0
  4. package/bin/bitrix-skills.js +3 -0
  5. package/dist/cli.js +1510 -0
  6. package/dist/features/bx-task/install.js +111 -0
  7. package/dist/features/task-sync/index.js +1053 -0
  8. package/package.json +69 -0
  9. package/src/features/bx/assets/SKILL.md +34 -0
  10. package/src/features/bx/feature.json +8 -0
  11. package/src/features/bx-calendar/assets/SKILL.md +61 -0
  12. package/src/features/bx-calendar/assets/availability.md +65 -0
  13. package/src/features/bx-calendar/assets/meeting.md +87 -0
  14. package/src/features/bx-calendar/assets/reminder.md +71 -0
  15. package/src/features/bx-calendar/assets/sync.md +70 -0
  16. package/src/features/bx-calendar/feature.json +10 -0
  17. package/src/features/bx-crm/assets/SKILL.md +59 -0
  18. package/src/features/bx-crm/assets/commerce.md +96 -0
  19. package/src/features/bx-crm/assets/onboard.md +127 -0
  20. package/src/features/bx-crm/assets/report.md +98 -0
  21. package/src/features/bx-crm/assets/research.md +71 -0
  22. package/src/features/bx-crm/feature.json +10 -0
  23. package/src/features/bx-task/assets/SKILL.md +148 -0
  24. package/src/features/bx-task/assets/lib/bx-api.sh +39 -0
  25. package/src/features/bx-task/assets/lib/bx-checklist.sh +127 -0
  26. package/src/features/bx-task/assets/lib/bx-resolve-task.sh +41 -0
  27. package/src/features/bx-task/assets/lib/bx-state.sh +131 -0
  28. package/src/features/bx-task/assets/lib/bx-tasks.sh +109 -0
  29. package/src/features/bx-task/assets/references/bootstrap.md +184 -0
  30. package/src/features/bx-task/assets/references/feature.md +97 -0
  31. package/src/features/bx-task/assets/references/init-templates/cli-tool.md +47 -0
  32. package/src/features/bx-task/assets/references/init-templates/generic.md +31 -0
  33. package/src/features/bx-task/assets/references/init-templates/library.md +45 -0
  34. package/src/features/bx-task/assets/references/init-templates/monorepo.md +38 -0
  35. package/src/features/bx-task/assets/references/init-templates/npm-package.md +40 -0
  36. package/src/features/bx-task/assets/references/init-templates/web-app.md +46 -0
  37. package/src/features/bx-task/assets/references/init.md +107 -0
  38. package/src/features/bx-task/assets/references/roadmap.md +93 -0
  39. package/src/features/bx-task/assets/references/summary.md +269 -0
  40. package/src/features/bx-task/assets/references/sync.md +104 -0
  41. package/src/features/bx-task/assets/references/time-log.md +214 -0
  42. package/src/features/bx-task/feature.json +10 -0
  43. package/src/features/bx-task/install.ts +117 -0
  44. package/src/features/task-sync/assets/docs/bitrix-task-reference.md +318 -0
  45. package/src/features/task-sync/assets/docs/bitrix-task-sync.md +254 -0
  46. package/src/features/task-sync/assets/githooks/commit-msg +44 -0
  47. package/src/features/task-sync/assets/githooks/install.sh +15 -0
  48. package/src/features/task-sync/assets/manifest.json +108 -0
  49. package/src/features/task-sync/assets/rules/00-bitrix-task-sync.md +161 -0
  50. package/src/features/task-sync/assets/scripts/bitrix-attach-files.sh +55 -0
  51. package/src/features/task-sync/assets/scripts/bitrix-lib.sh +540 -0
  52. package/src/features/task-sync/assets/scripts/bitrix-render-digest.sh +116 -0
  53. package/src/features/task-sync/assets/scripts/bitrix-session-check.sh +51 -0
  54. package/src/features/task-sync/assets/scripts/bitrix-session-sync.sh +89 -0
  55. package/src/features/task-sync/assets/scripts/bitrix-skill-end.sh +165 -0
  56. package/src/features/task-sync/assets/scripts/bitrix-skill-start.sh +58 -0
  57. package/src/features/task-sync/assets/scripts/lib/bb-formatter.sh +110 -0
  58. package/src/features/task-sync/assets/scripts/lib/bitrix-lib.sh +540 -0
  59. package/src/features/task-sync/assets/scripts/lib/time-helpers.sh +57 -0
  60. package/src/features/task-sync/assets/workflows/bitrix-sync.yml +85 -0
  61. package/src/features/task-sync/commands/install.ts +296 -0
  62. package/src/features/task-sync/commands/uninstall.ts +189 -0
  63. package/src/features/task-sync/commands/update.ts +11 -0
  64. package/src/features/task-sync/commands/verify.ts +141 -0
  65. package/src/features/task-sync/feature.json +12 -0
  66. package/src/features/task-sync/index.ts +121 -0
  67. package/src/features/task-sync/lib/dest-map.ts +96 -0
  68. package/src/features/task-sync/lib/drift-check.ts +47 -0
  69. package/src/features/task-sync/lib/file-ops.ts +36 -0
  70. package/src/features/task-sync/lib/manifest.ts +66 -0
  71. package/src/features/task-sync/lib/project-root.ts +38 -0
  72. package/src/features/task-sync/lib/settings-merge.ts +112 -0
  73. package/src/features/task-sync/lib/skill-refs.ts +106 -0
  74. package/src/features/task-sync/lib/task-id-finder.ts +31 -0
  75. package/src/features/task-sync/lib/token-extractor.ts +52 -0
  76. package/src/features/task-sync/lib/version.ts +36 -0
  77. package/src/features/task-sync/types.ts +40 -0
@@ -0,0 +1,40 @@
1
+ [B]{{PACKAGE_NAME}}[/B] — {{ONE_LINE_VALUE_PROP}}
2
+
3
+ [B]Install[/B]
4
+ [code]
5
+ {{INSTALL_COMMANDS}}
6
+ [/code]
7
+
8
+ [B]Commands[/B]
9
+ [code]
10
+ {{KEY_COMMANDS_OR_USAGE}}
11
+ [/code]
12
+
13
+ [B]Architecture[/B]
14
+ [code]
15
+ {{ASCII_DIAGRAM}}
16
+ [/code]
17
+
18
+ [B]Feature Matrix[/B]
19
+ [table]
20
+ [tr][th]Feature[/th][th]Target[/th][th]Trigger[/th][th]Lifecycle[/th][/tr]
21
+ {{FEATURE_MATRIX_ROWS}}
22
+ [/table]
23
+
24
+ [B]Phase Timeline[/B]
25
+ {{PHASE_TIMELINE}}
26
+
27
+ [B]Open Issues[/B]
28
+ {{OPEN_ISSUES}}
29
+
30
+ [B]Success Criteria[/B]
31
+ {{SUCCESS_CRITERIA}}
32
+
33
+ [B]Liên kết[/B]
34
+ • Repo: [URL={{REPO_URL}}]{{REPO_SHORT}}[/URL]
35
+ • npm: [URL=https://www.npmjs.com/package/{{PACKAGE_NAME}}]{{PACKAGE_NAME}}[/URL]
36
+ • Plan dir: {{PLAN_DIR}}
37
+ • Active phase: {{ACTIVE_PHASE_PATH}}
38
+ • Docs: docs/project-overview-pdr.md, docs/system-architecture.md, docs/codebase-summary.md
39
+ • README: README.md
40
+ • CHANGELOG: CHANGELOG.md
@@ -0,0 +1,46 @@
1
+ [B]{{PACKAGE_NAME}}[/B] — {{ONE_LINE_VALUE_PROP}}
2
+
3
+ [B]Dev / Build / Deploy[/B]
4
+ [code]
5
+ {{INSTALL_COMMANDS}}
6
+ [/code]
7
+
8
+ [B]Routes / Pages[/B]
9
+ [table]
10
+ [tr][th]Path[/th][th]Component[/th][th]Purpose[/th][/tr]
11
+ {{ROUTES_ROWS}}
12
+ [/table]
13
+
14
+ [B]Architecture[/B]
15
+ [code]
16
+ {{ASCII_DIAGRAM}}
17
+ [/code]
18
+
19
+ [B]Components & State[/B]
20
+ [table]
21
+ [tr][th]Module[/th][th]Role[/th][/tr]
22
+ {{FEATURE_MATRIX_ROWS}}
23
+ [/table]
24
+
25
+ [B]API Endpoints[/B]
26
+ {{API_ENDPOINTS_OR_NONE}}
27
+
28
+ [B]Deploy Targets[/B]
29
+ {{DEPLOY_TARGETS}}
30
+
31
+ [B]Phase Timeline[/B]
32
+ {{PHASE_TIMELINE}}
33
+
34
+ [B]Open Issues[/B]
35
+ {{OPEN_ISSUES}}
36
+
37
+ [B]Success Criteria[/B]
38
+ {{SUCCESS_CRITERIA}}
39
+
40
+ [B]Liên kết[/B]
41
+ • Repo: [URL={{REPO_URL}}]{{REPO_SHORT}}[/URL]
42
+ • Live: [URL={{LIVE_URL}}]{{LIVE_URL_SHORT}}[/URL]
43
+ • Plan dir: {{PLAN_DIR}}
44
+ • Active phase: {{ACTIVE_PHASE_PATH}}
45
+ • Docs: docs/project-overview-pdr.md, docs/system-architecture.md, docs/codebase-summary.md
46
+ • README: README.md
@@ -0,0 +1,107 @@
1
+ # /bx:task init — Initialize TASK_ID in CLAUDE.md
2
+
3
+ Detect or insert a `TASK_ID` block into the nearest `CLAUDE.md`. No Bitrix API calls — filesystem only.
4
+
5
+ ## When to use
6
+
7
+ - Starting a new AI session in a project that hasn't set `TASK_ID` yet
8
+ - Switching to a different Bitrix task mid-project
9
+ - Setting up a new feature branch with its own task context
10
+
11
+ ## Args
12
+
13
+ ```
14
+ /bx:task init [--task-id N]
15
+ ```
16
+
17
+ - `--task-id N` — skip interactive prompt, use this value directly
18
+
19
+ ## Algorithm
20
+
21
+ ### Step 1 — Locate CLAUDE.md
22
+
23
+ Walk up from `$PWD` looking for `CLAUDE.md`:
24
+
25
+ ```bash
26
+ dir="$PWD"
27
+ CLAUDE_MD=""
28
+ while [[ "$dir" != "/" ]]; do
29
+ if [[ -f "$dir/CLAUDE.md" ]]; then
30
+ CLAUDE_MD="$dir/CLAUDE.md"
31
+ break
32
+ fi
33
+ dir="$(dirname "$dir")"
34
+ done
35
+ ```
36
+
37
+ If not found → will create `$PWD/CLAUDE.md`.
38
+
39
+ ### Step 2 — Check existing TASK_ID
40
+
41
+ ```bash
42
+ EXISTING_ID=$(grep -m1 '^TASK_ID:' "${CLAUDE_MD:-}" 2>/dev/null | awk '{print $2}')
43
+ ```
44
+
45
+ If `EXISTING_ID` found:
46
+ - Show: `Current TASK_ID: {EXISTING_ID} in {CLAUDE_MD}`
47
+ - Ask via `AskUserQuestion`: "TASK_ID đã tồn tại. Bạn muốn làm gì?"
48
+ - "Giữ nguyên #{EXISTING_ID}" → exit 0
49
+ - "Đổi sang task khác" → continue to Step 3
50
+ - "Cancel" → exit 0
51
+
52
+ ### Step 3 — Get TASK_ID value
53
+
54
+ If `--task-id N` was passed → `NEW_ID=N`, skip prompt.
55
+
56
+ Otherwise use `AskUserQuestion`:
57
+ - question: "Nhập TASK_ID (số) cho project này:"
58
+ - options: leave as free-text (user types the number)
59
+
60
+ Validate: must be a positive integer. If invalid → error + re-prompt (max 3 attempts).
61
+
62
+ ### Step 4 — Insert or update TASK_ID block
63
+
64
+ **If CLAUDE.md exists and has existing `## Bitrix Task` section:**
65
+
66
+ Find the section and update/insert `TASK_ID: N` line:
67
+
68
+ ```bash
69
+ # Check if ## Bitrix Task section exists
70
+ if grep -q '^## Bitrix Task' "$CLAUDE_MD"; then
71
+ # Update existing TASK_ID line if present
72
+ if grep -q '^TASK_ID:' "$CLAUDE_MD"; then
73
+ sed -i '' "s/^TASK_ID:.*/TASK_ID: ${NEW_ID}/" "$CLAUDE_MD"
74
+ else
75
+ # Insert TASK_ID after "## Bitrix Task" line
76
+ sed -i '' "/^## Bitrix Task/a\\
77
+ TASK_ID: ${NEW_ID}" "$CLAUDE_MD"
78
+ fi
79
+ else
80
+ # Append full block at end of file
81
+ printf '\n## Bitrix Task\nTASK_ID: %s\n' "$NEW_ID" >> "$CLAUDE_MD"
82
+ fi
83
+ ```
84
+
85
+ **If CLAUDE.md does not exist:**
86
+
87
+ ```bash
88
+ printf '## Bitrix Task\nTASK_ID: %s\n' "$NEW_ID" > "$PWD/CLAUDE.md"
89
+ CLAUDE_MD="$PWD/CLAUDE.md"
90
+ ```
91
+
92
+ ### Step 5 — Confirm result
93
+
94
+ Print:
95
+ ```
96
+ ✓ TASK_ID set to #{NEW_ID} in {CLAUDE_MD}
97
+ Hooks will now sync AI activity to: https://{portal}/workgroups/group/{GROUP_ID}/tasks/task/view/{NEW_ID}/
98
+ ```
99
+
100
+ If `BITRIX_WEBHOOK_URL` is set, extract portal domain from the URL for the confirmation link.
101
+ Otherwise: `✓ TASK_ID: {NEW_ID} saved to {CLAUDE_MD}`
102
+
103
+ ## Error handling
104
+
105
+ - Invalid TASK_ID (non-integer) → `ERROR: TASK_ID must be a positive integer.`
106
+ - CLAUDE.md not writable → `ERROR: Cannot write to {path}. Check permissions.`
107
+ - No CLAUDE.md found and CWD not a git repo → warn "No CLAUDE.md found and CWD is not a git root. Creating {PWD}/CLAUDE.md anyway." → proceed
@@ -0,0 +1,93 @@
1
+ # /bx:task roadmap — Manage Done/Doing/Plan checklist groups on main task
2
+
3
+ Two actions:
4
+
5
+ | Action | Effect |
6
+ |--------|--------|
7
+ | `add <group> <item>` | Append a new item to a group (Done/Doing/Plan) |
8
+ | `move <item> <from> <to>` | Mark item complete in `<from>`, add (possibly checked) in `<to>` |
9
+
10
+ `<group>` ∈ `done | doing | plan`. `<item>` = exact title text used during add/move.
11
+
12
+ ## Args
13
+
14
+ ```
15
+ /bx:task roadmap add <group> <item-title>
16
+ /bx:task roadmap move <item-title> <from-group> <to-group>
17
+ ```
18
+
19
+ Item title supports spaces (quote in shell or pass as-is from skill arg parser).
20
+
21
+ ## Prerequisite
22
+
23
+ State must have all 3 `checklists.{done,doing,plan}.parentId` set. If missing → run
24
+ `/bx:task bootstrap` first.
25
+
26
+ ## Algorithm — `add`
27
+
28
+ ```bash
29
+ source ~/.claude/skills/bx-task/lib/bx-api.sh
30
+ source ~/.claude/skills/bx-task/lib/bx-state.sh
31
+ source ~/.claude/skills/bx-task/lib/bx-checklist.sh
32
+ source ~/.claude/skills/bx-task/lib/bx-tasks.sh
33
+
34
+ bx_preflight || exit 1
35
+ MAIN_ID=$(bx_state_get "mainTaskId")
36
+ PARENT=$(bx_state_get "checklists.${GROUP}.parentId")
37
+ if [[ -z "$MAIN_ID" || -z "$PARENT" ]]; then
38
+ echo "⛔ State not bootstrapped, or unknown group '$GROUP'." >&2
39
+ echo " Valid groups: done, doing, plan." >&2
40
+ exit 1
41
+ fi
42
+
43
+ # Confirm before POST (AskUserQuestion: "Add '$ITEM' to $GROUP on task #$MAIN_ID?")
44
+
45
+ NEW_ID=$(bx_checklist_add "$MAIN_ID" "$GROUP" "$ITEM")
46
+ [[ "$GROUP" == "done" ]] && bx_checklist_toggle "$MAIN_ID" "$NEW_ID" "Y"
47
+
48
+ echo "✓ Added '$ITEM' to $GROUP (item #$NEW_ID)"
49
+ ```
50
+
51
+ ## Algorithm — `move`
52
+
53
+ ```bash
54
+ bx_preflight || exit 1
55
+ MAIN_ID=$(bx_state_get "mainTaskId")
56
+
57
+ FROM_PID=$(bx_state_get "checklists.${FROM}.parentId")
58
+ TO_PID=$(bx_state_get "checklists.${TO}.parentId")
59
+ if [[ -z "$MAIN_ID" || -z "$FROM_PID" || -z "$TO_PID" ]]; then
60
+ echo "⛔ State not bootstrapped, or unknown group." >&2
61
+ exit 1
62
+ fi
63
+
64
+ # Confirm before POST
65
+
66
+ NEW_ID=$(bx_checklist_move "$MAIN_ID" "$ITEM" "$FROM" "$TO")
67
+ if [[ -z "$NEW_ID" ]]; then
68
+ echo "ERROR: move failed — item '$ITEM' may not exist in $FROM" >&2
69
+ exit 1
70
+ fi
71
+
72
+ echo "✓ Moved '$ITEM' from $FROM → $TO (new item #$NEW_ID)"
73
+ ```
74
+
75
+ ## Behavior notes
76
+
77
+ - **`add` to `done`** auto-toggles complete (`IS_COMPLETE=Y`).
78
+ - **`move`** preserves history by keeping the source item (marked complete) and creating a
79
+ new item in destination. This matches Bitrix UX (struck-through old + fresh new).
80
+ - **Title match in `move`** is exact (case-sensitive). If item title was renamed since add,
81
+ use `add` in target group + manually toggle source.
82
+
83
+ ## Errors / UX
84
+
85
+ - Unknown group → exit 1 with valid list
86
+ - Item not found in source for `move` → exit 1, suggest `add` instead
87
+ - No state → exit 1, hint `bootstrap`
88
+
89
+ ## What NOT to do
90
+
91
+ - ❌ Use `move` to undo a completion (instead: `bx_checklist_toggle <main> <itemId> N`)
92
+ - ❌ Add duplicate items to the same group (Bitrix allows it, but UX gets confusing)
93
+ - ❌ Skip the confirmation step (every POST goes through `AskUserQuestion`)
@@ -0,0 +1,269 @@
1
+ # /bx:task summary — Curated KB Result
2
+
3
+ Post a curated knowledge-base summary as a Bitrix Task Result entry (visible in task UI tab "Kết quả" / "Result"). Designed for moments worth pinning: releases, discoveries, bug post-mortems, ADRs, failed experiments.
4
+
5
+ ## When to use
6
+
7
+ - After shipping a release → `summary release`
8
+ - After investigating a bug → `summary bug-postmortem`
9
+ - After making an architecture decision → `summary adr`
10
+ - After learning something non-obvious → `summary discovery`
11
+ - After confirming a hypothesis is wrong → `summary failed-experiment`
12
+
13
+ If the user just wants to leave a chat note, the existing `bitrix-task-sync` hook auto-posts comments. This skill is for **persistent, structured KB entries** only.
14
+
15
+ ## Args
16
+
17
+ ```
18
+ /bx:task summary [type] [--task-id N]
19
+ ```
20
+
21
+ | Arg | Required | Notes |
22
+ |-----|----------|-------|
23
+ | `type` | optional | One of: `release`, `discovery`, `bug-postmortem`, `adr`, `failed-experiment`. Omit → picker. |
24
+ | `--task-id N` | optional | Override CLAUDE.md walk-up. Useful when running outside a Bitrix project or targeting a different task. |
25
+
26
+ ## Algorithm (Claude follows step by step)
27
+
28
+ ```
29
+ 1. Source helpers + pre-flight:
30
+ source ~/.claude/skills/bx-task/lib/bx-resolve-task.sh
31
+ source ~/.claude/skills/bx-task/lib/bx-api.sh
32
+ bx_preflight || abort
33
+
34
+ 2. Parse args:
35
+ - extract --task-id N if present, store in EXPLICIT_TASK_ID
36
+ - first positional = type (may be empty)
37
+
38
+ 3. Resolve TASK_ID:
39
+ TASK_ID=$(bx_resolve_task_id "$EXPLICIT_TASK_ID") || abort
40
+
41
+ 4. If type empty → AskUserQuestion picker (5 type options).
42
+ If type invalid → error: list valid types, exit 1.
43
+
44
+ 5. Look up the field list for the chosen type (table below).
45
+
46
+ 6. Collect each field via AskUserQuestion (one question per field).
47
+ Field labels in the table are the prompt wording.
48
+ Multi-line fields: ask user to write content as one paragraph; preserve newlines as-is.
49
+
50
+ 7. Render BB content by substituting collected values into the template
51
+ for that type (templates below).
52
+
53
+ 8. Show preview + confirm via AskUserQuestion:
54
+ Question: "Post this summary to Bitrix task #$TASK_ID?"
55
+ Preview field: raw BB code (KISS — exact text fidelity)
56
+ Options: [Confirm + Post (Recommended), Edit fields, Cancel]
57
+
58
+ 9. On Confirm → POST:
59
+ PAYLOAD=$(jq -n --argjson tid "$TASK_ID" --arg txt "$BB_CONTENT" \
60
+ '{fields:{taskId:$tid, text:$txt}}')
61
+ RESP=$(bx_call_v3 "tasks.task.result.add" "$PAYLOAD")
62
+ # Extract result.id via grep — DO NOT use jq on the full response.
63
+ # Bitrix v3 returns malformed JSON (literal newlines inside string values),
64
+ # which strict jq rejects. The id field appears early and is safe to grep.
65
+ RESULT_ID=$(echo "$RESP" | grep -oE '"id":[[:space:]]*[0-9]+' | head -1 | grep -oE '[0-9]+')
66
+ if [[ -n "$RESULT_ID" ]]; then
67
+ echo "✅ Posted result #${RESULT_ID} to task #${TASK_ID}"
68
+ else
69
+ echo "❌ POST failed: $RESP" >&2
70
+ exit 1
71
+ fi
72
+
73
+ 10. On Edit → loop back to step 6 (re-prompt fields, keep prior answers visible if AskUserQuestion supports defaults; otherwise re-ask).
74
+ On Cancel → exit 0 cleanly, no POST, no side effects.
75
+ ```
76
+
77
+ **Important:**
78
+ - Use `jq -n --arg txt "$BB_CONTENT"` for the REQUEST payload — NEVER string-concatenate user content into JSON. `jq --arg` handles quotes, newlines, and special chars (including `[/]`) safely.
79
+ - Do NOT use `jq` to parse the RESPONSE. Bitrix v3 returns JSON with literal (unescaped) newlines inside the `text` string value, which strict jq rejects. Use `grep -oE '"id":[[:space:]]*[0-9]+'` to extract the result id robustly.
80
+
81
+ ## Type → Template (BB code)
82
+
83
+ All templates below render in Bitrix UI as bold headings + plain text body. **No markdown**. Use literal `\n` line breaks (real newlines in the rendered string).
84
+
85
+ ### `release` 🚀
86
+
87
+ Fields: `VERSION`, `HIGHLIGHTS` (multi-line), `BREAKING`, `MIGRATION`
88
+
89
+ ```
90
+ 🚀 [b]Release {VERSION}[/b]
91
+
92
+ [b]Highlights:[/b]
93
+ {HIGHLIGHTS}
94
+
95
+ [b]Breaking changes:[/b]
96
+ {BREAKING}
97
+
98
+ [b]Migration:[/b]
99
+ {MIGRATION}
100
+ ```
101
+
102
+ ### `discovery` 💡
103
+
104
+ Fields: `TOPIC`, `INSIGHT`, `APPLICATION`, `SOURCE`
105
+
106
+ ```
107
+ 💡 [b]Discovery: {TOPIC}[/b]
108
+
109
+ [b]Insight:[/b]
110
+ {INSIGHT}
111
+
112
+ [b]Application:[/b]
113
+ {APPLICATION}
114
+
115
+ [b]Source:[/b]
116
+ {SOURCE}
117
+ ```
118
+
119
+ ### `bug-postmortem` 🪲
120
+
121
+ Fields: `SYMPTOM`, `SYMPTOM_DETAIL`, `ROOT_CAUSE`, `FIX`, `PREVENTION`
122
+
123
+ ```
124
+ 🪲 [b]Bug post-mortem: {SYMPTOM}[/b]
125
+
126
+ [b]Triệu chứng:[/b]
127
+ {SYMPTOM_DETAIL}
128
+
129
+ [b]Nguyên nhân:[/b]
130
+ {ROOT_CAUSE}
131
+
132
+ [b]Fix:[/b]
133
+ {FIX}
134
+
135
+ [b]Phòng ngừa:[/b]
136
+ {PREVENTION}
137
+ ```
138
+
139
+ ### `adr` 📐
140
+
141
+ Fields: `DECISION`, `CONTEXT`, `DECISION_DETAIL`, `CONSEQUENCES`, `STATUS`
142
+
143
+ ```
144
+ 📐 [b]ADR: {DECISION}[/b]
145
+
146
+ [b]Context:[/b]
147
+ {CONTEXT}
148
+
149
+ [b]Decision:[/b]
150
+ {DECISION_DETAIL}
151
+
152
+ [b]Consequences:[/b]
153
+ {CONSEQUENCES}
154
+
155
+ [b]Status:[/b] {STATUS}
156
+ ```
157
+
158
+ `STATUS` ∈ {`Proposed`, `Accepted`, `Deprecated`, `Superseded`}.
159
+
160
+ ### `failed-experiment` 🧪
161
+
162
+ Fields: `HYPOTHESIS`, `HYPOTHESIS_DETAIL`, `RESULT`, `LEARNING`
163
+
164
+ ```
165
+ 🧪 [b]Failed experiment: {HYPOTHESIS}[/b]
166
+
167
+ [b]Hypothesis:[/b]
168
+ {HYPOTHESIS_DETAIL}
169
+
170
+ [b]Result:[/b]
171
+ {RESULT}
172
+
173
+ [b]Learning:[/b]
174
+ {LEARNING}
175
+ ```
176
+
177
+ ## Field-list quick reference
178
+
179
+ | Type | Fields (prompt order) |
180
+ |------|-----------------------|
181
+ | `release` | VERSION, HIGHLIGHTS, BREAKING, MIGRATION |
182
+ | `discovery` | TOPIC, INSIGHT, APPLICATION, SOURCE |
183
+ | `bug-postmortem` | SYMPTOM, SYMPTOM_DETAIL, ROOT_CAUSE, FIX, PREVENTION |
184
+ | `adr` | DECISION, CONTEXT, DECISION_DETAIL, CONSEQUENCES, STATUS |
185
+ | `failed-experiment` | HYPOTHESIS, HYPOTHESIS_DETAIL, RESULT, LEARNING |
186
+
187
+ ## API payload shape
188
+
189
+ ```json
190
+ {
191
+ "fields": {
192
+ "taskId": 2776,
193
+ "text": "🚀 [b]Release v0.0.1[/b]\n\n[b]Highlights:[/b]\n• ..."
194
+ }
195
+ }
196
+ ```
197
+
198
+ Endpoint: `tasks.task.result.add` on the v3 path (`/rest/api/<user>/<token>/`). `bx_call_v3` rewrites the URL automatically.
199
+
200
+ Response shape (success):
201
+
202
+ ```json
203
+ {
204
+ "result": {
205
+ "item": {
206
+ "id": 123,
207
+ "taskId": 2776,
208
+ "createdBy": 614,
209
+ "messageId": null,
210
+ "text": "...",
211
+ "status": "open"
212
+ }
213
+ },
214
+ "time": {...}
215
+ }
216
+ ```
217
+
218
+ `messageId` is `null` because we use direct `result.add` (no comment-pin chain).
219
+
220
+ ## Error handling
221
+
222
+ | Failure | Behaviour |
223
+ |---------|-----------|
224
+ | `bx_preflight` fails | Exit 1, print env hint |
225
+ | `bx_resolve_task_id` fails | Exit 1, print "TASK_ID not found" hint |
226
+ | Invalid `type` arg | Exit 1, list 5 valid types |
227
+ | Network/HTTP error from `bx_call_v3` | Print raw response to stderr, exit 1 (NO retry — fail-fast, user re-runs) |
228
+ | User cancels at confirm | Exit 0, no POST, no side effects |
229
+
230
+ ## Live test plan (Phase 2 verification)
231
+
232
+ Run on task #2776 (this repo's SSOT) once with each type, verify in Bitrix UI tab "Kết quả", capture each `result.id`, then cleanup:
233
+
234
+ ```bash
235
+ # After each test posts, capture result.id from output, accumulate in $IDS array.
236
+ # Cleanup script:
237
+ for id in "${IDS[@]}"; do
238
+ bx_call_v3 "tasks.task.result.delete" "$(jq -n --argjson id "$id" '{id:$id}')"
239
+ done
240
+ ```
241
+
242
+ ## Examples
243
+
244
+ ### Skip picker (advanced)
245
+
246
+ ```
247
+ /bx:task summary release
248
+ ```
249
+ → Goes directly to release-type field prompts (VERSION, HIGHLIGHTS, ...).
250
+
251
+ ### Picker mode (default)
252
+
253
+ ```
254
+ /bx:task summary
255
+ ```
256
+ → AskUserQuestion shows 5 type options + Cancel.
257
+
258
+ ### Override task
259
+
260
+ ```
261
+ /bx:task summary adr --task-id 9999
262
+ ```
263
+ → Posts ADR to task #9999 instead of CLAUDE.md walk-up.
264
+
265
+ ## Notes
266
+
267
+ - Webhook user 614 ("Claude") owns each posted result (`createdBy: 614`) → has `rights.edit/remove = true`. Cleanup is allowed.
268
+ - `tasks.task.result.list` filter shape on v3 is unknown (multiple shapes returned "Unknown filter condition" in research). v1 of this skill does NOT support listing; if needed, view results in Bitrix UI directly.
269
+ - Extending to a 6th type: add row to "Type → Template" + "Field-list" tables, add picker option in step 4.
@@ -0,0 +1,104 @@
1
+ # /bx:task sync — Session Digest to Task Comment
2
+
3
+ Post a manual session digest as a comment to the Bitrix task chat. Use when you want to sync progress mid-session or after a coding session without waiting for the Stop hook.
4
+
5
+ ## When to use
6
+
7
+ - After completing a significant chunk of work in a session
8
+ - When Stop hook didn't fire (e.g. session crash, manual exit)
9
+ - When working in a project that hasn't set up bitrix-task-sync hooks yet
10
+ - When you want to sync a specific context note manually
11
+
12
+ ## Args
13
+
14
+ ```
15
+ /bx:task sync [--task-id N]
16
+ ```
17
+
18
+ - `--task-id N` — override TASK_ID resolution
19
+
20
+ ## Pre-flight
21
+
22
+ ```bash
23
+ source ~/.claude/skills/bx-task/lib/bx-resolve-task.sh
24
+ source ~/.claude/skills/bx-task/lib/bx-api.sh
25
+ bx_preflight || exit 1
26
+ TASK_ID=$(bx_resolve_task_id "${EXPLICIT_TASK_ID:-}") || exit 1
27
+ ```
28
+
29
+ ## Algorithm
30
+
31
+ ### Step 1 — Collect context
32
+
33
+ Run these bash commands silently (no output to user yet):
34
+
35
+ ```bash
36
+ # Recent commits (last 5, format: hash subject)
37
+ GIT_LOG=$(git log --oneline -5 2>/dev/null || echo "(no git history)")
38
+
39
+ # Files changed in last commit
40
+ GIT_FILES=$(git diff --name-only HEAD~1 HEAD 2>/dev/null | head -10 || echo "")
41
+
42
+ # Current branch
43
+ GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
44
+
45
+ # CWD project name (last dir component)
46
+ PROJECT=$(basename "$PWD")
47
+ ```
48
+
49
+ ### Step 2 — Ask user for session note (optional)
50
+
51
+ Use `AskUserQuestion`:
52
+ - question: "Thêm ghi chú cho session này? (optional — Enter để bỏ qua)"
53
+ - options: 3-4 common options like "Bỏ qua", "Đã xong feature X", "Đang debug issue Y", "Other..."
54
+
55
+ If user picks "Bỏ qua" or empty → `SESSION_NOTE=""`
56
+
57
+ ### Step 3 — Build BB comment
58
+
59
+ ```
60
+ [b]⚡ Manual sync — {PROJECT}[/b]
61
+
62
+ [b]Branch:[/b] {GIT_BRANCH}
63
+
64
+ [b]Recent commits:[/b]
65
+ {GIT_LOG formatted as bullet list with • prefix}
66
+
67
+ {if GIT_FILES not empty:}
68
+ [b]Files changed:[/b]
69
+ {GIT_FILES formatted as • list}
70
+ {endif}
71
+
72
+ {if SESSION_NOTE not empty:}
73
+ [b]Ghi chú:[/b] {SESSION_NOTE}
74
+ {endif}
75
+
76
+ [i]Synced via /bx:task sync[/i]
77
+ ```
78
+
79
+ Rules:
80
+ - Use `•` for bullet lists (not `-`)
81
+ - No markdown headers, no `**bold**` — BB only
82
+ - Max 2000 chars total; truncate git log lines to 72 chars each
83
+
84
+ ### Step 4 — Confirm + POST
85
+
86
+ Show the BB text in an `AskUserQuestion`:
87
+ - question: "Post comment này lên task #{TASK_ID}?"
88
+ - options: "Yes, post it", "No, cancel"
89
+
90
+ If Yes:
91
+
92
+ ```bash
93
+ bx_call_v1 "task.commentitem.add" \
94
+ "TASK_ID=${TASK_ID}&POST_MESSAGE=$(python3 -c "import urllib.parse,sys; print(urllib.parse.quote(sys.stdin.read()))" <<< "${BB_TEXT}")" \
95
+ || exit 1
96
+ ```
97
+
98
+ On success: print `✓ Comment posted to task #${TASK_ID}`
99
+
100
+ ## Error handling
101
+
102
+ - No git repo → skip git sections, post with note only
103
+ - Empty note + no git → warn "Nothing to sync. Add a --message or run from a git repo."
104
+ - API 5xx → fail-fast, print error, suggest retry