peaks-loop 4.0.0-beta.2 → 4.0.0-beta.4
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 +81 -0
- package/README-en.md +16 -3
- package/README.md +16 -3
- package/dist/src/cli/commands/asset-commands.d.ts +45 -0
- package/dist/src/cli/commands/asset-commands.js +404 -0
- package/dist/src/cli/commands/bee-commands.d.ts +26 -0
- package/dist/src/cli/commands/bee-commands.js +169 -0
- package/dist/src/cli/commands/evolution-commands.d.ts +27 -0
- package/dist/src/cli/commands/evolution-commands.js +393 -0
- package/dist/src/cli/commands/loop-commands.d.ts +19 -13
- package/dist/src/cli/commands/loop-commands.js +147 -13
- package/dist/src/cli/commands/sediment-commands.js +9 -0
- package/dist/src/cli/commands/skill-loop-engineering-readiness-commands.d.ts +67 -0
- package/dist/src/cli/commands/skill-loop-engineering-readiness-commands.js +173 -0
- package/dist/src/cli/program.js +17 -0
- package/dist/src/services/crystallization/crystallization-service.d.ts +239 -0
- package/dist/src/services/crystallization/crystallization-service.js +397 -0
- package/dist/src/services/crystallization/crystallization-store.d.ts +75 -0
- package/dist/src/services/crystallization/crystallization-store.js +193 -0
- package/dist/src/services/crystallization/crystallization-types.d.ts +313 -0
- package/dist/src/services/crystallization/crystallization-types.js +299 -0
- package/dist/src/services/crystallization/evidence-brief-builder.d.ts +237 -0
- package/dist/src/services/crystallization/evidence-brief-builder.js +240 -0
- package/dist/src/services/evolution/evolution-service.d.ts +137 -0
- package/dist/src/services/evolution/evolution-service.js +281 -0
- package/dist/src/services/evolution/evolution-store.d.ts +57 -0
- package/dist/src/services/evolution/evolution-store.js +232 -0
- package/dist/src/services/evolution/evolution-types.d.ts +706 -0
- package/dist/src/services/evolution/evolution-types.js +286 -0
- package/dist/src/services/evolution/independent-evaluator-runner.d.ts +90 -0
- package/dist/src/services/evolution/independent-evaluator-runner.js +106 -0
- package/dist/src/services/evolution/regression-skeptic-runner.d.ts +64 -0
- package/dist/src/services/evolution/regression-skeptic-runner.js +113 -0
- package/dist/src/services/loop/loop-bee-relation-service.d.ts +107 -0
- package/dist/src/services/loop/loop-bee-relation-service.js +211 -0
- package/dist/src/services/loop/loop-bee-relation-store.d.ts +53 -0
- package/dist/src/services/loop/loop-bee-relation-store.js +130 -0
- package/dist/src/services/loop/loop-bee-relation-types.d.ts +118 -0
- package/dist/src/services/loop/loop-bee-relation-types.js +114 -0
- package/dist/src/services/loop/loop-release-service.d.ts +46 -0
- package/dist/src/services/loop/loop-release-service.js +66 -0
- package/dist/src/services/loop/loop-release-store.d.ts +55 -0
- package/dist/src/services/loop/loop-release-store.js +134 -0
- package/dist/src/services/loop/loop-release-types.d.ts +250 -0
- package/dist/src/services/loop/loop-release-types.js +162 -0
- package/dist/src/services/share/bundle-reader.d.ts +100 -0
- package/dist/src/services/share/bundle-reader.js +434 -0
- package/dist/src/services/share/bundle-types.d.ts +392 -0
- package/dist/src/services/share/bundle-types.js +318 -0
- package/dist/src/services/share/bundle-writer.d.ts +97 -0
- package/dist/src/services/share/bundle-writer.js +429 -0
- package/dist/src/services/share/run-state-contract.d.ts +133 -0
- package/dist/src/services/share/run-state-contract.js +138 -0
- package/dist/src/services/skillhub/release-import.js +7 -2
- package/dist/src/services/skillhub/release-retain.js +6 -1
- package/dist/src/services/skillhub/sqlite-store.js +17 -1
- package/dist/src/services/skillhub/types.d.ts +10 -0
- package/dist/src/services/standards/loop-engineering-lint.d.ts +38 -0
- package/dist/src/services/standards/loop-engineering-lint.js +101 -0
- package/dist/src/services/standards/loop-engineering-readiness-lint.d.ts +111 -0
- package/dist/src/services/standards/loop-engineering-readiness-lint.js +248 -0
- package/dist/src/shared/version.d.ts +1 -1
- package/dist/src/shared/version.js +1 -1
- package/examples/video-demo/README.md +57 -0
- package/examples/video-demo/out/en-closing-960.png +0 -0
- package/examples/video-demo/out/zh-closing-960.png +0 -0
- package/examples/video-demo/preview/peaks-loop-demo-en.mp4 +0 -0
- package/examples/video-demo/preview/peaks-loop-demo.mp4 +0 -0
- package/package.json +6 -2
- package/skills/peaks-code/SKILL.md +13 -0
- package/skills/peaks-content/SKILL.md +272 -0
- package/skills/peaks-issue-fix-orchestrator/SKILL.md +307 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* LoopRelease — spec §4.1 (Loop Engineering Asset).
|
|
4
|
+
*
|
|
5
|
+
* M1 scope was the §4.1 fields. M3 (this slice) ADDS the share /
|
|
6
|
+
* desktop extension fields from §4.1 / §7A:
|
|
7
|
+
* - shareable (boolean, default true)
|
|
8
|
+
* - share_excluded_paths (string[], default [])
|
|
9
|
+
* - desktop_visible (boolean, default true)
|
|
10
|
+
* - export_bundle_format ('peaks.bundle/1', CLI-written constant)
|
|
11
|
+
*
|
|
12
|
+
* The four M3 fields are added with `.default(...)` so an in-memory
|
|
13
|
+
* object built from a pre-M3 snapshot still parses after the
|
|
14
|
+
* migration runs. NO enforcement on `shareable=false` is added in M3
|
|
15
|
+
* — the schema-only addition is the contract; full export /
|
|
16
|
+
* desktop enforcement lands in M7 (see plan
|
|
17
|
+
* m3-bee-release-extension.md and spec §7A).
|
|
18
|
+
*
|
|
19
|
+
* Field semantics — see the spec for full prose. Highlights:
|
|
20
|
+
*
|
|
21
|
+
* - `id` is the stable kebab-case loop id; the storage key.
|
|
22
|
+
* - `schema_version` is the constant literal `"peaks.loop/1"`; a
|
|
23
|
+
* schema-version bump requires a new table / new enum case and a
|
|
24
|
+
* migration — never edit this literal in place.
|
|
25
|
+
* - `lifecycle_status` is `candidate` / `stable` / `retired`; the
|
|
26
|
+
* default on first crystallization is `candidate`. LLMs cannot
|
|
27
|
+
* auto-promote to `stable` (see spec §5.6).
|
|
28
|
+
* - `linked_bees` is a denormalized pointer list of bee ids; the
|
|
29
|
+
* authoritative loop↔bee relations live in `loop_bee_relation`
|
|
30
|
+
* (M2). Keeping it here matches the spec §4.1 row shape and lets
|
|
31
|
+
* M1 readers iterate the loop without an extra join.
|
|
32
|
+
* - `success_criteria` / `evaluator_policy` are NL strings, not
|
|
33
|
+
* machine-checked predicates; the evaluator definitions live in
|
|
34
|
+
* the M4 evolution layer.
|
|
35
|
+
* - `share_excluded_paths` is a JSON-encoded TEXT column at the
|
|
36
|
+
* SQLite layer; the Zod schema accepts a string[] and the store
|
|
37
|
+
* does the JSON.stringify/parse boundary work. Matches the
|
|
38
|
+
* existing `loop_release` style (success_criteria_json, …).
|
|
39
|
+
* - `export_bundle_format` is pinned to the literal
|
|
40
|
+
* `"peaks.bundle/1"` per the spec §7A.2 contract — no other
|
|
41
|
+
* value is accepted in this schema version.
|
|
42
|
+
*/
|
|
43
|
+
export const LoopReleaseLifecycleStatusSchema = z.enum([
|
|
44
|
+
"candidate",
|
|
45
|
+
"stable",
|
|
46
|
+
"retired",
|
|
47
|
+
]);
|
|
48
|
+
/**
|
|
49
|
+
* The M3 share / desktop extension fields, listed for code-search /
|
|
50
|
+
* lint discoverability. They are now part of the schema (with safe
|
|
51
|
+
* defaults) — see `LoopReleaseM3ExtensionSchema` below.
|
|
52
|
+
*
|
|
53
|
+
* - shareable: defaults to true.
|
|
54
|
+
* - share_excluded_paths: string[] (defaults to []).
|
|
55
|
+
* - desktop_visible: defaults to true.
|
|
56
|
+
* - export_bundle_format: constant "peaks.bundle/1" (CLI-written).
|
|
57
|
+
*/
|
|
58
|
+
export const LOOP_RELEASE_M3_FIELDS = [
|
|
59
|
+
"shareable",
|
|
60
|
+
"share_excluded_paths",
|
|
61
|
+
"desktop_visible",
|
|
62
|
+
"export_bundle_format",
|
|
63
|
+
];
|
|
64
|
+
/**
|
|
65
|
+
* M3 share / desktop extension schema. Added to `LoopReleaseInputSchema`
|
|
66
|
+
* via `.extend(...)` so existing callers that omit these fields still
|
|
67
|
+
* parse — the Zod defaults below supply the spec values
|
|
68
|
+
* (true / [] / true / "peaks.bundle/1").
|
|
69
|
+
*
|
|
70
|
+
* `export_bundle_format` is pinned to a literal per spec §7A.2: the
|
|
71
|
+
* CLI is the only writer and only `"peaks.bundle/1"` is accepted. A
|
|
72
|
+
* schema-version bump is required to introduce another value.
|
|
73
|
+
*/
|
|
74
|
+
export const LoopReleaseM3ExtensionSchema = z.object({
|
|
75
|
+
shareable: z.boolean().default(true),
|
|
76
|
+
share_excluded_paths: z
|
|
77
|
+
.array(z.string().min(1).max(4096))
|
|
78
|
+
.default([]),
|
|
79
|
+
desktop_visible: z.boolean().default(true),
|
|
80
|
+
export_bundle_format: z
|
|
81
|
+
.literal("peaks.bundle/1")
|
|
82
|
+
.default("peaks.bundle/1"),
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* Zod schema for the create payload (LoopReleaseInput). Mirrors the
|
|
86
|
+
* §4.1 row shape; `schema_version` is defaulted (clients cannot
|
|
87
|
+
* override it) and `created_at` is not part of the input — the store
|
|
88
|
+
* stamps it from the server clock.
|
|
89
|
+
*/
|
|
90
|
+
export const LoopReleaseInputSchema = z
|
|
91
|
+
.object({
|
|
92
|
+
id: z
|
|
93
|
+
.string()
|
|
94
|
+
.min(1)
|
|
95
|
+
.max(64)
|
|
96
|
+
.regex(/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/, {
|
|
97
|
+
message: "id must be kebab-case starting with a lowercase letter (e.g. loop-onboarding-research)",
|
|
98
|
+
}),
|
|
99
|
+
name: z.string().min(1).max(200),
|
|
100
|
+
scenario: z.string().trim().min(1).max(4000),
|
|
101
|
+
trigger_policy: z.string().trim().min(1).max(2000),
|
|
102
|
+
success_criteria: z
|
|
103
|
+
.array(z.string().trim().min(1).max(1000))
|
|
104
|
+
.min(1, "success_criteria must list at least one declarative criterion"),
|
|
105
|
+
interaction_policy: z
|
|
106
|
+
.string()
|
|
107
|
+
.trim()
|
|
108
|
+
.min(1, "interaction_policy must declare human-NL-choice-only semantics")
|
|
109
|
+
.max(2000),
|
|
110
|
+
feedback_policy: z.string().trim().min(1).max(2000),
|
|
111
|
+
evolution_policy: z.string().trim().min(1).max(2000),
|
|
112
|
+
evaluator_policy: z.array(z.string().trim().min(1).max(1000)).min(1),
|
|
113
|
+
linked_bees: z.array(z.string().min(1).max(64)).default([]),
|
|
114
|
+
run_history: z.array(z.string().min(1).max(128)).default([]),
|
|
115
|
+
crystallization_evidence: z.array(z.string().min(1).max(128)).default([]),
|
|
116
|
+
lifecycle_status: LoopReleaseLifecycleStatusSchema,
|
|
117
|
+
version: z
|
|
118
|
+
.string()
|
|
119
|
+
.regex(/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/, {
|
|
120
|
+
message: "version must be a semver string (e.g. 0.1.0)",
|
|
121
|
+
}),
|
|
122
|
+
})
|
|
123
|
+
.extend(LoopReleaseM3ExtensionSchema.shape);
|
|
124
|
+
/**
|
|
125
|
+
* Full Zod schema for a LoopRelease row as persisted. Differs from the
|
|
126
|
+
* input schema only in that `schema_version` is exposed (and defaulted
|
|
127
|
+
* to the fixed literal). The literal constraint still rejects any
|
|
128
|
+
* client-supplied value other than `"peaks.loop/1"`; the default
|
|
129
|
+
* means omitting the key is fine and the output always carries the
|
|
130
|
+
* constant.
|
|
131
|
+
*
|
|
132
|
+
* We expose this as the canonical "row schema" used by lint and
|
|
133
|
+
* service.create/read paths.
|
|
134
|
+
*/
|
|
135
|
+
export const LoopReleaseSchema = LoopReleaseInputSchema.extend({
|
|
136
|
+
schema_version: z
|
|
137
|
+
.literal("peaks.loop/1")
|
|
138
|
+
.default("peaks.loop/1"),
|
|
139
|
+
});
|
|
140
|
+
/**
|
|
141
|
+
* Convenience: strict-parse an unknown payload into a LoopRelease row.
|
|
142
|
+
* Throws ZodError on failure. This is the public validation boundary.
|
|
143
|
+
*/
|
|
144
|
+
export function parseLoopRelease(input) {
|
|
145
|
+
return LoopReleaseSchema.parse(input);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Convenience: safe-parse that returns a Result-like shape so callers
|
|
149
|
+
* (CLI layer in M5) can render findings without try/catch noise.
|
|
150
|
+
*/
|
|
151
|
+
export function safeParseLoopRelease(input) {
|
|
152
|
+
const r = LoopReleaseSchema.safeParse(input);
|
|
153
|
+
if (r.success)
|
|
154
|
+
return { ok: true, row: r.data };
|
|
155
|
+
return {
|
|
156
|
+
ok: false,
|
|
157
|
+
findings: r.error.issues.map((i) => ({
|
|
158
|
+
path: i.path.join("."),
|
|
159
|
+
message: i.message,
|
|
160
|
+
})),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bundle-reader.ts — readBundle(inPath) (spec §7A.2).
|
|
3
|
+
*
|
|
4
|
+
* M7 / spec §7A.2 / §10 RL-9 / acceptance AC-25 / AC-26.
|
|
5
|
+
*
|
|
6
|
+
* Reads a `peaks.bundle/1` tar.gz and lands the contained release
|
|
7
|
+
* on the local SkillHub. The reader is the symmetrical counterpart
|
|
8
|
+
* of `bundle-writer.ts` — same layout, same content-addressed
|
|
9
|
+
* blobs/, but with three hard guards:
|
|
10
|
+
*
|
|
11
|
+
* 1. `format_version_major !== 1` is a HARD block. The reader
|
|
12
|
+
* throws `SHARE_BUNDLE_MAJOR_VERSION_MISMATCH` before any
|
|
13
|
+
* SQL side-effect. (Major-version bumps are reserved for
|
|
14
|
+
* breaking schema changes; the receiver is not assumed to
|
|
15
|
+
* know how to translate.)
|
|
16
|
+
* 2. `format_version_minor` mismatch is a non-fatal warn (the
|
|
17
|
+
* reader collects it as a warning on the return envelope).
|
|
18
|
+
* 3. The imported release ALWAYS lands as `candidate`. The
|
|
19
|
+
* reader refuses to write any other status; the receiver
|
|
20
|
+
* MUST run an independent evaluation before promoting the
|
|
21
|
+
* imported release to `stable` (AC-26 — peaks loop promote
|
|
22
|
+
* reads evolution_evaluation rows).
|
|
23
|
+
*
|
|
24
|
+
* The reader is also the integration point for AC-26 — the loop
|
|
25
|
+
* promote path (which lives in a future slice / CLI command) checks
|
|
26
|
+
* `evolution_evaluation.independent_scorer_verdict` before allowing
|
|
27
|
+
* a candidate → stable transition; this slice does not add a new
|
|
28
|
+
* `peaks loop promote` because `peaks asset crystallize` already
|
|
29
|
+
* enforces the brief-section + pre-run gates and creates the
|
|
30
|
+
* initial `candidate` row. The integration test for AC-26 verifies
|
|
31
|
+
* that a freshly imported bundle has no `evolution_evaluation`
|
|
32
|
+
* row and that promotion therefore cannot proceed.
|
|
33
|
+
*/
|
|
34
|
+
import type Database from "better-sqlite3";
|
|
35
|
+
import { SHARE_BUNDLE_ERROR_CODES, type PeaksBundleKind } from "./bundle-types.js";
|
|
36
|
+
/**
|
|
37
|
+
* Thrown when `format_version_major !== 1`. This is the explicit
|
|
38
|
+
* HARD block per spec §7A.2 (major mismatch).
|
|
39
|
+
*/
|
|
40
|
+
export declare class BundleMajorVersionMismatchError extends Error {
|
|
41
|
+
readonly code: typeof SHARE_BUNDLE_ERROR_CODES.MAJOR_VERSION_MISMATCH;
|
|
42
|
+
readonly receivedMajor: number;
|
|
43
|
+
constructor(receivedMajor: number);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Thrown when the schema-versions mapping is missing or carries
|
|
47
|
+
* non-canonical literals.
|
|
48
|
+
*/
|
|
49
|
+
export declare class BundleSchemaVersionsMismatchError extends Error {
|
|
50
|
+
readonly code: typeof SHARE_BUNDLE_ERROR_CODES.SCHEMA_VERSIONS_MISMATCH;
|
|
51
|
+
readonly received: Record<string, unknown> | undefined;
|
|
52
|
+
constructor(received: Record<string, unknown> | undefined);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Thrown when the caller asks to land as anything other than
|
|
56
|
+
* `candidate` (the only allowed target status).
|
|
57
|
+
*/
|
|
58
|
+
export declare class BundleImportToStableForbiddenError extends Error {
|
|
59
|
+
readonly code: typeof SHARE_BUNDLE_ERROR_CODES.IMPORT_TO_STABLE_FORBIDDEN;
|
|
60
|
+
constructor(receivedStatus: string);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Thrown when the bundle tarball is malformed (no manifest.json,
|
|
64
|
+
* bad JSON, etc.). Distinct from a ZodError so the CLI can map
|
|
65
|
+
* to a single BUNDLE_MALFORMED code.
|
|
66
|
+
*/
|
|
67
|
+
export declare class BundleMalformedError extends Error {
|
|
68
|
+
readonly code: typeof SHARE_BUNDLE_ERROR_CODES.BUNDLE_MALFORMED;
|
|
69
|
+
constructor(message: string);
|
|
70
|
+
}
|
|
71
|
+
export type ReadBundleArgs = {
|
|
72
|
+
db: Database.Database;
|
|
73
|
+
/** Blobs root for content-addressed file write-back. */
|
|
74
|
+
blobsDir: string;
|
|
75
|
+
/** Input `.tar.gz` bundle path. */
|
|
76
|
+
inPath: string;
|
|
77
|
+
/**
|
|
78
|
+
* Optional rename for the anchor asset on import. For `loop`
|
|
79
|
+
* bundles this is the loop id to overwrite the source id; for
|
|
80
|
+
* `bee` bundles this is the `--as` bee name.
|
|
81
|
+
*/
|
|
82
|
+
asName?: string;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Successful read result. The reader lands the bundle as a
|
|
86
|
+
* `candidate` regardless of any other lifecycle status on the
|
|
87
|
+
* source — this is the hard import rule per spec §7A.2 / AC-25.
|
|
88
|
+
*/
|
|
89
|
+
export type ReadBundleResult = {
|
|
90
|
+
/** Anchor asset id actually written. */
|
|
91
|
+
assetId: string | number;
|
|
92
|
+
kind: PeaksBundleKind;
|
|
93
|
+
/** Always `candidate` — the reader does not honor any other status. */
|
|
94
|
+
importedAs: "candidate";
|
|
95
|
+
/** Non-fatal warnings (e.g. minor-version mismatch). */
|
|
96
|
+
warnings: string[];
|
|
97
|
+
/** Count of crystallization_event rows imported. */
|
|
98
|
+
evidenceBriefCount: number;
|
|
99
|
+
};
|
|
100
|
+
export declare function readBundle(args: ReadBundleArgs): ReadBundleResult;
|