@harmonyos-arkts/d2h 0.0.0-stage → 0.1.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/.claude-plugin/marketplace.json +13 -0
- package/.claude-plugin/plugin.json +7 -0
- package/README.md +168 -2
- package/agents/android-to-hmos-00-orchestrator.md +312 -0
- package/agents/d2h.md +168 -0
- package/bin/install-opencode.mjs +51 -0
- package/install-opencode.sh +160 -0
- package/opencode/agents.json +16 -0
- package/package.json +16 -4
- package/schemas/android-source-manifest.schema.json +25 -0
- package/schemas/checkpoint-provenance.schema.json +67 -0
- package/schemas/final-acceptance.schema.json +29 -0
- package/schemas/managed-evidence-index.schema.json +15 -0
- package/schemas/managed-evidence.schema.json +114 -0
- package/schemas/migration-config.schema.json +51 -0
- package/schemas/migration-report-index.schema.json +39 -0
- package/schemas/migration-report-item.schema.json +51 -0
- package/schemas/migration-report-summary.schema.json +25 -0
- package/schemas/migration-status.schema.json +202 -0
- package/schemas/preflight.schema.json +60 -0
- package/schemas/source-order-audit.schema.json +16 -0
- package/schemas/source-provenance-event.schema.json +19 -0
- package/schemas/spec-app-shard.schema.json +45 -0
- package/schemas/spec-fact-corrections-shard.schema.json +13 -0
- package/schemas/spec-features-shard.schema.json +43 -0
- package/schemas/spec-index.schema.json +26 -0
- package/schemas/spec-interactions-shard.schema.json +40 -0
- package/schemas/spec-page.schema.json +98 -0
- package/schemas/spec-pages-index.schema.json +1 -0
- package/schemas/spec-unresolved-shard.schema.json +1 -0
- package/schemas/task-envelope.schema.json +55 -0
- package/schemas/task-plan.schema.json +123 -0
- package/skills/android2hmos_resources_convert/SKILL.md +162 -0
- package/skills/android2hmos_resources_convert/references/image-conversion-rules.md +230 -0
- package/skills/android2hmos_resources_convert/references/svg-fix-patterns.md +175 -0
- package/skills/android2hmos_resources_convert/references/xml-drawable-to-svg-rules.md +513 -0
- package/skills/appgraph-rule-audit/SKILL.md +58 -0
- package/skills/appgraph-rule-audit/references/audit-contract.md +47 -0
- package/skills/appgraph-rule-audit/references/recommendation-schema.md +41 -0
- package/skills/appgraph-rule-audit/schemas/rule-opportunities.schema.json +125 -0
- package/skills/arkts-app-identity/SKILL.md +238 -0
- package/skills/arkts-i18n/SKILL.md +496 -0
- package/skills/arkts-i18n/evals/evals.json +84 -0
- package/skills/arkts-i18n/references/code-examples.md +302 -0
- package/skills/arkts-i18n/references/common-pitfalls.md +391 -0
- package/skills/arkts-i18n/references/dynamic-language-switch.md +604 -0
- package/skills/arkts-i18n/references/hardcoded-string-scanner.md +348 -0
- package/skills/arkts-i18n/references/language-codes.md +104 -0
- package/skills/arkts-i18n/references/resource-file-structure.md +775 -0
- package/skills/arkts-i18n/references/static-vs-dynamic.md +242 -0
- package/skills/arkts-i18n/references/v1-compat.md +244 -0
- package/skills/arkts-i18n/scripts/audit_i18n_completeness.sh +174 -0
- package/skills/arkts-icon-sizing/SKILL.md +211 -0
- package/skills/arkts-icon-sizing/scripts/icon_audit.py +131 -0
- package/skills/arkts-icon-sizing/scripts/icon_autofix.py +88 -0
- package/skills/arkts-icon-sizing/scripts/icon_dims.py +179 -0
- package/skills/arkts-icon-sizing/scripts/icon_fix.py +119 -0
- package/skills/arkts-mvvm-architecture/SKILL.md +613 -0
- package/skills/harmonyos-migration-playbook/SKILL.md +56 -0
- package/skills/harmonyos-migration-playbook/agents/openai.yaml +7 -0
- package/skills/harmonyos-migration-playbook/references/arkts-compile.md +24 -0
- package/skills/harmonyos-migration-playbook/references/harmony-runtime.md +53 -0
- package/skills/harmonyos-migration-playbook/references/lesson-lifecycle.md +45 -0
- package/skills/harmonyos-migration-playbook/references/protocol-e2e.md +23 -0
- package/skills/harmonyos-migration-playbook/references/ui-automation.md +52 -0
- package/skills/harmonyos-migration-playbook/references/windows-environment.md +38 -0
- package/skills/maintaining-migration-report/SKILL.md +155 -0
- package/skills/native-library-substitution/SKILL.md +385 -0
- package/skills/native-library-substitution/references/native-library-substitution.json +56906 -0
- package/skills/native-library-substitution/references/native-library-substitution.md +163 -0
- package/skills/preparing-migration-workspace/SKILL.md +124 -0
- package/skills/preparing-migration-workspace/toolchain.json +43 -0
- package/skills/reviewing-migration-process/SKILL.md +62 -0
- package/src/install-opencode.mjs +108 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://harmonyos-ai.dev/schemas/spec-fact-corrections-shard.schema.json",
|
|
4
|
+
"title": "SPEC Semantic Corrections",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["shardVersion", "factCorrections", "exclusions"],
|
|
7
|
+
"properties": { "shardVersion": { "const": "2.0.0" }, "factCorrections": { "type": "array", "items": { "$ref": "#/$defs/correction" } }, "exclusions": { "type": "array" } },
|
|
8
|
+
"$defs": { "correction": { "type": "object", "required": ["id", "entityKind", "operation", "targetRef", "factValue", "semanticValue", "reason", "sourceEvidence"], "properties": {
|
|
9
|
+
"id": { "type": "string", "minLength": 1 }, "entityKind": { "enum": ["surface", "control", "entry", "interaction"] }, "operation": { "enum": ["add", "update", "remove"] }, "targetRef": { "type": "string", "minLength": 1 },
|
|
10
|
+
"factValue": { "type": ["object", "null"] }, "semanticValue": { "type": ["object", "null"] }, "reason": { "type": "string", "minLength": 1 },
|
|
11
|
+
"sourceEvidence": { "type": "array", "minItems": 1, "items": { "type": "object", "required": ["file"], "properties": { "file": { "type": "string", "minLength": 1 }, "symbol": { "type": ["string", "null"] }, "line": { "type": ["integer", "null"] }, "endLine": { "type": ["integer", "null"] } }, "additionalProperties": false } }
|
|
12
|
+
}, "additionalProperties": false } }, "additionalProperties": false
|
|
13
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://harmonyos-ai.dev/schemas/spec-features-shard.schema.json",
|
|
4
|
+
"title": "SPEC Business Features Shard",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["shardVersion", "domains", "features"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"shardVersion": { "const": "2.0.0" },
|
|
9
|
+
"domains": { "type": "array", "items": { "$ref": "#/$defs/domain" } },
|
|
10
|
+
"features": { "type": "array", "items": { "$ref": "#/$defs/feature" } }
|
|
11
|
+
},
|
|
12
|
+
"$defs": {
|
|
13
|
+
"text": { "type": "string", "minLength": 1 },
|
|
14
|
+
"nullableText": { "type": ["string", "null"], "minLength": 1 },
|
|
15
|
+
"refs": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/text" } },
|
|
16
|
+
"domain": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"required": ["id", "parentDomainRef", "name", "description", "featureRefs"],
|
|
19
|
+
"properties": {
|
|
20
|
+
"id": { "$ref": "#/$defs/text" },
|
|
21
|
+
"parentDomainRef": { "$ref": "#/$defs/nullableText" },
|
|
22
|
+
"name": { "$ref": "#/$defs/text" },
|
|
23
|
+
"description": { "$ref": "#/$defs/text" },
|
|
24
|
+
"featureRefs": { "$ref": "#/$defs/refs" }
|
|
25
|
+
},
|
|
26
|
+
"additionalProperties": false
|
|
27
|
+
},
|
|
28
|
+
"feature": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"required": ["id", "domainRef", "parentFeatureRef", "name", "description", "entryRefs"],
|
|
31
|
+
"properties": {
|
|
32
|
+
"id": { "$ref": "#/$defs/text" },
|
|
33
|
+
"domainRef": { "$ref": "#/$defs/text" },
|
|
34
|
+
"parentFeatureRef": { "$ref": "#/$defs/nullableText" },
|
|
35
|
+
"name": { "$ref": "#/$defs/text" },
|
|
36
|
+
"description": { "$ref": "#/$defs/text" },
|
|
37
|
+
"entryRefs": { "$ref": "#/$defs/refs" }
|
|
38
|
+
},
|
|
39
|
+
"additionalProperties": false
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"additionalProperties": false
|
|
43
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://harmonyos-ai.dev/schemas/spec-index.schema.json",
|
|
4
|
+
"title": "Sharded SPEC Index",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["specVersion", "shardFormatVersion", "language", "generation", "files", "counts", "factsSha256", "specSha256"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"specVersion": { "const": "2.0.0" },
|
|
9
|
+
"shardFormatVersion": { "const": "2.0.0" },
|
|
10
|
+
"language": { "const": "zh-CN" },
|
|
11
|
+
"generation": { "type": "object" },
|
|
12
|
+
"files": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"required": ["facts", "semantics"],
|
|
15
|
+
"properties": {
|
|
16
|
+
"facts": { "type": "object", "required": ["app", "pages", "interactions", "unresolved"], "additionalProperties": { "type": "string", "minLength": 1 } },
|
|
17
|
+
"semantics": { "type": "object", "required": ["app", "pages", "interactions", "features", "unresolved", "corrections"], "additionalProperties": { "type": "string", "minLength": 1 } }
|
|
18
|
+
},
|
|
19
|
+
"additionalProperties": false
|
|
20
|
+
},
|
|
21
|
+
"counts": { "type": "object" },
|
|
22
|
+
"factsSha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
23
|
+
"specSha256": { "type": ["string", "null"], "pattern": "^[a-f0-9]{64}$" }
|
|
24
|
+
},
|
|
25
|
+
"additionalProperties": false
|
|
26
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://harmonyos-ai.dev/schemas/spec-interactions-shard.schema.json",
|
|
4
|
+
"title": "SPEC 2.0.0 Interaction Facts Shard",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["shardVersion", "interactions"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"shardVersion": { "const": "2.0.0" },
|
|
9
|
+
"interactions": {
|
|
10
|
+
"type": "array",
|
|
11
|
+
"items": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"required": ["id", "relation", "fromRef", "toRef", "confidence", "sourceEvidence"],
|
|
14
|
+
"properties": {
|
|
15
|
+
"id": { "type": "string", "minLength": 1 },
|
|
16
|
+
"relation": { "enum": ["opens", "navigates-to", "launches-for-result"] },
|
|
17
|
+
"fromRef": { "type": "string", "minLength": 1 },
|
|
18
|
+
"toRef": { "type": "string", "minLength": 1 },
|
|
19
|
+
"confidence": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
20
|
+
"sourceEvidence": {
|
|
21
|
+
"type": "array",
|
|
22
|
+
"items": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"required": ["file", "symbol", "line", "endLine"],
|
|
25
|
+
"properties": {
|
|
26
|
+
"file": { "type": "string", "minLength": 1 },
|
|
27
|
+
"symbol": { "type": ["string", "null"] },
|
|
28
|
+
"line": { "type": ["integer", "null"], "minimum": 1 },
|
|
29
|
+
"endLine": { "type": ["integer", "null"], "minimum": 1 }
|
|
30
|
+
},
|
|
31
|
+
"additionalProperties": false
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"additionalProperties": false
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"additionalProperties": false
|
|
40
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://harmonyos-ai.dev/schemas/spec-page.schema.json",
|
|
4
|
+
"title": "SPEC 2.0.0 Surface Facts Shard",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["shardVersion", "kind", "surface", "controls", "entries"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"shardVersion": { "const": "2.0.0" },
|
|
9
|
+
"kind": { "const": "surface-facts" },
|
|
10
|
+
"surface": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"required": ["surfaceRef", "surfaceName", "surfaceType", "parentSurfaceRefs", "relation", "status", "sourceEvidence"],
|
|
13
|
+
"properties": {
|
|
14
|
+
"surfaceRef": { "type": "string", "minLength": 1 },
|
|
15
|
+
"surfaceName": { "type": "string", "minLength": 1 },
|
|
16
|
+
"surfaceType": { "type": "string", "minLength": 1 },
|
|
17
|
+
"parentSurfaceRefs": { "$ref": "#/$defs/refs" },
|
|
18
|
+
"relation": { "const": "hosts" },
|
|
19
|
+
"status": { "enum": ["root", "determined", "multiple", "unresolved"] },
|
|
20
|
+
"sourceEvidence": { "$ref": "#/$defs/evidenceList" }
|
|
21
|
+
},
|
|
22
|
+
"additionalProperties": false
|
|
23
|
+
},
|
|
24
|
+
"controls": { "type": "array", "items": { "$ref": "#/$defs/control" } },
|
|
25
|
+
"entries": { "type": "array", "items": { "$ref": "#/$defs/entry" } }
|
|
26
|
+
},
|
|
27
|
+
"$defs": {
|
|
28
|
+
"refs": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
|
|
29
|
+
"evidence": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"required": ["file", "symbol", "line", "endLine"],
|
|
32
|
+
"properties": {
|
|
33
|
+
"file": { "type": "string", "minLength": 1 },
|
|
34
|
+
"symbol": { "type": ["string", "null"] },
|
|
35
|
+
"line": { "type": ["integer", "null"], "minimum": 1 },
|
|
36
|
+
"endLine": { "type": ["integer", "null"], "minimum": 1 }
|
|
37
|
+
},
|
|
38
|
+
"additionalProperties": false
|
|
39
|
+
},
|
|
40
|
+
"evidenceList": { "type": "array", "items": { "$ref": "#/$defs/evidence" } },
|
|
41
|
+
"control": {
|
|
42
|
+
"type": "object",
|
|
43
|
+
"required": ["controlRef", "sourceCarrierRef", "name", "surfaceRef", "status", "sourceEvidence"],
|
|
44
|
+
"properties": {
|
|
45
|
+
"controlRef": { "type": "string", "minLength": 1 },
|
|
46
|
+
"sourceCarrierRef": { "type": "string", "minLength": 1 },
|
|
47
|
+
"name": { "type": "string", "minLength": 1 },
|
|
48
|
+
"surfaceRef": { "type": "string", "minLength": 1 },
|
|
49
|
+
"status": { "const": "determined" },
|
|
50
|
+
"sourceEvidence": { "$ref": "#/$defs/evidenceList" }
|
|
51
|
+
},
|
|
52
|
+
"additionalProperties": false
|
|
53
|
+
},
|
|
54
|
+
"entry": {
|
|
55
|
+
"type": "object",
|
|
56
|
+
"required": ["entryRef", "triggerCategory", "componentType", "ownershipStatus", "surfaceRef", "surfaceName", "surfaceType", "carrierRef", "carrierName", "carrierStatus", "event", "displayLabel", "handlerNames", "callTrace", "sourceEvidence", "warnings"],
|
|
57
|
+
"properties": {
|
|
58
|
+
"entryRef": { "type": "string", "minLength": 1 },
|
|
59
|
+
"triggerCategory": { "enum": ["user", "system", "application"] },
|
|
60
|
+
"componentType": { "enum": ["activity", "fragment", "dialog", "service", "receiver", "provider", "control", "custom-view", "unknown"] },
|
|
61
|
+
"ownershipStatus": { "enum": ["determined", "ambiguous", "unresolved"] },
|
|
62
|
+
"surfaceRef": { "type": ["string", "null"] },
|
|
63
|
+
"surfaceName": { "type": "string" },
|
|
64
|
+
"surfaceType": { "type": "string" },
|
|
65
|
+
"carrierRef": { "type": ["string", "null"] },
|
|
66
|
+
"carrierName": { "type": "string" },
|
|
67
|
+
"carrierStatus": { "enum": ["determined", "category-only", "not-applicable", "unknown"] },
|
|
68
|
+
"event": { "type": "string", "minLength": 1 },
|
|
69
|
+
"displayLabel": { "type": "string", "minLength": 1 },
|
|
70
|
+
"handlerNames": { "$ref": "#/$defs/refs" },
|
|
71
|
+
"callTrace": {
|
|
72
|
+
"type": "object",
|
|
73
|
+
"required": ["handlerRefs", "codeRefs", "callEdges", "truncated", "coverageWarnings"],
|
|
74
|
+
"properties": {
|
|
75
|
+
"handlerRefs": { "$ref": "#/$defs/refs" },
|
|
76
|
+
"codeRefs": { "type": "array", "items": { "type": "object" } },
|
|
77
|
+
"callEdges": {
|
|
78
|
+
"type": "array",
|
|
79
|
+
"items": {
|
|
80
|
+
"type": "object",
|
|
81
|
+
"required": ["from", "to"],
|
|
82
|
+
"properties": { "from": { "type": "string", "minLength": 1 }, "to": { "type": "string", "minLength": 1 } },
|
|
83
|
+
"additionalProperties": false
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
"truncated": { "type": "boolean" },
|
|
87
|
+
"coverageWarnings": { "type": "array", "items": { "type": "string" } }
|
|
88
|
+
},
|
|
89
|
+
"additionalProperties": false
|
|
90
|
+
},
|
|
91
|
+
"sourceEvidence": { "$ref": "#/$defs/evidenceList" },
|
|
92
|
+
"warnings": { "type": "array", "items": { "type": "string" } }
|
|
93
|
+
},
|
|
94
|
+
"additionalProperties": false
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"additionalProperties": false
|
|
98
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://harmonyos-ai.dev/schemas/spec-pages-index.schema.json","title":"SPEC Facts or Semantics Pages Index","type":"object","required":["indexVersion","pages","unassignedEntriesFile"],"properties":{"indexVersion":{"const":"2.0.0"},"pages":{"type":"array","items":{"type":"object","required":["surfaceRef","file"],"properties":{"surfaceRef":{"type":"string","minLength":1},"surfaceType":{"type":"string","minLength":1},"file":{"type":"string","pattern":"^(facts|semantics)/pages/.+\\.json$"}},"additionalProperties":false}},"unassignedEntriesFile":{"type":["string","null"]}},"additionalProperties":false}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://harmonyos-ai.dev/schemas/spec-unresolved-shard.schema.json","title":"SPEC Unresolved Semantics Shard","type":"object","required":["shardVersion","reviews"],"properties":{"shardVersion":{"const":"2.0.0"},"reviews":{"type":"array","items":{"type":"object","required":["unresolvedRef","decision","featureRef","reason"],"properties":{"unresolvedRef":{"type":"string","minLength":1},"decision":{"enum":["pending","covered-by-feature","excluded","accepted-unknown"]},"featureRef":{"type":["string","null"]},"reason":{"type":["string","null"]}},"additionalProperties":false}}},"additionalProperties":false}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://harmonyos-ai.dev/schemas/task-envelope.schema.json",
|
|
4
|
+
"title": "Android to HarmonyOS Task Envelope Page",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["taskEnvelopeVersion", "taskPlanSha256", "task", "brief", "coreFacts", "sourceContext", "continuation"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"taskEnvelopeVersion": { "const": "1.0.0" },
|
|
9
|
+
"taskPlanSha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
10
|
+
"task": { "type": "object" },
|
|
11
|
+
"brief": { "type": "string", "minLength": 1 },
|
|
12
|
+
"coreFacts": { "type": "array" },
|
|
13
|
+
"sourceContext": {
|
|
14
|
+
"description": "Bounded source location indexes only. Source text/snippets are forbidden.",
|
|
15
|
+
"type": "array",
|
|
16
|
+
"maxItems": 200,
|
|
17
|
+
"items": { "$ref": "#/$defs/sourceIndex" }
|
|
18
|
+
},
|
|
19
|
+
"continuation": {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"required": ["cursor", "remainingSourceContext"],
|
|
22
|
+
"properties": {
|
|
23
|
+
"cursor": { "type": ["string", "null"] },
|
|
24
|
+
"remainingSourceContext": { "type": "integer", "minimum": 0 }
|
|
25
|
+
},
|
|
26
|
+
"additionalProperties": false
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"$defs": {
|
|
30
|
+
"sourceIndex": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"required": ["kind", "value"],
|
|
33
|
+
"properties": {
|
|
34
|
+
"kind": { "enum": ["source-evidence", "code-ref"] },
|
|
35
|
+
"value": {
|
|
36
|
+
"type": "object",
|
|
37
|
+
"properties": {
|
|
38
|
+
"id": { "type": "string" },
|
|
39
|
+
"file": { "type": "string", "minLength": 1 },
|
|
40
|
+
"name": { "type": "string" },
|
|
41
|
+
"symbol": { "type": ["string", "null"] },
|
|
42
|
+
"kind": { "type": "string" },
|
|
43
|
+
"type": { "type": "string" },
|
|
44
|
+
"line": { "type": ["integer", "null"], "minimum": 1 },
|
|
45
|
+
"startLine": { "type": "integer", "minimum": 1 },
|
|
46
|
+
"endLine": { "type": ["integer", "null"], "minimum": 1 }
|
|
47
|
+
},
|
|
48
|
+
"additionalProperties": false
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"additionalProperties": false
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"additionalProperties": false
|
|
55
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://harmonyos-ai.dev/schemas/task-plan.schema.json",
|
|
4
|
+
"title": "Android to HarmonyOS Task Plan",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["taskPlanVersion", "planningModelVersion", "factsAdapterVersion", "plannerPolicyVersion", "baseline", "entryResolution", "tasks", "ownership", "planningWarnings"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"taskPlanVersion": { "const": "1.0.0" },
|
|
9
|
+
"planningModelVersion": { "const": "1.0.0" },
|
|
10
|
+
"factsAdapterVersion": { "const": "1.0.0" },
|
|
11
|
+
"plannerPolicyVersion": { "const": "1.1.0" },
|
|
12
|
+
"baseline": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"required": ["factsSha256", "planningInputSha256", "androidFingerprint", "specVersion", "factsWireVersion"],
|
|
15
|
+
"properties": {
|
|
16
|
+
"factsSha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
17
|
+
"planningInputSha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
18
|
+
"androidFingerprint": { "type": ["string", "null"], "pattern": "^[a-f0-9]{64}$" },
|
|
19
|
+
"specVersion": { "type": "string", "minLength": 1 },
|
|
20
|
+
"factsWireVersion": { "const": "2.0.0" }
|
|
21
|
+
},
|
|
22
|
+
"additionalProperties": false
|
|
23
|
+
},
|
|
24
|
+
"entryResolution": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"required": ["launcherSurfaceRefs", "launcherEntryRefs", "origin"],
|
|
27
|
+
"properties": {
|
|
28
|
+
"launcherSurfaceRefs": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
|
|
29
|
+
"launcherEntryRefs": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
|
|
30
|
+
"origin": { "enum": ["explicit-fact", "launch-entry-fact", "unresolved"] }
|
|
31
|
+
},
|
|
32
|
+
"additionalProperties": false
|
|
33
|
+
},
|
|
34
|
+
"tasks": { "type": "array", "items": { "$ref": "#/$defs/task" } },
|
|
35
|
+
"ownership": {
|
|
36
|
+
"type": "object",
|
|
37
|
+
"required": ["primaryOwnerByFactRef", "supportingTaskIdsByFactRef"],
|
|
38
|
+
"properties": {
|
|
39
|
+
"primaryOwnerByFactRef": { "type": "object", "additionalProperties": { "type": "string", "minLength": 1 } },
|
|
40
|
+
"supportingTaskIdsByFactRef": { "type": "object", "additionalProperties": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } } }
|
|
41
|
+
},
|
|
42
|
+
"additionalProperties": false
|
|
43
|
+
},
|
|
44
|
+
"planningWarnings": { "type": "array", "items": { "$ref": "#/$defs/warning" } }
|
|
45
|
+
},
|
|
46
|
+
"$defs": {
|
|
47
|
+
"warning": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"required": ["code", "message", "relatedRefs"],
|
|
50
|
+
"properties": {
|
|
51
|
+
"code": { "type": "string", "minLength": 1 },
|
|
52
|
+
"message": { "type": "string", "minLength": 1 },
|
|
53
|
+
"relatedRefs": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } }
|
|
54
|
+
},
|
|
55
|
+
"additionalProperties": false
|
|
56
|
+
},
|
|
57
|
+
"evidence": {
|
|
58
|
+
"type": "object",
|
|
59
|
+
"required": ["file", "symbol", "line", "endLine"],
|
|
60
|
+
"properties": {
|
|
61
|
+
"file": { "type": "string", "minLength": 1 },
|
|
62
|
+
"symbol": { "type": ["string", "null"] },
|
|
63
|
+
"line": { "type": ["integer", "null"], "minimum": 1 },
|
|
64
|
+
"endLine": { "type": ["integer", "null"], "minimum": 1 }
|
|
65
|
+
},
|
|
66
|
+
"additionalProperties": false
|
|
67
|
+
},
|
|
68
|
+
"task": {
|
|
69
|
+
"type": "object",
|
|
70
|
+
"required": ["id", "type", "title", "primaryFactRefs", "supportingFactRefs", "dependsOnTaskIds", "closure", "acceptance", "estimate"],
|
|
71
|
+
"properties": {
|
|
72
|
+
"id": { "type": "string", "pattern": "^task:[a-f0-9]{16}$" },
|
|
73
|
+
"type": { "enum": ["resolution", "bootstrap", "capability", "journey", "assembly", "regression"] },
|
|
74
|
+
"title": { "type": "string", "minLength": 1 },
|
|
75
|
+
"primaryFactRefs": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
|
|
76
|
+
"supportingFactRefs": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
|
|
77
|
+
"dependsOnTaskIds": { "type": "array", "uniqueItems": true, "items": { "type": "string", "pattern": "^task:[a-f0-9]{16}$" } },
|
|
78
|
+
"closure": {
|
|
79
|
+
"type": "object",
|
|
80
|
+
"required": ["entryRefs", "surfaceRefs", "controlRefs", "interactionRefs", "sourceEvidence", "codeRefs", "unresolvedRefs", "warningRefs", "requiresSourceReview"],
|
|
81
|
+
"properties": {
|
|
82
|
+
"entryRefs": { "$ref": "#/$defs/refs" },
|
|
83
|
+
"surfaceRefs": { "$ref": "#/$defs/refs" },
|
|
84
|
+
"controlRefs": { "$ref": "#/$defs/refs" },
|
|
85
|
+
"interactionRefs": { "$ref": "#/$defs/refs" },
|
|
86
|
+
"sourceEvidence": { "type": "array", "items": { "$ref": "#/$defs/evidence" } },
|
|
87
|
+
"codeRefs": { "type": "array", "items": { "type": "object" } },
|
|
88
|
+
"unresolvedRefs": { "$ref": "#/$defs/refs" },
|
|
89
|
+
"warningRefs": { "$ref": "#/$defs/refs" },
|
|
90
|
+
"requiresSourceReview": { "type": "boolean" }
|
|
91
|
+
},
|
|
92
|
+
"additionalProperties": false
|
|
93
|
+
},
|
|
94
|
+
"acceptance": {
|
|
95
|
+
"type": "object",
|
|
96
|
+
"required": ["observableOutcome", "requiredFactRefs", "verificationRequirements", "reportRefs"],
|
|
97
|
+
"properties": {
|
|
98
|
+
"observableOutcome": { "type": "string", "minLength": 1 },
|
|
99
|
+
"requiredFactRefs": { "$ref": "#/$defs/refs" },
|
|
100
|
+
"verificationRequirements": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
|
|
101
|
+
"reportRefs": { "$ref": "#/$defs/refs" }
|
|
102
|
+
},
|
|
103
|
+
"additionalProperties": false
|
|
104
|
+
},
|
|
105
|
+
"estimate": {
|
|
106
|
+
"type": "object",
|
|
107
|
+
"required": ["factCount", "sourceFileCount", "traceNodeCount", "estimatedFactTokens", "downstreamUnlockCount"],
|
|
108
|
+
"properties": {
|
|
109
|
+
"factCount": { "type": "integer", "minimum": 0 },
|
|
110
|
+
"sourceFileCount": { "type": "integer", "minimum": 0 },
|
|
111
|
+
"traceNodeCount": { "type": "integer", "minimum": 0 },
|
|
112
|
+
"estimatedFactTokens": { "type": "integer", "minimum": 0 },
|
|
113
|
+
"downstreamUnlockCount": { "type": "integer", "minimum": 0 }
|
|
114
|
+
},
|
|
115
|
+
"additionalProperties": false
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"additionalProperties": false
|
|
119
|
+
},
|
|
120
|
+
"refs": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } }
|
|
121
|
+
},
|
|
122
|
+
"additionalProperties": false
|
|
123
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: android2hmos_resources_convert
|
|
3
|
+
description: >-
|
|
4
|
+
Android 图片资源迁移到 HarmonyOS:位图(png/jpg/webp/gif/bmp)、nine-patch(.9.png)、mipmap 启动图标、
|
|
5
|
+
自适应图标(adaptive-icon → layered_image.json)以及 XML drawable(vector/shape/layer-list/selector → SVG)。
|
|
6
|
+
当用户要求把 Android 项目的图标、图片、drawable 资产迁移/转换到鸿蒙工程(res/ → resources/…/media/),
|
|
7
|
+
处理限定符目录映射(drawable-hdpi、drawable-night、mipmap-anydpi-v26 等),或修复迁移后图片在鸿蒙上
|
|
8
|
+
显示空白/错误时触发。即使只说「迁移图标」「图片没迁移」「矢量图转 SVG」也应触发。
|
|
9
|
+
不处理 values 资源(strings/colors/dimens 的迁移归 arkts-i18n)、布局、Lottie 和字体。
|
|
10
|
+
type: domain
|
|
11
|
+
domain: migration
|
|
12
|
+
tags: [migration, resources, android, images, svg, drawable]
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Android → HarmonyOS 图片资源转换
|
|
16
|
+
|
|
17
|
+
本 skill 只转换**图片类资源**:位图文件(png/jpg/webp/gif/bmp)、nine-patch 图片、启动图标(mipmap、自适应图标),
|
|
18
|
+
以及作为图片渲染的 XML drawable(`<vector>`、`<shape>`、`<layer-list>`、`<selector>`)→ SVG。
|
|
19
|
+
values 资源(strings/colors/dimens 的迁移)、布局、Lottie、字体明确不在范围内;`values*/colors.xml` 和
|
|
20
|
+
`values*/dimens.xml` 只作为解析 drawable 内 `@color:`/`@dimen:` 引用的查找来源被读取。
|
|
21
|
+
|
|
22
|
+
## 参考文档
|
|
23
|
+
|
|
24
|
+
| 要做什么 | 读什么 |
|
|
25
|
+
|---|---|
|
|
26
|
+
| 拷贝/转换位图、nine-patch、mipmap、自适应图标;限定符目录映射 | `references/image-conversion-rules.md` |
|
|
27
|
+
| Android XML Drawable(vector/shape/layer-list/selector)转 SVG | `references/xml-drawable-to-svg-rules.md` |
|
|
28
|
+
| 修复 SVG 显示问题(空白/不可见/尺寸错误/残留 Android 语法) | `references/svg-fix-patterns.md` |
|
|
29
|
+
|
|
30
|
+
## 输入
|
|
31
|
+
|
|
32
|
+
1. **Android 工程路径** — Android Gradle 工程根目录(含 `build.gradle` 或 `build.gradle.kts`)。
|
|
33
|
+
2. **HarmonyOS 工程路径** — 由 Preflight 创建或复用的工程(见 `preparing-migration-workspace`),通常是迁移工作区下的 `ohos/`,或 `.migration/config.json` 中 `--harmony-project` 配置的路径。图片写入 `<harmony>/entry/src/main/resources/`。本 skill 不创建工程壳;`ohos/` 尚不存在时先运行 Preflight。
|
|
34
|
+
|
|
35
|
+
## 工作流
|
|
36
|
+
|
|
37
|
+
### 第 1 步:校验输入
|
|
38
|
+
|
|
39
|
+
1. 确认 Android 工程路径存在且含 `build.gradle` 或 `build.gradle.kts`。
|
|
40
|
+
2. 通过 `droid2hmos status <ANDROID_PROJECT>` 或 `.migration/config.json` 确认 HarmonyOS 工程位置,并确认 `entry/src/main/resources/` 存在;不存在时停止并先补 Preflight,不要猜测工程结构。
|
|
41
|
+
|
|
42
|
+
### 第 2 步:确定资源来源
|
|
43
|
+
|
|
44
|
+
使用工程源码 `res/` 目录:
|
|
45
|
+
|
|
46
|
+
- 首选 `<android_project>/app/src/main/res/`
|
|
47
|
+
- 多模块工程同时检查其它模块目录
|
|
48
|
+
- 使用 flavor source set 时一并纳入(如 `app/src/debug/res/`、`app/src/flavor/res/`)
|
|
49
|
+
|
|
50
|
+
恒定从源码 `res/` 转换:仅由库依赖(AAR)提供的图片不在源码 `res/` 中,这类引用在报告中记为 unresolved,不尝试回收。
|
|
51
|
+
|
|
52
|
+
### 第 3 步:清点与分类
|
|
53
|
+
|
|
54
|
+
扫描资源来源中的每个 `drawable*/` 和 `mipmap*/` 目录。对每个文件按**内容**分类(`.xml` 文件读根元素判断,绝不只按目录名分类):
|
|
55
|
+
|
|
56
|
+
| 分类 | 判定 | 路由 |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| 位图 | `.png`、`.jpg`、`.jpeg`、`.gif`、`.webp`、`.bmp` | 直接拷贝(第 4.1 步) |
|
|
59
|
+
| Nine-patch | `.9.png` | 拷贝 + 重命名(第 4.1 步) |
|
|
60
|
+
| XML drawable:vector/shape/layer-list | `.xml`,根 `<vector>` / `<shape>` / `<layer-list>` | 转 SVG(第 4.2 步) |
|
|
61
|
+
| XML drawable:selector | `.xml`,根 `<selector>` | 提取默认状态 → SVG(第 4.2 步) |
|
|
62
|
+
| 自适应图标 | `.xml`,根 `<adaptive-icon>` | 转 layered-image JSON(第 4.3 步) |
|
|
63
|
+
| ripple/animated-vector/animated-selector/transition/level-list 等 | `.xml`,对应根元素 | 不可映射 — 记入报告 |
|
|
64
|
+
|
|
65
|
+
忽略 `values*/`、`layout*/`、`menu/`、`raw/`、`font/`、`xml/`、`anim*/`、`color/` — 超出范围。只有 `values*/colors.xml` 和 `values*/dimens.xml` 被读取,用于解析 drawable 内的 `@color:`/`@dimen:` 引用(第 4.4 步)。
|
|
66
|
+
|
|
67
|
+
### 第 4 步:转换
|
|
68
|
+
|
|
69
|
+
转换前先读 `references/image-conversion-rules.md`。四条路由概要:
|
|
70
|
+
|
|
71
|
+
**4.1 位图与 nine-patch → `media/`**
|
|
72
|
+
- 拷贝到限定符映射后的 `media/` 目录(完整限定符算法见 image-conversion-rules.md)
|
|
73
|
+
- `.9.png` → 重命名为 `<name>_9.png`(HarmonyOS 禁止资源文件名中含 `.`,仅允许最后扩展名分隔符)。nine-patch 拉伸语义丢失 — 报告中记录
|
|
74
|
+
|
|
75
|
+
**4.2 XML drawable → `media/` 中的 `.svg`**
|
|
76
|
+
- 严格按 `references/xml-drawable-to-svg-rules.md` 执行 — 尤其是强制保留 `clip-path`、三分支 `fill` 规则和渐变处理
|
|
77
|
+
- 每生成一个 SVG 后,执行该文档中的自检(clip-path 数量、fill 规则、viewBox 匹配)
|
|
78
|
+
|
|
79
|
+
**4.3 自适应图标 → layered-image JSON**
|
|
80
|
+
- `<adaptive-icon>` → `<name>_layered_image.json`,只含 `background`/`foreground` 键
|
|
81
|
+
- `@drawable/xxx`、`@mipmap/xxx` → `$media:xxx`;`@color/xxx` → 生成纯色 PNG(`<color_name>_bg.png`)— layered-image 不接受 `$color:` 引用
|
|
82
|
+
- `monochrome` 不写入 JSON,但其引用的 drawable 仍按普通图片转换
|
|
83
|
+
|
|
84
|
+
**4.4 解析 drawable 内引用**
|
|
85
|
+
- SVG 填充/描边中的 `@color/name` → 从 `values*/colors.xml` 解析(沿引用链;兜底 `#000000` + 记录)
|
|
86
|
+
- SVG 尺寸中的 `@dimen/name` → 从 `values*/dimens.xml` 解析(兜底:合理默认值 + 记录)
|
|
87
|
+
- 未解析引用(库专属资源不在源码 `res/`)记入报告,绝不静默丢弃
|
|
88
|
+
|
|
89
|
+
### 第 5 步:完整性校验
|
|
90
|
+
|
|
91
|
+
1. 第 3 步发现的每个文件都有且只有一个结局:已转换,或在报告中列为 unmappable/unmapped
|
|
92
|
+
2. 每个转换产物都实际存在于 HarmonyOS 工程
|
|
93
|
+
3. 生成的 layered-image JSON 中每个 `$media:xxx` 引用都指向 `media/` 中存在的文件
|
|
94
|
+
4. 每个转换后的 SVG 通过 `references/xml-drawable-to-svg-rules.md` 的自检
|
|
95
|
+
5. HarmonyOS 工程已有 `.ets` 文件时,扫描 `$r('app.media.xxx')` 并核对每个引用的图片存在(已有 media 文件**不覆盖** — 合并,冲突记录)
|
|
96
|
+
|
|
97
|
+
### 第 6 步:生成报告
|
|
98
|
+
|
|
99
|
+
按 `maintaining-migration-report` 的轻量原则,把转换报告落盘到迁移工作区(如 `.migration/` 下)或直接向用户呈现,结构如下:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
# Android to HarmonyOS Image Conversion Report
|
|
103
|
+
|
|
104
|
+
## Resource Source
|
|
105
|
+
- Resource source: source res/ (library-only images not included)
|
|
106
|
+
- Resource source path: <path>
|
|
107
|
+
|
|
108
|
+
## Summary
|
|
109
|
+
- Image files found (bitmap/9-patch/XML drawable/adaptive icon): <count per class>
|
|
110
|
+
- Successfully converted: <count>
|
|
111
|
+
- Unmappable (ripple/animated-vector/etc.): <count>
|
|
112
|
+
- Unmapped (unsupported qualifiers): <count>
|
|
113
|
+
- Unresolved color/dimen references: <count>
|
|
114
|
+
|
|
115
|
+
## Converted Images
|
|
116
|
+
| Android Source | HarmonyOS Target | Type | Notes |
|
|
117
|
+
|---|---|---|---|
|
|
118
|
+
|
|
119
|
+
## Qualifier Mappings Applied
|
|
120
|
+
| Android Qualifier Dir | HarmonyOS Qualifier Dir | Files Converted |
|
|
121
|
+
|---|---|---|---|
|
|
122
|
+
|
|
123
|
+
## Unmappable Resources
|
|
124
|
+
| Android Source | Reason |
|
|
125
|
+
|---|---|
|
|
126
|
+
|
|
127
|
+
## Unresolved References
|
|
128
|
+
| Resource File | Reference | Reason | Likely Source |
|
|
129
|
+
|---|---|---|---|
|
|
130
|
+
|
|
131
|
+
## Verification Results
|
|
132
|
+
- All image files accounted for: Yes/No
|
|
133
|
+
- All $media references satisfied: Yes/No
|
|
134
|
+
- SVG self-checks passed: Yes/No
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
影响行为的结论(不可映射资源、丢失的 nine-patch 语义、未解析引用)必须回流到对应报告分片的说明,或按 orchestrator 约定写入 `discoveries.json`;不要只留在一次性报告里。
|
|
138
|
+
|
|
139
|
+
### 第 7 步:Git 检查点
|
|
140
|
+
|
|
141
|
+
一个连贯、已校验的转换批次完成后,按仓库约定创建检查点(只纳入 HarmonyOS 工程内的资源文件):
|
|
142
|
+
|
|
143
|
+
```text
|
|
144
|
+
droid2hmos checkpoint create <ANDROID_PROJECT> --message <MESSAGE> --include <harmony>/entry/src/main/resources
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## 重要说明
|
|
148
|
+
|
|
149
|
+
- **XML drawable 转换是关键**:vector/shape/layer-list/selector 必须转成 SVG,不能跳过。转换前务必读 `references/xml-drawable-to-svg-rules.md` — 其中的属性映射表就是规范。
|
|
150
|
+
- **SVG 渲染问题**(空白、不可见、尺寸错误、残留 `android:` 语法)按 `references/svg-fix-patterns.md` 处理,不做临时猜测。
|
|
151
|
+
- **限定符目录是映射,不是保留**:`drawable-hdpi` → `ldpi/media/`(两平台 DPI 标签不同);`night` → `dark`;`land` → `horizontal`;`v<N>` 剥离;`sw<N>dp`/`w<N>dp`/屏幕尺寸限定符整目录跳过。完整算法见 `references/image-conversion-rules.md`。
|
|
152
|
+
- **转换恒定从源码 `res/` 出发**:仅库依赖(AAR)提供的图片不在其中;对它们的引用按 unresolved 报告,不做恢复。
|
|
153
|
+
- 资源名保持 Android 原拼写 — 它们是标识符。
|
|
154
|
+
- 解析 Android XML 时正确处理命名空间、注释和 CDATA;按 local name 匹配属性。
|
|
155
|
+
|
|
156
|
+
## 与其他 skill 的关系
|
|
157
|
+
|
|
158
|
+
- **preparing-migration-workspace**:⭐ 前置依赖。本 skill 需要 Preflight 已创建或复用的 HarmonyOS 工程(`ohos/`)。
|
|
159
|
+
- **arkts-app-identity**:它处理 App 级身份资源(app.json5 图标字段、版本号、包名);本 skill 负责 res/ 全量图片资产进 `media/`。启动器图标的位图/分层资产由本 skill 转换,app.json5 的接线归它。
|
|
160
|
+
- **arkts-icon-sizing**:图片资产就位后,它修 `.ets` 消费侧丢失的 `.width()/.height()`;本 skill 只管资源侧。
|
|
161
|
+
- **arkts-i18n**:values 资源(string.json 等)的迁移归它;本 skill 只把 colors.xml/dimens.xml 当查找源。
|
|
162
|
+
- **maintaining-migration-report**:转换结论回流报告分片的轻量约定。
|