@leejungkiin/awkit 1.0.9 → 1.1.1

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 (114) hide show
  1. package/README.md +3 -3
  2. package/VERSION +1 -1
  3. package/bin/awf.js +1 -1
  4. package/bin/awk.js +287 -34
  5. package/core/AGENTS.md +8 -9
  6. package/core/GEMINI.md +77 -199
  7. package/package.json +2 -1
  8. package/skill-packs/neural-memory/skills/nm-memory-sync/SKILL.md +2 -2
  9. package/skills/CATALOG.md +3 -2
  10. package/skills/README.md +109 -0
  11. package/skills/android-re-analyzer/SKILL.md +238 -0
  12. package/skills/android-re-analyzer/references/api-extraction-patterns.md +119 -0
  13. package/skills/android-re-analyzer/references/call-flow-analysis.md +176 -0
  14. package/skills/android-re-analyzer/references/fernflower-usage.md +115 -0
  15. package/skills/android-re-analyzer/references/jadx-usage.md +116 -0
  16. package/skills/android-re-analyzer/references/setup-guide.md +221 -0
  17. package/skills/android-re-analyzer/scripts/check-deps.sh +129 -0
  18. package/skills/android-re-analyzer/scripts/decompile.sh +375 -0
  19. package/skills/android-re-analyzer/scripts/find-api-calls.sh +118 -0
  20. package/skills/android-re-analyzer/scripts/install-dep.sh +448 -0
  21. package/skills/awf-session-restore/SKILL.md +108 -184
  22. package/skills/beads-manager/SKILL.md +2 -2
  23. package/skills/brainstorm-agent/SKILL.md +47 -2
  24. package/skills/gemini-conductor/SKILL.md +234 -0
  25. package/skills/memory-sync/SKILL.md +29 -1
  26. package/skills/nm-memory-sync/SKILL.md +2 -2
  27. package/skills/orchestrator/SKILL.md +32 -154
  28. package/skills/skills/nm-memory-sync/SKILL.md +2 -2
  29. package/skills/smali-to-kotlin/SKILL.md +1 -1
  30. package/skills/smali-to-swift/SKILL.md +1 -1
  31. package/skills/swiftui-pro/SKILL.md +108 -0
  32. package/skills/swiftui-pro/agents/openai.yaml +10 -0
  33. package/skills/swiftui-pro/assets/swiftui-pro-icon.png +0 -0
  34. package/skills/swiftui-pro/assets/swiftui-pro-icon.svg +29 -0
  35. package/skills/swiftui-pro/references/accessibility.md +13 -0
  36. package/skills/swiftui-pro/references/api.md +39 -0
  37. package/skills/swiftui-pro/references/data.md +43 -0
  38. package/skills/swiftui-pro/references/design.md +31 -0
  39. package/skills/swiftui-pro/references/hygiene.md +9 -0
  40. package/skills/swiftui-pro/references/navigation.md +14 -0
  41. package/skills/swiftui-pro/references/performance.md +46 -0
  42. package/skills/swiftui-pro/references/swift.md +56 -0
  43. package/skills/swiftui-pro/references/views.md +35 -0
  44. package/skills/symphony-enforcer/SKILL.md +227 -0
  45. package/skills/symphony-orchestrator/SKILL.md +301 -0
  46. package/skills/telegram-notify/SKILL.md +57 -0
  47. package/symphony/LICENSE +21 -0
  48. package/symphony/README.md +178 -0
  49. package/symphony/app/api/agents/route.js +152 -0
  50. package/symphony/app/api/events/route.js +22 -0
  51. package/symphony/app/api/knowledge/route.js +253 -0
  52. package/symphony/app/api/locks/route.js +29 -0
  53. package/symphony/app/api/notes/route.js +125 -0
  54. package/symphony/app/api/preflight/route.js +23 -0
  55. package/symphony/app/api/projects/route.js +116 -0
  56. package/symphony/app/api/roles/route.js +134 -0
  57. package/symphony/app/api/skills/route.js +82 -0
  58. package/symphony/app/api/status/route.js +18 -0
  59. package/symphony/app/api/tasks/route.js +157 -0
  60. package/symphony/app/api/workflows/route.js +61 -0
  61. package/symphony/app/api/workspaces/route.js +15 -0
  62. package/symphony/app/globals.css +2605 -0
  63. package/symphony/app/layout.js +20 -0
  64. package/symphony/app/page.js +2122 -0
  65. package/symphony/cli/index.js +1060 -0
  66. package/symphony/core/agent-manager.js +357 -0
  67. package/symphony/core/context-bus.js +100 -0
  68. package/symphony/core/db.js +223 -0
  69. package/symphony/core/file-lock-manager.js +154 -0
  70. package/symphony/core/merge-pipeline.js +234 -0
  71. package/symphony/core/orchestrator.js +236 -0
  72. package/symphony/core/task-manager.js +335 -0
  73. package/symphony/core/workspace-manager.js +168 -0
  74. package/symphony/jsconfig.json +7 -0
  75. package/symphony/lib/core.mjs +1034 -0
  76. package/symphony/mcp/index.js +29 -0
  77. package/symphony/mcp/server.js +110 -0
  78. package/symphony/mcp/tools/context.js +80 -0
  79. package/symphony/mcp/tools/locks.js +99 -0
  80. package/symphony/mcp/tools/status.js +82 -0
  81. package/symphony/mcp/tools/tasks.js +216 -0
  82. package/symphony/mcp/tools/workspace.js +143 -0
  83. package/symphony/next.config.mjs +7 -0
  84. package/symphony/package.json +53 -0
  85. package/symphony/scripts/postinstall.js +49 -0
  86. package/symphony/symphony.config.js +41 -0
  87. package/templates/conductor-tracks.md +38 -0
  88. package/templates/workflow_dual_mode_template.md +5 -5
  89. package/workflows/_uncategorized/AGENTS.md +38 -0
  90. package/workflows/_uncategorized/decompile.md +67 -0
  91. package/workflows/_uncategorized/skill-health.md +7 -7
  92. package/workflows/ads/ads-audit.md +5 -5
  93. package/workflows/ads/ads-optimize.md +10 -10
  94. package/workflows/ads/adsExpert.md +7 -7
  95. package/workflows/conductor.md +97 -0
  96. package/workflows/context/auto-implement.md +4 -4
  97. package/workflows/context/codebase-sync.md +19 -8
  98. package/workflows/context/next.md +27 -27
  99. package/workflows/context/user-intent-analysis-workflow.md +4 -4
  100. package/workflows/expert/codeExpert.md +28 -31
  101. package/workflows/expert/debugExpert.md +11 -11
  102. package/workflows/expert/planExpert.md +21 -36
  103. package/workflows/git/smart-git-ops.md +49 -6
  104. package/workflows/lifecycle/debug.md +7 -7
  105. package/workflows/lifecycle/deploy.md +10 -10
  106. package/workflows/lifecycle/master-code-workflow.md +3 -3
  107. package/workflows/lifecycle/plan.md +19 -21
  108. package/workflows/quality/audit.md +1 -1
  109. package/workflows/quality/project-audit.md +1 -1
  110. package/workflows/roles/vibe-coding-master-workflow.md +2 -2
  111. package/workflows/smart-git-ops.md +146 -0
  112. package/workflows/ui/app-screen-analyzer.md +4 -4
  113. package/workflows/ui/create-feature.md +8 -8
  114. package/workflows/ui/create-spec-architect.md +11 -11
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # AWKit — Antigravity Workflow Kit v1.0
2
2
 
