@lmzhen/dsh-evolution-merge 0.30.13 → 0.30.14

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/lib/index.js CHANGED
@@ -1801,6 +1801,7 @@ async function runScan(options) {
1801
1801
  runId: options.runId
1802
1802
  };
1803
1803
  const before = (await loadMergeState(options.io, options.home)).state.rows.find((item) => item.pairKey === row.pairKey);
1804
+ if (before?.state === "verify" && before.runId !== void 0 && before.runId !== options.runId && await options.isOwnerActive?.(before.runId) === true) continue;
1804
1805
  const placed = await upsertRow(options.io, options.home, options.now, row, "verify", before?.updatedAt ?? null);
1805
1806
  if (!placed.ok && before?.state === "skipped") {
1806
1807
  const restored = transition(before, {
@@ -2178,7 +2179,8 @@ async function runScanCommand(options) {
2178
2179
  startedAt: ctx.startedAt,
2179
2180
  runId: ctx.runId,
2180
2181
  ...options.timeoutMinutes === void 0 ? {} : { timeoutMinutes: options.timeoutMinutes },
2181
- ...options.notes === void 0 ? {} : { notes: options.notes }
2182
+ ...options.notes === void 0 ? {} : { notes: options.notes },
2183
+ ...options.isOwnerActive === void 0 ? {} : { isOwnerActive: options.isOwnerActive }
2182
2184
  });
2183
2185
  }
2184
2186
  });
@@ -2467,32 +2469,38 @@ async function runResumeCommand(options) {
2467
2469
  ok: false,
2468
2470
  message: "merge row not found: " + options.rowId
2469
2471
  };
