adaria-ai 0.1.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 (337) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +21 -0
  3. package/apps.example.yaml +65 -0
  4. package/dist/agent/audit.d.ts +16 -0
  5. package/dist/agent/audit.d.ts.map +1 -0
  6. package/dist/agent/audit.js +42 -0
  7. package/dist/agent/audit.js.map +1 -0
  8. package/dist/agent/claude.d.ts +62 -0
  9. package/dist/agent/claude.d.ts.map +1 -0
  10. package/dist/agent/claude.js +297 -0
  11. package/dist/agent/claude.js.map +1 -0
  12. package/dist/agent/conversation-summary.d.ts +29 -0
  13. package/dist/agent/conversation-summary.d.ts.map +1 -0
  14. package/dist/agent/conversation-summary.js +221 -0
  15. package/dist/agent/conversation-summary.js.map +1 -0
  16. package/dist/agent/core.d.ts +81 -0
  17. package/dist/agent/core.d.ts.map +1 -0
  18. package/dist/agent/core.js +527 -0
  19. package/dist/agent/core.js.map +1 -0
  20. package/dist/agent/mcp-launcher.d.ts +42 -0
  21. package/dist/agent/mcp-launcher.d.ts.map +1 -0
  22. package/dist/agent/mcp-launcher.js +38 -0
  23. package/dist/agent/mcp-launcher.js.map +1 -0
  24. package/dist/agent/mcp-manager.d.ts +81 -0
  25. package/dist/agent/mcp-manager.d.ts.map +1 -0
  26. package/dist/agent/mcp-manager.js +136 -0
  27. package/dist/agent/mcp-manager.js.map +1 -0
  28. package/dist/agent/memory.d.ts +10 -0
  29. package/dist/agent/memory.d.ts.map +1 -0
  30. package/dist/agent/memory.js +95 -0
  31. package/dist/agent/memory.js.map +1 -0
  32. package/dist/agent/safety.d.ts +45 -0
  33. package/dist/agent/safety.d.ts.map +1 -0
  34. package/dist/agent/safety.js +71 -0
  35. package/dist/agent/safety.js.map +1 -0
  36. package/dist/agent/session.d.ts +27 -0
  37. package/dist/agent/session.d.ts.map +1 -0
  38. package/dist/agent/session.js +124 -0
  39. package/dist/agent/session.js.map +1 -0
  40. package/dist/agent/tool-descriptions.d.ts +8 -0
  41. package/dist/agent/tool-descriptions.d.ts.map +1 -0
  42. package/dist/agent/tool-descriptions.js +26 -0
  43. package/dist/agent/tool-descriptions.js.map +1 -0
  44. package/dist/cli/analyze.d.ts +8 -0
  45. package/dist/cli/analyze.d.ts.map +1 -0
  46. package/dist/cli/analyze.js +114 -0
  47. package/dist/cli/analyze.js.map +1 -0
  48. package/dist/cli/daemon.d.ts +2 -0
  49. package/dist/cli/daemon.d.ts.map +1 -0
  50. package/dist/cli/daemon.js +91 -0
  51. package/dist/cli/daemon.js.map +1 -0
  52. package/dist/cli/doctor.d.ts +2 -0
  53. package/dist/cli/doctor.d.ts.map +1 -0
  54. package/dist/cli/doctor.js +198 -0
  55. package/dist/cli/doctor.js.map +1 -0
  56. package/dist/cli/init.d.ts +3 -0
  57. package/dist/cli/init.d.ts.map +1 -0
  58. package/dist/cli/init.js +459 -0
  59. package/dist/cli/init.js.map +1 -0
  60. package/dist/cli/logs.d.ts +4 -0
  61. package/dist/cli/logs.d.ts.map +1 -0
  62. package/dist/cli/logs.js +50 -0
  63. package/dist/cli/logs.js.map +1 -0
  64. package/dist/cli/monitor-cmd.d.ts +11 -0
  65. package/dist/cli/monitor-cmd.d.ts.map +1 -0
  66. package/dist/cli/monitor-cmd.js +59 -0
  67. package/dist/cli/monitor-cmd.js.map +1 -0
  68. package/dist/cli/start.d.ts +11 -0
  69. package/dist/cli/start.d.ts.map +1 -0
  70. package/dist/cli/start.js +103 -0
  71. package/dist/cli/start.js.map +1 -0
  72. package/dist/cli/status.d.ts +9 -0
  73. package/dist/cli/status.d.ts.map +1 -0
  74. package/dist/cli/status.js +49 -0
  75. package/dist/cli/status.js.map +1 -0
  76. package/dist/cli/stop.d.ts +2 -0
  77. package/dist/cli/stop.d.ts.map +1 -0
  78. package/dist/cli/stop.js +34 -0
  79. package/dist/cli/stop.js.map +1 -0
  80. package/dist/collectors/appstore.d.ts +51 -0
  81. package/dist/collectors/appstore.d.ts.map +1 -0
  82. package/dist/collectors/appstore.js +166 -0
  83. package/dist/collectors/appstore.js.map +1 -0
  84. package/dist/collectors/arden-tts.d.ts +60 -0
  85. package/dist/collectors/arden-tts.d.ts.map +1 -0
  86. package/dist/collectors/arden-tts.js +83 -0
  87. package/dist/collectors/arden-tts.js.map +1 -0
  88. package/dist/collectors/asomobile.d.ts +37 -0
  89. package/dist/collectors/asomobile.d.ts.map +1 -0
  90. package/dist/collectors/asomobile.js +88 -0
  91. package/dist/collectors/asomobile.js.map +1 -0
  92. package/dist/collectors/eodin-blog.d.ts +90 -0
  93. package/dist/collectors/eodin-blog.d.ts.map +1 -0
  94. package/dist/collectors/eodin-blog.js +238 -0
  95. package/dist/collectors/eodin-blog.js.map +1 -0
  96. package/dist/collectors/eodin-sdk.d.ts +60 -0
  97. package/dist/collectors/eodin-sdk.d.ts.map +1 -0
  98. package/dist/collectors/eodin-sdk.js +112 -0
  99. package/dist/collectors/eodin-sdk.js.map +1 -0
  100. package/dist/collectors/fridgify-recipes.d.ts +65 -0
  101. package/dist/collectors/fridgify-recipes.d.ts.map +1 -0
  102. package/dist/collectors/fridgify-recipes.js +111 -0
  103. package/dist/collectors/fridgify-recipes.js.map +1 -0
  104. package/dist/collectors/playstore.d.ts +46 -0
  105. package/dist/collectors/playstore.d.ts.map +1 -0
  106. package/dist/collectors/playstore.js +140 -0
  107. package/dist/collectors/playstore.js.map +1 -0
  108. package/dist/collectors/youtube.d.ts +44 -0
  109. package/dist/collectors/youtube.d.ts.map +1 -0
  110. package/dist/collectors/youtube.js +107 -0
  111. package/dist/collectors/youtube.js.map +1 -0
  112. package/dist/config/apps-schema.d.ts +94 -0
  113. package/dist/config/apps-schema.d.ts.map +1 -0
  114. package/dist/config/apps-schema.js +66 -0
  115. package/dist/config/apps-schema.js.map +1 -0
  116. package/dist/config/keychain.d.ts +14 -0
  117. package/dist/config/keychain.d.ts.map +1 -0
  118. package/dist/config/keychain.js +89 -0
  119. package/dist/config/keychain.js.map +1 -0
  120. package/dist/config/load-apps.d.ts +16 -0
  121. package/dist/config/load-apps.d.ts.map +1 -0
  122. package/dist/config/load-apps.js +38 -0
  123. package/dist/config/load-apps.js.map +1 -0
  124. package/dist/config/schema.d.ts +306 -0
  125. package/dist/config/schema.d.ts.map +1 -0
  126. package/dist/config/schema.js +220 -0
  127. package/dist/config/schema.js.map +1 -0
  128. package/dist/config/store.d.ts +38 -0
  129. package/dist/config/store.d.ts.map +1 -0
  130. package/dist/config/store.js +180 -0
  131. package/dist/config/store.js.map +1 -0
  132. package/dist/db/queries.d.ts +304 -0
  133. package/dist/db/queries.d.ts.map +1 -0
  134. package/dist/db/queries.js +327 -0
  135. package/dist/db/queries.js.map +1 -0
  136. package/dist/db/schema.d.ts +15 -0
  137. package/dist/db/schema.d.ts.map +1 -0
  138. package/dist/db/schema.js +252 -0
  139. package/dist/db/schema.js.map +1 -0
  140. package/dist/index.d.ts +3 -0
  141. package/dist/index.d.ts.map +1 -0
  142. package/dist/index.js +86 -0
  143. package/dist/index.js.map +1 -0
  144. package/dist/messenger/adapter.d.ts +63 -0
  145. package/dist/messenger/adapter.d.ts.map +1 -0
  146. package/dist/messenger/adapter.js +7 -0
  147. package/dist/messenger/adapter.js.map +1 -0
  148. package/dist/messenger/factory.d.ts +12 -0
  149. package/dist/messenger/factory.d.ts.map +1 -0
  150. package/dist/messenger/factory.js +9 -0
  151. package/dist/messenger/factory.js.map +1 -0
  152. package/dist/messenger/slack.d.ts +30 -0
  153. package/dist/messenger/slack.d.ts.map +1 -0
  154. package/dist/messenger/slack.js +309 -0
  155. package/dist/messenger/slack.js.map +1 -0
  156. package/dist/messenger/split.d.ts +17 -0
  157. package/dist/messenger/split.d.ts.map +1 -0
  158. package/dist/messenger/split.js +56 -0
  159. package/dist/messenger/split.js.map +1 -0
  160. package/dist/orchestrator/dashboard.d.ts +67 -0
  161. package/dist/orchestrator/dashboard.d.ts.map +1 -0
  162. package/dist/orchestrator/dashboard.js +113 -0
  163. package/dist/orchestrator/dashboard.js.map +1 -0
  164. package/dist/orchestrator/monitor.d.ts +37 -0
  165. package/dist/orchestrator/monitor.d.ts.map +1 -0
  166. package/dist/orchestrator/monitor.js +236 -0
  167. package/dist/orchestrator/monitor.js.map +1 -0
  168. package/dist/orchestrator/types.d.ts +82 -0
  169. package/dist/orchestrator/types.d.ts.map +1 -0
  170. package/dist/orchestrator/types.js +12 -0
  171. package/dist/orchestrator/types.js.map +1 -0
  172. package/dist/orchestrator/weekly.d.ts +66 -0
  173. package/dist/orchestrator/weekly.d.ts.map +1 -0
  174. package/dist/orchestrator/weekly.js +376 -0
  175. package/dist/orchestrator/weekly.js.map +1 -0
  176. package/dist/prompts/loader.d.ts +18 -0
  177. package/dist/prompts/loader.d.ts.map +1 -0
  178. package/dist/prompts/loader.js +28 -0
  179. package/dist/prompts/loader.js.map +1 -0
  180. package/dist/security/auth.d.ts +14 -0
  181. package/dist/security/auth.d.ts.map +1 -0
  182. package/dist/security/auth.js +14 -0
  183. package/dist/security/auth.js.map +1 -0
  184. package/dist/security/prompt-guard.d.ts +21 -0
  185. package/dist/security/prompt-guard.d.ts.map +1 -0
  186. package/dist/security/prompt-guard.js +54 -0
  187. package/dist/security/prompt-guard.js.map +1 -0
  188. package/dist/skills/aso.d.ts +60 -0
  189. package/dist/skills/aso.d.ts.map +1 -0
  190. package/dist/skills/aso.js +322 -0
  191. package/dist/skills/aso.js.map +1 -0
  192. package/dist/skills/content.d.ts +25 -0
  193. package/dist/skills/content.d.ts.map +1 -0
  194. package/dist/skills/content.js +90 -0
  195. package/dist/skills/content.js.map +1 -0
  196. package/dist/skills/index.d.ts +65 -0
  197. package/dist/skills/index.d.ts.map +1 -0
  198. package/dist/skills/index.js +90 -0
  199. package/dist/skills/index.js.map +1 -0
  200. package/dist/skills/onboarding.d.ts +58 -0
  201. package/dist/skills/onboarding.d.ts.map +1 -0
  202. package/dist/skills/onboarding.js +274 -0
  203. package/dist/skills/onboarding.js.map +1 -0
  204. package/dist/skills/registry.d.ts +24 -0
  205. package/dist/skills/registry.d.ts.map +1 -0
  206. package/dist/skills/registry.js +66 -0
  207. package/dist/skills/registry.js.map +1 -0
  208. package/dist/skills/review.d.ts +33 -0
  209. package/dist/skills/review.d.ts.map +1 -0
  210. package/dist/skills/review.js +236 -0
  211. package/dist/skills/review.js.map +1 -0
  212. package/dist/skills/sdk-request.d.ts +30 -0
  213. package/dist/skills/sdk-request.d.ts.map +1 -0
  214. package/dist/skills/sdk-request.js +72 -0
  215. package/dist/skills/sdk-request.js.map +1 -0
  216. package/dist/skills/seo-blog.d.ts +64 -0
  217. package/dist/skills/seo-blog.d.ts.map +1 -0
  218. package/dist/skills/seo-blog.js +268 -0
  219. package/dist/skills/seo-blog.js.map +1 -0
  220. package/dist/skills/short-form.d.ts +28 -0
  221. package/dist/skills/short-form.d.ts.map +1 -0
  222. package/dist/skills/short-form.js +121 -0
  223. package/dist/skills/short-form.js.map +1 -0
  224. package/dist/skills/social-publish.d.ts +32 -0
  225. package/dist/skills/social-publish.d.ts.map +1 -0
  226. package/dist/skills/social-publish.js +133 -0
  227. package/dist/skills/social-publish.js.map +1 -0
  228. package/dist/social/base.d.ts +47 -0
  229. package/dist/social/base.d.ts.map +1 -0
  230. package/dist/social/base.js +26 -0
  231. package/dist/social/base.js.map +1 -0
  232. package/dist/social/facebook.d.ts +27 -0
  233. package/dist/social/facebook.d.ts.map +1 -0
  234. package/dist/social/facebook.js +166 -0
  235. package/dist/social/facebook.js.map +1 -0
  236. package/dist/social/factory.d.ts +26 -0
  237. package/dist/social/factory.d.ts.map +1 -0
  238. package/dist/social/factory.js +32 -0
  239. package/dist/social/factory.js.map +1 -0
  240. package/dist/social/linkedin.d.ts +26 -0
  241. package/dist/social/linkedin.d.ts.map +1 -0
  242. package/dist/social/linkedin.js +190 -0
  243. package/dist/social/linkedin.js.map +1 -0
  244. package/dist/social/threads.d.ts +21 -0
  245. package/dist/social/threads.d.ts.map +1 -0
  246. package/dist/social/threads.js +122 -0
  247. package/dist/social/threads.js.map +1 -0
  248. package/dist/social/tiktok.d.ts +23 -0
  249. package/dist/social/tiktok.d.ts.map +1 -0
  250. package/dist/social/tiktok.js +110 -0
  251. package/dist/social/tiktok.js.map +1 -0
  252. package/dist/social/twitter.d.ts +30 -0
  253. package/dist/social/twitter.d.ts.map +1 -0
  254. package/dist/social/twitter.js +189 -0
  255. package/dist/social/twitter.js.map +1 -0
  256. package/dist/social/youtube.d.ts +21 -0
  257. package/dist/social/youtube.d.ts.map +1 -0
  258. package/dist/social/youtube.js +108 -0
  259. package/dist/social/youtube.js.map +1 -0
  260. package/dist/tools/app-info.d.ts +7 -0
  261. package/dist/tools/app-info.d.ts.map +1 -0
  262. package/dist/tools/app-info.js +53 -0
  263. package/dist/tools/app-info.js.map +1 -0
  264. package/dist/tools/collector-fetch.d.ts +11 -0
  265. package/dist/tools/collector-fetch.d.ts.map +1 -0
  266. package/dist/tools/collector-fetch.js +101 -0
  267. package/dist/tools/collector-fetch.js.map +1 -0
  268. package/dist/tools/db-query.d.ts +29 -0
  269. package/dist/tools/db-query.d.ts.map +1 -0
  270. package/dist/tools/db-query.js +159 -0
  271. package/dist/tools/db-query.js.map +1 -0
  272. package/dist/tools/skill-result.d.ts +8 -0
  273. package/dist/tools/skill-result.d.ts.map +1 -0
  274. package/dist/tools/skill-result.js +63 -0
  275. package/dist/tools/skill-result.js.map +1 -0
  276. package/dist/tools/tool-host.d.ts +12 -0
  277. package/dist/tools/tool-host.d.ts.map +1 -0
  278. package/dist/tools/tool-host.js +124 -0
  279. package/dist/tools/tool-host.js.map +1 -0
  280. package/dist/types/collectors.d.ts +198 -0
  281. package/dist/types/collectors.d.ts.map +1 -0
  282. package/dist/types/collectors.js +28 -0
  283. package/dist/types/collectors.js.map +1 -0
  284. package/dist/types/skill.d.ts +60 -0
  285. package/dist/types/skill.d.ts.map +1 -0
  286. package/dist/types/skill.js +9 -0
  287. package/dist/types/skill.js.map +1 -0
  288. package/dist/utils/circuit-breaker.d.ts +26 -0
  289. package/dist/utils/circuit-breaker.d.ts.map +1 -0
  290. package/dist/utils/circuit-breaker.js +67 -0
  291. package/dist/utils/circuit-breaker.js.map +1 -0
  292. package/dist/utils/errors.d.ts +44 -0
  293. package/dist/utils/errors.d.ts.map +1 -0
  294. package/dist/utils/errors.js +75 -0
  295. package/dist/utils/errors.js.map +1 -0
  296. package/dist/utils/escape.d.ts +11 -0
  297. package/dist/utils/escape.d.ts.map +1 -0
  298. package/dist/utils/escape.js +19 -0
  299. package/dist/utils/escape.js.map +1 -0
  300. package/dist/utils/logger.d.ts +19 -0
  301. package/dist/utils/logger.d.ts.map +1 -0
  302. package/dist/utils/logger.js +93 -0
  303. package/dist/utils/logger.js.map +1 -0
  304. package/dist/utils/parse-json.d.ts +13 -0
  305. package/dist/utils/parse-json.d.ts.map +1 -0
  306. package/dist/utils/parse-json.js +61 -0
  307. package/dist/utils/parse-json.js.map +1 -0
  308. package/dist/utils/paths.d.ts +14 -0
  309. package/dist/utils/paths.d.ts.map +1 -0
  310. package/dist/utils/paths.js +19 -0
  311. package/dist/utils/paths.js.map +1 -0
  312. package/dist/utils/rate-limiter.d.ts +20 -0
  313. package/dist/utils/rate-limiter.d.ts.map +1 -0
  314. package/dist/utils/rate-limiter.js +47 -0
  315. package/dist/utils/rate-limiter.js.map +1 -0
  316. package/dist/utils/retry.d.ts +26 -0
  317. package/dist/utils/retry.d.ts.map +1 -0
  318. package/dist/utils/retry.js +61 -0
  319. package/dist/utils/retry.js.map +1 -0
  320. package/launchd/.gitkeep +0 -0
  321. package/launchd/com.adaria-ai.daemon.plist.template +62 -0
  322. package/launchd/com.adaria-ai.monitor.plist.template +41 -0
  323. package/launchd/com.adaria-ai.weekly.plist.template +43 -0
  324. package/package.json +72 -0
  325. package/prompts/aso-description.md +44 -0
  326. package/prompts/aso-inapp-events.md +20 -0
  327. package/prompts/aso-metadata.md +34 -0
  328. package/prompts/aso-screenshots.md +20 -0
  329. package/prompts/onboarding-hypotheses.md +38 -0
  330. package/prompts/onboarding-review-timing.md +24 -0
  331. package/prompts/review-clustering.md +19 -0
  332. package/prompts/review-replies.md +18 -0
  333. package/prompts/review-sentiment.md +16 -0
  334. package/prompts/seo-blog-fridgify-recipe.md +116 -0
  335. package/prompts/seo-blog.md +69 -0
  336. package/prompts/short-form-ideas.md +50 -0
  337. package/prompts/social-publish.md +46 -0
