@roki-h5/create-roki-app 0.1.3 → 0.1.4

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.
Files changed (40) hide show
  1. package/package.json +4 -1
  2. package/templates/h5/.agents/skills/brainstorming/SKILL.md +159 -0
  3. package/templates/h5/.agents/skills/brainstorming/scripts/frame-template.html +213 -0
  4. package/templates/h5/.agents/skills/brainstorming/scripts/helper.js +167 -0
  5. package/templates/h5/.agents/skills/brainstorming/scripts/server.cjs +723 -0
  6. package/templates/h5/.agents/skills/brainstorming/scripts/start-server.sh +209 -0
  7. package/templates/h5/.agents/skills/brainstorming/scripts/stop-server.sh +120 -0
  8. package/templates/h5/.agents/skills/brainstorming/spec-document-reviewer-prompt.md +49 -0
  9. package/templates/h5/.agents/skills/brainstorming/visual-companion.md +298 -0
  10. package/templates/h5/.agents/skills/systematic-debugging/CREATION-LOG.md +119 -0
  11. package/templates/h5/.agents/skills/systematic-debugging/SKILL.md +296 -0
  12. package/templates/h5/.agents/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
  13. package/templates/h5/.agents/skills/systematic-debugging/condition-based-waiting.md +115 -0
  14. package/templates/h5/.agents/skills/systematic-debugging/defense-in-depth.md +122 -0
  15. package/templates/h5/.agents/skills/systematic-debugging/find-polluter.sh +63 -0
  16. package/templates/h5/.agents/skills/systematic-debugging/root-cause-tracing.md +169 -0
  17. package/templates/h5/.agents/skills/systematic-debugging/test-academic.md +14 -0
  18. package/templates/h5/.agents/skills/systematic-debugging/test-pressure-1.md +58 -0
  19. package/templates/h5/.agents/skills/systematic-debugging/test-pressure-2.md +68 -0
  20. package/templates/h5/.agents/skills/systematic-debugging/test-pressure-3.md +69 -0
  21. package/templates/h5/.agents/skills/test-driven-development/SKILL.md +371 -0
  22. package/templates/h5/.agents/skills/test-driven-development/testing-anti-patterns.md +299 -0
  23. package/templates/h5/.agents/skills/writing-plans/SKILL.md +174 -0
  24. package/templates/h5/.agents/skills/writing-plans/plan-document-reviewer-prompt.md +49 -0
  25. package/templates/h5/docs/agent-skills.md +136 -0
  26. package/templates/h5/scripts/version.js +1 -1
  27. package/templates/h5/skills-lock.json +29 -0
  28. package/templates/h5/src/assets/images/home/logo-poweroff.png +0 -0
  29. package/templates/h5/src/assets/images/home/logo-working.png +0 -0
  30. package/templates/h5/src/assets/styles/atomic/flex.css +60 -0
  31. package/templates/h5/src/assets/styles/atomic/index.css +4 -0
  32. package/templates/h5/src/assets/styles/atomic/layout.css +64 -0
  33. package/templates/h5/src/assets/styles/atomic/spacing.css +97 -0
  34. package/templates/h5/src/assets/styles/atomic/text.css +133 -0
  35. package/templates/h5/src/assets/styles/main.css +26 -1
  36. package/templates/h5/src/assets/styles/variables.css +19 -0
  37. package/templates/h5/src/components/WelcomeInfo.vue +2 -5
  38. package/templates/h5/src/main.ts +2 -2
  39. package/templates/h5/src/stores/app.ts +110 -0
  40. package/templates/h5/src/stores/index.ts +5 -108
