flow_chat 0.9.0 → 0.10.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 (110) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +29 -0
  3. data/.github/workflows/pages.yml +43 -0
  4. data/.gitignore +4 -1
  5. data/CHANGELOG.md +49 -0
  6. data/README.md +166 -295
  7. data/Rakefile +12 -1
  8. data/SECURITY.md +1 -1
  9. data/docs/architecture.md +52 -479
  10. data/docs/async-background-processing.md +31 -265
  11. data/docs/configuration.md +106 -613
  12. data/docs/factory-pattern.md +27 -324
  13. data/docs/gateway-context-variables.md +140 -143
  14. data/docs/gateway-development.md +86 -650
  15. data/docs/getting-started.md +40 -379
  16. data/docs/instrumentation.md +88 -279
  17. data/docs/platforms/instagram.md +278 -0
  18. data/docs/platforms/messenger.md +205 -0
  19. data/docs/platforms/telegram.md +47 -951
  20. data/docs/platforms/ussd.md +38 -653
  21. data/docs/platforms/whatsapp.md +73 -1321
  22. data/docs/superpowers/plans/2026-07-09-inbound-media-support.md +732 -0
  23. data/docs/superpowers/plans/2026-07-09-inbound-media-support.md.tasks.json +58 -0
  24. data/docs/superpowers/plans/2026-08-10-messenger-instagram.md +4064 -0
  25. data/docs/superpowers/plans/2026-08-10-messenger-instagram.md.tasks.json +226 -0
  26. data/docs/superpowers/plans/2026-08-16-unified-choice-resolution.md +972 -0
  27. data/docs/superpowers/plans/2026-08-16-unified-choice-resolution.md.tasks.json +88 -0
  28. data/docs/superpowers/specs/2026-07-09-inbound-media-support-design.md +195 -0
  29. data/docs/superpowers/specs/2026-08-10-messenger-instagram-design.md +391 -0
  30. data/docs/testing.md +26 -297
  31. data/examples/http_controller.rb +12 -10
  32. data/examples/intercom_configuration_example.rb +19 -24
  33. data/examples/intercom_controller.rb +8 -20
  34. data/examples/multi_tenant_whatsapp_controller.rb +61 -166
  35. data/examples/simulator_controller.rb +0 -1
  36. data/examples/ussd_controller.rb +86 -158
  37. data/examples/whatsapp_controller.rb +16 -15
  38. data/examples/whatsapp_media_examples.rb +27 -79
  39. data/flow_chat.gemspec +22 -2
  40. data/gemfiles/rails_main.gemfile +18 -0
  41. data/lib/flow_chat/app.rb +129 -11
  42. data/lib/flow_chat/async_job.rb +10 -0
  43. data/lib/flow_chat/choice_titles.rb +95 -0
  44. data/lib/flow_chat/config.rb +124 -1
  45. data/lib/flow_chat/delivery_error.rb +9 -0
  46. data/lib/flow_chat/gateway_async_support.rb +19 -1
  47. data/lib/flow_chat/http/configuration_error.rb +9 -0
  48. data/lib/flow_chat/http/gateway/simple.rb +24 -4
  49. data/lib/flow_chat/http/middleware/choice_mapper.rb +94 -0
  50. data/lib/flow_chat/input.rb +86 -0
  51. data/lib/flow_chat/instagram/client.rb +32 -0
  52. data/lib/flow_chat/instagram/configuration.rb +147 -0
  53. data/lib/flow_chat/instagram/configuration_error.rb +7 -0
  54. data/lib/flow_chat/instagram/gateway/send_api.rb +63 -0
  55. data/lib/flow_chat/instagram/middleware/choice_mapper.rb +22 -0
  56. data/lib/flow_chat/instagram/renderer.rb +23 -0
  57. data/lib/flow_chat/instrumentation/metrics_collector.rb +6 -1
  58. data/lib/flow_chat/instrumentation.rb +160 -1
  59. data/lib/flow_chat/intercom/client.rb +34 -28
  60. data/lib/flow_chat/intercom/configuration.rb +2 -49
  61. data/lib/flow_chat/intercom/configuration_error.rb +9 -0
  62. data/lib/flow_chat/intercom/gateway/intercom_api.rb +81 -57
  63. data/lib/flow_chat/intercom/middleware/choice_mapper.rb +101 -0
  64. data/lib/flow_chat/intercom/renderer.rb +57 -5
  65. data/lib/flow_chat/media.rb +121 -0
  66. data/lib/flow_chat/messenger/client.rb +264 -0
  67. data/lib/flow_chat/messenger/configuration.rb +103 -0
  68. data/lib/flow_chat/messenger/configuration_error.rb +9 -0
  69. data/lib/flow_chat/messenger/gateway/send_api.rb +42 -0
  70. data/lib/flow_chat/messenger/middleware/choice_mapper.rb +185 -0
  71. data/lib/flow_chat/messenger/renderer.rb +150 -0
  72. data/lib/flow_chat/meta/challenge.rb +24 -0
  73. data/lib/flow_chat/meta/choice_ladder.rb +37 -0
  74. data/lib/flow_chat/meta/configuration_error.rb +7 -0
  75. data/lib/flow_chat/meta/gateway_identity.rb +38 -0
  76. data/lib/flow_chat/meta/messaging_gateway.rb +471 -0
  77. data/lib/flow_chat/meta/signature.rb +30 -0
  78. data/lib/flow_chat/meta/signature_validation.rb +66 -0
  79. data/lib/flow_chat/meta/webhook_verification.rb +43 -0
  80. data/lib/flow_chat/named_configuration.rb +65 -0
  81. data/lib/flow_chat/prompt.rb +13 -16
  82. data/lib/flow_chat/renderers/markdown_support.rb +109 -0
  83. data/lib/flow_chat/security.rb +76 -0
  84. data/lib/flow_chat/session/middleware.rb +11 -2
  85. data/lib/flow_chat/simulator/controller.rb +31 -15
  86. data/lib/flow_chat/simulator/views/simulator.html.erb +184 -20
  87. data/lib/flow_chat/telegram/client.rb +47 -4
  88. data/lib/flow_chat/telegram/configuration.rb +2 -42
  89. data/lib/flow_chat/telegram/configuration_error.rb +9 -0
  90. data/lib/flow_chat/telegram/gateway/bot_api.rb +46 -28
  91. data/lib/flow_chat/telegram/middleware/choice_mapper.rb +77 -16
  92. data/lib/flow_chat/telegram/renderer.rb +10 -2
  93. data/lib/flow_chat/text_truncator.rb +75 -0
  94. data/lib/flow_chat/ussd/middleware/choice_mapper.rb +10 -0
  95. data/lib/flow_chat/version.rb +1 -1
  96. data/lib/flow_chat/whatsapp/client.rb +14 -7
  97. data/lib/flow_chat/whatsapp/configuration.rb +12 -51
  98. data/lib/flow_chat/whatsapp/configuration_error.rb +9 -0
  99. data/lib/flow_chat/whatsapp/gateway/cloud_api.rb +259 -203
  100. data/lib/flow_chat/whatsapp/middleware/choice_mapper.rb +144 -57
  101. data/lib/flow_chat/whatsapp/renderer.rb +121 -60
  102. data/lib/flow_chat.rb +0 -10
  103. data/lib/tasks/release.rake +11 -1
  104. data/site/.nojekyll +0 -0
  105. data/site/.og-card.html +89 -0
  106. data/site/favicon.svg +6 -0
  107. data/site/index.html +209 -0
  108. data/site/og.png +0 -0
  109. metadata +60 -11
  110. data/lib/flow_chat/whatsapp/id_generator.rb +0 -124
