Skip to content

Commit f1c6c02

Browse files
author
anyfn
committed
Initial release: anyfn v0.1.0
Make every Android app agent-ready in 60 seconds. No code changes. No SDK. - Scanner: AccessibilityService + UI tree extraction + LLM-powered function inference - Invoker: UI Automator-based replay with structured error recovery - Bridge: embedded Ktor MCP server (WebSocket/HTTP/SSE) + Android 16 AppFunctions exporter - UI: Jetpack Compose, Material 3, dark-first - Docs: full Docusaurus-ready content (getting-started, guides, how-it-works, safety, api-reference) - 5 worked examples (TikTok, WhatsApp, Spotify, cross-app chain, Grab) - Marketing site (Next.js 14) - 7 launch artifacts (demo script, HN, X thread, LinkedIn, Medium, KOL outreach, press kit) - CI: build, lint, test, release workflows
0 parents  commit f1c6c02

166 files changed

Lines changed: 7798 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
indent_style = space
7+
indent_size = 4
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
max_line_length = 120
11+
12+
[*.{kt,kts}]
13+
ij_kotlin_allow_trailing_comma = true
14+
ij_kotlin_allow_trailing_comma_on_call_site = true
15+
16+
[*.{json,yml,yaml,md,tsx,ts,js,jsx}]
17+
indent_size = 2
18+
19+
[Makefile]
20+
indent_style = tab
21+
22+
[*.md]
23+
trim_trailing_whitespace = false