@@ -0,0 +1,60 @@
1
+ /**
2
+ * ASO Skill โ€” App Store Optimization analysis.
3
+ *
4
+ * Ported from growth-agent `src/agents/aso-agent.js`. Analyzes keyword
5
+ * visibility, detects rank drops, discovers opportunities, tracks
6
+ * competitor metadata changes, and generates metadata improvement
7
+ * proposals via Claude.
8
+ *
9
+ * 65-80% of installs come from organic search, making this the
10
+ * highest-impact skill in the weekly briefing.
11
+ */
12
+ import type { Skill } from "./index.js";
13
+ import type { SkillContext, SkillResult } from "../types/skill.js";
14
+ import type { AppConfig } from "../config/apps-schema.js";
15
+ import type { AsoKeywordRanking, AsoCompetitorInfo } from "../types/collectors.js";
16
+ interface AsoCollectors {
17
+ getKeywordRankings: (appId: string, platform: string, keywords: string[]) => Promise<AsoKeywordRanking[]>;
18
+ getKeywordSuggestions: (appId: string, platform: string, locale: string) => Promise<Array<{
19
+ keyword: string;
20
+ searchVolume: number | null;
21
+ competition: number | null;
22
+ }>>;
23
+ getCompetitorInfo: (competitorId: string, platform: string) => Promise<AsoCompetitorInfo>;
24
+ }
25
+ interface AppStoreCollectors {
26
+ getAppLocalizations?: (appId: string, locale: string) => Promise<{
27
+ name?: string;
28
+ subtitle?: string;
29
+ description?: string;
30
+ } | null>;
31
+ }
32
+ /**
33
+ * Injected collector dependencies. Skills receive these via SkillContext
34
+ * or directly โ€” M4 passes them as constructor args until M5 wires a
35
+ * unified CollectorRegistry.
36
+ */
37
+ export interface AsoSkillDeps {
38
+ asoMobile: AsoCollectors;
39
+ appStore?: AppStoreCollectors;
40
+ }
41
+ export declare class AsoSkill implements Skill {
42
+ readonly name = "aso";
43
+ readonly commands: readonly ["aso"];
44
+ private readonly deps;
45
+ constructor(deps: AsoSkillDeps);
46
+ dispatch(ctx: SkillContext, text: string): Promise<SkillResult>;
47
+ analyzeAso(ctx: SkillContext, app: AppConfig): Promise<SkillResult>;
48
+ private collectKeywordRankings;
49
+ private calculateRankChanges;
50
+ private findOpportunities;
51
+ private detectCompetitorChanges;
52
+ private fetchAndCompareCompetitor;
53
+ private generateMetadataProposal;
54
+ private generateScreenshotSuggestions;
55
+ private generateInAppEventSuggestions;
56
+ private getCurrentMetadata;
57
+ private buildSummary;
58
+ }
59
+ export {};
60
+ //# sourceMappingURL=aso.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aso.d.ts","sourceRoot":"","sources":["../../src/skills/aso.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EAGZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAsCnF,UAAU,aAAa;IACrB,kBAAkB,EAAE,CAClB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAAE,KACf,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAClC,qBAAqB,EAAE,CACrB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC,CAAC;IAClG,iBAAiB,EAAE,CACjB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACjC;AAED,UAAU,kBAAkB;IAC1B,mBAAmB,CAAC,EAAE,CACpB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,KACX,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;CACjF;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,aAAa,CAAC;IACzB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AAED,qBAAa,QAAS,YAAW,KAAK;IACpC,QAAQ,CAAC,IAAI,SAAS;IACtB,QAAQ,CAAC,QAAQ,mBAAoB;IAErC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAe;gBAExB,IAAI,EAAE,YAAY;IAIxB,QAAQ,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAmB/D,UAAU,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;YA8D3D,sBAAsB;IAmCpC,OAAO,CAAC,oBAAoB;YA4Bd,iBAAiB;YAqCjB,uBAAuB;YAyBvB,yBAAyB;YA2DzB,wBAAwB;YAgDxB,6BAA6B;YA2B7B,6BAA6B;YAqB7B,kBAAkB;IAgBhC,OAAO,CAAC,YAAY;CAwDrB"}
@@ -0,0 +1,322 @@
1
+ /**
2
+ * ASO Skill โ€” App Store Optimization analysis.
3
+ *
4
+ * Ported from growth-agent `src/agents/aso-agent.js`. Analyzes keyword
5
+ * visibility, detects rank drops, discovers opportunities, tracks
6
+ * competitor metadata changes, and generates metadata improvement
7
+ * proposals via Claude.
8
+ *
9
+ * 65-80% of installs come from organic search, making this the
10
+ * highest-impact skill in the weekly briefing.
11
+ */
12
+ import { parseAppNameFromCommand } from "./index.js";
13
+ import { insertKeywordRanking, getKeywordRankChange, insertCompetitorMetadata, getPreviousCompetitorMetadata, } from "../db/queries.js";
14
+ import { preparePrompt } from "../prompts/loader.js";
15
+ import { warn as logWarn } from "../utils/logger.js";
16
+ import { sanitizeExternalText } from "../security/prompt-guard.js";
17
+ const MAX_DESCRIPTION_LEN = 200;
18
+ /** Threshold for keyword rank drops that trigger alerts. */
19
+ const DEFAULT_RANK_ALERT_THRESHOLD = 5;
20
+ export class AsoSkill {
21
+ name = "aso";
22
+ commands = ["aso"];
23
+ deps;
24
+ constructor(deps) {
25
+ this.deps = deps;
26
+ }
27
+ async dispatch(ctx, text) {
28
+ const appName = parseAppNameFromCommand(text);
29
+ const app = appName
30
+ ? ctx.apps.find((a) => a.id.toLowerCase() === appName)
31
+ : ctx.apps[0];
32
+ if (!app) {
33
+ return {
34
+ summary: appName
35
+ ? `โŒ App "${appName}" not found in apps.yaml. Available: ${ctx.apps.map((a) => a.id).join(", ")}`
36
+ : "โŒ No apps configured. Add apps to apps.yaml.",
37
+ alerts: [],
38
+ approvals: [],
39
+ };
40
+ }
41
+ return this.analyzeAso(ctx, app);
42
+ }
43
+ async analyzeAso(ctx, app) {
44
+ const alerts = [];
45
+ const approvals = [];
46
+ // 1. Collect current keyword rankings
47
+ const rankings = await this.collectKeywordRankings(ctx, app);
48
+ // 2. Calculate rank changes vs last week
49
+ const rankChanges = this.calculateRankChanges(ctx, app, rankings);
50
+ // 3. Detect critical drops
51
+ const criticalDrops = rankChanges.filter((c) => c.drop >= DEFAULT_RANK_ALERT_THRESHOLD);
52
+ for (const drop of criticalDrops) {
53
+ alerts.push({
54
+ severity: "high",
55
+ message: `"${drop.keyword}" (${drop.platform}) rank ${String(drop.previousRank)} โ†’ ${String(drop.currentRank)} (drop -${String(drop.drop)})`,
56
+ });
57
+ }
58
+ // 4. Find new keyword opportunities
59
+ const opportunities = await this.findOpportunities(app);
60
+ // 5. Detect competitor metadata changes
61
+ const competitorChanges = await this.detectCompetitorChanges(ctx, app);
62
+ // 6. Generate metadata improvement proposal via Claude
63
+ let metadataProposal = null;
64
+ if (alerts.length > 0 || opportunities.length > 0 || competitorChanges.length > 0) {
65
+ metadataProposal = await this.generateMetadataProposal(ctx, app, rankChanges, opportunities);
66
+ if (metadataProposal) {
67
+ approvals.push({
68
+ id: `aso-meta-${app.id}`,
69
+ description: `ASO metadata change proposal for ${app.name}`,
70
+ agent: "aso",
71
+ payload: { proposal: metadataProposal },
72
+ });
73
+ }
74
+ }
75
+ // 7. Screenshot caption suggestions
76
+ const screenshotSuggestions = await this.generateScreenshotSuggestions(ctx, app, opportunities);
77
+ // 8. In-App Events suggestions (iOS only)
78
+ const inAppEventSuggestions = await this.generateInAppEventSuggestions(ctx, app);
79
+ // 9. Build summary
80
+ const summary = this.buildSummary(app, alerts, rankChanges, opportunities, competitorChanges, screenshotSuggestions, inAppEventSuggestions);
81
+ return { summary, alerts, approvals };
82
+ }
83
+ async collectKeywordRankings(ctx, app) {
84
+ const collected = [];
85
+ for (const platform of app.platform) {
86
+ const storeId = platform === "ios" ? app.appStoreId : app.playStorePackage;
87
+ if (!storeId)
88
+ continue;
89
+ try {
90
+ const rankings = await this.deps.asoMobile.getKeywordRankings(storeId, platform, app.primaryKeywords);
91
+ for (const r of rankings) {
92
+ insertKeywordRanking(ctx.db, {
93
+ app_id: app.id,
94
+ keyword: r.keyword,
95
+ platform,
96
+ rank: r.rank,
97
+ search_volume: r.searchVolume,
98
+ });
99
+ collected.push({ ...r, platform });
100
+ }
101
+ }
102
+ catch (err) {
103
+ logWarn(`[aso] Keyword ranking collection failed for ${app.id}/${platform}: ${err instanceof Error ? err.message : String(err)}`);
104
+ }
105
+ }
106
+ return collected;
107
+ }
108
+ calculateRankChanges(ctx, app, currentRankings) {
109
+ const changes = [];
110
+ for (const ranking of currentRankings) {
111
+ const change = getKeywordRankChange(ctx.db, app.id, ranking.keyword, ranking.platform);
112
+ if (change.current_rank != null && change.previous_rank != null) {
113
+ const drop = change.current_rank - change.previous_rank;
114
+ changes.push({
115
+ keyword: ranking.keyword,
116
+ platform: ranking.platform,
117
+ currentRank: change.current_rank,
118
+ previousRank: change.previous_rank,
119
+ drop,
120
+ searchVolume: ranking.searchVolume,
121
+ });
122
+ }
123
+ }
124
+ return changes.sort((a, b) => b.drop - a.drop);
125
+ }
126
+ async findOpportunities(app) {
127
+ const opportunities = [];
128
+ for (const platform of app.platform) {
129
+ const storeId = platform === "ios" ? app.appStoreId : app.playStorePackage;
130
+ if (!storeId)
131
+ continue;
132
+ try {
133
+ const suggestions = await this.deps.asoMobile.getKeywordSuggestions(storeId, platform, app.locale[0] ?? "ko");
134
+ const existing = new Set(app.primaryKeywords.map((k) => k.toLowerCase()));
135
+ const filtered = suggestions.filter((s) => s.searchVolume != null &&
136
+ s.searchVolume > 100 &&
137
+ s.competition != null &&
138
+ s.competition < 40 &&
139
+ !existing.has(s.keyword.toLowerCase()));
140
+ for (const s of filtered.slice(0, 5)) {
141
+ opportunities.push({ ...s, platform });
142
+ }
143
+ }
144
+ catch (err) {
145
+ logWarn(`[aso] Keyword suggestions failed for ${app.id}/${platform}: ${err instanceof Error ? err.message : String(err)}`);
146
+ }
147
+ }
148
+ return opportunities;
149
+ }
150
+ async detectCompetitorChanges(ctx, app) {
151
+ const competitors = app.competitors;
152
+ if (competitors.length === 0)
153
+ return [];
154
+ const tasks = [];
155
+ for (const competitorId of competitors) {
156
+ for (const platform of app.platform) {
157
+ tasks.push(this.fetchAndCompareCompetitor(ctx, app, competitorId, platform));
158
+ }
159
+ }
160
+ const results = await Promise.allSettled(tasks);
161
+ return results
162
+ .filter((r) => r.status === "fulfilled" && r.value !== null)
163
+ .map((r) => r.value);
164
+ }
165
+ async fetchAndCompareCompetitor(ctx, app, competitorId, platform) {
166
+ try {
167
+ const current = await this.deps.asoMobile.getCompetitorInfo(competitorId, platform);
168
+ insertCompetitorMetadata(ctx.db, {
169
+ app_id: app.id,
170
+ competitor_id: competitorId,
171
+ platform,
172
+ title: current.title,
173
+ subtitle: current.subtitle,
174
+ description: current.description,
175
+ keywords: current.keywords,
176
+ });
177
+ const previous = getPreviousCompetitorMetadata(ctx.db, app.id, competitorId, platform);
178
+ if (previous) {
179
+ const diffs = [];
180
+ if (previous.title !== current.title) {
181
+ diffs.push({ field: "title", old: previous.title, new: current.title });
182
+ }
183
+ if (previous.subtitle !== current.subtitle) {
184
+ diffs.push({ field: "subtitle", old: previous.subtitle, new: current.subtitle });
185
+ }
186
+ if (previous.description !== current.description) {
187
+ diffs.push({
188
+ field: "description",
189
+ old: previous.description ? sanitizeExternalText(previous.description, MAX_DESCRIPTION_LEN) : previous.description,
190
+ new: current.description ? sanitizeExternalText(current.description, MAX_DESCRIPTION_LEN) : current.description,
191
+ });
192
+ }
193
+ const prevKw = previous.keywords ?? "";
194
+ const currKw = Array.isArray(current.keywords)
195
+ ? current.keywords.join(",")
196
+ : (current.keywords ?? "");
197
+ if (prevKw !== currKw) {
198
+ diffs.push({ field: "keywords", old: previous.keywords, new: currKw });
199
+ }
200
+ if (diffs.length > 0) {
201
+ return { competitorId, platform, diffs };
202
+ }
203
+ }
204
+ }
205
+ catch (err) {
206
+ logWarn(`[aso] Competitor fetch failed for ${competitorId}: ${err instanceof Error ? err.message : String(err)}`);
207
+ }
208
+ return null;
209
+ }
210
+ async generateMetadataProposal(ctx, app, rankChanges, opportunities) {
211
+ const currentMetadata = await this.getCurrentMetadata(app);
212
+ const rankChangesText = rankChanges.length > 0
213
+ ? rankChanges
214
+ .map((c) => `- "${c.keyword}" (${c.platform}): rank ${String(c.previousRank)} โ†’ ${String(c.currentRank)} (${c.drop > 0 ? "+" + String(c.drop) : String(c.drop)}) | volume ${c.searchVolume != null ? String(c.searchVolume) : "N/A"}`)
215
+ .join("\n")
216
+ : "No changes";
217
+ const opportunitiesText = opportunities.length > 0
218
+ ? opportunities
219
+ .map((o) => `- "${o.keyword}" (${o.platform}): volume ${o.searchVolume != null ? String(o.searchVolume) : "N/A"}, competition ${o.competition != null ? String(o.competition) : "N/A"}`)
220
+ .join("\n")
221
+ : "None";
222
+ const metadataText = currentMetadata
223
+ ? `## Current metadata\n- Title: ${currentMetadata.name ?? ""}\n- Subtitle: ${currentMetadata.subtitle ?? ""}\n- Description (first 200 chars): ${currentMetadata.description ? sanitizeExternalText(currentMetadata.description, 200) : ""}...`
224
+ : "";
225
+ const prompt = preparePrompt("aso-metadata", {
226
+ appName: app.name,
227
+ primaryKeywords: app.primaryKeywords.join(", "),
228
+ rankChanges: rankChangesText,
229
+ opportunities: opportunitiesText,
230
+ currentMetadata: metadataText,
231
+ });
232
+ try {
233
+ return await ctx.runClaude(prompt);
234
+ }
235
+ catch (err) {
236
+ logWarn(`[aso] Metadata proposal generation failed: ${err instanceof Error ? err.message : String(err)}`);
237
+ return null;
238
+ }
239
+ }
240
+ async generateScreenshotSuggestions(ctx, app, opportunities) {
241
+ const keywords = [
242
+ ...app.primaryKeywords,
243
+ ...opportunities.map((o) => o.keyword),
244
+ ].slice(0, 10);
245
+ if (keywords.length === 0)
246
+ return null;
247
+ const prompt = preparePrompt("aso-screenshots", {
248
+ appName: app.name,
249
+ keywords: keywords.join(", "),
250
+ });
251
+ try {
252
+ return await ctx.runClaude(prompt);
253
+ }
254
+ catch (err) {
255
+ logWarn(`[aso] Screenshot suggestions failed: ${err instanceof Error ? err.message : String(err)}`);
256
+ return null;
257
+ }
258
+ }
259
+ async generateInAppEventSuggestions(ctx, app) {
260
+ if (!app.platform.includes("ios"))
261
+ return null;
262
+ const prompt = preparePrompt("aso-inapp-events", {
263
+ appName: app.name,
264
+ keywords: app.primaryKeywords.join(", "),
265
+ });
266
+ try {
267
+ return await ctx.runClaude(prompt);
268
+ }
269
+ catch (err) {
270
+ logWarn(`[aso] In-App Events suggestions failed: ${err instanceof Error ? err.message : String(err)}`);
271
+ return null;
272
+ }
273
+ }
274
+ async getCurrentMetadata(app) {
275
+ if (!this.deps.appStore?.getAppLocalizations)
276
+ return null;
277
+ try {
278
+ if (app.platform.includes("ios") && app.appStoreId) {
279
+ return await this.deps.appStore.getAppLocalizations(app.appStoreId, app.locale[0] ?? "ko");
280
+ }
281
+ }
282
+ catch {
283
+ // metadata fetch failure is non-fatal
284
+ }
285
+ return null;
286
+ }
287
+ buildSummary(app, alerts, rankChanges, opportunities, competitorChanges, screenshotSuggestions, inAppEventSuggestions) {
288
+ const hasAlert = alerts.length > 0;
289
+ const header = hasAlert
290
+ ? `*๐Ÿ”ด [Urgent] ASO โ€” ${app.name}*`
291
+ : `*๐ŸŸข ASO โ€” ${app.name}*`;
292
+ const lines = [header];
293
+ if (hasAlert) {
294
+ const top = rankChanges.find((c) => c.drop >= DEFAULT_RANK_ALERT_THRESHOLD);
295
+ if (top) {
296
+ lines.push(`โ€ข "${top.keyword}" rank ${String(top.previousRank)} โ†’ ${String(top.currentRank)} (drop -${String(top.drop)})`);
297
+ }
298
+ }
299
+ const rising = rankChanges.filter((c) => c.drop < 0);
300
+ if (rising.length > 0) {
301
+ lines.push(`โ€ข ๐ŸŸข ${String(rising.length)} rising keywords: ${rising.slice(0, 3).map((c) => `"${c.keyword}" +${String(Math.abs(c.drop))}`).join(", ")}`);
302
+ }
303
+ if (opportunities.length > 0) {
304
+ lines.push(`โ€ข ๐Ÿ’ก ${String(opportunities.length)} new opportunities: ${opportunities.slice(0, 3).map((o) => `"${o.keyword}"`).join(", ")}`);
305
+ }
306
+ if (competitorChanges.length > 0) {
307
+ const comps = competitorChanges.map((c) => c.competitorId);
308
+ lines.push(`โ€ข ๐Ÿ”ต Competitor metadata change detected: ${comps.join(", ")}`);
309
+ }
310
+ if (screenshotSuggestions) {
311
+ lines.push("โ€ข ๐Ÿ“ธ Screenshot caption suggestions ready");
312
+ }
313
+ if (inAppEventSuggestions) {
314
+ lines.push("โ€ข ๐Ÿ“… In-App Events suggestions ready");
315
+ }
316
+ if (lines.length === 1) {
317
+ lines.push("โ€ข Keyword rankings stable");
318
+ }
319
+ return lines.join("\n");
320
+ }
321
+ }
322
+ //# sourceMappingURL=aso.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aso.js","sourceRoot":"","sources":["../../src/skills/aso.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Content Skill โ€” generates weekly content drafts (short-form scripts,
3
+ * Pinterest pins, blog posts). Uses Claude CLI instead of the
4
+ * Anthropic SDK directly (growth-agent used SDK; adaria-ai standardizes
5
+ * on CLI runner for all Claude calls).
6
+ *
7
+ * Ported from growth-agent `src/agents/content-agent.js`.
8
+ *
9
+ * NOTE: This skill overlaps with ShortFormSkill. The checklist notes
10
+ * "Port or fold into short-form.ts โ€” decide during port." Decision:
11
+ * keep separate because ContentAgent generates Pinterest pins and
12
+ * trend-research content that ShortFormSkill doesn't cover.
13
+ */
14
+ import type { Skill } from "./index.js";
15
+ import type { SkillContext, SkillResult } from "../types/skill.js";
16
+ import type { AppConfig } from "../config/apps-schema.js";
17
+ export declare class ContentSkill implements Skill {
18
+ readonly name = "content";
19
+ readonly commands: readonly ["content"];
20
+ dispatch(ctx: SkillContext, text: string): Promise<SkillResult>;
21
+ generate(ctx: SkillContext, app: AppConfig): Promise<SkillResult>;
22
+ private generateShortFormScripts;
23
+ private generatePinterestPins;
24
+ }
25
+ //# sourceMappingURL=content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/skills/content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAG1D,qBAAa,YAAa,YAAW,KAAK;IACxC,QAAQ,CAAC,IAAI,aAAa;IAC1B,QAAQ,CAAC,QAAQ,uBAAwB;IAEnC,QAAQ,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAiB/D,QAAQ,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;YAiBzD,wBAAwB;YA+BxB,qBAAqB;CAyBpC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Content Skill โ€” generates weekly content drafts (short-form scripts,
3
+ * Pinterest pins, blog posts). Uses Claude CLI instead of the
4
+ * Anthropic SDK directly (growth-agent used SDK; adaria-ai standardizes
5
+ * on CLI runner for all Claude calls).
6
+ *
7
+ * Ported from growth-agent `src/agents/content-agent.js`.
8
+ *
9
+ * NOTE: This skill overlaps with ShortFormSkill. The checklist notes
10
+ * "Port or fold into short-form.ts โ€” decide during port." Decision:
11
+ * keep separate because ContentAgent generates Pinterest pins and
12
+ * trend-research content that ShortFormSkill doesn't cover.
13
+ */
14
+ import { parseAppNameFromCommand } from "./index.js";
15
+ import { warn as logWarn } from "../utils/logger.js";
16
+ export class ContentSkill {
17
+ name = "content";
18
+ commands = ["content"];
19
+ async dispatch(ctx, text) {
20
+ const appName = parseAppNameFromCommand(text);
21
+ const app = appName
22
+ ? ctx.apps.find((a) => a.id.toLowerCase() === appName)
23
+ : ctx.apps[0];
24
+ if (!app) {
25
+ return {
26
+ summary: appName ? `โŒ App "${appName}" not found.` : "โŒ No apps configured.",
27
+ alerts: [],
28
+ approvals: [],
29
+ };
30
+ }
31
+ return this.generate(ctx, app);
32
+ }
33
+ async generate(ctx, app) {
34
+ const trendKeywords = app.primaryKeywords.slice(0, 10);
35
+ // Generate content types in parallel
36
+ const [scripts, pins] = await Promise.all([
37
+ this.generateShortFormScripts(ctx, app, trendKeywords, 3),
38
+ this.generatePinterestPins(ctx, app, trendKeywords, 5),
39
+ ]);
40
+ const lines = [`*๐ŸŸข Content โ€” ${app.name}*`];
41
+ lines.push(`โ€ข ${String(scripts.length)} short-form scripts ยท ${String(pins.length)} Pinterest pins`);
42
+ return { summary: lines.join("\n"), alerts: [], approvals: [] };
43
+ }
44
+ async generateShortFormScripts(ctx, app, keywords, count) {
45
+ const prompt = `Generate ${String(count)} short-form video scripts (TikTok/Reels) to promote the ${app.name} app.
46
+
47
+ ## App: ${app.name}
48
+ ## Target keywords: ${keywords.join(", ")}
49
+
50
+ ## Production guide
51
+ - Format: faceless โ€” screen recording, text overlays, AI voiceover
52
+ - Hook (first 3s): start with a problem statement, shocking stat, or question
53
+ - Body (15-25s): walk through app usage step by step
54
+ - CTA: "Link in bio" or "Search in the App Store"
55
+ - Each script should use a different angle
56
+
57
+ Respond with JSON only:
58
+ [{"title":"...","hook":"...","body":"...","cta":"...","hashtags":["#tag1"]}]`;
59
+ try {
60
+ const raw = await ctx.runClaude(prompt);
61
+ const parsed = JSON.parse(raw);
62
+ return Array.isArray(parsed) ? parsed : [];
63
+ }
64
+ catch (err) {
65
+ logWarn(`[content] Short-form script generation failed: ${err instanceof Error ? err.message : String(err)}`);
66
+ return [];
67
+ }
68
+ }
69
+ async generatePinterestPins(ctx, app, keywords, count) {
70
+ const prompt = `Generate ${String(count)} Pinterest pin copies for the ${app.name} app.
71
+
72
+ App: ${app.name}
73
+ Related keywords: ${keywords.join(", ")}
74
+
75
+ Each pin must include a title, description, and hashtags. Write in English.
76
+
77
+ Respond with JSON only:
78
+ [{"title":"Pin title","description":"Pin description","hashtags":["#tag1"]}]`;
79
+ try {
80
+ const raw = await ctx.runClaude(prompt);
81
+ const parsed = JSON.parse(raw);
82
+ return Array.isArray(parsed) ? parsed : [];
83
+ }
84
+ catch (err) {
85
+ logWarn(`[content] Pinterest pin generation failed: ${err instanceof Error ? err.message : String(err)}`);
86
+ return [];
87
+ }
88
+ }
89
+ }
90
+ //# sourceMappingURL=content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/skills/content.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Skill registry.
3
+ *
4
+ * A "skill" is a code-defined, domain-specific handler that reacts to
5
+ * explicit Slack commands (Mode A). Skills are heavy, may gate write paths
6
+ * through `ApprovalManager`, and are NOT exposed as MCP tools.
7
+ *
8
+ * M4 upgraded the Skill interface from `dispatch(text)` โ†’ `dispatch(ctx, text)`
9
+ * with a `SkillResult` return type. PlaceholderSkill still exists for
10
+ * skills not yet ported (M5 will remove it).
11
+ */
12
+ import type { SkillContext, SkillResult } from "../types/skill.js";
13
+ export interface Skill {
14
+ /** Human-readable name (used in logs and Slack messages). */
15
+ readonly name: string;
16
+ /**
17
+ * Command words that trigger this skill when they appear as the first
18
+ * whitespace-separated token of a Slack message (case-insensitive).
19
+ */
20
+ readonly commands: readonly string[];
21
+ /**
22
+ * Executes the skill with the shared context and the raw message text.
23
+ * The skill is responsible for parsing the app name from `text` and
24
+ * looking it up in `ctx.apps`.
25
+ */
26
+ dispatch(ctx: SkillContext, text: string): Promise<SkillResult>;
27
+ }
28
+ export declare class SkillRegistry {
29
+ private skills;
30
+ register(skill: Skill): void;
31
+ /**
32
+ * Returns the skill whose `commands` match the first token of `text`,
33
+ * or `null` if no skill matches. Matching is case-insensitive.
34
+ */
35
+ findSkill(text: string): Skill | null;
36
+ private findSkillByCommand;
37
+ getSkills(): readonly Skill[];
38
+ getSkillCount(): number;
39
+ }
40
+ /**
41
+ * Placeholder skill for commands not yet ported. Returns a clear
42
+ * "not implemented" message so the operator can verify Mode A plumbing.
43
+ * M5 removes this once all skills are real.
44
+ */
45
+ export declare class PlaceholderSkill implements Skill {
46
+ readonly name: string;
47
+ readonly commands: readonly string[];
48
+ constructor(name: string, commands: readonly string[]);
49
+ dispatch(_ctx: SkillContext, _text: string): Promise<SkillResult>;
50
+ }
51
+ /**
52
+ * Builds an M1 placeholder registry. Every command word that M4โ€“M6 will
53
+ * eventually recognize is mapped to a no-op skill that returns a clear
54
+ * "not implemented" message, so the operator can verify Mode A plumbing
55
+ * (reactions, status evolution, audit log) before any real skill lands.
56
+ */
57
+ export declare function createM1PlaceholderRegistry(): SkillRegistry;
58
+ /**
59
+ * Parse the app name from the second token of a command string.
60
+ * Returns `undefined` if no second token is present.
61
+ *
62
+ * Example: `"aso fridgify"` โ†’ `"fridgify"`
63
+ */
64
+ export declare function parseAppNameFromCommand(text: string): string | undefined;
65
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/skills/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEnE,MAAM,WAAW,KAAK;IACpB,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACjE;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAe;IAE7B,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAW5B;;;OAGG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI;IAMrC,OAAO,CAAC,kBAAkB;IAS1B,SAAS,IAAI,SAAS,KAAK,EAAE;IAI7B,aAAa,IAAI,MAAM;CAGxB;AAED;;;;GAIG;AACH,qBAAa,gBAAiB,YAAW,KAAK;IAE1C,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE;gBAD3B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,SAAS,MAAM,EAAE;IAGtC,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAOlE;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,IAAI,aAAa,CAc3D;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGxE"}