Known Pitfalls
Ordered by severity. Cross-referenced with workflow steps.
注意:下方的代码片段仅为历史参考实现。上游可能大规模重构,Agent 应根据同步后实际的代码架构来判断功能是否正确保留,而非机械匹配代码片段。
Critical — will cause silent breakage
-
packages/opencode/package.json custom dependencies lost (Step 4): upstream does not have
@deveco-codegenie/*packages, so accepting upstream's package.json drops them from bothdependenciesanddevDependencies. Additionally, thebinfield reverts from"deveco"to"opencode". After resolving package.json conflicts, always verify these are present:"bin": { "deveco": "./bin/deveco" }(not"opencode")- In both
devDependenciesanddependencies(inserted in dictionary order):@deveco-codegenie/mcp-bridge,@deveco-codegenie/mcp-bridge-darwin-arm64,@deveco-codegenie/mcp-bridge-darwin-x64,@deveco-codegenie/mcp-bridge-win32-x64
-
Auto-merge overwrites brand identifiers (Step 4, Step 7): git auto-merges
OPENCODE_env var prefixes without conflict, silently overwritingDEVECO_renames. New files from upstream also carryOPENCODE_. Always grep all packages (not just conflicted files) — see Step 7 verification. -
Database filename reverts (Step 4, Step 7):
packages/opencode/src/storage/db.ts— upstream uses"opencode.db"/"opencode-${channel}.db", we use"deveco.db"/"deveco-${channel}.db". Auto-merge may silently revert these. After every sync, verify database filename usesdeveco. -
Managed config directory reverts (Step 4, Step 7):
packages/opencode/src/config/managed.ts— upstream uses"ai.opencode.managed"plist domain,"/Library/Application Support/opencode","/etc/opencode", etc. We usedevecoequivalents. Auto-merge may revert these paths. After every sync, verify managed config paths and plist domain usedeveco. -
.opencode/directory patterns re-introduced (Step 4, Step 7):packages/opencode/src/config/agent.tsandcommand.ts— upstream searches/.opencode/agent/and/.opencode/command/patterns. DevEco Code only uses/.deveco/patterns. When upstream modifies these pattern arrays,/.opencode/entries may reappear via auto-merge. After every sync, verify pattern arrays only contain/.deveco/entries (no/.opencode/). -
Typecheck is mandatory (Step 7): upstream API changes (signatures, imports, renames, module migrations to
packages/core) produce type errors in auto-merged files.bun run typecheckcatches what merge conflict markers don't. -
Upstream renames hide import breakage (Step 3, Step 4): when upstream moves modules (e.g.
util/schema.ts→packages/core/src/), git shows rename but auto-merged referencing files keep old import paths. Checkgit diff --statrename lines. -
workspace dep name resets (Step 4):
packages/web/package.jsonreverts to"opencode": "workspace:*"on every sync. Always verify. -
Agent tool permission overwrites (Step 3, Step 4):
packages/opencode/src/agent/agent.ts— DevEco Code customizes permissions for two agents. When upstream restructures the permission format, naive conflict resolution drops these rules. Accept upstream's new permission structure, but always re-add all custom permissions:- build agent:
plan_enter: "ask",plan_write: "deny"(upstream defaults:"allow"/ absent) - plan agent:
plan_exit: "ask",plan_write: "allow",edit: "deny", plus 9 HarmonyOS tool deny rules (bash,build_project,check_ets_files,perform_ui_action,get_app_ui_tree,start_app,hdc_log,switch_cwd,arkts_knowledge_search)
- build agent:
-
HarmonyOS custom tool registrations dropped (Step 3, Step 4, Step 7):
packages/opencode/src/tool/registry.ts— upstream does not have HarmonyOS tools, so when upstream restructures the registry (renames tools, changes the import/init/builtin pattern, adds new Layer dependencies), the custom tool registrations are silently dropped even without conflict markers. After every sync, verify the following functional requirements are met (adapt to current architecture):- Imports:
HdcLogToolfrom"./hdc_log",SwitchCwdToolfrom"./switch-cwd",OhKnowledgeToolfrom"./oh_knowledge",Authfrom"@/auth",PlanWriteToolandPlanEnterToolfrom"./plan"(alongside existingPlanExitTool) - Layer dependency:
Auth.Servicein theLayer.Layertype union - Initialization:
yield* HdcLogTool,yield* SwitchCwdTool,yield* OhKnowledgeTool,yield* PlanWriteTool,yield* PlanEnterTool,yield* Auth.Service - Tool.init():
hdclog,switchcwd,ohknowledge,planwrite,planenterin theEffect.allblock - ohknowledge OAuth 门控: ohknowledge 工具仅在用户通过 deveco OAuth 认证时注册到 Builtin 列表。参考实现:
Builtin 列表中使用const authInfo = yield* auth.get("deveco").pipe(Effect.orElseSucceed(() => undefined)) const ohknowledgeEnabled = authInfo !== undefined && authInfo.type === "oauth"...(ohknowledgeEnabled ? [tool.ohknowledge] : [])条件展开(参考提交fee1ab5e) - Builtin list:
tool.hdclog,tool.switchcwd, and...(ohknowledgeEnabled ? [tool.ohknowledge] : [])(with// HarmonyOS toolscomment);tool.planwrite,tool.planenteralongsidetool.plangated byflags.client === "cli"only (NOTexperimentalPlanMode— Plan mode is a core DevEco Code feature, not experimental) - defaultLayer:
Layer.provide(Auth.defaultLayer)in the provider chain
- Imports:
-
Plan tools gating condition overwritten (Step 3, Step 4, Step 7): upstream v1.15.0 added
experimentalPlanModeto the Plan tools builtin condition. DevEco Code does not require this flag — Plan mode is a shipped feature. After every sync, verify plan tools are gated only by client type, without experimentalPlanMode.- Correct:
...(flags.client === "cli" ? [tool.plan, tool.planwrite, tool.planenter] : []) - Wrong:
...(flags.experimentalPlanMode && flags.client === "cli" ? [tool.plan, tool.planwrite, tool.planenter] : [])
- Correct:
-
postinstall.mjs branding and copyVendor dropped (Step 3, Step 4, Step 7):
packages/opencode/script/postinstall.mjs— upstream does not have DevEco Code branding or vendor directory support. When upstream modifies this file, git auto-merges or creates conflicts that revert:- Package name base:
@deveco/deveco-code-${platform}-${arch}(notopencode-${platform}-${arch}) - Binary names:
deveco/deveco.exe(notopencode/opencode.exe) copyVendor()function and its invocation — copiesvendor/directory from platform-specific packages (e.g. HarmonyOS native tools) to the install location. This function and both call sites (direct resolve path and npm temp install path) are DevEco Code only.resolvePackageDir()helper (extracted forcopyVendoruse) After every sync, verify all three: brand identifiers, copyVendor function + both call sites.
- Package name base:
-
Default skills extraction call dropped (Step 3, Step 4, Step 7):
packages/opencode/src/skill/index.ts— upstream does not havedefaults.ts(DevEco Code only), so when upstream refactors thediscoverSkillsfunction signature or body (e.g. Flag→RuntimeFlags migration), merging adopts upstream's function body and silently drops theDefaults.ensure()call. This has happened twice (v1.14.48→v1.14.49, v1.15.0→v1.15.1). After every sync, verify:defaults.tsfile exists withDEVECO_DEFAULT_SKILLSdeclareindex.tsimports:import { Defaults } from "./defaults"andimport { InstallationVersion } from "@opencode-ai/core/installation/version"discoverSkillsfunction body starts with:const defaultDir = yield* Defaults.ensure(InstallationVersion, fsys).pipe(Effect.orDie) yield* scan(state, defaultDir, SKILL_PATTERN)
-
Claude config defaults reverted to opt-in (Step 3, Step 4, Step 7):
packages/opencode/src/effect/runtime-flags.ts— DevEco Code usesboolTrue(defaulttrue) fordisableClaudeCodePromptanddisableClaudeCodeSkillsto prevent automatically inheriting user's.claude/configuration. Upstream usesbool(defaultfalse). When upstream modifiesruntime-flags.ts, auto-merge silently reverts these back tobool, re-enabling.claude/skills/scanning and Claude prompt injection. After every sync, verifydisableClaudeCodePromptanddisableClaudeCodeSkillsuseboolTrue, notbool. -
customize-opencode built-in skill re-introduced (Step 3, Step 4):
packages/opencode/src/skill/index.ts— upstream registers acustomize-opencodebuilt-in skill that teaches the model how to edit opencode.json config. DevEco Code removed this skill entirely (including thecustomize-opencode.mdfile). When upstream modifies the skill registration logic inindex.ts, the built-in skill block may re-appear via auto-merge. After every sync, verify noCUSTOMIZE_OPENCODE_SKILL_*constants or registration block exists in index.ts.
Moderate — causes errors or incorrect behavior
- Import deduplication (Step 4): merging import blocks by concatenation creates duplicate identifiers (
TS2300). Always dedupe. - Graft tag must be previous, not target (Step 2): using the target tag makes git report "Already up to date".
- macOS sed unreliable: use
perl -pi -e 's/OLD/NEW/g' filefor batch replacements. - Parenthesis matching (Step 4): replacing function calls (e.g.
Effect.promise→EffectBridge.fromPromise) may retain old closing parens. Check surrounding code.
Advisory — improves quality
- Upstream may have better implementation (Step 4): when local custom code conflicts with upstream's new version of the same feature, check if upstream covers the use case before mechanically keeping local.
- Rebase to cloud branch: after rebasing sync commits onto cloud-side develop, compare all cloud-side merge commit changes against current code —
--theirsmay overwrite custom dependencies (mcp-bridge etc). - Not all
opencodestrings should be renamed (Step 4):opencodeappears as provider IDs, external API headers (X-Title,X-Source), test fixtures, and npm bin names — these are functional identifiers, not brand strings. Only rename user-facing strings and env var prefixes. See Brand Identifier Mapping table for exact scope. - Not all
OPENCODE_env vars should be replaced (Step 4, Step 7):OPENCODE_prefixes ininfra/enterprise.ts(SST deployment config keys likeOPENCODE_STORAGE_ADAPTER) andsdks/vscode/src/extension.ts(external API identifiers like_EXTENSION_OPENCODE_PORT,OPENCODE_CALLER) are functional identifiers shared with external systems — do NOT rename them. - TUI tips branding (Step 4, Step 7):
packages/opencode/src/cli/cmd/tui/feature-plugins/home/tips-view.tsx— theTIPSarray contains user-facingopencodeCLI command references andOpenCodestrings. After each sync, replace user-visibleopencode <command>→deveco <command>andOpenCode→DevEco Code. Do NOT rename:opencode.aiURLs,/opencode/ocGitHub bot commands,ghcr.io/anomalyco/opencodeDocker image, import paths, or command IDs (e.g.opencode.status). - Auto-upgrade is npm-registry-only (Step 3, Step 4): DevEco Code only distributes via npm registry (
npm/pnpm/bun). Upstream'spackages/opencode/src/installation/index.tsalso supportsbrew/choco/scoop/curl/yarn, but these are irrelevant to our distribution. Upstream changes to non-npm installation paths can be accepted as-is — they have no effect on DevEco Code auto-upgrade. The CLIdeveco upgrade --methodalready limits choices to["npm", "pnpm", "bun"](packages/opencode/src/cli/cmd/upgrade.ts:20).