@@ -0,0 +1,133 @@
1
+ .text-left {
2
+ text-align: left;
3
+ }
4
+
5
+ .text-center {
6
+ text-align: center;
7
+ }
8
+
9
+ .text-right {
10
+ text-align: right;
11
+ }
12
+
13
+ .font-normal {
14
+ font-weight: 400;
15
+ }
16
+
17
+ .font-medium {
18
+ font-weight: 500;
19
+ }
20
+
21
+ .font-semibold {
22
+ font-weight: 600;
23
+ }
24
+
25
+ .font-bold {
26
+ font-weight: 700;
27
+ }
28
+
29
+ .text-primary {
30
+ color: var(--color-text-primary);
31
+ }
32
+
33
+ .text-secondary {
34
+ color: var(--color-text-secondary);
35
+ }
36
+
37
+ .text-tertiary {
38
+ color: var(--color-text-tertiary);
39
+ }
40
+
41
+ .text-disabled {
42
+ color: var(--color-text-disabled);
43
+ }
44
+
45
+ .text-12 {
46
+ font-size: 12px;
47
+ }
48
+
49
+ .text-13 {
50
+ font-size: 13px;
51
+ }
52
+
53
+ .text-14 {
54
+ font-size: 14px;
55
+ }
56
+
57
+ .text-15 {
58
+ font-size: 15px;
59
+ }
60
+
61
+ .text-16 {
62
+ font-size: 16px;
63
+ }
64
+
65
+ .text-17 {
66
+ font-size: 17px;
67
+ }
68
+
69
+ .text-18 {
70
+ font-size: 18px;
71
+ }
72
+
73
+ .text-19 {
74
+ font-size: 19px;
75
+ }
76
+
77
+ .text-20 {
78
+ font-size: 20px;
79
+ }
80
+
81
+ .text-21 {
82
+ font-size: 21px;
83
+ }
84
+
85
+ .text-22 {
86
+ font-size: 22px;
87
+ }
88
+
89
+ .text-23 {
90
+ font-size: 23px;
91
+ }
92
+
93
+ .text-24 {
94
+ font-size: 24px;
95
+ }
96
+
97
+ .text-25 {
98
+ font-size: 25px;
99
+ }
100
+
101
+ .text-26 {
102
+ font-size: 26px;
103
+ }
104
+
105
+ .text-27 {
106
+ font-size: 27px;
107
+ }
108
+
109
+ .text-28 {
110
+ font-size: 28px;
111
+ }
112
+
113
+ .ellipsis {
114
+ overflow: hidden;
115
+ white-space: nowrap;
116
+ text-overflow: ellipsis;
117
+ }
118
+
119
+ .line-clamp-2 {
120
+ display: -webkit-box;
121
+ -webkit-box-orient: vertical;
122
+ -webkit-line-clamp: 2;
123
+ overflow: hidden;
124
+ }
125
+
126
+ .link {
127
+ color: var(--color-primary);
128
+ text-decoration: none;
129
+ }
130
+
131
+ .link:active {
132
+ color: var(--color-primary-active);
133
+ }
@@ -1,8 +1,33 @@
1
+ @import './variables.css';
2
+ @import './atomic/index.css';
3
+
4
+ *,
5
+ *::before,
6
+ *::after {
7
+ box-sizing: border-box;
8
+ }
9
+
1
10
  html,
2
11
  body {
3
12
  margin: 0;
4
13
  padding: 0;
5
- background: #f5f6f8;
14
+ height: 100%;
15
+ overscroll-behavior-y: none;
16
+ -webkit-tap-highlight-color: transparent;
17
+ font-family:
18
+ system-ui,
19
+ -apple-system,
20
+ 'Segoe UI',
21
+ Roboto,
22
+ 'Helvetica Neue',
23
+ Arial,
24
+ 'Noto Sans',
25
+ 'PingFang SC',
26
+ 'Microsoft YaHei',
27
+ sans-serif;
28
+ font-size: 16px;
29
+ color: var(--color-text-primary);
30
+ background: var(--color-bg-page);
6
31
  }
7
32
 
8
33
  #app {
