diff --git a/AGENTS.md b/AGENTS.md index 85666b99..25fe79ad 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,305 +1,98 @@ # PROJECT KNOWLEDGE BASE -**Generated:** 2026-03-28 **Type:** OpenClaw DingTalk Channel Plugin -## OVERVIEW +## Overview -DingTalk (钉钉) enterprise bot channel plugin using Stream mode (WebSocket, no public IP required). Part of OpenClaw ecosystem. +DingTalk (钉钉) enterprise bot channel plugin for OpenClaw using Stream mode (WebSocket, no public IP required). Published as `@soimy/dingtalk` on npm. The plugin runs directly via the OpenClaw runtime — there is no build step. -Current architecture is modularized by responsibility. `src/channel.ts` is now an assembly layer; heavy logic is split into dedicated modules. -Recent refactors unified short-lived message persistence into `src/message-context-store.ts` and split reply delivery selection into dedicated `reply-strategy*` modules. -Recent targeting work added a learned target directory under `src/targeting/` and a `displayNameResolution` config gate (`disabled` by default, `all` to enable learned displayName resolution). +Current architecture is modularized by responsibility. `src/channel.ts` is an assembly layer, heavy logic is split into dedicated modules, and the contributor architecture guides are the source of truth for module boundaries and incremental migration rules. -For new code and refactors, the canonical architecture guide is `docs/contributor/architecture.en.md`. -Chinese version: `docs/contributor/architecture.zh-CN.md`. -Use those documents as the source of truth for logical domain placement, incremental migration rules, and module boundaries. -For AI-agent generated design and execution docs, write specs to `docs/spec/` and plans to `docs/plans/`. Do not create tool-specific doc roots such as `docs/superpowers/`. -Documentation updates must follow the repo docs structure: keep `README.md` as a concise project entry page, put user-facing details in `docs/user/`, contributor/process docs in `docs/contributor/`, and release notes in `docs/releases/`. Do not expand README with long-form feature/config/troubleshooting content that belongs in `docs/`. -This repository is licensed under MIT. If you reuse code, retain the copyright and license notice required by MIT. -If you substantially reuse this repository's documentation, prompts, AGENTS/CLAUDE conventions, architecture writeups, or agent-oriented implementation playbooks, please provide attribution to `OpenClaw DingTalk Channel Plugin`, `YM Shen and contributors`, and `https://github.com/soimy/openclaw-channel-dingtalk`. -See `docs/contributor/citation-and-attribution.md` and `CITATION.cff` for the preferred citation and attribution format. This request describes the project's preferred community norm and does not replace or modify the LICENSE file. -Issue convention for this repo: prefer the GitHub issue templates under `.github/ISSUE_TEMPLATE/`; keep issue communication primarily in Simplified Chinese; use `问题反馈` for bugs and `功能建议` for feature ideas; and encourage reporters to include background, reproduction or goals, environment, and desensitized evidence. -Pull request convention for this repo: use an English Conventional-style PR title such as `fix(targeting): normalize learned display names`; keep the title in English; write the PR description in Simplified Chinese; and include clearly labeled `背景`, `目标`, `实现`, `实现 TODO`, and `验证 TODO` sections. -Planned domain summary: -- `gateway/`: stream connection lifecycle, callback registration, inbound entry points -- `targeting/`: peer identity, session aliasing, target resolution, and learned displayName directory -- `messaging/`: inbound extraction, reply strategies, outbound delivery, message context -- `card/`: AI card lifecycle, recovery, and caches -- `command/`: slash commands and related extensions including feedback learning -- `platform/`: config, auth, runtime, logger, and core types -- `shared/`: reusable persistence primitives, dedup, and generic helpers - -## STRUCTURE - -``` -./ -├── index.ts # Plugin registration entry point -├── src/ -│ ├── channel.ts # Channel definition + gateway wiring + public exports -│ ├── inbound-handler.ts # Inbound pipeline (authz, routing, quote/media restore, dispatch orchestration) -│ ├── send-service.ts # Outbound send (session/proactive/text/media/card fallback) -│ ├── card-service.ts # AI Card lifecycle + cache + recovery helpers -│ ├── card-callback-service.ts # Card callback handling and action processing -│ ├── card-draft-controller.ts # Card draft buffering / state transitions -│ ├── reply-strategy.ts # Reply strategy selection entry -│ ├── reply-strategy-card.ts # AI Card reply strategy -│ ├── reply-strategy-markdown.ts # Markdown/text reply strategy -│ ├── reply-strategy-with-reaction.ts # Reply wrapper for reaction lifecycle -│ ├── auth.ts # Access token cache + retry -│ ├── config.ts # Config/account/agent helpers -│ ├── config-schema.ts # Zod validation schema -│ ├── runtime.ts # Runtime getter/setter -│ ├── types.ts # Shared types/constants -│ ├── access-control.ts # DM/group allowlist checks -│ ├── message-utils.ts # Markdown/title detection + inbound content extraction -│ ├── message-context-store.ts # Unified short-TTL message context persistence -│ ├── media-utils.ts # Media type detect + upload/download helpers -│ ├── quoted-file-service.ts # Quote/file recovery helpers -│ ├── docs-service.ts # DingTalk docs gateway methods -│ ├── feedback-learning-service.ts # Learning signal handling -│ ├── feedback-learning-store.ts # Learning persistence -│ ├── learning-command-service.ts # /learn command handling -│ ├── session-command-service.ts # Session alias and related commands -│ ├── connection-manager.ts # Robust stream connection lifecycle -│ ├── dedup.ts # Inbound message dedup with TTL + lazy cleanup -│ ├── persistence-store.ts # Namespace-based persistence primitives -│ ├── session-routing.ts # Agent/session routing helpers -│ ├── session-peer-store.ts # Session peer persistence -│ ├── session-lock.ts # Per-session dispatch locking -│ ├── peer-id-registry.ts # Preserve case-sensitive conversationId mapping -│ ├── proactive-risk-registry.ts # Proactive send risk tracking -│ ├── logger-context.ts # Shared logger getter/setter -│ ├── onboarding.ts # Channel onboarding adapter -│ ├── ack-reaction/ -│ │ ├── dynamic-ack-reaction-controller.ts # Tool-progress reaction orchestration -│ │ ├── dynamic-ack-reaction-events.ts # Reaction event definitions -│ │ └── dynamic-ack-reaction-progress.ts # Reaction progress mapping -│ ├── messaging/ -│ │ ├── attachment-text-extractor.ts # Text extraction for supported attachments -│ │ ├── quoted-file-service.ts # Quote/file recovery helpers -│ │ ├── quoted-context.ts # Quoted context assembly -│ │ └── quoted-ref.ts # Structured quotedRef helpers -│ └── targeting/ -│ ├── agent-name-matcher.ts # @agent name matching -│ ├── agent-routing.ts # Sub-agent routing helpers -│ ├── group-members-store.ts # Group member cache/persistence -│ ├── target-directory-adapter.ts # Learned directory bridge + displayNameResolution gate -│ ├── target-directory-store.ts # Learned group/user target persistence -│ └── target-input.ts # DingTalk target normalization + id heuristics -├── docs/ -│ ├── index.md # Docs home -│ ├── .vitepress/ # VitePress site config and build output root -│ ├── user/ # User-facing install/config/features/troubleshooting docs -│ ├── contributor/ # Contributor/dev/test/release/architecture docs -│ ├── releases/ # Release notes index + version pages -│ ├── en/ # Partial English entry pages -│ ├── spec/ # AI-authored design/spec docs (not published) -│ ├── plans/ # AI-authored implementation plans (not published) -│ ├── archive/ # Archived/non-nav docs -│ └── assets/ # Non-published doc assets -├── scripts/ -│ ├── dingtalk-connection-check.* # Connection diagnostics for Stream setup -│ ├── dingtalk-stream-monitor.mjs # Stream monitoring helper -│ └── feedback-learning-debug.mjs # Local feedback-learning inspection UI -├── tests/ -│ ├── unit/ # Unit tests -│ └── integration/ # Integration tests with mocked external calls -├── .github/ -│ └── workflows/ # CI, npm publish, docs pages deploy -└── [config files] # package.json, tsconfig.json, vitest.config.ts, lint/format configs -``` - -## WHERE TO LOOK - -| Task | Location | Notes | -| --- | --- | --- | -| Plugin registration | `index.ts` | Exports default plugin object | -| Channel assembly | `src/channel.ts` | Defines `dingtalkPlugin`; wires gateway/outbound/status | -| Inbound message handling | `src/inbound-handler.ts` | `handleDingTalkMessage`, `downloadMedia` | -| Text/media sending | `src/send-service.ts` | `sendBySession`, `sendProactive*`, `sendMessage` | -| Reply strategy selection | `src/reply-strategy.ts` | `createReplyStrategy` | -| AI Card operations | `src/card-service.ts` | `createAICard`, `streamAICard`, `finishAICard` | -| Message context persistence | `src/message-context-store.ts` | `upsertInboundMessageContext`, `upsertOutboundMessageContext`, `resolveByMsgId`, `resolveByAlias` | -| Token management | `src/auth.ts` | `getAccessToken` with clientId-scoped cache | -| Access control | `src/access-control.ts` | DM/group allowlist helpers | -| Message parsing | `src/message-utils.ts` | quote parsing + richText/media extraction | -| Config/path helpers | `src/config.ts` | `getConfig`, `resolveRelativePath`, `stripTargetPrefix` | -| Target directory persistence | `src/targeting/target-directory-store.ts` | learned group/user displayName directory | -| Target directory adapter | `src/targeting/target-directory-adapter.ts` | directory bridge + `displayNameResolution` gate | -| Deduplication | `src/dedup.ts` | message retry dedup keys | -| Type definitions | `src/types.ts` | DingTalk and plugin types/constants | - -## CODE MAP - -| Symbol | Type | Location | Role | -| --- | --- | --- | --- | -| `dingtalkPlugin` | const | `src/channel.ts` | Main channel plugin definition | -| `handleDingTalkMessage` | function | `src/inbound-handler.ts` | Process inbound messages end-to-end | -| `downloadMedia` | function | `src/inbound-handler.ts` | Download inbound media via runtime media service | -| `sendBySession` | function | `src/send-service.ts` | Send replies via session webhook | -| `sendMessage` | function | `src/send-service.ts` | Auto send (card/text/markdown fallback) | -| `sendProactiveMedia` | function | `src/send-service.ts` | Proactive media send | -| `createReplyStrategy` | function | `src/reply-strategy.ts` | Select reply implementation by mode/capability | -| `createAICard` | function | `src/card-service.ts` | Create and cache AI Card | -| `streamAICard` | function | `src/card-service.ts` | Stream updates to AI Card | -| `finishAICard` | function | `src/card-service.ts` | Finalize AI Card | -| `upsertInboundMessageContext` | function | `src/message-context-store.ts` | Persist inbound message context by canonical msgId | -| `upsertOutboundMessageContext` | function | `src/message-context-store.ts` | Persist outbound message context + delivery aliases | -| `resolveByMsgId` | function | `src/message-context-store.ts` | Resolve unified message record by canonical/inbound msgId | -| `resolveByAlias` | function | `src/message-context-store.ts` | Resolve outbound record by `messageId/processQueryKey/outTrackId/cardInstanceId` | -| `upsertObservedGroupTarget` | function | `src/targeting/target-directory-store.ts` | Persist observed group `conversationId/displayName` | -| `upsertObservedUserTarget` | function | `src/targeting/target-directory-store.ts` | Persist observed user `staffId/senderId/displayName` | -| `listDingTalkDirectoryGroups` | function | `src/targeting/target-directory-adapter.ts` | Expose learned group directory entries | -| `listDingTalkDirectoryUsers` | function | `src/targeting/target-directory-adapter.ts` | Expose learned user directory entries | -| `getAccessToken` | function | `src/auth.ts` | Get/cached DingTalk token | -| `extractMessageContent` | function | `src/message-utils.ts` | Normalize inbound msg payload | -| `normalizeAllowFrom` | function | `src/access-control.ts` | Normalize allowlist entries | -| `isMessageProcessed` | function | `src/dedup.ts` | Message dedup check | -| `DingTalkConfigSchema` | const | `src/config-schema.ts` | Zod validation schema | -| `AICardStatus` | const | `src/types.ts` | AI Card state constants | - -## CONVENTIONS - -**Code Style:** - -- TypeScript strict mode enabled -- ES2020 target, ESNext modules -- 4-space indentation (Prettier) -- Public low-level API exported from `src/channel.ts` (re-exported from service modules) - -**Naming:** - -- Private functions: camelCase -- Exported functions: camelCase -- Type interfaces: PascalCase -- Constants: UPPER_SNAKE_CASE - -**Error Handling:** - -- Use `try/catch` for async API calls -- Log with structured prefixes (e.g. `[DingTalk]`, `[DingTalk][AICard]`, `[DingTalk][Dispatch]`) -- For DingTalk API error payloads, use unified prefix format: - - Standard: `[DingTalk][ErrorPayload][]` - - AI Card: `[DingTalk][AICard][ErrorPayload][]` - - Include `code=<...> message=<...> payload=<...>` for fast diagnosis -- Send APIs return `{ ok: boolean, error?: string }` where applicable -- Retry with exponential backoff for transient HTTP failures (401/429/5xx) - -**State Management:** - -- Access token cache in `src/auth.ts` -- AI Card caches in `src/card-service.ts` (`aiCardInstances`, `activeCardsByTarget`) -- Unified short-TTL message contexts in `src/message-context-store.ts` under namespace `messages.context` -- Learned target directory persistence in `src/targeting/target-directory-store.ts` under namespace `targets.directory` -- Card createdAt fallback keeps an in-memory-only bucket in `src/card-service.ts` when no `storePath` is available -- Message dedup state in `src/dedup.ts` -- Runtime stored via getter/setter in `src/runtime.ts` +Start with `WORKFLOW.md` for the repository workflow summary, then use the contributor docs for detailed guidance. -## ANTI-PATTERNS (THIS PROJECT) +## Start Here -**Prohibited:** +- `WORKFLOW.md` +- `docs/contributor/agent-workflow.md` +- `docs/contributor/architecture.zh-CN.md` +- `docs/contributor/architecture.en.md` +- `docs/contributor/testing.md` +- `docs/contributor/release-process.md` -- Sending messages without token retrieval (`getAccessToken`) -- Creating multiple active AI Cards for same `accountId:conversationId` -- Hardcoding credentials (must read `channels.dingtalk`) -- Suppressing type errors with `@ts-ignore` -- Using `console.log` (use logger) -- Logging raw sensitive token data -- Re-introducing `quote-journal.ts` / `quoted-msg-cache.ts`-style wrapper persistence layers instead of using `message-context-store` directly +## Quick Commands -**Security:** - -- Validate `dmPolicy` / `groupPolicy` before command dispatch -- Respect allowlist (`allowFrom`) in allowlist modes -- Normalize sender IDs (strip `dingtalk:`, `dd:`, `ding:` prefixes) - -## UNIQUE STYLES - -**AI Card Flow:** - -1. Create card and cache with `PROCESSING` -2. Stream updates with full replacement (`isFull=true`) -3. Transition state to `INPUTING` on first stream -4. Finalize with `isFinalize=true` and `FINISHED` -5. Fallback to markdown send when card stream fails - -**Reply Delivery Flow:** - -1. `inbound-handler.ts` builds reply context and selects a strategy via `createReplyStrategy` -2. `reply-strategy-card.ts` owns AI Card creation/stream/finalize decisions -3. `reply-strategy-markdown.ts` handles markdown/text send fallback -4. `reply-strategy-with-reaction.ts` wraps strategy execution with reaction lifecycle when enabled - -**Unified Message Context Flow:** - -1. Inbound messages persist text/media into `messages.context` keyed by canonical `msgId` -2. Outbound messages persist after send succeeds using `messageId > processQueryKey > outTrackId` as canonical fallback -3. Alias lookup supports `messageId`, `processQueryKey`, `outTrackId`, `cardInstanceId`, and inbound `msgId` -4. Quote recovery prefers alias lookup and only uses `createdAt` window as fallback -5. Old persistence wrappers are removed; production code should call `message-context-store` directly +```bash +pnpm install +pnpm run type-check +pnpm run lint +pnpm run lint:fix +pnpm run format +pnpm test +pnpm test:coverage +pnpm run docs:build +``` -**Message Processing Pipeline:** +## Documentation Placement -1. Dedup check by bot-scoped key (`robotKey:msgId`) -2. Filter self-messages -3. Extract text/media content -4. Authorization check (`dmPolicy` / `groupPolicy`) -5. Resolve route + session + workspace -6. Download media into agent workspace if present -7. Persist inbound quote/media context into `messages.context` -8. Dispatch to runtime reply pipeline -9. Deliver via selected reply strategy +- Specs: `docs/spec/` +- Plans: `docs/plans/` +- User-facing docs: `docs/user/` +- Contributor and process docs: `docs/contributor/` +- Release notes: `docs/releases/` -**Media Handling:** +Keep `README.md` as a concise project entry page. Do not expand it with long-form feature, configuration, troubleshooting, or process details that belong under `docs/`. -- Inbound media saved to `/media/inbound` -- Outbound media uploaded then sent by DingTalk media template messages -- Orphaned temp cleanup at gateway startup +## Collaboration Conventions -## COMMANDS +- Prefer the GitHub issue templates under `.github/ISSUE_TEMPLATE/`. +- Keep issue communication primarily in Simplified Chinese. +- Use `问题反馈` for bugs and `功能建议` for feature ideas. +- Use an English Conventional-style pull request title. +- Write the pull request description in Simplified Chinese. +- Include clearly labeled `背景`, `目标`, `实现`, `实现 TODO`, and `验证 TODO` sections in pull requests. -```bash -# Type check -npm run type-check +## High-Priority Repository Rules -# Lint -npm run lint +- Keep `src/channel.ts` thin; do not add new business logic there. +- Use `src/message-context-store.ts` directly for production quote, media, and card context recovery. +- Do not reintroduce legacy wrappers such as `quote-journal.ts` or `quoted-msg-cache.ts`. +- Use `getAccessToken()` before DingTalk API calls. +- Use `getLogger()` instead of `console.log`. +- Never log raw access tokens. +- Do not create multiple active AI Cards for the same `accountId:conversationId`. +- Keep review comments in Simplified Chinese. -# Lint + fix -npm run lint:fix +## Architecture Pointers -# Unit + integration tests -pnpm test +- `index.ts` registers the plugin and sets the DingTalk runtime singleton. +- `src/inbound-handler.ts` owns inbound orchestration. +- `src/send-service.ts` owns outbound delivery. +- `src/card-service.ts` owns AI Card lifecycle and recovery. +- `src/message-context-store.ts` is the only production message context persistence API. +- `src/targeting/` owns learned target directory and target normalization. -# Coverage report (V8) -pnpm test:coverage -``` +## Quick Lookup -**Note:** No build script; plugin runs directly via OpenClaw runtime. +- Assembly and plugin entry: `index.ts`, `src/channel.ts` +- Inbound handling: `src/inbound-handler.ts` +- Outbound delivery: `src/send-service.ts` +- Card lifecycle: `src/card-service.ts` +- Message context persistence: `src/message-context-store.ts` +- Targeting: `src/targeting/` -## NOTES +## Optional Tooling -**OpenClaw Plugin Architecture:** +GitNexus is an optional enhancement for repository understanding, impact analysis, and change-scope review. -- `index.ts` registers `dingtalkPlugin` -- Runtime set once via `setDingTalkRuntime(api.runtime)` -- Multi-account config supported via `channels.dingtalk.accounts` -- `displayNameResolution` defaults to `disabled`; only `all` enables learned group/user displayName resolution -- Message quote/media recovery is unified through `messages.context`; no backward-compatible read path exists for removed legacy namespaces +- If GitNexus is available locally, treat `docs/contributor/gitnexus-optional.md` as the preferred path for repository navigation and impact analysis. +- If GitNexus is unavailable locally, use `docs/contributor/fallback-navigation.md` together with `WORKFLOW.md` and `docs/contributor/agent-workflow.md`. +- Optional tooling must not be the only documented way to complete a required workflow step. +- See `docs/contributor/gitnexus-optional.md` for the enhanced workflow. -**DingTalk API Endpoints Used:** +## Attribution -- Token: `/v1.0/oauth2/accessToken` -- Media download: `/v1.0/robot/messageFiles/download` -- Proactive send: `/v1.0/robot/groupMessages/send`, `/v1.0/robot/oToMessages/batchSend` -- AI Card create+deliver: `/v1.0/card/instances/createAndDeliver` -- AI Card stream: `/v1.0/card/streaming` +This repository is licensed under MIT. If you reuse code, retain the copyright and license notice required by MIT. -**Testing:** +If you substantially reuse this repository's documentation, prompts, AGENTS/CLAUDE conventions, architecture writeups, or agent-oriented implementation playbooks, please provide attribution to `OpenClaw DingTalk Channel Plugin`, `YM Shen and contributors`, and `https://github.com/soimy/openclaw-channel-dingtalk`. -- Vitest test suite is initialized with unit + integration coverage under `tests/` -- Network calls are mocked in tests (`vi.mock`), no real DingTalk API requests are made -- CI should run `pnpm test` on every push and pull request -- Coverage can be generated with `pnpm test:coverage` -- When the task involves DingTalk real-device validation, PR-scoped test checklists, `验证 TODO` drafting, or contributor-workflow updates for that process, read and follow `skills/dingtalk-real-device-testing/SKILL.md` first. +See `docs/contributor/citation-and-attribution.md` and `CITATION.cff` for the preferred citation and attribution format. This request describes the project's preferred community norm and does not replace or modify the LICENSE file. diff --git a/CLAUDE.md b/CLAUDE.md index 00425c71..07f2749a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,112 +1,104 @@ # CLAUDE.md -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. +This file provides guidance to Claude Code when working with code in this repository. It intentionally stays closely aligned with `AGENTS.md`, which remains the general project-level agent entrypoint for this public repository. -## Project Overview +## Overview -DingTalk (钉钉) enterprise bot channel plugin for OpenClaw. Uses Stream mode (WebSocket, no public IP required). Published as `@soimy/dingtalk` on npm. The plugin runs directly via the OpenClaw runtime — there is no build step. +DingTalk (钉钉) enterprise bot channel plugin for OpenClaw using Stream mode (WebSocket, no public IP required). Published as `@soimy/dingtalk` on npm. The plugin runs directly via the OpenClaw runtime — there is no build step. -This repository is licensed under MIT. If you reuse code, retain the copyright and license notice required by MIT. -If you substantially reuse this repository's documentation, prompts, AGENTS/CLAUDE conventions, architecture writeups, or agent-oriented implementation playbooks, please provide attribution to `OpenClaw DingTalk Channel Plugin`, `YM Shen and contributors`, and `https://github.com/soimy/openclaw-channel-dingtalk`. -See `docs/contributor/citation-and-attribution.md` and `CITATION.cff` for the preferred citation and attribution format. This request describes the project's preferred community norm and does not replace or modify the LICENSE file. +Current architecture is modularized by responsibility. `src/channel.ts` is an assembly layer, heavy logic is split into dedicated modules, and the contributor architecture guides are the source of truth for module boundaries and incremental migration rules. + +Start with `WORKFLOW.md` for the repository workflow summary, then use the contributor docs for detailed guidance. + +## Start Here -## Commands +- `WORKFLOW.md` +- `docs/contributor/agent-workflow.md` +- `docs/contributor/architecture.zh-CN.md` +- `docs/contributor/architecture.en.md` +- `docs/contributor/testing.md` +- `docs/contributor/release-process.md` + +## Quick Commands ```bash -# Install dependencies pnpm install - -# Type-check (strict TypeScript) pnpm run type-check - -# Lint (oxlint with type-aware rules) pnpm run lint - -# Lint + auto-fix + format pnpm run lint:fix - -# Format only (oxfmt) pnpm run format - -# Run all tests pnpm test +pnpm test:coverage +pnpm run docs:build +``` -# Run a single test file -pnpm vitest run tests/unit/config.test.ts +## Documentation Placement -# Run tests matching a pattern -pnpm vitest run -t "pattern" +- Specs: `docs/spec/` +- Plans: `docs/plans/` +- User-facing docs: `docs/user/` +- Contributor and process docs: `docs/contributor/` +- Release notes: `docs/releases/` -# Coverage report -pnpm test:coverage +Keep `README.md` as a concise project entry page. Do not expand it with long-form feature, configuration, troubleshooting, or process details that belong under `docs/`. -# Stream connection monitor (debugging) -pnpm run monitor:stream -- --duration 300 --summary-every 30 --probe-every 20 -``` +## Collaboration Conventions + +- Prefer the GitHub issue templates under `.github/ISSUE_TEMPLATE/`. +- Keep issue communication primarily in Simplified Chinese. +- Use `问题反馈` for bugs and `功能建议` for feature ideas. +- Use an English Conventional-style pull request title. +- Write the pull request description in Simplified Chinese. +- Include clearly labeled `背景`, `目标`, `实现`, `实现 TODO`, and `验证 TODO` sections in pull requests. + +## High-Priority Repository Rules -## Architecture - -### Entry Point - -`index.ts` — registers the plugin with OpenClaw via `api.registerChannel()` and `api.registerGatewayMethod()` (for docs API). Sets the DingTalk runtime singleton. - -### Core Module Responsibilities - -- **`src/channel.ts`** — Assembly layer only. Defines `dingtalkPlugin` (config, gateway, outbound, status, security, messaging, directory). Delegates all heavy logic to service modules. Keep this file thin. -- **`src/inbound-handler.ts`** — Inbound pipeline orchestrator: dedup → self-filter → content extraction → authorization → session routing → media download → message context persistence → reply dispatch. -- **`src/send-service.ts`** — All outbound delivery: session webhook, proactive text/markdown, proactive media, unified `sendMessage` with card/markdown fallback. -- **`src/card-service.ts`** — AI Card state machine (PROCESSING → INPUTING → FINISHED/FAILED), card instance cache, createdAt fallback cache, recovery of unfinished cards on restart. -- **`src/message-context-store.ts`** — Unified short-TTL message persistence under namespace `messages.context`. The **only** production API for quote/media/card context recovery. -- **`src/reply-strategy.ts`** + `reply-strategy-card.ts` + `reply-strategy-markdown.ts` + `reply-strategy-with-reaction.ts` — Strategy pattern for reply delivery. -- **`src/connection-manager.ts`** — Robust stream reconnect lifecycle with exponential backoff, jitter, cycle limits, and warm reconnection (creates fresh DWClient to minimize message-loss window). -- **`src/config.ts`** — Config resolution, multi-account merging, path resolution. `getConfig()` is the canonical way to read DingTalk config. -- **`src/auth.ts`** — Access token cache with clientId-scoped caching and retry. -- **`src/targeting/`** — Learned group/user displayName directory, target normalization, displayNameResolution gate. - -### Key Patterns - -- **Multi-account support**: `channels.dingtalk.accounts` allows multiple DingTalk bots. Named accounts inherit channel-level defaults with account-level overrides via `mergeAccountWithDefaults`. -- **Card fallback**: If card streaming fails, card is marked FAILED and delivery falls back to markdown/text. Priority: no message loss over card rendering fidelity. -- **Dedup + inflight protection**: `dedup.processed-message`, `session.lock`, and `channel.inflight` are process-local memory-only state. Never introduce cross-process persistence for these. -- **Peer SDK**: Types and APIs come from `openclaw/plugin-sdk`. The `tsconfig.json` paths resolve this from either `../openclaw/src/plugin-sdk` or `../../src/plugin-sdk`. - -### Planned Domain Directories - -New code should align with these logical boundaries (physical moves are incremental): -- `gateway/` — stream lifecycle, callbacks, inbound entry -- `targeting/` — peer identity, session aliasing, target resolution -- `messaging/` — content parsing, reply strategies, outbound delivery, message context -- `card/` — AI card lifecycle, recovery, caches -- `command/` — slash commands, feedback learning -- `platform/` — config, auth, runtime, logger, types -- `shared/` — persistence primitives, dedup, cross-domain helpers - -## Code Conventions - -- TypeScript strict mode, ES2023 target, ESNext modules -- 2-space indentation (oxfmt), no tabs -- Formatting: `oxfmt`; Linting: `oxlint` with unicorn/typescript/oxc plugins -- Structured log prefixes: `[DingTalk]`, `[DingTalk][AICard]`, `[accountId]` -- DingTalk API error payloads: `[DingTalk][ErrorPayload][]` with `code=... message=... payload=...` -- Send APIs return `{ ok: boolean, error?: string }` -- Use `getAccessToken()` before every DingTalk API call -- Use `getLogger()` for logging, never `console.log` -- Never suppress type errors with `@ts-ignore` -- Never log raw access tokens - -## Testing - -- Vitest with V8 coverage; tests in `tests/unit/` and `tests/integration/` -- All network calls are mocked (`vi.mock`) — no real DingTalk API access in tests -- Unit tests for parser, config, auth, dedup, and service logic -- Integration tests when behavior crosses module boundaries (gateway start, inbound dispatch, send lifecycle, persistence migration) -- `clearMocks`, `restoreMocks`, `mockReset` are all enabled globally in vitest config -- When work involves DingTalk real-device validation, PR-scoped test checklist generation, `验证 TODO` drafting, or contributor guidance for that workflow, read and follow `skills/dingtalk-real-device-testing/SKILL.md` first. - -## Important Anti-Patterns - -- Do not add business logic to `src/channel.ts` -- Do not re-introduce legacy `quote-journal.ts` or `quoted-msg-cache.ts` wrappers — use `message-context-store.ts` directly -- Do not create multiple active AI Cards for the same `accountId:conversationId` -- Do not hardcode credentials — read from `channels.dingtalk` config -- Write review comments in Simplified Chinese (per `.github/instructions/code-review.instructions.md`) +- Keep `src/channel.ts` thin; do not add new business logic there. +- Use `src/message-context-store.ts` directly for production quote, media, and card context recovery. +- Do not reintroduce legacy wrappers such as `quote-journal.ts` or `quoted-msg-cache.ts`. +- Use `getAccessToken()` before DingTalk API calls. +- Use `getLogger()` instead of `console.log`. +- Never log raw access tokens. +- Do not create multiple active AI Cards for the same `accountId:conversationId`. +- Keep review comments in Simplified Chinese. + +## Architecture Pointers + +- `index.ts` registers the plugin and sets the DingTalk runtime singleton. +- `src/inbound-handler.ts` owns inbound orchestration. +- `src/send-service.ts` owns outbound delivery. +- `src/card-service.ts` owns AI Card lifecycle and recovery. +- `src/message-context-store.ts` is the only production message context persistence API. +- `src/targeting/` owns learned target directory and target normalization. + +## Quick Lookup + +- Assembly and plugin entry: `index.ts`, `src/channel.ts` +- Inbound handling: `src/inbound-handler.ts` +- Outbound delivery: `src/send-service.ts` +- Card lifecycle: `src/card-service.ts` +- Message context persistence: `src/message-context-store.ts` +- Targeting: `src/targeting/` + +## Optional Tooling + +GitNexus is an optional enhancement for repository understanding, impact analysis, and change-scope review. + +- If GitNexus is available locally, treat `docs/contributor/gitnexus-optional.md` as the preferred path for repository navigation and impact analysis. +- If GitNexus is unavailable locally, use `docs/contributor/fallback-navigation.md` together with `WORKFLOW.md` and `docs/contributor/agent-workflow.md`. +- Optional tooling must not be the only documented way to complete a required workflow step. +- See `docs/contributor/gitnexus-optional.md` for the enhanced workflow. + +## Claude Code Notes + +- Prefer dedicated Claude Code tools over shell equivalents when possible. +- Follow the repository workflow documents before editing. +- Keep changes scoped to the request. + +## Attribution + +This repository is licensed under MIT. If you reuse code, retain the copyright and license notice required by MIT. + +If you substantially reuse this repository's documentation, prompts, AGENTS/CLAUDE conventions, architecture writeups, or agent-oriented implementation playbooks, please provide attribution to `OpenClaw DingTalk Channel Plugin`, `YM Shen and contributors`, and `https://github.com/soimy/openclaw-channel-dingtalk`. + +See `docs/contributor/citation-and-attribution.md` and `CITATION.cff` for the preferred citation and attribution format. This request describes the project's preferred community norm and does not replace or modify the LICENSE file. diff --git a/WORKFLOW.md b/WORKFLOW.md new file mode 100644 index 00000000..b0b0203a --- /dev/null +++ b/WORKFLOW.md @@ -0,0 +1,35 @@ +# Repository Workflow + +This file is the repository-wide workflow summary for maintainers, contributors, and coding agents. + +## Start Here + +This file is the starting point. After reading it, continue in this order: + +1. `docs/contributor/agent-workflow.md` +2. `docs/contributor/architecture.zh-CN.md` or `docs/contributor/architecture.en.md` +3. `docs/contributor/testing.md` +4. `docs/contributor/release-process.md` when preparing a release-related change + +## Base Workflow + +1. Understand the task and read the relevant files and docs. +2. Assess impact before editing by checking affected callers, imports, and execution paths. +3. Keep changes within the requested scope and follow the documented architecture boundaries. +4. Run validation that matches the change, including docs build for docs or workflow changes. +5. Summarize the changed scope, validation, and any follow-up before handoff. + +## Detailed Guides + +- Base contributor and agent workflow: `docs/contributor/agent-workflow.md` +- Architecture: `docs/contributor/architecture.zh-CN.md` +- English architecture guide: `docs/contributor/architecture.en.md` +- Testing and validation: `docs/contributor/testing.md` +- Release process: `docs/contributor/release-process.md` +- GitNexus-first navigation and impact workflow: `docs/contributor/gitnexus-optional.md` +- Manual fallback navigation without GitNexus: `docs/contributor/fallback-navigation.md` + +## Optional Tooling + +If GitNexus is available locally, use `docs/contributor/gitnexus-optional.md`. +If not, continue with the base workflow and `docs/contributor/fallback-navigation.md`. diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index bcd41156..7abe3982 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -75,7 +75,7 @@ export default defineConfig({ const defaultImageRenderer = md.renderer.rules.image ?? - ((tokens, idx, options, env, self) => self.renderToken(tokens, idx, options)) + ((tokens, idx, options, _env, self) => self.renderToken(tokens, idx, options)) md.renderer.rules.image = (tokens, idx, options, env, self) => { const token = tokens[idx] @@ -167,8 +167,12 @@ export default defineConfig({ items: [ { text: '概览', link: '/contributor/' }, { text: '仓库 TODO', link: '/contributor/todo' }, + { text: '贡献者与 Agent 工作流', link: '/contributor/agent-workflow' }, { text: '本地开发', link: '/contributor/development' }, { text: '测试与验证', link: '/contributor/testing' }, + { text: '发布流程', link: '/contributor/release-process' }, + { text: 'GitNexus 首选工作流', link: '/contributor/gitnexus-optional' }, + { text: '无 GitNexus 的手工导航', link: '/contributor/fallback-navigation' }, { text: 'NPM 发布', link: '/contributor/npm-publish' }, { text: '架构说明(中文详版)', link: '/contributor/architecture.zh-CN' }, { text: 'Persistence API 使用指南', link: '/contributor/reference/persistence-api-usage.zh-CN' }, diff --git a/docs/contributor/agent-workflow.md b/docs/contributor/agent-workflow.md new file mode 100644 index 00000000..f492de6b --- /dev/null +++ b/docs/contributor/agent-workflow.md @@ -0,0 +1,88 @@ +# Contributor and Agent Workflow + +This document defines the shared base workflow for contributors and coding agents in this repository. It must remain usable without optional local tools such as GitNexus. + +## Purpose + +Use this document as the authoritative workflow reference when changing code, docs, tests, or release-related assets in this repository. + +## Core Principles + +- Read before editing. +- Keep changes scoped to the request. +- Prefer existing architecture boundaries over ad hoc placement. +- Validate before claiming completion. +- Do not make optional tools the only documented path. + +## Workflow + +### 1. Understand the task + +- Clarify the requested outcome before changing files. +- Read the relevant source files and supporting docs first. +- Use `docs/contributor/architecture.zh-CN.md` or `docs/contributor/architecture.en.md` as the source of truth for module boundaries. +- If the task produces design or implementation planning documents, write them to `docs/spec/` and `docs/plans/`. + +### 2. Assess impact before editing + +- Review direct callers, importers, and affected execution paths before changing a function, class, method, or public behavior. +- For refactors, renames, or broad workflow changes, inspect the surrounding modules and likely downstream consumers. +- If optional graph-aware tooling is available locally, prefer it for impact analysis. If not, perform the same reasoning manually by reading the code and tests. + +### 3. Make the change + +- Prefer editing existing files over creating new ones unless a new file clearly improves structure. +- Keep `src/channel.ts` as an assembly layer; do not move new business logic into it. +- Do not reintroduce legacy quote persistence wrappers such as `quote-journal.ts` or `quoted-msg-cache.ts`; use `src/message-context-store.ts` directly. +- Do not add unrelated refactors or speculative abstractions outside the requested scope. +- Follow the documented domain boundaries for gateway, targeting, messaging, card, command, platform, and shared logic. +- Preserve current user-visible delivery priorities, including card-to-markdown fallback when AI Card delivery fails. +- Keep repository-specific return shapes and structured logging conventions stable unless the task explicitly changes them. + +### 4. Validate the change + +- Run validation that matches the changed scope. +- For code changes, the typical baseline is `pnpm run type-check`, `pnpm run lint`, and relevant tests. +- For docs or workflow changes, also run `pnpm run docs:build`. +- If work affects DingTalk user-visible message behavior, follow the real-device testing guidance in `docs/contributor/testing.md` and use the dedicated real-device-testing skill when that workflow applies. + +### 5. Prepare handoff + +- Summarize what changed and why. +- State which validation steps were run. +- Call out any known limitations, follow-up work, or intentionally untested areas. + +## Repository-Specific Rules + +- Use `getAccessToken()` before DingTalk API calls. +- Use `getLogger()` instead of `console.log`. +- Never log raw access tokens. +- Do not create multiple active AI Cards for the same `accountId:conversationId`. +- Keep review comments in Simplified Chinese, following `.github/instructions/code-review.instructions.md`. +- Keep process-local memory-only state such as inbound dedup and inflight protection out of cross-process persistence. +- Treat `src/message-context-store.ts` as the only production API for quote, media, and card context persistence. +- Preserve the current multi-account model based on `channels.dingtalk.accounts`; account-level settings inherit channel defaults unless explicitly overridden. + +## Documentation Conventions + +- Keep `README.md` as a concise project entry page. +- Put user-facing details in `docs/user/`. +- Put contributor, process, testing, and architecture docs in `docs/contributor/`. +- Put release notes in `docs/releases/`. +- Do not create tool-specific doc roots such as `docs/superpowers/`. + +## Collaboration Conventions + +- Prefer the GitHub issue templates under `.github/ISSUE_TEMPLATE/`. +- Keep issue communication primarily in Simplified Chinese. +- Use an English Conventional-style pull request title. +- Write the pull request description in Simplified Chinese. +- Include clearly labeled `背景`, `目标`, `实现`, `实现 TODO`, and `验证 TODO` sections in pull requests. + +## Optional Tooling Policy + +Optional tools may strengthen navigation, impact analysis, and verification, but they are not required local dependencies. + +- If optional tooling is available, contributors should use it to improve confidence and speed. +- If optional tooling is unavailable, contributors must continue with the base workflow instead of being blocked. +- Tool-specific commands must never be the only documented way to perform a required repository workflow step. diff --git a/docs/contributor/fallback-navigation.md b/docs/contributor/fallback-navigation.md new file mode 100644 index 00000000..b2d2699d --- /dev/null +++ b/docs/contributor/fallback-navigation.md @@ -0,0 +1,46 @@ +# Fallback Navigation Without GitNexus + +Use this document when GitNexus is unavailable locally and you need a manual way to find likely entry points or estimate impact before editing. + +## When to Use This Document + +Use this fallback guide when: + +- You do not have local GitNexus access. +- GitNexus is temporarily unavailable or stale and you do not want to refresh it yet. +- You need a manual cross-check after using the base workflow. + +If GitNexus is available locally, prefer `docs/contributor/gitnexus-optional.md` first. + +## Manual Start Order + +When you are unsure where to begin, read in this order: + +1. `WORKFLOW.md` +2. `docs/contributor/agent-workflow.md` +3. `docs/contributor/architecture.zh-CN.md` or `docs/contributor/architecture.en.md` +4. The most likely feature entry point from the list below +5. Nearby unit tests and integration tests + +## Where to Look First + +- Plugin registration and channel assembly → `index.ts`, `src/channel.ts` +- Inbound pipeline and routing → `src/inbound-handler.ts` +- Outbound delivery and reply selection → `src/send-service.ts`, `src/reply-strategy.ts` +- AI Card lifecycle and callbacks → `src/card-service.ts` +- Message context and quote recovery → `src/message-context-store.ts` +- Targeting and learned directory behavior → `src/targeting/` + +For repository rules, collaboration conventions, and validation expectations, see `docs/contributor/agent-workflow.md`. +For architecture boundaries and module placement, see `docs/contributor/architecture.zh-CN.md` or `docs/contributor/architecture.en.md`. +For test scope and real-device guidance, see `docs/contributor/testing.md`. + +## Manual Impact Review Without GitNexus + +When you are about to edit a symbol and GitNexus is unavailable: + +1. Read the defining file first. +2. Search for direct imports and obvious callers. +3. Read nearby tests to understand expected behavior. +4. Check whether the change touches inbound handling, outbound delivery, card lifecycle, targeting, or persistence. +5. Expand validation if the change sits on one of those high-traffic paths. diff --git a/docs/contributor/gitnexus-optional.md b/docs/contributor/gitnexus-optional.md new file mode 100644 index 00000000..e4f91084 --- /dev/null +++ b/docs/contributor/gitnexus-optional.md @@ -0,0 +1,102 @@ +# GitNexus Optional Workflow + +GitNexus is the preferred repository-understanding and impact-analysis path when it is available locally. This document describes the GitNexus-first workflow for this repository and the corresponding fallback path when GitNexus is unavailable. + +## Purpose + +Use GitNexus when it is available locally and you want graph-aware help for repository exploration, impact analysis, refactor safety, and change-scope review. This document complements the base workflow in `WORKFLOW.md` and `docs/contributor/agent-workflow.md`. + +## GitNexus-First Workflow + +When GitNexus is available locally, prefer it for the parts of the workflow that involve repository navigation, execution-flow tracing, blast-radius analysis, or change-scope verification. + +### 1. Understand the task + +Use GitNexus first when you need to answer questions such as: + +- Where does this behavior live? +- Which execution flow handles this request? +- Which modules participate in this feature? +- Which file should I read first? + +Recommended approach: + +- Start with repository context and index freshness. +- Use concept-oriented query to find relevant flows and symbols. +- Use symbol context when you need a focused view of callers, callees, and participating processes. + +### 2. Assess impact before editing + +Use GitNexus first when you need to answer: + +- What breaks if I change this function, class, or method? +- Which direct callers and indirect dependents are affected? +- Is this rename or refactor riskier than it looks? + +Recommended approach: + +- Run graph-aware impact analysis before editing symbols with multiple callers or cross-module usage. +- Treat HIGH or CRITICAL impact results as a cue to expand validation and communicate blast radius clearly. +- For refactors and symbol renames, prefer graph-aware rename and context-aware review over blind repository-wide text replacement. + +### 3. Validate and prepare handoff + +Use GitNexus first when you need to answer: + +- Did this change affect the scope I expected? +- Did I accidentally touch unrelated execution flows? +- Do I need broader regression testing before commit? + +Recommended approach: + +- Review the diff as usual. +- Then use change detection to confirm affected symbols and execution paths. +- If the detected scope is broader than expected, either reduce the change or expand the validation plan. + +## When to Use GitNexus + +GitNexus is especially helpful for: + +- Exploring unfamiliar architecture or execution paths +- Assessing blast radius before editing a function, class, or method +- Tracing likely callers and affected flows during debugging +- Reviewing rename or refactor safety +- Verifying that change scope matches the intended symbols and flows before commit + +## Recommended Usage Notes + +- Start by checking repository context and index freshness. +- If the index is stale, re-run analysis before relying on graph results. +- Prefer GitNexus over manually maintaining long `Where to find` lists when local GitNexus is available. +- Prefer graph-aware rename workflows over blind repository-wide text replacement when you are renaming symbols. +- Treat GitNexus as the first stop for codebase navigation when available, not merely as an optional afterthought. + +## Indexing This Repository + +When running `gitnexus analyze` on this repository, **always use the `--skip-agents-md` flag**: + +```bash +gitnexus analyze --skip-agents-md +``` + +This repository maintains detailed GitNexus guidance in this document rather than in the root `AGENTS.md` / `CLAUDE.md` entry files. The `--skip-agents-md` flag prevents GitNexus from injecting its standard usage block into those thin entry documents, preserving the repository's documentation layering strategy. + +If you accidentally run `gitnexus analyze` without this flag and the entry files are modified, remove the injected ` ... ` block before committing. + +## Relationship to Manual Navigation Guides + +This repository may still provide manual navigation and fallback guidance for contributors who do not have GitNexus locally. Those guides are secondary disclosure and should mainly be used when GitNexus is unavailable. + +If GitNexus is available locally, use this document first. If GitNexus is unavailable, use `docs/contributor/fallback-navigation.md`. + +## Fallback + +If GitNexus is unavailable locally: + +- Continue with `WORKFLOW.md` and `docs/contributor/agent-workflow.md`. +- Use `docs/contributor/fallback-navigation.md` for manual navigation, file entry points, and hand-traced impact exploration. +- Read the affected files directly. +- Search for callers, imports, and nearby tests manually. +- Run the same repository validation steps that you would run with GitNexus available. + +Lack of GitNexus must not block normal development, review, or documentation work in this repository. diff --git a/docs/contributor/index.md b/docs/contributor/index.md index 96f73dde..9a41e142 100644 --- a/docs/contributor/index.md +++ b/docs/contributor/index.md @@ -4,12 +4,15 @@ ## 建议阅读顺序 -1. [仓库 TODO](todo.md) +1. [贡献者与 Agent 工作流](agent-workflow.md) 2. [本地开发](development.md) 3. [测试与验证](testing.md) -4. [架构说明(中文详版)](architecture.zh-CN.md) -5. [NPM 发布](npm-publish.md) -6. [引用与署名](citation-and-attribution.md) +4. [发布流程](release-process.md) +5. [架构说明(中文详版)](architecture.zh-CN.md) +6. [GitNexus 首选工作流](gitnexus-optional.md) +7. [无 GitNexus 的手工导航](fallback-navigation.md) +8. [NPM 发布](npm-publish.md) +9. [引用与署名](citation-and-attribution.md) ## 范围说明 @@ -17,11 +20,15 @@ ## 贡献入口 +- [贡献者与 Agent 工作流](agent-workflow.md) - [仓库 TODO](todo.md) - [本地开发](development.md) - [测试与验证](testing.md) +- [发布流程](release-process.md) - [架构说明(中文详版)](architecture.zh-CN.md) - [Architecture guide](architecture.en.md) +- [GitNexus 首选工作流](gitnexus-optional.md) +- [无 GitNexus 的手工导航](fallback-navigation.md) - [NPM 发布](npm-publish.md) - [引用与署名](citation-and-attribution.md) - [Persistence API 使用指南](reference/persistence-api-usage.zh-CN.md) diff --git a/docs/plans/2026-04-08-agent-constraint-skills-roadmap-plan.md b/docs/plans/2026-04-08-agent-constraint-skills-roadmap-plan.md new file mode 100644 index 00000000..280d6e9c --- /dev/null +++ b/docs/plans/2026-04-08-agent-constraint-skills-roadmap-plan.md @@ -0,0 +1,190 @@ +# 智能体约束文档向 Skills 固化实施计划 + +> **For agentic workers:** Execute this plan task-by-task with review between steps. If your environment supports subagent-based execution you may use it; otherwise execute the checklist inline. + +**Goal:** 将当前文档中适合稳定流程化的内容逐步固化为 skills,减少主入口文档膨胀,并让 PR、release、impact analysis、文档落盘等流程具备更强的自动触发与一致性。 + +**Architecture:** 采用“文档保留规则与上下文,skill 承载高重复流程”的分工:文档层负责长期约束与参考资料,skill 层负责在具体任务场景下触发、编排步骤、生成标准输出,并在可选能力(如 GitNexus)与 fallback 之间做自动分流。 + +**Tech Stack:** Claude Code skills, Markdown SKILL.md, repository contributor docs, GitNexus MCP, GitHub PR workflow + +--- + +### Task 1: 定义 Skill 边界与优先级 + +**Files:** +- Create: `docs/spec/2026-04-08-agent-constraint-skills-roadmap-design.md` +- Create: `docs/plans/2026-04-08-agent-constraint-skills-roadmap-plan.md` + +- [ ] **Step 1: 固化候选 skills 的职责边界** + +```text +第一批:pr-description-writer, release-note-authoring, repo-impact-analysis +第二批:repo-doc-routing, release-publish-orchestration +第三批:增强 dingtalk-real-device-testing +``` + +- [ ] **Step 2: 明确哪些内容继续留在文档层** + +```text +保留在文档层:项目事实、架构边界、静态 code conventions、fallback reference +迁移到 skill 层:高重复、触发稳定、输出结构明确的流程 +``` + +- [ ] **Step 3: 确认技能触发边界与高风险动作确认策略** + +```text +release-publish-orchestration 默认只生成 readiness 结论与 checklist,不直接执行不可逆发布动作。 +``` + +### Task 2: 设计第一批 Skills + +**Files:** +- Create: `.claude/skills/pr-description-writer/SKILL.md` +- Create: `.claude/skills/release-note-authoring/SKILL.md` +- Create: `.claude/skills/repo-impact-analysis/SKILL.md` +- Modify: `docs/contributor/agent-workflow.md` +- Modify: `docs/contributor/gitnexus-optional.md` +- Modify: `docs/contributor/fallback-navigation.md` + +- [ ] **Step 1: 设计 `pr-description-writer`** + +```text +输入:git diff、相关 spec/plan、验证记录 +输出:中文 PR body,含 背景 / 目标 / 实现 / 实现 TODO / 验证 TODO +``` + +- [ ] **Step 2: 设计 `release-note-authoring`** + +```text +输入:版本号、变更范围、docs/releases 现状 +输出:release note 草案、必要的 release index/sidebar 联动提示 +``` + +- [ ] **Step 3: 设计 `repo-impact-analysis`** + +```text +输入:目标 symbol 或概念 +输出:GitNexus-first 或 fallback 的统一影响面摘要、关键入口、验证建议 +``` + +- [ ] **Step 4: 为每个 skill 制定 2-3 个触发测试 prompt** + +```text +示例: +- "帮我写这个 PR 的描述,并补齐验证 TODO" +- "根据最近的改动整理 3.5.4 的 release note" +- "如果我改 message-context-store,会影响什么?" +``` + +### Task 3: 设计第二批 Skills + +**Files:** +- Create: `.claude/skills/repo-doc-routing/SKILL.md` +- Create: `.claude/skills/release-publish-orchestration/SKILL.md` +- Modify: `WORKFLOW.md` +- Modify: `docs/contributor/release-process.md` + +- [ ] **Step 1: 设计 `repo-doc-routing`** + +```text +输入:用户要写的文档类型或任务描述 +输出:推荐落盘路径、需要同步更新的文档入口、禁止落盘位置提醒 +``` + +- [ ] **Step 2: 设计 `release-publish-orchestration`** + +```text +输入:版本号、发布目标、当前 readiness 状态 +输出:发布 checklist、阻塞项、需要用户确认的不可逆动作列表 +``` + +- [ ] **Step 3: 明确发布 skill 与 release note skill 的边界** + +```text +release-note-authoring 只负责编写说明;release-publish-orchestration 只负责编排发布准备与确认。 +``` + +### Task 4: 增强 `dingtalk-real-device-testing` + +**Files:** +- Modify: existing `dingtalk-real-device-testing` skill files +- Modify: `docs/contributor/testing.md` +- Modify: `docs/contributor/agent-workflow.md` + +- [ ] **Step 1: 对齐该 skill 与 PR / release 流程的接口** + +```text +让 skill 输出可直接复用到 PR 的 验证 TODO 和发布前检查。 +``` + +- [ ] **Step 2: 让真机验证清单按改动范围分层** + +```text +区分 docs/workflow 改动、消息链路改动、card 交互改动、引用/媒体改动。 +``` + +- [ ] **Step 3: 更新文档中的 skill 入口提示** + +```text +当任务涉及 DingTalk 用户可见行为时,优先使用该 skill。 +``` + +### Task 5: 评测与迭代 + +**Files:** +- Create: `evals/evals.json` under each new skill as needed +- Create: skill workspaces for iteration runs + +- [ ] **Step 1: 为第一批 skills 写触发测试集** + +```json +{ + "skill_name": "pr-description-writer", + "evals": [ + { + "id": 1, + "prompt": "我准备开 PR 了,帮我把这次改动整理成仓库要求的中文 PR 描述,并补 验证 TODO", + "expected_output": "生成符合仓库模板的 PR body", + "files": [] + } + ] +} +``` + +- [ ] **Step 2: 跑 with-skill / baseline 对比** + +```text +比较是否更稳定地产出仓库约定格式、是否减少漏项、是否更准确分流 GitNexus 与 fallback。 +``` + +- [ ] **Step 3: 根据反馈精修 skill 描述与触发条件** + +```text +重点看 under-trigger 和 over-trigger 问题。 +``` + +### Task 6: 更新入口文档 + +**Files:** +- Modify: `AGENTS.md` +- Modify: `CLAUDE.md` +- Modify: `WORKFLOW.md` +- Modify: `docs/contributor/agent-workflow.md` + +- [ ] **Step 1: 在入口文档中加入技能入口提示** + +```text +例如:准备 PR 时使用 pr-description-writer;写 release note 时使用 release-note-authoring。 +``` + +- [ ] **Step 2: 删除已被 skill 明确接管的长流程段** + +```text +保留规则摘要,移除可执行细节,避免重复维护。 +``` + +- [ ] **Step 3: 跑 docs 构建并复核链接** + +Run: `pnpm run docs:build` +Expected: PASS diff --git a/docs/plans/2026-04-08-agents-claude-doc-layering-and-gitnexus-optional-plan.md b/docs/plans/2026-04-08-agents-claude-doc-layering-and-gitnexus-optional-plan.md new file mode 100644 index 00000000..dbe6b7b6 --- /dev/null +++ b/docs/plans/2026-04-08-agents-claude-doc-layering-and-gitnexus-optional-plan.md @@ -0,0 +1,240 @@ +# AGENTS / CLAUDE 文档分层与 GitNexus 可选增强实施计划 + +> **For agentic workers:** Execute this plan task-by-task with review between steps. If your environment supports subagent-based execution you may use it; otherwise execute the checklist inline. + +**Goal:** 精简并同步 `AGENTS.md` 与 `CLAUDE.md`,引入共享工作流与 GitNexus 可选增强文档,使公开仓库在无 GitNexus 环境下也能完整协作。 + +**Architecture:** 采用“双入口 + 共享规则 + 可选增强”的文档分层模型:`AGENTS.md` 作为通用入口,`CLAUDE.md` 作为 Claude 兼容入口,`WORKFLOW.md` 提供摘要导航,`docs/contributor/agent-workflow.md` 承载基础规则,`docs/contributor/gitnexus-optional.md` 承载工具增强说明。 + +**Tech Stack:** Markdown, VitePress docs, pnpm scripts + +--- + +### Task 1: 新增共享工作流文档 + +**Files:** +- Create: `WORKFLOW.md` +- Create: `docs/contributor/agent-workflow.md` +- Test: `docs/contributor/index.md` + +- [ ] **Step 1: 写出 `WORKFLOW.md` 初稿** + +```md +# Repository Workflow + +## Start Here +- Read this file first for a repository-wide summary. +- Then follow the detailed contributor workflow and architecture docs. + +## Base Workflow +1. Understand the task and read the relevant files. +2. Assess impact before editing. +3. Keep changes within scope and follow architecture boundaries. +4. Run validation that matches the change. +5. Summarize scope, validation, and any follow-up. + +## Detailed Guides +- Base workflow: `docs/contributor/agent-workflow.md` +- Architecture: `docs/contributor/architecture.zh-CN.md` +- Testing: `docs/contributor/testing.md` +- Release process: `docs/contributor/release-process.md` + +## Optional Tooling +- GitNexus is an optional enhancement for repository understanding and impact analysis. +- If it is unavailable locally, continue with the base workflow. +- See `docs/contributor/gitnexus-optional.md`. +``` + +- [ ] **Step 2: 写出 `docs/contributor/agent-workflow.md` 初稿** + +```md +# Contributor and Agent Workflow + +## Purpose +This document defines the shared base workflow for contributors and coding agents in this repository. It must remain usable without optional local tools such as GitNexus. + +## Core Principles +- Read before editing. +- Keep changes scoped to the request. +- Prefer existing architecture boundaries. +- Validate before claiming completion. +- Do not make optional tools the only documented path. + +## Workflow +### 1. Understand the task +### 2. Assess impact before editing +### 3. Make the change +### 4. Validate the change +### 5. Prepare handoff +``` + +- [ ] **Step 3: 在 contributor 入口页加入新文档链接** + +```md +- [仓库工作流](../../WORKFLOW.md) +- [贡献者与 Agent 工作流](agent-workflow.md) +``` + +- [ ] **Step 4: 运行文档构建验证新链接** + +Run: `pnpm run docs:build` +Expected: docs build succeeds without broken links caused by the new workflow documents. + +### Task 2: 新增 GitNexus 可选增强文档 + +**Files:** +- Create: `docs/contributor/gitnexus-optional.md` +- Modify: `docs/contributor/index.md` +- Test: `docs/contributor/gitnexus-optional.md` + +- [ ] **Step 1: 写出 GitNexus 可选增强文档** + +```md +# GitNexus Optional Workflow + +## Purpose +GitNexus is an optional enhancement for code understanding, impact analysis, and change-scope review in this repository. + +## When to Use +- Exploring unfamiliar architecture +- Assessing impact before editing +- Tracing execution paths during debugging +- Verifying change scope before commit + +## Mapping to the Base Workflow +- Understand context -> `query`, `context` +- Assess impact -> `impact` +- Verify scope -> `detect_changes` + +## Fallback +If GitNexus is unavailable locally, continue with `WORKFLOW.md` and `docs/contributor/agent-workflow.md`. Lack of GitNexus must not block normal development or review. +``` + +- [ ] **Step 2: 在 contributor 入口页加入 GitNexus 可选增强链接** + +```md +- [GitNexus 可选增强工作流](gitnexus-optional.md) +``` + +- [ ] **Step 3: 运行文档构建确认 GitNexus 文档收录正常** + +Run: `pnpm run docs:build` +Expected: docs build succeeds and includes the new optional GitNexus page. + +### Task 3: 精简并同步 `AGENTS.md` + +**Files:** +- Modify: `AGENTS.md` +- Test: `WORKFLOW.md` + +- [ ] **Step 1: 将 `AGENTS.md` 重写为短入口骨架** + +```md +# PROJECT KNOWLEDGE BASE + +## Overview +DingTalk enterprise bot channel plugin for OpenClaw. Use the contributor architecture docs as the source of truth for module boundaries. + +## Start Here +- `WORKFLOW.md` +- `docs/contributor/agent-workflow.md` +- `docs/contributor/architecture.zh-CN.md` +- `docs/contributor/architecture.en.md` + +## Documentation Placement +- Specs -> `docs/spec/` +- Plans -> `docs/plans/` +- User docs -> `docs/user/` +- Contributor docs -> `docs/contributor/` +- Release notes -> `docs/releases/` + +## Collaboration Conventions +- Prefer issue templates in `.github/ISSUE_TEMPLATE/` +- Keep issue discussion primarily in Simplified Chinese +- Use an English Conventional-style PR title +- Write the PR body in Simplified Chinese with `背景`, `目标`, `实现`, `实现 TODO`, `验证 TODO` + +## Optional Tooling +GitNexus is an optional enhancement. The base workflow must remain usable without it. See `docs/contributor/gitnexus-optional.md`. +``` + +- [ ] **Step 2: 删除超长 `STRUCTURE`、`CODE MAP` 与 GitNexus 手册段** + +Run: manual edit in `AGENTS.md` +Expected: the file keeps only the high-value project summary, links, conventions, and high-priority repository rules. + +- [ ] **Step 3: 校对 `AGENTS.md` 与新工作流文档的一致性** + +Run: review `AGENTS.md`, `WORKFLOW.md`, and `docs/contributor/agent-workflow.md` +Expected: shared rules are consistent and `AGENTS.md` does not contradict the new base workflow. + +### Task 4: 精简并同步 `CLAUDE.md` + +**Files:** +- Modify: `CLAUDE.md` +- Test: `AGENTS.md` + +- [ ] **Step 1: 用与 `AGENTS.md` 相同的主骨架重写 `CLAUDE.md`** + +```md +# CLAUDE.md + +This file provides guidance to Claude Code when working in this repository. + +## Overview +DingTalk enterprise bot channel plugin for OpenClaw. This file intentionally stays closely aligned with `AGENTS.md`. + +## Start Here +- `WORKFLOW.md` +- `docs/contributor/agent-workflow.md` +- `docs/contributor/architecture.zh-CN.md` +- `docs/contributor/architecture.en.md` + +## Optional Tooling +GitNexus is an optional enhancement. If available locally, prefer it for impact analysis and change-scope review. If unavailable, continue with the base workflow. +``` + +- [ ] **Step 2: 保留最少量 Claude Code 专属说明** + +```md +## Claude Code Notes +- Prefer dedicated Claude Code tools over shell equivalents when possible. +- Follow repository workflow documents before editing. +- Keep changes scoped to the request. +``` + +- [ ] **Step 3: 删除内嵌 GitNexus 详细段并检查与 `AGENTS.md` 同步程度** + +Run: manual review of `CLAUDE.md` and `AGENTS.md` +Expected: both files share the same core structure, with only minimal Claude-specific additions. + +### Task 5: 统一措辞并完成验证 + +**Files:** +- Modify: `AGENTS.md` +- Modify: `CLAUDE.md` +- Modify: `WORKFLOW.md` +- Modify: `docs/contributor/agent-workflow.md` +- Modify: `docs/contributor/gitnexus-optional.md` +- Modify: `docs/contributor/index.md` + +- [ ] **Step 1: 将工具绑定型强约束改写为“目标强制、工具可选”** + +```md +Before editing a function, class, or method, contributors must assess the blast radius by reviewing direct callers, importers, and affected flows. If GitNexus is available locally, prefer graph-aware tools for this step. +``` + +- [ ] **Step 2: 运行文档构建** + +Run: `pnpm run docs:build` +Expected: PASS + +- [ ] **Step 3: 运行类型检查、lint 与测试的最小必要验证** + +Run: `pnpm run type-check && pnpm run lint` +Expected: PASS + +- [ ] **Step 4: 检查工作区变化范围** + +Run: `git diff -- AGENTS.md CLAUDE.md WORKFLOW.md docs/contributor/index.md docs/contributor/agent-workflow.md docs/contributor/gitnexus-optional.md docs/spec/2026-04-08-agents-claude-doc-layering-and-gitnexus-optional-design.md docs/plans/2026-04-08-agents-claude-doc-layering-and-gitnexus-optional-plan.md` +Expected: only the intended documentation files are changed. diff --git a/docs/spec/2026-04-08-agent-constraint-skills-roadmap-design.md b/docs/spec/2026-04-08-agent-constraint-skills-roadmap-design.md new file mode 100644 index 00000000..3a8a9e5b --- /dev/null +++ b/docs/spec/2026-04-08-agent-constraint-skills-roadmap-design.md @@ -0,0 +1,212 @@ +# 智能体约束文档向 Skills 固化的下一阶段设计 + +## 背景 + +当前仓库已完成智能体约束文档的第一轮信息架构整理: + +- `AGENTS.md` 作为公开、通用的项目级智能体入口 +- `CLAUDE.md` 作为 Claude Code 兼容入口并与 `AGENTS.md` 保持高同步 +- `WORKFLOW.md` 作为仓库级工作流摘要导航 +- `docs/contributor/agent-workflow.md` 作为共享基础规则层 +- `docs/contributor/gitnexus-optional.md` 作为 GitNexus-first 增强层 +- `docs/contributor/fallback-navigation.md` 作为无 GitNexus 的手工 fallback 层 + +这一层面已经解决了“规则如何分层披露”的问题,但仍有若干高重复、步骤稳定、输出格式明确的流程继续停留在文档规则中。对于这些内容,继续放在文档里只提供“可阅读的约束”,而不能提供“可执行的流程编排”。 + +## 目标 + +将适合固化的高频流程从智能体约束文档中进一步抽取为 skills,使 Claude/其他 agent 在特定上下文中能够自动进入稳定流程,减少漏步、减少输出格式漂移,并降低主入口文档继续膨胀的风险。 + +## 非目标 + +- 不把项目事实、架构边界、静态规则全部迁移成 skills。 +- 不在本阶段实现所有 skill 细节或完成所有 eval。 +- 不把高风险发布动作默认自动执行到不可逆阶段。 + +## 选择原则 + +一个流程适合 skill 化,通常满足以下特征: + +1. 触发语义清晰,用户请求容易识别。 +2. 步骤相对稳定,流程编排可以复用。 +3. 输出格式明确,适合模板化或 checklist 化。 +4. 容易漏掉关键步骤,文档提醒不够强。 +5. 与仓库约定强相关,通用模型容易偏离。 + +## 建议的 Skill 分组 + +### 一、文档与交付类 + +#### 1. `repo-doc-routing` + +**职责:** +根据用户要写的内容类型,决定文档应该落在哪个目录、是否属于用户文档 / contributor 文档 / release note / spec / plan,并提醒需要同步的相关入口。 + +**适用场景:** +- 写 spec +- 写 implementation plan +- 写 contributor 指南 +- 更新 release note +- 调整 docs 页面但不确定归属 + +**为什么适合 skill 化:** +该流程高度稳定,并且当前仓库已经明确禁止创建工具私有根目录、禁止在 README 堆积长文,skill 可显著减少错放文档的概率。 + +#### 2. `pr-description-writer` + +**职责:** +根据 diff、相关 spec / plan 和验证信息,生成符合本仓库约定的 PR 描述,并补齐 `背景` / `目标` / `实现` / `实现 TODO` / `验证 TODO` 结构。 + +**适用场景:** +- 准备创建 PR +- 需要补 PR body +- 需要根据改动生成 `验证 TODO` + +**为什么适合 skill 化:** +PR 描述格式稳定、输出结构固定、容易漏 `验证 TODO`,且与仓库中文 PR body 规范强绑定。 + +#### 3. `release-note-authoring` + +**职责:** +根据已完成改动、版本号、最近 commit / diff 或 release 目标,生成版本说明文档,并在必要时提示同步 release index / sidebar / 站点导航。 + +**适用场景:** +- 编写新版本说明 +- 补发版本记录 +- 需要根据改动汇总用户可见变化 + +**为什么适合 skill 化:** +版本说明结构、措辞和产物位置都相对稳定,并且与 docs 发布导航高度联动。 + +### 二、流程与安全类 + +#### 4. `repo-impact-analysis` + +**职责:** +统一封装“修改前影响评估”流程: +- GitNexus 可用时走 GitNexus-first +- GitNexus 不可用时退到 `fallback-navigation.md` +- 输出统一的影响面摘要、关键入口和建议验证范围 + +**适用场景:** +- 用户问“改这个会影响什么” +- 在编辑某个 symbol 前做安全评估 +- 定位入口文件或执行流 +- 准备做 rename / refactor + +**为什么适合 skill 化:** +当前仓库已经形成了明确的能力分流逻辑,这比长期把流程写在文档里更适合 skill 化。 + +#### 5. `release-publish-orchestration` + +**职责:** +编排发布前检查、版本 readiness、docs / test / release note / npm publish checklist,并把危险操作与只读检查动作清晰区分。 + +**适用场景:** +- 准备发布 npm 包 +- 做 release readiness check +- 需要确认能否发版 + +**为什么适合 skill 化:** +发布是高风险但流程稳定的动作,最适合通过 skill 进行强引导和明确确认边界。 + +### 三、项目专属验证类 + +#### 6. `dingtalk-real-device-testing`(增强现有 skill) + +**职责:** +继续强化当前真机验证流程,做到: +- 根据 diff 判断是否需要真机验证 +- 按改动类型生成更细颗粒度的 `验证 TODO` +- 区分 docs/workflow 改动与用户可见消息链路改动 +- 为 PR 描述和发布前检查复用同一套验证抽象 + +**适用场景:** +- 影响 DingTalk 用户可见行为的 PR +- 需要补真机验证清单 +- 需要在发布前检查真机覆盖情况 + +## 为什么不是所有内容都适合做 Skill + +以下内容更适合继续保留在文档层: + +- 项目事实和静态背景:例如 OpenClaw / DingTalk / Stream mode 的基本介绍 +- 长期稳定的架构边界:例如 `src/channel.ts` 保持薄、逻辑领域划分 +- fallback navigation 本身:它更适合作为 skill 的 reference,而不是独立 skill +- 日志前缀、返回值形状、基础 code conventions 等静态规则 + +这些内容本质上是上下文,而不是动作流程。 + +## 推荐实施顺序 + +### 第一批(优先级最高) + +1. `pr-description-writer` +2. `release-note-authoring` +3. `repo-impact-analysis` + +理由: +- 触发频率高 +- 流程最稳定 +- 对当前文档规约的减负效果最明显 +- 复用 GitNexus-first / fallback 分流最自然 + +### 第二批 + +4. `repo-doc-routing` +5. `release-publish-orchestration` + +理由: +- 价值高,但需要先稳定好第一批的输出接口和约定 +- `release-publish-orchestration` 涉及高风险动作,需要更审慎设计确认边界 + +### 第三批 + +6. 增强 `dingtalk-real-device-testing` + +理由: +- 现有技能已经承担一部分职责,应先在前两批 skill 成型后再对齐接口,避免重复设计 + +## 触发与边界建议 + +### `repo-doc-routing` +- 应在用户提到“写文档、写 spec、写计划、更新 contributor 文档、更新 release 文档”时触发 +- 只负责“文档类型判断与落盘路由”,不替代具体写作 skill + +### `pr-description-writer` +- 应在用户准备开 PR、补 PR 描述、生成 `验证 TODO` 时触发 +- 可读取 diff、spec、plan,但不直接 push / create PR + +### `release-note-authoring` +- 应在用户提到版本说明、release note、发布页时触发 +- 只负责文案和 docs 导航联动,不直接发布 npm 包 + +### `repo-impact-analysis` +- 应在用户问“改这个会影响什么”“这个从哪进来”“我要重构这里”时触发 +- 统一决定走 GitNexus-first 还是 fallback path + +### `release-publish-orchestration` +- 应在用户明确表示“准备发版 / 发 npm / 做发布检查”时触发 +- 默认只生成 checklist 和 readiness 结论;真正不可逆操作必须再次确认 + +### `dingtalk-real-device-testing` +- 继续用于 PR 级别真机验证与 `验证 TODO` 生成 +- 与 `pr-description-writer` / `release-publish-orchestration` 做接口衔接 + +## 对现有文档体系的影响 + +如果这些 skill 逐步落地,当前文档体系中的变化方向应是: + +- `AGENTS.md` / `CLAUDE.md` / `WORKFLOW.md` 保留“读哪些文档、何时触发哪些 skill”的入口语义 +- `docs/contributor/agent-workflow.md` 保留基础规则,不承载长 checklist +- `docs/contributor/gitnexus-optional.md` 继续作为 `repo-impact-analysis` 的参考文档之一 +- `docs/contributor/fallback-navigation.md` 继续作为手工 fallback reference,而不是默认入口 +- 发布、PR、文档落盘、真机验证等高重复流程更多通过 skills 表达 + +## 预期收益 + +- 减少主入口文档继续膨胀 +- 减少 PR / release / docs / impact 分析等流程的漏步率 +- 提升对公开仓库协作者的行为一致性 +- 让 GitNexus-first 与 fallback 路径真正变成可执行流程,而不只是文字约束 +- 为未来继续接入更多 MCP / 图谱 / 发布工具保留统一的 skill 化扩展点 diff --git a/docs/spec/2026-04-08-agents-claude-doc-layering-and-gitnexus-optional-design.md b/docs/spec/2026-04-08-agents-claude-doc-layering-and-gitnexus-optional-design.md new file mode 100644 index 00000000..df83656b --- /dev/null +++ b/docs/spec/2026-04-08-agents-claude-doc-layering-and-gitnexus-optional-design.md @@ -0,0 +1,192 @@ +# AGENTS / CLAUDE 文档分层与 GitNexus 可选增强设计 + +## 背景 + +仓库近期引入 GitNexus,用节点式知识图谱增强代码理解、影响评估与变更追溯能力。现有 `AGENTS.md` 与 `CLAUDE.md` 直接内嵌了大量 GitNexus 工作流、强约束语句与工具速查表,导致: + +1. 两个根入口文件体积显著膨胀。 +2. 项目事实、基础协作规则、工具增强说明混写,职责边界不清。 +3. `CLAUDE.md` 是 Claude Code 的正式入口,但公开仓库无法假设所有开发者或 AI 协作者都使用 Claude Code。 +4. `AGENTS.md` 作为更通用的项目级智能体入口,需要继续成立;同时又希望和 `CLAUDE.md` 尽量同步,减少漂移。 +5. 无 GitNexus 本地环境的贡献者不应被阻塞,基础工作流必须完整可用。 + +## 目标 + +- 保持 `AGENTS.md` 为公开、通用的项目级智能体约束入口。 +- 保持 `CLAUDE.md` 为 Claude Code 的兼容入口,并与 `AGENTS.md` 尽量同步。 +- 将“基础工作流”与“GitNexus 可选增强”拆层披露,减少根文档体积与重复。 +- 确保不安装 GitNexus 的开发者仍可完整遵循仓库协作规则。 +- 为后续继续接入其他可选工具保留扩展空间,而不再次膨胀根入口文档。 + +## 非目标 + +- 不改变现有代码架构或运行时行为。 +- 不要求删除 GitNexus 能力,也不降低其对熟悉仓库时的价值。 +- 不把规则迁移到仅对某个特定工具可见的位置。 + +## 设计原则 + +### 1. 双入口、同骨架 + +`AGENTS.md` 与 `CLAUDE.md` 都保留,且章节骨架尽量一致: + +- 项目概览 +- 开始阅读顺序 +- 文档落盘约定 +- 协作与 PR 约定 +- 可选工具原则 +- 架构入口与高优先级约束 + +其中 `CLAUDE.md` 只额外补充最少量的 Claude Code 专属说明,不再承载一整套独立规则体系。 + +### 2. 入口短、规则长 + +根目录入口文档只保留不应被忽略的摘要信息与导航链接。详细规则下沉到普通 Markdown 文档中,避免在两个入口文件中重复维护长篇手册。 + +### 3. 强制目标与可选工具分离 + +基础规则可要求“修改前评估影响面”“提交前核对变更范围”,但不能要求唯一依赖 GitNexus 命令实现这些目标。GitNexus 作为推荐增强路径单独说明。 + +### 4. Repo 内普通文档优先 + +共享规则文档必须是仓库内普通 Markdown 文件,使人类贡献者、Claude Code 以外的 AI 工具、以及纯网页浏览用户都能访问。 + +## 信息分层 + +### 第一层:根入口 + +- `AGENTS.md` +- `CLAUDE.md` +- `WORKFLOW.md` + +职责:快速起步、导航、强调高优先级仓库规则。 + +### 第二层:共享详细规则 + +- `docs/contributor/agent-workflow.md` + +职责:作为所有贡献者与代理共享的基础工作流权威来源。 + +### 第三层:可选工具增强 + +- `docs/contributor/gitnexus-optional.md` + +职责:说明 GitNexus 在理解代码、影响评估、重构与提交流程中的增强作用,以及缺失时的降级路径。 + +### 第四层:领域文档 + +- `docs/contributor/architecture.zh-CN.md` +- `docs/contributor/architecture.en.md` +- `docs/contributor/testing.md` +- `docs/contributor/release-process.md` +- 其他 contributor 文档 + +职责:承载专项长期文档,不再由根入口文件重复镜像。 + +## 目标文件职责 + +### `AGENTS.md` + +作为公开项目中的通用 agent 入口文件: + +- 保留项目概览与关键高优先级约束。 +- 指向 `WORKFLOW.md`、`docs/contributor/agent-workflow.md` 与架构文档。 +- 保留文档放置约定、Issue / PR 约定摘要。 +- 用短段说明 GitNexus 是可选增强,而非必须依赖。 +- 删除超长结构镜像、CODE MAP 与详细 GitNexus 速查表。 + +### `CLAUDE.md` + +作为 Claude Code 专用入口文件: + +- 与 `AGENTS.md` 保持相同主骨架。 +- 保留相同的项目概览、规则导航与高优先级约束。 +- 只新增少量 Claude Code 专属提示,如优先使用专用工具、遵循仓库工作流。 +- 不再内嵌完整 GitNexus 手册。 + +### `WORKFLOW.md` + +作为根目录摘要导航: + +- 告诉新进入仓库的协作者应先读什么。 +- 用 5 步以内描述基础工作流。 +- 链接到 `agent-workflow.md`、架构、测试、发布流程。 +- 说明 GitNexus 是可选增强,缺失时按基础工作流继续。 + +### `docs/contributor/agent-workflow.md` + +作为共享基础规则的唯一权威来源: + +- 说明适用对象与目标。 +- 按阶段描述基础工作流:理解任务、评估影响、实施变更、验证结果、准备交付。 +- 写清本仓库特有的高优先级约束。 +- 保留文档与 PR 规范。 +- 用工具无关语言表达必做事项。 + +### `docs/contributor/gitnexus-optional.md` + +作为 GitNexus 增强说明: + +- 说明何时使用 GitNexus。 +- 把基础工作流步骤映射到 GitNexus 工具能力。 +- 提供索引新鲜度与常用命令建议。 +- 明确声明:GitNexus 缺失不阻塞常规开发。 + +## 关键措辞改造 + +需要将现有“工具绑定型强约束”改为“目标强制、工具可选”的表达。 + +### 旧表达 + +- MUST run `gitnexus_impact` before editing any symbol. +- MUST run `gitnexus_detect_changes()` before committing. +- NEVER edit a function without GitNexus impact analysis. + +### 新表达 + +- 修改函数、类或方法前,必须评估影响面,检查直接调用方、导入方与受影响链路。 +- 若本地可用 GitNexus,优先使用 `gitnexus_impact`、`gitnexus_context` 等图谱工具完成该步骤。 +- 提交前必须确认变更范围与预期一致;若本地可用 GitNexus,`gitnexus_detect_changes()` 是推荐做法。 +- 重命名不要依赖盲目的仓库级文本替换;若本地可用 GitNexus,优先使用图谱感知重命名流程。 + +## 兼容性策略 + +### 无 GitNexus 的开发者 + +必须能仅依赖: + +- 阅读相关文件 +- 搜索调用点/导入点 +- 执行类型检查、lint、测试、docs 构建 +- 阅读架构与 workflow 文档 + +完成一次完整且合规的贡献流程。 + +### 有 GitNexus 的开发者 + +可在以下环节获得增强: + +- 初始理解仓库与执行流 +- 变更前影响评估 +- 重构与 rename 安全性提升 +- 提交前核对受影响范围 + +但这些增强不改变基础规则的存在与可执行性。 + +## 迁移步骤 + +1. 新增 `WORKFLOW.md`,提供仓库工作流摘要导航。 +2. 新增 `docs/contributor/agent-workflow.md`,承载共享基础规则。 +3. 新增 `docs/contributor/gitnexus-optional.md`,承载工具增强说明。 +4. 精简 `AGENTS.md`,移除长结构镜像、CODE MAP 与 GitNexus 详细手册,改为指向新文档。 +5. 精简 `CLAUDE.md`,保持与 `AGENTS.md` 同骨架,并仅增加少量 Claude Code 专属说明。 +6. 如有必要,在 contributor 入口页加入新文档链接。 +7. 运行 docs 构建验证站点链接与文档结构。 + +## 预期结果 + +- `AGENTS.md` 与 `CLAUDE.md` 长度显著下降。 +- 项目事实、基础规则、工具增强三类信息职责清晰。 +- 通用入口与 Claude 入口高度同步,但不再需要维护两份巨型手册。 +- GitNexus 从“主规则内嵌强依赖”转为“公开可选增强层”。 +- 仓库对未安装 GitNexus 的开发者更友好,同时保留 GitNexus 对熟悉仓库的加速价值。