mirror of
https://github.com/certd/certd.git
synced 2026-07-31 01:37:36 +08:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e0e0bb51ce | |||
| 1dc5a19c45 | |||
| 04aa9041e8 | |||
| 0d86c84b28 | |||
| 6605669113 | |||
| 4b8747b5da | |||
| 2ba4132c50 | |||
| 49dc2796cd | |||
| 1e07d69932 | |||
| aabf73a736 | |||
| c9be2293ab | |||
| 4662e45e58 | |||
| 1fefbdc9ab | |||
| 1cb2a57c55 | |||
| 246ee83015 | |||
| 335ddfc7a5 | |||
| 5b500830a1 | |||
| 5f53b81c75 | |||
| c8c269f612 | |||
| 743617dbda | |||
| 89806b828a | |||
| 2e530bfdb0 |
@@ -0,0 +1,133 @@
|
||||
```markdown
|
||||
# certd Development Patterns
|
||||
|
||||
> Auto-generated skill from repository analysis
|
||||
|
||||
## Overview
|
||||
|
||||
This skill teaches the core development patterns and workflows for the `certd` TypeScript codebase. It covers coding conventions, file organization, commit patterns, and detailed step-by-step instructions for extending user preferences—a common feature workflow. The repository is structured for modularity, with clear separation between UI and backend logic, and emphasizes maintainable, convention-driven development.
|
||||
|
||||
## Coding Conventions
|
||||
|
||||
### File Naming
|
||||
|
||||
- **CamelCase** is used for file names.
|
||||
- Example: `userPreferences.ts`, `preferencesDrawer.vue`
|
||||
|
||||
### Import Style
|
||||
|
||||
- **Absolute imports** are preferred.
|
||||
- Example:
|
||||
```typescript
|
||||
import { getUserPreferences } from 'packages/ui/certd-client/src/vben/layouts/widgets/preferences/api';
|
||||
```
|
||||
|
||||
### Export Style
|
||||
|
||||
- **Named exports** are used throughout the codebase.
|
||||
- Example:
|
||||
```typescript
|
||||
export function getUserPreferences() { ... }
|
||||
export const PREFERENCE_KEYS = [ ... ];
|
||||
```
|
||||
|
||||
### Commit Patterns
|
||||
|
||||
- **Conventional commits** are used, with the `feat` prefix for new features.
|
||||
- Example:
|
||||
```
|
||||
feat: add account sync to preferences
|
||||
```
|
||||
|
||||
## Workflows
|
||||
|
||||
### Extend Preferences Feature
|
||||
|
||||
**Trigger:** When someone wants to add or enhance a user preference feature (e.g., import/export, sync to account).
|
||||
**Command:** `/extend-preferences`
|
||||
|
||||
Follow these steps to extend user preferences functionality:
|
||||
|
||||
1. **Update localization files**
|
||||
Add or modify strings in:
|
||||
- `packages/ui/certd-client/src/locales/langs/en-US/preferences.ts`
|
||||
- `packages/ui/certd-client/src/locales/langs/zh-CN/preferences.ts`
|
||||
```typescript
|
||||
// en-US/preferences.ts
|
||||
export default {
|
||||
sync: "Sync Preferences",
|
||||
import: "Import Preferences",
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
2. **Modify or add Vue components for preferences UI**
|
||||
Update or create components such as:
|
||||
- `preferences-drawer.vue`
|
||||
- `account-sync.ts`
|
||||
```vue
|
||||
<!-- preferences-drawer.vue -->
|
||||
<template>
|
||||
<div>
|
||||
<button @click="syncPreferences">{{ $t('preferences.sync') }}</button>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
3. **Update or add supporting icon definitions**
|
||||
Edit:
|
||||
- `packages/ui/certd-client/src/vben/icons/lucide.ts`
|
||||
```typescript
|
||||
export const SyncIcon = { /* icon definition */ };
|
||||
```
|
||||
|
||||
4. **Implement or update store logic for settings**
|
||||
Update:
|
||||
- `packages/ui/certd-client/src/store/settings/index.tsx`
|
||||
```typescript
|
||||
export function syncPreferencesToAccount() { ... }
|
||||
```
|
||||
|
||||
5. **Add or update backend API/controller for user preferences**
|
||||
Edit or add:
|
||||
- `packages/ui/certd-client/src/vben/layouts/widgets/preferences/api.ts`
|
||||
- `packages/ui/certd-server/src/controller/user/mine/user-preferences.ts`
|
||||
```typescript
|
||||
// user-preferences.ts
|
||||
export async function updateUserPreferences(req, res) { ... }
|
||||
```
|
||||
|
||||
6. **Write or update backend tests for new preference logic**
|
||||
Add or update:
|
||||
- `packages/ui/certd-server/src/controller/user/mine/user-preferences.test.ts`
|
||||
```typescript
|
||||
test('should sync preferences', async () => { ... });
|
||||
```
|
||||
|
||||
7. **Update backend models if necessary**
|
||||
Edit:
|
||||
- `packages/ui/certd-server/src/modules/mine/service/models.ts`
|
||||
```typescript
|
||||
export interface UserPreferences { ... }
|
||||
```
|
||||
|
||||
## Testing Patterns
|
||||
|
||||
- **Test files** follow the `*.test.*` naming convention.
|
||||
- Example: `user-preferences.test.ts`
|
||||
- **Testing framework** is not explicitly detected, but tests are written in TypeScript and likely use a standard Node.js testing library (e.g., Jest or Mocha).
|
||||
- **Test Example:**
|
||||
```typescript
|
||||
test('should update preferences', async () => {
|
||||
// Arrange
|
||||
// Act
|
||||
// Assert
|
||||
});
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Purpose |
|
||||
|----------------------|--------------------------------------------------------------|
|
||||
| /extend-preferences | Guide to extend or enhance user preference functionality |
|
||||
```
|
||||
@@ -0,0 +1,6 @@
|
||||
interface:
|
||||
display_name: "Certd"
|
||||
short_description: "Repo-specific patterns and workflows for certd"
|
||||
default_prompt: "Use the certd repo skill to follow existing architecture, testing, and workflow conventions."
|
||||
policy:
|
||||
allow_implicit_invocation: true
|
||||
@@ -0,0 +1,227 @@
|
||||
{
|
||||
"version": "1.3",
|
||||
"schemaVersion": "1.0",
|
||||
"generatedBy": "ecc-tools",
|
||||
"generatedAt": "2026-07-30T02:07:44.046Z",
|
||||
"repo": "https://github.com/certd/certd",
|
||||
"referenceSetReadiness": {
|
||||
"score": 0,
|
||||
"present": 0,
|
||||
"total": 7,
|
||||
"items": [
|
||||
{
|
||||
"id": "deep-analyzer-corpus",
|
||||
"label": "Deep analyzer corpus",
|
||||
"status": "missing",
|
||||
"evidence": [],
|
||||
"recommendation": "Add analyzer fixture, golden, benchmark, or reference-set files that can catch analyzer regressions."
|
||||
},
|
||||
{
|
||||
"id": "rag-evaluator",
|
||||
"label": "RAG/evaluator comparison",
|
||||
"status": "missing",
|
||||
"evidence": [],
|
||||
"recommendation": "Add retrieval or evaluator reference-set comparison fixtures with expected ranking behavior."
|
||||
},
|
||||
{
|
||||
"id": "pr-salvage",
|
||||
"label": "PR salvage/review corpus",
|
||||
"status": "missing",
|
||||
"evidence": [],
|
||||
"recommendation": "Add stale-PR, review-thread, reopen-flow, or salvage reference cases for queue cleanup automation."
|
||||
},
|
||||
{
|
||||
"id": "discussion-triage",
|
||||
"label": "Discussion triage corpus",
|
||||
"status": "missing",
|
||||
"evidence": [],
|
||||
"recommendation": "Add public discussion triage fixtures, golden cases, or reference sets for informational, answered, and no-response classifications."
|
||||
},
|
||||
{
|
||||
"id": "harness-compatibility",
|
||||
"label": "Harness compatibility",
|
||||
"status": "missing",
|
||||
"evidence": [],
|
||||
"recommendation": "Add cross-harness, adapter-compliance, or harness-audit evidence for Claude, Codex, OpenCode, Zed, dmux, and agent surfaces."
|
||||
},
|
||||
{
|
||||
"id": "security-evidence",
|
||||
"label": "Security evidence",
|
||||
"status": "missing",
|
||||
"evidence": [],
|
||||
"recommendation": "Attach security evidence such as SBOMs, SARIF, audit reports, or AgentShield evidence packs."
|
||||
},
|
||||
{
|
||||
"id": "ci-failure-mode",
|
||||
"label": "CI failure-mode evidence",
|
||||
"status": "missing",
|
||||
"evidence": [],
|
||||
"recommendation": "Add captured CI failure logs, dry-run fixtures, or troubleshooting docs for common workflow failure modes."
|
||||
}
|
||||
]
|
||||
},
|
||||
"profiles": {
|
||||
"requested": "core",
|
||||
"recommended": "core",
|
||||
"effective": "core",
|
||||
"requestedAlias": "core",
|
||||
"recommendedAlias": "core",
|
||||
"effectiveAlias": "core"
|
||||
},
|
||||
"requestedProfile": "core",
|
||||
"profile": "core",
|
||||
"recommendedProfile": "core",
|
||||
"effectiveProfile": "core",
|
||||
"tier": "free",
|
||||
"requestedComponents": [
|
||||
"repo-baseline"
|
||||
],
|
||||
"selectedComponents": [
|
||||
"repo-baseline"
|
||||
],
|
||||
"requestedAddComponents": [],
|
||||
"requestedRemoveComponents": [],
|
||||
"blockedRemovalComponents": [],
|
||||
"tierFilteredComponents": [],
|
||||
"requestedRootPackages": [
|
||||
"runtime-core"
|
||||
],
|
||||
"selectedRootPackages": [
|
||||
"runtime-core"
|
||||
],
|
||||
"requestedPackages": [
|
||||
"runtime-core"
|
||||
],
|
||||
"requestedAddPackages": [],
|
||||
"requestedRemovePackages": [],
|
||||
"selectedPackages": [
|
||||
"runtime-core"
|
||||
],
|
||||
"packages": [
|
||||
"runtime-core"
|
||||
],
|
||||
"blockedRemovalPackages": [],
|
||||
"tierFilteredRootPackages": [],
|
||||
"tierFilteredPackages": [],
|
||||
"conflictingPackages": [],
|
||||
"dependencyGraph": {
|
||||
"runtime-core": []
|
||||
},
|
||||
"resolutionOrder": [
|
||||
"runtime-core"
|
||||
],
|
||||
"requestedModules": [
|
||||
"runtime-core"
|
||||
],
|
||||
"selectedModules": [
|
||||
"runtime-core"
|
||||
],
|
||||
"modules": [
|
||||
"runtime-core"
|
||||
],
|
||||
"managedFiles": [
|
||||
".claude/skills/certd/SKILL.md",
|
||||
".agents/skills/certd/SKILL.md",
|
||||
".agents/skills/certd/agents/openai.yaml",
|
||||
".claude/identity.json",
|
||||
".codex/config.toml",
|
||||
".codex/AGENTS.md",
|
||||
".codex/agents/explorer.toml",
|
||||
".codex/agents/reviewer.toml",
|
||||
".codex/agents/docs-researcher.toml",
|
||||
".claude/homunculus/instincts/inherited/certd-instincts.yaml"
|
||||
],
|
||||
"packageFiles": {
|
||||
"runtime-core": [
|
||||
".claude/skills/certd/SKILL.md",
|
||||
".agents/skills/certd/SKILL.md",
|
||||
".agents/skills/certd/agents/openai.yaml",
|
||||
".claude/identity.json",
|
||||
".codex/config.toml",
|
||||
".codex/AGENTS.md",
|
||||
".codex/agents/explorer.toml",
|
||||
".codex/agents/reviewer.toml",
|
||||
".codex/agents/docs-researcher.toml",
|
||||
".claude/homunculus/instincts/inherited/certd-instincts.yaml"
|
||||
]
|
||||
},
|
||||
"moduleFiles": {
|
||||
"runtime-core": [
|
||||
".claude/skills/certd/SKILL.md",
|
||||
".agents/skills/certd/SKILL.md",
|
||||
".agents/skills/certd/agents/openai.yaml",
|
||||
".claude/identity.json",
|
||||
".codex/config.toml",
|
||||
".codex/AGENTS.md",
|
||||
".codex/agents/explorer.toml",
|
||||
".codex/agents/reviewer.toml",
|
||||
".codex/agents/docs-researcher.toml",
|
||||
".claude/homunculus/instincts/inherited/certd-instincts.yaml"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
{
|
||||
"moduleId": "runtime-core",
|
||||
"path": ".claude/skills/certd/SKILL.md",
|
||||
"description": "Repository-specific Claude Code skill generated from git history."
|
||||
},
|
||||
{
|
||||
"moduleId": "runtime-core",
|
||||
"path": ".agents/skills/certd/SKILL.md",
|
||||
"description": "Codex-facing copy of the generated repository skill."
|
||||
},
|
||||
{
|
||||
"moduleId": "runtime-core",
|
||||
"path": ".agents/skills/certd/agents/openai.yaml",
|
||||
"description": "Codex skill metadata so the repo skill appears cleanly in the skill interface."
|
||||
},
|
||||
{
|
||||
"moduleId": "runtime-core",
|
||||
"path": ".claude/identity.json",
|
||||
"description": "Suggested identity.json baseline derived from repository conventions."
|
||||
},
|
||||
{
|
||||
"moduleId": "runtime-core",
|
||||
"path": ".codex/config.toml",
|
||||
"description": "Repo-local Codex MCP and multi-agent baseline aligned with ECC defaults."
|
||||
},
|
||||
{
|
||||
"moduleId": "runtime-core",
|
||||
"path": ".codex/AGENTS.md",
|
||||
"description": "Codex usage guide that points at the generated repo skill and workflow bundle."
|
||||
},
|
||||
{
|
||||
"moduleId": "runtime-core",
|
||||
"path": ".codex/agents/explorer.toml",
|
||||
"description": "Read-only explorer role config for Codex multi-agent work."
|
||||
},
|
||||
{
|
||||
"moduleId": "runtime-core",
|
||||
"path": ".codex/agents/reviewer.toml",
|
||||
"description": "Read-only reviewer role config focused on correctness and security."
|
||||
},
|
||||
{
|
||||
"moduleId": "runtime-core",
|
||||
"path": ".codex/agents/docs-researcher.toml",
|
||||
"description": "Read-only docs researcher role config for API verification."
|
||||
},
|
||||
{
|
||||
"moduleId": "runtime-core",
|
||||
"path": ".claude/homunculus/instincts/inherited/certd-instincts.yaml",
|
||||
"description": "Continuous-learning instincts derived from repository patterns."
|
||||
}
|
||||
],
|
||||
"workflows": [],
|
||||
"adapters": {
|
||||
"claudeCode": {
|
||||
"skillPath": ".claude/skills/certd/SKILL.md",
|
||||
"identityPath": ".claude/identity.json",
|
||||
"commandPaths": []
|
||||
},
|
||||
"codex": {
|
||||
"configPath": ".codex/config.toml",
|
||||
"agentsGuidePath": ".codex/AGENTS.md",
|
||||
"skillPath": ".agents/skills/certd/SKILL.md"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,486 @@
|
||||
# Instincts generated from https://github.com/certd/certd
|
||||
# Generated: 2026-07-30T02:08:05.402Z
|
||||
# Version: 2.0
|
||||
# NOTE: This file supplements (does not replace) any existing curated instincts.
|
||||
# High-confidence manually curated instincts should be preserved alongside these.
|
||||
|
||||
---
|
||||
id: certd-commit-conventional
|
||||
trigger: "when writing a commit message"
|
||||
confidence: 0.85
|
||||
domain: git
|
||||
source: repo-analysis
|
||||
source_repo: https://github.com/certd/certd
|
||||
---
|
||||
|
||||
# Certd Commit Conventional
|
||||
|
||||
## Action
|
||||
|
||||
Use conventional commit format with prefixes: feat
|
||||
|
||||
## Evidence
|
||||
|
||||
- 2 commits analyzed
|
||||
- Detected conventional commit pattern
|
||||
- Examples: feat: 偏好设置支持从剪切板导入, feat: 偏好设置支持保存到账号并在登录后自动同步
|
||||
|
||||
---
|
||||
id: certd-commit-length
|
||||
trigger: "when writing a commit message"
|
||||
confidence: 0.6
|
||||
domain: git
|
||||
source: repo-analysis
|
||||
source_repo: https://github.com/certd/certd
|
||||
---
|
||||
|
||||
# Certd Commit Length
|
||||
|
||||
## Action
|
||||
|
||||
Keep commit messages concise (~22 characters)
|
||||
|
||||
## Evidence
|
||||
|
||||
- Average commit message length: 22 chars
|
||||
- Based on 2 commits
|
||||
|
||||
---
|
||||
id: certd-naming-files
|
||||
trigger: "when creating a new file"
|
||||
confidence: 0.8
|
||||
domain: code-style
|
||||
source: repo-analysis
|
||||
source_repo: https://github.com/certd/certd
|
||||
---
|
||||
|
||||
# Certd Naming Files
|
||||
|
||||
## Action
|
||||
|
||||
Use camelCase naming convention
|
||||
|
||||
## Evidence
|
||||
|
||||
- Analyzed file naming patterns in repository
|
||||
- Dominant pattern: camelCase
|
||||
|
||||
---
|
||||
id: certd-export-style
|
||||
trigger: "when exporting from a module"
|
||||
confidence: 0.7
|
||||
domain: code-style
|
||||
source: repo-analysis
|
||||
source_repo: https://github.com/certd/certd
|
||||
---
|
||||
|
||||
# Certd Export Style
|
||||
|
||||
## Action
|
||||
|
||||
Prefer named exports
|
||||
|
||||
## Evidence
|
||||
|
||||
- Export pattern analysis
|
||||
- Dominant style: named
|
||||
|
||||
---
|
||||
id: certd-arch-feature-based
|
||||
trigger: "when adding a new feature"
|
||||
confidence: 0.85
|
||||
domain: architecture
|
||||
source: repo-analysis
|
||||
source_repo: https://github.com/certd/certd
|
||||
---
|
||||
|
||||
# Certd Arch Feature Based
|
||||
|
||||
## Action
|
||||
|
||||
Create a new folder in src/features/ with all related code colocated
|
||||
|
||||
## Evidence
|
||||
|
||||
- Feature-based module organization detected
|
||||
- Structure: src/features/[feature-name]/
|
||||
|
||||
---
|
||||
id: certd-workflow-extend-preferences-feature
|
||||
trigger: "when doing extend preferences feature"
|
||||
confidence: 0.6
|
||||
domain: workflow
|
||||
source: repo-analysis
|
||||
source_repo: https://github.com/certd/certd
|
||||
---
|
||||
|
||||
# Certd Workflow Extend Preferences Feature
|
||||
|
||||
## Action
|
||||
|
||||
Follow the extend-preferences-feature workflow:
|
||||
1. Update localization files for new preference-related strings
|
||||
2. Modify or add Vue components for preferences UI
|
||||
3. Update or add supporting icon definitions
|
||||
4. Implement or update store logic for settings
|
||||
5. Add or update backend API/controller for user preferences
|
||||
6. Write or update backend tests for new preference logic
|
||||
7. Update backend models if necessary
|
||||
|
||||
## Evidence
|
||||
|
||||
- Workflow detected from commit patterns
|
||||
- Frequency: ~2x per month
|
||||
- Files: packages/ui/certd-client/src/locales/langs/en-US/preferences.ts, packages/ui/certd-client/src/locales/langs/zh-CN/preferences.ts, packages/ui/certd-client/src/vben/layouts/widgets/preferences/preferences-drawer.vue
|
||||
|
||||
---
|
||||
id: certd-instinct-file-naming
|
||||
trigger: "When creating a new file in the codebase"
|
||||
confidence: 0.9
|
||||
domain: code-style
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct File Naming
|
||||
|
||||
## Action
|
||||
|
||||
Name the file using camelCase
|
||||
|
||||
## Evidence
|
||||
|
||||
- Pattern in codeStyle.namingConventions.files
|
||||
|
||||
---
|
||||
id: certd-instinct-function-naming
|
||||
trigger: "When defining a new function"
|
||||
confidence: 0.9
|
||||
domain: code-style
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Function Naming
|
||||
|
||||
## Action
|
||||
|
||||
Use camelCase for function names
|
||||
|
||||
## Evidence
|
||||
|
||||
- Pattern in codeStyle.namingConventions.functions
|
||||
|
||||
---
|
||||
id: certd-instinct-class-naming
|
||||
trigger: "When defining a new class"
|
||||
confidence: 0.9
|
||||
domain: code-style
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Class Naming
|
||||
|
||||
## Action
|
||||
|
||||
Use PascalCase for class names
|
||||
|
||||
## Evidence
|
||||
|
||||
- Pattern in codeStyle.namingConventions.classes
|
||||
|
||||
---
|
||||
id: certd-instinct-constant-naming
|
||||
trigger: "When declaring a constant"
|
||||
confidence: 0.9
|
||||
domain: code-style
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Constant Naming
|
||||
|
||||
## Action
|
||||
|
||||
Use SCREAMING_SNAKE_CASE for constant names
|
||||
|
||||
## Evidence
|
||||
|
||||
- Pattern in codeStyle.namingConventions.constants
|
||||
|
||||
---
|
||||
id: certd-instinct-import-style
|
||||
trigger: "When importing modules"
|
||||
confidence: 0.8
|
||||
domain: code-style
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Import Style
|
||||
|
||||
## Action
|
||||
|
||||
Use absolute import paths
|
||||
|
||||
## Evidence
|
||||
|
||||
- Pattern in codeStyle.importStyle
|
||||
|
||||
---
|
||||
id: certd-instinct-export-style
|
||||
trigger: "When exporting from a module"
|
||||
confidence: 0.8
|
||||
domain: code-style
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Export Style
|
||||
|
||||
## Action
|
||||
|
||||
Use named exports
|
||||
|
||||
## Evidence
|
||||
|
||||
- Pattern in codeStyle.exportStyle
|
||||
|
||||
---
|
||||
id: certd-instinct-try-catch
|
||||
trigger: "When handling errors in code"
|
||||
confidence: 0.8
|
||||
domain: code-style
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Try Catch
|
||||
|
||||
## Action
|
||||
|
||||
Use try-catch blocks for error handling
|
||||
|
||||
## Evidence
|
||||
|
||||
- Pattern in errorHandling.style
|
||||
|
||||
---
|
||||
id: certd-instinct-test-location
|
||||
trigger: "When adding or updating tests"
|
||||
confidence: 0.7
|
||||
domain: testing
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Test Location
|
||||
|
||||
## Action
|
||||
|
||||
Place tests in both source and test-specific folders as appropriate (mixed location)
|
||||
|
||||
## Evidence
|
||||
|
||||
- Pattern in architecture.folderStructure.testLocation
|
||||
- Seen in files like packages/ui/certd-server/src/controller/user/mine/user-preferences.test.ts
|
||||
|
||||
---
|
||||
id: certd-instinct-backend-test-pattern
|
||||
trigger: "When adding backend logic for user preferences"
|
||||
confidence: 0.8
|
||||
domain: testing
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Backend Test Pattern
|
||||
|
||||
## Action
|
||||
|
||||
Create or update a corresponding .test.ts file in the same directory
|
||||
|
||||
## Evidence
|
||||
|
||||
- Seen in packages/ui/certd-server/src/controller/user/mine/user-preferences.test.ts
|
||||
|
||||
---
|
||||
id: certd-instinct-conventional-commits
|
||||
trigger: "When writing a commit message"
|
||||
confidence: 0.9
|
||||
domain: git
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Conventional Commits
|
||||
|
||||
## Action
|
||||
|
||||
Use the conventional commit format with a type prefix (e.g., feat: ...)
|
||||
|
||||
## Evidence
|
||||
|
||||
- Pattern in commits.type
|
||||
- Examples: feat: 偏好设置支持从剪切板导入
|
||||
|
||||
---
|
||||
id: certd-instinct-commit-length
|
||||
trigger: "When writing a commit message"
|
||||
confidence: 0.7
|
||||
domain: git
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Commit Length
|
||||
|
||||
## Action
|
||||
|
||||
Keep the commit message concise, around 22 characters on average
|
||||
|
||||
## Evidence
|
||||
|
||||
- Pattern in commits.averageLength
|
||||
|
||||
---
|
||||
id: certd-instinct-extend-preferences-localization
|
||||
trigger: "When extending or adding a user preference feature"
|
||||
confidence: 0.9
|
||||
domain: workflow
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Extend Preferences Localization
|
||||
|
||||
## Action
|
||||
|
||||
Update localization files for new preference-related strings
|
||||
|
||||
## Evidence
|
||||
|
||||
- Workflow: extend-preferences-feature
|
||||
- Files: packages/ui/certd-client/src/locales/langs/en-US/preferences.ts, packages/ui/certd-client/src/locales/langs/zh-CN/preferences.ts
|
||||
|
||||
---
|
||||
id: certd-instinct-extend-preferences-ui
|
||||
trigger: "When extending or adding a user preference feature"
|
||||
confidence: 0.9
|
||||
domain: workflow
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Extend Preferences Ui
|
||||
|
||||
## Action
|
||||
|
||||
Modify or add Vue components for the preferences UI
|
||||
|
||||
## Evidence
|
||||
|
||||
- Workflow: extend-preferences-feature
|
||||
- Files: packages/ui/certd-client/src/vben/layouts/widgets/preferences/preferences-drawer.vue
|
||||
|
||||
---
|
||||
id: certd-instinct-extend-preferences-icons
|
||||
trigger: "When extending or adding a user preference feature"
|
||||
confidence: 0.8
|
||||
domain: workflow
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Extend Preferences Icons
|
||||
|
||||
## Action
|
||||
|
||||
Update or add supporting icon definitions
|
||||
|
||||
## Evidence
|
||||
|
||||
- Workflow: extend-preferences-feature
|
||||
- File: packages/ui/certd-client/src/vben/icons/lucide.ts
|
||||
|
||||
---
|
||||
id: certd-instinct-extend-preferences-store
|
||||
trigger: "When extending or adding a user preference feature"
|
||||
confidence: 0.9
|
||||
domain: workflow
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Extend Preferences Store
|
||||
|
||||
## Action
|
||||
|
||||
Implement or update store logic for settings
|
||||
|
||||
## Evidence
|
||||
|
||||
- Workflow: extend-preferences-feature
|
||||
- File: packages/ui/certd-client/src/store/settings/index.tsx
|
||||
|
||||
---
|
||||
id: certd-instinct-extend-preferences-backend-api
|
||||
trigger: "When extending or adding a user preference feature"
|
||||
confidence: 0.9
|
||||
domain: workflow
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Extend Preferences Backend Api
|
||||
|
||||
## Action
|
||||
|
||||
Add or update backend API/controller for user preferences
|
||||
|
||||
## Evidence
|
||||
|
||||
- Workflow: extend-preferences-feature
|
||||
- Files: packages/ui/certd-server/src/controller/user/mine/user-preferences.ts, packages/ui/certd-server/src/controller/user/mine/user-settings-controller.ts
|
||||
|
||||
---
|
||||
id: certd-instinct-extend-preferences-backend-test
|
||||
trigger: "When extending or adding a user preference feature"
|
||||
confidence: 0.9
|
||||
domain: workflow
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Extend Preferences Backend Test
|
||||
|
||||
## Action
|
||||
|
||||
Write or update backend tests for new preference logic
|
||||
|
||||
## Evidence
|
||||
|
||||
- Workflow: extend-preferences-feature
|
||||
- File: packages/ui/certd-server/src/controller/user/mine/user-preferences.test.ts
|
||||
|
||||
---
|
||||
id: certd-instinct-extend-preferences-models
|
||||
trigger: "When extending or adding a user preference feature and new data is needed"
|
||||
confidence: 0.8
|
||||
domain: workflow
|
||||
source: repo-analysis
|
||||
source_repo: certd/certd
|
||||
---
|
||||
|
||||
# Certd Instinct Extend Preferences Models
|
||||
|
||||
## Action
|
||||
|
||||
Update backend models if necessary
|
||||
|
||||
## Evidence
|
||||
|
||||
- Workflow: extend-preferences-feature
|
||||
- File: packages/ui/certd-server/src/modules/mine/service/models.ts
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"version": "2.0",
|
||||
"technicalLevel": "technical",
|
||||
"preferredStyle": {
|
||||
"verbosity": "detailed",
|
||||
"codeComments": true,
|
||||
"explanations": true
|
||||
},
|
||||
"domains": [
|
||||
"typescript"
|
||||
],
|
||||
"suggestedBy": "ecc-tools-repo-analysis",
|
||||
"createdAt": "2026-07-30T02:08:05.402Z"
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
```markdown
|
||||
# certd Development Patterns
|
||||
|
||||
> Auto-generated skill from repository analysis
|
||||
|
||||
## Overview
|
||||
|
||||
This skill teaches the core development patterns and workflows for the `certd` TypeScript codebase. It covers coding conventions, file organization, commit patterns, and detailed step-by-step instructions for extending user preferences—a common feature workflow. The repository is structured for modularity, with clear separation between UI and backend logic, and emphasizes maintainable, convention-driven development.
|
||||
|
||||
## Coding Conventions
|
||||
|
||||
### File Naming
|
||||
|
||||
- **CamelCase** is used for file names.
|
||||
- Example: `userPreferences.ts`, `preferencesDrawer.vue`
|
||||
|
||||
### Import Style
|
||||
|
||||
- **Absolute imports** are preferred.
|
||||
- Example:
|
||||
```typescript
|
||||
import { getUserPreferences } from 'packages/ui/certd-client/src/vben/layouts/widgets/preferences/api';
|
||||
```
|
||||
|
||||
### Export Style
|
||||
|
||||
- **Named exports** are used throughout the codebase.
|
||||
- Example:
|
||||
```typescript
|
||||
export function getUserPreferences() { ... }
|
||||
export const PREFERENCE_KEYS = [ ... ];
|
||||
```
|
||||
|
||||
### Commit Patterns
|
||||
|
||||
- **Conventional commits** are used, with the `feat` prefix for new features.
|
||||
- Example:
|
||||
```
|
||||
feat: add account sync to preferences
|
||||
```
|
||||
|
||||
## Workflows
|
||||
|
||||
### Extend Preferences Feature
|
||||
|
||||
**Trigger:** When someone wants to add or enhance a user preference feature (e.g., import/export, sync to account).
|
||||
**Command:** `/extend-preferences`
|
||||
|
||||
Follow these steps to extend user preferences functionality:
|
||||
|
||||
1. **Update localization files**
|
||||
Add or modify strings in:
|
||||
- `packages/ui/certd-client/src/locales/langs/en-US/preferences.ts`
|
||||
- `packages/ui/certd-client/src/locales/langs/zh-CN/preferences.ts`
|
||||
```typescript
|
||||
// en-US/preferences.ts
|
||||
export default {
|
||||
sync: "Sync Preferences",
|
||||
import: "Import Preferences",
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
2. **Modify or add Vue components for preferences UI**
|
||||
Update or create components such as:
|
||||
- `preferences-drawer.vue`
|
||||
- `account-sync.ts`
|
||||
```vue
|
||||
<!-- preferences-drawer.vue -->
|
||||
<template>
|
||||
<div>
|
||||
<button @click="syncPreferences">{{ $t('preferences.sync') }}</button>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
3. **Update or add supporting icon definitions**
|
||||
Edit:
|
||||
- `packages/ui/certd-client/src/vben/icons/lucide.ts`
|
||||
```typescript
|
||||
export const SyncIcon = { /* icon definition */ };
|
||||
```
|
||||
|
||||
4. **Implement or update store logic for settings**
|
||||
Update:
|
||||
- `packages/ui/certd-client/src/store/settings/index.tsx`
|
||||
```typescript
|
||||
export function syncPreferencesToAccount() { ... }
|
||||
```
|
||||
|
||||
5. **Add or update backend API/controller for user preferences**
|
||||
Edit or add:
|
||||
- `packages/ui/certd-client/src/vben/layouts/widgets/preferences/api.ts`
|
||||
- `packages/ui/certd-server/src/controller/user/mine/user-preferences.ts`
|
||||
```typescript
|
||||
// user-preferences.ts
|
||||
export async function updateUserPreferences(req, res) { ... }
|
||||
```
|
||||
|
||||
6. **Write or update backend tests for new preference logic**
|
||||
Add or update:
|
||||
- `packages/ui/certd-server/src/controller/user/mine/user-preferences.test.ts`
|
||||
```typescript
|
||||
test('should sync preferences', async () => { ... });
|
||||
```
|
||||
|
||||
7. **Update backend models if necessary**
|
||||
Edit:
|
||||
- `packages/ui/certd-server/src/modules/mine/service/models.ts`
|
||||
```typescript
|
||||
export interface UserPreferences { ... }
|
||||
```
|
||||
|
||||
## Testing Patterns
|
||||
|
||||
- **Test files** follow the `*.test.*` naming convention.
|
||||
- Example: `user-preferences.test.ts`
|
||||
- **Testing framework** is not explicitly detected, but tests are written in TypeScript and likely use a standard Node.js testing library (e.g., Jest or Mocha).
|
||||
- **Test Example:**
|
||||
```typescript
|
||||
test('should update preferences', async () => {
|
||||
// Arrange
|
||||
// Act
|
||||
// Assert
|
||||
});
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Purpose |
|
||||
|----------------------|--------------------------------------------------------------|
|
||||
| /extend-preferences | Guide to extend or enhance user preference functionality |
|
||||
```
|
||||
@@ -0,0 +1,26 @@
|
||||
# ECC for Codex CLI
|
||||
|
||||
This supplements the root `AGENTS.md` with a repo-local ECC baseline.
|
||||
|
||||
## Repo Skill
|
||||
|
||||
- Repo-generated Codex skill: `.agents/skills/certd/SKILL.md`
|
||||
- Claude-facing companion skill: `.claude/skills/certd/SKILL.md`
|
||||
- Keep user-specific credentials and private MCPs in `~/.codex/config.toml`, not in this repo.
|
||||
|
||||
## MCP Baseline
|
||||
|
||||
Treat `.codex/config.toml` as the default ECC-safe baseline for work in this repository.
|
||||
The generated baseline enables GitHub, Context7, Exa, Memory, Playwright, and Sequential Thinking.
|
||||
|
||||
## Multi-Agent Support
|
||||
|
||||
- Explorer: read-only evidence gathering
|
||||
- Reviewer: correctness, security, and regression review
|
||||
- Docs researcher: API and release-note verification
|
||||
|
||||
## Workflow Files
|
||||
|
||||
- No dedicated workflow command files were generated for this repo.
|
||||
|
||||
Use these workflow files as reusable task scaffolds when the detected repository workflows recur.
|
||||
@@ -0,0 +1,9 @@
|
||||
model = "gpt-5.4"
|
||||
model_reasoning_effort = "medium"
|
||||
sandbox_mode = "read-only"
|
||||
|
||||
developer_instructions = """
|
||||
Verify APIs, framework behavior, and release-note claims against primary documentation before changes land.
|
||||
Cite the exact docs or file paths that support each claim.
|
||||
Do not invent undocumented behavior.
|
||||
"""
|
||||
@@ -0,0 +1,9 @@
|
||||
model = "gpt-5.4"
|
||||
model_reasoning_effort = "medium"
|
||||
sandbox_mode = "read-only"
|
||||
|
||||
developer_instructions = """
|
||||
Stay in exploration mode.
|
||||
Trace the real execution path, cite files and symbols, and avoid proposing fixes unless the parent agent asks for them.
|
||||
Prefer targeted search and file reads over broad scans.
|
||||
"""
|
||||
@@ -0,0 +1,9 @@
|
||||
model = "gpt-5.4"
|
||||
model_reasoning_effort = "high"
|
||||
sandbox_mode = "read-only"
|
||||
|
||||
developer_instructions = """
|
||||
Review like an owner.
|
||||
Prioritize correctness, security, behavioral regressions, and missing tests.
|
||||
Lead with concrete findings and avoid style-only feedback unless it hides a real bug.
|
||||
"""
|
||||
@@ -0,0 +1,48 @@
|
||||
#:schema https://developers.openai.com/codex/config-schema.json
|
||||
|
||||
# ECC Tools generated Codex baseline
|
||||
approval_policy = "on-request"
|
||||
sandbox_mode = "workspace-write"
|
||||
web_search = "live"
|
||||
|
||||
[mcp_servers.github]
|
||||
command = "npx"
|
||||
args = ["-y", "@modelcontextprotocol/server-github"]
|
||||
|
||||
[mcp_servers.context7]
|
||||
command = "npx"
|
||||
args = ["-y", "@upstash/context7-mcp@latest"]
|
||||
|
||||
[mcp_servers.exa]
|
||||
url = "https://mcp.exa.ai/mcp"
|
||||
|
||||
[mcp_servers.memory]
|
||||
command = "npx"
|
||||
args = ["-y", "@modelcontextprotocol/server-memory"]
|
||||
|
||||
[mcp_servers.playwright]
|
||||
command = "npx"
|
||||
args = ["-y", "@playwright/mcp@latest", "--extension"]
|
||||
|
||||
[mcp_servers.sequential-thinking]
|
||||
command = "npx"
|
||||
args = ["-y", "@modelcontextprotocol/server-sequential-thinking"]
|
||||
|
||||
[features]
|
||||
multi_agent = true
|
||||
|
||||
[agents]
|
||||
max_threads = 6
|
||||
max_depth = 1
|
||||
|
||||
[agents.explorer]
|
||||
description = "Read-only codebase explorer for gathering evidence before changes are proposed."
|
||||
config_file = "agents/explorer.toml"
|
||||
|
||||
[agents.reviewer]
|
||||
description = "PR reviewer focused on correctness, security, and missing tests."
|
||||
config_file = "agents/reviewer.toml"
|
||||
|
||||
[agents.docs_researcher]
|
||||
description = "Documentation specialist that verifies APIs, framework behavior, and release notes."
|
||||
config_file = "agents/docs-researcher.toml"
|
||||
@@ -70,6 +70,8 @@ Certd 是可私有化部署的 SSL/TLS 证书自动化管理平台,提供 Web
|
||||
- 先读本文,再按任务读取具体代码或技能文件。
|
||||
- PowerShell 读取中文、Markdown、locale、文档类文件时使用 `Get-Content -Raw -Encoding UTF8`;仍乱码时先执行 `[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()`。
|
||||
- PowerShell 中用 `rg` 搜索含引号、括号、反斜杠的 pattern 时,优先用单引号包裹整个 pattern,例如 `rg 'await import\("tencentcloud-sdk-nodejs' packages/ui/certd-server/src -g '*.ts'`。
|
||||
- 手工编辑或创建文件时优先使用 `apply_patch`。单个文件内有多处不连续改动时,拆成多个独立的 `*** Update File` 块,每块只改一处附近上下文;不要在同一个 update hunk 里强塞多个 `@@`。
|
||||
- 只有真正机械化的大批量替换、格式化或生成任务才考虑脚本/工具。若必须使用临时脚本,应放在临时目录并在同一个受控步骤内完成创建、执行、删除;不要把临时脚本落在仓库里跨多步工具调用执行。
|
||||
- 不要主动运行 `pnpm install`;缺依赖、TTY、网络导致安装或测试失败时,停止尝试并说明环境问题。
|
||||
- 优先沿用现有模块、插件、service、页面模式;不要为形式上的复用制造过度抽象。
|
||||
- 代码可读性优先于短写法。复杂条件、三元表达式、链式调用、内联对象和多层 helper 调用要拆成命名清晰的中间变量或小方法。
|
||||
@@ -210,8 +212,8 @@ Certd 是可私有化部署的 SSL/TLS 证书自动化管理平台,提供 Web
|
||||
- 后端业务数据、接口、实体、权限、迁移:改 `packages/ui/certd-server/src/modules` 与 `src/controller`。
|
||||
- 表单、列表、插件配置 UI:改 `packages/ui/certd-client/src/views/certd` 及对应 `src/api`。
|
||||
|
||||
## 注意事项
|
||||
## 其他注意事项
|
||||
|
||||
### 旧版数据兼容
|
||||
|
||||
- 新增插件参数时,必须要考虑旧版数据兼容,比如新增一个deployType参数,有两种值:`default`和`custom`,需要在使用时判空,走旧版逻辑。
|
||||
- 新增插件参数时,必须要考虑旧版数据兼容,比如新增一个deployType参数,有两种值:`default`和`custom`,需要在使用时判空,走旧版逻辑。
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.42.6](https://github.com/certd/certd/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复正常批量删除流水线报权限不足的bug ([5b50083](https://github.com/certd/certd/commit/5b500830a122c6c42dab054e57fed509050f94da))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化动态加载依赖镜像地址,多次重试 ([5f53b81](https://github.com/certd/certd/commit/5f53b81c75dd242b4260ac08cae14c6d1a08a883))
|
||||
|
||||
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -107,11 +107,13 @@ https://certd.handfree.work/
|
||||
|
||||
**镜像版本:**
|
||||
|
||||
| 版本标签 | 基础系统 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `latest` / `[version]` | Alpine Linux | 默认版本,镜像体积小 |
|
||||
| `slim` / `[version]-slim` | Debian slim | 基于glibc,dns解析兼容性好(可能需要配置security_opt -seccomp=unconfined) |
|
||||
| `armv7` / `[version]-armv7` | Alpine Linux | ARMv7 架构专用版本 |
|
||||
|
||||
| 标签 | 指定版本 | 基础系统 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `latest` | `[version]` | Alpine Linux | 默认版本,镜像体积小 |
|
||||
| `slim` | `[version]-slim` | Debian slim | 基于glibc,dns解析兼容性好(可能需要配置security_opt -seccomp=unconfined) |
|
||||
| `armv7` | `[version]-armv7` | Alpine Linux | ARMv7 架构专用版本 |
|
||||
|
||||
|
||||
**镜像地址:**
|
||||
|
||||
|
||||
@@ -3,6 +3,28 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.42.6](https://github.com/certd/certd/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复正常批量删除流水线报权限不足的bug ([5b50083](https://github.com/certd/certd/commit/5b500830a122c6c42dab054e57fed509050f94da))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化动态加载依赖镜像地址,多次重试 ([5f53b81](https://github.com/certd/certd/commit/5f53b81c75dd242b4260ac08cae14c6d1a08a883))
|
||||
|
||||
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复上传到cos报runtimeDepsService未初始化的问题 ([167b303](https://github.com/certd/certd/commit/167b303faeca02cc11cf97e4be2a3df914852167))
|
||||
* 修复dingtalk通知格式没有换行的bug ([7ed1be9](https://github.com/certd/certd/commit/7ed1be994f8b4b74cdeb38743060c912c027248b))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 给SQLITE_IOERR_WRITE增加友好报错提示,将certd:latest镜像改为certd:slim ([b91c9e4](https://github.com/certd/certd/commit/b91c9e4ea671cb359ef164e27864de1d66cba9d3))
|
||||
* 优化vke keubconfig获取方式,改成先查询,如果没有再创建临时config ([604fa5b](https://github.com/certd/certd/commit/604fa5be634d099d797bfee5c2b0f26ce0ac8461))
|
||||
|
||||
## [1.42.4](https://github.com/certd/certd/compare/v1.42.3...v1.42.4) (2026-07-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@
|
||||
}
|
||||
},
|
||||
"npmClient": "pnpm",
|
||||
"version": "1.42.5"
|
||||
"version": "1.42.6"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.42.6](https://github.com/publishlab/node-acme-client/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.42.5](https://github.com/publishlab/node-acme-client/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "Simple and unopinionated ACME client",
|
||||
"private": false,
|
||||
"author": "nmorsman",
|
||||
"version": "1.42.5",
|
||||
"version": "1.42.6",
|
||||
"type": "module",
|
||||
"module": "./dist/index.js",
|
||||
"main": "./dist/index.js",
|
||||
@@ -18,7 +18,7 @@
|
||||
"types"
|
||||
],
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.42.5",
|
||||
"@certd/basic": "^1.42.6",
|
||||
"@peculiar/x509": "^1.11.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"axios": "^1.9.0",
|
||||
@@ -75,5 +75,5 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||
},
|
||||
"gitHead": "268cd6cc9cb4f1f3d5d5d77859a82f18f0cb6db7"
|
||||
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.42.6](https://github.com/certd/certd/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
@@ -1 +1 @@
|
||||
23:31
|
||||
01:12
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/basic",
|
||||
"private": false,
|
||||
"version": "1.42.5",
|
||||
"version": "1.42.6",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -54,5 +54,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "268cd6cc9cb4f1f3d5d5d77859a82f18f0cb6db7"
|
||||
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.42.6](https://github.com/certd/certd/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化动态加载依赖镜像地址,多次重试 ([5f53b81](https://github.com/certd/certd/commit/5f53b81c75dd242b4260ac08cae14c6d1a08a883))
|
||||
|
||||
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/pipeline",
|
||||
"private": false,
|
||||
"version": "1.42.5",
|
||||
"version": "1.42.6",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -21,8 +21,8 @@
|
||||
"lint": "eslint --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.42.5",
|
||||
"@certd/plus-core": "^1.42.5",
|
||||
"@certd/basic": "^1.42.6",
|
||||
"@certd/plus-core": "^1.42.6",
|
||||
"dayjs": "^1.11.7",
|
||||
"lodash-es": "^4.17.21",
|
||||
"reflect-metadata": "^0.2.2"
|
||||
@@ -51,5 +51,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "268cd6cc9cb4f1f3d5d5d77859a82f18f0cb6db7"
|
||||
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import assert from "assert";
|
||||
import assert from "assert";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import os from "os";
|
||||
@@ -34,6 +34,9 @@ describe("RuntimeDepsService", () => {
|
||||
async resolve() {
|
||||
return "https://registry.npmmirror.com";
|
||||
},
|
||||
async resolveOrdered() {
|
||||
return ["https://registry.npmmirror.com"];
|
||||
},
|
||||
} as any;
|
||||
service.commandRunner = {
|
||||
async run(command: string, args: string[]) {
|
||||
@@ -60,6 +63,9 @@ describe("RuntimeDepsService", () => {
|
||||
async resolve() {
|
||||
return "";
|
||||
},
|
||||
async resolveOrdered() {
|
||||
return [""];
|
||||
},
|
||||
} as any;
|
||||
service.commandRunner = {
|
||||
async run(command: string, args: string[]) {
|
||||
@@ -100,6 +106,9 @@ describe("RuntimeDepsService", () => {
|
||||
async resolve() {
|
||||
return "";
|
||||
},
|
||||
async resolveOrdered() {
|
||||
return [""];
|
||||
},
|
||||
} as any;
|
||||
service.commandRunner = {
|
||||
async run(command: string, args: string[]) {
|
||||
@@ -127,6 +136,9 @@ describe("RuntimeDepsService", () => {
|
||||
async resolve() {
|
||||
return "";
|
||||
},
|
||||
async resolveOrdered() {
|
||||
return [""];
|
||||
},
|
||||
} as any;
|
||||
service.commandRunner = {
|
||||
async run(command: string, args: string[]) {
|
||||
@@ -167,6 +179,9 @@ describe("RuntimeDepsService", () => {
|
||||
async resolve() {
|
||||
return "";
|
||||
},
|
||||
async resolveOrdered() {
|
||||
return [""];
|
||||
},
|
||||
} as any;
|
||||
service.commandRunner = {
|
||||
async run(command: string, args: string[]) {
|
||||
@@ -211,6 +226,9 @@ describe("RuntimeDepsService", () => {
|
||||
async resolve() {
|
||||
return "";
|
||||
},
|
||||
async resolveOrdered() {
|
||||
return [""];
|
||||
},
|
||||
} as any;
|
||||
service.commandRunner = {
|
||||
async run(command: string, args: string[]) {
|
||||
@@ -279,6 +297,9 @@ describe("RuntimeDepsService", () => {
|
||||
async resolve() {
|
||||
return "";
|
||||
},
|
||||
async resolveOrdered() {
|
||||
return [""];
|
||||
},
|
||||
} as any;
|
||||
service.commandRunner = {
|
||||
async run(command: string, args: string[], options: { env?: NodeJS.ProcessEnv }) {
|
||||
@@ -315,7 +336,7 @@ describe("RuntimeDepsService", () => {
|
||||
});
|
||||
|
||||
describe("NpmRegistryResolver", () => {
|
||||
it("chooses the fastest successful registry in auto mode", async () => {
|
||||
it("returns the fastest successful registry via resolve()", async () => {
|
||||
const resolver = new NpmRegistryResolver({
|
||||
mode: "auto",
|
||||
candidates: ["https://slow.example.com", "https://fast.example.com"],
|
||||
@@ -341,4 +362,60 @@ describe("NpmRegistryResolver", () => {
|
||||
const result = await resolver.resolve();
|
||||
assert.equal(result, "https://registry.example.com");
|
||||
});
|
||||
it("returns ordered list via resolveOrdered (fastest first)", async () => {
|
||||
const resolver = new NpmRegistryResolver({
|
||||
mode: "auto",
|
||||
candidates: ["https://slow.example.com", "https://fast.example.com"],
|
||||
probeTimeoutMs: 100,
|
||||
cacheTtlMs: 1000,
|
||||
});
|
||||
resolver.probe = async (registryUrl: string) => ({
|
||||
registryUrl,
|
||||
ok: true,
|
||||
elapsedMs: registryUrl.includes("fast") ? 10 : 50,
|
||||
});
|
||||
const result = await resolver.resolveOrdered();
|
||||
assert.deepEqual(result, ["https://fast.example.com", "https://slow.example.com"]);
|
||||
});
|
||||
it("includes failed registries at the end of resolveOrdered", async () => {
|
||||
const resolver = new NpmRegistryResolver({
|
||||
mode: "auto",
|
||||
candidates: ["https://good.example.com", "https://bad.example.com"],
|
||||
probeTimeoutMs: 100,
|
||||
cacheTtlMs: 1000,
|
||||
});
|
||||
resolver.probe = async (registryUrl: string) => {
|
||||
if (registryUrl.includes("bad")) {
|
||||
return { registryUrl, ok: false, elapsedMs: 200 };
|
||||
}
|
||||
return { registryUrl, ok: true, elapsedMs: 30 };
|
||||
};
|
||||
const result = await resolver.resolveOrdered();
|
||||
assert.deepEqual(result, ["https://good.example.com", "https://bad.example.com"]);
|
||||
});
|
||||
it("returns empty ordered list when no candidates", async () => {
|
||||
const resolver = new NpmRegistryResolver({ mode: "auto", candidates: [] });
|
||||
const result = await resolver.resolveOrdered();
|
||||
assert.deepEqual(result, []);
|
||||
const single = await resolver.resolve();
|
||||
assert.equal(single, "");
|
||||
});
|
||||
it("re-validates cached URL on resolveOrdered call", async () => {
|
||||
let probeCount = 0;
|
||||
const resolver = new NpmRegistryResolver({
|
||||
mode: "auto",
|
||||
candidates: ["https://mirror.example.com"],
|
||||
cacheTtlMs: 60000,
|
||||
});
|
||||
resolver.probe = async (registryUrl: string) => {
|
||||
probeCount++;
|
||||
return { registryUrl, ok: true, elapsedMs: 10 };
|
||||
};
|
||||
const first = await resolver.resolveOrdered();
|
||||
assert.deepEqual(first, ["https://mirror.example.com"]);
|
||||
assert.equal(probeCount, 1);
|
||||
const second = await resolver.resolveOrdered();
|
||||
assert.deepEqual(second, ["https://mirror.example.com"]);
|
||||
assert.equal(probeCount, 2);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import fs from "fs";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { spawn } from "child_process";
|
||||
import crypto from "crypto";
|
||||
@@ -89,7 +89,7 @@ export type RegistryProbeResult = {
|
||||
|
||||
export class NpmRegistryResolver {
|
||||
config: NpmRegistryResolverConfig;
|
||||
private cache?: { registryUrl: string; expiresAt: number };
|
||||
private cache?: { orderedUrls: string[]; expiresAt: number };
|
||||
|
||||
constructor(config?: NpmRegistryResolverConfig) {
|
||||
this.config = config || {};
|
||||
@@ -105,21 +105,67 @@ export class NpmRegistryResolver {
|
||||
}
|
||||
const cached = this.cache;
|
||||
if (cached && cached.expiresAt > Date.now()) {
|
||||
return cached.registryUrl;
|
||||
const fastUrl = cached.orderedUrls[0];
|
||||
if (fastUrl) {
|
||||
const probeResult = await this.probe(fastUrl);
|
||||
if (probeResult.ok) {
|
||||
return cached.orderedUrls[0] || "";
|
||||
}
|
||||
}
|
||||
this.cache = undefined;
|
||||
}
|
||||
const candidates = (config?.candidates || []).filter(Boolean);
|
||||
if (candidates.length === 0) {
|
||||
return "";
|
||||
}
|
||||
const probes = await Promise.allSettled(candidates.map(registryUrl => this.probe(registryUrl)));
|
||||
const okList = probes.map(item => (item.status === "fulfilled" ? item.value : null)).filter((item): item is RegistryProbeResult => !!item && item.ok);
|
||||
if (okList.length > 0) {
|
||||
okList.sort((a, b) => a.elapsedMs - b.elapsedMs);
|
||||
const best = okList[0].registryUrl;
|
||||
this.cache = { registryUrl: best, expiresAt: Date.now() + (config?.cacheTtlMs || 6 * 60 * 60 * 1000) };
|
||||
return best;
|
||||
const orderedUrls = await this.internalProbeAll(candidates);
|
||||
this.cache = { orderedUrls, expiresAt: Date.now() + (config?.cacheTtlMs ?? 300_000) };
|
||||
return orderedUrls[0] || "";
|
||||
}
|
||||
|
||||
async resolveOrdered(): Promise<string[]> {
|
||||
const config = this.config;
|
||||
if (config?.mode === "fixed" && config.fixedUrl) {
|
||||
return [config.fixedUrl];
|
||||
}
|
||||
return "";
|
||||
if (config?.mode === "system") {
|
||||
return [];
|
||||
}
|
||||
const cached = this.cache;
|
||||
if (cached && cached.expiresAt > Date.now()) {
|
||||
const fastUrl = cached.orderedUrls[0];
|
||||
if (fastUrl) {
|
||||
const probeResult = await this.probe(fastUrl);
|
||||
if (probeResult.ok) {
|
||||
return cached.orderedUrls;
|
||||
}
|
||||
}
|
||||
this.cache = undefined;
|
||||
}
|
||||
const candidates = (config?.candidates || []).filter(Boolean);
|
||||
if (candidates.length === 0) {
|
||||
return [];
|
||||
}
|
||||
const orderedUrls = await this.internalProbeAll(candidates);
|
||||
this.cache = { orderedUrls, expiresAt: Date.now() + (config?.cacheTtlMs ?? 300_000) };
|
||||
return orderedUrls;
|
||||
}
|
||||
|
||||
private async internalProbeAll(candidates: string[]): Promise<string[]> {
|
||||
const probes = await Promise.allSettled(candidates.map(registryUrl => this.probe(registryUrl)));
|
||||
const okList: RegistryProbeResult[] = [];
|
||||
const failList: RegistryProbeResult[] = [];
|
||||
for (const item of probes) {
|
||||
const result = item.status === "fulfilled" ? item.value : null;
|
||||
if (result && result.ok) {
|
||||
okList.push(result);
|
||||
} else if (result) {
|
||||
failList.push(result);
|
||||
}
|
||||
}
|
||||
okList.sort((a, b) => a.elapsedMs - b.elapsedMs);
|
||||
failList.sort((a, b) => a.elapsedMs - b.elapsedMs);
|
||||
return [...okList.map(r => r.registryUrl), ...failList.map(r => r.registryUrl)];
|
||||
}
|
||||
|
||||
async probe(registryUrl: string): Promise<RegistryProbeResult> {
|
||||
@@ -368,6 +414,7 @@ export class RuntimeDepsService {
|
||||
await this.ensureLazyDependency(packageName, logger);
|
||||
return this.resolveRuntimeSpecifier(specifier).resolved;
|
||||
} catch (lazyError: any) {
|
||||
logger?.error?.(`动态依赖安装失败: ${lazyError.message}`);
|
||||
return this.resolveProjectSpecifier(specifier, lazyError).resolved;
|
||||
}
|
||||
}
|
||||
@@ -508,30 +555,37 @@ export class RuntimeDepsService {
|
||||
const env = this.buildChildEnv(registryUrl);
|
||||
const command = this.getPnpmCommand();
|
||||
const pnpmVersion = await this.getPnpmVersion(command, env);
|
||||
const args = ["install", "--prod", "--ignore-scripts", "--ignore-workspace", "--no-frozen-lockfile", "--reporter=append-only"];
|
||||
if (registryUrl) {
|
||||
args.push(`--registry=${registryUrl}`);
|
||||
const allRegistryUrls = await this.registryResolver.resolveOrdered();
|
||||
const urlsToTry = allRegistryUrls.length > 0 ? allRegistryUrls : [""];
|
||||
let lastError: string | undefined;
|
||||
for (const tryUrl of urlsToTry) {
|
||||
const args = ["install", "--prod", "--ignore-scripts", "--ignore-workspace", "--no-frozen-lockfile", "--reporter=append-only"];
|
||||
if (tryUrl) {
|
||||
args.push(`--registry=${tryUrl}`);
|
||||
}
|
||||
const tryEnv = tryUrl ? this.buildChildEnv(tryUrl) : env;
|
||||
log.info(`开始安装第三方依赖: ${Object.keys(dependencies).join(", ")}${tryUrl ? `,镜像: ${tryUrl}` : ""}`);
|
||||
const result = await this.commandRunner.run(command, args, { cwd: rootDir, timeoutMs: this.installTimeoutMs, env: tryEnv });
|
||||
if (result.code === 0) {
|
||||
this.writeInstallState(statePath, { installedAt: new Date().toISOString(), registryUrl: tryUrl, dependenciesHash, nodeVersion: process.version, pnpmVersion, lockFileExists: fs.existsSync(lockPath) });
|
||||
log.info("第三方依赖安装完成");
|
||||
return { registryUrl: tryUrl, packageJsonPath };
|
||||
}
|
||||
lastError = result.stderr || result.stdout || "unknown error";
|
||||
log.warn?.(`镜像 ${tryUrl || "默认"} 安装失败${urlsToTry.length > 1 ? ",尝试下一个镜像..." : ""}`);
|
||||
}
|
||||
log.info(`开始安装第三方依赖: ${Object.keys(dependencies).join(", ")}`);
|
||||
const result = await this.commandRunner.run(command, args, { cwd: rootDir, timeoutMs: this.installTimeoutMs, env });
|
||||
if (result.code !== 0) {
|
||||
const message = result.stderr || result.stdout || "unknown error";
|
||||
this.writeInstallState(statePath, {
|
||||
...currentState,
|
||||
installedAt: currentState?.installedAt,
|
||||
failedAt: new Date().toISOString(),
|
||||
registryUrl,
|
||||
dependenciesHash,
|
||||
nodeVersion: process.version,
|
||||
pnpmVersion,
|
||||
lockFileExists: fs.existsSync(lockPath),
|
||||
lastError: message,
|
||||
});
|
||||
throw new Error(`动态依赖安装失败: ${message}`);
|
||||
}
|
||||
this.writeInstallState(statePath, { installedAt: new Date().toISOString(), registryUrl, dependenciesHash, nodeVersion: process.version, pnpmVersion, lockFileExists: fs.existsSync(lockPath) });
|
||||
log.info("第三方依赖安装完成");
|
||||
return { registryUrl, packageJsonPath };
|
||||
this.writeInstallState(statePath, {
|
||||
...currentState,
|
||||
installedAt: currentState?.installedAt,
|
||||
failedAt: new Date().toISOString(),
|
||||
registryUrl: urlsToTry[0],
|
||||
dependenciesHash,
|
||||
nodeVersion: process.version,
|
||||
pnpmVersion,
|
||||
lockFileExists: fs.existsSync(lockPath),
|
||||
lastError,
|
||||
});
|
||||
throw new Error(`动态依赖安装失败: ${lastError}`);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.42.6](https://github.com/certd/certd/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-huawei",
|
||||
"private": false,
|
||||
"version": "1.42.5",
|
||||
"version": "1.42.6",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
@@ -31,5 +31,5 @@
|
||||
"prettier": "3.3.3",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"gitHead": "268cd6cc9cb4f1f3d5d5d77859a82f18f0cb6db7"
|
||||
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.42.6](https://github.com/certd/certd/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-iframe",
|
||||
"private": false,
|
||||
"version": "1.42.5",
|
||||
"version": "1.42.6",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -37,5 +37,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "268cd6cc9cb4f1f3d5d5d77859a82f18f0cb6db7"
|
||||
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.42.6](https://github.com/certd/certd/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/jdcloud",
|
||||
"version": "1.42.5",
|
||||
"version": "1.42.6",
|
||||
"description": "jdcloud openApi sdk",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
@@ -63,5 +63,5 @@
|
||||
"fetch"
|
||||
]
|
||||
},
|
||||
"gitHead": "268cd6cc9cb4f1f3d5d5d77859a82f18f0cb6db7"
|
||||
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.42.6](https://github.com/certd/certd/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-k8s",
|
||||
"private": false,
|
||||
"version": "1.42.5",
|
||||
"version": "1.42.6",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -21,7 +21,7 @@
|
||||
"lint": "eslint --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.42.5",
|
||||
"@certd/basic": "^1.42.6",
|
||||
"@kubernetes/client-node": "0.21.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -38,5 +38,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "268cd6cc9cb4f1f3d5d5d77859a82f18f0cb6db7"
|
||||
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.42.6](https://github.com/certd/certd/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复正常批量删除流水线报权限不足的bug ([5b50083](https://github.com/certd/certd/commit/5b500830a122c6c42dab054e57fed509050f94da))
|
||||
|
||||
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/lib-server",
|
||||
"version": "1.42.5",
|
||||
"version": "1.42.6",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -29,11 +29,11 @@
|
||||
],
|
||||
"license": "AGPL",
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.42.5",
|
||||
"@certd/basic": "^1.42.5",
|
||||
"@certd/pipeline": "^1.42.5",
|
||||
"@certd/plugin-lib": "^1.42.5",
|
||||
"@certd/plus-core": "^1.42.5",
|
||||
"@certd/acme-client": "^1.42.6",
|
||||
"@certd/basic": "^1.42.6",
|
||||
"@certd/pipeline": "^1.42.6",
|
||||
"@certd/plugin-lib": "^1.42.6",
|
||||
"@certd/plus-core": "^1.42.6",
|
||||
"@midwayjs/cache": "3.14.0",
|
||||
"@midwayjs/core": "3.20.11",
|
||||
"@midwayjs/i18n": "3.20.13",
|
||||
@@ -69,5 +69,5 @@
|
||||
"typeorm": "^0.3.20",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "268cd6cc9cb4f1f3d5d5d77859a82f18f0cb6db7"
|
||||
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||
}
|
||||
|
||||
@@ -253,7 +253,6 @@ export abstract class BaseService<T> {
|
||||
if (!Array.isArray(ids)) {
|
||||
ids = [ids];
|
||||
}
|
||||
ids = this.filterIds(ids);
|
||||
const res = await this.getRepository().find({
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
@@ -266,7 +265,7 @@ export abstract class BaseService<T> {
|
||||
},
|
||||
});
|
||||
if (!res || res.length === ids.length) {
|
||||
return;
|
||||
return ids;
|
||||
}
|
||||
throw new PermissionException("权限不足");
|
||||
}
|
||||
@@ -280,6 +279,12 @@ export abstract class BaseService<T> {
|
||||
});
|
||||
}
|
||||
async batchDelete(ids: number[], userId: number, projectId?: number): Promise<number> {
|
||||
if (!ids || ids.length === 0) {
|
||||
throw new ValidateException("ids不能为空");
|
||||
}
|
||||
if (!Array.isArray(ids)) {
|
||||
ids = [ids];
|
||||
}
|
||||
ids = this.filterIds(ids);
|
||||
if (userId != null) {
|
||||
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.42.6](https://github.com/certd/certd/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/midway-flyway-js",
|
||||
"version": "1.42.5",
|
||||
"version": "1.42.6",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -52,5 +52,5 @@
|
||||
"typeorm": "^0.3.20",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "268cd6cc9cb4f1f3d5d5d77859a82f18f0cb6db7"
|
||||
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.42.6](https://github.com/certd/certd/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-cert",
|
||||
"private": false,
|
||||
"version": "1.42.5",
|
||||
"version": "1.42.6",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -20,7 +20,7 @@
|
||||
"lint": "eslint --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/plugin-lib": "^1.42.5"
|
||||
"@certd/plugin-lib": "^1.42.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.3.12",
|
||||
@@ -38,5 +38,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "268cd6cc9cb4f1f3d5d5d77859a82f18f0cb6db7"
|
||||
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.42.6](https://github.com/certd/certd/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-lib",
|
||||
"private": false,
|
||||
"version": "1.42.5",
|
||||
"version": "1.42.6",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -17,9 +17,9 @@
|
||||
"lint": "eslint --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.42.5",
|
||||
"@certd/basic": "^1.42.5",
|
||||
"@certd/pipeline": "^1.42.5",
|
||||
"@certd/acme-client": "^1.42.6",
|
||||
"@certd/basic": "^1.42.6",
|
||||
"@certd/pipeline": "^1.42.6",
|
||||
"dayjs": "^1.11.7",
|
||||
"jszip": "^3.10.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
@@ -45,5 +45,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "268cd6cc9cb4f1f3d5d5d77859a82f18f0cb6db7"
|
||||
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.42.6](https://github.com/certd/certd/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/ui-client
|
||||
|
||||
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-client",
|
||||
"version": "1.42.5",
|
||||
"version": "1.42.6",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --open",
|
||||
@@ -104,8 +104,8 @@
|
||||
"zod-defaults": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/lib-iframe": "^1.42.5",
|
||||
"@certd/pipeline": "^1.42.5",
|
||||
"@certd/lib-iframe": "^1.42.6",
|
||||
"@certd/pipeline": "^1.42.6",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/chai": "^4.3.12",
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.42.6](https://github.com/certd/certd/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复正常批量删除流水线报权限不足的bug ([5b50083](https://github.com/certd/certd/commit/5b500830a122c6c42dab054e57fed509050f94da))
|
||||
|
||||
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-server",
|
||||
"version": "1.42.5",
|
||||
"version": "1.42.6",
|
||||
"description": "fast-server base midway",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
@@ -42,20 +42,20 @@
|
||||
"lint1": "eslint --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.42.5",
|
||||
"@certd/basic": "^1.42.5",
|
||||
"@certd/commercial-core": "^1.42.5",
|
||||
"@certd/acme-client": "^1.42.6",
|
||||
"@certd/basic": "^1.42.6",
|
||||
"@certd/commercial-core": "^1.42.6",
|
||||
"@certd/cv4pve-api-javascript": "^8.4.2",
|
||||
"@certd/jdcloud": "^1.42.5",
|
||||
"@certd/lib-huawei": "^1.42.5",
|
||||
"@certd/lib-k8s": "^1.42.5",
|
||||
"@certd/lib-server": "^1.42.5",
|
||||
"@certd/midway-flyway-js": "^1.42.5",
|
||||
"@certd/pipeline": "^1.42.5",
|
||||
"@certd/plugin-cert": "^1.42.5",
|
||||
"@certd/plugin-lib": "^1.42.5",
|
||||
"@certd/plugin-plus": "^1.42.5",
|
||||
"@certd/plus-core": "^1.42.5",
|
||||
"@certd/jdcloud": "^1.42.6",
|
||||
"@certd/lib-huawei": "^1.42.6",
|
||||
"@certd/lib-k8s": "^1.42.6",
|
||||
"@certd/lib-server": "^1.42.6",
|
||||
"@certd/midway-flyway-js": "^1.42.6",
|
||||
"@certd/pipeline": "^1.42.6",
|
||||
"@certd/plugin-cert": "^1.42.6",
|
||||
"@certd/plugin-lib": "^1.42.6",
|
||||
"@certd/plugin-plus": "^1.42.6",
|
||||
"@certd/plus-core": "^1.42.6",
|
||||
"@koa/cors": "^5.0.0",
|
||||
"@midwayjs/bootstrap": "3.20.11",
|
||||
"@midwayjs/cache": "3.14.0",
|
||||
|
||||
@@ -806,6 +806,8 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
}
|
||||
|
||||
async batchDelete(ids: number[], userId: number, projectId?: number): Promise<number> {
|
||||
|
||||
ids = this.filterIds(ids);
|
||||
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
|
||||
await this.repository.delete({
|
||||
id: In(ids),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Config, Inject, Provide, Scope, ScopeEnum, sleep } from "@midwayjs/core";
|
||||
import { InjectEntityModel } from "@midwayjs/typeorm";
|
||||
import { In, MoreThan, Repository } from "typeorm";
|
||||
import { AccessService, BaseService, isEnterprise, NeedSuiteException, NeedVIPException, PageReq, SysPublicSettings, SysSettingsService, SysSiteInfo } from "@certd/lib-server";
|
||||
import { AccessService, BaseService, isEnterprise, NeedSuiteException, NeedVIPException, PageReq, SysPublicSettings, SysSettingsService, SysSiteInfo, ValidateException } from "@certd/lib-server";
|
||||
import { PipelineEntity } from "../entity/pipeline.js";
|
||||
import { PipelineDetail } from "../entity/vo/pipeline-detail.js";
|
||||
import { Executor, IAccessService, ICnameProxyService, INotificationService, Notification, Pipeline, pluginRegistry, ResultType, RunHistory, RunnableCollection, SysInfo, UserInfo } from "@certd/pipeline";
|
||||
@@ -966,15 +966,19 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||
if (!isPlus()) {
|
||||
throw new NeedVIPException("此功能需要升级Certd专业版");
|
||||
}
|
||||
if (!ids || ids.length === 0) {
|
||||
throw new ValidateException("ids不能为空");
|
||||
}
|
||||
ids = this.filterIds(ids);
|
||||
|
||||
if (userId && userId > 0) {
|
||||
await this.checkUserId(ids, userId);
|
||||
}
|
||||
if (projectId) {
|
||||
await this.checkUserId(ids, projectId, "projectId");
|
||||
}
|
||||
for (const id of ids) {
|
||||
if (userId && userId > 0) {
|
||||
await this.checkUserId(id, userId);
|
||||
}
|
||||
if (projectId) {
|
||||
await this.checkUserId(id, projectId, "projectId");
|
||||
}
|
||||
await this.delete(id);
|
||||
ids.push(id);
|
||||
}
|
||||
return ids.length;
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ export class TemplateService extends BaseService<TemplateEntity> {
|
||||
}
|
||||
|
||||
async batchDelete(ids: number[], userId: number, projectId?: number): Promise<number> {
|
||||
ids = this.filterIds(ids);
|
||||
const where: any = {
|
||||
id: In(ids),
|
||||
};
|
||||
|
||||
@@ -1 +1 @@
|
||||
02:48
|
||||
01:14
|
||||
|
||||
@@ -1 +1 @@
|
||||
03:41
|
||||
01:28
|
||||
|
||||
Reference in New Issue
Block a user