ai/at
ai/at
1
0

Compare commits

...

5 Commits

Author SHA1 Message Date
d668aa382b
fix 2025-05-05 08:34:28 +09:00
fa603e17d8
fix ozone 2025-05-05 08:22:01 +09:00
81b8b1851d
ozone 2025-05-05 08:15:49 +09:00
caae3a63df
fix 2025-04-30 00:50:06 +09:00
5b96fb3061
fix scpt 2025-04-26 17:50:28 +09:00
8 changed files with 349 additions and 68 deletions

View File

@ -67,40 +67,37 @@ services:
database:
condition: service_healthy
# ozone:
# ports:
# - 2585:3000
# build:
# context: ./repos/atproto/
# dockerfile: services/ozone/Dockerfile
# restart: always
# command: node --enable-source-maps api.js
# volumes:
# - ./data/ozone/:/data/
# - ./repos/ozone.js:/app/services/ozone/api.js:ro
# env_file:
# - ./envs/ozone
# healthcheck:
# test: "wget -q --spider http://localhost:3000/xrpc/_health"
# interval: 5s
# retries: 20
# depends_on:
# database:
# condition: service_healthy
#
# ozone-daemon:
# build:
# context: ./repos/atproto/
# dockerfile: services/ozone/Dockerfile
# restart: always
# command: node --enable-source-maps daemon.js
# env_file:
# - ./envs/ozone
# depends_on:
# ozone:
# condition: service_healthy
# database:
# condition: service_healthy
ozone:
build:
context: ./repos/atproto/
dockerfile: services/ozone/Dockerfile
ports:
- 2585:3000
restart: always
command: node --enable-source-maps api.js
volumes:
- ./data/ozone/:/data/
env_file:
- ./envs/ozone
depends_on:
database:
condition: service_healthy
ozone-daemon:
build:
context: ./repos/atproto/
dockerfile: services/ozone/Dockerfile
restart: always
command: node --enable-source-maps daemon.js
volumes:
- ./data/ozone/:/data/
env_file:
- ./envs/ozone
depends_on:
database:
condition: service_healthy
ozone:
condition: service_healthy
social-app:
ports:

View File

@ -15,6 +15,7 @@ function at-repos-env() {
https://github.com/bluesky-social/atproto
https://github.com/bluesky-social/social-app
https://github.com/bluesky-social/feed-generator
https://github.com/bluesky-social/ozone
)
d=${0:a:h}
dh=${0:a:h:h}
@ -144,9 +145,29 @@ function at-repos-social-app-patch() {
popd
}
function at-repos-ozone-patch() {
#DOMAIN=syu.is
cd $d/repos
d_=$d/repos/ozone
rm -rf ${d_}
p_=$d/patching/120-ozone-runtimeEnvVars.diff
git clone https://github.com/bluesky-social/ozone
cd ${d_}
pushd ${d_}
echo "applying patch: under ${d_} for ${p_}"
patch -p1 < ${p_}
popd
p_=$d/patching/122-ozone-enable-daemon.diff
echo "applying patch: under ${d_} for ${p_}"
pushd ${d_}
patch -p1 < ${p_}
popd
}
function at-repos-docker() {
cd $d
sudo docker compose build && sudo docker compose up -d
docker compose build && docker compose up -d
}
at-repos-env
@ -157,6 +178,7 @@ at-repos-social-app-icon-origin
at-repos-social-app-write
at-repos-bsky-patch
at-repos-social-app-patch
at-repos-ozone-patch
echo "[y]docker compose build && up"
read key

View File