.github/FUNDING.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
github: [anyfn]
2+
open_collective: anyfn
3+
custom: ['https://anyfn.dev/sponsor']
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
name: Bug report
3+
about: Something is wrong inside anyfn itself
4+
title: "[bug] "
5+
labels: bug
6+
assignees: ''
7+
---
8+
9+
## What happened
10+
11+
A short, clear description.
12+
13+
## Steps to reproduce
14+
15+
1. ...
16+
2. ...
17+
3. ...
18+
19+
## What you expected
20+
21+
...
22+
23+
## Environment
24+
25+
- anyfn version: (Settings → About)
26+
- Android version:
27+
- Device model:
28+
- Target app + version (if relevant):
29+
- LLM backend: Anthropic / Gemini Nano
30+
31+
## Logs
32+
33+
```
34+
adb logcat -d -s anyfn:* AccessibilityService:* > anyfn.log
35+
```
36+
37+
Paste the relevant section here. Redact API keys.
38+
39+
## Screen recording
40+
41+
A 5–10 second clip helps a lot. GitHub accepts `.mp4` and `.gif` drops directly into the issue body.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
name: Feature request
3+
about: An idea for anyfn itself (not a specific app)
4+
title: "[feature] "
5+
labels: enhancement
6+
assignees: ''
7+
---
8+
9+
## The problem
10+
11+
What can't you do today? Concrete scenario, please — "agents on Android are hard" is too abstract to act on.
12+
13+
## The proposal
14+
15+
What you'd like anyfn to do. Sketches, pseudocode, or screenshots all welcome.
16+
17+
## Alternatives considered
18+
19+
Anything you tried first, and why it didn't work.
20+
21+
## Scope check
22+
23+
- [ ] This does not require running unauthenticated remote code.
24+
- [ ] This does not introduce telemetry or analytics.
25+
- [ ] This works without modifying target apps' source.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
name: New app support
3+
about: anyfn doesn't yet handle a specific app well — let's fix that
4+
title: "[app] "
5+
labels: app-support
6+
assignees: ''
7+
---
8+
9+
## The app
10+
11+
- Name:
12+
- Package: (e.g. `com.zhiliaoapp.musically`)
13+
- Version:
14+
- Country / locale (UI varies by region):
15+
16+
## What you wanted to do
17+
18+
The function as you'd phrase it to an agent. Example:
19+
> "Search TikTok for 'sunset' and save the top 3 videos to my favourites."
20+
21+
## What happened on scan
22+
23+
- [ ] anyfn failed to launch the app
24+
- [ ] anyfn launched but the inference returned zero functions
25+
- [ ] anyfn returned functions but their schemas are wrong
26+
- [ ] anyfn returned the right schemas but invocation fails
27+
28+
## Dumps
29+
30+
Run a scan with debug mode on (Settings → Debug → Dump UI trees), then attach:
31+
32+
```bash
33+
adb pull /sdcard/Android/data/dev.anyfn/files/dumps/<package>.json
34+
```
35+
36+
Attach the JSON here. Redact anything personal.
37+
38+
## Invocation log
39+
40+
If invocation was attempted:
41+
42+
```bash
43+
adb logcat -d -s anyfn:* > anyfn.log
44+
```
45+
46+
Paste the relevant section.
47+
48+
## Notes
49+
50+
Anything else worth knowing — region-locked UI, A/B-tested screens, login walls, etc.

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
## What this PR does
2+
3+
One-line summary.
4+
5+
## Why
6+
7+
The problem it solves, or the issue it closes. Link issues with `Closes #N`.
8+
9+
## How
10+
11+
Brief design notes for the reviewer. What changed, what didn't, what you ruled out.
12+
13+
## Screenshots / recording
14+
15+
For UI changes, drop a screenshot or a 5-second `.mp4`.
16+
17+
## Checklist
18+
19+
- [ ] `./gradlew lint test assembleDebug` passes locally
20+
- [ ] Added or updated a unit test
21+
- [ ] Updated docs if user-facing behaviour changed
22+
- [ ] No new dependencies (or justified in the description)
23+
- [ ] No telemetry / network beacons of any kind
24+
- [ ] Commits follow Conventional Commits
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: android-build
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
9+
10+
permissions:
11+
contents: read
12+
13+
jobs:
14+
build:
15+
runs-on: ubuntu-latest
16+
timeout-minutes: 30
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Set up JDK 17
21+
uses: actions/setup-java@v4
22+
with:
23+
distribution: temurin
24+
java-version: '17'
25+
26+
- name: Set up Gradle
27+
uses: gradle/actions/setup-gradle@v3
28+
with:
29+
cache-read-only: ${{ github.ref != 'refs/heads/main' }}
30+
31+
- name: Assemble debug APK
32+
working-directory: android
33+
run: ./gradlew :app:assembleDebug --stacktrace
34+
35+
- name: Assemble release APK (unsigned)
36+
working-directory: android
37+
run: ./gradlew :app:assembleRelease --stacktrace
38+
39+
- name: Upload debug APK
40+
uses: actions/upload-artifact@v4
41+
with:
42+
name: anyfn-debug-${{ github.sha }}
43+
path: android/app/build/outputs/apk/debug/*.apk
44+
retention-days: 14
45+
46+
- name: Upload release APK
47+
uses: actions/upload-artifact@v4
48+
with:
49+
name: anyfn-release-unsigned-${{ github.sha }}
50+
path: android/app/build/outputs/apk/release/*.apk
51+
retention-days: 14

.github/workflows/lint.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: lint
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
ktlint-detekt:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
- uses: actions/setup-java@v4
18+
with:
19+
distribution: temurin
20+
java-version: '17'
21+
- uses: gradle/actions/setup-gradle@v3
22+
- name: ktlint
23+
working-directory: android
24+
run: ./gradlew ktlintCheck --stacktrace
25+
- name: detekt
26+
working-directory: android
27+
run: ./gradlew detekt --stacktrace

.github/workflows/release.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
release:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0
18+
19+
- uses: actions/setup-java@v4
20+
with:
21+
distribution: temurin
22+
java-version: '17'
23+
24+
- uses: gradle/actions/setup-gradle@v3
25+
26+
- name: Decode keystore
27+
if: env.SIGNING_KEYSTORE_BASE64 != ''
28+
env:
29+
SIGNING_KEYSTORE_BASE64: ${{ secrets.SIGNING_KEYSTORE_BASE64 }}
30+
run: echo "$SIGNING_KEYSTORE_BASE64" | base64 -d > android/app/release.keystore
31+
32+
- name: Build signed release APK
33+
working-directory: android
34+
env:
35+
SIGNING_KEYSTORE_PATH: release.keystore
36+
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
37+
SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
38+
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
39+
run: ./gradlew :app:assembleRelease --stacktrace
40+
41+
- name: Generate release notes
42+
run: bash scripts/generate-release-notes.sh "${GITHUB_REF_NAME}" > release-notes.md
43+
44+
- name: Create GitHub Release
45+
uses: softprops/action-gh-release@v2
46+
with:
47+
name: ${{ github.ref_name }}
48+
body_path: release-notes.md
49+
files: |
50+
android/app/build/outputs/apk/release/*.apk
51+
draft: false
52+
prerelease: ${{ contains(github.ref_name, '-') }}

.github/workflows/test.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: test
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
unit:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
- uses: actions/setup-java@v4
18+
with:
19+
distribution: temurin
20+
java-version: '17'
21+
- uses: gradle/actions/setup-gradle@v3
22+
- name: Unit tests
23+
working-directory: android
24+
run: ./gradlew test --stacktrace
25+
- name: Upload test reports
26+
if: failure()
27+
uses: actions/upload-artifact@v4
28+
with:
29+
name: unit-test-reports
30+
path: android/**/build/reports/tests/
31+
retention-days: 7

0 commit comments

Comments
 (0)