3
- > **v1.0.0** · Single Source of Truth · Beads-First · Ambient Memory
3
+ > **v1.0.0** · Single Source of Truth · Symphony-First · Ambient Memory
4
4
 
5
5
  AWKit là framework điều phối AI agent chuyên nghiệp. Đây là **nơi duy nhất** chứa toàn bộ workflows, skills, GEMINI.md và cấu hình — không còn phân tán giữa nhiều repo.
6
6
 
@@ -77,7 +77,7 @@ main-awf/ (AWKit v7.0 — Source of Truth)
77
77
  │ ├── orchestrator/
78
78
  │ ├── memory-sync/
79
79
  │ ├── brainstorm-agent/
80
- │ ├── beads-manager/
80
+ │ ├── symphony-orchestrator/
81
81
  │ ├── awf-session-restore/
82
82
  │ └── ...
83
83
  ├── skill-packs/ ← Optional add-ons
@@ -127,7 +127,7 @@ awkit enable-pack ios-dev
127
127
  | Version | Name | Notes |
128
128
  |---------|------|-------|
129
129
  | 4.x | AWF v4 | Shell-based, `awf-` prefix skills |
130
- | 5.x | Antigravity v5 | Node.js, Beads integration |
130
+ | 5.x | Antigravity v5 | Node.js, Symphony integration |
131
131
  | 6.x | AWF v6 | main-awf, multiple sources |