@ -0,0 +1,119 @@
diff --git a/app/layout.tsx b/app/layout.tsx
index bfc3470..9350629 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -5,6 +5,7 @@ import 'yet-another-react-lightbox/styles.css'
import 'yet-another-react-lightbox/plugins/thumbnails.css'
import 'yet-another-react-lightbox/plugins/captions.css'
import { ToastContainer } from 'react-toastify'
+import { PublicEnvScript } from 'next-runtime-env';
import { Shell } from '@/shell/Shell'
import { CommandPaletteRoot } from '@/shell/CommandPalette/Root'
@@ -36,6 +37,7 @@ export default function RootLayout({
isDarkModeEnabled() ? 'dark' : ''
}`}
>
+ <head>
<title>Ozone</title>
<link
rel="icon"
@@ -43,6 +45,8 @@ export default function RootLayout({
sizes="any"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
+ <PublicEnvScript />
+ </head>
<body className="h-full overflow-hidden">
<ToastContainer
position="bottom-right"
diff --git a/environment.d.ts b/environment.d.ts
index 7a47cc2..33ab29f 100644
--- a/environment.d.ts
+++ b/environment.d.ts
@@ -9,6 +9,8 @@ declare global {
NEXT_PUBLIC_OZONE_SERVICE_DID?: string // e.g. did:plc:xxx#atproto_labeler
NEXT_PUBLIC_OZONE_PUBLIC_URL?: string // e.g. https://ozone.example.com (falls back to window.location.origin)
NEXT_PUBLIC_SOCIAL_APP_URL?: string // e.g. https://bsky.app
+ NEXT_PUBLIC_SOCIAL_APP_DOMAIN?: string // e.g. bsky.app
+ NEXT_PUBLIC_HANDLE_RESOLVER_URL?: string // e.g. https://api.bsky.app
}
}
}
diff --git a/lib/constants.ts b/lib/constants.ts
index fe7c0e8..c286ac6 100644
--- a/lib/constants.ts
+++ b/lib/constants.ts
@@ -1,29 +1,32 @@
+import { env } from 'next-runtime-env';
+
export const OAUTH_SCOPE = 'atproto transition:generic'
export const OZONE_SERVICE_DID =
- process.env.NEXT_PUBLIC_OZONE_SERVICE_DID || undefined
+ env('NEXT_PUBLIC_OZONE_SERVICE_DID') || undefined
export const OZONE_PUBLIC_URL =
- process.env.NEXT_PUBLIC_OZONE_PUBLIC_URL || undefined
+ env('NEXT_PUBLIC_OZONE_PUBLIC_URL') || undefined
export const PLC_DIRECTORY_URL =
- process.env.NEXT_PUBLIC_PLC_DIRECTORY_URL ||
+ env('NEXT_PUBLIC_PLC_DIRECTORY_URL') ||
(process.env.NODE_ENV === 'development'
? 'http://localhost:2582'
: 'https://plc.directory')
-export const QUEUE_CONFIG = process.env.NEXT_PUBLIC_QUEUE_CONFIG || '{}'
+export const QUEUE_CONFIG = env('NEXT_PUBLIC_QUEUE_CONFIG') || '{}'
-export const QUEUE_SEED = process.env.NEXT_PUBLIC_QUEUE_SEED || ''
+export const QUEUE_SEED = env('NEXT_PUBLIC_QUEUE_SEED') || ''
+export const SOCIAL_APP_DOMAIN = env('NEXT_PUBLIC_SOCIAL_APP_DOMAIN') || 'bsky.app'
export const SOCIAL_APP_URL =
- process.env.NEXT_PUBLIC_SOCIAL_APP_URL ||
+ env('NEXT_PUBLIC_SOCIAL_APP_URL') ||
(process.env.NODE_ENV === 'development'
? 'http://localhost:2584'
- : 'https://bsky.app')
+ : `https://${SOCIAL_APP_DOMAIN}`)
export const HANDLE_RESOLVER_URL =
- process.env.NEXT_PUBLIC_HANDLE_RESOLVER_URL ||
+ env('NEXT_PUBLIC_HANDLE_RESOLVER_URL') ||
(process.env.NODE_ENV === 'development'
? 'http://localhost:2584'
: 'https://api.bsky.app')
diff --git a/lib/util.ts b/lib/util.ts
index 0aa4460..ecec7d1 100644
--- a/lib/util.ts
+++ b/lib/util.ts
@@ -1,5 +1,5 @@
import { CollectionId } from '@/reports/helpers/subject'
-import { SOCIAL_APP_URL } from './constants'
+import { SOCIAL_APP_URL, SOCIAL_APP_DOMAIN } from './constants'
import { AtUri } from '@atproto/api'
export function classNames(...classes: (string | undefined)[]) {
@@ -57,7 +57,7 @@ export function takesKeyboardEvt(el?: EventTarget | null) {
)
}
-const blueSkyUrlMatcher = new RegExp('(https?://)?.*bsky.app')
+const blueSkyUrlMatcher = new RegExp('(https?://)?.*'+ `${SOCIAL_APP_DOMAIN}`)
export const isBlueSkyAppUrl = (url: string) => blueSkyUrlMatcher.test(url)
diff --git a/package.json b/package.json
index 8919841..750dce9 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
"kbar": "^0.1.0-beta.45",
"lande": "^1.0.10",
"next": "15.2.4",
+ "next-runtime-env": "^3.2.1",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-dropzone": "^14.3.5",

View File

@ -0,0 +1,82 @@
diff --git a/service/index.js b/service/index.js
index 943c281..7721cd9 100644
--- a/service/index.js
+++ b/service/index.js
@@ -1,5 +1,7 @@
const next = require('next')
-const {
+const ozone = require('@atproto/ozone')
+/*
+{
readEnv,
httpLogger,
envToCfg,
@@ -7,6 +9,7 @@ const {
OzoneService,
Database,
} = require('@atproto/ozone')
+*/
const pkg = require('@atproto/ozone/package.json')
async function main() {
@@ -16,37 +19,48 @@ async function main() {
const frontendHandler = frontend.getRequestHandler()
await frontend.prepare()
// backend
- const env = readEnv()
+ const env = ozone.readEnv()
env.version ??= pkg.version
- const config = envToCfg(env)
- const secrets = envToSecrets(env)
+ const config = ozone.envToCfg(env)
+ const secrets = ozone.envToSecrets(env)
const migrate = process.env.OZONE_DB_MIGRATE === '1'
if (migrate) {
- const db = new Database({
+ const db = new ozone.Database({
url: config.db.postgresUrl,
schema: config.db.postgresSchema,
})
await db.migrateToLatestOrThrow()
await db.close()
}
- const ozone = await OzoneService.create(config, secrets)
+ const server = await ozone.OzoneService.create(config, secrets)
// setup handlers
- ozone.app.get('/.well-known/ozone-metadata.json', (_req, res) => {
+ server.app.get('/.well-known/ozone-metadata.json', (_req, res) => {
return res.json({
- did: ozone.ctx.cfg.service.did,
- url: ozone.ctx.cfg.service.publicUrl,
- publicKey: ozone.ctx.signingKey.did(),
+ did: server.ctx.cfg.service.did,
+ url: server.ctx.cfg.service.publicUrl,
+ publicKey: server.ctx.signingKey.did(),
})
})
// Note: We must use `use()` here. This should be the last middleware.
- ozone.app.use((req, res) => {
+ server.app.use((req, res) => {
void frontendHandler(req, res, undefined)
})
// run
- const httpServer = await ozone.start()
+ const httpServer = await server.start()
+ // starts: involve ops from atproto/packages/dev-env/src/ozone.ts >>>
+ ozone.httpLogger.info('starts ozone daemon')
+ const daemon = await ozone.OzoneDaemon.create(config, secrets)
+ await daemon.start()
+ //if (process.env.OZONE_ENABLE_EVENT_REVERSER != 'true') // atproto/services/ozone/daemon.js doesn't stop eventReverser
+ //{
+ // ozone.httpLogger.info('disable ozone daemon eventReverser')
+ // await daemon.ctx.eventReverser.destroy()
+ //}
+ // ends: involve ops from atproto/packages/dev-env/src/ozone.ts <<<
+
/** @type {import('net').AddressInfo} */
const addr = httpServer.address()
- httpLogger.info(`Ozone is running at http://localhost:${addr.port}`)
+ ozone.httpLogger.info(`Ozone is running at http://localhost:${addr.port}`)
}
main().catch(console.error)

View File

@ -4,6 +4,8 @@ d=${0:a:h}
source $d/src/tag.zsh
source $d/src/func.zsh
source $d/src/ai/syui/game/character.zsh
source $d/src/is/syu/main.zsh
at-env
case $1 in
@ -38,29 +40,29 @@ case $1 in
at-profile
;;
download-character-icon)
source $d/src/ai/syui/game/character.zsh
download_character_icon
;;
create-game-character)
source $d/src/ai/syui/game/character.zsh
create_game_character
;;
create-game-user)
source $d/src/ai/syui/game/character.zsh
create_game_user $2
;;
create-item)
source $d/src/ai/syui/game/character.zsh
create_item
create-system)
create_system
;;
get-game-user)
source $d/src/ai/syui/game/character.zsh
get_game_user $2
;;
delete-game-user)
source $d/src/ai/syui/game/character.zsh
delete_game_user $2 $3
;;
verify-icon)
verify-icon
;;
self-col)
self-col
;;
*)
echo "${help[@]}"
echo "${host[@]}"

