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,273 +0,0 @@
1
- import { useRef, useState } from 'react';
2
- import { App, Button, Space, Tag, Upload } from 'antd';
3
- import { PlusOutlined, UploadOutlined, DownloadOutlined, DeleteOutlined } from '@ant-design/icons';
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 {
9
- getOrderPage,
10
- deleteOrder,
11
- importOrders,
12
- exportOrders,
13
- downloadOrderTemplate,
14
- } from '@/api/aps/order';
15
- import type { OrderVO } from '@/types/aps/order';
16
- import { ORDER_STATUS, ORDER_PRIORITY } from '@/types/aps/order';
17
- import OrderDrawer from './components/OrderDrawer';
18
-
19
- const OrderPage: React.FC = () => {
20
- const { t } = useTranslation('aps/order');
21
- const { t: tc } = useTranslation('common');
22
- const { message, modal } = App.useApp();
23
- const actionRef = useRef<ActionType>(null);
24
- const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
25
- const [drawerOpen, setDrawerOpen] = useState(false);
26
- const [editId, setEditId] = useState<number | null>(null);
27
-
28
- const reload = () => actionRef.current?.reload();
29
-
30
- const handleDelete = (record: OrderVO) => {
31
- modal.confirm({
32
- title: t('deleteConfirm'),
33
- okType: 'danger',
34
- content: t('deleteConfirmContent', { name: record.orderId }),
35
- onOk: async () => {
36
- await deleteOrder(record.id);
37
- message.success(tc('success'));
38
- reload();
39
- },
40
- });
41
- };
42
-
43
- const handleDeleteBatch = () => {
44
- modal.confirm({
45
- title: t('deleteConfirm'),
46
- okType: 'danger',
47
- content: t('deleteBatchConfirmContent', { count: selectedRowKeys.length }),
48
- onOk: async () => {
49
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
- await Promise.all(selectedRowKeys.map((id) => deleteOrder(id as any)));
51
- message.success(tc('success'));
52
- setSelectedRowKeys([]);
53
- reload();
54
- },
55
- });
56
- };
57
-
58
- const handleImport = async (file: File) => {
59
- const result = await importOrders(file);
60
- if (result.data.failCount === 0) {
61
- message.success(t('importSuccess', { count: result.data.successCount }));
62
- } else {
63
- message.warning(t('importFailed', { count: result.data.failCount }));
64
- }
65
- reload();
66
- return false;
67
- };
68
-
69
- const handleExport = async () => {
70
- await exportOrders({});
71
- message.success(tc('success'));
72
- };
73
-
74
- const handleDownloadTemplate = async () => {
75
- await downloadOrderTemplate();
76
- message.success(tc('success'));
77
- };
78
-
79
- const columns: ProColumns<OrderVO>[] = [
80
- {
81
- title: t('orderId'),
82
- dataIndex: 'orderId',
83
- ellipsis: true,
84
- width: 100,
85
- },
86
- {
87
- title: t('customerName'),
88
- dataIndex: 'customerName',
89
- ellipsis: true,
90
- width: 120,
91
- },
92
- {
93
- title: t('alloy'),
94
- dataIndex: 'alloy',
95
- search: false,
96
- width: 80,
97
- },
98
- {
99
- title: t('temper'),
100
- dataIndex: 'temper',
101
- search: false,
102
- width: 80,
103
- },
104
- {
105
- title: t('width'),
106
- dataIndex: 'width',
107
- search: false,
108
- width: 80,
109
- },
110
- {
111
- title: t('thickness'),
112
- dataIndex: 'thickness',
113
- search: false,
114
- width: 80,
115
- },
116
- {
117
- title: t('demand'),
118
- dataIndex: 'demand',
119
- search: false,
120
- width: 100,
121
- },
122
- {
123
- title: t('assigned'),
124
- dataIndex: 'assigned',
125
- search: false,
126
- width: 100,
127
- },
128
- {
129
- title: t('deliveryDate'),
130
- dataIndex: 'deliveryDate',
131
- search: false,
132
- width: 120,
133
- },
134
- {
135
- title: t('priority'),
136
- dataIndex: 'priority',
137
- valueType: 'select',
138
- valueEnum: {
139
- 1: { text: ORDER_PRIORITY[1].label },
140
- 2: { text: ORDER_PRIORITY[2].label },
141
- 3: { text: ORDER_PRIORITY[3].label },
142
- 4: { text: ORDER_PRIORITY[4].label },
143
- 5: { text: ORDER_PRIORITY[5].label },
144
- },
145
- width: 80,
146
- render: (_, record) => {
147
- const item = ORDER_PRIORITY[record.priority as keyof typeof ORDER_PRIORITY];
148
- return item ? <Tag color={item.color}>{item.label}</Tag> : '-';
149
- },
150
- },
151
- {
152
- title: t('status'),
153
- dataIndex: 'status',
154
- valueType: 'select',
155
- valueEnum: {
156
- 0: { text: ORDER_STATUS[0].label, status: 'Default' },
157
- 1: { text: ORDER_STATUS[1].label, status: 'Processing' },
158
- 2: { text: ORDER_STATUS[2].label, status: 'Success' },
159
- 3: { text: ORDER_STATUS[3].label, status: 'Error' },
160
- },
161
- width: 100,
162
- render: (_, record) => {
163
- const item = ORDER_STATUS[record.status as keyof typeof ORDER_STATUS];
164
- return item ? <Tag color={item.color}>{item.label}</Tag> : '-';
165
- },
166
- },
167
- {
168
- title: t('createTime'),
169
- dataIndex: 'createTime',
170
- search: false,
171
- width: 180,
172
- },
173
- {
174
- title: tc('operation'),
175
- key: 'action',
176
- fixed: 'right',
177
- search: false,
178
- width: 150,
179
- render: (_, record) => (
180
- <Space>
181
- <Access code="aps:order:update">
182
- <a
183
- onClick={() => {
184
- setEditId(record.id);
185
- setDrawerOpen(true);
186
- }}
187
- >
188
- {tc('edit')}
189
- </a>
190
- </Access>
191
- <Access code="aps:order:delete">
192
- <a style={{ color: '#ff4d4f' }} onClick={() => handleDelete(record)}>
193
- {tc('delete')}
194
- </a>
195
- </Access>
196
- </Space>
197
- ),
198
- },
199
- ];
200
-
201
- return (
202
- <>
203
- <ProTable<OrderVO>
204
- columns={columns}
205
- actionRef={actionRef}
206
- rowKey="id"
207
- headerTitle={t('title')}
208
- scroll={{ x: 1400 }}
209
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
210
- request={async (params: any) => {
211
- const { current, pageSize, ...rest } = params;
212
- const { data } = await getOrderPage({
213
- pageNo: current ?? 1,
214
- pageSize: pageSize ?? 10,
215
- ...rest,
216
- });
217
- return { data: data.list, total: data.total, success: true };
218
- }}
219
- pagination={{ defaultPageSize: 10, showSizeChanger: true }}
220
- rowSelection={{ selectedRowKeys, onChange: setSelectedRowKeys }}
221
- toolBarRender={() => [
222
- <Access code="aps:order:create" key="add">
223
- <Button
224
- type="primary"
225
- icon={<PlusOutlined />}
226
- onClick={() => {
227
- setEditId(null);
228
- setDrawerOpen(true);
229
- }}
230
- >
231
- {tc('create')}
232
- </Button>
233
- </Access>,
234
- <Access code="aps:order:import" key="import">
235
- <Upload accept=".xlsx,.xls" showUploadList={false} beforeUpload={handleImport}>
236
- <Button icon={<UploadOutlined />}>{t('import')}</Button>
237
- </Upload>
238
- </Access>,
239
- <Access code="aps:order:export" key="export">
240
- <Button icon={<DownloadOutlined />} onClick={handleExport}>
241
- {t('export')}
242
- </Button>
243
- </Access>,
244
- <Access code="aps:order:delete" key="batch">
245
- <Button
246
- danger
247
- icon={<DeleteOutlined />}
248
- disabled={selectedRowKeys.length === 0}
249
- onClick={handleDeleteBatch}
250
- >
251
- {t('deleteBatch')}
252
- </Button>
253
- </Access>,
254
- <Button key="template" icon={<DownloadOutlined />} onClick={handleDownloadTemplate}>
255
- {t('downloadTemplate')}
256
- </Button>,
257
- ]}
258
- />
259
-
260
- <OrderDrawer
261
- open={drawerOpen}
262
- id={editId}
263
- onSuccess={() => {
264
- setDrawerOpen(false);
265
- reload();
266
- }}
267
- onClose={() => setDrawerOpen(false)}
268
- />
269
- </>
270
- );
271
- };
272
-
273
- export default OrderPage;
@@ -1,153 +0,0 @@
1
- import { useEffect, useState, useCallback } from 'react';
2
- import { Card, Form, InputNumber, Button, Space, Popconfirm, message, Divider } from 'antd';
3
- import { useTranslation } from 'react-i18next';
4
- import { Access } from '@/components/Access';
5
- import { getParamList, saveParams, resetParams } from '@/api/aps/param';
6
- import type { ProcessParamVO } from '@/types/aps/param';
7
- import { PARAM_NAMES } from '@/types/aps/param';
8
-
9
- const ParamPage: React.FC = () => {
10
- const { t } = useTranslation('aps/param');
11
- const { t: tc } = useTranslation('common');
12
- const [form] = Form.useForm();
13
- const [loading, setLoading] = useState(false);
14
- const [params, setParams] = useState<ProcessParamVO[]>([]);
15
-
16
- const loadParams = useCallback(async () => {
17
- setLoading(true);
18
- try {
19
- const res = await getParamList();
20
- setParams(res.data);
21
- const formValues: Record<string, string> = {};
22
- res.data.forEach((p) => {
23
- formValues[p.paramName] = p.paramValue;
24
- });
25
- form.setFieldsValue(formValues);
26
- } finally {
27
- setLoading(false);
28
- }
29
- }, [form]);
30
-
31
- useEffect(() => {
32
- // eslint-disable-next-line react-hooks/set-state-in-effect
33
- loadParams();
34
- }, [loadParams]);
35
-
36
- const handleSave = async () => {
37
- try {
38
- const values = form.getFieldsValue();
39
-
40
- // Validate weight sum
41
- const utilWeight = parseFloat(values[PARAM_NAMES.UTILIZATION_WEIGHT] || '0');
42
- const priorityWeight = parseFloat(values[PARAM_NAMES.PRIORITY_WEIGHT] || '0');
43
- const cutsWeight = parseFloat(values[PARAM_NAMES.CUTS_WEIGHT] || '0');
44
- const weightSum = utilWeight + priorityWeight + cutsWeight;
45
-
46
- if (Math.abs(weightSum - 1.0) > 0.001) {
47
- message.error(t('weightSumError', { sum: weightSum.toFixed(2) }));
48
- return;
49
- }
50
-
51
- const paramsToSave = Object.entries(values).map(([paramName, paramValue]) => {
52
- const existingParam = params.find(p => p.paramName === paramName);
53
- return {
54
- paramName,
55
- paramValue: String(paramValue),
56
- paramUnit: existingParam?.paramUnit || '',
57
- description: existingParam?.description || '',
58
- };
59
- });
60
-
61
- await saveParams(paramsToSave);
62
- message.success(t('saveSuccess'));
63
- loadParams();
64
- } catch {
65
- // Error handling
66
- }
67
- };
68
-
69
- const handleReset = async () => {
70
- await resetParams();
71
- message.success(t('resetSuccess'));
72
- loadParams();
73
- };
74
-
75
- const basicParams = [
76
- PARAM_NAMES.EDGE_WASTE_WIDTH,
77
- PARAM_NAMES.HEAD_TAIL_WASTE,
78
- PARAM_NAMES.CUT_HEAD_LENGTH,
79
- PARAM_NAMES.MAX_VERTICAL_CUTS,
80
- PARAM_NAMES.MAX_HORIZONTAL_CUTS,
81
- PARAM_NAMES.MIN_ORDER_WIDTH,
82
- ];
83
-
84
- const weightParams: string[] = [
85
- PARAM_NAMES.UTILIZATION_WEIGHT,
86
- PARAM_NAMES.PRIORITY_WEIGHT,
87
- PARAM_NAMES.CUTS_WEIGHT,
88
- ];
89
-
90
- const otherParams = [
91
- PARAM_NAMES.MIN_REGION_LENGTH,
92
- PARAM_NAMES.MAX_ORDER_SPLIT,
93
- ];
94
-
95
- const getParamUnit = (paramName: string) => {
96
- const param = params.find((p) => p.paramName === paramName);
97
- return param?.paramUnit || '';
98
- };
99
-
100
- const renderParamInput = (paramName: string) => {
101
- const unit = getParamUnit(paramName);
102
- const isWeight = weightParams.includes(paramName);
103
-
104
- return (
105
- <Form.Item
106
- key={paramName}
107
- name={paramName}
108
- label={t(`paramNames.${paramName}`)}
109
- rules={[{ required: true, message: tc('required') }]}
110
- >
111
- <InputNumber
112
- min={0}
113
- step={isWeight ? 0.1 : 1}
114
- style={{ width: '100%' }}
115
- addonAfter={unit || undefined}
116
- />
117
- </Form.Item>
118
- );
119
- };
120
-
121
- return (
122
- <Form form={form} layout="vertical">
123
- <Card title={t('paramGroups.basic')} style={{ marginBottom: 16 }}>
124
- {basicParams.map(renderParamInput)}
125
- </Card>
126
-
127
- <Card title={t('paramGroups.weight')} style={{ marginBottom: 16 }}>
128
- {weightParams.map(renderParamInput)}
129
- </Card>
130
-
131
- <Card title={t('paramGroups.other')} style={{ marginBottom: 16 }}>
132
- {otherParams.map(renderParamInput)}
133
- </Card>
134
-
135
- <Divider />
136
-
137
- <Space>
138
- <Access code="aps:param:update">
139
- <Button type="primary" onClick={handleSave} loading={loading}>
140
- {t('save')}
141
- </Button>
142
- </Access>
143
- <Access code="aps:param:update">
144
- <Popconfirm title={t('resetConfirm')} onConfirm={handleReset}>
145
- <Button loading={loading}>{t('reset')}</Button>
146
- </Popconfirm>
147
- </Access>
148
- </Space>
149
- </Form>
150
- );
151
- };
152
-
153
- export default ParamPage;