aiwf 0.3.7 → 0.3.8
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/.aiwf/00_PROJECT_MANIFEST.md +226 -2
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/S03_M02_sprint_meta.md +112 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T01_S03_new_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T02_S03_first_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T03_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T04_S03_task_with_special_characters.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T05_S03_test.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T06_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T07_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T08_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T09_S03_new_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T100_S03_task_with_special_characters.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T101_S03_test.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T102_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T103_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T104_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T105_S03_new_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T106_S03_first_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T107_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T108_S03_task_with_special_characters.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T109_S03_test.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T10_S03_first_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T110_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T111_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T112_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T11_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T12_S03_task_with_special_characters.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T13_S03_test.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T14_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T15_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T16_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T17_S03_new_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T18_S03_first_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T19_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T20_S03_task_with_special_characters.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T21_S03_test.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T22_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T23_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T24_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T25_S03_new_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T26_S03_first_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T27_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T28_S03_task_with_special_characters.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T29_S03_test.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T30_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T31_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T32_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T33_S03_new_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T34_S03_first_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T35_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T36_S03_task_with_special_characters.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T37_S03_test.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T38_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T39_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T40_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T41_S03_new_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T42_S03_first_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T43_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T44_S03_task_with_special_characters.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T45_S03_test.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T46_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T47_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T48_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T49_S03_new_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T50_S03_first_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T51_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T52_S03_task_with_special_characters.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T53_S03_test.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T54_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T55_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T56_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T57_S03_new_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T58_S03_first_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T59_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T60_S03_task_with_special_characters.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T61_S03_test.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T62_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T63_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T64_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T65_S03_new_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T66_S03_first_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T67_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T68_S03_task_with_special_characters.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T69_S03_test.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T70_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T71_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T72_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T73_S03_new_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T74_S03_first_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T75_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T76_S03_task_with_special_characters.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T77_S03_test.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T78_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T79_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T80_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T81_S03_new_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T82_S03_first_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T83_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T84_S03_task_with_special_characters.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T85_S03_test.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T86_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T87_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T88_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T89_S03_new_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T90_S03_first_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T91_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T92_S03_task_with_special_characters.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T93_S03_test.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T94_S03_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T95_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T96_S03_next_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T97_S03_new_test_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T98_S03_first_task.md +39 -0
- package/.aiwf/03_SPRINTS/S03_M02_ecosystem_integration/T99_S03_test_task.md +39 -0
- package/.aiwf/test-results-s02.json +5 -5
- package/.claude/commands/aiwf/aiwf_compress_aggressive_persona.md +3 -15
- package/.claude/commands/aiwf/aiwf_compress_minimal_persona.md +2 -15
- package/.claude/commands/aiwf/aiwf_compress_stats.md +2 -51
- package/.claude/commands/aiwf/aiwf_compress_with_persona.md +5 -18
- package/.claude/commands/aiwf/aiwf_create_feature_ledger.md +1 -1
- package/.claude/commands/aiwf/aiwf_default_mode.md +1 -1
- package/.claude/commands/aiwf/aiwf_evaluate.md +3 -16
- package/.claude/commands/aiwf/aiwf_get_feature_details.md +1 -1
- package/.claude/commands/aiwf/aiwf_link_feature_to_milestone.md +1 -1
- package/.claude/commands/aiwf/aiwf_list_features.md +1 -1
- package/.claude/commands/aiwf/aiwf_switch_language.md +48 -120
- package/.claude/commands/aiwf/aiwf_update_feature_status.md +1 -1
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_aggressive_persona.md +2 -2
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_minimal_persona.md +2 -2
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_stats.md +10 -47
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_compress_with_persona.md +2 -2
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_create_feature_ledger.md +1 -1
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_default_mode.md +1 -1
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_evaluate.md +2 -2
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_get_feature_details.md +1 -1
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_link_feature_to_milestone.md +1 -1
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_list_features.md +1 -1
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_architect.md +1 -1
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_backend.md +1 -1
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_data_analyst.md +1 -1
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_frontend.md +1 -1
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_security.md +1 -1
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_persona_status.md +1 -1
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_update_feature_status.md +1 -1
- package/package.json +1 -1
- package/src/cli/index.js +174 -0
- package/src/commands/compress.js +60 -0
- package/src/commands/create-project.js +23 -17
- package/src/commands/evaluate.js +459 -0
- package/src/commands/feature.js +365 -0
- package/src/commands/persona.js +37 -16
- package/src/commands/token.js +312 -0
- package/src/lib/resource-loader.js +250 -0
- package/src/lib/resources/commands/ai-persona.js +602 -0
- package/src/lib/resources/commands/compress-context.js +389 -0
- package/src/lib/resources/commands/evaluate.js +246 -0
- package/src/lib/resources/commands/feature-ledger.js +565 -0
- package/src/lib/resources/commands/feature_commit_report.js +370 -0
- package/src/lib/resources/commands/persona-context-apply.js +562 -0
- package/src/lib/resources/commands/scan_git_history.js +234 -0
- package/src/lib/resources/commands/sync_feature_commits.js +154 -0
- package/src/lib/resources/commands/token-tracking.js +443 -0
- package/src/lib/resources/config/commit-patterns.js +103 -0
- package/src/lib/resources/config/language.json +6 -0
- package/src/lib/resources/personas/PERSONA_INDEX.md +57 -0
- package/src/lib/resources/personas/analyst.json +44 -0
- package/src/lib/resources/personas/architect/best_practices.md +136 -0
- package/src/lib/resources/personas/architect/knowledge_base.md +377 -0
- package/src/lib/resources/personas/architect.json +44 -0
- package/src/lib/resources/personas/backend/best_practices.md +766 -0
- package/src/lib/resources/personas/backend/knowledge_base.md +1070 -0
- package/src/lib/resources/personas/data_analyst/best_practices.md +594 -0
- package/src/lib/resources/personas/data_analyst/knowledge_base.md +1057 -0
- package/src/lib/resources/personas/developer.json +44 -0
- package/src/lib/resources/personas/developer.md +37 -0
- package/src/lib/resources/personas/evaluation_criteria.json +137 -0
- package/src/lib/resources/personas/frontend/best_practices.md +445 -0
- package/src/lib/resources/personas/frontend/knowledge_base.md +729 -0
- package/src/lib/resources/personas/persona-index.json +31 -0
- package/src/lib/resources/personas/reviewer.json +44 -0
- package/src/lib/resources/personas/security/best_practices.md +307 -0
- package/src/lib/resources/personas/security/knowledge_base.md +498 -0
- package/src/lib/resources/personas/tester.json +44 -0
- package/src/lib/resources/templates/README.md +78 -0
- package/src/lib/resources/templates/api-server/config.json +64 -0
- package/src/lib/resources/templates/api-server/template/.aiwf/config.json +56 -0
- package/src/lib/resources/templates/api-server/template/.aiwf/feature-ledger.json +42 -0
- package/src/lib/resources/templates/api-server/template/.aiwf/personas/backend-engineer.json +40 -0
- package/src/lib/resources/templates/api-server/template/.aiwf/scripts/cli.js +111 -0
- package/src/lib/resources/templates/api-server/template/.env.example +29 -0
- package/src/lib/resources/templates/api-server/template/.eslintrc.json +23 -0
- package/src/lib/resources/templates/api-server/template/README.md +171 -0
- package/src/lib/resources/templates/api-server/template/jest.config.js +26 -0
- package/src/lib/resources/templates/api-server/template/nodemon.json +9 -0
- package/src/lib/resources/templates/api-server/template/package.json +61 -0
- package/src/lib/resources/templates/api-server/template/src/app.ts +60 -0
- package/src/lib/resources/templates/api-server/template/src/config/swagger.ts +38 -0
- package/src/lib/resources/templates/api-server/template/src/controllers/aiwfController.ts +68 -0
- package/src/lib/resources/templates/api-server/template/src/controllers/authController.ts +128 -0
- package/src/lib/resources/templates/api-server/template/src/controllers/statusController.ts +28 -0
- package/src/lib/resources/templates/api-server/template/src/index.ts +28 -0
- package/src/lib/resources/templates/api-server/template/src/middleware/aiwfMiddleware.ts +50 -0
- package/src/lib/resources/templates/api-server/template/src/middleware/authMiddleware.ts +41 -0
- package/src/lib/resources/templates/api-server/template/src/middleware/errorHandler.ts +42 -0
- package/src/lib/resources/templates/api-server/template/src/middleware/notFoundHandler.ts +14 -0
- package/src/lib/resources/templates/api-server/template/src/middleware/requestLogger.ts +20 -0
- package/src/lib/resources/templates/api-server/template/src/routes/aiwf.ts +42 -0
- package/src/lib/resources/templates/api-server/template/src/routes/index.ts +13 -0
- package/src/lib/resources/templates/api-server/template/src/routes/v1/index.ts +67 -0
- package/src/lib/resources/templates/api-server/template/src/utils/logger.ts +37 -0
- package/src/lib/resources/templates/api-server/template/tests/app.test.ts +40 -0
- package/src/lib/resources/templates/api-server/template/tsconfig.json +43 -0
- package/src/lib/resources/templates/npm-library/config.json +61 -0
- package/src/lib/resources/templates/npm-library/template/LICENSE +21 -0
- package/src/lib/resources/templates/npm-library/template/README.md +201 -0
- package/src/lib/resources/templates/npm-library/template/package.json +78 -0
- package/src/lib/resources/templates/web-app/config.json +53 -0
- package/src/lib/resources/templates/web-app/template/.aiwf/config.json +54 -0
- package/src/lib/resources/templates/web-app/template/.aiwf/feature-ledger.json +37 -0
- package/src/lib/resources/templates/web-app/template/.aiwf/personas/fullstack-developer.json +40 -0
- package/src/lib/resources/templates/web-app/template/.aiwf/scripts/cli.js +110 -0
- package/src/lib/resources/templates/web-app/template/.eslintrc.cjs +20 -0
- package/src/lib/resources/templates/web-app/template/README.md +151 -0
- package/src/lib/resources/templates/web-app/template/index.html +14 -0
- package/src/lib/resources/templates/web-app/template/package.json +44 -0
- package/src/lib/resources/templates/web-app/template/postcss.config.js +6 -0
- package/src/lib/resources/templates/web-app/template/public/vite.svg +1 -0
- package/src/lib/resources/templates/web-app/template/src/App.tsx +21 -0
- package/src/lib/resources/templates/web-app/template/src/components/Layout.tsx +57 -0
- package/src/lib/resources/templates/web-app/template/src/components/aiwf/ContextStatus.tsx +107 -0
- package/src/lib/resources/templates/web-app/template/src/components/aiwf/FeatureLedger.tsx +93 -0
- package/src/lib/resources/templates/web-app/template/src/components/aiwf/TokenUsage.tsx +71 -0
- package/src/lib/resources/templates/web-app/template/src/index.css +60 -0
- package/src/lib/resources/templates/web-app/template/src/main.tsx +10 -0
- package/src/lib/resources/templates/web-app/template/src/pages/AiwfDashboard.tsx +60 -0
- package/src/lib/resources/templates/web-app/template/src/pages/HomePage.tsx +89 -0
- package/src/lib/resources/templates/web-app/template/src/pages/NotFound.tsx +25 -0
- package/src/lib/resources/templates/web-app/template/src/stores/aiwfStore.ts +126 -0
- package/src/lib/resources/templates/web-app/template/src/types/global.d.ts +9 -0
- package/src/lib/resources/templates/web-app/template/src/vite-env.d.ts +1 -0
- package/src/lib/resources/templates/web-app/template/tailwind.config.js +30 -0
- package/src/lib/resources/templates/web-app/template/tsconfig.json +37 -0
- package/src/lib/resources/templates/web-app/template/tsconfig.node.json +10 -0
- package/src/lib/resources/templates/web-app/template/vite.config.ts +23 -0
- package/src/lib/resources/utils/background-monitor.js +223 -0
- package/src/lib/resources/utils/compression-metrics.js +1031 -0
- package/src/lib/resources/utils/compression-strategies.js +557 -0
- package/src/lib/resources/utils/content-normalizer.js +455 -0
- package/src/lib/resources/utils/context-compressor.js +583 -0
- package/src/lib/resources/utils/context-rule-parser.js +180 -0
- package/src/lib/resources/utils/context-token-monitor.js +463 -0
- package/src/lib/resources/utils/context-update-manager.js +502 -0
- package/src/lib/resources/utils/feature-updater.js +271 -0
- package/src/lib/resources/utils/git-utils.js +220 -0
- package/src/lib/resources/utils/importance-classifier.js +645 -0
- package/src/lib/resources/utils/information-filter.js +710 -0
- package/src/lib/resources/utils/persona-aware-compressor.js +598 -0
- package/src/lib/resources/utils/prompt-injector.js +242 -0
- package/src/lib/resources/utils/simplified-evaluator.js +119 -0
- package/src/lib/resources/utils/text-summarizer.js +492 -0
- package/src/lib/resources/utils/token-counter.js +177 -0
- package/src/lib/resources/utils/token-monitor.js +484 -0
- package/src/lib/resources/utils/token-reporter.js +453 -0
- package/src/lib/resources/utils/token-storage.js +433 -0
- package/src/lib/resources/utils/token-tracker.js +283 -0
- package/claude-code/aiwf/ko/.claude/commands/aiwf/aiwf_switch_language.md +0 -160
- /package/claude-code/aiwf/ko/.claude/commands/aiwf/{aiwf_update_docs_kr.md → aiwf_update_docs.md} +0 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# {{projectName}}
|
|
2
|
+
|
|
3
|
+
AIWF가 통합된 React + TypeScript 웹 애플리케이션입니다.
|
|
4
|
+
|
|
5
|
+
## 시작하기
|
|
6
|
+
|
|
7
|
+
### 개발 서버 실행
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install
|
|
11
|
+
npm run dev
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
브라우저에서 [http://localhost:3000](http://localhost:3000)을 열어 확인하세요.
|
|
15
|
+
|
|
16
|
+
### 빌드
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm run build
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 프리뷰
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm run preview
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 기술 스택
|
|
29
|
+
|
|
30
|
+
- **React 18** - UI 라이브러리
|
|
31
|
+
- **TypeScript** - 타입 안정성
|
|
32
|
+
- **Vite** - 빠른 빌드 도구
|
|
33
|
+
- **Tailwind CSS** - 유틸리티 우선 CSS
|
|
34
|
+
- **React Router** - 클라이언트 사이드 라우팅
|
|
35
|
+
- **Zustand** - 상태 관리
|
|
36
|
+
- **AIWF** - AI 지원 개발 워크플로우
|
|
37
|
+
|
|
38
|
+
## 프로젝트 구조
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
src/
|
|
42
|
+
├── components/ # 재사용 가능한 컴포넌트
|
|
43
|
+
│ ├── Layout.tsx
|
|
44
|
+
│ └── aiwf/ # AIWF 관련 컴포넌트
|
|
45
|
+
├── pages/ # 페이지 컴포넌트
|
|
46
|
+
├── stores/ # Zustand 스토어
|
|
47
|
+
├── hooks/ # 커스텀 훅
|
|
48
|
+
├── utils/ # 유틸리티 함수
|
|
49
|
+
└── types/ # TypeScript 타입 정의
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## AIWF 기능
|
|
53
|
+
|
|
54
|
+
### Feature Ledger
|
|
55
|
+
|
|
56
|
+
프로젝트에서 개발된 모든 기능을 자동으로 추적합니다.
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm run aiwf:feature list # 기능 목록 보기
|
|
60
|
+
npm run aiwf:feature add # 새 기능 추가
|
|
61
|
+
npm run aiwf:feature update # 기능 상태 업데이트
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Context 압축
|
|
65
|
+
|
|
66
|
+
토큰 사용을 최적화하여 비용을 절감합니다.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm run aiwf:context status # 현재 상태 확인
|
|
70
|
+
npm run aiwf:context compress # 수동 압축 실행
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### AI 페르소나
|
|
74
|
+
|
|
75
|
+
프로젝트 유형에 맞는 AI 어시스턴트를 활성화합니다.
|
|
76
|
+
|
|
77
|
+
- `fullstack-developer` - 풀스택 개발 (기본값)
|
|
78
|
+
- `frontend-specialist` - 프론트엔드 전문
|
|
79
|
+
- `ui-ux-designer` - UI/UX 디자인
|
|
80
|
+
- `performance-optimizer` - 성능 최적화
|
|
81
|
+
- `security-auditor` - 보안 감사
|
|
82
|
+
|
|
83
|
+
## 개발 가이드
|
|
84
|
+
|
|
85
|
+
### 컴포넌트 생성
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
// src/components/MyComponent.tsx
|
|
89
|
+
interface MyComponentProps {
|
|
90
|
+
title: string
|
|
91
|
+
children: React.ReactNode
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export default function MyComponent({ title, children }: MyComponentProps) {
|
|
95
|
+
return (
|
|
96
|
+
<div>
|
|
97
|
+
<h2>{title}</h2>
|
|
98
|
+
{children}
|
|
99
|
+
</div>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 상태 관리
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
// src/stores/myStore.ts
|
|
108
|
+
import { create } from 'zustand'
|
|
109
|
+
|
|
110
|
+
interface MyStore {
|
|
111
|
+
count: number
|
|
112
|
+
increment: () => void
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export const useMyStore = create<MyStore>((set) => ({
|
|
116
|
+
count: 0,
|
|
117
|
+
increment: () => set((state) => ({ count: state.count + 1 })),
|
|
118
|
+
}))
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 스타일링
|
|
122
|
+
|
|
123
|
+
Tailwind CSS 클래스를 사용합니다:
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
<div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow">
|
|
127
|
+
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">
|
|
128
|
+
제목
|
|
129
|
+
</h1>
|
|
130
|
+
</div>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## 배포
|
|
134
|
+
|
|
135
|
+
### Vercel
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
npm run build
|
|
139
|
+
vercel
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Netlify
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
npm run build
|
|
146
|
+
netlify deploy --prod --dir=dist
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## 라이선스
|
|
150
|
+
|
|
151
|
+
MIT
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="ko">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>{{projectName}}</title>
|
|
8
|
+
<link rel="stylesheet" as="style" crossorigin href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.8/dist/web/variable/pretendardvariable-dynamic-subset.css" />
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{projectName}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "tsc && vite build",
|
|
9
|
+
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
10
|
+
"preview": "vite preview",
|
|
11
|
+
"test": "jest",
|
|
12
|
+
"aiwf": "node .aiwf/scripts/cli.js",
|
|
13
|
+
"aiwf:status": "npm run aiwf status",
|
|
14
|
+
"aiwf:feature": "npm run aiwf feature",
|
|
15
|
+
"aiwf:context": "npm run aiwf context"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"react": "^18.2.0",
|
|
19
|
+
"react-dom": "^18.2.0",
|
|
20
|
+
"react-router-dom": "^6.14.0",
|
|
21
|
+
"zustand": "^4.3.8",
|
|
22
|
+
"axios": "^1.4.0",
|
|
23
|
+
"clsx": "^1.2.1"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/react": "^18.2.0",
|
|
27
|
+
"@types/react-dom": "^18.2.0",
|
|
28
|
+
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
|
29
|
+
"@typescript-eslint/parser": "^5.60.0",
|
|
30
|
+
"@vitejs/plugin-react": "^4.0.0",
|
|
31
|
+
"autoprefixer": "^10.4.14",
|
|
32
|
+
"eslint": "^8.43.0",
|
|
33
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
34
|
+
"eslint-plugin-react-refresh": "^0.4.0",
|
|
35
|
+
"postcss": "^8.4.24",
|
|
36
|
+
"tailwindcss": "^3.3.2",
|
|
37
|
+
"typescript": "^5.1.0",
|
|
38
|
+
"vite": "^4.3.0",
|
|
39
|
+
"@types/node": "^20.0.0",
|
|
40
|
+
"jest": "^29.5.0",
|
|
41
|
+
"@testing-library/react": "^14.0.0",
|
|
42
|
+
"@testing-library/jest-dom": "^5.16.0"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
|
|
2
|
+
import Layout from '@/components/Layout'
|
|
3
|
+
import HomePage from '@/pages/HomePage'
|
|
4
|
+
import AiwfDashboard from '@/pages/AiwfDashboard'
|
|
5
|
+
import NotFound from '@/pages/NotFound'
|
|
6
|
+
|
|
7
|
+
function App() {
|
|
8
|
+
return (
|
|
9
|
+
<Router>
|
|
10
|
+
<Routes>
|
|
11
|
+
<Route path="/" element={<Layout />}>
|
|
12
|
+
<Route index element={<HomePage />} />
|
|
13
|
+
<Route path="aiwf" element={<AiwfDashboard />} />
|
|
14
|
+
<Route path="*" element={<NotFound />} />
|
|
15
|
+
</Route>
|
|
16
|
+
</Routes>
|
|
17
|
+
</Router>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default App
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Outlet, Link, useLocation } from 'react-router-dom'
|
|
2
|
+
import { useEffect } from 'react'
|
|
3
|
+
|
|
4
|
+
export default function Layout() {
|
|
5
|
+
const location = useLocation()
|
|
6
|
+
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
// AIWF 페이지 추적
|
|
9
|
+
if (window.aiwf) {
|
|
10
|
+
window.aiwf.trackPage(location.pathname)
|
|
11
|
+
}
|
|
12
|
+
}, [location])
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div className="min-h-screen bg-gray-50 dark:bg-gray-900">
|
|
16
|
+
<nav className="bg-white dark:bg-gray-800 shadow">
|
|
17
|
+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
18
|
+
<div className="flex justify-between h-16">
|
|
19
|
+
<div className="flex">
|
|
20
|
+
<div className="flex-shrink-0 flex items-center">
|
|
21
|
+
<h1 className="text-xl font-bold text-gray-900 dark:text-white">
|
|
22
|
+
{{projectName}}
|
|
23
|
+
</h1>
|
|
24
|
+
</div>
|
|
25
|
+
<div className="hidden sm:ml-6 sm:flex sm:space-x-8">
|
|
26
|
+
<Link
|
|
27
|
+
to="/"
|
|
28
|
+
className={`inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium ${
|
|
29
|
+
location.pathname === '/'
|
|
30
|
+
? 'border-primary text-gray-900 dark:text-white'
|
|
31
|
+
: 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-300 dark:hover:text-white'
|
|
32
|
+
}`}
|
|
33
|
+
>
|
|
34
|
+
홈
|
|
35
|
+
</Link>
|
|
36
|
+
<Link
|
|
37
|
+
to="/aiwf"
|
|
38
|
+
className={`inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium ${
|
|
39
|
+
location.pathname === '/aiwf'
|
|
40
|
+
? 'border-primary text-gray-900 dark:text-white'
|
|
41
|
+
: 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-300 dark:hover:text-white'
|
|
42
|
+
}`}
|
|
43
|
+
>
|
|
44
|
+
AIWF 대시보드
|
|
45
|
+
</Link>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</nav>
|
|
51
|
+
|
|
52
|
+
<main className="py-10">
|
|
53
|
+
<Outlet />
|
|
54
|
+
</main>
|
|
55
|
+
</div>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
interface ContextStatusData {
|
|
2
|
+
compressionLevel: 'none' | 'balanced' | 'aggressive'
|
|
3
|
+
cacheEnabled: boolean
|
|
4
|
+
cacheSize: number
|
|
5
|
+
maxCacheSize: number
|
|
6
|
+
lastCompression: string
|
|
7
|
+
savedTokens: number
|
|
8
|
+
activePersona: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface ContextStatusProps {
|
|
12
|
+
status: ContextStatusData
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default function ContextStatus({ status }: ContextStatusProps) {
|
|
16
|
+
const compressionLevels = {
|
|
17
|
+
none: { label: '없음', color: 'gray' },
|
|
18
|
+
balanced: { label: '균형', color: 'blue' },
|
|
19
|
+
aggressive: { label: '공격적', color: 'orange' },
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const level = compressionLevels[status.compressionLevel]
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<div className="space-y-6">
|
|
26
|
+
<div className="bg-white dark:bg-gray-800 overflow-hidden shadow rounded-lg">
|
|
27
|
+
<div className="p-6">
|
|
28
|
+
<h3 className="text-lg font-medium text-gray-900 dark:text-white mb-4">
|
|
29
|
+
Context 압축 설정
|
|
30
|
+
</h3>
|
|
31
|
+
|
|
32
|
+
<dl className="grid grid-cols-1 gap-x-4 gap-y-6 sm:grid-cols-2">
|
|
33
|
+
<div>
|
|
34
|
+
<dt className="text-sm font-medium text-gray-500 dark:text-gray-400">
|
|
35
|
+
압축 레벨
|
|
36
|
+
</dt>
|
|
37
|
+
<dd className="mt-1 text-sm text-gray-900 dark:text-white">
|
|
38
|
+
<span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-${level.color}-100 text-${level.color}-800 dark:bg-${level.color}-900 dark:text-${level.color}-200`}>
|
|
39
|
+
{level.label}
|
|
40
|
+
</span>
|
|
41
|
+
</dd>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div>
|
|
45
|
+
<dt className="text-sm font-medium text-gray-500 dark:text-gray-400">
|
|
46
|
+
캐시 상태
|
|
47
|
+
</dt>
|
|
48
|
+
<dd className="mt-1 text-sm text-gray-900 dark:text-white">
|
|
49
|
+
{status.cacheEnabled ? '활성화' : '비활성화'}
|
|
50
|
+
</dd>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<div>
|
|
54
|
+
<dt className="text-sm font-medium text-gray-500 dark:text-gray-400">
|
|
55
|
+
캐시 사용량
|
|
56
|
+
</dt>
|
|
57
|
+
<dd className="mt-1 text-sm text-gray-900 dark:text-white">
|
|
58
|
+
{(status.cacheSize / 1024 / 1024).toFixed(2)} MB / {(status.maxCacheSize / 1024 / 1024).toFixed(0)} MB
|
|
59
|
+
</dd>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<div>
|
|
63
|
+
<dt className="text-sm font-medium text-gray-500 dark:text-gray-400">
|
|
64
|
+
절약된 토큰
|
|
65
|
+
</dt>
|
|
66
|
+
<dd className="mt-1 text-sm text-gray-900 dark:text-white">
|
|
67
|
+
{status.savedTokens.toLocaleString()} 토큰
|
|
68
|
+
</dd>
|
|
69
|
+
</div>
|
|
70
|
+
</dl>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<div className="bg-white dark:bg-gray-800 shadow rounded-lg">
|
|
75
|
+
<div className="p-6">
|
|
76
|
+
<h4 className="text-md font-medium text-gray-900 dark:text-white mb-4">
|
|
77
|
+
AI 페르소나
|
|
78
|
+
</h4>
|
|
79
|
+
<div className="flex items-center justify-between">
|
|
80
|
+
<div>
|
|
81
|
+
<p className="text-sm font-medium text-gray-900 dark:text-white">
|
|
82
|
+
현재 활성 페르소나
|
|
83
|
+
</p>
|
|
84
|
+
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
|
|
85
|
+
프로젝트 유형에 최적화된 AI 어시스턴트
|
|
86
|
+
</p>
|
|
87
|
+
</div>
|
|
88
|
+
<span className="text-sm font-medium text-primary">
|
|
89
|
+
{status.activePersona}
|
|
90
|
+
</span>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<div className="bg-white dark:bg-gray-800 shadow rounded-lg">
|
|
96
|
+
<div className="p-6">
|
|
97
|
+
<h4 className="text-md font-medium text-gray-900 dark:text-white mb-2">
|
|
98
|
+
마지막 압축
|
|
99
|
+
</h4>
|
|
100
|
+
<p className="text-sm text-gray-500 dark:text-gray-400">
|
|
101
|
+
{new Date(status.lastCompression).toLocaleString('ko-KR')}
|
|
102
|
+
</p>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
)
|
|
107
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
interface Feature {
|
|
2
|
+
id: string
|
|
3
|
+
name: string
|
|
4
|
+
description: string
|
|
5
|
+
status: 'completed' | 'in_progress' | 'planned'
|
|
6
|
+
type: string
|
|
7
|
+
created_at: string
|
|
8
|
+
completed_at?: string
|
|
9
|
+
tags: string[]
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface FeatureLedgerProps {
|
|
13
|
+
features: Feature[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default function FeatureLedger({ features }: FeatureLedgerProps) {
|
|
17
|
+
const getStatusBadge = (status: Feature['status']) => {
|
|
18
|
+
const styles = {
|
|
19
|
+
completed: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
|
|
20
|
+
in_progress: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200',
|
|
21
|
+
planned: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300',
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const labels = {
|
|
25
|
+
completed: '완료',
|
|
26
|
+
in_progress: '진행중',
|
|
27
|
+
planned: '계획됨',
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${styles[status]}`}>
|
|
32
|
+
{labels[status]}
|
|
33
|
+
</span>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div className="bg-white dark:bg-gray-800 shadow overflow-hidden sm:rounded-lg">
|
|
39
|
+
<div className="px-4 py-5 sm:px-6">
|
|
40
|
+
<h3 className="text-lg leading-6 font-medium text-gray-900 dark:text-white">
|
|
41
|
+
Feature Ledger
|
|
42
|
+
</h3>
|
|
43
|
+
<p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
|
44
|
+
프로젝트에서 개발된 모든 기능을 추적합니다.
|
|
45
|
+
</p>
|
|
46
|
+
</div>
|
|
47
|
+
<div className="border-t border-gray-200 dark:border-gray-700">
|
|
48
|
+
<ul className="divide-y divide-gray-200 dark:divide-gray-700">
|
|
49
|
+
{features.map((feature) => (
|
|
50
|
+
<li key={feature.id} className="px-4 py-4 sm:px-6">
|
|
51
|
+
<div className="flex items-start justify-between">
|
|
52
|
+
<div className="flex-1">
|
|
53
|
+
<div className="flex items-center justify-between">
|
|
54
|
+
<p className="text-sm font-medium text-gray-900 dark:text-white truncate">
|
|
55
|
+
{feature.name}
|
|
56
|
+
</p>
|
|
57
|
+
{getStatusBadge(feature.status)}
|
|
58
|
+
</div>
|
|
59
|
+
<p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
|
60
|
+
{feature.description}
|
|
61
|
+
</p>
|
|
62
|
+
<div className="mt-2 flex items-center text-xs text-gray-500 dark:text-gray-400">
|
|
63
|
+
<span>{feature.id}</span>
|
|
64
|
+
<span className="mx-2">•</span>
|
|
65
|
+
<span>{new Date(feature.created_at).toLocaleDateString('ko-KR')}</span>
|
|
66
|
+
{feature.completed_at && (
|
|
67
|
+
<>
|
|
68
|
+
<span className="mx-2">→</span>
|
|
69
|
+
<span>{new Date(feature.completed_at).toLocaleDateString('ko-KR')}</span>
|
|
70
|
+
</>
|
|
71
|
+
)}
|
|
72
|
+
</div>
|
|
73
|
+
{feature.tags.length > 0 && (
|
|
74
|
+
<div className="mt-2 flex flex-wrap gap-1">
|
|
75
|
+
{feature.tags.map((tag) => (
|
|
76
|
+
<span
|
|
77
|
+
key={tag}
|
|
78
|
+
className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300"
|
|
79
|
+
>
|
|
80
|
+
{tag}
|
|
81
|
+
</span>
|
|
82
|
+
))}
|
|
83
|
+
</div>
|
|
84
|
+
)}
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</li>
|
|
88
|
+
))}
|
|
89
|
+
</ul>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
interface TokenUsageData {
|
|
2
|
+
total: number
|
|
3
|
+
used: number
|
|
4
|
+
remaining: number
|
|
5
|
+
percentage: number
|
|
6
|
+
history: Array<{
|
|
7
|
+
date: string
|
|
8
|
+
tokens: number
|
|
9
|
+
action: string
|
|
10
|
+
}>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface TokenUsageProps {
|
|
14
|
+
usage: TokenUsageData
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default function TokenUsage({ usage }: TokenUsageProps) {
|
|
18
|
+
return (
|
|
19
|
+
<div className="space-y-6">
|
|
20
|
+
<div className="bg-white dark:bg-gray-800 overflow-hidden shadow rounded-lg">
|
|
21
|
+
<div className="p-6">
|
|
22
|
+
<h3 className="text-lg font-medium text-gray-900 dark:text-white">
|
|
23
|
+
토큰 사용 현황
|
|
24
|
+
</h3>
|
|
25
|
+
|
|
26
|
+
<div className="mt-4">
|
|
27
|
+
<div className="flex justify-between text-sm text-gray-600 dark:text-gray-400">
|
|
28
|
+
<span>사용량</span>
|
|
29
|
+
<span>{usage.used.toLocaleString()} / {usage.total.toLocaleString()}</span>
|
|
30
|
+
</div>
|
|
31
|
+
<div className="mt-2 w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2">
|
|
32
|
+
<div
|
|
33
|
+
className="bg-primary h-2 rounded-full transition-all duration-500"
|
|
34
|
+
style={{ width: `${usage.percentage}%` }}
|
|
35
|
+
/>
|
|
36
|
+
</div>
|
|
37
|
+
<div className="mt-2 flex justify-between text-xs text-gray-500 dark:text-gray-400">
|
|
38
|
+
<span>{usage.percentage}% 사용</span>
|
|
39
|
+
<span>{usage.remaining.toLocaleString()} 토큰 남음</span>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div className="bg-white dark:bg-gray-800 shadow rounded-lg">
|
|
46
|
+
<div className="p-6">
|
|
47
|
+
<h4 className="text-md font-medium text-gray-900 dark:text-white mb-4">
|
|
48
|
+
최근 사용 내역
|
|
49
|
+
</h4>
|
|
50
|
+
<div className="space-y-3">
|
|
51
|
+
{usage.history.map((item, index) => (
|
|
52
|
+
<div key={index} className="flex items-center justify-between py-2 border-b border-gray-100 dark:border-gray-700 last:border-0">
|
|
53
|
+
<div>
|
|
54
|
+
<p className="text-sm font-medium text-gray-900 dark:text-white">
|
|
55
|
+
{item.action}
|
|
56
|
+
</p>
|
|
57
|
+
<p className="text-xs text-gray-500 dark:text-gray-400">
|
|
58
|
+
{new Date(item.date).toLocaleString('ko-KR')}
|
|
59
|
+
</p>
|
|
60
|
+
</div>
|
|
61
|
+
<span className="text-sm text-gray-600 dark:text-gray-300">
|
|
62
|
+
{item.tokens.toLocaleString()} 토큰
|
|
63
|
+
</span>
|
|
64
|
+
</div>
|
|
65
|
+
))}
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
)
|
|
71
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
@tailwind base;
|
|
2
|
+
@tailwind components;
|
|
3
|
+
@tailwind utilities;
|
|
4
|
+
|
|
5
|
+
@layer base {
|
|
6
|
+
:root {
|
|
7
|
+
--background: 0 0% 100%;
|
|
8
|
+
--foreground: 222.2 84% 4.9%;
|
|
9
|
+
--card: 0 0% 100%;
|
|
10
|
+
--card-foreground: 222.2 84% 4.9%;
|
|
11
|
+
--popover: 0 0% 100%;
|
|
12
|
+
--popover-foreground: 222.2 84% 4.9%;
|
|
13
|
+
--primary: 221.2 83.2% 53.3%;
|
|
14
|
+
--primary-foreground: 210 40% 98%;
|
|
15
|
+
--secondary: 210 40% 96.1%;
|
|
16
|
+
--secondary-foreground: 222.2 47.4% 11.2%;
|
|
17
|
+
--muted: 210 40% 96.1%;
|
|
18
|
+
--muted-foreground: 215.4 16.3% 46.9%;
|
|
19
|
+
--accent: 210 40% 96.1%;
|
|
20
|
+
--accent-foreground: 222.2 47.4% 11.2%;
|
|
21
|
+
--destructive: 0 84.2% 60.2%;
|
|
22
|
+
--destructive-foreground: 210 40% 98%;
|
|
23
|
+
--border: 214.3 31.8% 91.4%;
|
|
24
|
+
--input: 214.3 31.8% 91.4%;
|
|
25
|
+
--ring: 221.2 83.2% 53.3%;
|
|
26
|
+
--radius: 0.5rem;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.dark {
|
|
30
|
+
--background: 222.2 84% 4.9%;
|
|
31
|
+
--foreground: 210 40% 98%;
|
|
32
|
+
--card: 222.2 84% 4.9%;
|
|
33
|
+
--card-foreground: 210 40% 98%;
|
|
34
|
+
--popover: 222.2 84% 4.9%;
|
|
35
|
+
--popover-foreground: 210 40% 98%;
|
|
36
|
+
--primary: 217.2 91.2% 59.8%;
|
|
37
|
+
--primary-foreground: 222.2 47.4% 11.2%;
|
|
38
|
+
--secondary: 217.2 32.6% 17.5%;
|
|
39
|
+
--secondary-foreground: 210 40% 98%;
|
|
40
|
+
--muted: 217.2 32.6% 17.5%;
|
|
41
|
+
--muted-foreground: 215 20.2% 65.1%;
|
|
42
|
+
--accent: 217.2 32.6% 17.5%;
|
|
43
|
+
--accent-foreground: 210 40% 98%;
|
|
44
|
+
--destructive: 0 62.8% 30.6%;
|
|
45
|
+
--destructive-foreground: 210 40% 98%;
|
|
46
|
+
--border: 217.2 32.6% 17.5%;
|
|
47
|
+
--input: 217.2 32.6% 17.5%;
|
|
48
|
+
--ring: 224.3 76.3% 48%;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@layer base {
|
|
53
|
+
* {
|
|
54
|
+
@apply border-border;
|
|
55
|
+
}
|
|
56
|
+
body {
|
|
57
|
+
@apply bg-background text-foreground;
|
|
58
|
+
font-family: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, 'Helvetica Neue', 'Segoe UI', sans-serif;
|
|
59
|
+
}
|
|
60
|
+
}
|