@harmonyos-arkts/d2h 0.1.27 → 0.1.29
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/plugin.json +1 -1
- package/AGENTS.md +2 -0
- package/README.md +43 -3
- package/agents/d2h.md +16 -14
- package/dist/bin/install-opencode.js +28 -23
- package/dist/src/install-codex.js +5 -126
- package/dist/src/install-skills.js +147 -0
- package/dist/src/install-vscode.js +2 -2
- package/dist/src/select-agent.js +207 -0
- package/docs/environment-check.md +3 -3
- package/package.json +6 -6
- package/skills/arkts-mvvm-architecture/SKILL.md +2 -0
- package/skills/d2h-architecture-plan/SKILL.md +19 -26
- package/skills/d2h-architecture-plan/references/architecture-plan.example.json +80 -315
- package/skills/d2h-architecture-plan/references/directory-creation.md +27 -34
- package/skills/d2h-architecture-plan/references/hybrid-design.md +13 -15
- package/skills/d2h-architecture-plan/references/json-contract.md +29 -91
- package/skills/d2h-architecture-plan/references/layout-reference.md +30 -27
- package/skills/d2h-architecture-plan/references/plan-contract.md +27 -34
- package/skills/d2h-architecture-plan/references/source-review.md +1 -1
- package/skills/d2h-architecture-plan/scripts/architecture_plan.py +29 -163
- package/skills/d2h-architecture-plan/scripts/test_architecture_plan.py +205 -342
- package/skills/d2h-spec-develop/SKILL.md +5 -4
- package/{install-opencode.sh → tooling/install-opencode.sh} +3 -3
- package/{opencode → tooling/opencode}/interactive-tools/advance-progress-demo.mjs +1 -1
- package/{opencode → tooling/opencode}/interactive-tools/demo.mjs +3 -3
- package/{opencode → tooling/opencode}/interactive-tools/prepare-demo.mjs +1 -1
- package/{scripts → tooling/scripts}/check-environment.mjs +3 -3
- package/skills/d2h-architecture-plan/references/selection-flow.md +0 -71
- /package/{opencode → tooling/opencode}/agents.json +0 -0
- /package/{opencode → tooling/opencode}/interactive-tools/browser-host.ts +0 -0
- /package/{opencode → tooling/opencode}/interactive-tools/core.ts +0 -0
- /package/{opencode → tooling/opencode}/interactive-tools/demo-workflow.ts +0 -0
- /package/{opencode → tooling/opencode}/interactive-tools/package-lock.json +0 -0
- /package/{opencode → tooling/opencode}/interactive-tools/package.json +0 -0
- /package/{opencode → tooling/opencode}/interactive-tools/panel.ts +0 -0
- /package/{opencode → tooling/opencode}/interactive-tools/prepare-progress-demo.mjs +0 -0
- /package/{opencode → tooling/opencode}/interactive-tools/progress.ts +0 -0
- /package/{opencode → tooling/opencode}/interactive-tools/server-legacy.mjs +0 -0
- /package/{opencode → tooling/opencode}/interactive-tools/server.mjs +0 -0
- /package/{opencode → tooling/opencode}/interactive-tools/tui.tsx +0 -0
- /package/{opencode → tooling/opencode}/vscode-d2h-package.json +0 -0
- /package/{opencode → tooling/opencode}/vscode-d2h-plugin.mjs +0 -0
|
@@ -7,10 +7,10 @@ usage() {
|
|
|
7
7
|
Install this repository's skills and agents into the user-level OpenCode config.
|
|
8
8
|
|
|
9
9
|
Usage:
|
|
10
|
-
sh install-opencode.sh [options]
|
|
10
|
+
sh tooling/install-opencode.sh [options]
|
|
11
11
|
|
|
12
12
|
Options:
|
|
13
|
-
--source-dir <path> Repository root. Defaults to the
|
|
13
|
+
--source-dir <path> Repository root. Defaults to the repository root.
|
|
14
14
|
--config-dir <path> OpenCode config root. Defaults to
|
|
15
15
|
$OPENCODE_CONFIG_DIR, or
|
|
16
16
|
${XDG_CONFIG_HOME:-$HOME/.config}/opencode.
|
|
@@ -30,7 +30,7 @@ fail() {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
script_dir=$(CDPATH= cd "$(dirname "$0")" && pwd -P)
|
|
33
|
-
source_dir=$script_dir
|
|
33
|
+
source_dir=$(CDPATH= cd "$script_dir/.." && pwd -P)
|
|
34
34
|
config_dir=${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-${HOME}/.config}/opencode}
|
|
35
35
|
install_mode=copy
|
|
36
36
|
force_install=0
|
|
@@ -2,7 +2,7 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
4
|
import { execFileSync } from 'node:child_process';
|
|
5
|
-
import { workflowAsset } from '
|
|
5
|
+
import { workflowAsset } from '../../../dist/opencode/interactive-tools/progress.js';
|
|
6
6
|
|
|
7
7
|
if (!process.argv[2]) { throw new Error('需要指定演示项目路径'); }
|
|
8
8
|
const project = fs.realpathSync(process.argv[2]);
|
|
@@ -3,9 +3,9 @@ import fs from 'node:fs';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
import { randomBytes } from 'node:crypto';
|
|
6
|
-
import { listInteractions, interactionStatus, submitDecision } from '
|
|
7
|
-
import { interactionHtml } from '
|
|
8
|
-
import { runDemo } from '
|
|
6
|
+
import { listInteractions, interactionStatus, submitDecision } from '../../../dist/opencode/interactive-tools/core.js';
|
|
7
|
+
import { interactionHtml } from '../../../dist/opencode/interactive-tools/panel.js';
|
|
8
|
+
import { runDemo } from '../../../dist/opencode/interactive-tools/demo-workflow.js';
|
|
9
9
|
|
|
10
10
|
const root = path.dirname(fileURLToPath(import.meta.url));
|
|
11
11
|
const project = path.resolve(process.argv[2] || path.join(root, '../../../validation/interactive-tools-mvp', `browser-${Date.now()}`));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
4
|
-
import { demoWorkflow } from '
|
|
4
|
+
import { demoWorkflow } from '../../../dist/opencode/interactive-tools/demo-workflow.js';
|
|
5
5
|
|
|
6
6
|
const root = path.dirname(fileURLToPath(import.meta.url));
|
|
7
7
|
const project = path.resolve(process.argv[2] || path.join(root, '../../../validation/interactive-tools-mvp', `opencode-${Date.now()}`));
|
|
@@ -6,7 +6,7 @@ import { spawn, spawnSync } from 'node:child_process';
|
|
|
6
6
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
7
7
|
import { parseArgs } from 'node:util';
|
|
8
8
|
|
|
9
|
-
const DEFAULT_REQUIREMENTS = fileURLToPath(new URL('
|
|
9
|
+
const DEFAULT_REQUIREMENTS = fileURLToPath(new URL('../../skills/managing-d2h-toolchain/environment-requirements.json', import.meta.url));
|
|
10
10
|
const VERSION_TOOLS = ['node', 'python', 'git', 'npm', 'java', 'python-json5', 'appgraph', 'droid2hmos', 'hvigor', 'ohpm', 'devecocli'];
|
|
11
11
|
const CATEGORY_LABELS = {
|
|
12
12
|
runtime: '运行环境',
|
|
@@ -354,7 +354,7 @@ export function parseOptions(argv) {
|
|
|
354
354
|
timeout: { type: 'string', default: '15' }, 'output-dir': { type: 'string' }, help: { type: 'boolean', short: 'h' },
|
|
355
355
|
} });
|
|
356
356
|
if (!/^\d+$/.test(values.timeout) || Number(values.timeout) < 1 || Number(values.timeout) > 60) throw new Error('--timeout 必须为 1–60 的整数');
|
|
357
|
-
return { pluginRoot: values['plugin-root'] || fileURLToPath(new URL('
|
|
357
|
+
return { pluginRoot: values['plugin-root'] || fileURLToPath(new URL('../../', import.meta.url)),
|
|
358
358
|
requirementsFile: values.requirements ? path.resolve(values.requirements) : DEFAULT_REQUIREMENTS,
|
|
359
359
|
androidProject: values['android-project'], sdkPath: values['sdk-path'],
|
|
360
360
|
harmonyProject: values['harmony-project'],
|
|
@@ -366,7 +366,7 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
366
366
|
let options;
|
|
367
367
|
try { options = parseOptions(argv); } catch (error) { console.error(error.message); return 2; }
|
|
368
368
|
if (options.help) {
|
|
369
|
-
console.log('用法:node scripts/check-environment.mjs [--plugin-root <path>] [--android-project <path>]\n [--harmony-project <path>] [--sdk-path <path>] [--requirements <json>]\n [--timeout <1–60 秒>] [--output-dir <path>]\n默认版本约束来自 skills/managing-d2h-toolchain/environment-requirements.json。只写报告,不自动安装依赖或修改配置。');
|
|
369
|
+
console.log('用法:node tooling/scripts/check-environment.mjs [--plugin-root <path>] [--android-project <path>]\n [--harmony-project <path>] [--sdk-path <path>] [--requirements <json>]\n [--timeout <1–60 秒>] [--output-dir <path>]\n默认版本约束来自 skills/managing-d2h-toolchain/environment-requirements.json。只写报告,不自动安装依赖或修改配置。');
|
|
370
370
|
return 0;
|
|
371
371
|
}
|
|
372
372
|
const report = await collect(options);
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# 统一选型:看板与 question 使用同一份确认结果
|
|
2
|
-
|
|
3
|
-
需要用户选择方案、接收选择或恢复目录实施时读取。JSON 字段见 [json-contract.md](json-contract.md)。
|
|
4
|
-
|
|
5
|
-
## 1. 展示当前规划,明确确认后的动作
|
|
6
|
-
|
|
7
|
-
先生成并校验 `architecture-plan.json`,展示三套方案、推荐及当前选择。只要求分析/查看 JSON 时交付即可,不强制发起选型。
|
|
8
|
-
|
|
9
|
-
完整迁移或用户要求创建时,选择界面明确说明“请选择目录方案,确定后将创建或复用基础工程并补齐目录”。此场景的一次“确定”就是 `select-and-create`,不再追加“是否继续”。用户只要求记录选型时才使用 `select`;选择本身不能扩大用户已约定的创建范围。
|
|
10
|
-
|
|
11
|
-
风险只是展示信息,不是必须作答的内容。
|
|
12
|
-
|
|
13
|
-
## 2. 两个入口,一次有效确认
|
|
14
|
-
|
|
15
|
-
| 入口 | 行为 | 确认记录中的 `source` |
|
|
16
|
-
|---|---|---|
|
|
17
|
-
| 看板 | 用户单选一套方案并点击“确定”,看板将实际提交交给 Agent | `dashboard` |
|
|
18
|
-
| OpenCode `question` | 不使用看板时,Agent 用 `question` 展示同样的三个方案供单选,收到实际回答后将选项映射为方案 ID | `question` |
|
|
19
|
-
| 已有明确对话指令 | 用户已明确“选择某方案”或“采用推荐并创建”,按真实指令记录,不再重复提问 | `conversation` |
|
|
20
|
-
|
|
21
|
-
同一个待选问题只启用一个交互入口。已在看板确认,不再调用 `question`;已收到 question 回答,不要求用户再到看板确认。当前看板交互不可用或用户选择不用看板时,用 question 接续;若环境没有 question 工具,可用明确的对话回答接续并如实记录来源。不能假装已调用工具。
|
|
22
|
-
|
|
23
|
-
question 选项一一对应 `android-mirror`、`harmony-practice`、`hybrid`,名称、说明和推荐标识取自当前 JSON。提示中说明这次是“确认并创建”还是“只选型”。只接受实际回答:未选择、取消、关闭界面或超时都不写选择,不能把默认选项、模型推荐当用户答案。
|
|
24
|
-
|
|
25
|
-
若用户自由输入修改意见且没有确认当前方案,先通过对话修订 JSON 并重新展示;不把修改要求强行解释为选中了某套旧目录。
|
|
26
|
-
|
|
27
|
-
## 3. 先持久化,再交接下一步
|
|
28
|
-
|
|
29
|
-
两个入口都形成同一结构的提交对象,先写入独立的临时请求文件。question 的工具返回不能只留在上下文中,看板只提供消息时也由 Agent 写入请求文件。`architecture-selection.json` 是脚本维护的已校验确认记录,不是原始请求入口;看板和文件工具不得先覆盖它。字段示例见 JSON 契约。
|
|
30
|
-
|
|
31
|
-
实际处理顺序:
|
|
32
|
-
|
|
33
|
-
1. 根据实际操作/回答确定 `planId`、方案 ID、`action`、`source`,为本次提交生成 `requestId`,真实意见写入 `notes`。不生成虚假的用户确认。
|
|
34
|
-
2. 检查 `notes`:若要求改变目录,先处理修改,不按旧树创建。否则以独立请求文件运行 `apply-selection`;它对照最近确认检查请求,校验通过后才保存到固定确认文件,并更新规划的 `selectedProposalId`。无效请求不覆盖已有确认。
|
|
35
|
-
3. 确认记录先保存,规划选择后更新;任一写入失败都不得进入目录实施。两份文件不是一次事务,恢复时须核对一致性。已确认记录写入而规划尚未更新时,可在核对原授权和当前目录未变后重新应用该记录,不重复问用户。
|
|
36
|
-
4. 同步 Markdown 的实际选型;后续创建流程只读取持久化 JSON,不依赖 question 返回值、聊天记忆或看板当前高亮。
|
|
37
|
-
|
|
38
|
-
```text
|
|
39
|
-
python <本Skill目录>/scripts/architecture_plan.py apply-selection <产物目录>/architecture-plan.json <独立的请求JSON文件>
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
脚本始终把有效确认保存到 `<产物目录>/architecture-selection.json`;请求文件只是传输输入,成功后可由其创建方清理。调用方须串行处理,并保持请求 ID 的内容不变,不重放已被新提交替代的请求。脚本只比对最近确认及当前方案身份,不判断历史目录差异,因此目录修改后必须清理确认并取消旧提交。
|
|
43
|
-
|
|
44
|
-
若确认已写入、规划更新中断,核对原授权与目录未变后,使用显式恢复入口重放脚本保存的确认:
|
|
45
|
-
|
|
46
|
-
```text
|
|
47
|
-
python <本Skill目录>/scripts/architecture_plan.py apply-selection <产物目录>/architecture-plan.json <产物目录>/architecture-selection.json --recover
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
`--recover` 只接受固定确认文件;它不用于接收新提交,也不把损坏或缺失的确认恢复为模型推荐。
|
|
51
|
-
|
|
52
|
-
## 4. 目录实施入口必须重新读取
|
|
53
|
-
|
|
54
|
-
进入目录实施时(包括恢复会话),从磁盘重新读取 `architecture-plan.json` 与 `architecture-selection.json`:
|
|
55
|
-
|
|
56
|
-
```text
|
|
57
|
-
python <本Skill目录>/scripts/architecture_plan.py read-selection <产物目录>/architecture-plan.json
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
- 规划的 `selectedProposalId` 必须非空,确认文件的 `planId`、方案 ID 必须与规划一致,且该方案确实存在。缺少记录、无效记录或不一致时不创建,不根据推荐推断用户选择。
|
|
61
|
-
- 读取摘要中的 `notes` 并核对是否还有未处理的目录修改;有则回到对话修订,不能仅凭下一动作字段执行旧树。脚本不判断自然语言意见是否改变布局。
|
|
62
|
-
- `nextAction: selection-recorded` 只表示已选型;`nextAction: create-directory-shell` 才进入 [directory-creation.md](directory-creation.md),并从 `proposals` 中取该 ID 的 `directoryTree` 实施。无需再询问确认。
|
|
63
|
-
- 重新核对实际目标根与原授权范围,读取现有 receipt 和真实目录;已完成的请求复核返回,部分完成只继续未完成项,不重复初始化、搬迁或覆盖。
|
|
64
|
-
|
|
65
|
-
`read-selection` 返回确认摘要、原始意见和下一动作;目录树仍从规划 JSON 中按选定 ID 读取。两个入口共用这一实施入口。
|
|
66
|
-
|
|
67
|
-
## 5. 后续修改与外部接入边界
|
|
68
|
-
|
|
69
|
-
仅调整项目说明、分析或风险文本时保留有效确认。影响目录、目标位置或授权范围时,先移除当前 `architecture-selection.json` 并清空 `selectedProposalId`,再更新规划、刷新展示并取消未处理的旧提交。历史授权和实际落地记录按 Markdown/receipt 保留;不能让旧确认用于新目录。
|
|
70
|
-
|
|
71
|
-
本 Skill 不提供看板 HTTP 端点或监听服务。看板适配方负责实际用户提交、文件/消息交付及通知当前或恢复会话;仅写文件不会自动唤醒 Agent。这里规定交互和落盘流程,不宣称已完成外部看板接线。
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|