mooner / Resume KO/EN /

mooner:~/resume $ cat projects/starlight/README.md

Project StarLight

스크립터블 메신저 자동응답 프레임워크

메신저로 온 메시지를 사용자가 쓴 스크립트에 넘기고 답장을 보내는 크로스 메신저 자동응답 프레임워크입니다. 카카오톡은 안드로이드 알림과 그 답장 기능으로, Discord는 플러그인으로 연결하고, 스크립트 언어와 기능도 플러그인으로 더합니다.

Site ↗Source ↗

mooner:~/resume/projects/starlight $ tree -L 1

Structure01

구조

06 parts

Gradle 모듈 세 개와 플러그인 형식(.slp)으로 되어 있습니다. 앱과 플러그인은 같은 SDK(PluginCore)를 공유합니다.

app/
알림 리스너, 메시지 파서, 내장 JavaScript 엔진(Rhino), 스크립트 API 18종, 코드 에디터와 테스트용 디버그룸.
PluginCore/
앱과 플러그인이 함께 쓰는 SDK. 스크립트 언어, API, 프로젝트 이벤트, 위젯, 이벤트 버스를 확장하는 지점이 여기 있습니다.
ConfigDSL/
설정 화면을 Kotlin DSL로 선언하면 목록 화면으로 그려 주는 라이브러리. 앱과 플러그인 설정에 같이 씁니다.
*.slp
매니페스트(starlight.json)가 든 플러그인 패키지. Discord 연동, V8 같은 새 스크립트 언어, API를 더합니다.
starlight-version
채널별(snapshot · beta · release) 최신 버전과 변경 기록. 앱의 업데이트 확인과 소개 페이지가 읽습니다.
Gradle plugin
플러그인 프로젝트를 .slp로 묶는 빌드 태스크. Gradle Plugin Portal에 올려 두었습니다.

mooner:~/resume/projects/starlight $ cat docs/architecture.md

Architecture02

아키텍처

Data flow

MESSENGERnotificationLISTENERpackage + profilePARSER SPECroom · senderPROJECTSallowed events onlySCRIPTonMessage(event).SLP PLUGINSDiscord · V8 · APIaddLanguage · addApiREMOTEINPUTreply actionevent.room.send()// each project runs on its own thread pool;// an error stops only that project

알림 한 건이 규칙 → 파서 → 이벤트 → 프로젝트 순서로 흘러가고, 스크립트의 답장은 그 알림의 답장 기능으로 돌아갑니다.

  • 알림은 앱 패키지와 사용자 프로필로 규칙을 찾고, 규칙이 고른 파서가 방, 보낸 사람, 답장 경로를 꺼냅니다. 카카오톡은 이 기본 규칙으로 받고, Discord는 따로 배포하는 플러그인으로 연결합니다.
  • 이벤트는 그 이벤트를 허용한 프로젝트에만 전달됩니다. 허용 목록은 와일드카드를 쓰는 트리로 맞춥니다.
  • 프로젝트마다 스레드 풀이 따로 있고, 오류가 나면 그 프로젝트만 멈춥니다.
  • 플러그인 로더는 예약 ID와 API 버전을 검사하고 의존 순서대로 불러오며, 플러그인이 코어 클래스를 가리지 못하게 막습니다.
  • 기존 자동응답 앱의 스크립트가 그대로 돌도록 레거시 API와 response 이벤트도 함께 구현했습니다.

mooner:~/resume/projects/starlight $ git log --grep=fix

Problem solving03

문제 해결

03 cases

  1. 01

    한 메시지에 답장이 두 번 간다

    Problem
    공개 알파를 올린 다음 날, 명령 하나에 답장이 두 번 간다는 제보가 들어왔습니다.
    Approach
    안드로이드가 기존 알림 리스너를 끝내지 않고 새 리스너를 한 번 더 등록하는 경우가 있다고 보고, 같은 메시지 ID가 연달아 들어오면 두 번째를 버리게 했습니다.
    Result
    수정 빌드를 바로 올렸고, 제보자가 정상 동작을 확인해 이슈를 닫았습니다.
  2. 02

    답장이 다른 방으로 간다

    Problem
    레거시 response 이벤트의 답장이 명령이 온 방이 아니라, 마지막으로 알림이 온 방으로 갔습니다. 답장 객체가 하나뿐이고 방 정보를 들고 있지 않았기 때문입니다.
    Approach
    호환 대상 앱에서 같은 상황이 어떻게 동작하는지 먼저 확인한 뒤, 방마다 답장 객체를 만들어 약한 참조 캐시에 두도록 바꿨습니다.
    Result
    0.3.2a에 반영했습니다. 새로 쓰는 스크립트에는 방 정보가 이벤트에 함께 담기는 onMessage를 권합니다.
  3. 03

    Android 14 이하에서 로그가 쌓이면 앱이 종료된다

    Problem
    컴파일 대상 SDK를 35로 올린 뒤, 프로젝트 로그가 한도를 넘으면 Android 14 이하 기기에서 앱이 종료됐습니다.
    Approach
    원인을 Kotlin의 removeFirst가 Android 14 이하에는 없는 메서드로 컴파일되는 문제(KT-71375)로 짚어 이슈에 정리했습니다. 곧바로 고칠 수 없는 동안에는 다운로드 링크를 이전 안정 버전으로 되돌렸고, 수정 코드는 외부 기여자의 PR(#60)을 리뷰해 병합했습니다.
    Result
    0.3.3a에서 해결했고, 같은 원인으로 열린 이슈 세 개를 닫았습니다.

mooner:~/resume/projects/starlight $ ls ./screens

Screens04

화면

02 images

프로젝트 탭. JavaScript와 V8 프로젝트 목록과 프로젝트별 편집, 재컴파일, 디버그룸 버튼
프로젝트 목록
플러그인 탭. V8, Discord, Awt 플러그인이 설치된 모습
설치된 플러그인

Accepting requestsAnsan --:-- KST

mooner:~/resume $ ./contact.sh

Contact→

Name
문민기 / Minki Moon
Handle
@mooner
Base
Ansan, KR

느긋하게 커피 한 잔 어떠세요?

궁금한 점이 있다면 편하게 연락 주세요.

// ping me anytime — i read all.

© 2026 Minki Mooncrafted with monospace affection · rev 2026.10.18