132
132
  | **1.0** | **AWKit v1.0** | **Single source of truth, this repo** |
133
133
 
package/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.7
1
+ 1.1.1
package/bin/awf.js CHANGED
@@ -355,7 +355,7 @@ function cmdDoctor() {
355
355
  ok(`${skills.length} skills found`);
356
356
 
357
357
  // Check essential skills
358
- const essentialSkills = ['orchestrator', 'beads-manager', 'session-restore'];
358
+ const essentialSkills = ['orchestrator', 'symphony-orchestrator', 'session-restore'];
359
359
  for (const s of essentialSkills) {
360
360
  if (!skills.includes(s)) {
361
361
  warn(`Essential skill missing: ${s}`); issues++;
package/bin/awk.js CHANGED
@@ -16,6 +16,8 @@
16
16
  * awkit enable-pack Enable a skill pack
17
17
  * awkit disable-pack Disable a skill pack
18
18
  * awkit list-packs List available skill packs
19
+ * awkit tg setup Setup Telegram Bot API credentials
20
+ * awkit tg send Send a message via Telegram Bot API
19
21
  * awkit version Show current version
20
22
  *
21
23
  * Created by Kien AI
@@ -23,6 +25,7 @@
23
25
 
24
26
  const fs = require('fs');
25
27
  const path = require('path');
28
+ const https = require('https');
26
29
  const { execSync, spawnSync } = require('child_process');
27
30
 
28
31
  // ─── Constants ────────────────────────────────────────────────────────────────
@@ -197,18 +200,18 @@ function syncGeminiMd() {
197
200
  // ─── Commands ────────────────────────────────────────────────────────────────
198
201
 
199
202
  /**
200
- * Ensure 'bd' (Beads) is installed. Install via Homebrew if missing.
203
+ * Ensure Symphony is available. Install via Homebrew if missing.
201
204
  * Returns true if bd is available after the call.
202
205
  */
203
- function installBeads({ silent = false } = {}) {
206
+ function installSymphony({ silent = false } = {}) {
204
207
  // Check if bd already installed
205
208
  try {
206
209
  execSync('which bd', { stdio: 'ignore' });
207
- if (!silent) ok('bd (Beads) already installed');
210
+ if (!silent) ok('Symphony already installed');
208
211
  return true;
209
212
  } catch (_) { /* not installed */ }
210
213
 
211
- if (!silent) info('bd (Beads) not found — installing via Homebrew...');
214
+ if (!silent) info('Symphony not found — installing via Homebrew...');
212
215
 
213
216
  // Check if brew is available
214
217
  let brewAvailable = false;
@@ -216,21 +219,21 @@ function installBeads({ silent = false } = {}) {
216
219
 
217
220
  if (!brewAvailable) {
218
221
  warn('Homebrew not found. Please install bd manually:');
219
- dim(' brew install beads');
220
- dim(' or visit: https://github.com/steveyegge/beads');
222
+ dim(' npm install -g @anthropic/symphony');
223
+ dim(' or visit: https://github.com/anthropic/symphony');
221
224
  return false;
222
225
  }
223
226
 
224
227
  try {
225
- if (!silent) info('Running: brew install beads');
226
- execSync('brew install beads', { stdio: silent ? 'pipe' : 'inherit' });
228
+ if (!silent) info('Running: npm install -g @anthropic/symphony');
229
+ execSync('npm install -g @anthropic/symphony', { stdio: silent ? 'pipe' : 'inherit' });
227
230
  // Verify install
228
231
  execSync('which bd', { stdio: 'ignore' });
229
- if (!silent) ok('bd (Beads) installed successfully ✨');
232
+ if (!silent) ok('Symphony installed successfully ✨');
230
233
  return true;
231
234
  } catch (e) {
232
235
  warn(`Failed to install bd via brew: ${e.message}`);
233
- dim('Try manually: brew install beads');
236
+ dim('Try manually: npm install -g @anthropic/symphony');
234
237
  return false;
235
238
  }
236
239
  }
@@ -244,10 +247,10 @@ function cmdInstall() {
244
247
 
245
248
  const target = TARGETS.antigravity;
246
249
 
247
- // 0. Install bd (Beads) if missing
250
+ // 0. Install Symphony if missing
248
251
  log('');
249
252
  info('Checking dependencies...');
250
- installBeads();
253
+ installSymphony();
251
254
 
252
255
  // 1. Ensure target dirs exist
253
256
  info('Creating directories...');
@@ -345,7 +348,7 @@ function cmdInstall() {
345
348
  dim(`Packs: ${defaultPacks.join(', ')} (auto-enabled)`);
346
349
  }
347
350
  const bdVer = (() => { try { return execSync('bd --version', { encoding: 'utf8' }).trim().split('\n')[0]; } catch (_) { return 'installed'; } })();
348
- dim(`Beads: ${bdVer} — task tracking ready`);
351
+ dim(`Symphony: task tracking ready`);
349
352
  log('');
350
353
  log(`${C.cyan}👉 Type '/plan' in your AI chat to get started.${C.reset}`);
351
354
  log(`${C.cyan}👉 Run 'awkit init' in any project to initialize it.${C.reset}`);
@@ -413,21 +416,63 @@ function cmdUninstall() {
413
416
  }
414
417
 
415
418
  function cmdUpdate() {
416
- info(`Updating to AWK v${AWK_VERSION}...`);
419
+ info('Checking for updates on npm registry...');
417
420
 
418
- // Check current version
419
- let currentVersion = '0.0.0';
421
+ // 1. Fetch latest version from npm
422
+ let npmLatest = null;
423
+ try {
424
+ npmLatest = execSync(
425
+ 'npm view @leejungkiin/awkit version',
426
+ { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 5000 }
427
+ ).trim();
428
+ } catch (_) {
429
+ warn('Could not reach npm registry (offline?). Falling back to local check.');
430
+ }
431
+
432
+ // 2. Read currently installed version
433
+ let installedVersion = '0.0.0';
420
434
  if (fs.existsSync(TARGETS.versionFile)) {
421
- currentVersion = fs.readFileSync(TARGETS.versionFile, 'utf8').trim();
435
+ installedVersion = fs.readFileSync(TARGETS.versionFile, 'utf8').trim();
422
436
  }
423
437
 
424
- if (currentVersion === AWK_VERSION) {
425
- ok(`Already on latest version (${AWK_VERSION})`);
438
+ const targetVersion = npmLatest || AWK_VERSION;
439
+
440
+ log('');
441
+ log(`${C.gray} npm latest: v${npmLatest || '(unknown)'}${C.reset}`);
442
+ log(`${C.gray} installed: v${installedVersion}${C.reset}`);
443
+ log(`${C.gray} local repo: v${AWK_VERSION}${C.reset}`);
444
+ log('');
445
+
446
+ // 3. Already up-to-date?
447
+ if (npmLatest && npmLatest === installedVersion) {
448
+ ok(`Already on the latest version (v${installedVersion}) 🎉`);
426
449
  return;
427
450
  }
428
451
 
429
- info(`Upgrading from ${currentVersion}${AWK_VERSION}`);
430
- cmdInstall();
452
+ // 4. New version available on npm install from registry
453
+ if (npmLatest && npmLatest !== installedVersion) {
454
+ info(`Upgrading: v${installedVersion} → v${npmLatest}`);
455
+ info('Running: npm install -g @leejungkiin/awkit');
456
+ try {
457
+ execSync('npm install -g @leejungkiin/awkit', { stdio: 'inherit' });
458
+ } catch (e) {
459
+ err(`npm install failed: ${e.message}`);
460
+ dim('Try manually: npm install -g @leejungkiin/awkit');
461
+ return;
462
+ }
463
+ log('');
464
+ info('Applying new workflows, skills & schemas...');
465
+ cmdInstall();
466
+ return;
467
+ }
468
+
469
+ // 5. Offline fallback: compare AWK_VERSION (local repo) vs installed
470
+ if (installedVersion === AWK_VERSION) {
471
+ ok(`Already on latest version (v${AWK_VERSION}) — could not verify with npm`);
472
+ } else {
473
+ info(`Upgrading from v${installedVersion} → v${AWK_VERSION} (local only, npm unreachable)`);
474
+ cmdInstall();
475
+ }
431
476
  }
432
477
 
433
478
  function cmdDoctor() {
@@ -470,7 +515,7 @@ function cmdDoctor() {
470
515
  ok(`${skills.length} skills found`);
471
516
 
472
517
  // Check essential skills
473
- const essentialSkills = ['orchestrator', 'beads-manager', 'awf-session-restore'];
518
+ const essentialSkills = ['orchestrator', 'symphony-orchestrator', 'awf-session-restore'];
474
519
  for (const s of essentialSkills) {
475
520
  if (!skills.includes(s)) {
476
521
  warn(`Essential skill missing: ${s}`); issues++;
@@ -1198,7 +1243,7 @@ function cmdHelp() {
1198
1243
  log(` ${C.green}init${C.reset} Init mobile project (Firebase) in CWD`);
1199
1244
  log(` ${C.gray} --force${C.reset} Overwrite existing files`);
1200
1245
  log(` ${C.gray} Generates: .project-identity, <Name>.code-workspace,${C.reset}`);
1201
- log(` ${C.gray} CODEBASE.md, .beads/ (Beads task DB)${C.reset}`);
1246
+ log(` ${C.gray} CODEBASE.md, .symphony/ (Symphony task DB)${C.reset}`);
1202
1247
  log('');
1203
1248
 
1204
1249
  // Sync
@@ -1217,6 +1262,16 @@ function cmdHelp() {
1217
1262
  log(` ${C.green}disable-pack${C.reset} <name> Uninstall a skill pack (backed up)`);
1218
1263
  log('');
1219
1264
 
1265
+ // Telegram
1266
+ log(`${C.bold}📨 Telegram${C.reset}`);
1267
+ log(line);
1268
+ log(` ${C.green}tg setup${C.reset} Setup Bot Token, Chat ID & Topic`);
1269
+ log(` ${C.green}tg send${C.reset} <message> Send message to default group/topic`);
1270
+ log(` ${C.gray} --chat <id>${C.reset} Send to specific chat`);
1271
+ log(` ${C.gray} --topic <id>${C.reset} Send to specific forum topic`);
1272
+ log(` ${C.gray} --parse-mode <md|html>${C.reset} Formatting mode`);
1273
+ log('');
1274
+
1220
1275
  // Available packs
1221
1276
  const packsDir = path.join(AWK_ROOT, 'skill-packs');
1222
1277
  if (fs.existsSync(packsDir)) {
@@ -1553,7 +1608,7 @@ function buildCodebaseMd(projectName, projectType, identity) {
1553
1608
  * .project-identity
1554
1609
  * <ProjectName>.code-workspace
1555
1610
  * CODEBASE.md
1556
- * .beads/ (via bd init)
1611
+ * .symphony/ (via Symphony)
1557
1612
  */
1558
1613
  function cmdInit(forceFlag = false) {
1559
1614
  const cwd = process.cwd();
@@ -1620,25 +1675,25 @@ function cmdInit(forceFlag = false) {
1620
1675
  ok('CODEBASE.md created');
1621
1676
  }
1622
1677
 
1623
- // ── 5. Beads init ─────────────────────────────────────────────────────────
1624
- const beadsDir = path.join(cwd, '.beads');
1625
- if (fs.existsSync(beadsDir) && !forceFlag) {
1626
- warn('.beads/ already exists — skipping bd init');
1678
+ // ── 5. Symphony init ─────────────────────────────────────────────────────────
1679
+ const symphonyDir = path.join(cwd, '.symphony');
1680
+ if (fs.existsSync(symphonyDir) && !forceFlag) {
1681
+ warn('.symphony/ already exists — skipping');
1627
1682
  } else {
1628
- info('Initializing Beads task database...');
1683
+ info('Initializing Symphony task database...');
1629
1684
  // Ensure bd is installed (auto-install silently if missing)
1630
- const bdReady = installBeads({ silent: true });
1685
+ const bdReady = installSymphony({ silent: true });
1631
1686
  if (!bdReady) {
1632
1687
  warn('bd not available — skipping bd init');
1633
- dim('Install manually: brew install beads');
1688
+ dim('Install manually: npm install -g @anthropic/symphony');
1634
1689
  } else {
1635
1690
  try {
1636
1691
  execSync('bd init', { cwd, stdio: 'pipe' });
1637
- ok('Beads database initialized (.beads/)');
1692
+ ok('Symphony initialized (.symphony/)');
1638
1693
  } catch (e) {
1639
1694
  const msg = (e.stderr || e.stdout || e.message || '').toString().trim();
1640
1695
  if (msg.includes('already')) {
1641
- warn('Beads already initialized — skipping');
1696
+ warn('Symphony already initialized — skipping');
1642
1697
  } else {
1643
1698
  warn(`bd init failed: ${msg || e.message}`);
1644
1699
  dim('Try manually: cd <project> && bd init');
@@ -1655,7 +1710,7 @@ function cmdInit(forceFlag = false) {
1655
1710
  dim(`Type: ${projectType}`);
1656
1711
  dim(`Firebase: analytics, crashlytics, remote-config, auth`);
1657
1712
  dim(`Files: .project-identity, ${workspaceName}, CODEBASE.md`);
1658
- dim(`Beads: .beads/ (task tracking ready)`);
1713
+ dim(`Symphony: task tracking ready)`);
1659
1714
  log('');
1660
1715
  log(`${C.cyan}👉 Open ${workspaceName} in VS Code to get started.${C.reset}`);
1661
1716
  log(`${C.cyan}👉 Run '/codebase-sync' in AI chat to keep CODEBASE.md updated.${C.reset}`);
@@ -1663,6 +1718,200 @@ function cmdInit(forceFlag = false) {
1663
1718
  log('');
1664
1719
  }
1665
1720
 
1721
+ // ─── Telegram Bot API ─────────────────────────────────────────────────────────
1722
+
1723
+ const TG_CONFIG_PATH = path.join(TARGETS.antigravity, '.tg_config.json');
1724
+
1725
+ function tgLoadConfig() {
1726
+ if (!fs.existsSync(TG_CONFIG_PATH)) return null;
1727
+ try {
1728
+ return JSON.parse(fs.readFileSync(TG_CONFIG_PATH, 'utf8'));
1729
+ } catch (_) {
1730
+ return null;
1731
+ }
1732
+ }
1733
+
1734
+ function tgSaveConfig(config) {
1735
+ const dir = path.dirname(TG_CONFIG_PATH);
1736
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
1737
+ fs.writeFileSync(TG_CONFIG_PATH, JSON.stringify(config, null, 2) + '\n');
1738
+ }
1739
+
1740
+ /**
1741
+ * Send message via Telegram Bot API using built-in https module.
1742
+ * Returns a Promise that resolves with the API response.
1743
+ */
1744
+ function tgApiSendMessage(botToken, chatId, text, parseMode, topicId) {
1745
+ return new Promise((resolve, reject) => {
1746
+ const payload = JSON.stringify({
1747
+ chat_id: chatId,
1748
+ text: text,
1749
+ ...(parseMode ? { parse_mode: parseMode === 'md' ? 'Markdown' : 'HTML' } : {}),
1750
+ ...(topicId ? { message_thread_id: parseInt(topicId, 10) } : {}),
1751
+ });
1752
+
1753
+ const options = {
1754
+ hostname: 'api.telegram.org',
1755
+ path: `/bot${botToken}/sendMessage`,
1756
+ method: 'POST',
1757
+ headers: {
1758
+ 'Content-Type': 'application/json',
1759
+ 'Content-Length': Buffer.byteLength(payload),
1760
+ },
1761
+ };
1762
+
1763
+ const req = https.request(options, (res) => {
1764
+ let data = '';
1765
+ res.on('data', (chunk) => (data += chunk));
1766
+ res.on('end', () => {
1767
+ try {
1768
+ const json = JSON.parse(data);
1769
+ if (json.ok) resolve(json);
1770
+ else reject(new Error(json.description || 'Telegram API error'));
1771
+ } catch (e) {
1772
+ reject(new Error(`Invalid response: ${data}`));
1773
+ }
1774
+ });
1775
+ });
1776
+
1777
+ req.on('error', reject);
1778
+ req.write(payload);
1779
+ req.end();
1780
+ });
1781
+ }
1782
+
1783
+ function tgSetup() {
1784
+ log('');
1785
+ log(`${C.cyan}${C.bold}📨 Telegram Bot API Setup${C.reset}`);
1786
+ log('');
1787
+ log(`${C.gray} 1. Open Telegram → search @BotFather → /newbot${C.reset}`);
1788
+ log(`${C.gray} 2. Copy the Bot Token${C.reset}`);
1789
+ log(`${C.gray} 3. Add the bot to your target group${C.reset}`);
1790
+ log(`${C.gray} 4. Get group Chat ID (send a message, then check:${C.reset}`);
1791
+ log(`${C.gray} https://api.telegram.org/bot<TOKEN>/getUpdates)${C.reset}`);
1792
+ log('');
1793
+
1794
+ // Prompt for Bot Token
1795
+ let botToken = '';
1796
+ try {
1797
+ botToken = execSync(
1798
+ `bash -c 'read -p "Bot Token: " token; echo $token'`,
1799
+ { stdio: ['inherit', 'pipe', 'inherit'] }
1800
+ ).toString().trim();
1801
+ } catch (_) { err('Failed to read input.'); return; }
1802
+
1803
+ if (!botToken) { err('Bot Token is required.'); return; }
1804
+
1805
+ // Prompt for Chat ID
1806
+ let chatId = '';
1807
+ try {
1808
+ chatId = execSync(
1809
+ `bash -c 'read -p "Default Chat ID (e.g. -100xxx): " cid; echo $cid'`,
1810
+ { stdio: ['inherit', 'pipe', 'inherit'] }
1811
+ ).toString().trim();
1812
+ } catch (_) { err('Failed to read input.'); return; }
1813
+
1814
+ if (!chatId) { err('Chat ID is required.'); return; }
1815
+
1816
+ // Prompt for Topic ID (optional)
1817
+ let topicId = '';
1818
+ try {
1819
+ topicId = execSync(
1820
+ `bash -c 'read -p "Default Topic ID (optional, press Enter to skip): " tid; echo $tid'`,
1821
+ { stdio: ['inherit', 'pipe', 'inherit'] }
1822
+ ).toString().trim();
1823
+ } catch (_) { /* optional, ignore */ }
1824
+
1825
+ // Save config
1826
+ const config = { bot_token: botToken, default_chat_id: chatId };
1827
+ if (topicId) config.default_topic_id = topicId;
1828
+ tgSaveConfig(config);
1829
+ ok(`Config saved to ${TG_CONFIG_PATH}`);
1830
+
1831
+ // Test connection
1832
+ info('Sending test message...');
1833
+ tgApiSendMessage(botToken, chatId, '✅ AWKit Telegram integration connected!', null, topicId || null)
1834
+ .then(() => {
1835
+ ok('Test message sent successfully! 🎉');
1836
+ log('');
1837
+ log(`${C.cyan}Usage: awkit tg send "Your message here"${C.reset}`);
1838
+ log('');
1839
+ })
1840
+ .catch((e) => {
1841
+ err(`Test failed: ${e.message}`);
1842
+ warn('Check your Bot Token and Chat ID, then run "awkit tg setup" again.');
1843
+ });
1844
+ }
1845
+
1846
+ function tgSend(args) {
1847
+ const config = tgLoadConfig();
1848
+ if (!config) {
1849
+ err('Telegram not configured. Run "awkit tg setup" first.');
1850
+ return;
1851
+ }
1852
+
1853
+ // Parse args: --chat <id>, --parse-mode <md|html>, rest is message
1854
+ let chatId = config.default_chat_id;
1855
+ let topicId = config.default_topic_id || null;
1856
+ let parseMode = null;
1857
+ const messageParts = [];
1858
+
1859
+ for (let i = 0; i < args.length; i++) {
1860
+ if (args[i] === '--chat' && args[i + 1]) {
1861
+ chatId = args[++i];
1862
+ } else if (args[i] === '--topic' && args[i + 1]) {
1863
+ topicId = args[++i];
1864
+ } else if (args[i] === '--parse-mode' && args[i + 1]) {
1865
+ parseMode = args[++i];
1866
+ } else {
1867
+ messageParts.push(args[i]);
1868
+ }
1869
+ }
1870
+
1871
+ const message = messageParts.join(' ');
1872
+ if (!message) {
1873
+ err('No message provided.');
1874
+ dim('Usage: awkit tg send "Your message"');
1875
+ return;
1876
+ }
1877
+
1878
+ tgApiSendMessage(config.bot_token, chatId, message, parseMode, topicId)
1879
+ .then(() => {
1880
+ ok(`Message sent to ${chatId}`);
1881
+ })
1882
+ .catch((e) => {
1883
+ err(`Failed to send: ${e.message}`);
1884
+ });
1885
+ }
1886
+
1887
+ function tgHelp() {
1888
+ log('');
1889
+ log(`${C.cyan}${C.bold}📨 Telegram Commands${C.reset}`);
1890
+ log('');
1891
+ log(` ${C.green}awkit tg setup${C.reset} Setup Bot Token, Chat ID & Topic`);
1892
+ log(` ${C.green}awkit tg send${C.reset} <message> Send to default group/topic`);
1893
+ log(` ${C.green}awkit tg send --chat <id>${C.reset} <msg> Send to specific chat`);
1894
+ log(` ${C.green}awkit tg send --topic <id>${C.reset} <msg> Send to specific forum topic`);
1895
+ log(` ${C.green}awkit tg send --parse-mode md${C.reset} Markdown formatting`);
1896
+ log(` ${C.green}awkit tg send --parse-mode html${C.reset} HTML formatting`);
1897
+ log('');
1898
+ }
1899
+
1900
+ function cmdTelegram(args) {
1901
+ const subCmd = args[0];
1902
+ switch (subCmd) {
1903
+ case 'send':
1904
+ tgSend(args.slice(1));
1905
+ break;
1906
+ case 'setup':
1907
+ tgSetup();
1908
+ break;
1909
+ default:
1910
+ tgHelp();
1911
+ break;
1912
+ }
1913
+ }
1914
+
1666
1915
  // ─── Auto-Update Checker ──────────────────────────────────────────────────────
1667
1916
 
1668
1917
  function checkAutoUpdate() {
@@ -1750,6 +1999,10 @@ switch (command) {
1750
1999
  case 'lint':
1751
2000
  cmdLint();
1752
2001
  break;
2002
+ case 'tg':
2003
+ case 'telegram':
2004
+ cmdTelegram(args);
2005
+ break;
1753
2006
  case 'help':
1754
2007
  case '--help':
1755
2008
  case '-h':
package/core/AGENTS.md CHANGED
@@ -1,15 +1,15 @@
1
1
  # Agent Instructions
2
2
 
3
- This project uses **bd** (beads) for issue tracking. Run `bd onboard` to get started.
3
+ This project uses **Symphony** for task management and issue tracking.
4
4
 
5
5
  ## Quick Reference
6
6
 
7
7
  ```bash
8
- bd ready # Find available work
9
- bd show <id> # View issue details
10
- bd update <id> --status in_progress # Claim work
11
- bd close <id> # Complete work
12
- bd sync # Sync with git
8
+ symphony_available_tasks # Find available work
9
+ symphony_claim_task <id> # Claim a task
10
+ symphony_report_progress <id> # Report progress
11
+ symphony_complete_task <id> # Complete work
12
+ symphony_status # Check system status
13
13
  ```
14
14
 
15
15
  ## Landing the Plane (Session Completion)
@@ -18,13 +18,12 @@ bd sync # Sync with git
18
18
 
19
19
  **MANDATORY WORKFLOW:**
20
20
 
21
- 1. **File issues for remaining work** — Create issues for anything that needs follow-up
21
+ 1. **File issues for remaining work** — Create tasks for anything that needs follow-up
22
22
  2. **Run quality gates** (if code changed) — Tests, linters, builds
23
- 3. **Update issue status** — Close finished work, update in-progress items
23
+ 3. **Update task status** — Complete finished work, update in-progress items
24
24
  4. **PUSH TO REMOTE** — This is MANDATORY:
25
25
  ```bash
26
26
  git pull --rebase
27
- bd sync
28
27
  git push
29
28
  git status # MUST show "up to date with origin"
30
29
  ```