Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
282 commits
Select commit Hold shift + click to select a range
a637356
perf(kilo-chat): cache sandbox labels
iscekic Apr 30, 2026
aa59432
fix(db): collapse badge count drop migration
iscekic Apr 30, 2026
019c122
fix(notifications): remove duplicate service class
iscekic Apr 30, 2026
418a44b
fix(mobile): inline trivial chat read helpers
iscekic Apr 30, 2026
408cdbb
fix(kilo-chat): share token response builder
iscekic Apr 30, 2026
da4b9bf
fix(kilo-chat): return user id with chat token
iscekic Apr 30, 2026
8a32610
fix(notifications): parse badge buckets centrally
iscekic Apr 30, 2026
5b29952
fix(mobile): remove stale chat route comments
iscekic Apr 30, 2026
c54a7ab
fix(kiloclaw): remove stream chat image plugin
iscekic Apr 30, 2026
e81dbec
fix(notifications): route lifecycle pushes by sandbox id
iscekic Apr 30, 2026
1a71a90
fix(kilo-chat): avoid stale sandbox ownership cache
iscekic Apr 30, 2026
26fe8f7
chore(kiloclaw): regenerate worker bindings
iscekic Apr 30, 2026
961c3a6
fix(kiloclaw): sanitize legacy stream chat config
iscekic Apr 30, 2026
fe7104a
fix(kiloclaw): allow kilo chat plugin on upgrades
iscekic Apr 30, 2026
fdb6bdd
fix(kiloclaw): hash image plugin sources locally
iscekic Apr 30, 2026
748749b
fix(kiloclaw): drop stream chat env references
iscekic Apr 30, 2026
dfb375e
fix(kilo-chat): tighten event payload schemas
iscekic May 1, 2026
e43a0c2
fix(kilo-chat): validate status numbers
iscekic May 1, 2026
67da3ed
fix(notifications): reject empty chat push IDs
iscekic May 1, 2026
4d1d7e8
fix(kilo-chat): split message content schemas
iscekic May 1, 2026
e6bc779
fix(kilo-chat): skip textless bot webhooks
iscekic May 1, 2026
c4d7b72
fix(kilo-chat): reuse event payload schemas
iscekic May 1, 2026
fcfe516
chore(kilo-chat): sync plugin wire schemas
iscekic May 1, 2026
9523bae
fix(kiloclaw): avoid resolved approval edits
iscekic May 1, 2026
a95a04f
Merge remote-tracking branch 'origin/main' into feat/kilo-chat-migrat…
iscekic May 1, 2026
afcd772
fix(kilo-chat): require explicit recipient reads
iscekic May 1, 2026
18a6063
fix(notifications): record badges without push tokens
iscekic May 1, 2026
094138b
fix(kilo-chat): roll back failed action webhooks
iscekic May 1, 2026
19726df
fix(mobile): add kilo chat message actions
iscekic May 1, 2026
d4fc906
fix(kilo-chat): retry failed mark-read attempts
iscekic May 1, 2026
65ff5eb
fix(mobile): add reply and delivery failure parity
iscekic May 1, 2026
e05c9eb
fix(event-service): retry after token refresh
iscekic May 1, 2026
2d49613
fix(mobile): dispatch message actions by identity
iscekic May 1, 2026
713afbf
fix(kiloclaw): disable bot-added chat members
iscekic May 1, 2026
85c7573
fix(mobile): show chat action errors
iscekic May 1, 2026
b36d69a
feat(mobile): add chat typing indicators
iscekic May 1, 2026
f89353e
fix(mobile): generate ulid chat client ids
iscekic May 1, 2026
ead58ee
fix(kilo-chat): reorder conversations after activity
iscekic May 1, 2026
b472cbd
fix(kilo-chat): bound mark-read to observed message
iscekic May 1, 2026
a28b13f
fix(kilo-chat): keep first auto-title
iscekic May 1, 2026
a03eb09
fix(kilo-chat): suppress pending message actions
iscekic May 1, 2026
332190d
fix(notifications): fail open on presence lookup errors
iscekic May 1, 2026
d810e40
fix(notifications): dedupe presence suppressed pushes
iscekic May 1, 2026
e4d9821
fix(kilo-chat): ignore pending ids for read boundary
iscekic May 1, 2026
b2fce72
fix(event-service): keep reconnecting after pre-open failures
iscekic May 1, 2026
de6f1d8
fix(kilo-chat): reject bot additional members
iscekic May 1, 2026
0ffe425
fix(web): wait for kilo chat user id
iscekic May 1, 2026
687715b
fix(kilo-chat): use message timestamp for read activity
iscekic May 1, 2026
ce800d2
fix(kilo-chat): clear badges from mark read
iscekic May 1, 2026
747aa45
fix(kilo-chat): order resolved optimistic messages
iscekic May 1, 2026
16cd90e
fix(mobile): keep mark-read success authoritative
iscekic May 1, 2026
6d56061
fix(mobile): enforce chat message length
iscekic May 1, 2026
de05199
fix(mobile): gate kilo chat sends on bot status
iscekic May 1, 2026
107e221
fix(kilo-chat): revoke mutations after leave
iscekic May 1, 2026
2e4a11f
fix(kilo-chat): include reply parent snapshots
iscekic May 1, 2026
0b91d29
fix(kilo-chat): preserve live reply snapshots
iscekic May 1, 2026
87b2027
fix(kilo-chat): preserve failed edit drafts
iscekic May 1, 2026
6ff09d3
fix(mobile): refresh unread badges under chat provider
iscekic May 1, 2026
9d1894b
fix(web): retry failed kilo chat mark-read
iscekic May 1, 2026
e7bd00d
fix(kilo-chat): suppress false delivery-failed events
iscekic May 1, 2026
5e38128
fix(mobile): retry kilo chat mark read failures
iscekic May 2, 2026
2dffb01
fix(mobile): hide failed message actions
iscekic May 2, 2026
c28402c
fix(kilo-chat): suppress stale action failure events
iscekic May 2, 2026
6316e80
fix(mobile): hide deleted message reactions
iscekic May 2, 2026
c208669
fix(kilo-chat): skip duplicate action failure events
iscekic May 2, 2026
c18b1cb
fix(mobile): redirect stale chat routes
iscekic May 2, 2026
7ff4ec7
fix(kilo-chat): suppress duplicate delivery failure events
iscekic May 2, 2026
6f219c3
fix(web): filter delivery failure toasts by context
iscekic May 2, 2026
ab0dcbb
fix(kilo-chat): guard optimistic message rollbacks
iscekic May 2, 2026
e9007ff
fix(kilo-chat): order delayed message events
iscekic May 2, 2026
321026e
chore: sync schemas
iscekic May 2, 2026
4d81c97
fix(kilo-chat): handle send queue cleanup rejection
iscekic May 2, 2026
4f34b76
fix(kilo-chat): guard read rollback state
iscekic May 2, 2026
78228f7
fix(kilo-chat): keep conversation timestamps monotonic
iscekic May 2, 2026
b867ec8
fix(kilo-chat): ignore stale message update events
iscekic May 2, 2026
0cd3d5d
fix(kilo-chat): preserve state on delayed creates
iscekic May 2, 2026
6b80c53
fix(kilo-chat): preserve resolved actions on delayed creates
iscekic May 2, 2026
78c5be4
fix(kilo-chat): guard stale reaction events
iscekic May 2, 2026
1896394
fix(kilo-chat): preserve badges for stale mark-read
iscekic May 2, 2026
b481119
fix(kilo-chat): seed local reaction operations
iscekic May 2, 2026
a894a2c
fix(kilo-chat): clear deleted conversation badges
iscekic May 2, 2026
9236c07
fix(kilo-chat): seed idempotent reaction removes
iscekic May 2, 2026
f94dfc7
fix(kilo-chat): gate badge clears on mark-read response
iscekic May 2, 2026
e234bf1
fix(mobile): guard stale chat badge writes
iscekic May 2, 2026
e361c20
fix(kilo-chat): invalidate messages on edit conflict
iscekic May 2, 2026
3587ae5
fix(kilo-chat): resolve ci drift
iscekic May 2, 2026
a2836f8
fix(kilo-chat): guard mobile pagination fetches
iscekic May 2, 2026
a3dac48
fix(kilo-chat): remove redundant typing fanout
iscekic May 2, 2026
e7a6bf1
perf(kilo-chat): contain web message rows
iscekic May 2, 2026
46e0347
perf(kilo-chat): collapse membership post-commit update
iscekic May 2, 2026
ec92507
perf(kilo-chat): share reply parent lookup
iscekic May 2, 2026
6e295d1
perf(kilo-chat): reuse create message member info
iscekic May 2, 2026
bbaf0e0
perf(kilo-chat): resolve mark read in conversation do
iscekic May 2, 2026
56d8589
perf(notifications): reuse incremented badge total
iscekic May 2, 2026
f9ddce5
perf(web): stabilize message failure handlers
iscekic May 2, 2026
0d2673a
perf(kilo-chat): slim mark-read resolver payload
iscekic May 2, 2026
1ea0d85
perf(web): scope kilo chat cache events
iscekic May 2, 2026
4889cec
perf(kilo-chat): patch loaded activity rows
iscekic May 2, 2026
d25a3d9
perf(kilo-chat): conditionally advance read markers
iscekic May 2, 2026
259750f
perf(kilo-chat): scope mark-read cache updates
iscekic May 2, 2026
bd31269
perf(kilo-chat): localize action pending state
iscekic May 2, 2026
03875f5
perf(notifications): skip noop badge total writes
iscekic May 2, 2026
032b12b
feat(kilo-chat): return created conversation rows
iscekic May 2, 2026
6de8bc9
feat(kilo-chat): return message page cursors
iscekic May 2, 2026
9a4de85
feat(kilo-chat): return canonical mark-read state
iscekic May 2, 2026
49233f4
fix(kilo-chat): align conversation create response
iscekic May 2, 2026
7a13c88
feat(kilo-chat): return execute-action result
iscekic May 2, 2026
aa56ee6
fix(kilo-chat): return canonical created messages
iscekic May 2, 2026
b543122
fix(kiloclaw): expose message pagination cursors
iscekic May 2, 2026
8ee532c
fix(kilo-chat): preserve message page cursors
iscekic May 2, 2026
828804b
fix(kilo-chat): scope create fallback invalidation
iscekic May 2, 2026
dbf55c2
perf(kilo-chat): return execute action fanout context
iscekic May 2, 2026
89e5771
test(kilo-chat): align response contract assertions
iscekic May 2, 2026
985212b
perf(kilo-chat): scope rename leave invalidations
iscekic May 2, 2026
4ca8be9
fix(chat): scope public chat token auth
iscekic May 2, 2026
c28a4b2
fix(events): use websocket connection tickets
iscekic May 2, 2026
6253346
refactor(kilo-chat-hooks): normalize message page cache
iscekic May 2, 2026
8e19049
refactor(kilo-chat-hooks): share conversation list event handling
iscekic May 2, 2026
8f7a960
refactor(kilo-chat-hooks): share mark-read retry helpers
iscekic May 2, 2026
985788f
refactor(kilo-chat): share bot status hook
iscekic May 2, 2026
483b730
test(kilo-chat-hooks): consolidate helper coverage
iscekic May 2, 2026
3ac292b
fix(kiloclaw): align image hash inputs
iscekic May 2, 2026
7ebb435
fix(kiloclaw): hash local OpenClaw images
iscekic May 2, 2026
6794b6f
fix(kiloclaw): preserve local OpenClaw image mode
iscekic May 2, 2026
232599e
fix(kiloclaw): include image mode in dev handoff
iscekic May 2, 2026
1d786bb
fix(kiloclaw): include dockerignore in image hashes
iscekic May 2, 2026
abcf263
fix(kilo-chat): validate event fanout payloads
iscekic May 2, 2026
5739258
fix(web): invalidate conversation status on reconnect
iscekic May 2, 2026
056a417
fix(event-service): allow local web connect tickets
iscekic May 2, 2026
fb4d714
fix(mobile): subscribe chat routes to instance events
iscekic May 2, 2026
220c2b8
fix(notifications): validate chat push rpc payloads
iscekic May 2, 2026
89b1588
fix(notifications): retry transient expo push failures
iscekic May 2, 2026
257f337
fix(mobile): reconcile native badge on hydration
iscekic May 2, 2026
eec6b41
fix(mobile): update chat stack route registration
iscekic May 2, 2026
3a6c6bf
fix(notifications): surface expo ticket errors
iscekic May 2, 2026
5866996
fix(notifications): make no-token dispatch terminal
iscekic May 2, 2026
1bd151e
fix(notifications): surface lifecycle ticket errors
iscekic May 2, 2026
13fb628
fix(notifications): report expo receipt errors
iscekic May 2, 2026
4e1fa1d
fix(notifications): report all-stale chat pushes
iscekic May 2, 2026
c1c1996
fix(notifications): terminalize partial ticket failures
iscekic May 2, 2026
14bc95f
fix(mobile): show message pagination loader only while fetching
iscekic May 2, 2026
a3f4fff
fix(web): guard kilo chat conversation sandbox
iscekic May 2, 2026
b71b589
fix(web): preserve kilo chat scroll anchor
iscekic May 2, 2026
6ba8ee7
fix(kilo-chat): seed cold message cache on send
iscekic May 2, 2026
1dfb0c7
fix(kilo-chat): refetch cold send history
iscekic May 2, 2026
d2b4402
fix(kilo-chat): patch renamed conversation detail
iscekic May 2, 2026
46f97e7
fix(web): preserve composer after send failure
iscekic May 2, 2026
7716279
fix(web): preserve kilo chat status errors
iscekic May 2, 2026
f90e2b9
fix(web): preserve pending chat drafts
iscekic May 2, 2026
393b17d
fix(kilo-chat): preserve sidebar state on leave rollback
iscekic May 2, 2026
06441f1
fix(notifications): trust typed rpc inputs
iscekic May 2, 2026
96d024e
fix(kilo-chat): trust event rpc payloads
iscekic May 2, 2026
bc4046f
fix(kiloclaw): trust chat webhook rpc input
iscekic May 2, 2026
590b0e8
fix(web): trust kilo chat token output
iscekic May 2, 2026
ba297c0
fix(kilo-chat): reject invalid delivery failure bodies
iscekic May 2, 2026
b97412c
fix(kiloclaw): type kilo-chat request bodies
iscekic May 2, 2026
4a6f54e
fix(kilo-chat): type client request payloads
iscekic May 2, 2026
4c7904a
fix(event-service): validate connect ticket responses
iscekic May 2, 2026
ea117dd
fix(event-service): type websocket messages
iscekic May 2, 2026
ff1611a
fix(kilo-chat): type notification rpc payloads
iscekic May 2, 2026
99db623
fix(event-service): type ticket mint requests
iscekic May 2, 2026
e8193a1
fix(event-service): validate connect ticket query
iscekic May 2, 2026
cc7ef16
fix(event-service): schema-check ticket consume responses
iscekic May 2, 2026
709abf3
fix(kilo-chat): type mark-read success responses
iscekic May 2, 2026
06d625d
fix(kilo-chat): validate action failure group ids
iscekic May 2, 2026
2575d82
fix(kilo-chat): return empty accepted action failures
iscekic May 2, 2026
786e0db
fix(kiloclaw): type plugin typing requests
iscekic May 2, 2026
0524e46
fix(kiloclaw): type chat webhook forwards
iscekic May 2, 2026
a9ce2e7
fix(event-service): share connect ticket query schema
iscekic May 3, 2026
15a3536
fix(kilo-chat): return empty bot status nudge acks
iscekic May 3, 2026
f1b2a20
fix(kilo-chat): return empty delivery failure acks
iscekic May 3, 2026
2cd9c1b
fix(web): route claw chat to kilo chat
iscekic May 3, 2026
9e1782c
fix(dev-env): sync local secrets store bindings
iscekic May 3, 2026
0cf7360
fix(event-service): align local auth env
iscekic May 3, 2026
960094f
refactor(event-service): use RPC for connection tickets
iscekic May 3, 2026
12b5b4c
fix(event-service): reconnect pre-open socket failures
iscekic May 3, 2026
c2e09a2
fix(kilo-chat): surface badge clear failures
iscekic May 3, 2026
e666160
fix(kilo-chat): return ok for void successes
iscekic May 3, 2026
33dbb61
fix(kilo-chat-hooks): refetch incomplete activity reorders
iscekic May 3, 2026
f210b16
fix(notifications): omit tokens from ticket errors
iscekic May 3, 2026
98586b9
fix(web): gate org chat layout server-side
iscekic May 3, 2026
8c9e8c8
fix(web): apply billing wrapper to personal chat
iscekic May 3, 2026
08d3cdf
fix(env-sync): resolve suffixed local secret sources
iscekic May 3, 2026
0212c49
fix(web): show chat creation progress
iscekic May 3, 2026
bb7ccc7
fix(mobile): recover kilo chat user id after token retry
iscekic May 3, 2026
b361e13
fix(mobile): separate chat list loading states
iscekic May 3, 2026
6b48adc
fix(mobile): gate chat history initial load
iscekic May 3, 2026
272407b
fix(mobile): guard chat route sandbox mismatches
iscekic May 3, 2026
25d646f
fix(mobile): persist focused kilo chat sandbox
iscekic May 3, 2026
8a02d6b
fix(kilo-chat): retry HTTP calls after auth refresh
iscekic May 3, 2026
a26d771
fix(event-service): stop exhausted auth reconnects
iscekic May 3, 2026
c20e15f
fix(notifications): retry transient Expo tickets
iscekic May 3, 2026
3f3c8ef
fix(env-sync): prefer exact secret sources
iscekic May 3, 2026
93b2f9d
fix(env-sync): skip exec during secret discovery
iscekic May 3, 2026
34ed5ed
fix(mobile): keep chat state types internal
iscekic May 3, 2026
4c93890
refactor(kilo-chat): share bearer auth verification
iscekic May 3, 2026
f260989
refactor(kilo-chat): share presence subscriptions
iscekic May 3, 2026
95c1842
refactor(kilo-chat): share message action policy
iscekic May 3, 2026
4727e54
test(notifications): mint badge route tokens for worker env
iscekic May 3, 2026
1e192e9
refactor(worker-utils): remove unused chat token verifier
iscekic May 3, 2026
4dc41ce
fix(kilo-chat): prevent trial banner page scroll
iscekic May 3, 2026
8dd07dd
fix(kilo-chat): refresh inactive conversation messages
iscekic May 4, 2026
5963557
fix(kiloclaw): clarify kilo chat message tool contract
iscekic May 4, 2026
e0541cf
Merge remote-tracking branch 'origin/main' into feat/kilo-chat-migrat…
iscekic May 4, 2026
619a7ed
chore(mobile): add local env example
iscekic May 4, 2026
abce63e
docs(mobile): document local env host access
iscekic May 4, 2026
9e24550
fix(dev): respect configured app url
iscekic May 4, 2026
8e68906
fix(mobile): center bottom tab labels
iscekic May 4, 2026
246fa95
fix: fix kilo-chat-hooks dependency resolution
iscekic May 4, 2026
58d93ec
fix(mobile): use expo crypto for chat client ids
iscekic May 4, 2026
21b8ba3
fix(mobile): route kiloclaw tab through instances
iscekic May 4, 2026
a6b73e4
feat(mobile): add kiloclaw instance list
iscekic May 4, 2026
ad855ea
feat(mobile): polish kilo chat conversations
iscekic May 4, 2026
ec25446
fix(mobile): preserve kilo chat drafts
iscekic May 4, 2026
3d65d1b
feat(mobile): complete kilo chat message actions
iscekic May 4, 2026
0e89e51
feat(mobile): polish kilo chat shell
iscekic May 4, 2026
7e0fe08
fix(mobile): address kiloclaw chat qa
iscekic May 4, 2026
0a79e34
fix(mobile): show greeting in home header
iscekic May 4, 2026
38817c7
fix(mobile): keep kiloclaw navigation in tabs
iscekic May 4, 2026
a4fb74a
fix(mobile): align kiloclaw tab header
iscekic May 4, 2026
21f490c
fix(mobile): hide create instance with instances
iscekic May 4, 2026
b95bafa
fix(mobile): remove invalid kiloclaw route registration
iscekic May 4, 2026
5b36707
fix(mobile): keep home tab navigation intact
iscekic May 4, 2026
b594ca0
fix(mobile): remove kiloclaw instance subtitle
iscekic May 4, 2026
01a3772
fix(mobile): hide kiloclaw section counts
iscekic May 4, 2026
5062203
fix(mobile): remove kiloclaw current marker
iscekic May 4, 2026
075dce1
fix(mobile): show agent identity in kiloclaw rows
iscekic May 4, 2026
52e38d4
fix(mobile): make kiloclaw conversation list route match
iscekic May 4, 2026
f4043c2
fix(mobile): polish kilo chat conversation list
iscekic May 4, 2026
f50d05c
fix(mobile): add full-page pull refresh
iscekic May 4, 2026
a0902cf
fix(mobile): hide refresh spinner during polling
iscekic May 4, 2026
05279bf
fix(mobile): show bot name in chat header
iscekic May 4, 2026
8228d9d
fix(mobile): title instance switcher by bot
iscekic May 4, 2026
583b1ae
fix(mobile): move kilo chat rename route
iscekic May 4, 2026
838de70
fix(mobile): improve kilo chat list actions
iscekic May 4, 2026
a94c11b
fix(mobile): polish kilo chat composer layout
iscekic May 4, 2026
a940e4f
fix(mobile): match kilo chat composer shape
iscekic May 4, 2026
d9fe03c
fix(mobile): float kilo chat composer
iscekic May 4, 2026
af540c3
fix(mobile): restore kilo chat composer background
iscekic May 4, 2026
c16a8f4
fix(mobile): center kilo chat composer text
iscekic May 4, 2026
5aaebea
fix(kilo-chat): avoid toSorted in message cache
iscekic May 4, 2026
e26d605
fix(mobile): improve kilo chat message display
iscekic May 4, 2026
feb6504
fix(mobile): add swipe reply for kilo chat
iscekic May 4, 2026
170731b
fix(mobile): animate kilo chat message long press
iscekic May 4, 2026
f411e78
fix(mobile): disable kilo chat message text selection
iscekic May 4, 2026
93b67b8
fix(mobile): shorten kilo chat reaction actions
iscekic May 4, 2026
df62687
fix(mobile): preserve back gesture in kilo chat
iscekic May 4, 2026
b1f237b
docs(kiloclaw): note approval ownership invariant
iscekic May 5, 2026
1a4090b
docs(kiloclaw): explain resolved approval skip
iscekic May 5, 2026
a95d938
fix(kiloclaw): validate webhook sandbox ids
iscekic May 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .agents/skills/kilo-design/reference/ux-writing.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ expectations: `Provisioning machine. This usually takes 30–60 seconds.`
Confirm only for truly irreversible or high-stakes actions. Name the
action in both buttons:

- `Delete workspace permanently?`
Primary: `Delete workspace` (destructive variant).
- `Delete workspace permanently?`
Primary: `Delete workspace` (destructive variant).
Secondary: `Keep workspace`.

### Accessibility copy
Expand Down
13 changes: 3 additions & 10 deletions .github/workflows/deploy-kiloclaw.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ jobs:
# - container/ (COPY container/TOOLS.md → /usr/local/share/kiloclaw/)
# - plugins/kiloclaw-customizer/ (COPY plugin package for image install)
# - plugins/kilo-chat/ (COPY plugin package for image install)
# - plugins/kiloclaw-morning-briefing/ (COPY plugin package for image install)
# - openclaw-pairing-list.js, openclaw-device-pairing-list.js (COPY)
# - skills/ (COPY skills/ → /root/clawd/skills/)
#
Expand All @@ -70,16 +71,7 @@ jobs:
fi
done

CONTENT_HASH=$(
find Dockerfile controller/ container/ plugins/kiloclaw-customizer/ plugins/kilo-chat/ plugins/kiloclaw-morning-briefing/ skills/ \
openclaw-pairing-list.js openclaw-device-pairing-list.js \
-type f \
| sort \
| xargs sha256sum \
| sha256sum \
| cut -d' ' -f1 \
| cut -c1-12
)
CONTENT_HASH="$(scripts/image-content-hash.sh --hash --dockerfile Dockerfile)"

