@harmonyos-arkts/d2h 0.1.11 → 0.1.13

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 (126) hide show
  1. package/.claude-plugin/marketplace.json +15 -13
  2. package/.claude-plugin/plugin.json +13 -7
  3. package/AGENTS.md +5 -5
  4. package/README.md +212 -212
  5. package/agents/android-to-hmos-00-orchestrator.md +318 -318
  6. package/agents/d2h.md +157 -157
  7. package/dist/bin/install-opencode.js +30 -30
  8. package/docs/environment-check.md +86 -86
  9. package/install-opencode.sh +160 -160
  10. package/opencode/agents.json +16 -16
  11. package/opencode/vscode-d2h-package.json +7 -7
  12. package/opencode/vscode-d2h-plugin.mjs +29 -29
  13. package/package.json +54 -54
  14. package/schemas/android-source-manifest.schema.json +25 -25
  15. package/schemas/checkpoint-provenance.schema.json +67 -67
  16. package/schemas/final-acceptance.schema.json +29 -29
  17. package/schemas/managed-evidence-index.schema.json +15 -15
  18. package/schemas/managed-evidence.schema.json +114 -114
  19. package/schemas/migration-config.schema.json +51 -51
  20. package/schemas/migration-report-index.schema.json +39 -39
  21. package/schemas/migration-report-item.schema.json +51 -51
  22. package/schemas/migration-report-summary.schema.json +25 -25
  23. package/schemas/migration-status.schema.json +202 -202
  24. package/schemas/preflight.schema.json +60 -60
  25. package/schemas/source-order-audit.schema.json +16 -16
  26. package/schemas/source-provenance-event.schema.json +19 -19
  27. package/schemas/spec-app-shard.schema.json +45 -45
  28. package/schemas/spec-fact-corrections-shard.schema.json +13 -13
  29. package/schemas/spec-features-shard.schema.json +43 -43
  30. package/schemas/spec-index.schema.json +26 -26
  31. package/schemas/spec-interactions-shard.schema.json +40 -40
  32. package/schemas/spec-page.schema.json +98 -98
  33. package/schemas/spec-pages-index.schema.json +1 -1
  34. package/schemas/spec-unresolved-shard.schema.json +1 -1
  35. package/schemas/task-envelope.schema.json +109 -109
  36. package/schemas/task-plan.schema.json +341 -341
  37. package/scripts/check-environment.mjs +320 -320
  38. package/skills/android2hmos_resources_convert/SKILL.md +180 -180
  39. package/skills/android2hmos_resources_convert/references/image-conversion-rules.md +230 -230
  40. package/skills/android2hmos_resources_convert/references/svg-fix-patterns.md +175 -175
  41. package/skills/android2hmos_resources_convert/references/xml-drawable-to-svg-rules.md +513 -513
  42. package/skills/arkts-app-identity/SKILL.md +238 -238
  43. package/skills/arkts-i18n/SKILL.md +496 -496
  44. package/skills/arkts-i18n/evals/evals.json +84 -84
  45. package/skills/arkts-i18n/references/code-examples.md +302 -302
  46. package/skills/arkts-i18n/references/common-pitfalls.md +391 -391
  47. package/skills/arkts-i18n/references/dynamic-language-switch.md +604 -604
  48. package/skills/arkts-i18n/references/hardcoded-string-scanner.md +348 -348
  49. package/skills/arkts-i18n/references/language-codes.md +104 -104
  50. package/skills/arkts-i18n/references/resource-file-structure.md +775 -775
  51. package/skills/arkts-i18n/references/static-vs-dynamic.md +242 -242
  52. package/skills/arkts-i18n/references/v1-compat.md +244 -244
  53. package/skills/arkts-i18n/scripts/audit_i18n_completeness.sh +174 -174
  54. package/skills/arkts-icon-sizing/SKILL.md +211 -211
  55. package/skills/arkts-icon-sizing/scripts/icon_audit.py +131 -131
  56. package/skills/arkts-icon-sizing/scripts/icon_autofix.py +88 -88
  57. package/skills/arkts-icon-sizing/scripts/icon_dims.py +179 -179
  58. package/skills/arkts-icon-sizing/scripts/icon_fix.py +119 -119
  59. package/skills/arkts-mvvm-architecture/SKILL.md +613 -613
  60. package/skills/d2h-hypium-forge/SKILL.md +309 -309
  61. package/skills/d2h-hypium-forge/references/functional-spec-template.md +140 -140
  62. package/skills/d2h-hypium-forge/references/official-api.md +135 -135
  63. package/skills/d2h-hypium-forge/references/pitfalls.md +98 -98
  64. package/skills/d2h-hypium-forge/references/testability-template.md +71 -71
  65. package/skills/d2h-hypium-forge/scripts/_common_template.py +659 -659
  66. package/skills/d2h-hypium-forge/scripts/analyze_results.py +165 -165
  67. package/skills/d2h-hypium-forge/scripts/assert_audit.py +107 -107
  68. package/skills/d2h-hypium-forge/scripts/collect_runtime_pages.py +169 -169
  69. package/skills/d2h-hypium-forge/scripts/forge_report.py +325 -325
  70. package/skills/d2h-hypium-forge/scripts/inject_resource_ids.py +114 -114
  71. package/skills/d2h-hypium-forge/scripts/lint_asserts.py +80 -80
  72. package/skills/d2h-hypium-forge/scripts/lint_locate.py +60 -60
  73. package/skills/d2h-hypium-forge/scripts/merge_appgraph.py +249 -249
  74. package/skills/d2h-hypium-forge/scripts/precondition.py +140 -140
  75. package/skills/d2h-hypium-forge/scripts/preinject_ids.py +232 -232
  76. package/skills/d2h-hypium-forge/scripts/probe.py +197 -197
  77. package/skills/d2h-hypium-forge/scripts/run_direct.py +823 -823
  78. package/skills/d2h-hypium-forge/scripts/run_parallel.py +121 -121
  79. package/skills/d2h-hypium-forge/scripts/scan_features.py +255 -255
  80. package/skills/d2h-hypium-forge/scripts/upgrade_asserts.py +66 -66
  81. package/skills/d2h-hypium-forge/scripts/validate_scenarios.py +84 -84
  82. package/skills/d2h-page-develop/SKILL.md +112 -112
  83. package/skills/d2h-page-develop/agents/openai.yaml +7 -7
  84. package/skills/d2h-page-spec-generate/SKILL.md +206 -206
  85. package/skills/d2h-page-spec-generate/scripts/build_batch_report.py +227 -227
  86. package/skills/d2h-utg-ai-generate/SKILL.md +128 -128
  87. package/skills/d2h-utg-ai-generate/references/click-paths-schema.json +76 -76
  88. package/skills/d2h-utg-ai-generate/references/extraction-guide.md +34 -34
  89. package/skills/d2h-utg-ai-generate/references/facts-contract.md +96 -96
  90. package/skills/d2h-utg-ai-generate/references/page-schema.json +61 -61
  91. package/skills/d2h-utg-ai-generate/references/utg-schema.json +89 -89
  92. package/skills/d2h-utg-ai-generate/scripts/build_page_json.py +314 -314
  93. package/skills/d2h-utg-ai-generate/scripts/build_utg.py +123 -123
  94. package/skills/d2h-utg-ai-generate/scripts/capture_from_page_json.ts +280 -280
  95. package/skills/d2h-utg-ai-generate/scripts/utg_common.py +524 -524
  96. package/skills/d2h-utg-ai-generate/scripts/utg_html.py +489 -489
  97. package/skills/d2h-utg-ai-generate/scripts/validate_utg.py +69 -69
  98. package/skills/d2h-utg-ai-generate/scripts/vendor/D3-LICENSE +13 -13
  99. package/skills/d2h-utg-ai-generate/scripts/vendor/d3-7.9.0.min.js +2 -2
  100. package/skills/d2h-utg-ai-generate/tests/test_pipeline.py +369 -369
  101. package/skills/d2h-utg-static-generate/SKILL.md +73 -73
  102. package/skills/d2h-utg-static-generate/references/discoveries.md +38 -38
  103. package/skills/d2h-utg-static-generate/scripts/generate.py +499 -499
  104. package/skills/d2h-utg-static-generate/tests/test_static.py +335 -335
  105. package/skills/d2h-utg-static-generate/tests/verify-offline-html.py +60 -60
  106. package/skills/d2h-utg-static-generate/tests/verify-produced-fixture.py +131 -131
  107. package/skills/harmonyos-migration-playbook/SKILL.md +83 -83
  108. package/skills/harmonyos-migration-playbook/agents/openai.yaml +7 -7
  109. package/skills/harmonyos-migration-playbook/references/arkts-compile.md +24 -24
  110. package/skills/harmonyos-migration-playbook/references/harmony-runtime.md +53 -53
  111. package/skills/harmonyos-migration-playbook/references/lesson-lifecycle.md +45 -45
  112. package/skills/harmonyos-migration-playbook/references/protocol-e2e.md +23 -23
  113. package/skills/harmonyos-migration-playbook/references/ui-automation.md +53 -53
  114. package/skills/harmonyos-migration-playbook/references/windows-environment.md +38 -38
  115. package/skills/maintaining-migration-report/SKILL.md +144 -144
  116. package/skills/maintaining-migration-report/references/final-acceptance.md +48 -48
  117. package/skills/maintaining-migration-report/references/source-provenance.md +66 -66
  118. package/skills/managing-d2h-toolchain/SKILL.md +24 -24
  119. package/skills/managing-d2h-toolchain/environment-requirements.json +16 -16
  120. package/skills/managing-d2h-toolchain/scripts/manage-toolchain.mjs +98 -98
  121. package/skills/managing-d2h-toolchain/toolchain.json +16 -16
  122. package/skills/native-library-substitution/SKILL.md +384 -384
  123. package/skills/native-library-substitution/references/native-library-substitution.json +56905 -56905
  124. package/skills/native-library-substitution/references/native-library-substitution.md +163 -163
  125. package/skills/preparing-migration-workspace/SKILL.md +131 -131
  126. package/skills/reviewing-migration-process/SKILL.md +62 -62