2470
- if (row.state === "verify") return await runScanCommand({
2471
- io: options.io,
2472
- home: options.home,
2473
- registry: options.registry,
2474
- approval: true,
2475
- platformWrite: options.platformWrite,
2476
- now: options.now,
2477
- ...options.makePorts === void 0 ? { ports: {
2478
- ...options.ports,
2479
- screening: () => Promise.resolve([{
2480
- a: row.a,
2481
- b: row.b
2482
- }])
2483
- } } : { makePorts: (runId) => {
2484
- const makePorts = options.makePorts;
2485
- if (makePorts === void 0) throw new Error("resume makePorts disappeared");
2486
- return {
2487
- ...makePorts(runId),
2472
+ if (row.state === "verify") {
2473
+ if (row.runId !== void 0 && await options.isOwnerActive?.(row.runId) === true) return {
2474
+ ok: false,
2475
+ message: "merge run still owns this verify row: " + row.runId
2476
+ };
2477
+ return await runScanCommand({
2478
+ io: options.io,
2479
+ home: options.home,
2480
+ registry: options.registry,
2481
+ approval: true,
2482
+ platformWrite: options.platformWrite,
2483
+ now: options.now,
2484
+ ...options.makePorts === void 0 ? { ports: {
2485
+ ...options.ports,
2488
2486
  screening: () => Promise.resolve([{
2489
2487
  a: row.a,
2490
2488
  b: row.b
2491
2489
  }])
2492
- };
2493
- } },
2494
- ...options.timeoutMinutes === void 0 ? {} : { timeoutMinutes: options.timeoutMinutes }
2495
- });
2490
+ } } : { makePorts: (runId) => {
2491
+ const makePorts = options.makePorts;
2492
+ if (makePorts === void 0) throw new Error("resume makePorts disappeared");
2493
+ return {
2494
+ ...makePorts(runId),
2495
+ screening: () => Promise.resolve([{
2496
+ a: row.a,
2497
+ b: row.b
2498
+ }])
2499
+ };
2500
+ } },
2501
+ ...options.timeoutMinutes === void 0 ? {} : { timeoutMinutes: options.timeoutMinutes }
2502
+ });
2503
+ }
2496
2504
  if (row.state !== "fuse" && row.state !== "approved") return {
2497
2505
  ok: false,
2498
2506
  message: "row is not resumable from state " + row.state
@@ -3774,6 +3782,7 @@ function createMergeRuntime(deps) {
3774
3782
  registry: deps.registry,
3775
3783
  platformWrite: deps.platformWrite,
3776
3784
  now: deps.now,
3785
+ ...deps.isOwnerActive === void 0 ? {} : { isOwnerActive: deps.isOwnerActive },
3777
3786
  ...timeout === void 0 ? {} : { timeoutMinutes: timeout }
3778
3787
  };
3779
3788
  const stage = deps.stage;
@@ -4092,6 +4101,7 @@ function createMergeRuntime(deps) {
4092
4101
  ...common,
4093
4102
  rowId: row.id,
4094
4103
  ports: basePorts,
4104
+ ...deps.isOwnerActive === void 0 ? {} : { isOwnerActive: deps.isOwnerActive },
4095
4105
  makePorts: (runId) => createChannelScanPorts({
4096
4106
  io: deps.io,
4097
4107
  home: deps.home,
@@ -4818,6 +4828,10 @@ function apply(ctx, rawConfig = {}) {
4818
4828
  isBlocked: async (name) => {
4819
4829
  return await ctx.get("evolutionCurator")?.isBlocked?.(name) === true;
4820
4830
  },
4831
+ isOwnerActive: (runId) => {
4832
+ const run = runs.find(runId);
4833
+ return run !== void 0 && run.state === "running";
4834
+ },
4821
4835
  async cards(signal) {
4822
4836
  const listed = await skills.list({ withContent: true });
4823
4837
  if (signal.aborted) return [];
@@ -222,6 +222,10 @@ export function apply(ctx, rawConfig = {}) {
222
222
  const curator = ctx.get('evolutionCurator');
223
223
  return (await curator?.isBlocked?.(name)) === true;
224
224
  },
225
+ isOwnerActive: (runId) => {
226
+ const run = runs.find(runId);
227
+ return run !== undefined && run.state === 'running';
228
+ },
225
229
  async cards(signal) {
226
230
  const listed = await skills.list({ withContent: true });
227
231
  if (signal.aborted)
@@ -19,6 +19,7 @@ export interface RunResumeCommandOptions {
19
19
  readonly platformWrite: boolean;
20
20
  readonly timeoutMinutes?: number;
21
21
  readonly now: () => number;
22
+ readonly isOwnerActive?: (runId: string) => boolean | Promise<boolean>;
22
23
  }
23
24
  export declare function runResumeCommand(options: RunResumeCommandOptions): Promise<WithMergeRunResult>;
24
25
  //# sourceMappingURL=resume-command.d.ts.map
@@ -8,6 +8,9 @@ export async function runResumeCommand(options) {
8
8
  if (row === undefined)
9
9
  return { ok: false, message: 'merge row not found: ' + options.rowId };
10
10
  if (row.state === 'verify') {
11
+ if (row.runId !== undefined && (await options.isOwnerActive?.(row.runId)) === true) {
12
+ return { ok: false, message: 'merge run still owns this verify row: ' + row.runId };
13
+ }
11
14
  return await runScanCommand({
12
15
  io: options.io, home: options.home, registry: options.registry,
13
16
  approval: true, platformWrite: options.platformWrite, now: options.now,
@@ -33,6 +33,7 @@ export interface MergeRuntimeDeps {
33
33
  readonly cards: (signal: AbortSignal) => Promise<readonly SkillCard[]>;
34
34
  /** Curator gate set: excluded/referenced/suppressed/protected builtins. */
35
35
  readonly isBlocked?: (name: string) => boolean | Promise<boolean>;
36
+ readonly isOwnerActive?: (runId: string) => boolean | Promise<boolean>;
36
37
  /** Run-scoped engine screening. */
37
38
  readonly screeningForRun: (cards: readonly SkillCard[], runId: string, signal: AbortSignal) => Promise<readonly MergeCandidate[]>;
38
39
  readonly stage?: MergeStageBindingPort;
@@ -34,6 +34,7 @@ export function createMergeRuntime(deps) {
34
34
  const common = {
35
35
  io: deps.io, home: deps.home, registry: deps.registry,
36
36
  platformWrite: deps.platformWrite, now: deps.now,
37
+ ...(deps.isOwnerActive === undefined ? {} : { isOwnerActive: deps.isOwnerActive }),
37
38
  ...(timeout === undefined ? {} : { timeoutMinutes: timeout }),
38
39
  };
39
40
  const stage = deps.stage;
@@ -250,6 +251,7 @@ export function createMergeRuntime(deps) {
250
251
  };
251
252
  const result = await runResumeCommand({
252
253
  ...common, rowId: row.id, ports: basePorts,
254
+ ...(deps.isOwnerActive === undefined ? {} : { isOwnerActive: deps.isOwnerActive }),
253
255
  makePorts: runId => createChannelScanPorts({
254
256
  io: deps.io, home: deps.home, runId, cards, screening: pair,
255
257
  channel: deps.channel, parent, allow: deps.allow,
@@ -18,6 +18,7 @@ export interface RunScanCommandOptions {
18
18
  readonly now: () => number;
19
19
  readonly detached?: boolean;
20
20
  readonly notes?: readonly string[];
21
+ readonly isOwnerActive?: (runId: string) => boolean | Promise<boolean>;
21
22
  }
22
23
  export declare function runScanCommand(options: RunScanCommandOptions): Promise<WithMergeRunResult>;
23
24
  //# sourceMappingURL=scan-command.d.ts.map
@@ -25,6 +25,7 @@ export async function runScanCommand(options) {
25
25
  runId: ctx.runId,
26
26
  ...(options.timeoutMinutes === undefined ? {} : { timeoutMinutes: options.timeoutMinutes }),
27
27
  ...(options.notes === undefined ? {} : { notes: options.notes }),
28
+ ...(options.isOwnerActive === undefined ? {} : { isOwnerActive: options.isOwnerActive }),
28
29
  });
29
30
  },
30
31
  });
@@ -45,6 +45,7 @@ export interface RunScanOptions {
45
45
  }) => Promise<void>;
46
46
  readonly notes?: readonly string[];
47
47
  readonly runId?: string;
48
+ readonly isOwnerActive?: (runId: string) => boolean | Promise<boolean>;
48
49
  }
49
50
  export declare function runScan(options: RunScanOptions): Promise<MergeRunReportDraft>;
50
51
  //# sourceMappingURL=scan-run.d.ts.map
@@ -66,6 +66,10 @@ export async function runScan(options) {
66
66
  throw new Error(created.ok ? 'candidate row missing' : created.message);
67
67
  row = options.runId === undefined ? created.row : { ...created.row, runId: options.runId };
68
68
  const before = (await loadMergeState(options.io, options.home)).state.rows.find(item => item.pairKey === row.pairKey);
69
+ if (before?.state === 'verify' && before.runId !== undefined && before.runId !== options.runId
70
+ && (await options.isOwnerActive?.(before.runId)) === true) {
71
+ continue;
72
+ }
69
73
  const placed = await upsertRow(options.io, options.home, options.now, row, 'verify', before?.updatedAt ?? null);
70
74
  if (!placed.ok && before?.state === 'skipped') {
71
75
  const restored = transition(before, { type: 'restore', at: at(options.now) });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-merge",
3
3
  "description": "Skill auto-merge domain: screening, two-round authoring, queues and commit orchestration (community build)",
4
- "version": "0.30.13",
4
+ "version": "0.30.14",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -27,8 +27,8 @@
27
27
  "license": "MIT",
28
28
  "dependencies": {
29
29
  "@deepseek-ai/schemastery": "^3.18.5",
30
- "@lmzhen/dsh-evolution-core": "^0.30.13",
31
- "@lmzhen/dsh-evolution-merge-engine": "^0.30.13"
30
+ "@lmzhen/dsh-evolution-core": "^0.30.14",
31
+ "@lmzhen/dsh-evolution-merge-engine": "^0.30.14"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "@deepseek-ai/cordis": "^4.0.5"