@lmzhen/dsh-evolution-merge 0.0.0 → 0.29.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 (53) hide show
  1. package/README.md +27 -1
  2. package/lib/index.js +3814 -0
  3. package/lib/types/adapters/channel.d.ts +42 -0
  4. package/lib/types/adapters/engine-screen.d.ts +55 -0
  5. package/lib/types/adapters/library.d.ts +8 -0
  6. package/lib/types/adapters/model-runner.d.ts +28 -0
  7. package/lib/types/adapters/undo.d.ts +9 -0
  8. package/lib/types/approve-command.d.ts +22 -0
  9. package/lib/types/authoring-flow.d.ts +40 -0
  10. package/lib/types/channel-port.d.ts +61 -0
  11. package/lib/types/commands.d.ts +55 -0
  12. package/lib/types/commit-assembly.d.ts +27 -0
  13. package/lib/types/commit-execute.d.ts +29 -0
  14. package/lib/types/commit-plan.d.ts +45 -0
  15. package/lib/types/commit-receipt.d.ts +17 -0
  16. package/lib/types/contracts.d.ts +141 -0
  17. package/lib/types/coordinator.d.ts +65 -0
  18. package/lib/types/decision.d.ts +18 -0
  19. package/lib/types/doctor.d.ts +10 -0
  20. package/lib/types/gate-cache.d.ts +12 -0
  21. package/lib/types/index.d.ts +81 -0
  22. package/lib/types/ladder.d.ts +65 -0
  23. package/lib/types/merge-command.d.ts +39 -0
  24. package/lib/types/merge-routes.d.ts +24 -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 +14 -0
  29. package/lib/types/pending-actions.d.ts +17 -0
  30. package/lib/types/prompts.d.ts +15 -0
  31. package/lib/types/read-commands.d.ts +9 -0
  32. package/lib/types/report.d.ts +10 -0
  33. package/lib/types/resume-command.d.ts +24 -0
  34. package/lib/types/round2-outcome.d.ts +13 -0
  35. package/lib/types/routes.d.ts +64 -0
  36. package/lib/types/rules.d.ts +24 -0
  37. package/lib/types/run-shell.d.ts +65 -0
  38. package/lib/types/runtime.d.ts +37 -0
  39. package/lib/types/scan-command.d.ts +21 -0
  40. package/lib/types/scan-ports.d.ts +32 -0
  41. package/lib/types/scan-run.d.ts +46 -0
  42. package/lib/types/skill-card.d.ts +12 -0
  43. package/lib/types/skipped.d.ts +8 -0
  44. package/lib/types/stage-tool-registry.d.ts +14 -0
  45. package/lib/types/stage-tool.d.ts +45 -0
  46. package/lib/types/staged-tree.d.ts +4 -0
  47. package/lib/types/staging-files.d.ts +15 -0
  48. package/lib/types/staging.d.ts +49 -0
  49. package/lib/types/state.d.ts +29 -0
  50. package/lib/types/status.d.ts +14 -0
  51. package/lib/types/supersede.d.ts +8 -0
  52. package/lib/types/undo-merge.d.ts +13 -0
  53. package/package.json +31 -3
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Compose the channel and authoring flow into ScanPorts for a scan run.
3
+ *
4
+ * Approval off: round1 keeps the child, round2 authors the staging tree, then commits.
5
+ * Approval on: round1 disposes the child immediately; the row waits in pending and the later
6
+ * approve run must open a new child (not handled by this factory).
7
+ */
8
+ import type { EvolutionIoLike } from '@lmzhen/dsh-evolution-core';
9
+ import type { SkillCard } from './skill-card.ts';
10
+ import { type ConversationChannelLike } from './channel-port.ts';
11
+ import type { CommitPort } from './commit-execute.ts';
12
+ import type { StageToolContext } from './stage-tool.ts';
13
+ import type { ScanPorts } from './scan-run.ts';
14
+ export interface CreateScanPortsOptions {
15
+ readonly io: EvolutionIoLike;
16
+ readonly home: string;
17
+ readonly runId: string;
18
+ readonly cards: readonly SkillCard[];
19
+ readonly screening: ScanPorts['screening'];
20
+ readonly channel: ConversationChannelLike;
21
+ readonly parent: unknown;
22
+ readonly allow: readonly string[];
23
+ readonly cwd?: string;
24
+ readonly timeoutMs: number;
25
+ readonly approval: boolean;
26
+ readonly commitPort: CommitPort;
27
+ readonly now: () => number;
28
+ readonly onChild?: (context: StageToolContext) => void;
29
+ readonly onChildClosed?: (childId: string) => void;
30
+ }
31
+ export declare function createChannelScanPorts(options: CreateScanPortsOptions): ScanPorts;
32
+ //# sourceMappingURL=scan-ports.d.ts.map
@@ -0,0 +1,46 @@
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
+ readonly stagingRef?: string;
13
+ readonly stagingExpiresAt?: number;
14
+ }
15
+ export interface ScanRound2Outcome {
16
+ readonly kind: 'merged' | 'failed';
17
+ readonly unitId?: string;
18
+ readonly archived?: readonly string[];
19
+ readonly target?: {
20
+ readonly requested: string;
21
+ readonly actual: string;
22
+ readonly created: boolean;
23
+ };
24
+ readonly failure?: MergeFailure;
25
+ }
26
+ export interface ScanPorts {
27
+ screening(signal: AbortSignal): Promise<readonly MergeCandidate[]>;
28
+ round1(candidate: MergeCandidate, signal: AbortSignal): Promise<ScanRound1Outcome>;
29
+ round2(row: MergeRow, decision: MergeDecision, signal: AbortSignal): Promise<ScanRound2Outcome>;
30
+ }
31
+ export interface RunScanOptions {
32
+ readonly io: EvolutionIoLike;
33
+ readonly home: string;
34
+ readonly now: () => number;
35
+ readonly signal: AbortSignal;
36
+ readonly approval: boolean;
37
+ readonly timeoutMinutes?: number;
38
+ readonly startedAt?: number;
39
+ readonly ports: ScanPorts;
40
+ readonly stage?: (stage: RunStage, progress?: {
41
+ done: number;
42
+ total: number;
43
+ }) => Promise<void>;
44
+ }
45
+ export declare function runScan(options: RunScanOptions): Promise<MergeRunReportDraft>;
46
+ //# sourceMappingURL=scan-run.d.ts.map
@@ -0,0 +1,12 @@
1
+ export interface SkillCard {
2
+ readonly name: string;
3
+ readonly description: string;
4
+ readonly body: string;
5
+ readonly files?: readonly {
6
+ readonly path: string;
7
+ readonly content: string;
8
+ }[];
9
+ readonly protectedBy?: string | null;
10
+ readonly protectionUnknown?: boolean;
11
+ }
12
+ //# sourceMappingURL=skill-card.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,49 @@
1
+ import { type EvolutionIoLike, type Probe } from '@lmzhen/dsh-evolution-core';
2
+ export declare const STAGING_SCHEMA_VERSION = 1;
3
+ export declare function stageKeyOf(runId: string, pairKey: string): string;
4
+ export declare function stagingRoot(home: string, runId: string): string;
5
+ export interface StagingSource {
6
+ readonly name: string;
7
+ readonly body: string;
8
+ readonly files: readonly {
9
+ readonly path: string;
10
+ readonly content: string;
11
+ }[];
12
+ }
13
+ export interface StagingManifest {
14
+ readonly schemaVersion: typeof STAGING_SCHEMA_VERSION;
15
+ readonly runId: string;
16
+ readonly target: string;
17
+ readonly mode?: 'merge-into-existing' | 'create-umbrella' | 'keep';
18
+ readonly sources: readonly string[];
19
+ readonly promptVersion: string;
20
+ readonly createdAt: number;
21
+ readonly expiresAt: number;
22
+ }
23
+ export interface CreateStagingInput {
24
+ readonly runId: string;
25
+ readonly target: string;
26
+ readonly mode?: 'merge-into-existing' | 'create-umbrella' | 'keep';
27
+ readonly sources: readonly StagingSource[];
28
+ readonly promptVersion: string;
29
+ readonly ttlDays: number;
30
+ readonly now: () => number;
31
+ }
32
+ export type CreateStagingResult = {
33
+ readonly ok: true;
34
+ readonly path: string;
35
+ readonly manifest: StagingManifest;
36
+ } | {
37
+ readonly ok: false;
38
+ readonly message: string;
39
+ };
40
+ export declare function createStaging(io: EvolutionIoLike, home: string, input: CreateStagingInput): Promise<CreateStagingResult>;
41
+ export interface StagedView {
42
+ readonly path: string;
43
+ readonly manifest: StagingManifest;
44
+ }
45
+ export declare function readStaging(io: EvolutionIoLike, home: string, runId: string): Promise<Probe<StagedView>>;
46
+ export declare function ensureStaging(io: EvolutionIoLike, home: string, input: CreateStagingInput): Promise<CreateStagingResult>;
47
+ export declare function setStagingTarget(io: EvolutionIoLike, home: string, stageKey: string, target: string, mode?: 'merge-into-existing' | 'create-umbrella' | 'keep'): Promise<boolean>;
48
+ export declare function dropStaging(io: EvolutionIoLike, home: string, stageKey: string): Promise<void>;
49
+ //# 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,11 +1,39 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-merge",
3
- "version": "0.0.0",
4
- "description": "Placeholder for the skill merge host package; the release is published from CI.",
5
- "license": "MIT",
3
+ "description": "Skill auto-merge domain: screening, two-round authoring, queues and commit orchestration (community build)",
4
+ "version": "0.29.0",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
6
8
  "repository": {
7
9
  "type": "git",
8
10
  "url": "git+https://github.com/lmzhen/dsh-evolution.git",
9
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.29.0",
31
+ "@lmzhen/dsh-evolution-merge-engine": "^0.29.0"
32
+ },
33
+ "peerDependencies": {
34
+ "@deepseek-ai/cordis": "^4.0.5"
35
+ },
36
+ "engines": {
37
+ "dsh": ">=0.2.1-rc.1 <0.2.2-0"
10
38
  }
11
39
  }