if [ -z "$CONTENT_HASH" ] || [ ${#CONTENT_HASH} -ne 12 ]; then
echo "::error::Failed to compute valid content hash"
Expand Down Expand Up @@ -412,6 +404,7 @@ jobs:
echo "FLY_IMAGE_DIGEST=${DIGEST}"
fi
echo "OPENCLAW_VERSION=${OPENCLAW}"
echo "FLY_IMAGE_CONTENT_MODE=production"
echo "FLY_IMAGE_CONTENT_HASH=${CONTENT}"
echo '```'
echo ""
Expand Down
3 changes: 3 additions & 0 deletions apps/mobile/.env
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ CLOUD_AGENT_WS_URL=wss://cloud-agent-next.kilosessions.ai
SESSION_INGEST_WS_URL=wss://ingest.kilosessions.ai
APPSFLYER_DEV_KEY=jnoVs6KzXanpbKrqXckPu9
APPSFLYER_APP_ID=6761193135
KILO_CHAT_URL=https://chat.kiloapps.io
EVENT_SERVICE_URL=wss://events.kiloapps.io
NOTIFICATIONS_URL=https://notifications.kiloapps.io
15 changes: 15 additions & 0 deletions apps/mobile/.env.local.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Client-side env vars are bundled into the app binary and are not secret.
#
# localhost works for local tooling and most simulator flows. When running on a
# physical phone, replace localhost with your development machine's LAN IP.
# On macOS, get the active LAN IP with:
# route -n get default | awk '/interface:/{print $2}' | xargs ipconfig getifaddr
API_BASE_URL=http://localhost:3000
WEB_BASE_URL=http://localhost:3000
CLOUD_AGENT_WS_URL=ws://localhost:8794
SESSION_INGEST_WS_URL=ws://localhost:8800
APPSFLYER_DEV_KEY=jnoVs6KzXanpbKrqXckPu9
APPSFLYER_APP_ID=6761193135
KILO_CHAT_URL=http://localhost:8808
EVENT_SERVICE_URL=ws://localhost:8809
NOTIFICATIONS_URL=http://localhost:8804
15 changes: 11 additions & 4 deletions apps/mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,16 @@
"dependencies": {
"@expo-google-fonts/jetbrains-mono": "^0.4.1",
"@expo/react-native-action-sheet": "^4.1.1",
"@kilocode/event-service": "workspace:*",
"@kilocode/kilo-chat": "workspace:*",
"@kilocode/kilo-chat-hooks": "workspace:*",
"@kilocode/notifications": "workspace:*",
"@kilocode/trpc": "workspace:*",
"@react-native-community/netinfo": "11.5.2",
"@rn-primitives/portal": "^1.3.0",
"@rn-primitives/slot": "^1.2.0",
"@sentry/react-native": "~7.11.0",
"@shopify/flash-list": "2.0.2",
"@tailwindcss/postcss": "^4.2.2",
"@tanstack/react-query": "catalog:",
"@trpc/client": "catalog:",
Expand All @@ -49,7 +54,6 @@
"expo-font": "~55.0.6",
"expo-haptics": "~55.0.13",
"expo-image": "~55.0.8",
"expo-image-manipulator": "~55.0.14",
"expo-image-picker": "~55.0.17",
"expo-insights": "55.0.15",
"expo-linking": "~55.0.11",
Expand Down Expand Up @@ -78,11 +82,9 @@
"react-native-svg": "15.15.3",
"react-native-worklets": "0.7.2",
"sonner-native": "^0.23.1",
"stream-chat": "catalog:",
"stream-chat-expo": "^8.13.7",
"tailwind-merge": "^3.5.0",
"tailwindcss": "^4.2.2",
"zod": "catalog:"
"ulid": "3.0.1"
},
"devDependencies": {
"@sentry/cli": "catalog:",
Expand All @@ -93,5 +95,10 @@
"typescript": "catalog:",
"vitest": "^4.1.0"
},
"dependenciesMeta": {
"@kilocode/kilo-chat-hooks": {
"injected": true
}
},
"private": true
}
24 changes: 23 additions & 1 deletion apps/mobile/src/app/(app)/(tabs)/(1_kiloclaw)/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,27 @@ export const unstable_settings = {
};

export default function KiloClawLayout() {
return <Stack screenOptions={{ headerShown: false }} />;
return (
<Stack screenOptions={{ headerShown: false }}>
<Stack.Screen name="index" />
<Stack.Screen
name="rename-conversation"
options={{
presentation: 'formSheet',
sheetAllowedDetents: [0.5],
sheetGrabberVisible: true,
headerShown: false,
}}
/>
<Stack.Screen
name="chat/instance-picker"
options={{
presentation: 'formSheet',
sheetAllowedDetents: [0.5, 1],
sheetGrabberVisible: true,
headerShown: false,
}}
/>
</Stack>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { useLocalSearchParams, useRouter } from 'expo-router';
import { useEffect } from 'react';
import { toast } from 'sonner-native';

import { ChatSandboxRouteMounts } from '@/components/kilo-chat/chat-sandbox-route-mounts';
import { ConversationScreen } from '@/components/kilo-chat/conversation-screen';
import {
getConversationRouteDecision,
getConversationRouteErrorMessage,
shouldRenderConversationScreen,
} from '@/components/kilo-chat/conversation-route-state';
import { useConversationDetail } from '@/components/kilo-chat/hooks/use-conversations';
import { useKiloChatClient } from '@/components/kilo-chat/hooks/use-kilo-chat-client';
import { chatSandboxPath } from '@/lib/kilo-chat-routes';

export default function ChatConversationRoute() {
const params = useLocalSearchParams<{ 'sandbox-id': string; 'conversation-id': string }>();
const sandboxId = params['sandbox-id'];
const conversationId = params['conversation-id'];
const router = useRouter();
const client = useKiloChatClient();
const conversationDetail = useConversationDetail(client, conversationId);
const redirectPath = chatSandboxPath(sandboxId);
const routeDecision = getConversationRouteDecision({
detail: conversationDetail,
routeSandboxId: sandboxId,
});

useEffect(() => {
if (conversationDetail.isError) {
toast.error(getConversationRouteErrorMessage(conversationDetail.error));
router.replace(redirectPath);
return;
}
if (routeDecision === 'not-found') {
toast.error('Conversation not found');
router.replace(redirectPath);
}
}, [conversationDetail.error, conversationDetail.isError, redirectPath, routeDecision, router]);

if (
!shouldRenderConversationScreen({
detail: conversationDetail,
routeSandboxId: sandboxId,
}) ||
!conversationDetail.data
) {
return null;
}

return (
<>
<ChatSandboxRouteMounts />
<ConversationScreen
sandboxId={sandboxId}
conversationId={conversationId}
conversationTitle={conversationDetail.data.title ?? 'Untitled'}
conversationRenameTitle={conversationDetail.data.title ?? ''}
conversationMembers={conversationDetail.data.members}
/>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useLocalSearchParams } from 'expo-router';

import { ChatSandboxRouteMounts } from '@/components/kilo-chat/chat-sandbox-route-mounts';
import { ConversationListScreen } from '@/components/kilo-chat/conversation-list-screen';
import { useAllKiloClawInstances } from '@/lib/hooks/use-instance-context';

export default function ChatSandboxIndex() {
const { 'sandbox-id': sandboxId } = useLocalSearchParams<{ 'sandbox-id': string }>();
const { data: instances } = useAllKiloClawInstances();
const instance = instances?.find(i => i.sandboxId === sandboxId);
const sandboxLabel =
instance?.botName ?? instance?.name ?? instance?.organizationName ?? 'KiloClaw';
return (
<>
<ChatSandboxRouteMounts />
<ConversationListScreen sandboxId={sandboxId} sandboxLabel={sandboxLabel} />
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import * as Haptics from 'expo-haptics';
import { useLocalSearchParams, useRouter } from 'expo-router';
import { Check } from 'lucide-react-native';
import { Pressable, ScrollView, View } from 'react-native';

import { StatusBadge } from '@/components/kiloclaw/status-badge';
import { QueryError } from '@/components/query-error';
import { Skeleton } from '@/components/ui/skeleton';
import { Text } from '@/components/ui/text';
import { useAllKiloClawInstances } from '@/lib/hooks/use-instance-context';
import { useThemeColors } from '@/lib/hooks/use-theme-colors';
import { kiloclawInstanceSwitcherTitle } from '@/lib/kiloclaw-display';
import { chatSandboxPath } from '@/lib/kilo-chat-routes';

export default function InstancePickerScreen() {
const router = useRouter();
const colors = useThemeColors();
const { currentId } = useLocalSearchParams<{ currentId: string }>();
const instancesQuery = useAllKiloClawInstances();
const { data: instances } = instancesQuery;

const handleSelect = (sandboxId: string) => {
void Haptics.selectionAsync();
if (sandboxId === currentId) {
router.back();
return;
}
router.dismissAll();
router.push(chatSandboxPath(sandboxId));
};

return (
<ScrollView className="flex-1 bg-background">
<View className="border-b border-border px-4 pb-3 pt-4">
<View className="h-11 flex-row items-center justify-center">
<Text className="text-lg font-semibold text-foreground">Switch Instance</Text>
<Pressable
onPress={() => {
router.back();
}}
hitSlop={8}
accessibilityRole="button"
accessibilityLabel="Done"
className="absolute right-0 rounded-full bg-secondary px-4 py-2 active:opacity-70 will-change-pressable"
>
<Text className="text-base font-medium text-foreground">Done</Text>
</Pressable>
</View>
</View>

{instancesQuery.isPending ? (
<View className="gap-3 px-4 py-4">
<Skeleton className="h-16 rounded-xl" />
<Skeleton className="h-16 rounded-xl" />
<Skeleton className="h-16 rounded-xl" />
</View>
) : null}
{instancesQuery.isError ? (
<QueryError
className="py-12"
message="Could not load instances"
onRetry={() => {
void instancesQuery.refetch();
}}
/>
) : null}
{!instancesQuery.isPending && !instancesQuery.isError
? (instances ?? []).map(instance => {
const isCurrent = instance.sandboxId === currentId;
const title = kiloclawInstanceSwitcherTitle(instance);
return (
<Pressable
key={instance.sandboxId}
className="mx-4 mt-3 min-h-16 flex-row items-center gap-3 rounded-xl border border-border bg-card px-4 py-3 active:bg-secondary will-change-pressable"
onPress={() => {
handleSelect(instance.sandboxId);
}}
accessibilityRole="button"
accessibilityLabel={`${title}${isCurrent ? ', current' : ''}`}
>
<View className="min-w-0 flex-1 gap-1">
<Text className="text-base font-semibold text-foreground" numberOfLines={1}>
{title}
</Text>
<View className="flex-row flex-wrap items-center gap-x-3 gap-y-1">
<Text variant="muted" numberOfLines={1}>
{instance.organizationName ?? 'Personal'}
</Text>
<StatusBadge status={instance.status} />
</View>
</View>
{isCurrent ? <Check size={18} color={colors.primary} /> : null}
</Pressable>
);
})
: null}
</ScrollView>
);
}
Loading