@amityco/social-plus-vise 0.4.0 → 0.8.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.
- package/README.md +297 -59
- package/dist/outcomes.js +376 -0
- package/dist/tools/ast.js +297 -0
- package/dist/tools/project.js +1209 -12
- package/package.json +10 -4
- package/rules/auth.yaml +126 -0
- package/rules/chat.yaml +876 -0
- package/rules/comments.yaml +906 -0
- package/rules/feed.yaml +2285 -30
- package/rules/live-data.yaml +60 -0
- package/rules/moderation.yaml +1286 -0
- package/rules/network.yaml +66 -0
- package/rules/push.yaml +467 -16
- package/rules/sdk-lifecycle.yaml +60 -0
- package/rules/security.yaml +60 -0
- package/skills/social-plus-vise/SKILL.md +148 -1
- package/dist/tools/patch.js +0 -67
package/dist/outcomes.js
CHANGED
|
@@ -5,6 +5,9 @@ export function hasAnswer(answers, id) {
|
|
|
5
5
|
const CLASSIFY_ORDER = [
|
|
6
6
|
"setup-push",
|
|
7
7
|
"setup-live-data",
|
|
8
|
+
"add-moderation",
|
|
9
|
+
"add-chat",
|
|
10
|
+
"add-comments",
|
|
8
11
|
"add-feed",
|
|
9
12
|
"troubleshoot",
|
|
10
13
|
"validate-setup",
|
|
@@ -17,6 +20,15 @@ const LIVE_PATTERNS = [
|
|
|
17
20
|
const FEED_PATTERNS = [
|
|
18
21
|
/\b(social feature|social features|feed|timeline|post list|news feed|create post|create a post|post creation|compose post)\b/,
|
|
19
22
|
];
|
|
23
|
+
const COMMENT_PATTERNS = [
|
|
24
|
+
/\b(comment|comments|reply|replies|thread|discussion thread|comment composer)\b/,
|
|
25
|
+
];
|
|
26
|
+
const MODERATION_OUTCOME_PATTERNS = [
|
|
27
|
+
/\b(moderation|report|flag|block user|mute user|hide content|abuse|review queue|admin queue)\b/,
|
|
28
|
+
];
|
|
29
|
+
const CHAT_PATTERNS = [
|
|
30
|
+
/\b(chat|messaging|dm|direct message|conversation|group chat|channel|inbox)\b/,
|
|
31
|
+
];
|
|
20
32
|
const TROUBLESHOOT_PATTERNS = [/\b(error|broken|crash|not working|fail|timeout|401|403)\b/];
|
|
21
33
|
const VALIDATE_PATTERNS = [/\b(validate|check|correct|setup right|initiali[sz])\b/];
|
|
22
34
|
const SETUP_PATTERNS = [/\b(setup|set up|install|integrate|wire|configure)\b/];
|
|
@@ -485,6 +497,367 @@ const addFeed = {
|
|
|
485
497
|
],
|
|
486
498
|
resolveNotes: () => [],
|
|
487
499
|
};
|
|
500
|
+
function commentDocPath(platform) {
|
|
501
|
+
const paths = {
|
|
502
|
+
android: "social-plus-sdk/social/comments/android",
|
|
503
|
+
flutter: "social-plus-sdk/social/comments/flutter",
|
|
504
|
+
ios: "social-plus-sdk/social/comments/ios",
|
|
505
|
+
typescript: "social-plus-sdk/social/comments/typescript",
|
|
506
|
+
"react-native": "social-plus-sdk/social/comments/typescript",
|
|
507
|
+
};
|
|
508
|
+
return paths[platform] ?? "social-plus-sdk/social/comments";
|
|
509
|
+
}
|
|
510
|
+
const addComments = {
|
|
511
|
+
id: "add-comments",
|
|
512
|
+
patterns: COMMENT_PATTERNS,
|
|
513
|
+
interpretation: "Add a comments/replies surface to an existing post or content entity using the customer app's design system.",
|
|
514
|
+
docsQuery: (platform) => `${platform} social comments replies`,
|
|
515
|
+
docs: (platform) => [
|
|
516
|
+
{
|
|
517
|
+
path: commentDocPath(platform),
|
|
518
|
+
reason: "Canonical comment/reply API, query patterns, and lifecycle guidance.",
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
path: "social-plus-sdk/social/comments",
|
|
522
|
+
reason: "Comment concepts overview: threading, moderation, and target types.",
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
path: liveDataPlatformPath(platform),
|
|
526
|
+
reason: "Platform-specific Live Object and Live Collection implementation for real-time comment updates.",
|
|
527
|
+
},
|
|
528
|
+
],
|
|
529
|
+
intakeQuestions: (ctx) => {
|
|
530
|
+
const questions = [
|
|
531
|
+
{
|
|
532
|
+
id: "comment_target",
|
|
533
|
+
question: "What content type should comments attach to (post, story, custom entity)?",
|
|
534
|
+
why: "Comments must reference a concrete parent. The coding agent must not invent postId or targetId values.",
|
|
535
|
+
required: true,
|
|
536
|
+
blocksImplementationWhenMissing: true,
|
|
537
|
+
options: ["post", "story", "custom entity"],
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
id: "comment_depth",
|
|
541
|
+
question: "Should comments support threaded replies? If yes, what is the maximum depth?",
|
|
542
|
+
why: "Threaded comments require different query strategy and UI rendering. Unbounded depth creates recursion risk.",
|
|
543
|
+
required: true,
|
|
544
|
+
blocksImplementationWhenMissing: true,
|
|
545
|
+
options: ["flat (no threading)", "one level of replies", "multi-level (specify depth)"],
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
id: "moderation_flow",
|
|
549
|
+
question: "What moderation actions should be available on comments (report, delete, hide)?",
|
|
550
|
+
why: "Comments are user-generated content and need a moderation affordance path.",
|
|
551
|
+
required: true,
|
|
552
|
+
blocksImplementationWhenMissing: false,
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
id: "lifecycle_owner",
|
|
556
|
+
question: "What owns the lifecycle of the live comment subscription (Activity, ViewController, Widget, React component)?",
|
|
557
|
+
why: "Live comment observers must be cleaned up to prevent memory leaks and stale updates.",
|
|
558
|
+
required: true,
|
|
559
|
+
blocksImplementationWhenMissing: true,
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
id: "target_screen",
|
|
563
|
+
question: "Which screen or component should display comments?",
|
|
564
|
+
why: "Vise needs to know the target file/route for comment UI placement.",
|
|
565
|
+
required: true,
|
|
566
|
+
blocksImplementationWhenMissing: true,
|
|
567
|
+
},
|
|
568
|
+
];
|
|
569
|
+
return filterAnswered(ctx.answers, questions);
|
|
570
|
+
},
|
|
571
|
+
requiredInputs: () => [
|
|
572
|
+
"comment target type: post, story, or custom entity",
|
|
573
|
+
"concrete parent entity ID or selection flow",
|
|
574
|
+
"comment depth: flat or threaded with max depth",
|
|
575
|
+
"lifecycle owner for comment observer cleanup",
|
|
576
|
+
"target screen or component for comment UI",
|
|
577
|
+
],
|
|
578
|
+
implementationRules: () => [
|
|
579
|
+
"Do not invent or hardcode postId, commentId, or any comment target. Ask for the target or implement a parent-entity-owned flow.",
|
|
580
|
+
"Do not ask for API keys in chat. Create an env/config placeholder.",
|
|
581
|
+
"Comment observers must be cleaned up when the lifecycle owner is destroyed.",
|
|
582
|
+
"Threaded comments must respect the declared max depth.",
|
|
583
|
+
],
|
|
584
|
+
implementationSteps: (ctx) => {
|
|
585
|
+
const designEvidence = ctx.designSignals.length > 0
|
|
586
|
+
? ctx.designSignals.map((signal) => signal.file)
|
|
587
|
+
: ["requiredInputs.design token or theme source file"];
|
|
588
|
+
return [
|
|
589
|
+
{
|
|
590
|
+
step: "Confirm the parent entity (post/story), target screen, and threading depth before writing code.",
|
|
591
|
+
evidence: [
|
|
592
|
+
"requiredInputs.comment target type",
|
|
593
|
+
"requiredInputs.comment depth",
|
|
594
|
+
"requiredInputs.target screen or component",
|
|
595
|
+
],
|
|
596
|
+
},
|
|
597
|
+
{
|
|
598
|
+
step: "Fetch comment docs and implement the comment query using platform live collection patterns.",
|
|
599
|
+
evidence: [commentDocPath(ctx.platform), liveDataPlatformPath(ctx.platform)],
|
|
600
|
+
},
|
|
601
|
+
{ step: "Reuse the host app's existing visual system for the comment UI.", evidence: designEvidence },
|
|
602
|
+
{ step: "Implement loading, empty, error, and data states for comments.", evidence: ["implementationRules.file-specific edits"] },
|
|
603
|
+
{ step: "Add comment creation (composer) with auth gate and error handling.", evidence: ["requiredInputs.concrete parent entity ID"] },
|
|
604
|
+
{ step: "Wire moderation affordance (report/hide/delete) on each comment.", evidence: ["implementationRules.file-specific edits"] },
|
|
605
|
+
{ step: "Run validate_setup and detected command sensors after edits.", evidence: ["validate_setup", "run_sensors"] },
|
|
606
|
+
];
|
|
607
|
+
},
|
|
608
|
+
validation: (platform) => [
|
|
609
|
+
"comment target resolved",
|
|
610
|
+
"no invented postId/commentId",
|
|
611
|
+
`${platform}.comments.target-resolved`,
|
|
612
|
+
`${platform}.comments.observer-cleanup`,
|
|
613
|
+
`${platform}.comments.ui-states-present`,
|
|
614
|
+
`${platform}.comments.moderation-affordance-present`,
|
|
615
|
+
],
|
|
616
|
+
stopConditions: (ctx) => filterStops(ctx.answers, [
|
|
617
|
+
{ id: "comment_target", text: "The comment target entity is unknown; do not invent postId, commentId, or parent entity references." },
|
|
618
|
+
{ id: "comment_depth", text: "The threading depth is unknown; cannot implement comment query or UI without knowing if replies are flat or nested." },
|
|
619
|
+
{ id: "lifecycle_owner", text: "The lifecycle owner for comment observer cleanup is unknown." },
|
|
620
|
+
{ id: "moderation_flow", text: "The moderation flow for comments is unknown; comments are UGC and need report/block/hide." },
|
|
621
|
+
]),
|
|
622
|
+
resolvePlan: () => [
|
|
623
|
+
{ file: "Target screen/component", intent: "Add comment query, render list with loading/empty/error/data states." },
|
|
624
|
+
{ file: "Comment composer", intent: "Add comment creation flow with auth gate." },
|
|
625
|
+
{ file: "Moderation", intent: "Add report/hide/delete affordance on each comment." },
|
|
626
|
+
],
|
|
627
|
+
resolveVerification: () => [
|
|
628
|
+
"Confirm comments load from the correct parent entity.",
|
|
629
|
+
"Confirm comment observer is cleaned up on lifecycle end.",
|
|
630
|
+
"Confirm threading respects declared depth limit.",
|
|
631
|
+
"Confirm moderation affordance is present.",
|
|
632
|
+
],
|
|
633
|
+
resolveNotes: () => [],
|
|
634
|
+
};
|
|
635
|
+
const addModeration = {
|
|
636
|
+
id: "add-moderation",
|
|
637
|
+
patterns: MODERATION_OUTCOME_PATTERNS,
|
|
638
|
+
interpretation: "Add moderation capabilities (report, block, mute, hide) to social content.",
|
|
639
|
+
docsQuery: (platform) => `${platform} moderation report flag block`,
|
|
640
|
+
docs: (platform) => [
|
|
641
|
+
{
|
|
642
|
+
path: "social-plus-sdk/social/moderation",
|
|
643
|
+
reason: "Moderation concepts: report, block, mute, hide content, and admin review.",
|
|
644
|
+
},
|
|
645
|
+
{
|
|
646
|
+
path: liveDataPlatformPath(platform),
|
|
647
|
+
reason: "Platform-specific patterns for observing moderation state changes.",
|
|
648
|
+
},
|
|
649
|
+
],
|
|
650
|
+
intakeQuestions: (ctx) => {
|
|
651
|
+
const questions = [
|
|
652
|
+
{
|
|
653
|
+
id: "moderation_target",
|
|
654
|
+
question: "What content types need moderation (post, comment, message, user)?",
|
|
655
|
+
why: "Each content type has different moderation APIs and UI patterns.",
|
|
656
|
+
required: true,
|
|
657
|
+
blocksImplementationWhenMissing: true,
|
|
658
|
+
options: ["posts", "comments", "messages", "users", "all"],
|
|
659
|
+
},
|
|
660
|
+
{
|
|
661
|
+
id: "moderation_actions",
|
|
662
|
+
question: "Which moderation actions should be available (report, block, mute, hide, admin queue)?",
|
|
663
|
+
why: "The action set determines API calls and UI affordances needed.",
|
|
664
|
+
required: true,
|
|
665
|
+
blocksImplementationWhenMissing: true,
|
|
666
|
+
},
|
|
667
|
+
{
|
|
668
|
+
id: "admin_ownership",
|
|
669
|
+
question: "Who owns the admin/review queue for reported content?",
|
|
670
|
+
why: "Admin moderation may live in a separate dashboard or external service.",
|
|
671
|
+
required: false,
|
|
672
|
+
blocksImplementationWhenMissing: false,
|
|
673
|
+
},
|
|
674
|
+
{
|
|
675
|
+
id: "post_action_rendering",
|
|
676
|
+
question: "How should moderated content appear to the user (hidden, placeholder, blurred)?",
|
|
677
|
+
why: "Customer policy determines whether blocked/hidden content shows a placeholder or disappears entirely.",
|
|
678
|
+
required: true,
|
|
679
|
+
blocksImplementationWhenMissing: false,
|
|
680
|
+
},
|
|
681
|
+
];
|
|
682
|
+
return filterAnswered(ctx.answers, questions);
|
|
683
|
+
},
|
|
684
|
+
requiredInputs: () => [
|
|
685
|
+
"moderation target types: post, comment, message, user",
|
|
686
|
+
"moderation action set: report, block, mute, hide, admin queue",
|
|
687
|
+
"post-action rendering policy for blocked/hidden content",
|
|
688
|
+
],
|
|
689
|
+
implementationRules: () => [
|
|
690
|
+
"Do not implement moderation without knowing the target content types.",
|
|
691
|
+
"Report actions must include confirmation UI before submission.",
|
|
692
|
+
"Blocked/muted state must be applied to the rendered UI, not just stored.",
|
|
693
|
+
],
|
|
694
|
+
implementationSteps: (ctx) => {
|
|
695
|
+
const designEvidence = ctx.designSignals.length > 0
|
|
696
|
+
? ctx.designSignals.map((signal) => signal.file)
|
|
697
|
+
: ["requiredInputs.design token or theme source file"];
|
|
698
|
+
return [
|
|
699
|
+
{
|
|
700
|
+
step: "Confirm moderation targets, actions, and rendering policy before writing code.",
|
|
701
|
+
evidence: ["requiredInputs.moderation target types", "requiredInputs.moderation action set"],
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
step: "Implement report flow with confirmation UX.",
|
|
705
|
+
evidence: ["social-plus-sdk/social/moderation"],
|
|
706
|
+
},
|
|
707
|
+
{ step: "Implement block/mute state application to rendered content.", evidence: designEvidence },
|
|
708
|
+
{ step: "Add hidden/blocked content rendering per customer policy.", evidence: ["requiredInputs.post-action rendering policy"] },
|
|
709
|
+
{ step: "Run validate_setup and detected command sensors after edits.", evidence: ["validate_setup", "run_sensors"] },
|
|
710
|
+
];
|
|
711
|
+
},
|
|
712
|
+
validation: (platform) => [
|
|
713
|
+
`${platform}.moderation.report-flow-present`,
|
|
714
|
+
`${platform}.moderation.block-or-mute-state-applied`,
|
|
715
|
+
`${platform}.moderation.hidden-content-rendering-present`,
|
|
716
|
+
`${platform}.moderation.confirmation-ux-present`,
|
|
717
|
+
],
|
|
718
|
+
stopConditions: (ctx) => filterStops(ctx.answers, [
|
|
719
|
+
{ id: "moderation_target", text: "The moderation target content types are unknown." },
|
|
720
|
+
{ id: "moderation_actions", text: "The moderation action set is unknown; cannot implement without knowing which actions are needed." },
|
|
721
|
+
]),
|
|
722
|
+
resolvePlan: () => [
|
|
723
|
+
{ file: "Report UI", intent: "Add report flow with confirmation dialog." },
|
|
724
|
+
{ file: "Content rendering", intent: "Apply blocked/muted/hidden state to rendered items." },
|
|
725
|
+
{ file: "Moderation actions", intent: "Wire block/mute/hide actions to SDK calls." },
|
|
726
|
+
],
|
|
727
|
+
resolveVerification: () => [
|
|
728
|
+
"Confirm report flow includes confirmation before submission.",
|
|
729
|
+
"Confirm blocked/muted content renders according to customer policy.",
|
|
730
|
+
"Confirm moderation actions are wired to correct SDK APIs.",
|
|
731
|
+
],
|
|
732
|
+
resolveNotes: () => [],
|
|
733
|
+
};
|
|
734
|
+
const addChat = {
|
|
735
|
+
id: "add-chat",
|
|
736
|
+
patterns: CHAT_PATTERNS,
|
|
737
|
+
interpretation: "Add chat/messaging capabilities using the customer app's design system.",
|
|
738
|
+
docsQuery: (platform) => `${platform} chat messaging channel`,
|
|
739
|
+
docs: (platform) => [
|
|
740
|
+
{
|
|
741
|
+
path: "social-plus-sdk/chat/channels",
|
|
742
|
+
reason: "Chat channel concepts: creation, types (1:1, group, community), and member management.",
|
|
743
|
+
},
|
|
744
|
+
{
|
|
745
|
+
path: "social-plus-sdk/chat/messages",
|
|
746
|
+
reason: "Message send/receive, observer lifecycle, delivery state, and moderation.",
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
path: liveDataPlatformPath(platform),
|
|
750
|
+
reason: "Platform-specific Live Object/Collection patterns for real-time message updates.",
|
|
751
|
+
},
|
|
752
|
+
],
|
|
753
|
+
intakeQuestions: (ctx) => {
|
|
754
|
+
const questions = [
|
|
755
|
+
{
|
|
756
|
+
id: "chat_shape",
|
|
757
|
+
question: "What chat shape is needed (1:1, group, community channel)?",
|
|
758
|
+
why: "Determines channel creation strategy and query patterns.",
|
|
759
|
+
required: true,
|
|
760
|
+
blocksImplementationWhenMissing: true,
|
|
761
|
+
options: ["1:1 direct message", "group chat", "community channel"],
|
|
762
|
+
},
|
|
763
|
+
{
|
|
764
|
+
id: "channel_source",
|
|
765
|
+
question: "How are channels/conversations created or discovered?",
|
|
766
|
+
why: "Avoids invented channel IDs. Channels come from user selection, SDK query, or app logic.",
|
|
767
|
+
required: true,
|
|
768
|
+
blocksImplementationWhenMissing: true,
|
|
769
|
+
},
|
|
770
|
+
{
|
|
771
|
+
id: "message_capabilities",
|
|
772
|
+
question: "Which message capabilities are needed (send, read, edit, delete, reactions)?",
|
|
773
|
+
why: "Determines the scope of SDK calls and UI affordances.",
|
|
774
|
+
required: true,
|
|
775
|
+
blocksImplementationWhenMissing: true,
|
|
776
|
+
options: ["send only", "send + read", "full (send/read/edit/delete/react)"],
|
|
777
|
+
},
|
|
778
|
+
{
|
|
779
|
+
id: "read_receipts",
|
|
780
|
+
question: "Should read receipts be shown?",
|
|
781
|
+
why: "Read receipts require additional SDK subscriptions and cleanup.",
|
|
782
|
+
required: true,
|
|
783
|
+
blocksImplementationWhenMissing: false,
|
|
784
|
+
options: ["yes", "no"],
|
|
785
|
+
},
|
|
786
|
+
{
|
|
787
|
+
id: "typing_indicators",
|
|
788
|
+
question: "Should typing indicators be shown?",
|
|
789
|
+
why: "Typing indicators require observer lifecycle management.",
|
|
790
|
+
required: true,
|
|
791
|
+
blocksImplementationWhenMissing: false,
|
|
792
|
+
options: ["yes", "no"],
|
|
793
|
+
},
|
|
794
|
+
{
|
|
795
|
+
id: "moderation_flow",
|
|
796
|
+
question: "What moderation actions are needed for chat messages?",
|
|
797
|
+
why: "Chat messages are UGC and need report/block/mute affordance.",
|
|
798
|
+
required: true,
|
|
799
|
+
blocksImplementationWhenMissing: false,
|
|
800
|
+
},
|
|
801
|
+
];
|
|
802
|
+
return filterAnswered(ctx.answers, questions);
|
|
803
|
+
},
|
|
804
|
+
requiredInputs: () => [
|
|
805
|
+
"chat shape: 1:1, group, or community channel",
|
|
806
|
+
"channel source: how channels are created or discovered",
|
|
807
|
+
"message capabilities scope",
|
|
808
|
+
"read receipt and typing indicator requirements",
|
|
809
|
+
"moderation flow for chat messages",
|
|
810
|
+
],
|
|
811
|
+
implementationRules: () => [
|
|
812
|
+
"Do not invent or hardcode channelId, conversationId, or member lists.",
|
|
813
|
+
"Message observers must be cleaned up when the chat view is dismissed.",
|
|
814
|
+
"Typing indicator subscriptions must be cleaned up on view disposal.",
|
|
815
|
+
"Read receipt marking must only fire when messages are actually displayed.",
|
|
816
|
+
],
|
|
817
|
+
implementationSteps: (ctx) => {
|
|
818
|
+
const designEvidence = ctx.designSignals.length > 0
|
|
819
|
+
? ctx.designSignals.map((signal) => signal.file)
|
|
820
|
+
: ["requiredInputs.design token or theme source file"];
|
|
821
|
+
return [
|
|
822
|
+
{
|
|
823
|
+
step: "Confirm chat shape, channel source, and capabilities before writing code.",
|
|
824
|
+
evidence: ["requiredInputs.chat shape", "requiredInputs.channel source", "requiredInputs.message capabilities scope"],
|
|
825
|
+
},
|
|
826
|
+
{
|
|
827
|
+
step: "Implement channel query/creation and message observation with lifecycle cleanup.",
|
|
828
|
+
evidence: ["social-plus-sdk/chat/channels", "social-plus-sdk/chat/messages"],
|
|
829
|
+
},
|
|
830
|
+
{ step: "Reuse the host app's existing visual system for chat UI.", evidence: designEvidence },
|
|
831
|
+
{ step: "Add message send with error handling and auth gate.", evidence: ["implementationRules.file-specific edits"] },
|
|
832
|
+
{ step: "Wire read receipts and typing indicators if required.", evidence: ["requiredInputs.read receipt and typing indicator requirements"] },
|
|
833
|
+
{ step: "Add moderation affordance on messages.", evidence: ["requiredInputs.moderation flow for chat messages"] },
|
|
834
|
+
{ step: "Run validate_setup and detected command sensors after edits.", evidence: ["validate_setup", "run_sensors"] },
|
|
835
|
+
];
|
|
836
|
+
},
|
|
837
|
+
validation: (platform) => [
|
|
838
|
+
`${platform}.chat.channel-target-resolved`,
|
|
839
|
+
`${platform}.chat.message-observer-cleanup`,
|
|
840
|
+
`${platform}.chat.send-error-handling`,
|
|
841
|
+
`${platform}.chat.moderation-affordance-present`,
|
|
842
|
+
],
|
|
843
|
+
stopConditions: (ctx) => filterStops(ctx.answers, [
|
|
844
|
+
{ id: "chat_shape", text: "The chat shape is unknown; cannot implement without knowing 1:1, group, or community channel." },
|
|
845
|
+
{ id: "channel_source", text: "The channel/member source is unknown; do not invent channelId or member lists." },
|
|
846
|
+
{ id: "message_capabilities", text: "The message capabilities scope is unknown." },
|
|
847
|
+
]),
|
|
848
|
+
resolvePlan: () => [
|
|
849
|
+
{ file: "Channel view", intent: "Query/create channel and observe messages with lifecycle cleanup." },
|
|
850
|
+
{ file: "Message composer", intent: "Send messages with error handling and auth gate." },
|
|
851
|
+
{ file: "Message list", intent: "Render messages with read receipts and moderation affordance." },
|
|
852
|
+
],
|
|
853
|
+
resolveVerification: () => [
|
|
854
|
+
"Confirm channel is queried from a valid source, not invented.",
|
|
855
|
+
"Confirm message observer is cleaned up on view dismissal.",
|
|
856
|
+
"Confirm send has error handling.",
|
|
857
|
+
"Confirm moderation affordance exists on messages.",
|
|
858
|
+
],
|
|
859
|
+
resolveNotes: () => [],
|
|
860
|
+
};
|
|
488
861
|
const troubleshoot = {
|
|
489
862
|
id: "troubleshoot",
|
|
490
863
|
patterns: TROUBLESHOOT_PATTERNS,
|
|
@@ -568,6 +941,9 @@ const outcomeRegistry = {
|
|
|
568
941
|
"setup-push": setupPush,
|
|
569
942
|
"setup-live-data": setupLiveData,
|
|
570
943
|
"add-feed": addFeed,
|
|
944
|
+
"add-comments": addComments,
|
|
945
|
+
"add-moderation": addModeration,
|
|
946
|
+
"add-chat": addChat,
|
|
571
947
|
troubleshoot,
|
|
572
948
|
"validate-setup": validateSetup,
|
|
573
949
|
unknown,
|