create-dwy 0.25.3 → 0.27.0
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/CHANGELOG.md +20 -0
- package/package.json +1 -1
- package/src/sync-all.js +46 -2
- package/src/sync-plan.js +9 -1
- package/templates/ai-tools/CHANGELOG.md +17 -0
- package/templates/ai-tools/VERSION +1 -1
- package/templates/ai-tools/skills/Apple/dwy-apple-appkit/SKILL.md +17 -0
- package/templates/ai-tools/skills/Apple/dwy-apple-architecture/SKILL.md +12 -0
- package/templates/ai-tools/skills/Apple/dwy-apple-architecture/references/extraction.md +9 -0
- package/templates/ai-tools/{rules/iOS/dwy-apple-layering.md → skills/Apple/dwy-apple-architecture/references/layering.md} +2 -10
- package/templates/ai-tools/skills/Apple/dwy-apple-architecture/references/pitfalls.md +3 -0
- package/templates/ai-tools/skills/Apple/dwy-ios-development/SKILL.md +14 -0
- package/templates/ai-tools/skills/Apple/dwy-ios-development/references/appearance.md +6 -0
- package/templates/ai-tools/{rules/iOS/dwy-ios-layout-adaptation.md → skills/Apple/dwy-ios-development/references/layout.md} +0 -6
- package/templates/ai-tools/{rules/iOS/dwy-ios-pitfalls.md → skills/Apple/dwy-ios-development/references/pitfalls.md} +1 -9
- package/templates/ai-tools/skills/Apple/dwy-ios-development/references/presentations.md +11 -0
- package/templates/ai-tools/skills/Apple/dwy-macos-development/SKILL.md +14 -0
- package/templates/ai-tools/skills/Apple/dwy-macos-development/references/pitfalls.md +9 -0
- package/templates/ai-tools/skills/Apple/dwy-macos-development/references/presentations.md +5 -0
- package/templates/ai-tools/skills/Apple/dwy-macos-development/references/ui-adaptation.md +6 -0
- package/templates/ai-tools/skills/Apple/dwy-swift-development/SKILL.md +16 -0
- package/templates/ai-tools/{rules/iOS/dwy-swift-core.md → skills/Apple/dwy-swift-development/references/conventions.md} +2 -8
- package/templates/ai-tools/skills/Apple/dwy-swift-development/references/pitfalls.md +5 -0
- package/templates/ai-tools/skills/Apple/dwy-swift-development/references/presentations.md +8 -0
- package/templates/ai-tools/skills/Python/dwy-apple-notify/SKILL.md +24 -0
- package/templates/ai-tools/skills/Python/dwy-apple-notify/references/v0/0.1.6.md +81 -0
- package/templates/ai-tools/skills/Python/dwy-auth/SKILL.md +24 -0
- package/templates/ai-tools/skills/Python/dwy-auth/references/v0/0.2.0.md +163 -0
- package/templates/ai-tools/skills/Python/dwy-device-fingerprint/SKILL.md +19 -0
- package/templates/ai-tools/skills/Python/dwy-device-fingerprint/references/v0/0.1.1.md +90 -0
- package/templates/ai-tools/skills/Python/dwy-eapi/SKILL.md +1 -1
- package/templates/ai-tools/skills/Python/dwy-eapi/versions.yml +3 -3
- package/templates/ai-tools/skills/Python/dwy-email-notify/SKILL.md +19 -0
- package/templates/ai-tools/skills/Python/dwy-email-notify/references/v0/0.1.0.md +31 -0
- package/templates/ai-tools/skills/Python/dwy-notify/SKILL.md +24 -0
- package/templates/ai-tools/skills/Python/dwy-notify/references/v0/0.3.2.md +128 -0
- package/templates/ai-tools/skills/Python/dwy-payment/SKILL.md +19 -0
- package/templates/ai-tools/skills/Python/dwy-payment/references/v0/0.3.0.md +90 -0
- package/templates/ai-tools/skills/Python/dwy-python-api/SKILL.md +8 -0
- package/templates/ai-tools/skills/Python/dwy-python-architecture/SKILL.md +8 -0
- package/templates/ai-tools/skills/Python/dwy-python-development/SKILL.md +17 -0
- package/templates/ai-tools/{rules/Python → skills/Python/dwy-python-development/references}/dwy-python-base-lib.md +3 -3
- package/templates/ai-tools/skills/Python/dwy-webhooks/SKILL.md +24 -0
- package/templates/ai-tools/skills/Python/dwy-webhooks/references/v0/0.6.2.md +238 -0
- package/templates/ai-tools/skills/Python/dwy-wechatpay-notify/SKILL.md +19 -0
- package/templates/ai-tools/skills/Python/dwy-wechatpay-notify/references/v0/0.1.1.md +101 -0
- package/templates/ai-tools/skills/Vue/dwy-admin-kit/SKILL.md +12 -0
- package/templates/ai-tools/skills/Vue/dwy-admin-kit/references/v0/0.3.0.md +176 -0
- package/templates/ai-tools/skills/Vue/dwy-auth-web/SKILL.md +10 -0
- package/templates/ai-tools/skills/Vue/dwy-ekit/SKILL.md +2 -3
- package/templates/ai-tools/skills/Vue/dwy-eui/SKILL.md +1 -1
- package/templates/ai-tools/skills/Vue/dwy-eui/versions.yml +2 -2
- package/templates/ai-tools/skills/Vue/dwy-vue-architecture/SKILL.md +8 -0
- package/templates/ai-tools/skills/Vue/dwy-vue-development/SKILL.md +16 -0
- package/templates/ai-tools/{rules/Vue → skills/Vue/dwy-vue-development/references}/dwy-vue-base-lib.md +3 -3
- package/templates/ai-tools/skills//344/272/247/345/223/2010/345/210/2601/dwy-architecture/SKILL.md +6 -6
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-commercial-sdk/SKILL.md +20 -0
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-github-action-publish/SKILL.md +1 -1
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/SKILL.md +6 -2
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/android.md +2 -2
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/backend-deploy.md +1 -1
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/frontend-deploy.md +1 -1
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/generic-release.md +2 -2
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/harmony.md +2 -2
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/ios.md +2 -2
- package/templates/ai-tools/skills//351/200/232/347/224/250/dwy-dependency-choice/SKILL.md +2 -2
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/SKILL.md +0 -244
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/assets/files-whitelist-snippet.json +0 -22
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/assets/js-commercial.npmignore +0 -76
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/assets/python-commercial-MANIFEST.in +0 -37
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/assets/python-commercial.gitignore +0 -62
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/references/js-commercial-guide.md +0 -133
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/references/publish-blacklist.md +0 -106
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/references/python-commercial-guide.md +0 -147
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/references/sensitive-patterns.md +0 -112
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/scripts/check_comments.py +0 -260
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/scripts/check_js_publish.sh +0 -110
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/scripts/check_python_publish.sh +0 -171
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/scripts/detect_sdk.sh +0 -71
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/scripts/init_config.sh +0 -91
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-semver/SKILL.md +0 -136
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-semver/references/semver-spec.md +0 -70
- package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-semver/scripts/bump.py +0 -137
- /package/templates/ai-tools/{rules/Python → skills/Python/dwy-python-api/references}/dwy-python-backend.md +0 -0
- /package/templates/ai-tools/{rules/Python → skills/Python/dwy-python-architecture/references}/dwy-python-layering.md +0 -0
- /package/templates/ai-tools/{rules/Python → skills/Python/dwy-python-development/references}/dwy-python-core.md +0 -0
- /package/templates/ai-tools/{rules/Python → skills/Python/dwy-python-development/references}/dwy-python-pitfalls.md +0 -0
- /package/templates/ai-tools/{rules/Python → skills/Python/dwy-python-development/references}/dwy-python-testing.md +0 -0
- /package/templates/ai-tools/{rules/Vue → skills/Vue/dwy-vue-architecture/references}/dwy-vue-layering.md +0 -0
- /package/templates/ai-tools/{rules/Vue → skills/Vue/dwy-vue-development/references}/dwy-vue-core.md +0 -0
- /package/templates/ai-tools/{rules/Vue → skills/Vue/dwy-vue-development/references}/dwy-vue-pinia.md +0 -0
- /package/templates/ai-tools/{rules/Vue → skills/Vue/dwy-vue-development/references}/dwy-vue-pitfalls.md +0 -0
- /package/templates/ai-tools/{rules/Vue → skills/Vue/dwy-vue-development/references}/dwy-vue-testing.md +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# create-dwy
|
|
2
2
|
|
|
3
|
+
## [0.27.0] - 2026-11-07
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- 新增 Python、Vue 和 Apple 按需开发、架构与基础库 Skills;按版本查找公开接口和接入说明。
|
|
8
|
+
- 迁移 Python、Vue 旧托管 Rules,推荐对应 Skills;未选择替代项时保留旧内容,预览并保护个人配置。其他技术栈 Rules 保持可用。
|
|
9
|
+
- 修正 EUI、EAPI 版本线匹配范围和 Ekit Skill 元数据;模板详情见 ai-tools 0.34.0。
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## [0.26.0] - 2026-11-06
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- `dwy-publish` 独立判断发版版本,移除 `dwy-semver`;已有安装需改用 `dwy-publish`。
|
|
18
|
+
- `dwy-sdk-spec` 改为 `dwy-commercial-sdk`,依据项目实际商业 SDK 保护要求检查,不再缓存项目配置;已有安装需选择新 skill,旧入口需自行移除。
|
|
19
|
+
- 模板详情见 ai-tools 0.33.0。
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
3
23
|
## [0.25.3] - 2026-11-06
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
package/package.json
CHANGED
package/src/sync-all.js
CHANGED
|
@@ -134,6 +134,7 @@ async function managedNames(root, global, codexHome) {
|
|
|
134
134
|
for (const name of await fs.readdir(path.join(codexHome, 'skills'))) codexSkills.add(name)
|
|
135
135
|
}
|
|
136
136
|
return {
|
|
137
|
+
projectRules,
|
|
137
138
|
claude: { skills: await scanExisting(claude, 'skills'), rules: unionSets(projectRules, await scanExisting(claude, 'rules')), hooks: await scanExisting(claude, 'hooks') },
|
|
138
139
|
codex: { skills: codexSkills, rules: projectRules, hooks: await scanExistingCodexHooks(root, global ? codexHome : path.join(root, '.codex')) },
|
|
139
140
|
opencode: { skills: await scanExisting(opencode, 'skills'), rules: projectRules, hooks: new Set() },
|
|
@@ -141,13 +142,39 @@ async function managedNames(root, global, codexHome) {
|
|
|
141
142
|
}
|
|
142
143
|
}
|
|
143
144
|
|
|
145
|
+
const RULE_SKILL_MIGRATIONS = {
|
|
146
|
+
'dwy-python-core.md': ['dwy-python-development'],
|
|
147
|
+
'dwy-python-testing.md': ['dwy-python-development'],
|
|
148
|
+
'dwy-python-pitfalls.md': ['dwy-python-development'],
|
|
149
|
+
'dwy-python-base-lib.md': ['dwy-python-development', 'dwy-eapi'],
|
|
150
|
+
'dwy-python-backend.md': ['dwy-python-api'],
|
|
151
|
+
'dwy-python-layering.md': ['dwy-python-architecture'],
|
|
152
|
+
'dwy-vue-core.md': ['dwy-vue-development'],
|
|
153
|
+
'dwy-vue-testing.md': ['dwy-vue-development'],
|
|
154
|
+
'dwy-vue-pitfalls.md': ['dwy-vue-development'],
|
|
155
|
+
'dwy-vue-pinia.md': ['dwy-vue-development'],
|
|
156
|
+
'dwy-vue-base-lib.md': ['dwy-vue-development', 'dwy-eui', 'dwy-ekit'],
|
|
157
|
+
'dwy-vue-layering.md': ['dwy-vue-architecture'],
|
|
158
|
+
'dwy-swift-core.md': ['dwy-swift-development'],
|
|
159
|
+
'dwy-apple-layering.md': ['dwy-apple-architecture'],
|
|
160
|
+
'dwy-ios-layout-adaptation.md': ['dwy-ios-development'],
|
|
161
|
+
'dwy-ios-pitfalls.md': ['dwy-ios-development'],
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** 将旧托管规则映射为可选的对应技能,保留用户最终选择。 */
|
|
165
|
+
export function migratedRuleSkills(names) {
|
|
166
|
+
return new Set([...names].flatMap(name => RULE_SKILL_MIGRATIONS[name] || []))
|
|
167
|
+
}
|
|
168
|
+
|
|
144
169
|
function staleEntries(scans, state, existing, platforms) {
|
|
145
170
|
const current = Object.fromEntries(['skills', 'rules', 'hooks'].map(type => [type, new Set(scans[type].map(item => item.name))]))
|
|
146
171
|
const result = {}
|
|
147
172
|
for (const platform of platforms) {
|
|
148
173
|
result[platform] = {}
|
|
149
174
|
for (const type of PLATFORM_SYNC_TYPES[platform].filter(type => current[type])) {
|
|
150
|
-
|
|
175
|
+
const historical = state.platforms[platform]?.[type] || []
|
|
176
|
+
const knownRules = type === 'rules' && platform !== 'cursor' ? [...existing.projectRules].filter(name => RULE_SKILL_MIGRATIONS[name]) : []
|
|
177
|
+
result[platform][type] = [...new Set([...historical, ...knownRules])].filter(name =>
|
|
151
178
|
!current[type].has(name) && existing[platform][type].has(platform === 'cursor' && type === 'rules' ? buildCursorRuleName(name) : name))
|
|
152
179
|
}
|
|
153
180
|
}
|
|
@@ -274,11 +301,16 @@ export async function syncAll({
|
|
|
274
301
|
if (contentTypes.some(type => !allowed.has(type))) throw new Error('所选范围或平台不支持此同步内容')
|
|
275
302
|
if (contentTypes.length === 0) { console.log('未选择处理内容。'); return }
|
|
276
303
|
const existing = await managedNames(targetRoot, global, codexHome)
|
|
277
|
-
const cursorRules = new Set(scans.rules.
|
|
304
|
+
const cursorRules = new Set([...scans.rules.map(rule => rule.name), ...Object.keys(RULE_SKILL_MIGRATIONS)]
|
|
305
|
+
.filter(name => existing.cursor.rules.has(buildCursorRuleName(name))))
|
|
278
306
|
const current = Object.fromEntries(['skills', 'rules', 'hooks'].map(type => [type,
|
|
279
307
|
unionSets(...platforms.map(platform => platform === 'cursor' && type === 'rules' ? cursorRules : existing[platform][type]))]))
|
|
280
308
|
const defaults = buildSelectionDefaultsFromSyncState(current, targetState, platforms)
|
|
281
309
|
for (const type of ['skills', 'rules', 'hooks']) defaults[type] = unionSets(defaults[type], current[type])
|
|
310
|
+
if (!global && contentTypes.includes('skills')) {
|
|
311
|
+
const oldRules = unionSets(current.rules, ...platforms.map(platform => new Set(targetState.platforms[platform]?.rules || [])))
|
|
312
|
+
defaults.skills = unionSets(defaults.skills, migratedRuleSkills(oldRules))
|
|
313
|
+
}
|
|
282
314
|
const choices = !global && contentTypes.includes('skills')
|
|
283
315
|
? { ...scans, skills: await projectSkillChoices(scans.skills, platforms, { homeDir, codexHome }) } : scans
|
|
284
316
|
const selected = selectedOverride
|
|
@@ -329,10 +361,22 @@ export async function syncAll({
|
|
|
329
361
|
if (mainFlow) contentTypes = contentTypes.filter(type => options.some(option => option.value === type))
|
|
330
362
|
const stale = staleEntries(scans, targetState, existing, platforms)
|
|
331
363
|
const removals = normalizeRemovals(removalsOverride || stale)
|
|
364
|
+
if (!removalsOverride) {
|
|
365
|
+
const availableSkills = new Set(scans.skills.map(skill => skill.name))
|
|
366
|
+
const selectedSkills = new Set(selected.skills.map(skill => skill.name).filter(name => availableSkills.has(name)))
|
|
367
|
+
for (const platform of platforms) for (const name of removals[platform]?.rules || []) {
|
|
368
|
+
const required = RULE_SKILL_MIGRATIONS[name]
|
|
369
|
+
if (required && (platform === 'cursor' || !contentTypes.includes('skills') || required.some(skill => !selectedSkills.has(skill)))) {
|
|
370
|
+
removals[platform].rules.delete(name)
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
332
374
|
const baseline = contentTypes.some(type => type === 'rules' || type === 'baseline') ? await readBaselineDoc(sourceDir) : ''
|
|
333
375
|
const plan = await buildSyncPlan({
|
|
334
376
|
scope, platforms, contentTypes, selected, scans, sourceDir, projectDir, homeDir, codexHome,
|
|
335
377
|
projectState, globalState, staleRemovals: removals, staleEntries: stale, baseline,
|
|
378
|
+
migratedRuleSources: Object.fromEntries(Object.entries(RULE_SKILL_MIGRATIONS).map(([name, skills]) => [name,
|
|
379
|
+
path.join(sourceDir, 'skills', name.startsWith('dwy-python-') ? 'Python' : name.startsWith('dwy-vue-') ? 'Vue' : 'Apple', skills[0], 'references', name)])),
|
|
336
380
|
contentActions,
|
|
337
381
|
refreshSkills: mainFlow,
|
|
338
382
|
skillScope: normalizeSkillScope(skillScopeOverride),
|
package/src/sync-plan.js
CHANGED
|
@@ -74,6 +74,7 @@ function ownedGlobalRoots(platform, homeDir, codexHome) {
|
|
|
74
74
|
export async function buildSyncPlan({
|
|
75
75
|
scope, platforms, contentTypes, selected, scans, sourceDir, projectDir, homeDir, codexHome,
|
|
76
76
|
projectState, globalState, staleRemovals = {}, staleEntries = {}, baseline,
|
|
77
|
+
migratedRuleSources = {},
|
|
77
78
|
contentActions = {},
|
|
78
79
|
refreshSkills = false,
|
|
79
80
|
skillScope = { destinations: ['project'], globalSkills: [] },
|
|
@@ -229,8 +230,9 @@ export async function buildSyncPlan({
|
|
|
229
230
|
const selectedNames = new Set(selected.rules.map(item => item.name))
|
|
230
231
|
const rules = scans.rules.filter(rule => selectedNames.has(rule.name))
|
|
231
232
|
const preserved = new Set(cliPlatforms.flatMap(platform => retained(platform, 'rules')))
|
|
233
|
+
const removed = [...new Set(cliPlatforms.flatMap(platform => approved(platform, 'rules')))]
|
|
232
234
|
if (cliPlatforms.length) {
|
|
233
|
-
await addConfig('rules',
|
|
235
|
+
await addConfig('rules', `更新项目 Rules(保留通用规范和手写内容)${removed.length ? `;移除旧托管项:${removed.join('、')}` : ''}`, [path.join(projectDir, 'AGENTS.md')], projectDir,
|
|
234
236
|
() => syncProjectAgentsMd(projectDir, rules, { preservedRuleNames: preserved }))
|
|
235
237
|
const names = [...new Set([...rules.map(rule => rule.name), ...preserved])].sort()
|
|
236
238
|
for (const platform of ['claude', 'codex', 'opencode']) {
|
|
@@ -251,7 +253,13 @@ export async function buildSyncPlan({
|
|
|
251
253
|
if (platforms.includes('claude')) {
|
|
252
254
|
const names = new Set([...scans.rules.map(rule => rule.name), ...approved('claude', 'rules')])
|
|
253
255
|
for (const name of names) {
|
|
256
|
+
if (!scans.rules.some(rule => rule.name === name) && !(projectState.platforms.claude?.rules || []).includes(name)) continue
|
|
254
257
|
const dest = path.join(projectDir, '.claude', 'rules', name)
|
|
258
|
+
if (migratedRuleSources[name] && await existsEntry(dest)) {
|
|
259
|
+
const reference = migratedRuleSources[name]
|
|
260
|
+
if (!(await fs.lstat(dest)).isFile()) continue
|
|
261
|
+
if (!await fs.pathExists(reference) || await fs.readFile(dest, 'utf8') !== await fs.readFile(reference, 'utf8')) continue
|
|
262
|
+
}
|
|
255
263
|
if (safeName(name) && await existsEntry(dest)) add('legacy-rule', '清理旧项目规则入口', [dest], () => fs.remove(dest))
|
|
256
264
|
}
|
|
257
265
|
}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# ai-tools 内部版本
|
|
2
2
|
|
|
3
|
+
## 0.34.0 - 2026-11-07
|
|
4
|
+
|
|
5
|
+
- 新增 `skills/Python/dwy-python-*`、Python 基础包 Skills、`skills/Vue/dwy-vue-*`、管理与认证包 Skills,以及 `skills/Apple/dwy-apple-appkit`;按能力和实际版本导航,保留已发布版本接入资料。
|
|
6
|
+
- 将 `rules/Python/` 和 `rules/Vue/` 的技术规范迁入对应 Skills 的参考资料;Apple 开发规范使用 Swift、iOS、macOS 和架构 Skills。
|
|
7
|
+
- 修复 `skills/Vue/dwy-ekit/SKILL.md` 的非标准元数据,收紧 EUI 和 EAPI 版本线;无法确定安装版本时不再假定版本。
|
|
8
|
+
|
|
9
|
+
|
|
3
10
|
本目录(`dwy-cli/templates/ai-tools`)rules / skills / hooks / commands / CLAUDE.md 等模板资产的**内部版本**,与 `create-dwy` npm 版本**解耦**。
|
|
4
11
|
|
|
5
12
|
- 当前版本:见同目录 `VERSION`(单一事实源)
|
|
@@ -52,6 +59,16 @@
|
|
|
52
59
|
|
|
53
60
|
---
|
|
54
61
|
|
|
62
|
+
## 0.33.0 — 2026-11-06
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
- `skills/发布发版/dwy-publish`:内置发版版本决策,不再依赖 `dwy-semver`。
|
|
66
|
+
- `skills/发布发版/dwy-commercial-sdk`:替代 `dwy-sdk-spec`,按项目商业 SDK 的实际保护要求检查,不再使用项目配置缓存或强制指定编译方案。
|
|
67
|
+
- 迁移:发版版本判断改用 `dwy-publish`;商业 SDK 检查选择 `dwy-commercial-sdk`。已安装的旧 skill 不会自动删除,按需移除旧入口。
|
|
68
|
+
|
|
69
|
+
### Removed
|
|
70
|
+
- `skills/发布发版/dwy-semver` 和 `skills/发布发版/dwy-sdk-spec` 及其专用脚本和模板。
|
|
71
|
+
|
|
55
72
|
## 0.32.0 — 2026-10-29
|
|
56
73
|
|
|
57
74
|
### Changed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.34.0
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dwy-apple-appkit
|
|
3
|
+
description: 使用或排查 AppleAppKit SwiftPM 自有基础库时使用,按模块和项目锁定版本查证接口。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# AppleAppKit 自有基础库
|
|
7
|
+
|
|
8
|
+
先查项目 Package.resolved、实际 checkout 和已使用的产品;版本范围不是锁定版本。源码及示例只在与项目锁定版本一致时作为依据。
|
|
9
|
+
|
|
10
|
+
- SyncCore:同步;CoreKit、LogKit、L10nKit、CacheKit:基础功能、日志、本地化与缓存。
|
|
11
|
+
- DesignCore、DesignKitIOS、DesignKitMac:跨平台及平台界面能力。
|
|
12
|
+
- AuthCore、AuthUI、AuthGoogleIOS、AuthAppleIOS、AuthGoogleMac:认证核心与平台接入。
|
|
13
|
+
- PurchaseCore:购买能力。
|
|
14
|
+
|
|
15
|
+
按目标平台查 Package.swift、对应公开声明和 ios/README.md,再核对初始化、生命周期、系统版本与错误处理。找不到确切版本时查对应语义化 Git tag;不可用时说明缺口,不以默认分支替代。使用新产品或新增依赖遵守项目选择和授权,不擅自安装。
|
|
16
|
+
|
|
17
|
+
查到对应版本源码后:同步查 `ios/Docs/SYNC_CORE.md` 与 `ios/Examples/OfflineSync/`;Apple 登录、Google 登录和邮箱密码分别查 `ios/Docs/APPLE_AUTH.md`、`ios/Docs/GOOGLE_AUTH.md`、`ios/Docs/EMAIL_PASSWORD_AUTH.md` 与相应示例。具体文件是否存在以所选 tag 为准。
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dwy-apple-architecture
|
|
3
|
+
description: 设计、开发、排查或评审 iOS、macOS 的模块架构、依赖方向、共享基础库及代码抽取时使用。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Apple 架构与复用
|
|
7
|
+
|
|
8
|
+
同时使用可用的 `dwy-swift-development` 和受影响的平台 Skill;缺少时按现有项目约定继续,不自动安装。先检查项目结构、已有基础库、调用方和依赖边界;不因启用 Skill 重建现有工程。
|
|
9
|
+
|
|
10
|
+
需要分层与依赖判断时读 [分层与依赖](references/layering.md),需要共用或抽取时读 [共享与抽取](references/extraction.md),遇到架构问题读 [架构踩坑](references/pitfalls.md)。新项目遵循团队分层;既有项目先尊重实际架构,若与团队规范冲突,说明影响并在授权范围内处理。
|
|
11
|
+
|
|
12
|
+
新项目默认 iOS 17+、macOS 15+;现有项目以实际 deployment target 为准,不擅自抬高。针对当前任务查找适用的 Apple 官方 Skill;缺失时使用官方文档。目标平台和 SDK 版本决定 API 可用性。
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# 共享与抽取
|
|
2
|
+
|
|
3
|
+
1. 查项目已有模块、团队基础库、实际调用方与依赖版本,优先复用可满足需求的能力;不能把抽取候选当作已存在的能力。
|
|
4
|
+
2. 区分跨产品基础能力、跨 Feature 的本产品业务能力和某个平台的壳或界面状态,按职责及依赖方向确定落点。
|
|
5
|
+
3. 一次性业务留在原处;有第二个实际消费者或明确已授权需求,再按收益、接口稳定性和迁移成本考虑抽取,不为假设复用提前建层。
|
|
6
|
+
4. 共享逻辑只抽真正相同的部分;平台生命周期、窗口、导航和平台专属状态留在对应端。改基础库与业务侧修复按实际成本、复用收益及授权判断。
|
|
7
|
+
5. 验证现有调用方、公开接口、依赖边、受影响平台和测试。跨仓库修改、破坏性接口变更、新增依赖或发布须有相应授权。
|
|
8
|
+
|
|
9
|
+
通用缺口本轮落在业务侧时,遵循项目关于基础库抽取候选的记录和确认规则;不自行扩展本轮范围。
|
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: iOS / macOS 四层分包与依赖方向(双壳 Assembly + Features / BizFoundation / Foundation);根 Package.swift 锁定第三方版本
|
|
3
|
-
paths:
|
|
4
|
-
- "**/*.swift"
|
|
5
|
-
- "**/Package.swift"
|
|
6
|
-
- "**/project.yml"
|
|
7
|
-
---
|
|
8
|
-
|
|
9
1
|
# Apple 四层架构与依赖
|
|
10
2
|
|
|
11
|
-
|
|
3
|
+
团队新项目默认 iOS 17+ / macOS 15+;既有项目以实际 deployment target 和现有架构为准,不为套用层名而擅自重构或抬高版本。风格与国际化见 `dwy-swift-development`。本文件只管**层、引用边、版本写在哪**;以下目录和分层适用于采用该架构的项目。
|
|
12
4
|
|
|
13
5
|
单壳(只有 iPhone 或只有 Mac)**不建** PlatformFoundation。双壳且某端领域字节级不同时才加 `DesktopKit`。
|
|
14
6
|
|
|
@@ -31,7 +23,7 @@ paths:
|
|
|
31
23
|
|
|
32
24
|
| **PlatformFoundation** | 同一业务多个壳,且某端领域字节级不同 | 被其他壳 import;塞回 BizFoundation |
|
|
33
25
|
|
|
34
|
-
升层:第二个 Feature
|
|
26
|
+
升层:第二个 Feature 或第二个产品**真在用**,或用户明确授权本次抽取时,才考虑升到 BizFoundation / Foundation;仍需评估依赖方向和迁移成本。禁止因「可能复用」提前抽。禁止为了共用而抽 `AppShared` 把壳状态(Store / Session)塞进 BizFoundation。
|
|
35
27
|
|
|
36
28
|
业务内聚:一个业务域 = 壳内 `Features/<Name>/`。禁止按 `Views/` `ViewModels/` 横切。目录不等于层:Features 若与壳同一 target,仍遵守互不 import 的源码边界。
|
|
37
29
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dwy-ios-development
|
|
3
|
+
description: 开发、排查、评审或适配 iOS、iPadOS 应用时使用,涵盖界面、系统版本、弹层、Liquid Glass 和目标设备验证。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# iOS 开发
|
|
7
|
+
|
|
8
|
+
同时使用可用的 `dwy-swift-development`;涉及模块边界或公共代码时使用 `dwy-apple-architecture`。缺少其他 Skill 时说明并按现有项目约定继续,不自动安装。按任务使用 Apple 官方 Skill;没有适用项时查官方文档。
|
|
9
|
+
|
|
10
|
+
新项目默认最低 iOS 17;现有项目先读取实际 deployment target,发现差异时说明,不擅自升级。新 API 按 SDK 与运行时版本判断,保留低版本可用体验。
|
|
11
|
+
|
|
12
|
+
按需阅读:[布局与安全区](references/layout.md)、[系统外观与 Liquid Glass](references/appearance.md)、[弹窗和锚点](references/presentations.md)、[iOS 踩坑](references/pitfalls.md)。界面变更先确定受影响系统、屏幕尺寸、滚动和交互,再验证布局、可访问性与视觉;编译通过不等于设备验收。
|
|
13
|
+
|
|
14
|
+
发现可复用新坑先查重:只在 iOS 证实的放本 Skill;双端均有证据时将共通部分放 Swift Skill,保留平台差异。记录现象、范围、根因及证据、处理方法、验证状态和未验证项;未确认标记待验证,项目专属问题留项目内。修改共享 Skill 必须已有来源仓库授权。
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# iOS 系统外观与 Liquid Glass
|
|
2
|
+
|
|
3
|
+
- iOS 26+ 使用适配 SDK 构建时,先检查系统导航、工具栏、控件和弹层的原生外观;自定义背景可能遮挡系统效果。根据产品设计适配,勿给所有内容叠加玻璃。
|
|
4
|
+
- 仅在适合的自定义控件使用系统玻璃 API,检查 SDK 和运行时可用性;iOS 17–25 保留可用、可读的原生或项目既有外观,不将普通透明背景称作 Liquid Glass。
|
|
5
|
+
- 在受影响的目标系统检查深浅色、减少透明度、增加对比度、动态字体、触控区域和内容遮挡。记录 SDK、系统、设备及实际交互与视觉验证;只编译或截图空白不能证明通过。
|
|
6
|
+
- 具体行为以 Apple 官方文档及当前 SDK 为准:https://developer.apple.com/documentation/technologyoverviews/adopting-liquid-glass
|
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: iOS / Swift / SwiftUI 开发避坑清单(XcodeGen / 签名 / 真机部署 / SwiftUI 代码踩坑)
|
|
3
|
-
paths:
|
|
4
|
-
- "**/*.swift"
|
|
5
|
-
- "**/project.yml"
|
|
6
|
-
- "**/Package.swift"
|
|
7
|
-
---
|
|
8
|
-
|
|
9
1
|
# iOS 开发坑清单
|
|
10
2
|
|
|
11
|
-
>
|
|
3
|
+
> 以下为迁移自旧规则的经验,适用范围和结论须结合当前 SDK、系统及现场证据核实。新增记录遵循 SKILL.md 的证据和权限要求。
|
|
12
4
|
|
|
13
5
|
## 分类索引
|
|
14
6
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# iOS 弹窗差异与案例
|
|
2
|
+
|
|
3
|
+
- 共通锚点规则和验证见 `dwy-swift-development` 的弹层参考。
|
|
4
|
+
- iPhone 的 popover 默认适配为 sheet,垂直紧凑环境可适配为全屏;iOS 常规尺寸类别的 confirmation dialog 可以呈现为 popover。按设备和尺寸类别验证,勿假设始终有箭头。
|
|
5
|
+
- 对指定 `arrowEdge` 的 SwiftUI popover,iOS 18.1 前系统不遵循指定边;新行为还要求使用 iOS 18.1 或更新 SDK 编译并运行在对应系统。允许系统选方向时使用不指定边的重载;按支持版本验证。
|
|
6
|
+
|
|
7
|
+
## 卸载插件弹窗案例:待目标环境验证
|
|
8
|
+
|
|
9
|
+
- 现象:点击页面底部卸载行后,截图中的带箭头确认框出现在页面上方。
|
|
10
|
+
- 证据:触发行只更改状态,`confirmationDialog` 挂在外层滚动视图;这与错误锚点一致,但未在截图对应系统实测,根因仍待验证。
|
|
11
|
+
- 排查:将确认框关联触发行后,在相同环境和滚动位置比较箭头与入口,并检查取消和确认目标。未验证的修复不宣称已通过。
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dwy-macos-development
|
|
3
|
+
description: 开发、排查、评审或适配 macOS 应用时使用,涵盖窗口、菜单、键鼠、系统版本、Liquid Glass 和目标系统验证。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# macOS 开发
|
|
7
|
+
|
|
8
|
+
同时使用可用的 `dwy-swift-development`;涉及模块边界或公共代码时使用 `dwy-apple-architecture`。缺少其他 Skill 时说明并按现有项目约定继续,不自动安装。按任务使用 Apple 官方 Skill;没有适用项时查官方文档。
|
|
9
|
+
|
|
10
|
+
新项目默认最低 macOS 15;现有项目先读取实际 deployment target,发现差异时说明,不擅自升级。新 API 按 SDK 与运行时版本判断,保留低版本可用体验。
|
|
11
|
+
|
|
12
|
+
按需阅读 [窗口与系统外观](references/ui-adaptation.md)、[弹窗差异](references/presentations.md) 和 [macOS 踩坑](references/pitfalls.md)。界面变更先确定目标系统、窗口尺寸、键鼠和辅助功能验证;签名或启动通过不等于目标系统交互与视觉验收。
|
|
13
|
+
|
|
14
|
+
发现可复用新坑先查重:只在 macOS 证实的放本 Skill;双端均有证据时将共通部分放 Swift Skill,保留平台差异。记录现象、范围、根因及证据、处理方法、验证状态和未验证项;未确认标记待验证,项目专属问题留项目内。修改共享 Skill 必须已有来源仓库授权。
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# macOS 踩坑
|
|
2
|
+
|
|
3
|
+
记录已验证的 macOS 专属问题;每条写现象、适用系统与条件、根因及证据、处理方式、验证状态和未验证项。先查重;未证实的推断不能写成事实,项目专属问题留在项目中。
|
|
4
|
+
|
|
5
|
+
## macOS 15 原生外观与 Liquid Glass
|
|
6
|
+
|
|
7
|
+
- 现象:系统组件在 macOS 15 上可以呈现原生外观,但这不能证明使用了 macOS 26 的 Liquid Glass API。
|
|
8
|
+
- 依据:曾有项目通过系统导航和表单完成 macOS 15 样式适配,源码未使用玻璃 API;当时目标系统的完整视觉交互验收尚未完成。
|
|
9
|
+
- 处理:分别检查 API 实际使用与目标系统的显示、交互,不以构建或签名通过替代验收。
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# macOS 窗口与系统外观
|
|
2
|
+
|
|
3
|
+
- 使用现有系统窗口、侧栏、工具栏、菜单和焦点行为;验证窗口缩放、最小尺寸、键盘、鼠标、菜单和辅助功能。不要把 iPhone 的固定尺寸布局搬到 Mac。
|
|
4
|
+
- macOS 26+ 使用适配 SDK 构建时先检查系统组件的 Liquid Glass;仅在适合的自定义控件使用系统 API,避免叠加遮挡内容。macOS 15 上保留可用的原生外观,不把普通材质或系统旧样式称为 Liquid Glass API。
|
|
5
|
+
- 根据 SDK 和运行时版本判断 API 可用性;检查深浅色、减少透明度、增加对比度和可读性。按任务在目标 macOS 版本启动、操作并观察界面;编译、签名或进程存在不能代替视觉与交互验收。
|
|
6
|
+
- 具体行为以 Apple 官方文档及当前 SDK 为准:https://developer.apple.com/documentation/technologyoverviews/adopting-liquid-glass
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dwy-swift-development
|
|
3
|
+
description: 开发、排查或评审 Swift、SwiftUI 和 Apple 平台共享代码时使用;提供团队 Swift 规范、Apple 官方技能查找和共通问题处理。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Swift 开发基线
|
|
7
|
+
|
|
8
|
+
先确认任务范围、项目现有约定、调用方和实际 SDK;用户明确要求优先。阅读 [团队写法](references/conventions.md) 中与任务有关的部分;iOS 专属要求不套用到 macOS。架构、公共模块或抽取涉及 `dwy-apple-architecture` 时同时使用它;涉及 iOS / iPadOS 或 macOS 时分别使用 `dwy-ios-development` 或 `dwy-macos-development`。若其他 Skill 未安装,说明缺口并按项目现有约定继续,不自动安装。
|
|
9
|
+
|
|
10
|
+
SwiftUI、App Intents 等具体技术优先查找当前环境中与任务匹配的 Apple 官方 Skill,阅读相关参考;确认其来源后使用。不存在或不可用时查 Apple 官方文档,不强制安装、不把第三方 Skill 冒充官方。
|
|
11
|
+
|
|
12
|
+
项目使用 AppleAppKit 时先查可用的 `dwy-apple-appkit`,按项目锁定版本复用同步、基础工具、设计、认证和购买等已有能力;未安装该 Skill 时核实实际依赖与源码,不自动安装依赖。
|
|
13
|
+
|
|
14
|
+
涉及弹窗、popover 或其锚点时读取 [弹层与锚点](references/presentations.md),再读取对应平台 Skill 中的差异。
|
|
15
|
+
|
|
16
|
+
排查共通问题时读 [共通踩坑](references/pitfalls.md)。新增经验先查重,记录现象、适用平台和版本、根因与证据、处理方式、验证及未验证项;未证实的推断明确标记。仅单项目成立的经验留在项目中。共享 Skill 属于其来源仓库:只有已获授权才修改,否则在结果中提出候选;不擅自写全局配置。
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
description: iOS 17+ SwiftUI 开发基线规则(全局适配、动画、国际化、注释)
|
|
3
|
-
paths:
|
|
4
|
-
- "**/*.swift"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
分层、双壳依赖、Package.swift 版本锁定见 `dwy-apple-layering`。本文件只管写法与体验基线。
|
|
1
|
+
以下是迁移自原 Swift 基线的团队约定;先遵循用户要求和现有项目约定,平台专属内容仅在相应平台使用。架构和依赖方向使用 `dwy-apple-architecture`。
|
|
8
2
|
|
|
9
3
|
## iOS 目标与写法
|
|
10
4
|
|
|
11
|
-
- iOS
|
|
5
|
+
- 新项目默认 iOS 17+、macOS 15+;既有项目以实际 deployment target 为准,不擅自抬高。
|
|
12
6
|
- 统一 Observation + `@MainActor`,状态对象默认 `final class`。
|
|
13
7
|
|
|
14
8
|
```swift
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# SwiftUI 弹层与锚点
|
|
2
|
+
|
|
3
|
+
- 需要指向入口的 `popover` 或可能以 popover 呈现的 `confirmationDialog`,把呈现修饰符关联实际触发按钮或行;列表须对应当前目标,工具栏须对应入口。自定义锚点时检查其坐标和所属视图。
|
|
4
|
+
- 呈现方式由平台、系统和窗口环境决定;普通系统通知、居中 alert 等不一定有入口锚点,不按弹出位置错误处理。
|
|
5
|
+
- 在相关平台验证触发入口、滚动或窗口变化、屏幕边缘、取消和实际目标;以目标系统的交互及视觉为准,编译通过不能证明位置正确。
|
|
6
|
+
- 平台差异分别见 `dwy-ios-development` 的弹窗参考和 `dwy-macos-development` 的弹窗参考;这些 Skill 不可用时查 Apple 官方文档。
|
|
7
|
+
|
|
8
|
+
依据:[SwiftUI popover](https://developer.apple.com/documentation/swiftui/view/popover(ispresented:attachmentanchor:arrowedge:content:))、[弹层设计指引](https://developer.apple.com/design/human-interface-guidelines/popovers)。
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dwy-apple-notify
|
|
3
|
+
description: 使用或排查 dwy-apple-notify Apple 服务端通知能力时使用;先核实项目安装版本及公开 API。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dwy-apple-notify
|
|
7
|
+
|
|
8
|
+
Apple 购买、审核、评论及经营报表通知;核实来源配置、签名验证、投递和平台 extra。
|
|
9
|
+
|
|
10
|
+
## 查找与使用
|
|
11
|
+
|
|
12
|
+
项目使用 0.1.6 时可阅读 [0.1.6 接入和示例](references/v0/0.1.6.md);其他版本先查该版本的资料和代码,不把此快照当作其他版本的合同。
|
|
13
|
+
|
|
14
|
+
1. 检查项目锁文件和当前 Python 环境;用 `importlib.metadata.version("dwy-apple-notify")` 查询实际发行版本,依赖范围不等于实际安装版本。未安装时不得假设可用或自动安装。
|
|
15
|
+
2. 在实际环境中检查 `dwy_apple_notify` 的公开接口、类型及项目已有调用;editable 安装以实际源码为准。说明、实现或安装版本不一致时以运行代码为准。
|
|
16
|
+
3. 本索引基于仓库 0.1.6,能力与签名可能随小版本变化。精确版本源码位于仓库 `backend/packages/apple-notify`,文档为该目录的 `README.md`;只在确认其版本与消费项目一致时使用。缺少安装源码时查对应 `dwy-apple-notify@版本` 标签,不能用默认分支冒充。
|
|
17
|
+
4. 在已有调用和该版本文档中核对配置、必需依赖、输入校验、失败处理及生命周期后接入。没有足够证据时说明缺口,不猜 API。
|
|
18
|
+
|
|
19
|
+
## 0.x 已核实差异
|
|
20
|
+
|
|
21
|
+
- 0.1.0 提供购买、审核、评论和经营报表通知;0.1.5 新增可选 ratings extra 和评分日报。
|
|
22
|
+
- 0.1.6 才支持通过已验签的交易查询首次获取 App 的平台;该平台不代表本次内购设备。
|
|
23
|
+
|
|
24
|
+
不要因为发现此库就改动项目依赖;新增依赖遵循项目选型规则。关联 FastAPI 或其他自有包时同时参考可用的对应 Skill。
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<!-- 来源:dwy-apple-notify@0.1.6 的 backend/packages/apple-notify/README.md;文中相对链接相对原仓库路径。 -->
|
|
2
|
+
|
|
3
|
+
# dwy-apple-notify
|
|
4
|
+
|
|
5
|
+
Apple 通知集成:购买通知验签与文案、App Store Connect 审核事件、评论监控、经营日报和周报。通知投递统一使用 `dwy-notify`;本包不处理应用账户与权益。
|
|
6
|
+
|
|
7
|
+
## 按需安装
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install 'dwy-apple-notify[iap,asc,reviews,analytics,ratings]==0.1.6'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`iap` 安装 Apple Server SDK;`asc`、`reviews`、`analytics` 分别安装现有 ASC HTTP/JWT/加密依赖。只使用审核、评论或报表时不需要 Apple Server SDK,也不需要 Resend。
|
|
14
|
+
|
|
15
|
+
## 模块入口
|
|
16
|
+
|
|
17
|
+
- `dwy_apple_notify.apple`:已验签通知与交易模型、购买文案。
|
|
18
|
+
- `dwy_apple_notify.config`:`AppleNotifyConfig`、各 Apple 来源配置。
|
|
19
|
+
- `dwy_apple_notify.fastapi`:`install_apple_notifications`、`AppleNotifySinks`、`AppleNotifyRuntime`。
|
|
20
|
+
- `dwy_apple_notify.analytics`:官方报表客户端、快照、存储与 monitor。
|
|
21
|
+
- `dwy_apple_notify.reviews`:评论客户端、存储与 monitor。
|
|
22
|
+
- `dwy_apple_notify.ratings`:公开 Lookup 评分采集、独立每日调度、日周月变化与持久日报(当前源码新增,尚未发布)。
|
|
23
|
+
|
|
24
|
+
配置由宿主显式注入,本包不读取环境变量、不建数据库、不执行迁移。数据库会话、表和生命周期由宿主管理,已有队列表名、来源标识与目标指纹保持兼容。
|
|
25
|
+
|
|
26
|
+
`apple_original_platform(client, verify, transaction_id)` 使用 Apple 官方客户端查询 App 交易,并通过宿主提供的异步验签函数验证签名后返回平台。调用方负责超时和错误处理;可将结果传入 `VerifiedAppleNotification.original_platform` 显示。该平台表示首次获取 App 的平台,不能用于判断本次内购的设备,iOS 也不区分 iPhone 与 iPad。
|
|
27
|
+
|
|
28
|
+
## 经营统计日期
|
|
29
|
+
|
|
30
|
+
默认北京时间 `Asia/Shanghai` 每天 08:30,内部固定查询统计时区日期的前两天,例如 30 日查询 28 日、31 日查询 29 日。Apple 报表生成存在延迟,因此不暴露 `lag_days` 配置。周一附加截至前两天的连续七天周报。日报和周报固定展示全部指标与地区、来源 Top 3:有值显示实际数值,获取不到显示“无数据”,真实零值保留为零。快照仍保留原始可用性状态,不把缺失数据写成零,不自动重复补发历史日报。
|
|
31
|
+
|
|
32
|
+
## 名称与头像
|
|
33
|
+
|
|
34
|
+
购买默认“购买通知”,审核默认“应用审核通知”,日报周报默认“经营报表”,评论默认“系统通知”。各模块 `appearance.py` 公开 `DEFAULT_APPEARANCE`;应用与单次发送可逐字段覆盖,最终名称必填,头像可省略或显式清除以使用平台默认。
|
|
35
|
+
|
|
36
|
+
Logo 沿用 GitHub 固定资产提交 `091ad4fea18ed3840fec83dc833f18b759256ca7`,无需应用部署图片服务。资产与 Lucide 许可维护于 `backend/packages/webhooks/assets/`,固定历史引用不受本次 Python 包迁移影响。
|
|
37
|
+
|
|
38
|
+
## 每日评分日报
|
|
39
|
+
|
|
40
|
+
从 `0.1.5` 起提供 `ratings` extra,仅使用现有固定版本 HTTPX;旧版 `0.1.4` 不包含该入口。开发时也可从仓库根安装源码:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install './backend/packages/apple-notify[ratings]'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
宿主提供会话工厂、通知发送器和迁移,库不读取 `.env`、不创建数据库,不需要 Apple 账号或私钥:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from dwy_apple_notify.ratings import (
|
|
50
|
+
AppleRatingsConfig,
|
|
51
|
+
RatingApp,
|
|
52
|
+
build_rating_tables,
|
|
53
|
+
install_rating_monitor,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def configure_ratings(app, sessions, metadata, sender):
|
|
58
|
+
"""宿主须先通过自身迁移创建 tables 对应的表,再启动应用。"""
|
|
59
|
+
config = AppleRatingsConfig(
|
|
60
|
+
apps={"1234567890": RatingApp(name="Demo")},
|
|
61
|
+
territories=("cn", "us"),
|
|
62
|
+
timezone="Asia/Shanghai",
|
|
63
|
+
send_hour=8,
|
|
64
|
+
send_minute=30,
|
|
65
|
+
retention_days=90,
|
|
66
|
+
)
|
|
67
|
+
tables = build_rating_tables(metadata)
|
|
68
|
+
return install_rating_monitor(app, config, sessions, tables, sender=sender)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
也可配置 `notifications` 使用 `dwy-notify` 的已有目标。默认展示名称为“评分日报”。运行时位于 `app.state.dwy_rating_monitor`,公开 `monitor.run_once()` 与 `queue.process_pending()`;可注入 `client`、`sender` 和 `clock` 离线运行。采集器协议为 `async get_rating(app_id, territory) -> AppleRating(count=..., average=...)`,预期采集失败抛 `RatingCollectionError`;外部客户端由宿主关闭。
|
|
72
|
+
|
|
73
|
+
默认表为 `app_store_ratings_state`、`app_store_ratings_snapshots`、`app_store_ratings_deliveries`;`build_rating_tables(metadata, prefix=...)` 支持同库独立监控器。三表必须在同一数据库,保证有效租约下快照与 outbox 原子提交。库每分钟检查到期计划;每天只生成一份跨应用、地区日报,长文按 2000 UTF-16 单位无损分段。
|
|
74
|
+
|
|
75
|
+
读取地址为 `https://itunes.apple.com/lookup?id=1234567890&country=cn`,只使用 `userRatingCount` 与 `averageUserRating` 全版本字段。日/周基准分别为昨天和七天前,月基准为上月同日(月末截断);按时区隔离历史,不跨地区相加。均分保留原始返回精度,展示累计均分之差;不足展示精度的非零变化明确标记,不伪造新增评分平均分。
|
|
76
|
+
|
|
77
|
+
缺失历史、基准日失败和当前采集失败分别展示;零值只来自有效零评分响应。当日采集失败也定稿日报,同日不再拉取;发送失败仅重试已生成内容。停机只采集当前已到期日期,不补造历史。历史默认保留 90 天,最少 32 天;切换时区不改写旧快照,已经生成的旧时区日报仍可投递。发送成功但本地确认前中断可能重复发送,不承诺严格一次投递。公开聚合数包含仅打星和文字评价附带的星级,无法识别逐条无文字评分。
|
|
78
|
+
|
|
79
|
+
每份日报的全部分段同时固定保存应用 ID 名单。投递前若发现其中任一应用已从当前配置撤销,整份日报标记为 `suppressed` 并清空内容,不重算或发送其中部分内容;完整停用后重新启用子集也执行此检查。只调整时区而未撤销应用时,旧时区待发日报仍正常投递。
|
|
80
|
+
|
|
81
|
+
采集跨过配置时区的午夜时,停止后续地区请求,整轮定稿为“采集跨日,本轮数据不可用”,包括丢弃午夜前已取得的部分成功值,避免把跨日数据写作昨日成功基线。失败快照的 `day` 为计划日期,`collected_at` 为实际失败完成时间;日报显示实际时间。计划日已完成后不重拉,次日仍按配置时刻执行。当前不保存逐项采集时间,需保留跨日部分成功值时再扩展该能力。
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dwy-auth
|
|
3
|
+
description: 使用或排查 dwy-auth 认证与会话能力时使用;先核实项目安装版本及公开 API。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dwy-auth
|
|
7
|
+
|
|
8
|
+
认证主体、邮箱验证码、会话和管理端认证;核实适配器、配置、存储及 HTTP 路由由宿主如何装配。
|
|
9
|
+
|
|
10
|
+
## 查找与使用
|
|
11
|
+
|
|
12
|
+
项目使用 0.2.0 时可阅读 [0.2.0 接入和示例](references/v0/0.2.0.md);其他版本先查该版本的资料和代码,不把此快照当作其他版本的合同。
|
|
13
|
+
|
|
14
|
+
1. 检查项目锁文件和当前 Python 环境;用 `importlib.metadata.version("dwy-auth")` 查询实际发行版本,依赖范围不等于实际安装版本。未安装时不得假设可用或自动安装。
|
|
15
|
+
2. 在实际环境中检查 `dwy_auth` 的公开接口、类型及项目已有调用;editable 安装以实际源码为准。说明、实现或安装版本不一致时以运行代码为准。
|
|
16
|
+
3. 本索引基于仓库 0.2.0,能力与签名可能随小版本变化。精确版本源码位于仓库 `backend/packages/auth`,文档为该目录的 `README.md`;只在确认其版本与消费项目一致时使用。缺少安装源码时查对应 `dwy-auth@版本` 标签,不能用默认分支冒充。
|
|
17
|
+
4. 在已有调用和该版本文档中核对配置、必需依赖、输入校验、失败处理及生命周期后接入。没有足够证据时说明缺口,不猜 API。
|
|
18
|
+
|
|
19
|
+
## 0.x 已核实差异
|
|
20
|
+
|
|
21
|
+
- 0.1.0 提供独立认证运行时、Google 和可选邮箱认证;0.1.1 增加 Apple 登录验证与撤销队列。
|
|
22
|
+
- 0.2.0 增加可选滑动刷新与凭据代次状态;升级涉及宿主数据库迁移。按实际版本文档核实迁移与会话配置,不将这些能力用于 0.1.x。
|
|
23
|
+
|
|
24
|
+
不要因为发现此库就改动项目依赖;新增依赖遵循项目选型规则。关联 FastAPI 或其他自有包时同时参考可用的对应 Skill。
|