adspecs 0.1.18 → 0.1.20

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 (88) hide show
  1. package/.adspecs/extensions/git/commands/adspecs.git.initialize.md +4 -4
  2. package/.adspecs/extensions/git/extension.yml +1 -1
  3. package/.adspecs/extensions/git/git-config.yml +17 -2
  4. package/.adspecs/extensions.yml +32 -0
  5. package/.adspecs/feature.json +16 -16
  6. package/.adspecs/feature.yml +28 -28
  7. package/.adspecs/paths.json +17 -0
  8. package/.adspecs/templates/02-/344/272/247/345/223/201/351/234/200/346/261/202/350/257/264/346/230/216/344/271/246/346/250/241/346/235/277.md +4 -0
  9. package/.adspecs/workflows/adspecs/workflow.yml +5 -4
  10. package/.claude-plugin/marketplace.json +23 -23
  11. package/.claude-plugin/plugin.json +18 -18
  12. package/.qoder-plugin/plugin.json +31 -31
  13. package/CLAUDE.md +1 -5
  14. package/README.md +395 -395
  15. package/bin/adspecs.js +129 -129
  16. package/hooks/commit-queue.js +245 -245
  17. package/hooks/hooks.json +63 -63
  18. package/hooks/session-start.js +44 -44
  19. package/hooks/wiki-queue.js +127 -127
  20. package/package.json +61 -61
  21. package/references/ant6-front-standard/index.md +99 -99
  22. package/references/antd-front-demo/.env.develop +12 -0
  23. package/references/antd-front-demo/.env.production +5 -0
  24. package/references/antd-front-demo/package-lock.json +2 -2
  25. package/references/antd-front-demo/package.json +1 -1
  26. package/references/antd-front-demo/public/mockServiceWorker.js +361 -361
  27. package/references/ecp-end-standard/index.md +63 -63
  28. package/references/python-end-standard/01-Python/345/220/216/347/253/257/347/274/226/347/240/201/350/247/204/350/214/203.md +372 -372
  29. package/references/python-end-standard/02-/346/225/260/346/215/256/345/272/223/350/256/276/350/256/241/344/270/216/344/275/277/347/224/250/350/247/204/350/214/203.md +226 -226
  30. package/references/python-end-standard/03-Celery/345/274/202/346/255/245/344/273/273/345/212/241/350/247/204/350/214/203.md +237 -237
  31. package/references/python-end-standard/04-Redis/344/275/277/347/224/250/350/247/204/350/214/203.md +231 -231
  32. package/scripts/postinstall.js +107 -107
  33. package/scripts/sync-version.js +105 -105
  34. package/skills/.claude/.wiki-update-queue +26 -26
  35. package/skills/adspecs-constitution/SKILL.md +157 -0
  36. package/skills/adspecs-export-word/SKILL.md +498 -498
  37. package/skills/adspecs-export-word/references/md-to-docx.js +862 -862
  38. package/skills/adspecs-export-word/references/package-lock.json +220 -220
  39. package/skills/adspecs-export-word/references/package.json +10 -10
  40. package/skills/adspecs-front-prototype/SKILL.md +405 -0
  41. package/skills/adspecs-git-commit/SKILL.md +23 -8
  42. package/skills/adspecs-git-initialize/SKILL.md +54 -0
  43. package/skills/adspecs-plan/SKILL.md +59 -69
  44. package/skills/adspecs-prd/SKILL.md +13 -5
  45. package/skills/adspecs-prd-to-demo/SKILL.md +532 -0
  46. package/skills/adspecs-tasks/SKILL.md +175 -204
  47. package/skills/adspecs-update-status/SKILL.md +382 -382
  48. package/skills/adspecs-utest/SKILL.md +107 -116
  49. package/skills/grill-me/SKILL.md +7 -0
  50. package/skills/grill-me/agents/openai.yaml +5 -0
  51. package/skills/playwright-cli/SKILL.md +420 -0
  52. package/skills/playwright-cli/references/element-attributes.md +23 -0
  53. package/skills/playwright-cli/references/playwright-tests.md +39 -0
  54. package/skills/playwright-cli/references/request-mocking.md +87 -0
  55. package/skills/playwright-cli/references/running-code.md +241 -0
  56. package/skills/playwright-cli/references/session-management.md +225 -0
  57. package/skills/playwright-cli/references/storage-state.md +275 -0
  58. package/skills/playwright-cli/references/test-generation.md +433 -0
  59. package/skills/playwright-cli/references/tracing.md +139 -0
  60. package/skills/playwright-cli/references/video-recording.md +143 -0
  61. package/skills/playwright-trace/SKILL.md +171 -0
  62. package/skills/project-init/references/front-demo/.claude/settings.local.json +9 -0
  63. package/skills/wiki-update/SKILL.md +232 -232
  64. package/src/commands/doctor.js +197 -197
  65. package/src/commands/init.js +83 -83
  66. package/src/commands/plugin.js +165 -165
  67. package/src/commands/update.js +87 -87
  68. package/src/lib/area-scanner.js +129 -129
  69. package/src/lib/copier.js +104 -104
  70. package/src/lib/dir-utils.js +133 -133
  71. package/src/lib/json-merge.js +114 -114
  72. package/src/lib/paths-defaults.js +37 -37
  73. package/src/lib/prompts.js +347 -345
  74. package/src/lib/readme-gen.js +143 -143
  75. package/src/lib/report.js +327 -327
  76. package/src/lib/scaffolder.js +518 -518
  77. package/src/lib/short-name.js +36 -36
  78. package/src/utils.js +80 -80
  79. package/references/antd-front-demo/.env +0 -15
  80. package/references/antd-front-demo/src/pages/aps/coil/components/CoilDrawer.tsx +0 -141
  81. package/references/antd-front-demo/src/pages/aps/coil/index.tsx +0 -209
  82. package/references/antd-front-demo/src/pages/aps/optimization/index.tsx +0 -192
  83. package/references/antd-front-demo/src/pages/aps/order/components/OrderDrawer.tsx +0 -251
  84. package/references/antd-front-demo/src/pages/aps/order/index.tsx +0 -273
  85. package/references/antd-front-demo/src/pages/aps/param/index.tsx +0 -153
  86. package/references/antd-front-demo/src/pages/aps/plan/components/CuttingPlanVisualization.tsx +0 -821
  87. package/references/antd-front-demo/src/pages/aps/plan/index.tsx +0 -254
  88. package/references/antd-front-demo/src/pages/aps/task/index.tsx +0 -190