@@ -0,0 +1,58 @@
1
+ {
2
+ "planPath": "docs/superpowers/plans/2026-07-09-inbound-media-support.md",
3
+ "tasks": [
4
+ {
5
+ "id": 1,
6
+ "subject": "Task 1: FlowChat::Media value object",
7
+ "status": "completed",
8
+ "description": "**Goal:** Value object wrapping one inbound media item with metadata + per-platform url/download.\n\n```json:metadata\n{\"files\": [\"lib/flow_chat/media.rb\", \"test/unit/media_test.rb\"], \"verifyCommand\": \"ruby -Itest test/unit/media_test.rb -v\", \"acceptanceCriteria\": [\"metadata readers\", \"url/download dispatch per platform\", \"autoloads via Zeitwerk\"], \"requiresUserVerification\": false}\n```"
9
+ },
10
+ {
11
+ "id": 2,
12
+ "subject": "Task 2: Telegram client media download",
13
+ "status": "completed",
14
+ "description": "**Goal:** Add get_file, file_url, download_file to Telegram client for inbound media.\n\n```json:metadata\n{\"files\": [\"lib/flow_chat/telegram/client.rb\", \"test/unit/telegram/client_test.rb\"], \"verifyCommand\": \"ruby -Itest test/unit/telegram/client_test.rb -v\", \"acceptanceCriteria\": [\"get_file\", \"file_url\", \"download_file\"], \"requiresUserVerification\": false}\n```"
15
+ },
16
+ {
17
+ "id": 3,
18
+ "subject": "Task 3: Wire App to expose inbound media/location/contact",
19
+ "status": "completed",
20
+ "blockedBy": [1, 2],
21
+ "description": "**Goal:** Replace nil stubs; normalize single/array media into media_items, media as first-item convenience.\n\n```json:metadata\n{\"files\": [\"lib/flow_chat/app.rb\", \"test/integration/media_support_test.rb\"], \"verifyCommand\": \"ruby -Itest test/integration/media_support_test.rb -v\", \"acceptanceCriteria\": [\"media_items normalizes single/array/none\", \"media is first item\", \"location/contact/contact_name exposed\", \"correct platform client\"], \"requiresUserVerification\": false}\n```"
22
+ },
23
+ {
24
+ "id": 4,
25
+ "subject": "Task 4: Intercom gateway inbound media parsing",
26
+ "status": "completed",
27
+ "blockedBy": [3],
28
+ "description": "**Goal:** Parse Intercom attachments (array) into request.media, supporting multiple per message.\n\n```json:metadata\n{\"files\": [\"lib/flow_chat/intercom/gateway/intercom_api.rb\", \"test/unit/intercom/gateway/intercom_api_test.rb\"], \"verifyCommand\": \"ruby -Itest test/unit/intercom/gateway/intercom_api_test.rb -v\", \"acceptanceCriteria\": [\"attachments array parsed\", \"content_type mapping\", \"media sentinel input set\", \"text unaffected\"], \"requiresUserVerification\": false}\n```"
29
+ },
30
+ {
31
+ "id": 5,
32
+ "subject": "Task 5: HTTP gateway inbound media parsing",
33
+ "status": "completed",
34
+ "blockedBy": [3],
35
+ "description": "**Goal:** Accept inbound media via HTTP params (media_url/media_type/mime_type).\n\n```json:metadata\n{\"files\": [\"lib/flow_chat/http/gateway/simple.rb\", \"test/unit/http/gateway/simple_test.rb\"], \"verifyCommand\": \"ruby -Itest test/unit/http/gateway/simple_test.rb -v\", \"acceptanceCriteria\": [\"media_url sets request.media\", \"media sentinel when no text\", \"text precedence preserved\"], \"requiresUserVerification\": false}\n```"
36
+ },
37
+ {
38
+ "id": 6,
39
+ "subject": "Task 6: Full suite regression + docs",
40
+ "status": "completed",
41
+ "blockedBy": [4, 5],
42
+ "description": "**Goal:** Confirm full suite green; document inbound media API.\n\n```json:metadata\n{\"files\": [\"README.md\"], \"verifyCommand\": \"bundle exec rake test\", \"acceptanceCriteria\": [\"full suite green\", \"docs updated\"], \"requiresUserVerification\": false}\n```"
43
+ },
44
+ {
45
+ "id": 7,
46
+ "subject": "Task 7: Normalize FlowChat::Media#type across platforms",
47
+ "status": "completed",
48
+ "description": "**Goal:** Follow-up from final review. media.type returns canonical type; raw_type returns native. Committed 51ae2f8."
49
+ },
50
+ {
51
+ "id": 8,
52
+ "subject": "Task 8: Capture inbound captions (Telegram + Intercom)",
53
+ "status": "completed",
54
+ "description": "**Goal:** Follow-up from final review. Telegram message caption + Intercom body captured as media caption. Committed d58a0f5."
55
+ }
56
+ ],
57
+ "lastUpdated": "2026-07-09"
58
+ }