peaks-loop 4.0.24 → 4.0.25
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/CHANGELOG.md +16 -0
- package/dist/cli/commands/codegraph-commands.d.ts +10 -0
- package/dist/cli/commands/codegraph-commands.js +18 -4
- package/package.json +5 -5
- package/skills/bee/peaks-rd/SKILL.md +7 -0
- package/skills/bee/peaks-rd/references/frontend-acl-mapper.md +29 -0
- package/skills/peaks-code/references/codegraph-orchestration.md +7 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.0.25 — 2026-09-01 (codegraph hint fix + post-slice re-index + frontend ACL)
|
|
4
|
+
|
|
5
|
+
**1 atomic commit from session 2026-09-01-session-fdd7aa** (user feedback batch):
|
|
6
|
+
|
|
7
|
+
- `70184e1f` feat(peaks-code): apply feedback batch — codegraph hint fix + post-slice re-index + frontend ACL + headroom sediment
|
|
8
|
+
|
|
9
|
+
**Highlights**:
|
|
10
|
+
|
|
11
|
+
1. **codegraph 提示泄漏修复** — `peaks codegraph <subcommand>` 透传上游 stdout/stderr 前,新增 `rewriteBareCodegraphHints` 纯函数,把上游裸 `codegraph <sub>` 提示改写为 `peaks codegraph <sub>`(上游 binary 是嵌套传递依赖、不在 PATH,裸命令提示会误导 LLM 敲 "command not found")。8 个 vitest 用例:quoted/backtick hint、7 子命令全量、幂等、`@colbymchenry/codegraph` 包名不误伤。
|
|
12
|
+
|
|
13
|
+
2. **codegraph post-slice 增量刷新** — peaks-code 编排规范:每个 slice/task 完成后主动 `peaks codegraph index`,让下一 slice 的 affected/query/context 基于最新代码图,而不是过期的 pre-slice 图。
|
|
14
|
+
|
|
15
|
+
3. **前端防腐层 ACL 标准** — peaks-rd 新增硬约束:前端内部模型不被外部/API 形状污染;DTO ↔ ViewModel 映射(外部字段 → 内部字段);Mapper 聚合单文件(如 `mappers/user.mapper.ts`),不散落各页面。QA / code-review 校验。
|
|
16
|
+
|
|
17
|
+
4. **headroom-ai 半成品 finding sediment** — 记录 headroom proxy 后端(N-7)未接、当前 0 token 节省;省 token 主杠杆是 G7 metadata-only + auto-compact + cache 对齐。
|
|
18
|
+
|
|
3
19
|
## 4.0.24 — 2026-08-12 (zod v4 + Context7 + Step 2.5 best-practice scan)
|
|
4
20
|
|
|
5
21
|
**6 atomic commits from session 2026-08-12-session-4aaf2b** (5 functional + 1 sediment):
|
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { type ProgramIO } from '../cli-helpers.js';
|
|
3
|
+
/**
|
|
4
|
+
* Rewrites bare upstream `codegraph <subcommand>` hints to the peaks-loop
|
|
5
|
+
* equivalent (`peaks codegraph <subcommand>`). The upstream binary is a
|
|
6
|
+
* nested transitive dependency and is NOT on PATH, so an LLM that follows
|
|
7
|
+
* a bare hint like `Run "codegraph init" to initialize` would hit
|
|
8
|
+
* "command not found". Already-prefixed `peaks codegraph ...` hints and
|
|
9
|
+
* other `codegraph` references (e.g. `@colbymchenry/codegraph`) are left
|
|
10
|
+
* untouched.
|
|
11
|
+
*/
|
|
12
|
+
export declare function rewriteBareCodegraphHints(text: string): string;
|
|
3
13
|
export declare function registerCodegraphCommands(program: Command, io: ProgramIO): void;
|
|
@@ -24,6 +24,18 @@ function printCodegraphFailure(io, command, error, asJson, exitCode = 1) {
|
|
|
24
24
|
printResult(io, fail(command, 'CODEGRAPH_COMMAND_FAILED', redactSensitiveErrorMessage(getErrorMessage(error)), {}, ['Check the codegraph command options and project path before retrying']), asJson);
|
|
25
25
|
process.exitCode = exitCode;
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Rewrites bare upstream `codegraph <subcommand>` hints to the peaks-loop
|
|
29
|
+
* equivalent (`peaks codegraph <subcommand>`). The upstream binary is a
|
|
30
|
+
* nested transitive dependency and is NOT on PATH, so an LLM that follows
|
|
31
|
+
* a bare hint like `Run "codegraph init" to initialize` would hit
|
|
32
|
+
* "command not found". Already-prefixed `peaks codegraph ...` hints and
|
|
33
|
+
* other `codegraph` references (e.g. `@colbymchenry/codegraph`) are left
|
|
34
|
+
* untouched.
|
|
35
|
+
*/
|
|
36
|
+
export function rewriteBareCodegraphHints(text) {
|
|
37
|
+
return text.replace(/(?<![\w-])(?<!peaks\s)codegraph(?=\s+(?:status|init|index|query|files|context|affected)\b)/g, 'peaks codegraph');
|
|
38
|
+
}
|
|
27
39
|
async function runCodegraphCommand(io, command, options, asJson) {
|
|
28
40
|
try {
|
|
29
41
|
const invocation = createCodegraphInvocation(options);
|
|
@@ -33,11 +45,13 @@ async function runCodegraphCommand(io, command, options, asJson) {
|
|
|
33
45
|
return;
|
|
34
46
|
}
|
|
35
47
|
const didFail = result.exitCode !== null && result.exitCode !== 0;
|
|
36
|
-
|
|
37
|
-
|
|
48
|
+
const stdout = rewriteBareCodegraphHints(result.stdout);
|
|
49
|
+
const stderr = rewriteBareCodegraphHints(result.stderr);
|
|
50
|
+
if (stdout.length > 0) {
|
|
51
|
+
io.stdout((didFail ? redactSensitiveErrorMessage(stdout) : stdout).trimEnd());
|
|
38
52
|
}
|
|
39
|
-
if (
|
|
40
|
-
io.stderr((didFail ? redactSensitiveErrorMessage(
|
|
53
|
+
if (stderr.length > 0) {
|
|
54
|
+
io.stderr((didFail ? redactSensitiveErrorMessage(stderr) : stderr).trimEnd());
|
|
41
55
|
}
|
|
42
56
|
if (didFail) {
|
|
43
57
|
process.exitCode = result.exitCode;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "peaks-loop",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.25",
|
|
4
4
|
"description": "Loop Engineering CLI — workflow primitive / loop guards / evaluators / slice orchestration",
|
|
5
5
|
"author": "SquabbyZ",
|
|
6
6
|
"keywords": [
|
|
@@ -102,10 +102,10 @@
|
|
|
102
102
|
"headroom-ai": "0.22.4",
|
|
103
103
|
"yaml": "^2.9.0",
|
|
104
104
|
"zod": "^4.4.3",
|
|
105
|
-
"peaks-loop-internal-runtime": "0.0.
|
|
106
|
-
"peaks-loop-mut": "0.1.
|
|
107
|
-
"peaks-loop-shared": "0.0.
|
|
108
|
-
"peaks-loop-shared
|
|
105
|
+
"peaks-loop-internal-runtime": "0.0.10",
|
|
106
|
+
"peaks-loop-mut": "0.1.23",
|
|
107
|
+
"peaks-loop-shared-channel": "0.0.27",
|
|
108
|
+
"peaks-loop-shared": "0.0.59"
|
|
109
109
|
},
|
|
110
110
|
"devDependencies": {
|
|
111
111
|
"@changesets/cli": "2.31.1",
|
|
@@ -189,6 +189,12 @@ When RD work creates a frontend application and the user has not specified a tec
|
|
|
189
189
|
|
|
190
190
|
→ see `references/frontend-project-generation.md` for the scaffold protocol.
|
|
191
191
|
|
|
192
|
+
## Frontend anti-corruption layer (ACL)
|
|
193
|
+
|
|
194
|
+
When RD work touches the frontend (pure frontend or full-stack), enforce the ACL discipline: the frontend's internal model is never polluted by external / API shapes. DTO ↔ ViewModel mapping converts external fields to internal fields at the boundary, and all conversion logic lives in one mapper file per domain (e.g. `mappers/user.mapper.ts`) — never scattered across pages. Hard constraint, verified by QA / code-review.
|
|
195
|
+
|
|
196
|
+
→ see `references/frontend-acl-mapper.md` for the three rules + reference shape + verification.
|
|
197
|
+
|
|
192
198
|
## Artifact and standards output
|
|
193
199
|
|
|
194
200
|
When project identification or scanning produces reports, matrices, maps, plans, or validation files, write them under the configured Peaks-Loop artifact workspace (default: `.peaks/_runtime/<sessionId>/rd/`). Do not default to a git-backed artifact repository or external artifact sync. Route standards mutations through `peaks standards init/update`; do not hand-write. Do not update user-global `~/.claude/rules/**` from this workflow.
|
|
@@ -267,6 +273,7 @@ Index of every `references/` file in this skill. Read on demand.
|
|
|
267
273
|
| `references/compact-handoff.md` | RD compact handoff capsule. |
|
|
268
274
|
| `references/external-references.md` | External 3rd-party inventory. |
|
|
269
275
|
| `references/frontend-project-generation.md` | React + Vite + shadcn/ui default. |
|
|
276
|
+
| `references/frontend-acl-mapper.md` | 前端防腐层 ACL + DTO↔VM 映射 + Mapper 聚合硬约束. |
|
|
270
277
|
| `references/library-version-awareness.md` | Breaking-change gate + freshness check. |
|
|
271
278
|
| `references/mandatory-perf-baseline.md` | RD-side perf baseline + `peaks perf baseline` workflow. |
|
|
272
279
|
| `references/matt-pocock-integration.md` | Matt Pocock skills as references. |
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Frontend anti-corruption layer (ACL) + Mapper aggregation (RD)
|
|
2
|
+
|
|
3
|
+
> Body of `## Frontend anti-corruption layer (ACL)`. When RD work touches the frontend (pure frontend OR full-stack), the frontend's internal model MUST NOT be polluted by external / API data shapes. Enforce the anti-corruption layer (ACL) discipline on every frontend slice.
|
|
4
|
+
|
|
5
|
+
## Three hard rules (BLOCKING)
|
|
6
|
+
|
|
7
|
+
1. **ACL — protect the frontend internals.** The frontend never consumes backend / API DTOs directly in components, pages, hooks, or stores. An anti-corruption layer translates every external shape into an internal one at the boundary.
|
|
8
|
+
|
|
9
|
+
2. **DTO ↔ ViewModel mapping — external fields → internal fields.** API / DTO field names and nesting are external concerns. Map them to internal ViewModel fields at the boundary. Backend field/schema drift must not leak past the mapper.
|
|
10
|
+
|
|
11
|
+
3. **Mapper aggregation — one file per domain.** All conversion logic for a domain lives in exactly one mapper file (e.g. `mappers/user.mapper.ts`), never scattered across pages / components. A page or component imports the mapper; it does not inline a mapping.
|
|
12
|
+
|
|
13
|
+
## Reference shape
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
// mappers/user.mapper.ts — the ONLY place user DTO ↔ ViewModel mapping lives
|
|
17
|
+
import type { UserDTO } from '@/api/types'; // external
|
|
18
|
+
import type { UserViewModel } from '@/models/user'; // internal
|
|
19
|
+
|
|
20
|
+
export function toUserViewModel(dto: UserDTO): UserViewModel {
|
|
21
|
+
return { id: dto.user_id, name: dto.display_name, avatar: dto.avatar_url };
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Components / hooks import `toUserViewModel`; they never destructure `dto.user_id` directly.
|
|
26
|
+
|
|
27
|
+
## Verification
|
|
28
|
+
|
|
29
|
+
QA / code-review must flag: (a) any component / hook / store consuming a `*DTO` or a raw API response field directly, (b) any `*.mapper.ts` duplication across pages. The mapper is the single translation seam between external DTOs and the internal ViewModel.
|
|
@@ -2,4 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
> Body of `## Codegraph orchestration context`. Code treats `peaks codegraph affected --project <path> <changed-files...> --json` as an optional project-analysis enhancement that informs the role handoff between PRD, RD, and QA. The output is untrusted supporting evidence — Code must not treat codegraph output as approval for scope, design, or QA verdict.
|
|
4
4
|
|
|
5
|
-
Do not run upstream installer flows, mutate agent settings, or commit `.codegraph/` artifacts into git. Peaks-Loop gates remain authoritative; codegraph context is a hint, never a substitute for role-skill output.
|
|
5
|
+
Do not run upstream installer flows, mutate agent settings, or commit `.codegraph/` artifacts into git. Peaks-Loop gates remain authoritative; codegraph context is a hint, never a substitute for role-skill output.
|
|
6
|
+
|
|
7
|
+
## Post-slice incremental re-index (slice 2026-09-01-feedback)
|
|
8
|
+
|
|
9
|
+
After each slice / task completes (RD done → QA done), the orchestrator MUST proactively run `peaks codegraph index --project <path>` to refresh the codegraph so the next slice's `affected` / `query` / `context` reflect the latest code — never a stale pre-slice graph. `index` is an incremental refresh; `peaks codegraph init` runs once per project, `index` runs after every slice.
|
|
10
|
+
|
|
11
|
+
The upstream bare `codegraph <subcommand>` binary is NOT on PATH — always route through `peaks codegraph <subcommand>`. (Upstream's own `status` output prints `Run "codegraph init" to initialize`; that bare-command hint is misleading in the peaks-loop context. A separate fix slice rewrites it to `peaks codegraph init`.)
|