@lmzhen/dsh-evolution-merge 0.0.0-stage → 0.28.0

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.
Files changed (55) hide show
  1. package/README.md +25 -2
  2. package/lib/index.js +3997 -0
  3. package/lib/types/adapters/channel.d.ts +42 -0
  4. package/lib/types/adapters/library.d.ts +8 -0
  5. package/lib/types/adapters/model.d.ts +31 -0
  6. package/lib/types/adapters/undo.d.ts +9 -0
  7. package/lib/types/approve-command.d.ts +22 -0
  8. package/lib/types/authoring-flow.d.ts +35 -0
  9. package/lib/types/channel-port.d.ts +60 -0
  10. package/lib/types/commands.d.ts +55 -0
  11. package/lib/types/commit-assembly.d.ts +25 -0
  12. package/lib/types/commit-execute.d.ts +29 -0
  13. package/lib/types/commit-plan.d.ts +45 -0
  14. package/lib/types/commit-receipt.d.ts +14 -0
  15. package/lib/types/contracts.d.ts +136 -0
  16. package/lib/types/coordinator.d.ts +57 -0
  17. package/lib/types/decision.d.ts +18 -0
  18. package/lib/types/doctor.d.ts +10 -0
  19. package/lib/types/gate-cache.d.ts +12 -0
  20. package/lib/types/gate-filter.d.ts +31 -0
  21. package/lib/types/index.d.ts +82 -0
  22. package/lib/types/ladder.d.ts +65 -0
  23. package/lib/types/merge-command.d.ts +36 -0
  24. package/lib/types/merge-routes.d.ts +23 -0
  25. package/lib/types/merge-tool.d.ts +22 -0
  26. package/lib/types/new-child-authoring.d.ts +29 -0
  27. package/lib/types/pair-command.d.ts +20 -0
  28. package/lib/types/params.d.ts +13 -0
  29. package/lib/types/pending-actions.d.ts +17 -0
  30. package/lib/types/prompts.d.ts +13 -0
  31. package/lib/types/propose.d.ts +26 -0
  32. package/lib/types/read-commands.d.ts +9 -0
  33. package/lib/types/report.d.ts +10 -0
  34. package/lib/types/resume-command.d.ts +24 -0
  35. package/lib/types/round2-outcome.d.ts +13 -0
  36. package/lib/types/routes.d.ts +49 -0
  37. package/lib/types/rules.d.ts +24 -0
  38. package/lib/types/run-shell.d.ts +65 -0
  39. package/lib/types/runtime.d.ts +38 -0
  40. package/lib/types/scan-command.d.ts +21 -0
  41. package/lib/types/scan-ports.d.ts +32 -0
  42. package/lib/types/scan-run.d.ts +44 -0
  43. package/lib/types/screening-port.d.ts +47 -0
  44. package/lib/types/screening.d.ts +30 -0
  45. package/lib/types/skipped.d.ts +8 -0
  46. package/lib/types/stage-tool-registry.d.ts +14 -0
  47. package/lib/types/stage-tool.d.ts +45 -0
  48. package/lib/types/staged-tree.d.ts +4 -0
  49. package/lib/types/staging-files.d.ts +15 -0
  50. package/lib/types/staging.d.ts +43 -0
  51. package/lib/types/state.d.ts +29 -0
  52. package/lib/types/status.d.ts +14 -0
  53. package/lib/types/supersede.d.ts +8 -0
  54. package/lib/types/undo-merge.d.ts +13 -0
  55. package/package.json +40 -4
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The scan pair loop. Registry/report lifecycle stays in withMergeRun; this module owns
3
+ * candidate → round1 → pending/fuse → commit transitions and returns the report draft.
4
+ */
5
+ import { type MergeCandidate, type MergeDecision, type MergeFailure, type MergeRow } from './contracts.ts';
6
+ import type { EvolutionIoLike, RunStage } from '@lmzhen/dsh-evolution-core';
7
+ import type { MergeRunReportDraft } from './run-shell.ts';
8
+ export interface ScanRound1Outcome {
9
+ readonly kind: 'keep' | 'merge' | 'failed';
10
+ readonly decision?: MergeDecision;
11
+ readonly failure?: MergeFailure;
12
+ }
13
+ export interface ScanRound2Outcome {
14
+ readonly kind: 'merged' | 'failed';
15
+ readonly unitId?: string;
16
+ readonly archived?: readonly string[];
17
+ readonly target?: {
18
+ readonly requested: string;
19
+ readonly actual: string;
20
+ readonly created: boolean;
21
+ };
22
+ readonly failure?: MergeFailure;
23
+ }
24
+ export interface ScanPorts {
25
+ screening(signal: AbortSignal): Promise<readonly MergeCandidate[]>;
26
+ round1(candidate: MergeCandidate, signal: AbortSignal): Promise<ScanRound1Outcome>;
27
+ round2(row: MergeRow, decision: MergeDecision, signal: AbortSignal): Promise<ScanRound2Outcome>;
28
+ }
29
+ export interface RunScanOptions {
30
+ readonly io: EvolutionIoLike;
31
+ readonly home: string;
32
+ readonly now: () => number;
33
+ readonly signal: AbortSignal;
34
+ readonly approval: boolean;
35
+ readonly timeoutMinutes?: number;
36
+ readonly startedAt?: number;
37
+ readonly ports: ScanPorts;
38
+ readonly stage?: (stage: RunStage, progress?: {
39
+ done: number;
40
+ total: number;
41
+ }) => Promise<void>;
42
+ }
43
+ export declare function runScan(options: RunScanOptions): Promise<MergeRunReportDraft>;
44
+ //# sourceMappingURL=scan-run.d.ts.map
@@ -0,0 +1,47 @@
1
+ /**
2
+ * The real screening port: lexical floor + optional C3 proposal + optional L0–L2 gate.
3
+ * Each stage is independently testable; this file only composes their frozen contracts.
4
+ */
5
+ import { type MergeCandidate } from './contracts.ts';
6
+ import { type SkillCard, type ScreeningOptions } from './screening.ts';
7
+ import { type ModelPort } from './propose.ts';
8
+ import type { GateCache, GateModelPort } from './ladder.ts';
9
+ export interface ScreeningForRunOptions extends Omit<BuildScreeningOptions, 'signal'> {
10
+ readonly runSeed: string;
11
+ }
12
+ export interface BuildScreeningOptions {
13
+ readonly cards: readonly SkillCard[];
14
+ readonly signal: AbortSignal;
15
+ readonly lexical?: ScreeningOptions;
16
+ readonly propose?: {
17
+ readonly model: ModelPort;
18
+ readonly shardSize?: number;
19
+ readonly maxPairs?: number;
20
+ };
21
+ readonly gate?: {
22
+ readonly model: GateModelPort;
23
+ readonly modelName: string;
24
+ readonly runSeed: string;
25
+ readonly cache?: GateCache;
26
+ readonly auditRate?: number;
27
+ };
28
+ }
29
+ export interface ScreeningPortStats {
30
+ readonly lexical: number;
31
+ readonly proposed: number;
32
+ readonly candidates: number;
33
+ readonly kept: number;
34
+ readonly dropped: number;
35
+ readonly gateCalls: number;
36
+ readonly gateErrors: number;
37
+ readonly shards: number;
38
+ }
39
+ export interface ScreeningPortResult {
40
+ readonly candidates: readonly MergeCandidate[];
41
+ readonly stats: ScreeningPortStats;
42
+ readonly degraded: readonly string[];
43
+ }
44
+ export declare function buildScreeningCandidates(options: BuildScreeningOptions): Promise<ScreeningPortResult>;
45
+ /** Build the run-scoped screening function; the run id seeds the 10% audit. */
46
+ export declare function createScreeningForRun(options: ScreeningForRunOptions): (signal: AbortSignal) => Promise<readonly MergeCandidate[]>;
47
+ //# sourceMappingURL=screening-port.d.ts.map
@@ -0,0 +1,30 @@
1
+ import type { MergeCandidate } from './contracts.ts';
2
+ export interface SkillCard {
3
+ readonly name: string;
4
+ readonly description: string;
5
+ readonly body: string;
6
+ }
7
+ export interface ScreeningOptions {
8
+ /** Body Jaccard at/above this is a candidate on its own. */
9
+ readonly bodyGate?: number;
10
+ /** Description Jaccard at/above this is a candidate when the body also clears minAffinity. */
11
+ readonly summaryGate?: number;
12
+ /** Minimum body affinity for a summary-led candidate. */
13
+ readonly minAffinity?: number;
14
+ /** Upper bound after sorting by score; absent = no cap. */
15
+ readonly maxCandidates?: number;
16
+ }
17
+ export interface ScreeningStats {
18
+ readonly skills: number;
19
+ readonly filtered: number;
20
+ readonly candidates: number;
21
+ }
22
+ export interface ScreeningResult {
23
+ readonly candidates: readonly MergeCandidate[];
24
+ readonly stats: ScreeningStats;
25
+ }
26
+ /** Shannon entropy over characters; a cheap prefilter signal, not a name-quality judge. */
27
+ export declare function nameEntropy(name: string): number;
28
+ export declare function prefilter(cards: readonly SkillCard[]): readonly SkillCard[];
29
+ export declare function lexicalCandidates(cards: readonly SkillCard[], options?: ScreeningOptions): ScreeningResult;
30
+ //# sourceMappingURL=screening.d.ts.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Skipped filtering: a pair the operator marked as not-worth-merging stays out of automatic
3
+ * screening until mergeSkippedTtlDays expires. Explicit /merge pair ignores this set.
4
+ */
5
+ import { type MergeRow } from './contracts.ts';
6
+ export declare function skippedPairKeys(rows: readonly MergeRow[], ttlDays: number, now: number): ReadonlySet<string>;
7
+ export declare function isSkippedPair(keys: ReadonlySet<string>, a: string, b: string): boolean;
8
+ //# sourceMappingURL=skipped.d.ts.map
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Child-scoped stage-tool bindings. A round child is bound only for the window in which its
3
+ * staging writes are legal; the tool resolves the caller from the platform exec and refuses
4
+ * when no binding exists.
5
+ */
6
+ import type { StageToolContext } from './stage-tool.ts';
7
+ export declare class StageToolRegistry {
8
+ private readonly bindings;
9
+ bind(childId: string, context: StageToolContext): void;
10
+ unbind(childId: string): void;
11
+ clear(): void;
12
+ resolve(exec: unknown): StageToolContext | undefined;
13
+ }
14
+ //# sourceMappingURL=stage-tool-registry.d.ts.map
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The pure half of the model-facing merge_stage tool.
3
+ *
4
+ * Registration/session binding lives in the plugin shell; this function owns the rules a
5
+ * caller cannot bypass: only the bound merge child, and only the author phase may write.
6
+ */
7
+ import type { EvolutionIoLike } from '@lmzhen/dsh-evolution-core';
8
+ import { type StageArea } from './staging-files.ts';
9
+ export type StagePhase = 'decide' | 'author';
10
+ export interface StageToolContext {
11
+ readonly runId: string;
12
+ readonly childId: string;
13
+ readonly expectedChildId: string;
14
+ readonly phase: StagePhase;
15
+ }
16
+ export type StageToolOp = {
17
+ readonly op: 'list';
18
+ readonly area: StageArea;
19
+ readonly path?: string;
20
+ readonly source?: string;
21
+ } | {
22
+ readonly op: 'read';
23
+ readonly area: StageArea;
24
+ readonly path: string;
25
+ readonly source?: string;
26
+ } | {
27
+ readonly op: 'write';
28
+ readonly path: string;
29
+ readonly content: string;
30
+ } | {
31
+ readonly op: 'copy';
32
+ readonly source: string;
33
+ readonly from: string;
34
+ readonly to: string;
35
+ };
36
+ export type StageToolResult = {
37
+ readonly ok: true;
38
+ readonly value?: unknown;
39
+ } | {
40
+ readonly ok: false;
41
+ readonly code: 'not-merge-child' | 'phase' | 'not-found' | 'io' | 'bad-path';
42
+ readonly message: string;
43
+ };
44
+ export declare function applyStageTool(io: EvolutionIoLike, home: string, ctx: StageToolContext, op: StageToolOp): Promise<StageToolResult>;
45
+ //# sourceMappingURL=stage-tool.d.ts.map
@@ -0,0 +1,4 @@
1
+ import { type EvolutionIoLike, type Probe } from '@lmzhen/dsh-evolution-core';
2
+ import type { StagedTree } from './rules.ts';
3
+ export declare function readStagedTree(io: EvolutionIoLike, home: string, runId: string): Promise<Probe<StagedTree>>;
4
+ //# sourceMappingURL=staged-tree.d.ts.map
@@ -0,0 +1,15 @@
1
+ import { type EvolutionIoLike, type Probe } from '@lmzhen/dsh-evolution-core';
2
+ export type StageArea = 'sources' | 'merged';
3
+ export type StageWriteResult = {
4
+ readonly ok: true;
5
+ readonly path: string;
6
+ } | {
7
+ readonly ok: false;
8
+ readonly message: string;
9
+ };
10
+ export declare function writeStagedFile(io: EvolutionIoLike, home: string, runId: string, path: string, content: string, source?: string): Promise<StageWriteResult>;
11
+ export declare function readStagedFile(io: EvolutionIoLike, home: string, runId: string, path: string, area: StageArea, source?: string): Promise<Probe<string>>;
12
+ export declare function listStagedFiles(io: EvolutionIoLike, home: string, runId: string, area: StageArea, path?: string, source?: string): Promise<Probe<readonly string[]>>;
13
+ /** Copy one source file into the merged target; the only cross-area operation allowed. */
14
+ export declare function copyStagedFile(io: EvolutionIoLike, home: string, runId: string, source: string, from: string, to: string): Promise<StageWriteResult>;
15
+ //# sourceMappingURL=staging-files.d.ts.map
@@ -0,0 +1,43 @@
1
+ import { type EvolutionIoLike, type Probe } from '@lmzhen/dsh-evolution-core';
2
+ export declare const STAGING_SCHEMA_VERSION = 1;
3
+ export declare function stagingRoot(home: string, runId: string): string;
4
+ export interface StagingSource {
5
+ readonly name: string;
6
+ readonly body: string;
7
+ readonly files: readonly {
8
+ readonly path: string;
9
+ readonly content: string;
10
+ }[];
11
+ }
12
+ export interface StagingManifest {
13
+ readonly schemaVersion: typeof STAGING_SCHEMA_VERSION;
14
+ readonly runId: string;
15
+ readonly target: string;
16
+ readonly sources: readonly string[];
17
+ readonly promptVersion: string;
18
+ readonly createdAt: number;
19
+ readonly expiresAt: number;
20
+ }
21
+ export interface CreateStagingInput {
22
+ readonly runId: string;
23
+ readonly target: string;
24
+ readonly sources: readonly StagingSource[];
25
+ readonly promptVersion: string;
26
+ readonly ttlDays: number;
27
+ readonly now: () => number;
28
+ }
29
+ export type CreateStagingResult = {
30
+ readonly ok: true;
31
+ readonly path: string;
32
+ readonly manifest: StagingManifest;
33
+ } | {
34
+ readonly ok: false;
35
+ readonly message: string;
36
+ };
37
+ export declare function createStaging(io: EvolutionIoLike, home: string, input: CreateStagingInput): Promise<CreateStagingResult>;
38
+ export interface StagedView {
39
+ readonly path: string;
40
+ readonly manifest: StagingManifest;
41
+ }
42
+ export declare function readStaging(io: EvolutionIoLike, home: string, runId: string): Promise<Probe<StagedView>>;
43
+ //# sourceMappingURL=staging.d.ts.map
@@ -0,0 +1,29 @@
1
+ import type { EvolutionIoLike } from '@lmzhen/dsh-evolution-core';
2
+ import { type MergePairState, type MergeQueue, type MergeRow, type MergeState } from './contracts.ts';
3
+ export declare function mergeStatePath(home: string): string;
4
+ export interface LoadMergeStateResult {
5
+ readonly ok: boolean;
6
+ readonly state: MergeState;
7
+ readonly note?: string;
8
+ }
9
+ /** Pure read: never writes, never deletes a row. */
10
+ export declare function loadMergeState(io: EvolutionIoLike, home: string): Promise<LoadMergeStateResult>;
11
+ /** The ONE write point. The callback returns the whole row set, not a delta. */
12
+ export declare function mutateMergeState<T>(io: EvolutionIoLike, home: string, now: () => number, fn: (rows: readonly MergeRow[]) => {
13
+ rows: readonly MergeRow[];
14
+ result: T;
15
+ }): Promise<T>;
16
+ export interface MoveRowPatch {
17
+ readonly queue: MergeQueue;
18
+ readonly state?: MergePairState;
19
+ readonly failure?: MergeRow['failure'];
20
+ readonly runId?: string;
21
+ readonly unitId?: string;
22
+ readonly origin?: MergeRow['origin'];
23
+ readonly attempts?: number;
24
+ }
25
+ export declare function upsertRow(io: EvolutionIoLike, home: string, now: () => number, row: MergeRow): Promise<void>;
26
+ export declare function moveRow(io: EvolutionIoLike, home: string, now: () => number, id: string, patch: MoveRowPatch): Promise<MergeRow | undefined>;
27
+ export declare function dropRow(io: EvolutionIoLike, home: string, now: () => number, id: string): Promise<boolean>;
28
+ export declare function rowsOf(io: EvolutionIoLike, home: string, queue?: MergeQueue): Promise<readonly MergeRow[]>;
29
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Read-only status projections for the merge command/panel. Pure formatting over rows; no
3
+ * writes, no report reads. The UI and command parser share this vocabulary.
4
+ */
5
+ import type { MergeQueue, MergeRow } from './contracts.ts';
6
+ export interface MergeCounts {
7
+ readonly pending: number;
8
+ readonly retry: number;
9
+ readonly skipped: number;
10
+ }
11
+ export declare function countRows(rows: readonly MergeRow[]): MergeCounts;
12
+ export declare function formatStatus(rows: readonly MergeRow[]): string;
13
+ export declare function formatQueue(rows: readonly MergeRow[], queue: MergeQueue): string;
14
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * A tree restore invalidates earlier merge runs: their commit receipts may describe a tree
3
+ * that no longer exists. Mark every non-superseded merge run in this process's registry.
4
+ */
5
+ import type { RunRecord, RunRegistry } from '@lmzhen/dsh-evolution-core';
6
+ export declare function mergeRunIdsToSupersede(runs: readonly RunRecord[]): readonly string[];
7
+ export declare function supersedeMergeRuns(registry: RunRegistry): Promise<number>;
8
+ //# sourceMappingURL=supersede.d.ts.map
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Execute a merge undo from its commit receipt. The receipt names the unit and archived
3
+ * sources; this module resolves versions, plans the cross-skill undo and runs the shared
4
+ * executor. No command/routing logic here.
5
+ */
6
+ import type { SkillVersion } from '@lmzhen/dsh-evolution-core';
7
+ import { type UnitUndoExecution, type UnitUndoSink } from '@lmzhen/dsh-evolution-core';
8
+ import type { CommitReceipt } from './commit-receipt.ts';
9
+ export interface MergeUndoPort extends UnitUndoSink {
10
+ listVersions(skill: string): Promise<readonly SkillVersion[]>;
11
+ }
12
+ export declare function undoMergeReceipt(receipt: CommitReceipt, port: MergeUndoPort): Promise<UnitUndoExecution>;
13
+ //# sourceMappingURL=undo-merge.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,42 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-merge",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "description": "Skill auto-merge domain: screening, two-round authoring, queues and commit orchestration (community build)",
4
+ "version": "0.28.0",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/lmzhen/dsh-evolution.git",
11
+ "directory": "packages/evolution-merge"
12
+ },
13
+ "type": "module",
14
+ "main": "lib/index.js",
15
+ "types": "lib/types/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./lib/types/index.d.ts",
19
+ "default": "./lib/index.js"
20
+ },
21
+ "./package.json": "./package.json"
22
+ },
23
+ "files": [
24
+ "lib/*.js",
25
+ "lib/types/**/*.d.ts"
26
+ ],
27
+ "license": "MIT",
28
+ "dependencies": {
29
+ "@deepseek-ai/schemastery": "^3.18.5",
30
+ "@lmzhen/dsh-evolution-core": "^0.28.0"
31
+ },
32
+ "peerDependencies": {
33
+ "@deepseek-ai/cordis": "^4.0.5"
34
+ },
35
+ "devDependencies": {
36
+ "@deepseek-ai/cordis": "^4.0.5",
37
+ "@lmzhen/dsh-evolution-core": "^0.28.0"
38
+ },
39
+ "engines": {
40
+ "dsh": ">=0.2.1-rc.1 <0.2.2-0"
41
+ }
42
+ }