@@ -1,254 +0,0 @@
1
- import { useRef, useState } from 'react';
2
- import { Space, Tag, Popconfirm, message, Modal, Table, Descriptions } from 'antd';
3
- import { ProTable } from '@ant-design/pro-components';
4
- import type { ActionType, ProColumns } from '@ant-design/pro-components';
5
- import { useTranslation } from 'react-i18next';
6
- import { Access } from '@/components/Access';
7
- import { getPlanPage, deletePlan, confirmPlan, getPlanDetail, exportWorkInstruction } from '@/api/aps/plan';
8
- import type { CuttingPlanVO, PlanDetailVO, SmallCoilVO } from '@/types/aps/plan';
9
- import CuttingPlanVisualization from './components/CuttingPlanVisualization';
10
-
11
- const PlanPage: React.FC = () => {
12
- const { t } = useTranslation('aps/plan');
13
- const { t: tc } = useTranslation('common');
14
- const actionRef = useRef<ActionType>(null);
15
- const [detailOpen, setDetailOpen] = useState(false);
16
- const [detailData, setDetailData] = useState<PlanDetailVO | null>(null);
17
- const [detailLoading, setDetailLoading] = useState(false);
18
-
19
- const handleDelete = (planId: string) => async () => {
20
- await deletePlan(planId);
21
- message.success(tc('success'));
22
- actionRef.current?.reload();
23
- };
24
-
25
- const handleConfirm = (planId: string) => async () => {
26
- await confirmPlan(planId);
27
- message.success(tc('success'));
28
- actionRef.current?.reload();
29
- };
30
-
31
- const handleDetail = async (planId: string) => {
32
- setDetailOpen(true);
33
- setDetailLoading(true);
34
- try {
35
- const res = await getPlanDetail(planId);
36
- setDetailData(res.data);
37
- } finally {
38
- setDetailLoading(false);
39
- }
40
- };
41
-
42
- const handleExport = async (planId: string) => {
43
- await exportWorkInstruction(planId, 'excel');
44
- message.success(tc('success'));
45
- };
46
-
47
- const smallCoilColumns = [
48
- {
49
- title: t('smallCoilId'),
50
- dataIndex: 'smallCoilId',
51
- key: 'smallCoilId',
52
- width: 120,
53
- },
54
- {
55
- title: t('width'),
56
- dataIndex: 'width',
57
- key: 'width',
58
- width: 100,
59
- },
60
- {
61
- title: t('length'),
62
- dataIndex: 'length',
63
- key: 'length',
64
- width: 100,
65
- },
66
- {
67
- title: t('weight'),
68
- dataIndex: 'weight',
69
- key: 'weight',
70
- width: 100,
71
- },
72
- {
73
- title: t('outerDiameter'),
74
- dataIndex: 'outerDiameter',
75
- key: 'outerDiameter',
76
- width: 120,
77
- },
78
- {
79
- title: t('orderId'),
80
- dataIndex: 'orderId',
81
- key: 'orderId',
82
- width: 120,
83
- render: (orderId: string | undefined) => orderId || <Tag>{t('unassigned')}</Tag>,
84
- },
85
- {
86
- title: t('region'),
87
- dataIndex: 'region',
88
- key: 'region',
89
- width: 80,
90
- },
91
- ];
92
-
93
- const columns: ProColumns<CuttingPlanVO>[] = [
94
- {
95
- title: t('planId'),
96
- dataIndex: 'planId',
97
- ellipsis: true,
98
- width: 180,
99
- },
100
- {
101
- title: t('coilId'),
102
- dataIndex: 'coilId',
103
- width: 100,
104
- },
105
- {
106
- title: t('coilAlloy'),
107
- dataIndex: 'coilAlloy',
108
- search: false,
109
- width: 80,
110
- },
111
- {
112
- title: t('coilTemper'),
113
- dataIndex: 'coilTemper',
114
- search: false,
115
- width: 80,
116
- },
117
- {
118
- title: t('coilWidth'),
119
- dataIndex: 'coilWidth',
120
- search: false,
121
- width: 100,
122
- },
123
- {
124
- title: t('coilWeight'),
125
- dataIndex: 'coilWeight',
126
- search: false,
127
- width: 100,
128
- },
129
- {
130
- title: t('totalCuts'),
131
- dataIndex: 'totalCuts',
132
- search: false,
133
- width: 100,
134
- },
135
- {
136
- title: t('theoreticalUtilization'),
137
- dataIndex: 'theoreticalUtilization',
138
- search: false,
139
- width: 140,
140
- render: (_, record) => `${record.theoreticalUtilization.toFixed(2)}%`,
141
- },
142
- {
143
- title: t('score'),
144
- dataIndex: 'score',
145
- search: false,
146
- width: 100,
147
- render: (_, record) => record.score.toFixed(4),
148
- },
149
- {
150
- title: t('createTime'),
151
- dataIndex: 'createTime',
152
- search: false,
153
- width: 180,
154
- },
155
- {
156
- title: tc('operation'),
157
- key: 'action',
158
- fixed: 'right',
159
- search: false,
160
- width: 250,
161
- render: (_, record) => (
162
- <Space>
163
- <Access code="aps:plan:query">
164
- <a onClick={() => handleDetail(record.planId)}>{t('actions.detail')}</a>
165
- </Access>
166
- <Access code="aps:plan:confirm">
167
- <Popconfirm title={t('confirmConfirm')} onConfirm={handleConfirm(record.planId)}>
168
- <a>{t('actions.confirm')}</a>
169
- </Popconfirm>
170
- </Access>
171
- <Access code="aps:plan:export">
172
- <a onClick={() => handleExport(record.planId)}>{t('actions.export')}</a>
173
- </Access>
174
- <Access code="aps:plan:delete">
175
- <Popconfirm title={t('deleteConfirm')} onConfirm={handleDelete(record.planId)}>
176
- <a style={{ color: '#ff4d4f' }}>{t('actions.delete')}</a>
177
- </Popconfirm>
178
- </Access>
179
- </Space>
180
- ),
181
- },
182
- ];
183
-
184
- return (
185
- <>
186
- <ProTable<CuttingPlanVO>
187
- columns={columns}
188
- actionRef={actionRef}
189
- rowKey="planId"
190
- headerTitle={t('title')}
191
- request={async (params) => {
192
- const { current, pageSize, ...rest } = params;
193
- const { data } = await getPlanPage({
194
- pageNo: current!,
195
- pageSize: pageSize!,
196
- ...rest,
197
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
198
- } as any);
199
- return { data: data.list, total: data.total, success: true };
200
- }}
201
- pagination={{ defaultPageSize: 10, showSizeChanger: true }}
202
- scroll={{ x: 1400 }}
203
- />
204
-
205
- <Modal
206
- title={t('actions.detail')}
207
- open={detailOpen}
208
- onCancel={() => setDetailOpen(false)}
209
- footer={null}
210
- width={1200}
211
- >
212
- {detailData && (
213
- <>
214
- <Descriptions bordered column={2} size="small" style={{ marginBottom: 16 }}>
215
- <Descriptions.Item label={t('planId')}>{detailData.planId}</Descriptions.Item>
216
- <Descriptions.Item label={t('coilId')}>{detailData.coilId}</Descriptions.Item>
217
- <Descriptions.Item label={t('coilAlloy')}>{detailData.coilAlloy}</Descriptions.Item>
218
- <Descriptions.Item label={t('coilTemper')}>{detailData.coilTemper}</Descriptions.Item>
219
- <Descriptions.Item label={t('coilWidth')}>{detailData.coilWidth} mm</Descriptions.Item>
220
- <Descriptions.Item label={t('coilWeight')}>{detailData.coilWeight} 吨</Descriptions.Item>
221
- <Descriptions.Item label={t('totalCuts')}>{detailData.totalCuts}</Descriptions.Item>
222
- <Descriptions.Item label={t('theoreticalUtilization')}>
223
- {detailData.theoreticalUtilization.toFixed(2)}%
224
- </Descriptions.Item>
225
- <Descriptions.Item label={t('score')}>{detailData.score.toFixed(4)}</Descriptions.Item>
226
- <Descriptions.Item label={t('createTime')}>{detailData.createTime}</Descriptions.Item>
227
- <Descriptions.Item label={t('verticalCuts')} span={2}>
228
- {detailData.verticalCuts}
229
- </Descriptions.Item>
230
- <Descriptions.Item label={t('horizontalCuts')} span={2}>
231
- {detailData.horizontalCuts}
232
- </Descriptions.Item>
233
- </Descriptions>
234
-
235
- <CuttingPlanVisualization plan={detailData} />
236
-
237
- <h4 style={{ marginTop: 16 }}>{t('smallCoils')}</h4>
238
- <Table<SmallCoilVO>
239
- columns={smallCoilColumns}
240
- dataSource={detailData.smallCoils}
241
- rowKey="smallCoilId"
242
- size="small"
243
- pagination={false}
244
- scroll={{ x: 800 }}
245
- loading={detailLoading}
246
- />
247
- </>
248
- )}
249
- </Modal>
250
- </>
251
- );
252
- };
253
-
254
- export default PlanPage;
@@ -1,190 +0,0 @@
1
- import { useRef } from 'react';
2
- import { Space, Tag, Popconfirm, Progress, message } from 'antd';
3
- import { useNavigate } from 'react-router-dom';
4
- import { ProTable } from '@ant-design/pro-components';
5
- import type { ActionType, ProColumns } from '@ant-design/pro-components';
6
- import { useTranslation } from 'react-i18next';
7
- import { Access } from '@/components/Access';
8
- import { getTaskPage, cancelTask, resumeTask, deleteTask } from '@/api/aps/task';
9
- import type { OptimizationTaskVO } from '@/types/aps/task';
10
- import { TASK_STATUS, TASK_TYPE, TASK_PHASE } from '@/types/aps/task';
11
-
12
- const TaskPage: React.FC = () => {
13
- const { t } = useTranslation('aps/task');
14
- const { t: tc } = useTranslation('common');
15
- const actionRef = useRef<ActionType>(null);
16
- const navigate = useNavigate();
17
-
18
- const handleCancel = (taskId: string) => async () => {
19
- await cancelTask(taskId);
20
- message.success(tc('success'));
21
- actionRef.current?.reload();
22
- };
23
-
24
- const handleResume = (taskId: string) => async () => {
25
- await resumeTask(taskId);
26
- message.success(tc('success'));
27
- actionRef.current?.reload();
28
- };
29
-
30
- const handleDelete = (taskId: string) => async () => {
31
- await deleteTask(taskId);
32
- message.success(tc('success'));
33
- actionRef.current?.reload();
34
- };
35
-
36
- const columns: ProColumns<OptimizationTaskVO>[] = [
37
- {
38
- title: t('taskId'),
39
- dataIndex: 'taskId',
40
- ellipsis: true,
41
- width: 180,
42
- },
43
- {
44
- title: t('taskType'),
45
- dataIndex: 'taskType',
46
- valueType: 'select',
47
- valueEnum: {
48
- SINGLE_COIL: { text: TASK_TYPE.SINGLE_COIL.label },
49
- GLOBAL_OPTIMIZATION: { text: TASK_TYPE.GLOBAL_OPTIMIZATION.label },
50
- },
51
- width: 120,
52
- render: (_, record) => {
53
- const item = TASK_TYPE[record.taskType as keyof typeof TASK_TYPE];
54
- return item ? <Tag color={item.color}>{item.label}</Tag> : '-';
55
- },
56
- },
57
- {
58
- title: t('status'),
59
- dataIndex: 'status',
60
- valueType: 'select',
61
- valueEnum: {
62
- PENDING: { text: TASK_STATUS.PENDING.label, status: 'Default' },
63
- RUNNING: { text: TASK_STATUS.RUNNING.label, status: 'Processing' },
64
- PAUSED: { text: TASK_STATUS.PAUSED.label, status: 'Warning' },
65
- COMPLETED: { text: TASK_STATUS.COMPLETED.label, status: 'Success' },
66
- FAILED: { text: TASK_STATUS.FAILED.label, status: 'Error' },
67
- CANCELLED: { text: TASK_STATUS.CANCELLED.label, status: 'Default' },
68
- },
69
- width: 100,
70
- render: (_, record) => {
71
- const item = TASK_STATUS[record.status as keyof typeof TASK_STATUS];
72
- return item ? <Tag color={item.color}>{item.label}</Tag> : '-';
73
- },
74
- },
75
- {
76
- title: t('progress'),
77
- dataIndex: 'progress',
78
- search: false,
79
- width: 150,
80
- render: (_, record) => (
81
- <Progress
82
- percent={record.progress}
83
- size="small"
84
- status={
85
- record.status === 'RUNNING' ? 'active' :
86
- record.status === 'COMPLETED' ? 'success' :
87
- record.status === 'FAILED' ? 'exception' : 'normal'
88
- }
89
- />
90
- ),
91
- },
92
- {
93
- title: t('currentPhase'),
94
- dataIndex: 'currentPhase',
95
- search: false,
96
- width: 120,
97
- render: (_, record) => {
98
- if (!record.currentPhase) return '-';
99
- const item = TASK_PHASE[record.currentPhase as keyof typeof TASK_PHASE];
100
- return item ? <Tag color={item.color}>{item.label}</Tag> : '-';
101
- },
102
- },
103
- {
104
- title: t('progressDesc'),
105
- dataIndex: 'progressDesc',
106
- search: false,
107
- ellipsis: true,
108
- width: 180,
109
- },
110
- {
111
- title: t('errorMessage'),
112
- dataIndex: 'errorMessage',
113
- search: false,
114
- ellipsis: true,
115
- width: 200,
116
- render: (_, record) => record.errorMessage || '-',
117
- },
118
- {
119
- title: t('createdBy'),
120
- dataIndex: 'createdBy',
121
- search: false,
122
- width: 100,
123
- },
124
- {
125
- title: t('createTime'),
126
- dataIndex: 'createTime',
127
- search: false,
128
- width: 180,
129
- },
130
- {
131
- title: tc('operation'),
132
- key: 'action',
133
- fixed: 'right',
134
- search: false,
135
- width: 200,
136
- render: (_, record) => (
137
- <Space>
138
- {(record.status === 'RUNNING' || record.status === 'PENDING') && (
139
- <Access code="aps:task:cancel">
140
- <Popconfirm title={t('cancelConfirm')} onConfirm={handleCancel(record.taskId)}>
141
- <a>{t('actions.cancel')}</a>
142
- </Popconfirm>
143
- </Access>
144
- )}
145
- {(record.status === 'FAILED' || record.status === 'CANCELLED' || record.status === 'PAUSED') && (
146
- <Access code="aps:task:resume">
147
- <Popconfirm title={t('resumeConfirm')} onConfirm={handleResume(record.taskId)}>
148
- <a>{t('actions.resume')}</a>
149
- </Popconfirm>
150
- </Access>
151
- )}
152
- {record.status === 'COMPLETED' && record.resultRef && (
153
- <Access code="aps:plan:query">
154
- <a onClick={() => navigate(`/aps/plan?planId=${record.resultRef}`)}>{t('actions.viewResult')}</a>
155
- </Access>
156
- )}
157
- <Access code="aps:task:delete">
158
- <Popconfirm title={t('deleteConfirm')} onConfirm={handleDelete(record.taskId)}>
159
- <a style={{ color: '#ff4d4f' }}>{t('actions.delete')}</a>
160
- </Popconfirm>
161
- </Access>
162
- </Space>
163
- ),
164
- },
165
- ];
166
-
167
- return (
168
- <ProTable<OptimizationTaskVO>
169
- columns={columns}
170
- actionRef={actionRef}
171
- rowKey="taskId"
172
- headerTitle={t('title')}
173
- request={async (params) => {
174
- const { current, pageSize, ...rest } = params;
175
- const { data } = await getTaskPage({
176
- pageNo: current!,
177
- pageSize: pageSize!,
178
- ...rest,
179
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
180
- } as any);
181
- return { data: data.list, total: data.total, success: true };
182
- }}
183
- pagination={{ defaultPageSize: 10, showSizeChanger: true }}
184
- scroll={{ x: 1600 }}
185
- polling={5000} // Auto-refresh every 5 seconds for running tasks
186
- />
187
- );
188
- };
189
-
190
- export default TaskPage;