View File

@ -210,6 +210,7 @@ delete_game_user() {
req=com.atproto.repo.DeleteRecord
url=https://$pds/xrpc/$req
repo=$did
#repo=did:plc:6qyecktefllvenje24fcxnie
json="{\"collection\":\"$col\", \"rkey\":\"$rkey\", \"repo\":\"$repo\"}"
echo $json
curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d $json $url
@ -218,9 +219,12 @@ delete_game_user() {
function create_game_user() {
col=ai.syui.game
rkey=$1
did=$did_yui
handle=$handle_yui
pds=bsky.social
did=$did
handle=$handle
pds=`cat $f|jq -r ".didDoc.service.[].serviceEndpoint"|cut -d / -f 3`
if [ "$pds" != "syu.is" ];then
pds=bsky.social
fi
version=4
#rkey=syui
#img=https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:4hqjfn7m6n5hno3doamuhgef/bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy@jpeg
@ -282,8 +286,8 @@ function create_game_user() {
v1_json="
{
\"repo\": \"$handle_yui\",
\"did\": \"$did_yui\",
\"repo\": \"$handle\",
\"did\": \"$did\",
\"collection\": \"$col\",
\"rkey\": \"$rkey\",
\"record\": {
@ -309,8 +313,8 @@ json_item="
json="
{
\"repo\": \"$handle_yui\",
\"did\": \"$did_yui\",
\"repo\": \"$handle\",
\"did\": \"$did\",
\"collection\": \"$col\",
\"rkey\": \"$rkey\",
\"record\": {
@ -350,32 +354,41 @@ if echo $json|jq . ;then
fi
}
function create_item() {
col=ai.syui.item
function create_system() {
col=ai.syui.system
rkey=self
did=$did_yui
handle=$handle_yui
pds=bsky.social
did=$did
handle=$handle
pds=`cat $f|jq -r ".didDoc.service.[].serviceEndpoint"|cut -d / -f 3`
if [ "$pds" != "syu.is" ];then
pds=bsky.social
fi
version=1
#rkey=syui
#img=https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:4hqjfn7m6n5hno3doamuhgef/bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy@jpeg
req=com.atproto.repo.putRecord
url=https://$pds/xrpc/$req
cid=bafkreia3huw2gdenqatoobx3hcft74chced46bw4znfgepo5aenegobkri
imguri=https://cdn.bsky.app/img/feed_thumbnail/plain/$did_yui/${cid}@jpeg
imgurl=https://git.syui.ai/ai/ai/raw/branch/main/item/
#cid=bafkreia3huw2gdenqatoobx3hcft74chced46bw4znfgepo5aenegobkri
#imguri=https://cdn.bsky.app/img/feed_thumbnail/plain/$did_yui/${cid}@jpeg
imgurl=https://git.syui.ai/ai/ai/raw/branch/main/img/item/card
json_card=" \"id\": $id, \"name\": \"$name\", \"img\": \"${imgurl}/${id}.webp\""
json_card=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/item/card.json|jq .`
json_weapon=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/item/weapon.json|jq .`
json_card=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/card.json|jq ".[]"`
json_weapon=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/weapon.json|jq ".[]"`
json_system=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/system.json|jq ".[]"`
json_character=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/character.json|jq ".[]"`
json_ability=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/ability.json|jq ".[]"`
json="
{
\"repo\": \"$handle_yui\",
\"did\": \"$did_yui\",
\"repo\": \"$handle\",
\"did\": \"$did\",
\"collection\": \"$col\",
\"rkey\": \"$rkey\",
\"record\": {
\"card\": ${json_card},
\"weapon\": ${json_weapon},
\"system\": ${json_system},
\"character\": ${json_character},
\"ability\": ${json_ability},
\"createdAt\": \"${created}\",
\"updatedAt\": \"${created}\"
}

View File

@ -8,21 +8,25 @@ function at-env() {
did_syui=did:plc:uqzpqmrjnptsxezjx4xuh2mn
handle=$handle_yui
did=$did_yui
created=2020-01-01T00:00:00+09:00
at_uri=at://$did_yui/ai.syui.game.user/syui
created=2025-04-21T00:00:00.323Z
docs_uri=https://docs.bsky.app/docs/api
did=`echo $at_uri|cut -d / -f 3`
collection=`echo $at_uri|cut -d / -f 4`
rkey=`echo $at_uri|cut -d / -f 5`
d=${0:a:h}
f=~/.config/ai/token.json
if [ -f $f ];then
host=`cat $f|jq -r ".didDoc.service.[].serviceEndpoint"`
host=`cat $f|jq -r ".didDoc.service.[].serviceEndpoint"|cut -d / -f 3`
token=`cat $f|jq -r .accessJwt`
did=`cat $f|jq -r .did`
handle=`cat $f|jq -r .handle`
actor=$did
fi
if [ "$host" = "syu.is" ];then
plc=plc.syu.is
pds=$host
fi
at_uri=at://$handle/ai.syui.game/ai
did=`echo $at_uri|cut -d / -f 3`
collection=`echo $at_uri|cut -d / -f 4`
rkey=`echo $at_uri|cut -d / -f 5`
}
function at-unset() {
@ -173,3 +177,32 @@ function at-profile() {
url="${host}${req}?actor=$did"
curl -sL -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $token" $url|jq .
}
function verify-icon() {
syuisadmin_handle=ai.syu.is
syuisadmin_did=did:plc:6qyecktefllvenje24fcxnie
#rkey=
col=app.bsky.graph.verification
handle=syui.syu.is
subject=did:plc:vzsvtbtbnwn22xjqhcu3vd6y
displayName=syui
req=/xrpc/com.atproto.repo.createRecord
url=${host}${req}
json="
{
\"repo\": \"$syuisadmin_handle\",
\"did\": \"$syuisadmin_did\",
\"collection\": \"$col\",
\"record\": {
\"subject\": \"$subject\",
\"handle\": \"$handle\",
\"displayName\": \"$displayName\",
\"createdAt\": \"${created}\"
}
}"
if echo $json|jq . ;then
t=`curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d $json $url`
echo $t
fi
}

13
scpt/src/is/syu/main.zsh Normal file
View File

@ -0,0 +1,13 @@
#!/bin/zsh
function self-col(){
col=(
ai.syui.game
ai.syui.system
)
e=${col[@]: -1}
for i in $col; do
t=`curl -sL "$pds/xrpc/com.atproto.repo.listRecords?repo=$handle&collection=$i"`
echo $t|jq .
done
}