Files
mal/docs/superpowers/plans/2026-05-06-allanime-decomposition.md

4.8 KiB

AllAnime Client Decomposition Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Decompose the monolithic api/playback/allanime_client.go into focused, maintainable units.

Architecture:

  1. Move uTLS networking logic to pkg/net/utls.
  2. Move crypto and key discovery to api/playback/allanime_crypto.go.
  3. Move data extraction and stream detection to api/playback/allanime_extractor.go.
  4. Keep core API and GraphQL logic in api/playback/allanime_client.go.

Tech Stack: Go (uTLS, SHA256, AES-CTR)


Task 1: Move uTLS RoundTripper to pkg/net/utls

Files:

  • Create: pkg/net/utls/utls.go

  • Modify: api/playback/allanime_client.go

  • Step 1: Create pkg/net/utls/utls.go

package utls

import (
	"bufio"
	"context"
	"net"
	"net/http"
	"time"

	utls "github.com/refraction-networking/utls"
	"golang.org/x/net/http2"
)

type UtlsRoundTripper struct{}

func (rt *UtlsRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	port := req.URL.Port()
	if port == "" {
		if req.URL.Scheme == "https" {
			port = "443"
		} else {
			port = "80"
		}
	}

	addr := net.JoinHostPort(req.URL.Hostname(), port)
	conn, err := net.DialTimeout("tcp", addr, 10*time.Second)
	if err != nil {
		return nil, err
	}

	config := &utls.Config{ServerName: req.URL.Hostname()}
	uConn := utls.UClient(conn, config, utls.HelloFirefox_Auto)

	if err := uConn.Handshake(); err != nil {
		return nil, err
	}

	var httpRT http.RoundTripper
	switch uConn.ConnectionState().NegotiatedProtocol {
	case http2.NextProtoTLS:
		t2 := &http2.Transport{
			DialTLSContext: func(ctx context.Context, network, addr string, cfg *utls.Config) (net.Conn, error) {
				return uConn, nil
			},
		}
		httpRT = t2
	default:
		t1 := &http.Transport{
			DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
				return uConn, nil
			},
		}
		httpRT = t1
	}

	return httpRT.RoundTrip(req)
}
  • Step 2: Update allanime_client.go to use the new package

Remove utlsRoundTripper from api/playback/allanime_client.go and update newAllAnimeClient to use &utls.UtlsRoundTripper{}.

  • Step 3: Verify build and commit

Run: go build ./api/playback/... Expected: PASS

git add pkg/net/utls/utls.go api/playback/allanime_client.go
git commit -m "refactor: move utls roundtripper to pkg/net/utls"

Task 2: Extract Crypto and Key Discovery

Files:

  • Create: api/playback/allanime_crypto.go

  • Modify: api/playback/allanime_client.go

  • Step 1: Move crypto logic to allanime_crypto.go

Extract constants (allAnimeAESKey, aniCliRawSourceURL, etc.) and functions (decryptTobeparsed, tryDecryptCTR, getAESKey, fetchKeyFromForks, extractKey, getTestPayload, validateKeys, getAllKeys) to api/playback/allanime_crypto.go.

  • Step 2: Update allanime_client.go

Remove the extracted code from api/playback/allanime_client.go.

  • Step 3: Verify build and commit

Run: go build ./api/playback/... Expected: PASS

git add api/playback/allanime_crypto.go api/playback/allanime_client.go
git commit -m "refactor: extract allanime crypto and key discovery"

Task 3: Extract Data Extraction and Stream Detection

Files:

  • Create: api/playback/allanime_extractor.go

  • Modify: api/playback/allanime_client.go

  • Step 1: Move extraction logic to allanime_extractor.go

Extract functions (extractSourceURLsFromData, buildStreamSource, sourceReference struct, buildSourceReferences, extractEpisodeData, decodeSourceURL, detectStreamType, detectEmbedType, getMapKeys) to api/playback/allanime_extractor.go.

  • Step 2: Update allanime_client.go

Remove the extracted code from api/playback/allanime_client.go. Ensure allAnimeClient methods still call these (now package-level) functions.

  • Step 3: Verify build and commit

Run: go build ./api/playback/... Expected: PASS

git add api/playback/allanime_extractor.go api/playback/allanime_client.go
git commit -m "refactor: extract allanime data extraction logic"

Task 4: Final Cleanup and Verification

Files:

  • Modify: api/playback/allanime_client.go

  • Step 1: Final review of allanime_client.go

Ensure only allAnimeClient struct, newAllAnimeClient, graphqlRequest, graphqlRequestWithHash, Search, GetEpisodes, GetAvailableEpisodes, and GetEpisodeMetadata remain.

  • Step 2: Run all tests

Run: go test -v ./api/playback/... Expected: PASS

  • Step 3: Commit final cleanup
git add api/playback/allanime_client.go
git commit -m "refactor: final cleanup of allanime_client.go"