@kyoofus/kyoflow 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/.env.example +4 -0
- package/dist/backend/pyproject.toml +19 -0
- package/dist/backend/requirements.txt +2 -0
- package/dist/backend/src/kyoflow/__init__.py +12 -0
- package/dist/backend/src/kyoflow/__main__.py +88 -0
- package/dist/backend/src/kyoflow/__pycache__/__init__.cpython-314.pyc +0 -0
- package/dist/backend/src/kyoflow/__pycache__/__main__.cpython-314.pyc +0 -0
- package/dist/backend/src/kyoflow/__pycache__/main.cpython-314.pyc +0 -0
- package/dist/backend/src/kyoflow/main.py +63 -0
- package/dist/cli.js +178 -0
- package/dist/cli.js.map +1 -0
- package/dist/postinstall.js +18 -0
- package/dist/postinstall.js.map +1 -0
- package/dist/server.js +31 -0
- package/dist/server.js.map +1 -0
- package/dist/web/client/_app/immutable/assets/0.BrmKgNLm.css +1 -0
- package/dist/web/client/_app/immutable/assets/0.BrmKgNLm.css.br +0 -0
- package/dist/web/client/_app/immutable/assets/0.BrmKgNLm.css.gz +0 -0
- package/dist/web/client/_app/immutable/assets/3.DVH1XF8v.css +1 -0
- package/dist/web/client/_app/immutable/assets/3.DVH1XF8v.css.br +0 -0
- package/dist/web/client/_app/immutable/assets/3.DVH1XF8v.css.gz +0 -0
- package/dist/web/client/_app/immutable/assets/4.zbKoyNjI.css +1 -0
- package/dist/web/client/_app/immutable/assets/4.zbKoyNjI.css.br +0 -0
- package/dist/web/client/_app/immutable/assets/4.zbKoyNjI.css.gz +0 -0
- package/dist/web/client/_app/immutable/assets/5.CHnq1Bst.css +1 -0
- package/dist/web/client/_app/immutable/assets/5.CHnq1Bst.css.br +0 -0
- package/dist/web/client/_app/immutable/assets/5.CHnq1Bst.css.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/44EpIQ4d.js +1 -0
- package/dist/web/client/_app/immutable/chunks/44EpIQ4d.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/44EpIQ4d.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/B09fC2bi.js +1 -0
- package/dist/web/client/_app/immutable/chunks/B09fC2bi.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/B09fC2bi.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/BJ-VzAMM.js +1 -0
- package/dist/web/client/_app/immutable/chunks/BJ-VzAMM.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/BJ-VzAMM.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/B_AmmRQN.js +1 -0
- package/dist/web/client/_app/immutable/chunks/B_AmmRQN.js.br +2 -0
- package/dist/web/client/_app/immutable/chunks/B_AmmRQN.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/C63Z97y6.js +1 -0
- package/dist/web/client/_app/immutable/chunks/C63Z97y6.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/C63Z97y6.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/C_EPgsy6.js +1 -0
- package/dist/web/client/_app/immutable/chunks/C_EPgsy6.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/C_EPgsy6.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/Ck1fWG4n.js +1 -0
- package/dist/web/client/_app/immutable/chunks/Ck1fWG4n.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/Ck1fWG4n.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/D8fmz15L.js +1 -0
- package/dist/web/client/_app/immutable/chunks/D8fmz15L.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/D8fmz15L.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/DDNuMsfB.js +1 -0
- package/dist/web/client/_app/immutable/chunks/DDNuMsfB.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/DDNuMsfB.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/Da9oKyxb.js +1 -0
- package/dist/web/client/_app/immutable/chunks/Da9oKyxb.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/Da9oKyxb.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/DtmuEK64.js +1 -0
- package/dist/web/client/_app/immutable/chunks/DtmuEK64.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/DtmuEK64.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/EmrU7Abi.js +298 -0
- package/dist/web/client/_app/immutable/chunks/EmrU7Abi.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/EmrU7Abi.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/PPVm8Dsz.js +1 -0
- package/dist/web/client/_app/immutable/chunks/PPVm8Dsz.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/PPVm8Dsz.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/ZW9ZwxRj.js +2 -0
- package/dist/web/client/_app/immutable/chunks/ZW9ZwxRj.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/ZW9ZwxRj.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/b2dyOoG8.js +1 -0
- package/dist/web/client/_app/immutable/chunks/b2dyOoG8.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/b2dyOoG8.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/dKdRdI5_.js +2 -0
- package/dist/web/client/_app/immutable/chunks/dKdRdI5_.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/dKdRdI5_.js.gz +0 -0
- package/dist/web/client/_app/immutable/chunks/z6vZsXi_.js +1 -0
- package/dist/web/client/_app/immutable/chunks/z6vZsXi_.js.br +0 -0
- package/dist/web/client/_app/immutable/chunks/z6vZsXi_.js.gz +0 -0
- package/dist/web/client/_app/immutable/entry/app.CY5BI3xj.js +2 -0
- package/dist/web/client/_app/immutable/entry/app.CY5BI3xj.js.br +0 -0
- package/dist/web/client/_app/immutable/entry/app.CY5BI3xj.js.gz +0 -0
- package/dist/web/client/_app/immutable/entry/start.DtRSN8RT.js +1 -0
- package/dist/web/client/_app/immutable/entry/start.DtRSN8RT.js.br +2 -0
- package/dist/web/client/_app/immutable/entry/start.DtRSN8RT.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/0.D-FNblRd.js +1 -0
- package/dist/web/client/_app/immutable/nodes/0.D-FNblRd.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/0.D-FNblRd.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/1.D4Y_4dgV.js +1 -0
- package/dist/web/client/_app/immutable/nodes/1.D4Y_4dgV.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/1.D4Y_4dgV.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/2.B5eVU3OO.js +1 -0
- package/dist/web/client/_app/immutable/nodes/2.B5eVU3OO.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/2.B5eVU3OO.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/3.CLx1_dgI.js +1 -0
- package/dist/web/client/_app/immutable/nodes/3.CLx1_dgI.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/3.CLx1_dgI.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/4.B2lLNz3B.js +61 -0
- package/dist/web/client/_app/immutable/nodes/4.B2lLNz3B.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/4.B2lLNz3B.js.gz +0 -0
- package/dist/web/client/_app/immutable/nodes/5.DVjHkNQz.js +1 -0
- package/dist/web/client/_app/immutable/nodes/5.DVjHkNQz.js.br +0 -0
- package/dist/web/client/_app/immutable/nodes/5.DVjHkNQz.js.gz +0 -0
- package/dist/web/client/_app/version.json +1 -0
- package/dist/web/client/_app/version.json.br +0 -0
- package/dist/web/client/_app/version.json.gz +0 -0
- package/dist/web/client/robots.txt +3 -0
- package/dist/web/env.js +94 -0
- package/dist/web/handler.js +1435 -0
- package/dist/web/index.js +345 -0
- package/dist/web/kyoflow.mjs +21 -0
- package/dist/web/scripts/ecosystem.config.cjs +54 -0
- package/dist/web/scripts/run-node.mjs +158 -0
- package/dist/web/scripts/startDev.mjs +64 -0
- package/dist/web/server/chunks/0-CyAFthPc.js +9 -0
- package/dist/web/server/chunks/0-CyAFthPc.js.map +1 -0
- package/dist/web/server/chunks/1-DYCRQF-y.js +9 -0
- package/dist/web/server/chunks/1-DYCRQF-y.js.map +1 -0
- package/dist/web/server/chunks/2-BMUiKlN4.js +9 -0
- package/dist/web/server/chunks/2-BMUiKlN4.js.map +1 -0
- package/dist/web/server/chunks/3-BHJbC3kl.js +9 -0
- package/dist/web/server/chunks/3-BHJbC3kl.js.map +1 -0
- package/dist/web/server/chunks/4-kguK6pdz.js +9 -0
- package/dist/web/server/chunks/4-kguK6pdz.js.map +1 -0
- package/dist/web/server/chunks/5-Cg1lR31m.js +9 -0
- package/dist/web/server/chunks/5-Cg1lR31m.js.map +1 -0
- package/dist/web/server/chunks/_layout.svelte-Dk-_4d6Q.js +15 -0
- package/dist/web/server/chunks/_layout.svelte-Dk-_4d6Q.js.map +1 -0
- package/dist/web/server/chunks/_page.svelte-Clor3HA3.js +19 -0
- package/dist/web/server/chunks/_page.svelte-Clor3HA3.js.map +1 -0
- package/dist/web/server/chunks/_page.svelte-D5WvBH3m.js +6 -0
- package/dist/web/server/chunks/_page.svelte-D5WvBH3m.js.map +1 -0
- package/dist/web/server/chunks/_page.svelte-D7hhqLhW.js +90 -0
- package/dist/web/server/chunks/_page.svelte-D7hhqLhW.js.map +1 -0
- package/dist/web/server/chunks/_page.svelte-DDxnQ3X4.js +71 -0
- package/dist/web/server/chunks/_page.svelte-DDxnQ3X4.js.map +1 -0
- package/dist/web/server/chunks/context-CKR25gbz.js +90 -0
- package/dist/web/server/chunks/context-CKR25gbz.js.map +1 -0
- package/dist/web/server/chunks/error.svelte-BLEcYUzd.js +12 -0
- package/dist/web/server/chunks/error.svelte-BLEcYUzd.js.map +1 -0
- package/dist/web/server/chunks/exports-k9UzK37u.js +303 -0
- package/dist/web/server/chunks/exports-k9UzK37u.js.map +1 -0
- package/dist/web/server/chunks/index-DjKos2HY.js +1362 -0
- package/dist/web/server/chunks/index-DjKos2HY.js.map +1 -0
- package/dist/web/server/chunks/index2-CxBujh0K.js +43 -0
- package/dist/web/server/chunks/index2-CxBujh0K.js.map +1 -0
- package/dist/web/server/index.js +7832 -0
- package/dist/web/server/index.js.map +1 -0
- package/dist/web/server/manifest.js +70 -0
- package/dist/web/server/manifest.js.map +1 -0
- package/dist/web/shims.js +32 -0
- package/package.json +37 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Peter Steinberger
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "wendy-backend"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Python FastAPI backend for Wendy"
|
|
5
|
+
dependencies = [
|
|
6
|
+
"fastapi>=0.115.8",
|
|
7
|
+
"langchain-core>=1.2.14",
|
|
8
|
+
"langchain-openai>=1.1.10",
|
|
9
|
+
"langchain[google-genai]>=1.2.10",
|
|
10
|
+
"langgraph>=1.0.9",
|
|
11
|
+
"loguru>=0.7.3",
|
|
12
|
+
"openai>=2.21.0",
|
|
13
|
+
"python-box>=7.3.2",
|
|
14
|
+
"python-dotenv>=1.2.1",
|
|
15
|
+
"uvicorn>=0.34.0",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[tool.uv]
|
|
19
|
+
managed = true
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Optionally expose other important items at package level
|
|
2
|
+
# __all__ = ["__main__", "app"]
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
from .__main__ import main as entrypoint_main
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# uv run kyoflow 명령어로 실행할 때, 이 main() 함수가 호출됩니다.
|
|
9
|
+
def main():
|
|
10
|
+
"""Main entry point for the package."""
|
|
11
|
+
|
|
12
|
+
entrypoint_main()
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import uvicorn
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
from box import Box
|
|
5
|
+
from loguru import logger
|
|
6
|
+
import platform
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def find_workspace_root() -> Path | None:
|
|
11
|
+
current = Path(__file__).resolve().parent
|
|
12
|
+
while current != current.parent:
|
|
13
|
+
if (current / "pnpm-workspace.yaml").exists():
|
|
14
|
+
return current
|
|
15
|
+
current = current.parent
|
|
16
|
+
return None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# -----------------------------------------------------------------------------------------------
|
|
20
|
+
# python -m kyoflow로 실행
|
|
21
|
+
# 패키지 내부에 있는 __main__.py의 main() 함수를 호출하여 실행하도록 설정
|
|
22
|
+
# python -m kyoflow는 파이썬의 모듈 실행 플래그를 사용하는 방식
|
|
23
|
+
def main():
|
|
24
|
+
"""Main entry point for the package."""
|
|
25
|
+
|
|
26
|
+
workspace_root = find_workspace_root()
|
|
27
|
+
app_base_path = workspace_root if workspace_root else Path.home() / ".kyoflow"
|
|
28
|
+
logs_dir = app_base_path / "logs"
|
|
29
|
+
app_base_path.mkdir(parents=True, exist_ok=True)
|
|
30
|
+
logs_dir.mkdir(parents=True, exist_ok=True)
|
|
31
|
+
|
|
32
|
+
logger.remove()
|
|
33
|
+
logger.add(
|
|
34
|
+
logs_dir / "backend.log",
|
|
35
|
+
level="INFO",
|
|
36
|
+
rotation="10 MB",
|
|
37
|
+
retention=10,
|
|
38
|
+
enqueue=True,
|
|
39
|
+
)
|
|
40
|
+
logger.add(sys.stderr, level="INFO")
|
|
41
|
+
|
|
42
|
+
os.environ["APP_BASE_PATH"] = str(app_base_path)
|
|
43
|
+
logger.info(f"Runtime mode: {'development' if workspace_root else 'installed'}")
|
|
44
|
+
logger.info(f"App base path set to: {app_base_path}")
|
|
45
|
+
|
|
46
|
+
app_env = os.environ["APP_ENV"] if "APP_ENV" in os.environ else "development"
|
|
47
|
+
logger.info(f'APP_ENV: {os.environ.get("APP_ENV", "development")}')
|
|
48
|
+
|
|
49
|
+
env_file_path = app_base_path / ".env"
|
|
50
|
+
if env_file_path.exists():
|
|
51
|
+
from dotenv import load_dotenv
|
|
52
|
+
|
|
53
|
+
load_dotenv(str(env_file_path), override=True)
|
|
54
|
+
logger.info(f"Loaded environment variables from {env_file_path}")
|
|
55
|
+
logger.info(
|
|
56
|
+
f'OPENAI_API_KEY: {"set" if os.environ.get("OPENAI_API_KEY") else "not set"}'
|
|
57
|
+
)
|
|
58
|
+
else:
|
|
59
|
+
logger.warning(f"Env file not found: {env_file_path}")
|
|
60
|
+
|
|
61
|
+
logger.info("Starting server...")
|
|
62
|
+
logger.info(f"platform.system(): {platform.system()}")
|
|
63
|
+
|
|
64
|
+
# 'Windows', 'Linux', 'Darwin' (macOS)
|
|
65
|
+
|
|
66
|
+
app_port = os.environ["APP_PORT"] if "APP_PORT" in os.environ else 8000
|
|
67
|
+
uvicorn_config = Box(
|
|
68
|
+
{
|
|
69
|
+
# package.module:FastAPI_인스턴스_이름
|
|
70
|
+
# src/kyoflow/main.py 의 app 인스턴스를 가리킴
|
|
71
|
+
"app_path": "kyoflow.main:app",
|
|
72
|
+
"host": "0.0.0.0",
|
|
73
|
+
"port": int(app_port),
|
|
74
|
+
}
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
uvicorn.run(
|
|
78
|
+
uvicorn_config.app_path, host=uvicorn_config.host, port=uvicorn_config.port
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# -----------------------------------------------------------------------------------------------
|
|
83
|
+
# Optionally expose other important items at package level
|
|
84
|
+
# __all__ = ["main", "app"]
|
|
85
|
+
|
|
86
|
+
if __name__ == "__main__":
|
|
87
|
+
"""uv run python -m kyoflow.__init__"""
|
|
88
|
+
main()
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from fastapi import APIRouter, FastAPI, HTTPException
|
|
3
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
4
|
+
from fastapi.responses import StreamingResponse
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
from langchain_openai import ChatOpenAI
|
|
7
|
+
from langchain_core.messages import HumanMessage
|
|
8
|
+
|
|
9
|
+
app = FastAPI()
|
|
10
|
+
|
|
11
|
+
app.add_middleware(
|
|
12
|
+
CORSMiddleware,
|
|
13
|
+
allow_origins=["*"],
|
|
14
|
+
allow_credentials=True,
|
|
15
|
+
allow_methods=["*"],
|
|
16
|
+
allow_headers=["*"],
|
|
17
|
+
)
|
|
18
|
+
import uvicorn
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
router = APIRouter()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", "")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@router.get("/hello_world")
|
|
28
|
+
def hello_world():
|
|
29
|
+
return {"message": "hello_world"}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class LlmStreamRequest(BaseModel):
|
|
33
|
+
message: str
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _stream_llm_response(message: str):
|
|
37
|
+
llm = ChatOpenAI(model="gpt-5-nano", streaming=True, openai_api_key=OPENAI_API_KEY)
|
|
38
|
+
for chunk in llm.stream([HumanMessage(content=message)]):
|
|
39
|
+
if chunk.content:
|
|
40
|
+
yield chunk.content
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@router.post("/llm/stream")
|
|
44
|
+
async def llm_stream(req: LlmStreamRequest):
|
|
45
|
+
if not req.message.strip():
|
|
46
|
+
raise HTTPException(status_code=400, detail="message is required")
|
|
47
|
+
|
|
48
|
+
return StreamingResponse(
|
|
49
|
+
_stream_llm_response(req.message),
|
|
50
|
+
media_type="text/plain; charset=utf-8",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
app.include_router(router)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def run() -> None:
|
|
58
|
+
app_port = int(os.environ.get("APP_PORT", os.environ.get("BACKEND_PORT", "8000")))
|
|
59
|
+
uvicorn.run("kyoflow.main:app", host="0.0.0.0", port=app_port)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
if __name__ == "__main__":
|
|
63
|
+
run()
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import { spawn, execFileSync } from "child_process";
|
|
6
|
+
import path from "path";
|
|
7
|
+
import fs from "fs";
|
|
8
|
+
import os from "os";
|
|
9
|
+
import chalk from "chalk";
|
|
10
|
+
import { fileURLToPath } from "url";
|
|
11
|
+
import dotenv from "dotenv";
|
|
12
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
var __dirname = path.dirname(__filename);
|
|
14
|
+
function findProjectRoot() {
|
|
15
|
+
let current = __dirname;
|
|
16
|
+
while (path.dirname(current) !== current) {
|
|
17
|
+
if (fs.existsSync(path.join(current, "pnpm-workspace.yaml"))) {
|
|
18
|
+
return { root: current, isDev: true };
|
|
19
|
+
}
|
|
20
|
+
current = path.dirname(current);
|
|
21
|
+
}
|
|
22
|
+
return { root: __dirname, isDev: false };
|
|
23
|
+
}
|
|
24
|
+
var { root: PROJECT_ROOT, isDev: IS_DEV } = findProjectRoot();
|
|
25
|
+
var KYOFLOW_DIR = path.join(os.homedir(), ".kyoflow");
|
|
26
|
+
var KYOFLOW_ENV_FILE = path.join(KYOFLOW_DIR, ".env");
|
|
27
|
+
var KYOFLOW_ENV_EXAMPLE_FILE = path.join(KYOFLOW_DIR, ".env.example");
|
|
28
|
+
var KYOFLOW_VENV_PATH = path.join(KYOFLOW_DIR, ".venv");
|
|
29
|
+
var PID_FILE = path.join(KYOFLOW_DIR, "daemon.json");
|
|
30
|
+
function ensureRuntimeDirectory() {
|
|
31
|
+
if (!fs.existsSync(KYOFLOW_DIR)) {
|
|
32
|
+
fs.mkdirSync(KYOFLOW_DIR, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function ensureEnvExampleFile() {
|
|
36
|
+
if (fs.existsSync(KYOFLOW_ENV_EXAMPLE_FILE)) return;
|
|
37
|
+
const envExampleCandidates = [
|
|
38
|
+
path.join(PROJECT_ROOT, ".env.example"),
|
|
39
|
+
path.join(__dirname, ".env.example")
|
|
40
|
+
];
|
|
41
|
+
for (const src of envExampleCandidates) {
|
|
42
|
+
if (fs.existsSync(src)) {
|
|
43
|
+
fs.copyFileSync(src, KYOFLOW_ENV_EXAMPLE_FILE);
|
|
44
|
+
console.log(chalk.yellow(`Copied .env.example to ${KYOFLOW_ENV_EXAMPLE_FILE}`));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
console.log(chalk.yellow("Warning: .env.example template was not found in package artifacts."));
|
|
49
|
+
}
|
|
50
|
+
function ensureRuntimeEnvFile() {
|
|
51
|
+
if (fs.existsSync(KYOFLOW_ENV_FILE)) return;
|
|
52
|
+
if (!fs.existsSync(KYOFLOW_ENV_EXAMPLE_FILE)) {
|
|
53
|
+
console.log(chalk.yellow(`Warning: ${KYOFLOW_ENV_EXAMPLE_FILE} not found; cannot create ${KYOFLOW_ENV_FILE}.`));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
fs.copyFileSync(KYOFLOW_ENV_EXAMPLE_FILE, KYOFLOW_ENV_FILE);
|
|
57
|
+
console.log(chalk.yellow(`Copied ${KYOFLOW_ENV_EXAMPLE_FILE} to ${KYOFLOW_ENV_FILE}`));
|
|
58
|
+
}
|
|
59
|
+
function loadRuntimeEnv() {
|
|
60
|
+
const envPath = IS_DEV ? path.join(PROJECT_ROOT, ".env") : KYOFLOW_ENV_FILE;
|
|
61
|
+
if (!fs.existsSync(envPath)) {
|
|
62
|
+
console.log(chalk.red(`Missing env file: ${envPath}`));
|
|
63
|
+
if (IS_DEV) {
|
|
64
|
+
console.log(chalk.yellow("Create project root .env for development mode."));
|
|
65
|
+
} else {
|
|
66
|
+
console.log(chalk.yellow(`Create it by copying ${KYOFLOW_ENV_EXAMPLE_FILE} to ${KYOFLOW_ENV_FILE} and updating values.`));
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
dotenv.config({ path: envPath, override: true });
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
function syncBackendEnvironment() {
|
|
74
|
+
console.log(chalk.blue(`Syncing backend environment at ${KYOFLOW_VENV_PATH}...`));
|
|
75
|
+
execFileSync("uv", ["sync", "--project", BACKEND_PATHS.dir], {
|
|
76
|
+
stdio: "inherit",
|
|
77
|
+
env: {
|
|
78
|
+
...process.env,
|
|
79
|
+
UV_PROJECT_ENVIRONMENT: KYOFLOW_VENV_PATH
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function getBackendPaths() {
|
|
84
|
+
if (IS_DEV) {
|
|
85
|
+
const devDir = path.join(PROJECT_ROOT, "packages", "backend");
|
|
86
|
+
return {
|
|
87
|
+
dir: devDir,
|
|
88
|
+
src: path.join(devDir, "src"),
|
|
89
|
+
main: "kyoflow"
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
const distDir = path.join(__dirname, "backend");
|
|
93
|
+
return {
|
|
94
|
+
dir: distDir,
|
|
95
|
+
src: path.join(distDir, "src"),
|
|
96
|
+
main: "kyoflow"
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
var BACKEND_PATHS = getBackendPaths();
|
|
100
|
+
var program = new Command();
|
|
101
|
+
function ensureUvInstalled() {
|
|
102
|
+
try {
|
|
103
|
+
execFileSync("uv", ["--version"], { stdio: "ignore" });
|
|
104
|
+
} catch (error) {
|
|
105
|
+
throw new Error("uv is required but was not found in PATH. Install uv and retry.");
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function getPids() {
|
|
109
|
+
if (fs.existsSync(PID_FILE)) {
|
|
110
|
+
try {
|
|
111
|
+
return JSON.parse(fs.readFileSync(PID_FILE, "utf-8"));
|
|
112
|
+
} catch (e) {
|
|
113
|
+
return {};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return {};
|
|
117
|
+
}
|
|
118
|
+
program.name("wendy").version("1.0.6");
|
|
119
|
+
program.command("start").action(async () => {
|
|
120
|
+
ensureRuntimeDirectory();
|
|
121
|
+
if (!IS_DEV) {
|
|
122
|
+
ensureEnvExampleFile();
|
|
123
|
+
ensureRuntimeEnvFile();
|
|
124
|
+
}
|
|
125
|
+
if (!loadRuntimeEnv()) {
|
|
126
|
+
process.exitCode = 1;
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
ensureUvInstalled();
|
|
130
|
+
syncBackendEnvironment();
|
|
131
|
+
process.chdir(KYOFLOW_DIR);
|
|
132
|
+
const pids = getPids();
|
|
133
|
+
try {
|
|
134
|
+
const serverScript = path.join(__dirname, "server.js");
|
|
135
|
+
const backendPort = process.env.BACKEND_PORT || process.env.APP_PORT || "8000";
|
|
136
|
+
console.log(chalk.blue("Starting Wendy services..."));
|
|
137
|
+
const out = fs.openSync(path.join(KYOFLOW_DIR, "out.log"), "a");
|
|
138
|
+
const err = fs.openSync(path.join(KYOFLOW_DIR, "err.log"), "a");
|
|
139
|
+
const frontendProc = spawn("node", [serverScript], {
|
|
140
|
+
detached: true,
|
|
141
|
+
stdio: ["ignore", out, err],
|
|
142
|
+
windowsHide: true,
|
|
143
|
+
cwd: KYOFLOW_DIR
|
|
144
|
+
});
|
|
145
|
+
frontendProc.unref();
|
|
146
|
+
const backendProc = spawn("uv", ["run", "--project", BACKEND_PATHS.dir, "python", "-m", BACKEND_PATHS.main], {
|
|
147
|
+
detached: true,
|
|
148
|
+
stdio: ["ignore", out, err],
|
|
149
|
+
env: {
|
|
150
|
+
...process.env,
|
|
151
|
+
PYTHONPATH: BACKEND_PATHS.src,
|
|
152
|
+
UV_PROJECT_ENVIRONMENT: KYOFLOW_VENV_PATH,
|
|
153
|
+
BACKEND_PORT: backendPort,
|
|
154
|
+
APP_PORT: backendPort
|
|
155
|
+
},
|
|
156
|
+
windowsHide: true,
|
|
157
|
+
cwd: KYOFLOW_DIR
|
|
158
|
+
});
|
|
159
|
+
backendProc.unref();
|
|
160
|
+
fs.writeFileSync(PID_FILE, JSON.stringify({ frontend: frontendProc.pid, backend: backendProc.pid }));
|
|
161
|
+
console.log(chalk.green(`Started! (PIDs: ${frontendProc.pid}, ${backendProc.pid})`));
|
|
162
|
+
} catch (e) {
|
|
163
|
+
console.error(chalk.red(`Error: ${e}`));
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
program.command("stop").action(() => {
|
|
167
|
+
const pids = getPids();
|
|
168
|
+
[pids.frontend, pids.backend].forEach((pid) => {
|
|
169
|
+
if (pid) try {
|
|
170
|
+
process.kill(pid, "SIGTERM");
|
|
171
|
+
} catch (e) {
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
if (fs.existsSync(PID_FILE)) fs.unlinkSync(PID_FILE);
|
|
175
|
+
console.log(chalk.green("Stopped."));
|
|
176
|
+
});
|
|
177
|
+
program.parse();
|
|
178
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n// Kyoflow CLI 진입점\n// - start: 웹/백엔드 프로세스 시작\n// - stop: 저장된 PID로 프로세스 종료\nimport { Command } from 'commander';\nimport { spawn, execFileSync } from 'child_process';\nimport path from 'path';\nimport fs from 'fs';\nimport os from 'os';\nimport chalk from 'chalk';\nimport { fileURLToPath } from 'url';\nimport dotenv from 'dotenv';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// --- 경로 탐색 로직 개선 ---\nfunction findProjectRoot() {\n // dist 실행(배포)과 소스 실행(개발)을 구분하기 위해\n // 상위 경로에서 pnpm-workspace.yaml 존재 여부를 탐색한다.\n let current = __dirname;\n // 1. 개발 환경: pnpm-workspace.yaml이 있는 곳이 루트\n while (path.dirname(current) !== current) {\n if (fs.existsSync(path.join(current, 'pnpm-workspace.yaml'))) {\n return { root: current, isDev: true };\n }\n current = path.dirname(current);\n }\n // 2. 배포 환경: cli.js(dist)가 있는 곳이 패키지 루트\n return { root: __dirname, isDev: false };\n}\n\nconst { root: PROJECT_ROOT, isDev: IS_DEV } = findProjectRoot();\n\nconst KYOFLOW_DIR = path.join(os.homedir(), '.kyoflow');\nconst KYOFLOW_ENV_FILE = path.join(KYOFLOW_DIR, '.env');\nconst KYOFLOW_ENV_EXAMPLE_FILE = path.join(KYOFLOW_DIR, '.env.example');\nconst KYOFLOW_VENV_PATH = path.join(KYOFLOW_DIR, '.venv');\nconst PID_FILE = path.join(KYOFLOW_DIR, 'daemon.json');\n\n// 전역 설치 런타임 디렉터리 보장\nfunction ensureRuntimeDirectory() {\n if (!fs.existsSync(KYOFLOW_DIR)) {\n fs.mkdirSync(KYOFLOW_DIR, { recursive: true });\n }\n}\n\n// 설치 모드에서 ~/.kyoflow/.env.example이 없으면 템플릿을 복사한다.\nfunction ensureEnvExampleFile() {\n if (fs.existsSync(KYOFLOW_ENV_EXAMPLE_FILE)) return;\n\n const envExampleCandidates = [\n path.join(PROJECT_ROOT, '.env.example'),\n path.join(__dirname, '.env.example')\n ];\n\n for (const src of envExampleCandidates) {\n if (fs.existsSync(src)) {\n fs.copyFileSync(src, KYOFLOW_ENV_EXAMPLE_FILE);\n console.log(chalk.yellow(`Copied .env.example to ${KYOFLOW_ENV_EXAMPLE_FILE}`));\n return;\n }\n }\n\n console.log(chalk.yellow('Warning: .env.example template was not found in package artifacts.'));\n}\n\n// 설치 모드에서 ~/.kyoflow/.env가 없으면 .env.example 기반으로 생성한다.\nfunction ensureRuntimeEnvFile() {\n if (fs.existsSync(KYOFLOW_ENV_FILE)) return;\n\n if (!fs.existsSync(KYOFLOW_ENV_EXAMPLE_FILE)) {\n console.log(chalk.yellow(`Warning: ${KYOFLOW_ENV_EXAMPLE_FILE} not found; cannot create ${KYOFLOW_ENV_FILE}.`));\n return;\n }\n\n fs.copyFileSync(KYOFLOW_ENV_EXAMPLE_FILE, KYOFLOW_ENV_FILE);\n console.log(chalk.yellow(`Copied ${KYOFLOW_ENV_EXAMPLE_FILE} to ${KYOFLOW_ENV_FILE}`));\n}\n\n// 개발 모드: 워크스페이스 루트 .env\n// 설치 모드: ~/.kyoflow/.env\nfunction loadRuntimeEnv() {\n const envPath = IS_DEV\n ? path.join(PROJECT_ROOT, '.env')\n : KYOFLOW_ENV_FILE;\n\n if (!fs.existsSync(envPath)) {\n console.log(chalk.red(`Missing env file: ${envPath}`));\n if (IS_DEV) {\n console.log(chalk.yellow('Create project root .env for development mode.'));\n } else {\n console.log(chalk.yellow(`Create it by copying ${KYOFLOW_ENV_EXAMPLE_FILE} to ${KYOFLOW_ENV_FILE} and updating values.`));\n }\n return false;\n }\n\n dotenv.config({ path: envPath, override: true });\n return true;\n}\n\n// 백엔드 의존성을 동기화하면서 가상환경 위치를 ~/.kyoflow/.venv로 고정한다.\nfunction syncBackendEnvironment() {\n console.log(chalk.blue(`Syncing backend environment at ${KYOFLOW_VENV_PATH}...`));\n execFileSync('uv', ['sync', '--project', BACKEND_PATHS.dir], {\n stdio: 'inherit',\n env: {\n ...process.env,\n UV_PROJECT_ENVIRONMENT: KYOFLOW_VENV_PATH\n }\n });\n}\n\n// 백엔드 프로젝트 경로 계산\n// - 개발: packages/backend\n// - 배포: packages/cli/dist/backend\nfunction getBackendPaths() {\n if (IS_DEV) {\n const devDir = path.join(PROJECT_ROOT, 'packages', 'backend');\n return {\n dir: devDir,\n src: path.join(devDir, 'src'),\n main: 'kyoflow'\n };\n }\n // 배포 환경 (dist/backend)\n const distDir = path.join(__dirname, 'backend');\n return {\n dir: distDir,\n src: path.join(distDir, 'src'),\n main: 'kyoflow'\n };\n}\n\nconst BACKEND_PATHS = getBackendPaths();\n// -----------------------\n\nconst program = new Command();\n\n// uv 설치 여부 사전 점검\nfunction ensureUvInstalled() {\n try {\n execFileSync('uv', ['--version'], { stdio: 'ignore' });\n } catch (error) {\n throw new Error('uv is required but was not found in PATH. Install uv and retry.');\n }\n}\n\n// start 시 저장해 둔 daemon.json에서 PID를 읽는다.\nfunction getPids() {\n if (fs.existsSync(PID_FILE)) {\n try { return JSON.parse(fs.readFileSync(PID_FILE, 'utf-8')); } catch (e) { return {}; }\n }\n return {};\n}\n\nprogram.name('wendy').version('1.0.6');\n\nprogram.command('start').action(async () => {\n // 실행 전 준비: 런타임 디렉터리, env 로딩, uv/venv 동기화\n ensureRuntimeDirectory();\n if (!IS_DEV) {\n ensureEnvExampleFile();\n ensureRuntimeEnvFile();\n }\n if (!loadRuntimeEnv()) {\n process.exitCode = 1;\n return;\n }\n ensureUvInstalled();\n syncBackendEnvironment();\n process.chdir(KYOFLOW_DIR);\n\n const pids = getPids();\n\n try {\n const serverScript = path.join(__dirname, 'server.js');\n const backendPort = process.env.BACKEND_PORT || process.env.APP_PORT || '8000';\n \n console.log(chalk.blue('Starting Wendy services...'));\n const out = fs.openSync(path.join(KYOFLOW_DIR, 'out.log'), 'a');\n const err = fs.openSync(path.join(KYOFLOW_DIR, 'err.log'), 'a');\n\n // 프론트엔드(내장 Node 서버) 시작\n const frontendProc = spawn('node', [serverScript], {\n detached: true,\n stdio: ['ignore', out, err],\n windowsHide: true,\n cwd: KYOFLOW_DIR\n });\n frontendProc.unref();\n\n // 백엔드(Python 모듈) 시작\n const backendProc = spawn('uv', ['run', '--project', BACKEND_PATHS.dir, 'python', '-m', BACKEND_PATHS.main], {\n detached: true,\n stdio: ['ignore', out, err],\n env: { \n ...process.env, \n PYTHONPATH: BACKEND_PATHS.src,\n UV_PROJECT_ENVIRONMENT: KYOFLOW_VENV_PATH,\n BACKEND_PORT: backendPort,\n APP_PORT: backendPort\n },\n windowsHide: true,\n cwd: KYOFLOW_DIR\n });\n backendProc.unref();\n\n // stop 명령에서 사용할 수 있도록 PID 저장\n fs.writeFileSync(PID_FILE, JSON.stringify({ frontend: frontendProc.pid, backend: backendProc.pid }));\n console.log(chalk.green(`Started! (PIDs: ${frontendProc.pid}, ${backendProc.pid})`));\n } catch (e) {\n console.error(chalk.red(`Error: ${e}`));\n }\n});\n\nprogram.command('stop').action(() => {\n // daemon.json에 기록된 프로세스를 종료한다.\n const pids = getPids();\n [pids.frontend, pids.backend].forEach(pid => {\n if (pid) try { process.kill(pid, 'SIGTERM'); } catch (e) {}\n });\n if (fs.existsSync(PID_FILE)) fs.unlinkSync(PID_FILE);\n console.log(chalk.green('Stopped.'));\n});\n\nprogram.parse();\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// src/postinstall.ts
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import os from "os";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
var __dirname = path.dirname(__filename);
|
|
8
|
+
var runtimeDir = path.join(os.homedir(), ".kyoflow");
|
|
9
|
+
var runtimeEnvExample = path.join(runtimeDir, ".env.example");
|
|
10
|
+
var packagedEnvExample = path.join(__dirname, ".env.example");
|
|
11
|
+
if (!fs.existsSync(runtimeDir)) {
|
|
12
|
+
fs.mkdirSync(runtimeDir, { recursive: true });
|
|
13
|
+
}
|
|
14
|
+
if (!fs.existsSync(runtimeEnvExample) && fs.existsSync(packagedEnvExample)) {
|
|
15
|
+
fs.copyFileSync(packagedEnvExample, runtimeEnvExample);
|
|
16
|
+
console.log(`Copied .env.example to ${runtimeEnvExample}`);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=postinstall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/postinstall.ts"],"sourcesContent":["import fs from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst runtimeDir = path.join(os.homedir(), '.kyoflow');\nconst runtimeEnvExample = path.join(runtimeDir, '.env.example');\nconst packagedEnvExample = path.join(__dirname, '.env.example');\n\n// npm install -g 직후 사용자 런타임 디렉터리를 준비한다.\nif (!fs.existsSync(runtimeDir)) {\n fs.mkdirSync(runtimeDir, { recursive: true });\n}\n\n// 이미 존재하면 덮어쓰지 않고, 없을 때만 템플릿을 제공한다.\nif (!fs.existsSync(runtimeEnvExample) && fs.existsSync(packagedEnvExample)) {\n fs.copyFileSync(packagedEnvExample, runtimeEnvExample);\n console.log(`Copied .env.example to ${runtimeEnvExample}`);\n}\n"],"mappings":";AAAA,OAAO,QAAQ;AACf,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAE9B,IAAM,aAAa,cAAc,YAAY,GAAG;AAChD,IAAM,YAAY,KAAK,QAAQ,UAAU;AAEzC,IAAM,aAAa,KAAK,KAAK,GAAG,QAAQ,GAAG,UAAU;AACrD,IAAM,oBAAoB,KAAK,KAAK,YAAY,cAAc;AAC9D,IAAM,qBAAqB,KAAK,KAAK,WAAW,cAAc;AAG9D,IAAI,CAAC,GAAG,WAAW,UAAU,GAAG;AAC9B,KAAG,UAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAC9C;AAGA,IAAI,CAAC,GAAG,WAAW,iBAAiB,KAAK,GAAG,WAAW,kBAAkB,GAAG;AAC1E,KAAG,aAAa,oBAAoB,iBAAiB;AACrD,UAAQ,IAAI,0BAA0B,iBAAiB,EAAE;AAC3D;","names":[]}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// src/server.ts
|
|
2
|
+
import http from "http";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
5
|
+
|
|
6
|
+
// ../shared/src/index.ts
|
|
7
|
+
var PROJECT_NAME = "wendy";
|
|
8
|
+
|
|
9
|
+
// src/server.ts
|
|
10
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
var __dirname = path.dirname(__filename);
|
|
12
|
+
var PORT = process.env.PORT || 3e3;
|
|
13
|
+
var WEB_DIST = path.join(__dirname, "web");
|
|
14
|
+
var HANDLER_PATH = path.join(WEB_DIST, "handler.js");
|
|
15
|
+
async function startServer() {
|
|
16
|
+
try {
|
|
17
|
+
const handlerUrl = pathToFileURL(HANDLER_PATH).href;
|
|
18
|
+
const { handler } = await import(handlerUrl);
|
|
19
|
+
const server = http.createServer((req, res) => {
|
|
20
|
+
handler(req, res);
|
|
21
|
+
});
|
|
22
|
+
server.listen(PORT, () => {
|
|
23
|
+
console.log(`${PROJECT_NAME} server running at http://localhost:${PORT}/`);
|
|
24
|
+
});
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.error("Failed to load SvelteKit handler:", error);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
startServer();
|
|
31
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../../shared/src/index.ts"],"sourcesContent":["import http from 'http';\nimport path from 'path';\nimport { fileURLToPath, pathToFileURL } from 'url';\nimport { PROJECT_NAME } from '@kyoofus/shared';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst PORT = process.env.PORT || 3000;\nconst WEB_DIST = path.join(__dirname, 'web');\nconst HANDLER_PATH = path.join(WEB_DIST, 'handler.js');\n\n// SvelteKit build 결과의 handler.js를 동적으로 로드해\n// 단일 Node HTTP 서버에서 요청을 위임 처리한다.\nasync function startServer() {\n try {\n // Windows compatibility for ESM import\n const handlerUrl = pathToFileURL(HANDLER_PATH).href;\n const { handler } = await import(handlerUrl);\n\n const server = http.createServer((req, res) => {\n handler(req, res);\n });\n\n server.listen(PORT, () => {\n console.log(`${PROJECT_NAME} server running at http://localhost:${PORT}/`);\n });\n } catch (error) {\n console.error('Failed to load SvelteKit handler:', error);\n process.exit(1);\n }\n}\n\n// CLI 백그라운드 프로세스로 실행되는 서버 진입점\nstartServer();\n","export const PROJECT_NAME = 'wendy';\n"],"mappings":";AAAA,OAAO,UAAU;AACjB,OAAO,UAAU;AACjB,SAAS,eAAe,qBAAqB;;;ACFtC,IAAM,eAAe;;;ADK5B,IAAM,aAAa,cAAc,YAAY,GAAG;AAChD,IAAM,YAAY,KAAK,QAAQ,UAAU;AAEzC,IAAM,OAAO,QAAQ,IAAI,QAAQ;AACjC,IAAM,WAAW,KAAK,KAAK,WAAW,KAAK;AAC3C,IAAM,eAAe,KAAK,KAAK,UAAU,YAAY;AAIrD,eAAe,cAAc;AAC3B,MAAI;AAEF,UAAM,aAAa,cAAc,YAAY,EAAE;AAC/C,UAAM,EAAE,QAAQ,IAAI,MAAM,OAAO;AAEjC,UAAM,SAAS,KAAK,aAAa,CAAC,KAAK,QAAQ;AAC7C,cAAQ,KAAK,GAAG;AAAA,IAClB,CAAC;AAED,WAAO,OAAO,MAAM,MAAM;AACxB,cAAQ,IAAI,GAAG,YAAY,uCAAuC,IAAI,GAAG;AAAA,IAC3E,CAAC;AAAA,EACH,SAAS,OAAO;AACd,YAAQ,MAAM,qCAAqC,KAAK;AACxD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAGA,YAAY;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer theme,base,components,utilities;@layer theme{@theme default{ --font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; --font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif; --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; --color-red-50: oklch(97.1% .013 17.38); --color-red-100: oklch(93.6% .032 17.717); --color-red-200: oklch(88.5% .062 18.334); --color-red-300: oklch(80.8% .114 19.571); --color-red-400: oklch(70.4% .191 22.216); --color-red-500: oklch(63.7% .237 25.331); --color-red-600: oklch(57.7% .245 27.325); --color-red-700: oklch(50.5% .213 27.518); --color-red-800: oklch(44.4% .177 26.899); --color-red-900: oklch(39.6% .141 25.723); --color-red-950: oklch(25.8% .092 26.042); --color-orange-50: oklch(98% .016 73.684); --color-orange-100: oklch(95.4% .038 75.164); --color-orange-200: oklch(90.1% .076 70.697); --color-orange-300: oklch(83.7% .128 66.29); --color-orange-400: oklch(75% .183 55.934); --color-orange-500: oklch(70.5% .213 47.604); --color-orange-600: oklch(64.6% .222 41.116); --color-orange-700: oklch(55.3% .195 38.402); --color-orange-800: oklch(47% .157 37.304); --color-orange-900: oklch(40.8% .123 38.172); --color-orange-950: oklch(26.6% .079 36.259); --color-amber-50: oklch(98.7% .022 95.277); --color-amber-100: oklch(96.2% .059 95.617); --color-amber-200: oklch(92.4% .12 95.746); --color-amber-300: oklch(87.9% .169 91.605); --color-amber-400: oklch(82.8% .189 84.429); --color-amber-500: oklch(76.9% .188 70.08); --color-amber-600: oklch(66.6% .179 58.318); --color-amber-700: oklch(55.5% .163 48.998); --color-amber-800: oklch(47.3% .137 46.201); --color-amber-900: oklch(41.4% .112 45.904); --color-amber-950: oklch(27.9% .077 45.635); --color-yellow-50: oklch(98.7% .026 102.212); --color-yellow-100: oklch(97.3% .071 103.193); --color-yellow-200: oklch(94.5% .129 101.54); --color-yellow-300: oklch(90.5% .182 98.111); --color-yellow-400: oklch(85.2% .199 91.936); --color-yellow-500: oklch(79.5% .184 86.047); --color-yellow-600: oklch(68.1% .162 75.834); --color-yellow-700: oklch(55.4% .135 66.442); --color-yellow-800: oklch(47.6% .114 61.907); --color-yellow-900: oklch(42.1% .095 57.708); --color-yellow-950: oklch(28.6% .066 53.813); --color-lime-50: oklch(98.6% .031 120.757); --color-lime-100: oklch(96.7% .067 122.328); --color-lime-200: oklch(93.8% .127 124.321); --color-lime-300: oklch(89.7% .196 126.665); --color-lime-400: oklch(84.1% .238 128.85); --color-lime-500: oklch(76.8% .233 130.85); --color-lime-600: oklch(64.8% .2 131.684); --color-lime-700: oklch(53.2% .157 131.589); --color-lime-800: oklch(45.3% .124 130.933); --color-lime-900: oklch(40.5% .101 131.063); --color-lime-950: oklch(27.4% .072 132.109); --color-green-50: oklch(98.2% .018 155.826); --color-green-100: oklch(96.2% .044 156.743); --color-green-200: oklch(92.5% .084 155.995); --color-green-300: oklch(87.1% .15 154.449); --color-green-400: oklch(79.2% .209 151.711); --color-green-500: oklch(72.3% .219 149.579); --color-green-600: oklch(62.7% .194 149.214); --color-green-700: oklch(52.7% .154 150.069); --color-green-800: oklch(44.8% .119 151.328); --color-green-900: oklch(39.3% .095 152.535); --color-green-950: oklch(26.6% .065 152.934); --color-emerald-50: oklch(97.9% .021 166.113); --color-emerald-100: oklch(95% .052 163.051); --color-emerald-200: oklch(90.5% .093 164.15); --color-emerald-300: oklch(84.5% .143 164.978); --color-emerald-400: oklch(76.5% .177 163.223); --color-emerald-500: oklch(69.6% .17 162.48); --color-emerald-600: oklch(59.6% .145 163.225); --color-emerald-700: oklch(50.8% .118 165.612); --color-emerald-800: oklch(43.2% .095 166.913); --color-emerald-900: oklch(37.8% .077 168.94); --color-emerald-950: oklch(26.2% .051 172.552); --color-teal-50: oklch(98.4% .014 180.72); --color-teal-100: oklch(95.3% .051 180.801); --color-teal-200: oklch(91% .096 180.426); --color-teal-300: oklch(85.5% .138 181.071); --color-teal-400: oklch(77.7% .152 181.912); --color-teal-500: oklch(70.4% .14 182.503); --color-teal-600: oklch(60% .118 184.704); --color-teal-700: oklch(51.1% .096 186.391); --color-teal-800: oklch(43.7% .078 188.216); --color-teal-900: oklch(38.6% .063 188.416); --color-teal-950: oklch(27.7% .046 192.524); --color-cyan-50: oklch(98.4% .019 200.873); --color-cyan-100: oklch(95.6% .045 203.388); --color-cyan-200: oklch(91.7% .08 205.041); --color-cyan-300: oklch(86.5% .127 207.078); --color-cyan-400: oklch(78.9% .154 211.53); --color-cyan-500: oklch(71.5% .143 215.221); --color-cyan-600: oklch(60.9% .126 221.723); --color-cyan-700: oklch(52% .105 223.128); --color-cyan-800: oklch(45% .085 224.283); --color-cyan-900: oklch(39.8% .07 227.392); --color-cyan-950: oklch(30.2% .056 229.695); --color-sky-50: oklch(97.7% .013 236.62); --color-sky-100: oklch(95.1% .026 236.824); --color-sky-200: oklch(90.1% .058 230.902); --color-sky-300: oklch(82.8% .111 230.318); --color-sky-400: oklch(74.6% .16 232.661); --color-sky-500: oklch(68.5% .169 237.323); --color-sky-600: oklch(58.8% .158 241.966); --color-sky-700: oklch(50% .134 242.749); --color-sky-800: oklch(44.3% .11 240.79); --color-sky-900: oklch(39.1% .09 240.876); --color-sky-950: oklch(29.3% .066 243.157); --color-blue-50: oklch(97% .014 254.604); --color-blue-100: oklch(93.2% .032 255.585); --color-blue-200: oklch(88.2% .059 254.128); --color-blue-300: oklch(80.9% .105 251.813); --color-blue-400: oklch(70.7% .165 254.624); --color-blue-500: oklch(62.3% .214 259.815); --color-blue-600: oklch(54.6% .245 262.881); --color-blue-700: oklch(48.8% .243 264.376); --color-blue-800: oklch(42.4% .199 265.638); --color-blue-900: oklch(37.9% .146 265.522); --color-blue-950: oklch(28.2% .091 267.935); --color-indigo-50: oklch(96.2% .018 272.314); --color-indigo-100: oklch(93% .034 272.788); --color-indigo-200: oklch(87% .065 274.039); --color-indigo-300: oklch(78.5% .115 274.713); --color-indigo-400: oklch(67.3% .182 276.935); --color-indigo-500: oklch(58.5% .233 277.117); --color-indigo-600: oklch(51.1% .262 276.966); --color-indigo-700: oklch(45.7% .24 277.023); --color-indigo-800: oklch(39.8% .195 277.366); --color-indigo-900: oklch(35.9% .144 278.697); --color-indigo-950: oklch(25.7% .09 281.288); --color-violet-50: oklch(96.9% .016 293.756); --color-violet-100: oklch(94.3% .029 294.588); --color-violet-200: oklch(89.4% .057 293.283); --color-violet-300: oklch(81.1% .111 293.571); --color-violet-400: oklch(70.2% .183 293.541); --color-violet-500: oklch(60.6% .25 292.717); --color-violet-600: oklch(54.1% .281 293.009); --color-violet-700: oklch(49.1% .27 292.581); --color-violet-800: oklch(43.2% .232 292.759); --color-violet-900: oklch(38% .189 293.745); --color-violet-950: oklch(28.3% .141 291.089); --color-purple-50: oklch(97.7% .014 308.299); --color-purple-100: oklch(94.6% .033 307.174); --color-purple-200: oklch(90.2% .063 306.703); --color-purple-300: oklch(82.7% .119 306.383); --color-purple-400: oklch(71.4% .203 305.504); --color-purple-500: oklch(62.7% .265 303.9); --color-purple-600: oklch(55.8% .288 302.321); --color-purple-700: oklch(49.6% .265 301.924); --color-purple-800: oklch(43.8% .218 303.724); --color-purple-900: oklch(38.1% .176 304.987); --color-purple-950: oklch(29.1% .149 302.717); --color-fuchsia-50: oklch(97.7% .017 320.058); --color-fuchsia-100: oklch(95.2% .037 318.852); --color-fuchsia-200: oklch(90.3% .076 319.62); --color-fuchsia-300: oklch(83.3% .145 321.434); --color-fuchsia-400: oklch(74% .238 322.16); --color-fuchsia-500: oklch(66.7% .295 322.15); --color-fuchsia-600: oklch(59.1% .293 322.896); --color-fuchsia-700: oklch(51.8% .253 323.949); --color-fuchsia-800: oklch(45.2% .211 324.591); --color-fuchsia-900: oklch(40.1% .17 325.612); --color-fuchsia-950: oklch(29.3% .136 325.661); --color-pink-50: oklch(97.1% .014 343.198); --color-pink-100: oklch(94.8% .028 342.258); --color-pink-200: oklch(89.9% .061 343.231); --color-pink-300: oklch(82.3% .12 346.018); --color-pink-400: oklch(71.8% .202 349.761); --color-pink-500: oklch(65.6% .241 354.308); --color-pink-600: oklch(59.2% .249 .584); --color-pink-700: oklch(52.5% .223 3.958); --color-pink-800: oklch(45.9% .187 3.815); --color-pink-900: oklch(40.8% .153 2.432); --color-pink-950: oklch(28.4% .109 3.907); --color-rose-50: oklch(96.9% .015 12.422); --color-rose-100: oklch(94.1% .03 12.58); --color-rose-200: oklch(89.2% .058 10.001); --color-rose-300: oklch(81% .117 11.638); --color-rose-400: oklch(71.2% .194 13.428); --color-rose-500: oklch(64.5% .246 16.439); --color-rose-600: oklch(58.6% .253 17.585); --color-rose-700: oklch(51.4% .222 16.935); --color-rose-800: oklch(45.5% .188 13.697); --color-rose-900: oklch(41% .159 10.272); --color-rose-950: oklch(27.1% .105 12.094); --color-slate-50: oklch(98.4% .003 247.858); --color-slate-100: oklch(96.8% .007 247.896); --color-slate-200: oklch(92.9% .013 255.508); --color-slate-300: oklch(86.9% .022 252.894); --color-slate-400: oklch(70.4% .04 256.788); --color-slate-500: oklch(55.4% .046 257.417); --color-slate-600: oklch(44.6% .043 257.281); --color-slate-700: oklch(37.2% .044 257.287); --color-slate-800: oklch(27.9% .041 260.031); --color-slate-900: oklch(20.8% .042 265.755); --color-slate-950: oklch(12.9% .042 264.695); --color-gray-50: oklch(98.5% .002 247.839); --color-gray-100: oklch(96.7% .003 264.542); --color-gray-200: oklch(92.8% .006 264.531); --color-gray-300: oklch(87.2% .01 258.338); --color-gray-400: oklch(70.7% .022 261.325); --color-gray-500: oklch(55.1% .027 264.364); --color-gray-600: oklch(44.6% .03 256.802); --color-gray-700: oklch(37.3% .034 259.733); --color-gray-800: oklch(27.8% .033 256.848); --color-gray-900: oklch(21% .034 264.665); --color-gray-950: oklch(13% .028 261.692); --color-zinc-50: oklch(98.5% 0 0); --color-zinc-100: oklch(96.7% .001 286.375); --color-zinc-200: oklch(92% .004 286.32); --color-zinc-300: oklch(87.1% .006 286.286); --color-zinc-400: oklch(70.5% .015 286.067); --color-zinc-500: oklch(55.2% .016 285.938); --color-zinc-600: oklch(44.2% .017 285.786); --color-zinc-700: oklch(37% .013 285.805); --color-zinc-800: oklch(27.4% .006 286.033); --color-zinc-900: oklch(21% .006 285.885); --color-zinc-950: oklch(14.1% .005 285.823); --color-neutral-50: oklch(98.5% 0 0); --color-neutral-100: oklch(97% 0 0); --color-neutral-200: oklch(92.2% 0 0); --color-neutral-300: oklch(87% 0 0); --color-neutral-400: oklch(70.8% 0 0); --color-neutral-500: oklch(55.6% 0 0); --color-neutral-600: oklch(43.9% 0 0); --color-neutral-700: oklch(37.1% 0 0); --color-neutral-800: oklch(26.9% 0 0); --color-neutral-900: oklch(20.5% 0 0); --color-neutral-950: oklch(14.5% 0 0); --color-stone-50: oklch(98.5% .001 106.423); --color-stone-100: oklch(97% .001 106.424); --color-stone-200: oklch(92.3% .003 48.717); --color-stone-300: oklch(86.9% .005 56.366); --color-stone-400: oklch(70.9% .01 56.259); --color-stone-500: oklch(55.3% .013 58.071); --color-stone-600: oklch(44.4% .011 73.639); --color-stone-700: oklch(37.4% .01 67.558); --color-stone-800: oklch(26.8% .007 34.298); --color-stone-900: oklch(21.6% .006 56.043); --color-stone-950: oklch(14.7% .004 49.25); --color-black: #000; --color-white: #fff; --spacing: .25rem; --breakpoint-sm: 40rem; --breakpoint-md: 48rem; --breakpoint-lg: 64rem; --breakpoint-xl: 80rem; --breakpoint-2xl: 96rem; --container-3xs: 16rem; --container-2xs: 18rem; --container-xs: 20rem; --container-sm: 24rem; --container-md: 28rem; --container-lg: 32rem; --container-xl: 36rem; --container-2xl: 42rem; --container-3xl: 48rem; --container-4xl: 56rem; --container-5xl: 64rem; --container-6xl: 72rem; --container-7xl: 80rem; --text-xs: .75rem; --text-xs--line-height: calc(1 / .75); --text-sm: .875rem; --text-sm--line-height: calc(1.25 / .875); --text-base: 1rem; --text-base--line-height: 1.5 ; --text-lg: 1.125rem; --text-lg--line-height: calc(1.75 / 1.125); --text-xl: 1.25rem; --text-xl--line-height: calc(1.75 / 1.25); --text-2xl: 1.5rem; --text-2xl--line-height: calc(2 / 1.5); --text-3xl: 1.875rem; --text-3xl--line-height: 1.2 ; --text-4xl: 2.25rem; --text-4xl--line-height: calc(2.5 / 2.25); --text-5xl: 3rem; --text-5xl--line-height: 1; --text-6xl: 3.75rem; --text-6xl--line-height: 1; --text-7xl: 4.5rem; --text-7xl--line-height: 1; --text-8xl: 6rem; --text-8xl--line-height: 1; --text-9xl: 8rem; --text-9xl--line-height: 1; --font-weight-thin: 100; --font-weight-extralight: 200; --font-weight-light: 300; --font-weight-normal: 400; --font-weight-medium: 500; --font-weight-semibold: 600; --font-weight-bold: 700; --font-weight-extrabold: 800; --font-weight-black: 900; --tracking-tighter: -.05em; --tracking-tight: -.025em; --tracking-normal: 0em; --tracking-wide: .025em; --tracking-wider: .05em; --tracking-widest: .1em; --leading-tight: 1.25; --leading-snug: 1.375; --leading-normal: 1.5; --leading-relaxed: 1.625; --leading-loose: 2; --radius-xs: .125rem; --radius-sm: .25rem; --radius-md: .375rem; --radius-lg: .5rem; --radius-xl: .75rem; --radius-2xl: 1rem; --radius-3xl: 1.5rem; --radius-4xl: 2rem; --shadow-2xs: 0 1px rgb(0 0 0 / .05); --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / .05); --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1); --shadow-md: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1); --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1); --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1); --shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / .25); --inset-shadow-2xs: inset 0 1px rgb(0 0 0 / .05); --inset-shadow-xs: inset 0 1px 1px rgb(0 0 0 / .05); --inset-shadow-sm: inset 0 2px 4px rgb(0 0 0 / .05); --drop-shadow-xs: 0 1px 1px rgb(0 0 0 / .05); --drop-shadow-sm: 0 1px 2px rgb(0 0 0 / .15); --drop-shadow-md: 0 3px 3px rgb(0 0 0 / .12); --drop-shadow-lg: 0 4px 4px rgb(0 0 0 / .15); --drop-shadow-xl: 0 9px 7px rgb(0 0 0 / .1); --drop-shadow-2xl: 0 25px 25px rgb(0 0 0 / .15); --text-shadow-2xs: 0px 1px 0px rgb(0 0 0 / .15); --text-shadow-xs: 0px 1px 1px rgb(0 0 0 / .2); --text-shadow-sm: 0px 1px 0px rgb(0 0 0 / .075), 0px 1px 1px rgb(0 0 0 / .075), 0px 2px 2px rgb(0 0 0 / .075); --text-shadow-md: 0px 1px 1px rgb(0 0 0 / .1), 0px 1px 2px rgb(0 0 0 / .1), 0px 2px 4px rgb(0 0 0 / .1); --text-shadow-lg: 0px 1px 2px rgb(0 0 0 / .1), 0px 3px 2px rgb(0 0 0 / .1), 0px 4px 8px rgb(0 0 0 / .1); --ease-in: cubic-bezier(.4, 0, 1, 1); --ease-out: cubic-bezier(0, 0, .2, 1); --ease-in-out: cubic-bezier(.4, 0, .2, 1); --animate-spin: spin 1s linear infinite; --animate-ping: ping 1s cubic-bezier(0, 0, .2, 1) infinite; --animate-pulse: pulse 2s cubic-bezier(.4, 0, .6, 1) infinite; --animate-bounce: bounce 1s infinite; @keyframes spin { to { transform: rotate(360deg); } } @keyframes ping { 75%, 100% { transform: scale(2); opacity: 0; } } @keyframes pulse { 50% { opacity: .5; } } @keyframes bounce { 0%, 100% { transform: translateY(-25%); animation-timing-function: cubic-bezier(.8, 0, 1, 1); } 50% { transform: none; animation-timing-function: cubic-bezier(0, 0, .2, 1); } } --blur-xs: 4px; --blur-sm: 8px; --blur-md: 12px; --blur-lg: 16px; --blur-xl: 24px; --blur-2xl: 40px; --blur-3xl: 64px; --perspective-dramatic: 100px; --perspective-near: 300px; --perspective-normal: 500px; --perspective-midrange: 800px; --perspective-distant: 1200px; --aspect-video: 16 / 9; --default-transition-duration: .15s; --default-transition-timing-function: cubic-bezier(.4, 0, .2, 1); --default-font-family: --theme(--font-sans, initial); --default-font-feature-settings: --theme( --font-sans--font-feature-settings, initial ); --default-font-variation-settings: --theme( --font-sans--font-variation-settings, initial ); --default-mono-font-family: --theme(--font-mono, initial); --default-mono-font-feature-settings: --theme( --font-mono--font-feature-settings, initial ); --default-mono-font-variation-settings: --theme( --font-mono--font-variation-settings, initial ); }@theme default inline reference{ --blur: 8px; --shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1); --shadow-inner: inset 0 2px 4px 0 rgb(0 0 0 / .05); --drop-shadow: 0 1px 2px rgb(0 0 0 / .1), 0 1px 1px rgb(0 0 0 / .06); --radius: .25rem; --max-width-prose: 65ch; }}@layer base{*,:after,:before,::backdrop,::file-selector-button{box-sizing:border-box;margin:0;padding:0;border:0 solid}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;tab-size:4;font-family:--theme(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:--theme(--default-font-feature-settings,normal);font-variation-settings:--theme(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:--theme(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:--theme(--default-mono-font-feature-settings,normal);font-variation-settings:--theme(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea,::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;border-radius:0;background-color:transparent;opacity:1}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]),::file-selector-button{appearance:button}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer utilities{@tailwind utilities;}@plugin "@tailwindcss/forms";@plugin "@tailwindcss/typography";
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ai-container.svelte-1h2iha8{background:#fff;border-radius:16px;padding:24px;box-shadow:0 4px 20px #00000014;max-width:800px;margin:0 auto;font-family:Segoe UI,system-ui,sans-serif}header.svelte-1h2iha8{display:flex;justify-content:space-between;align-items:center;margin-bottom:24px}h2.svelte-1h2iha8{margin:0;font-size:1.5rem;color:#1a1a1b}.badge.svelte-1h2iha8{padding:4px 12px;border-radius:20px;font-size:.8rem;font-weight:600;background:#f1f3f5;color:#495057}.badge.available.svelte-1h2iha8{background:#e7f5ff;color:#1971c2}.badge.warning.svelte-1h2iha8{background:#fff9db;color:#f08c00}.controls.svelte-1h2iha8{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-bottom:24px}.field.svelte-1h2iha8{display:flex;flex-direction:column;gap:6px}label.svelte-1h2iha8{font-size:.85rem;font-weight:600;color:#4b5563}select.svelte-1h2iha8,input.svelte-1h2iha8,textarea.svelte-1h2iha8{padding:10px;border:1px solid #d1d5db;border-radius:8px;font-size:.95rem}textarea.svelte-1h2iha8{min-height:160px;resize:vertical}.input-area.svelte-1h2iha8{display:flex;flex-direction:column;gap:12px;margin-bottom:20px}.action-row.svelte-1h2iha8{display:flex;align-items:center;gap:20px;margin-bottom:20px}.run-btn.svelte-1h2iha8{background:#1a1a1b;color:#fff;border:none;padding:12px 32px;border-radius:8px;font-weight:600;cursor:pointer;transition:opacity .2s}.run-btn.svelte-1h2iha8:disabled{opacity:.5;cursor:not-allowed}.status-box.svelte-1h2iha8{flex:1;display:flex;flex-direction:column;gap:4px}.msg.svelte-1h2iha8{font-size:.85rem;color:#6b7280}.progress-bar.svelte-1h2iha8{height:6px;background:#e5e7eb;border-radius:3px;overflow:hidden}.fill.svelte-1h2iha8{height:100%;background:#2563eb;transition:width .3s ease}.result-area.svelte-1h2iha8{margin-top:24px;padding-top:24px;border-top:1px solid #f3f4f6}.output-display.svelte-1h2iha8{margin-top:8px;padding:16px;background:#f8fafc;border-radius:8px;border-left:4px solid #3b82f6;white-space:pre-wrap;line-height:1.6;font-size:1rem;color:#1e293b}.page-container.svelte-1e4332c{padding:2rem}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import"https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap";body{margin:0;padding:0;background:#212121;font-family:Inter,Noto Sans KR,-apple-system,BlinkMacSystemFont,sans-serif;color:#ececec;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*,*:before,*:after{box-sizing:border-box}.chat-app.svelte-ohdcd4{display:flex;flex-direction:column;height:100vh;max-height:100dvh;overflow:hidden}.messages-viewport.svelte-ohdcd4{flex:1;overflow-y:auto;scroll-behavior:smooth;padding-bottom:24px}.messages-viewport.svelte-ohdcd4::-webkit-scrollbar{width:6px}.messages-viewport.svelte-ohdcd4::-webkit-scrollbar-track{background:transparent}.messages-viewport.svelte-ohdcd4::-webkit-scrollbar-thumb{background:#424242;border-radius:3px}.messages-viewport.svelte-ohdcd4::-webkit-scrollbar-thumb:hover{background:#555}.empty-state.svelte-ohdcd4{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;min-height:60vh;text-align:center;gap:12px;-webkit-user-select:none;user-select:none}.empty-icon.svelte-ohdcd4{width:64px;height:64px;background:#2f2f2f;border-radius:50%;display:flex;align-items:center;justify-content:center;color:#b4b4b4;margin-bottom:8px}.empty-title.svelte-ohdcd4{margin:0;font-size:24px;font-weight:600;color:#ececec;letter-spacing:-.02em}.empty-subtitle.svelte-ohdcd4{margin:0;font-size:16px;color:#8e8e8e;font-weight:400}.messages-list.svelte-ohdcd4{display:flex;flex-direction:column}.message-row.svelte-ohdcd4{padding:24px 0}.message-row.assistant.svelte-ohdcd4{background:#2f2f2f}.message-row.user.svelte-ohdcd4{background:transparent}.message-inner.svelte-ohdcd4{max-width:768px;margin:0 auto;padding:0 24px;display:flex;gap:16px;align-items:flex-start}.avatar.svelte-ohdcd4{flex-shrink:0;width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;margin-top:2px}.avatar.assistant.svelte-ohdcd4{background:linear-gradient(135deg,#ab68ff,#6366f1);color:#fff}.avatar.user.svelte-ohdcd4{background:#565869;color:#ececec}.message-content.svelte-ohdcd4{flex:1;min-width:0;line-height:1.7;font-size:15px}.message-role.svelte-ohdcd4{display:block;font-weight:600;font-size:14px;margin-bottom:4px;color:#ececec}.plain-text.svelte-ohdcd4{white-space:pre-wrap;word-break:break-word;color:#d9d9d9}.markdown-body.svelte-ohdcd4{color:#d9d9d9}.markdown-body.svelte-ohdcd4 p{margin:0 0 12px}.markdown-body.svelte-ohdcd4 p:last-child{margin-bottom:0}.markdown-body.svelte-ohdcd4 pre{background:#1a1a1a;color:#e2e8f0;padding:16px;border-radius:12px;overflow-x:auto;font-size:13px;margin:12px 0;border:1px solid #333}.markdown-body.svelte-ohdcd4 code{font-family:Consolas,Monaco,Courier New,monospace;font-size:13px}.markdown-body.svelte-ohdcd4 :not(pre)>code{background:#3a3a3a;padding:2px 6px;border-radius:4px;font-size:13px}.markdown-body.svelte-ohdcd4 ul,.markdown-body.svelte-ohdcd4 ol{margin:8px 0;padding-left:24px}.markdown-body.svelte-ohdcd4 li{margin:4px 0}.markdown-body.svelte-ohdcd4 strong{color:#ececec;font-weight:600}.markdown-body.svelte-ohdcd4 a{color:#818cf8;text-decoration:none}.markdown-body.svelte-ohdcd4 a:hover{text-decoration:underline}.markdown-body.svelte-ohdcd4 blockquote{border-left:3px solid #555;margin:12px 0;padding:4px 16px;color:#b4b4b4}.markdown-body.svelte-ohdcd4 table{width:100%;border-collapse:collapse;margin:12px 0}.markdown-body.svelte-ohdcd4 th,.markdown-body.svelte-ohdcd4 td{border:1px solid #444;padding:8px 12px;text-align:left}.markdown-body.svelte-ohdcd4 th{background:#333;font-weight:600;color:#ececec}.markdown-body.svelte-ohdcd4 hr{border:none;border-top:1px solid #444;margin:16px 0}.typing-indicator.svelte-ohdcd4{display:flex;align-items:center;gap:4px;padding:4px 0}.dot.svelte-ohdcd4{width:8px;height:8px;background:#8e8e8e;border-radius:50%;animation:svelte-ohdcd4-bounce 1.4s ease-in-out infinite both}.dot.svelte-ohdcd4:nth-child(1){animation-delay:-.32s}.dot.svelte-ohdcd4:nth-child(2){animation-delay:-.16s}@keyframes svelte-ohdcd4-bounce{0%,80%,to{transform:scale(.6);opacity:.4}40%{transform:scale(1);opacity:1}}.input-area.svelte-ohdcd4{flex-shrink:0;padding:0 24px 24px;background:#212121}.input-container.svelte-ohdcd4{max-width:768px;margin:0 auto}.input-wrapper.svelte-ohdcd4{display:flex;align-items:flex-end;gap:0;background:#2f2f2f;border:1px solid #424242;border-radius:24px;padding:8px 8px 8px 20px;transition:border-color .2s ease}.input-wrapper.svelte-ohdcd4:focus-within{border-color:#6366f1}.input-wrapper.svelte-ohdcd4 textarea:where(.svelte-ohdcd4){flex:1;border:none;outline:none;background:transparent;color:#ececec;font-family:inherit;font-size:15px;line-height:1.5;resize:none;max-height:200px;padding:6px 0}.input-wrapper.svelte-ohdcd4 textarea:where(.svelte-ohdcd4)::placeholder{color:#8e8e8e}.input-wrapper.svelte-ohdcd4 textarea:where(.svelte-ohdcd4):disabled{opacity:.5}.send-btn.svelte-ohdcd4{flex-shrink:0;width:36px;height:36px;border-radius:50%;border:none;background:#ececec;color:#171717;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .2s ease,opacity .2s ease,transform .15s ease}.send-btn.svelte-ohdcd4:hover:not(:disabled){background:#fff;transform:scale(1.05)}.send-btn.svelte-ohdcd4:active:not(:disabled){transform:scale(.95)}.send-btn.svelte-ohdcd4:disabled{background:#424242;color:#666;cursor:default}.disclaimer.svelte-ohdcd4{text-align:center;font-size:12px;color:#666;margin:10px 0 0;-webkit-user-select:none;user-select:none}@media(max-width:768px){.message-inner.svelte-ohdcd4{padding:0 16px}.input-area.svelte-ohdcd4{padding:0 12px 16px}.empty-title.svelte-ohdcd4{font-size:20px}.empty-subtitle.svelte-ohdcd4{font-size:14px}}@media(max-width:375px){.message-inner.svelte-ohdcd4{padding:0 12px;gap:10px}}@media(prefers-reduced-motion:reduce){.dot.svelte-ohdcd4{animation:none;opacity:.6}.messages-viewport.svelte-ohdcd4{scroll-behavior:auto}.send-btn.svelte-ohdcd4{transition:none}}
|
|
Binary file
|
|
Binary file
|