@@ -1,98 +1,98 @@
1
- #!/usr/bin/env node
2
- import fs from 'node:fs';
3
- import path from 'node:path';
4
- import { spawnSync } from 'node:child_process';
5
- import { fileURLToPath } from 'node:url';
6
-
7
- const skillDir = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
8
-
9
- export function loadManifest(file = path.join(skillDir, 'toolchain.json')) {
10
- const manifest = JSON.parse(fs.readFileSync(file, 'utf8'));
11
- if (manifest?.schemaVersion !== 1 || !manifest.tools || Array.isArray(manifest.tools) ||
12
- !Object.keys(manifest.tools).length) throw new Error('invalid toolchain manifest');
13
- for (const [name, tool] of Object.entries(manifest.tools)) {
14
- if (!/^[a-z][a-z0-9-]*$/.test(name) || tool?.package !== `@harmonyos-arkts/${name}` ||
15
- !/^\d+\.\d+\.\d+$/.test(tool.version) || !tool.capabilities ||
16
- !Object.keys(tool.capabilities).length || Object.values(tool.capabilities).some(args =>
17
- !Array.isArray(args) || !args.length || args.some(arg => typeof arg !== 'string' || !arg))) {
18
- throw new Error(`invalid toolchain entry: ${name}`);
19
- }
20
- }
21
- return manifest;
22
- }
23
-
24
- export function run(command, args) {
25
- let executable = command;
26
- let parameters = args;
27
- if (process.platform === 'win32') {
28
- const quote = value => `'${value.replaceAll("'", "''")}'`;
29
- const binary = /^(npm|appgraph|droid2hmos)$/.test(command) ? `${command}.cmd` : command;
30
- const script = `& ${[binary, ...args].map(quote).join(' ')}; exit $LASTEXITCODE`;
31
- executable = 'powershell.exe';
32
- parameters = ['-NoProfile', '-NonInteractive', '-EncodedCommand', Buffer.from(script, 'utf16le').toString('base64')];
33
- }
34
- const result = spawnSync(executable, parameters, { encoding: 'utf8', windowsHide: true, timeout: 300000 });
35
- return { status: result.status, stdout: result.stdout ?? '', stderr: result.stderr ?? '', error: result.error };
36
- }
37
-
38
- export function inspect(name, tool, runner = run) {
39
- const result = runner(name, ['--version']);
40
- const installedVersion = result.status === 0 ? /\b\d+\.\d+\.\d+\b/.exec(`${result.stdout}\n${result.stderr}`)?.[0] ?? null : null;
41
- const capabilities = Object.fromEntries(Object.entries(tool.capabilities).map(([capability, args]) => {
42
- const probe = installedVersion ? runner(name, args) : null;
43
- const command = capability === 'analyze-android' ? 'analyze' : capability === 'build-android' ? 'build' : capability;
44
- return [capability, probe?.status === 0 && `${probe.stdout}\n${probe.stderr}`.includes(command)];
45
- }));
46
- return { name, package: tool.package, expectedVersion: tool.version, installedVersion,
47
- status: installedVersion === tool.version && Object.values(capabilities).every(Boolean) ? 'passed' : 'failed', capabilities };
48
- }
49
-
50
- export function manage({ action = 'check', manifestFile, force = false, runner = run, log = console.log } = {}) {
51
- if (!['check', 'install'].includes(action)) throw new Error(`unsupported action: ${action}`);
52
- const manifest = loadManifest(manifestFile);
53
- const results = Object.entries(manifest.tools).map(([name, tool]) => inspect(name, tool, runner));
54
- for (const item of results) log(`${item.status}: ${item.package} expected ${item.expectedVersion}, installed ${item.installedVersion ?? 'missing'}; capabilities ${JSON.stringify(item.capabilities)}`);
55
- if (action === 'check') return results.every(item => item.status === 'passed');
56
- const targets = force ? results : results.filter(item => item.status !== 'passed');
57
- if (!targets.length) return true;
58
- const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
59
- const root = runner(npm, ['root', '--global']);
60
- if (root.status !== 0 || !root.stdout.trim()) throw new Error(`cannot inspect global npm installation: ${root.stderr || root.error?.message || 'empty root'}`);
61
- // Check every target before making changes, so a protected npm link cannot cause a partial installation.
62
- for (const item of targets) {
63
- const target = path.join(root.stdout.trim(), ...item.package.split('/'));
64
- if (fs.existsSync(target) && fs.lstatSync(target).isSymbolicLink() && !force) {
65
- throw new Error(`${item.package} is an npm link at ${target}; rerun with --force to replace it`);
66
- }
67
- }
68
- for (const item of targets) {
69
- const coordinate = `${item.package}@${item.expectedVersion}`;
70
- const target = path.join(root.stdout.trim(), ...item.package.split('/'));
71
- const result = runner(npm, ['install', '--global', coordinate, ...(force ? ['--force'] : [])]);
72
- if (result.status !== 0) throw new Error(`failed to install ${coordinate}: ${result.stderr || result.error?.message}`);
73
- if (fs.existsSync(target) && fs.lstatSync(target).isSymbolicLink()) {
74
- throw new Error(`${coordinate} installation completed but npm link remains at ${target}`);
75
- }
76
- const verified = inspect(item.name, manifest.tools[item.name], runner);
77
- if (verified.status !== 'passed') throw new Error(`${coordinate} installed but CLI version or capabilities failed verification`);
78
- log(`installed and verified ${coordinate}`);
79
- }
80
- return true;
81
- }
82
-
83
- if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
84
- try {
85
- const [action = 'check', ...args] = process.argv.slice(2);
86
- if (action === '--help' || action === '-h') {
87
- console.log('Usage: node manage-toolchain.mjs check|install [--force]\nChecks exact AppGraph/droid2hmos versions and capabilities; install only changes missing or incompatible packages.');
88
- } else {
89
- if (args.some(arg => arg !== '--force') || args.filter(arg => arg === '--force').length > 1 || (action === 'check' && args.length)) {
90
- throw new Error('usage: node manage-toolchain.mjs check|install [--force]');
91
- }
92
- if (!manage({ action, force: args.includes('--force') })) process.exitCode = 1;
93
- }
94
- } catch (error) {
95
- console.error(`manage-toolchain: ${error instanceof Error ? error.message : String(error)}`);
96
- process.exitCode = 1;
97
- }
98
- }
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { spawnSync } from 'node:child_process';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const skillDir = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
8
+
9
+ export function loadManifest(file = path.join(skillDir, 'toolchain.json')) {
10
+ const manifest = JSON.parse(fs.readFileSync(file, 'utf8'));
11
+ if (manifest?.schemaVersion !== 1 || !manifest.tools || Array.isArray(manifest.tools) ||
12
+ !Object.keys(manifest.tools).length) throw new Error('invalid toolchain manifest');
13
+ for (const [name, tool] of Object.entries(manifest.tools)) {
14
+ if (!/^[a-z][a-z0-9-]*$/.test(name) || tool?.package !== `@harmonyos-arkts/${name}` ||
15
+ !/^\d+\.\d+\.\d+$/.test(tool.version) || !tool.capabilities ||
16
+ !Object.keys(tool.capabilities).length || Object.values(tool.capabilities).some(args =>
17
+ !Array.isArray(args) || !args.length || args.some(arg => typeof arg !== 'string' || !arg))) {
18
+ throw new Error(`invalid toolchain entry: ${name}`);
19
+ }
20
+ }
21
+ return manifest;
22
+ }
23
+
24
+ export function run(command, args) {
25
+ let executable = command;
26
+ let parameters = args;
27
+ if (process.platform === 'win32') {
28
+ const quote = value => `'${value.replaceAll("'", "''")}'`;
29
+ const binary = /^(npm|appgraph|droid2hmos)$/.test(command) ? `${command}.cmd` : command;
30
+ const script = `& ${[binary, ...args].map(quote).join(' ')}; exit $LASTEXITCODE`;
31
+ executable = 'powershell.exe';
32
+ parameters = ['-NoProfile', '-NonInteractive', '-EncodedCommand', Buffer.from(script, 'utf16le').toString('base64')];
33
+ }
34
+ const result = spawnSync(executable, parameters, { encoding: 'utf8', windowsHide: true, timeout: 300000 });
35
+ return { status: result.status, stdout: result.stdout ?? '', stderr: result.stderr ?? '', error: result.error };
36
+ }
37
+
38
+ export function inspect(name, tool, runner = run) {
39
+ const result = runner(name, ['--version']);
40
+ const installedVersion = result.status === 0 ? /\b\d+\.\d+\.\d+\b/.exec(`${result.stdout}\n${result.stderr}`)?.[0] ?? null : null;
41
+ const capabilities = Object.fromEntries(Object.entries(tool.capabilities).map(([capability, args]) => {
42
+ const probe = installedVersion ? runner(name, args) : null;
43
+ const command = capability === 'analyze-android' ? 'analyze' : capability === 'build-android' ? 'build' : capability;
44
+ return [capability, probe?.status === 0 && `${probe.stdout}\n${probe.stderr}`.includes(command)];
45
+ }));
46
+ return { name, package: tool.package, expectedVersion: tool.version, installedVersion,
47
+ status: installedVersion === tool.version && Object.values(capabilities).every(Boolean) ? 'passed' : 'failed', capabilities };
48
+ }
49
+
50
+ export function manage({ action = 'check', manifestFile, force = false, runner = run, log = console.log } = {}) {
51
+ if (!['check', 'install'].includes(action)) throw new Error(`unsupported action: ${action}`);
52
+ const manifest = loadManifest(manifestFile);
53
+ const results = Object.entries(manifest.tools).map(([name, tool]) => inspect(name, tool, runner));
54
+ for (const item of results) log(`${item.status}: ${item.package} expected ${item.expectedVersion}, installed ${item.installedVersion ?? 'missing'}; capabilities ${JSON.stringify(item.capabilities)}`);
55
+ if (action === 'check') return results.every(item => item.status === 'passed');
56
+ const targets = force ? results : results.filter(item => item.status !== 'passed');
57
+ if (!targets.length) return true;
58
+ const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
59
+ const root = runner(npm, ['root', '--global']);
60
+ if (root.status !== 0 || !root.stdout.trim()) throw new Error(`cannot inspect global npm installation: ${root.stderr || root.error?.message || 'empty root'}`);
61
+ // Check every target before making changes, so a protected npm link cannot cause a partial installation.
62
+ for (const item of targets) {
63
+ const target = path.join(root.stdout.trim(), ...item.package.split('/'));
64
+ if (fs.existsSync(target) && fs.lstatSync(target).isSymbolicLink() && !force) {
65
+ throw new Error(`${item.package} is an npm link at ${target}; rerun with --force to replace it`);
66
+ }
67
+ }
68
+ for (const item of targets) {
69
+ const coordinate = `${item.package}@${item.expectedVersion}`;
70
+ const target = path.join(root.stdout.trim(), ...item.package.split('/'));
71
+ const result = runner(npm, ['install', '--global', coordinate, ...(force ? ['--force'] : [])]);
72
+ if (result.status !== 0) throw new Error(`failed to install ${coordinate}: ${result.stderr || result.error?.message}`);
73
+ if (fs.existsSync(target) && fs.lstatSync(target).isSymbolicLink()) {
74
+ throw new Error(`${coordinate} installation completed but npm link remains at ${target}`);
75
+ }
76
+ const verified = inspect(item.name, manifest.tools[item.name], runner);
77
+ if (verified.status !== 'passed') throw new Error(`${coordinate} installed but CLI version or capabilities failed verification`);
78
+ log(`installed and verified ${coordinate}`);
79
+ }
80
+ return true;
81
+ }
82
+
83
+ if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
84
+ try {
85
+ const [action = 'check', ...args] = process.argv.slice(2);
86
+ if (action === '--help' || action === '-h') {
87
+ console.log('Usage: node manage-toolchain.mjs check|install [--force]\nChecks exact AppGraph/droid2hmos versions and capabilities; install only changes missing or incompatible packages.');
88
+ } else {
89
+ if (args.some(arg => arg !== '--force') || args.filter(arg => arg === '--force').length > 1 || (action === 'check' && args.length)) {
90
+ throw new Error('usage: node manage-toolchain.mjs check|install [--force]');
91
+ }
92
+ if (!manage({ action, force: args.includes('--force') })) process.exitCode = 1;
93
+ }
94
+ } catch (error) {
95
+ console.error(`manage-toolchain: ${error instanceof Error ? error.message : String(error)}`);
96
+ process.exitCode = 1;
97
+ }
98
+ }
@@ -1,16 +1,16 @@
1
- {
2
- "schemaVersion": 1,
3
- "node": { "minimum": "22.5.0", "maximumExclusive": "25.0.0" },
4
- "tools": {
5
- "appgraph": {
6
- "package": "@harmonyos-arkts/appgraph",
7
- "version": "0.0.10",
8
- "capabilities": { "build-android": ["build", "--help"], "spec-analysis": ["spec-analysis", "--help"] }
9
- },
10
- "droid2hmos": {
11
- "package": "@harmonyos-arkts/droid2hmos",
12
- "version": "0.0.11",
13
- "capabilities": { "analyze-android": ["--help"], "preflight": ["--help"], "status": ["--help"] }
14
- }
15
- }
16
- }
1
+ {
2
+ "schemaVersion": 1,
3
+ "node": { "minimum": "22.5.0", "maximumExclusive": "25.0.0" },
4
+ "tools": {
5
+ "appgraph": {
6
+ "package": "@harmonyos-arkts/appgraph",
7
+ "version": "0.0.11",
8
+ "capabilities": { "build-android": ["build", "--help"], "spec-analysis": ["spec-analysis", "--help"] }
9
+ },
10
+ "droid2hmos": {
11
+ "package": "@harmonyos-arkts/droid2hmos",
12
+ "version": "0.0.12",
13
+ "capabilities": { "analyze-android": ["--help"], "preflight": ["--help"], "status": ["--help"] }
14
+ }
15
+ }
16
+ }