@sctg/backport-agent 0.1.0-20260529153002

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ronan Le Meillat - SCTG Development
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # Backport Agent
2
+
3
+ A deterministic IA powered agent for keeping a heavily customized Git fork in sync with an active upstream repository.
4
+
5
+ This project is the implementation of the architecture described in [analysis.md](analysis.md). It is designed for the real-world case where a fork is not just a few patches on top of upstream, but a living codebase with custom providers, build-time rewrites, documentation changes, and operational workflows that must survive every sync.
6
+
7
+ ## Why this exists
8
+
9
+ Keeping a fork aligned with upstream is hard when the fork carries important product decisions. A naive merge strategy can silently break custom behavior even when Git reports no conflicts.
10
+
11
+ Backport Agent focuses on the parts that matter most:
12
+
13
+ - identify the upstream commits that still need to be integrated;
14
+ - classify change risk before touching the fork;
15
+ - preserve fork-specific customizations;
16
+ - run validation after each meaningful integration step;
17
+ - produce a clear report instead of pushing blind changes.
18
+
19
+ ## What it does
20
+
21
+ The agent works as a sync pipeline rather than a one-shot merge bot. It reads the upstream history, selects candidate commits, evaluates their risk, applies them in controlled batches, validates the result, and generates a report for review.
22
+
23
+ It is built to support a fork that includes features such as:
24
+
25
+ - the `keypoollive` provider;
26
+ - encrypted vault-backed model and key discovery;
27
+ - round-robin key rotation;
28
+ - GitHub Actions build-time package renaming;
29
+ - Mintlify documentation generation;
30
+ - a local reporting and validation workflow.
31
+
32
+ ## How it is structured
33
+
34
+ The codebase is intentionally split into small, testable pieces:
35
+
36
+ - `src/git` handles Git operations and cherry-pick workflows;
37
+ - `src/risk` classifies commits and customization sensitivity;
38
+ - `src/validation` runs allowlisted validation commands;
39
+ - `src/github` manages pull request creation and metadata;
40
+ - `src/reports` assembles the final sync report;
41
+ - `src/ai` exposes analysis helpers used when deterministic logic is not enough;
42
+ - `src/config` and `src/customizations` load the sync configuration and fork-specific invariants.
43
+
44
+ The agent entry point is [src/main.ts](src/main.ts), which wires the sync flow together and also enables the built-in SDK tools used by the runtime.
45
+
46
+ ## Getting started
47
+
48
+ 1. Install dependencies.
49
+
50
+ ```bash
51
+ npm install
52
+ ```
53
+
54
+ 2. Copy the example configuration files and adjust them for your environment.
55
+
56
+ - [config.example.json](config.example.json)
57
+ - [customizations.example.yaml](customizations.example.yaml)
58
+
59
+ 3. Set the required vault environment variables in your shell or `.env` file.
60
+
61
+ ```bash
62
+ KEYPOOL_VAULT_URL=https://...
63
+ KEYPOOL_LIVE_SECRET=...
64
+ ```
65
+
66
+ 4. Start the agent.
67
+
68
+ ```bash
69
+ npm start
70
+ ```
71
+
72
+ If you want a no-op run that still exercises the workflow, use:
73
+
74
+ ```bash
75
+ npm run dry-run
76
+ ```
77
+
78
+ Set `VERBOSE=true` to see detailed iteration and tool-call progress in stderr:
79
+
80
+ ```bash
81
+ VERBOSE=true npm start
82
+ ```
83
+
84
+ ## Retry behavior
85
+
86
+ The agent includes automatic retry logic for transient provider errors (rate limits, overloaded endpoints, high-demand responses, HTTP 503, etc.). When a retriable error is detected, the agent waits with exponential backoff (15 s, 30 s, 45 s…) and restarts up to 5 times.
87
+
88
+ Because agent state is anchored to Git, restarting is safe — already-applied commits are detected from the git log and skipped automatically.
89
+
90
+ The iteration counter in verbose output is continuous across retries. A retry is indicated by a suffix in the progress lines:
91
+
92
+ ```
93
+ --- iteration 16 ---
94
+ [Retry] Silent provider error on attempt 1/5: This model is currently experiencing high demand…
95
+ [Retry] Waiting 15s before retrying...
96
+ --- iteration 17 - Retry 1 ---
97
+ --- iteration 18 - Retry 1 ---
98
+ ```
99
+
100
+ ## Validation and tests
101
+
102
+ The repository includes both unit and integration coverage.
103
+
104
+ - `npm run typecheck` checks the TypeScript build.
105
+ - `npm test` runs the full test suite.
106
+ - `npm run test:unit` runs fast deterministic tests.
107
+ - `npm run test:integration` runs integration tests, including real KeypoolLive calls when your vault is configured.
108
+
109
+ The integration suite is intentionally practical. It verifies Git behavior in temporary repositories and exercises real SDK tools against the `keypoollive` provider with the `mistral/devstral-latest` model when `.env` is available.
110
+
111
+ ## Configuration
112
+
113
+ The main runtime configuration lives in a JSON file modeled after [config.example.json](config.example.json). It defines:
114
+
115
+ - the upstream repository and branch;
116
+ - the fork repository and branch;
117
+ - the working directory;
118
+ - sync limits and batching;
119
+ - model selection;
120
+ - validation tiers.
121
+
122
+ Custom fork invariants live in a YAML file modeled after [customizations.example.yaml](customizations.example.yaml). This is where you describe the areas that must not be broken by a backport run.
123
+
124
+ ## For contributors
125
+
126
+ Contributions are especially welcome in the following areas:
127
+
128
+ - additional integration tests for more SDK tools and runtime behaviors;
129
+ - stronger customization detection and risk classification;
130
+ - better report formatting and human-review summaries;
131
+ - more realistic validation strategies for large forks;
132
+ - documentation improvements and onboarding examples;
133
+ - support for additional providers or model-routing strategies.
134
+
135
+ If you are looking for a good first contribution, start with tests or documentation. The project already has a deterministic core, so incremental improvements are easy to verify.
136
+
137
+ ## Design principles
138
+
139
+ This project intentionally avoids the “merge everything and hope” approach. The main design goals are:
140
+
141
+ - preserve the fork’s intent;
142
+ - keep changes small and reviewable;
143
+ - use deterministic logic first;
144
+ - use AI only where it adds clear value;
145
+ - fail safely when confidence is low.
146
+
147
+ That makes the agent more useful for real maintenance work and easier for contributors to reason about.
148
+
149
+ ## License
150
+
151
+ MIT License. See [LICENSE.md](LICENSE.md) for details.
@@ -0,0 +1,63 @@
1
+ {
2
+ "auth": {
3
+ "_comment_ssh": "Use sshKeyPath for SSH remotes (supports ~ expansion)",
4
+ "sshKeyPath": "~/.ssh/id_ed25519",
5
+ "_comment_token": "Use githubToken for HTTPS remotes; prefix with $ to read from env var",
6
+ "_githubToken_example": "$GITHUB_TOKEN"
7
+ },
8
+ "upstream": {
9
+ "url": "git@github.com:cline/cline.git",
10
+ "repo": "cline/cline",
11
+ "branch": "dev",
12
+ "remote": "upstream"
13
+ },
14
+ "fork": {
15
+ "url": "git@github.com:TEA-ching/cline.git",
16
+ "repo": "TEA-ching/cline",
17
+ "branch": "keypool-live",
18
+ "remote": "origin"
19
+ },
20
+ "workingDir": "/path/to/your/local/TEA-ching-cline-clone",
21
+ "sync": {
22
+ "maxCommitsPerRun": 20,
23
+ "initialFetchDepth": 200,
24
+ "maxFetchDepth": 4000,
25
+ "batchSize": 5,
26
+ "dryRun": true,
27
+ "createPullRequest": true,
28
+ "branchPrefix": "sync/upstream-"
29
+ },
30
+ "models": {
31
+ "fast": "mistral/devstral-latest",
32
+ "specialist": "mistral/devstral-latest",
33
+ "powerful": "mistral/magistral-medium-latest"
34
+ },
35
+ "resolve": {
36
+ "_comment": "Glob or /regex/flags patterns matched against repo-relative file paths",
37
+ "ours": [
38
+ "package-lock.json",
39
+ "bun.lockb"
40
+ ],
41
+ "theirs": [
42
+ "CHANGELOG.md",
43
+ "/^docs\//"
44
+ ]
45
+ },
46
+ "report": {
47
+ "destination": "."
48
+ },
49
+ "validation": {
50
+ "low": [
51
+ "npm run typecheck"
52
+ ],
53
+ "medium": [
54
+ "npm run typecheck",
55
+ "npm run test:unit"
56
+ ],
57
+ "high": [
58
+ "npm run typecheck",
59
+ "npm run test:unit",
60
+ "npm run compile"
61
+ ]
62
+ }
63
+ }
@@ -0,0 +1,44 @@
1
+ customizations:
2
+ - id: keypoollive-provider-vscode
3
+ description: |
4
+ keypoollive LLM provider integration dans l'extension VS Code.
5
+ Fournit la rotation automatique de clés via KEYPOOL_VAULT_URL.
6
+ paths:
7
+ - "apps/vscode/src/shared/providers/keypoollive*"
8
+ - "apps/vscode/src/api/providers/keypoollive*"
9
+ invariants:
10
+ - "keypoollive est listé dans providers.json"
11
+ - "KEYPOOL_VAULT_URL est chargé correctement"
12
+ - "les tests unitaires du provider passent"
13
+
14
+ - id: keypoollive-provider-sdk
15
+ description: |
16
+ keypoollive LLM provider dans le SDK @sctg/cline-sdk.
17
+ paths:
18
+ - "sdk/packages/llms/src/providers/vendors/keypoollive.ts"
19
+ - "sdk/packages/llms/src/providers/vendors/keypoollive*"
20
+ invariants:
21
+ - "le provider est exporté dans l'index du package llms"
22
+ - "apiKey: 'auto' déclenche la récupération du vault"
23
+
24
+ - id: package-renaming-sctg
25
+ description: |
26
+ Renommage @cline/* → @sctg/cline-* dans le build et la publication npm.
27
+ paths:
28
+ - ".github/workflows/**"
29
+ - "scripts/rename-packages*"
30
+ - "scripts/publish*"
31
+ invariants:
32
+ - "les packages publiés utilisent le prefix @sctg/"
33
+ - "la CI publie sur le scope sctg et non cline"
34
+
35
+ - id: ai-json-vault
36
+ description: |
37
+ Fichier ai.json chiffré servant de vault pour les clés API.
38
+ Ne doit jamais être poussé en clair.
39
+ paths:
40
+ - "ai.json"
41
+ - "ai.json.*.enc"
42
+ invariants:
43
+ - "ai.json n'est pas commité en clair (doit être dans .gitignore)"
44
+ - "ai.json.*.enc est le seul format permis en dépôt public"