@@ -0,0 +1,19 @@
1
+ :root {
2
+ --color-primary: #005da7;
3
+ --color-primary-hover: #4096ff;
4
+ --color-primary-active: #0958d9;
5
+ --color-success: #52c41a;
6
+ --color-warning: #faad14;
7
+ --color-error: #ff4d4f;
8
+ --color-info: #005da7;
9
+ --color-text-primary: rgba(0, 0, 0, 0.8);
10
+ --color-text-secondary: rgba(0, 0, 0, 0.65);
11
+ --color-text-tertiary: rgba(0, 0, 0, 0.45);
12
+ --color-text-disabled: rgba(0, 0, 0, 0.25);
13
+ --color-bg-page: #f5f6f8;
14
+ --color-bg-subtle: #eef0f4;
15
+ --color-bg-elevated: #ffffff;
16
+ --color-bg-mask: rgba(0, 0, 0, 0.45);
17
+ --color-border: #e8e8e8;
18
+ --color-divider: rgba(0, 0, 0, 0.06);
19
+ }
@@ -22,8 +22,8 @@ const speechText = computed(() => {
22
22
  <section class="welcome-info">
23
23
  <div class="welcome-info__left">
24
24
  <img class="welcome-info__logo" :src="logoSrc" alt="ROKI" />
25
- <h3 v-if="prefixText" class="welcome-info__prefix">{{ prefixText }}</h3>
26
- <p v-if="speechText" class="welcome-info__speech">{{ speechText }}</p>
25
+ <h3 v-if="prefixText" class="welcome-info__prefix text-20">{{ prefixText }}</h3>
26
+ <p v-if="speechText" class="welcome-info__speech text-12 text-primary">{{ speechText }}</p>
27
27
  </div>
28
28
 
29
29
  <div class="welcome-info__right">
@@ -64,15 +64,12 @@ const speechText = computed(() => {
64
64
  -webkit-background-clip: text;
65
65
  background-clip: text;
66
66
  color: transparent;
67
- font-size: 20px;
68
67
  font-weight: 400;
69
68
  line-height: 1.4;
70
69
  }
71
70
 
72
71
  .welcome-info__speech {
73
72
  margin: 0;
74
- color: rgba(0, 0, 0, 0.8);
75
- font-size: 12px;
76
73
  line-height: 1.5;
77
74
  }
78
75
 
@@ -1,8 +1,8 @@
1
1
  import { createApp } from 'vue'
2
- import { createPinia } from 'pinia'
3
2
  import RokiUI from '@roki-h5/ui'
4
3
  import '@roki-h5/ui/style.css'
5
4
  import { setupRem } from '@/utils/rem'
5
+ import pinia from '@/stores'
6
6
  import router from '@/router'
7
7
  import App from './App.vue'
8
8
  import '@/assets/styles/main.css'
@@ -10,7 +10,7 @@ import '@/assets/styles/main.css'
10
10
  setupRem()
11
11
 
12
12
  const app = createApp(App)
13
- app.use(createPinia())
13
+ app.use(pinia)
14
14
  app.use(router)
15
15
  app.use(RokiUI)
16
16
  app.mount('#app')
@@ -0,0 +1,110 @@
1
+ import { ref } from 'vue'
2
+ import { defineStore } from 'pinia'
3
+ import { getWelcomeMessage, type WelcomeMessageData } from '@/api/welcome'
4
+
5
+ function formatRequestDate(date = new Date()) {
6
+ const pad = (n: number) => String(n).padStart(2, '0')
7
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
8
+ }
9
+
10
+ /** 可通过 updateState 批量更新的字段 */
11
+ export interface AppStateUpdates {
12
+ terminal?: string
13
+ accessToken?: string
14
+ familyId?: string
15
+ deviceType?: string
16
+ deviceCategory?: string
17
+ deviceName?: string
18
+ deviceId?: string
19
+ deviceGuid?: string
20
+ userId?: string
21
+ }
22
+
23
+ export const useAppStore = defineStore('app', () => {
24
+ /** 应用展示名,可在启动时由接口或配置覆盖 */
25
+ const appName = ref('Roki H5')
26
+ const terminal = ref('android')
27
+ const deviceName = ref('燃气热水器·HT808-16')
28
+ const familyId = ref('')
29
+ const deviceId = ref('HT80888a68d0fb812')
30
+ const deviceGuid = ref('HT80888a68d0fb812')
31
+ const deviceType = ref('HT808')
32
+ const deviceCategory = ref('RRSQ')
33
+ const userId = ref('3243300064')
34
+
35
+ /** 开发联调用 token,生产环境由 App 注入覆盖 */
36
+ const accessToken = ref(
37
+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4MDI5Mjg0ODAsInVzZXJJZCI6MzI0MzMwMDA2NCwianRpIjoiMDI3ZjhiMGMtYmU5MS00NzA2LWI3ZDUtOGI5OTJlMjA0MzQ2IiwiY2xpZW50X2lkIjoicm9raV9jbGllbnQifQ.aW0hKvcv-k_4PocYNVWiml7IB15jZIcn24eXZFZCSz4',
38
+ )
39
+
40
+ /** `/rest/ops/ai/welcome` 的 data:prefix / speech */
41
+ const welcomeCopy = ref<WelcomeMessageData>({})
42
+
43
+ function setAppName(name: string) {
44
+ appName.value = name
45
+ }
46
+
47
+ function setAccessToken(token: string) {
48
+ accessToken.value = token
49
+ }
50
+
51
+ function resetWelcomeCopy() {
52
+ welcomeCopy.value = {}
53
+ }
54
+
55
+ async function loadWelcomeMessage(params: Record<string, unknown> = {}) {
56
+ try {
57
+ const res = await getWelcomeMessage({
58
+ date: formatRequestDate(),
59
+ ...params,
60
+ })
61
+ welcomeCopy.value = res?.data ?? {}
62
+ } catch (e) {
63
+ welcomeCopy.value = {}
64
+ if (import.meta.env.DEV) {
65
+ console.warn('[App] loadWelcomeMessage failed', e)
66
+ }
67
+ }
68
+ }
69
+
70
+ function updateState(updates: AppStateUpdates) {
71
+ const stateRefs = {
72
+ terminal,
73
+ accessToken,
74
+ familyId,
75
+ deviceType,
76
+ deviceCategory,
77
+ deviceName,
78
+ deviceId,
79
+ deviceGuid,
80
+ userId,
81
+ } as const
82
+
83
+ Object.entries(updates).forEach(([key, value]) => {
84
+ if (key in stateRefs) {
85
+ stateRefs[key as keyof typeof stateRefs].value = value as never
86
+ } else if (import.meta.env.DEV) {
87
+ console.warn(`[App] updateState: unknown key "${key}"`)
88
+ }
89
+ })
90
+ }
91
+
92
+ return {
93
+ appName,
94
+ terminal,
95
+ deviceName,
96
+ familyId,
97
+ deviceId,
98
+ deviceGuid,
99
+ deviceType,
100
+ deviceCategory,
101
+ userId,
102
+ accessToken,
103
+ welcomeCopy,
104
+ setAppName,
105
+ setAccessToken,
106
+ resetWelcomeCopy,
107
+ loadWelcomeMessage,
108
+ updateState,
109
+ }
110
+ })
@@ -1,110 +1,7 @@
1
- import { ref } from 'vue'
2
- import { defineStore } from 'pinia'
3
- import { getWelcomeMessage, type WelcomeMessageData } from '@/api/welcome'
1
+ import { createPinia } from 'pinia'
4
2
 
5
- function formatRequestDate(date = new Date()) {
6
- const pad = (n: number) => String(n).padStart(2, '0')
7
- return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
8
- }
3
+ const pinia = createPinia()
9
4
 
10
- /** 可通过 updateState 批量更新的字段 */
11
- export interface AppStateUpdates {
12
- terminal?: string
13
- accessToken?: string
14
- familyId?: string
15
- deviceType?: string
16
- deviceCategory?: string
17
- deviceName?: string
18
- deviceId?: string
19
- deviceGuid?: string
20
- userId?: string
21
- }
22
-
23
- export const useAppStore = defineStore('app', () => {
24
- /** 应用展示名,可在启动时由接口或配置覆盖 */
25
- const appName = ref('Roki H5')
26
- const terminal = ref('android')
27
- const deviceName = ref('燃气热水器·HT808-16')
28
- const familyId = ref('')
29
- const deviceId = ref('HT80888a68d0fb812')
30
- const deviceGuid = ref('HT80888a68d0fb812')
31
- const deviceType = ref('HT808')
32
- const deviceCategory = ref('RRSQ')
33
- const userId = ref('3243300064')
34
-
35
- /** 开发联调用 token,生产环境由 App 注入覆盖 */
36
- const accessToken = ref(
37
- 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4MDI5Mjg0ODAsInVzZXJJZCI6MzI0MzMwMDA2NCwianRpIjoiMDI3ZjhiMGMtYmU5MS00NzA2LWI3ZDUtOGI5OTJlMjA0MzQ2IiwiY2xpZW50X2lkIjoicm9raV9jbGllbnQifQ.aW0hKvcv-k_4PocYNVWiml7IB15jZIcn24eXZFZCSz4',
38
- )
39
-
40
- /** `/rest/ops/ai/welcome` 的 data:prefix / speech */
41
- const welcomeCopy = ref<WelcomeMessageData>({})
42
-
43
- function setAppName(name: string) {
44
- appName.value = name
45
- }
46
-
47
- function setAccessToken(token: string) {
48
- accessToken.value = token
49
- }
50
-
51
- function resetWelcomeCopy() {
52
- welcomeCopy.value = {}
53
- }
54
-
55
- async function loadWelcomeMessage(params: Record<string, unknown> = {}) {
56
- try {
57
- const res = await getWelcomeMessage({
58
- date: formatRequestDate(),
59
- ...params,
60
- })
61
- welcomeCopy.value = res?.data ?? {}
62
- } catch (e) {
63
- welcomeCopy.value = {}
64
- if (import.meta.env.DEV) {
65
- console.warn('[App] loadWelcomeMessage failed', e)
66
- }
67
- }
68
- }
69
-
70
- function updateState(updates: AppStateUpdates) {
71
- const stateRefs = {
72
- terminal,
73
- accessToken,
74
- familyId,
75
- deviceType,
76
- deviceCategory,
77
- deviceName,
78
- deviceId,
79
- deviceGuid,
80
- userId,
81
- } as const
82
-
83
- Object.entries(updates).forEach(([key, value]) => {
84
- if (key in stateRefs) {
85
- stateRefs[key as keyof typeof stateRefs].value = value as never
86
- } else if (import.meta.env.DEV) {
87
- console.warn(`[App] updateState: unknown key "${key}"`)
88
- }
89
- })
90
- }
91
-
92
- return {
93
- appName,
94
- terminal,
95
- deviceName,
96
- familyId,
97
- deviceId,
98
- deviceGuid,
99
- deviceType,
100
- deviceCategory,
101
- userId,
102
- accessToken,
103
- welcomeCopy,
104
- setAppName,
105
- setAccessToken,
106
- resetWelcomeCopy,
107
- loadWelcomeMessage,
108
- updateState,
109
- }
110
- })
5
+ export default pinia
6
+ export { useAppStore } from './app'
7
+ export type { AppStateUpdates } from './app'