@mstar-harness/dsh 3.7.3 → 3.8.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.
package/dist/index.js CHANGED
@@ -1122,8 +1122,8 @@ var require_lib2 = __commonJS(function(exports, module) {
1122
1122
  });
1123
1123
 
1124
1124
  // src/index.ts
1125
- import { existsSync as existsSync22, readFileSync as readFileSync18, readdirSync as readdirSync14 } from "node:fs";
1126
- import { join as join24 } from "node:path";
1125
+ import { existsSync as existsSync22, readFileSync as readFileSync19, readdirSync as readdirSync14 } from "node:fs";
1126
+ import { join as join25 } from "node:path";
1127
1127
  import { fileURLToPath as fileURLToPath3 } from "node:url";
1128
1128
  import {
1129
1129
  apply as applySkillLocal,
@@ -4353,6 +4353,11 @@ function sessionCwdOf(agent) {
4353
4353
  const cwd = session?.header?.cwd;
4354
4354
  return typeof cwd === "string" && cwd.trim() !== "" ? cwd : undefined;
4355
4355
  }
4356
+ function sessionHeaderIdOf(agent) {
4357
+ const session = agent?.session;
4358
+ const id = session?.header?.id;
4359
+ return typeof id === "string" && id.trim() !== "" ? id : undefined;
4360
+ }
4356
4361
  function actorAgentOf(actor) {
4357
4362
  return actor?.agent;
4358
4363
  }
@@ -4377,8 +4382,8 @@ function skillLocalConfig(config) {
4377
4382
  }
4378
4383
 
4379
4384
  // src/gates/catalog.ts
4380
- import { existsSync as existsSync14, readFileSync as readFileSync8, readdirSync as readdirSync4 } from "node:fs";
4381
- import { join as join8 } from "node:path";
4385
+ import { existsSync as existsSync14, readFileSync as readFileSync11, readdirSync as readdirSync4 } from "node:fs";
4386
+ import { join as join12 } from "node:path";
4382
4387
  import { createUserMessage } from "@deepseek-ai/dsh-llm";
4383
4388
 
4384
4389
  // src/gates/agent-flow.ts
@@ -4655,9 +4660,15 @@ function assignmentHeaderValue(headerRegion, label) {
4655
4660
  const line = headerRegion.match(bold)?.[1] ?? headerRegion.match(plain)?.[1];
4656
4661
  if (line === undefined)
4657
4662
  return;
4658
- const value = line.trim();
4663
+ const value = stripWrappingCodeSpan(line.trim());
4659
4664
  return value === "" ? undefined : value;
4660
4665
  }
4666
+ function stripWrappingCodeSpan(value) {
4667
+ if (value.length < 2 || !value.startsWith("`") || !value.endsWith("`"))
4668
+ return value;
4669
+ const inner = value.slice(1, -1);
4670
+ return inner.includes("`") ? value : inner.trim();
4671
+ }
4661
4672
  function firstToken(value) {
4662
4673
  const token = value.split(/\s+/)[0];
4663
4674
  return token === "" ? undefined : token;
@@ -5639,6 +5650,228 @@ function recordTaskSettle(snapshot, pairing) {
5639
5650
  }
5640
5651
  }
5641
5652
 
5653
+ // src/engine-status-store.ts
5654
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync8, renameSync as renameSync3, rmSync, writeFileSync as writeFileSync5 } from "node:fs";
5655
+ import { dirname as dirname9, join as join8 } from "node:path";
5656
+ var ENGINE_STATUS_SNAPSHOT_VERSION = 1;
5657
+ var ENGINE_STATUS_SNAPSHOT_ENTRY_VERSION = 1;
5658
+ var ENGINE_STATUS_SNAPSHOT_MAX_PER_SESSION = 50;
5659
+ var ENGINE_STATUS_SNAPSHOT_MAX_AGE_MS = 30 * 24 * 60 * 60 * 1000;
5660
+ var ENGINE_STATUS_SNAPSHOT_MAX_BYTES = 16 * 1024 * 1024;
5661
+ var ENGINE_STATUS_SNAPSHOT_LOCK_TIMEOUT_MS = 250;
5662
+ var ENGINE_STATUS_SNAPSHOT_RELATIVE_PATH = "snapshots/engine-status.json";
5663
+ function engineStatusSnapshotPath(harnessDir) {
5664
+ return join8(harnessDir, ENGINE_STATUS_SNAPSHOT_RELATIVE_PATH);
5665
+ }
5666
+ function engineStatusUnavailable(reason) {
5667
+ return { kind: "unavailable", reason };
5668
+ }
5669
+ function isPlainObject6(value) {
5670
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5671
+ }
5672
+ function nonEmptyString(value) {
5673
+ return typeof value === "string" && value !== "" ? value : undefined;
5674
+ }
5675
+ function asEntry(value) {
5676
+ if (!isPlainObject6(value))
5677
+ return;
5678
+ if (value.rv !== ENGINE_STATUS_SNAPSHOT_ENTRY_VERSION)
5679
+ return;
5680
+ const cwd = nonEmptyString(value.cwd);
5681
+ const at = nonEmptyString(value.at);
5682
+ if (cwd === undefined || at === undefined)
5683
+ return;
5684
+ if (typeof value.turn !== "number" || !Number.isFinite(value.turn))
5685
+ return;
5686
+ if (!isPlainObject6(value.payload))
5687
+ return;
5688
+ return { rv: value.rv, cwd, at, turn: value.turn, payload: value.payload };
5689
+ }
5690
+ function entryAge(at, nowMs) {
5691
+ const parsed = Date.parse(at);
5692
+ if (!Number.isFinite(parsed))
5693
+ return;
5694
+ return nowMs - parsed;
5695
+ }
5696
+ function readEngineStatusSnapshot(harnessDir, sessionId) {
5697
+ if (harnessDir === null || harnessDir === "")
5698
+ return engineStatusUnavailable("no-harness-dir");
5699
+ if (sessionId === "")
5700
+ return engineStatusUnavailable("no-session-entry");
5701
+ let raw;
5702
+ try {
5703
+ raw = readFileSync8(engineStatusSnapshotPath(harnessDir), "utf8");
5704
+ } catch (error) {
5705
+ const code = error.code;
5706
+ return engineStatusUnavailable(code === "ENOENT" ? "absent" : "unreadable");
5707
+ }
5708
+ let doc;
5709
+ try {
5710
+ doc = JSON.parse(raw);
5711
+ } catch {
5712
+ return engineStatusUnavailable("invalid-json");
5713
+ }
5714
+ if (!isPlainObject6(doc) || doc.sv !== ENGINE_STATUS_SNAPSHOT_VERSION) {
5715
+ return engineStatusUnavailable("envelope-schema");
5716
+ }
5717
+ const entries = doc.entries;
5718
+ if (!isPlainObject6(entries))
5719
+ return engineStatusUnavailable("envelope-schema");
5720
+ if (!Object.hasOwn(entries, sessionId))
5721
+ return engineStatusUnavailable("no-session-entry");
5722
+ const bucket = entries[sessionId];
5723
+ if (!Array.isArray(bucket) || bucket.length === 0)
5724
+ return engineStatusUnavailable("no-session-entry");
5725
+ const entry = asEntry(bucket[bucket.length - 1]);
5726
+ if (entry === undefined)
5727
+ return engineStatusUnavailable("entry-schema");
5728
+ return { kind: "ok", entry };
5729
+ }
5730
+ function sessionMap() {
5731
+ return Object.create(null);
5732
+ }
5733
+ function loadForWrite(harnessDir) {
5734
+ let raw;
5735
+ try {
5736
+ raw = readFileSync8(engineStatusSnapshotPath(harnessDir), "utf8");
5737
+ } catch (error) {
5738
+ if (error.code === "ENOENT") {
5739
+ return { kind: "ok", doc: { sv: ENGINE_STATUS_SNAPSHOT_VERSION, entries: sessionMap() } };
5740
+ }
5741
+ return { kind: "refused", reason: "store-unreadable" };
5742
+ }
5743
+ let parsed;
5744
+ try {
5745
+ parsed = JSON.parse(raw);
5746
+ } catch {
5747
+ return { kind: "refused", reason: "store-invalid-json" };
5748
+ }
5749
+ if (!isPlainObject6(parsed) || parsed.sv !== ENGINE_STATUS_SNAPSHOT_VERSION || !isPlainObject6(parsed.entries)) {
5750
+ return { kind: "refused", reason: "store-envelope-schema" };
5751
+ }
5752
+ const entries = sessionMap();
5753
+ for (const [key, value] of Object.entries(parsed.entries)) {
5754
+ if (!Array.isArray(value))
5755
+ return { kind: "refused", reason: "store-entry-schema" };
5756
+ const kept = [];
5757
+ for (const candidate of value) {
5758
+ const entry = asEntry(candidate);
5759
+ if (entry === undefined)
5760
+ return { kind: "refused", reason: "store-entry-schema" };
5761
+ kept.push(entry);
5762
+ }
5763
+ if (kept.length > 0)
5764
+ entries[key] = kept;
5765
+ }
5766
+ return { kind: "ok", doc: { sv: ENGINE_STATUS_SNAPSHOT_VERSION, entries } };
5767
+ }
5768
+ function pruneBucket(bucket, nowMs) {
5769
+ const fresh = [];
5770
+ for (const entry of bucket) {
5771
+ const age = entryAge(entry.at, nowMs);
5772
+ if (age === undefined || age > ENGINE_STATUS_SNAPSHOT_MAX_AGE_MS)
5773
+ continue;
5774
+ fresh.push(entry);
5775
+ }
5776
+ if (fresh.length <= ENGINE_STATUS_SNAPSHOT_MAX_PER_SESSION)
5777
+ return fresh;
5778
+ return fresh.slice(fresh.length - ENGINE_STATUS_SNAPSHOT_MAX_PER_SESSION);
5779
+ }
5780
+ function bucketRecency(bucket) {
5781
+ let newest = 0;
5782
+ for (const entry of bucket) {
5783
+ const parsed = Date.parse(entry.at);
5784
+ if (Number.isFinite(parsed) && parsed > newest)
5785
+ newest = parsed;
5786
+ }
5787
+ return newest;
5788
+ }
5789
+ function enforceGlobalBound(pruned, keep, maxBytes, sizeOf) {
5790
+ if (sizeOf(pruned) <= maxBytes)
5791
+ return 0;
5792
+ const candidates = Object.keys(pruned).filter((key) => key !== keep).map((key) => ({ key, recency: bucketRecency(pruned[key]) })).sort((left, right) => left.recency - right.recency);
5793
+ let evicted = 0;
5794
+ for (const candidate of candidates) {
5795
+ if (sizeOf(pruned) <= maxBytes)
5796
+ break;
5797
+ delete pruned[candidate.key];
5798
+ evicted += 1;
5799
+ }
5800
+ return evicted;
5801
+ }
5802
+ var oversizeWarned = new Set;
5803
+ function writeEngineStatusSnapshot(harnessDir, input) {
5804
+ if (harnessDir === null || harnessDir === "")
5805
+ return { kind: "degraded", reason: "no-harness-dir" };
5806
+ if (input.sessionId === "")
5807
+ return { kind: "degraded", reason: "no-session-id" };
5808
+ if (input.cwd === "")
5809
+ return { kind: "degraded", reason: "no-session-cwd" };
5810
+ if (!Number.isFinite(input.turn))
5811
+ return { kind: "degraded", reason: "invalid-turn" };
5812
+ if (!isPlainObject6(input.payload))
5813
+ return { kind: "degraded", reason: "payload-not-object" };
5814
+ const at = (input.now ?? new Date).toISOString();
5815
+ if (!Number.isFinite(Date.parse(at)))
5816
+ return { kind: "degraded", reason: "invalid-timestamp" };
5817
+ const dir = dirname9(engineStatusSnapshotPath(harnessDir));
5818
+ const file = engineStatusSnapshotPath(harnessDir);
5819
+ const tmp = `${file}.${process.pid}.${Math.random().toString(36).slice(2, 10)}.tmp`;
5820
+ try {
5821
+ mkdirSync3(dir, { recursive: true });
5822
+ return withWorkflowDirLock(dir, () => {
5823
+ const loaded = loadForWrite(harnessDir);
5824
+ if (loaded.kind === "refused")
5825
+ return { kind: "degraded", reason: loaded.reason };
5826
+ const doc = loaded.doc;
5827
+ const nowMs = Date.parse(at);
5828
+ const bucket = pruneBucket(doc.entries[input.sessionId] ?? [], nowMs);
5829
+ bucket.push({
5830
+ rv: ENGINE_STATUS_SNAPSHOT_ENTRY_VERSION,
5831
+ cwd: input.cwd,
5832
+ at,
5833
+ turn: input.turn,
5834
+ payload: input.payload
5835
+ });
5836
+ doc.entries[input.sessionId] = pruneBucket(bucket, nowMs);
5837
+ const pruned = sessionMap();
5838
+ for (const [key, value] of Object.entries(doc.entries)) {
5839
+ const kept = pruneBucket(value, nowMs);
5840
+ if (kept.length === 0)
5841
+ continue;
5842
+ pruned[key] = kept;
5843
+ }
5844
+ const maxBytes = input.maxBytes ?? ENGINE_STATUS_SNAPSHOT_MAX_BYTES;
5845
+ const serialized = (entries) => JSON.stringify({ sv: ENGINE_STATUS_SNAPSHOT_VERSION, entries });
5846
+ const evicted = enforceGlobalBound(pruned, input.sessionId, maxBytes, (entries) => Buffer.byteLength(serialized(entries), "utf8"));
5847
+ const payload = serialized(pruned);
5848
+ const oversized = Buffer.byteLength(payload, "utf8") > maxBytes;
5849
+ let total = 0;
5850
+ for (const kept of Object.values(pruned))
5851
+ total += kept.length;
5852
+ writeFileSync5(tmp, payload);
5853
+ renameSync3(tmp, file);
5854
+ let warn;
5855
+ if (oversized && !oversizeWarned.has(file)) {
5856
+ oversizeWarned.add(file);
5857
+ warn = `engine-status snapshot store ${file} is above its ${maxBytes}-byte ceiling ` + `(kept ${total} entries, shed ${evicted} oldest session bucket(s) this write); ` + "recovery: delete the file — it is prunable plugin-owned state and readers answer unavailable for it";
5858
+ }
5859
+ return {
5860
+ kind: "written",
5861
+ path: file,
5862
+ entries: total,
5863
+ evicted,
5864
+ ...warn === undefined ? {} : { warn }
5865
+ };
5866
+ }, { timeoutMs: ENGINE_STATUS_SNAPSHOT_LOCK_TIMEOUT_MS });
5867
+ } catch (error) {
5868
+ try {
5869
+ rmSync(tmp, { force: true });
5870
+ } catch {}
5871
+ return { kind: "degraded", reason: error?.message ?? "write-failed" };
5872
+ }
5873
+ }
5874
+
5642
5875
  // src/gates/catalog.ts
5643
5876
  var CATALOG_LOGGER = "mstar/engine-status-catalog";
5644
5877
  var DEFAULT_CATALOG_TTL_MS = 60000;
@@ -5655,18 +5888,19 @@ function residualSeverityIndex(severity) {
5655
5888
  function pluginVersion() {
5656
5889
  for (const rel of ["../package.json", "../../package.json"]) {
5657
5890
  try {
5658
- const pkg = JSON.parse(readFileSync8(new URL(rel, import.meta.url), "utf8"));
5891
+ const pkg = JSON.parse(readFileSync11(new URL(rel, import.meta.url), "utf8"));
5659
5892
  if (typeof pkg.version === "string" && pkg.version !== "")
5660
5893
  return pkg.version;
5661
5894
  } catch {}
5662
5895
  }
5663
5896
  return "0.0.0";
5664
5897
  }
5665
- function engineStatusSource(harnessDir) {
5898
+ function engineStatusSource() {
5899
+ return { kind: "plugin", plugin: "mstar-engine-status", form: "catalog" };
5900
+ }
5901
+ function engineStatusPayload(harnessDir) {
5666
5902
  const iteration = harnessDir !== null ? iterationGateSource(harnessDir) : undefined;
5667
5903
  return {
5668
- kind: "mstar-engine-status",
5669
- form: "catalog",
5670
5904
  version: pluginVersion(),
5671
5905
  harnessDir,
5672
5906
  enforcement: harnessDir !== null ? resolveRepoEnforcement(harnessDir) : { hard: false, source: "none" },
@@ -5690,23 +5924,23 @@ function createCatalogInvalidation(cache) {
5690
5924
  }
5691
5925
  };
5692
5926
  }
5693
- function buildCatalogSources(ctx, harnessDir) {
5694
- const source = engineStatusSource(harnessDir);
5695
- if (source.version === "0.0.0") {
5927
+ function buildCatalogPayload(ctx, harnessDir) {
5928
+ const payload = engineStatusPayload(harnessDir);
5929
+ if (payload.version === "0.0.0") {
5696
5930
  ctx.logger(CATALOG_LOGGER).warn("plugin manifest version unavailable — falling back to 0.0.0 for the engine-status catalog watermark");
5697
5931
  }
5698
- return source;
5932
+ return payload;
5699
5933
  }
5700
- function catalogSourcesFor(ctx, cache, register, key, harnessDir, ttlMs) {
5934
+ function catalogPayloadFor(ctx, cache, register, key, harnessDir, ttlMs) {
5701
5935
  const entry = cache.get(key);
5702
5936
  if (entry !== undefined && Date.now() - entry.builtAt < ttlMs) {
5703
5937
  register(harnessDir, key);
5704
- return entry.sources;
5938
+ return entry.payload;
5705
5939
  }
5706
- const sources = buildCatalogSources(ctx, harnessDir);
5707
- cache.set(key, { sources, builtAt: Date.now() });
5940
+ const payload = buildCatalogPayload(ctx, harnessDir);
5941
+ cache.set(key, { payload, builtAt: Date.now() });
5708
5942
  register(harnessDir, key);
5709
- return sources;
5943
+ return payload;
5710
5944
  }
5711
5945
  function renderEngineStatusCatalog(source) {
5712
5946
  const enforcement = `${source.enforcement.hard ? "hard" : "soft"}${source.enforcement.source === "none" ? "" : ` (${source.enforcement.source})`}`;
@@ -5784,7 +6018,7 @@ function hhmm(ts) {
5784
6018
  function harnessStateSource(harnessDir) {
5785
6019
  if (harnessDir === null)
5786
6020
  return null;
5787
- const statusPath = join8(harnessDir, STATUS_FILE);
6021
+ const statusPath = join12(harnessDir, STATUS_FILE);
5788
6022
  if (!existsSync14(statusPath))
5789
6023
  return null;
5790
6024
  try {
@@ -5804,7 +6038,7 @@ function harnessStateSource(harnessDir) {
5804
6038
  if (selection.kind === "error") {
5805
6039
  return selectionErrorState(selection, rollup, harnessDir, compass);
5806
6040
  }
5807
- const snapshotPath = join8(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
6041
+ const snapshotPath = join12(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
5808
6042
  let snapshot;
5809
6043
  if (!existsSync14(snapshotPath)) {
5810
6044
  return selectionErrorState({
@@ -5868,7 +6102,7 @@ function harnessStateSource(harnessDir) {
5868
6102
  leases,
5869
6103
  knowledge: knowledgeDigest(harnessDir),
5870
6104
  direction: compass !== undefined ? compassDirection(compass.compassPath) : null,
5871
- agentFlow: readAgentFlow(join8(harnessDir, selection.dir), 50)
6105
+ agentFlow: readAgentFlow(join12(harnessDir, selection.dir), 50)
5872
6106
  };
5873
6107
  } catch {
5874
6108
  return null;
@@ -5908,11 +6142,11 @@ function projectRollupSource(harnessDir, residuals) {
5908
6142
  for (const entry of entries) {
5909
6143
  if (!entry.isDirectory())
5910
6144
  continue;
5911
- const roadmapPath = join8(projectsDir, entry.name, PROJECT_ROADMAP_FILE);
6145
+ const roadmapPath = join12(projectsDir, entry.name, PROJECT_ROADMAP_FILE);
5912
6146
  if (!existsSync14(roadmapPath))
5913
6147
  continue;
5914
6148
  try {
5915
- const doc = parseCompassFrontmatterText(readFileSync8(roadmapPath, "utf8"), roadmapPath);
6149
+ const doc = parseCompassFrontmatterText(readFileSync11(roadmapPath, "utf8"), roadmapPath);
5916
6150
  if (Array.isArray(doc.milestones)) {
5917
6151
  for (const milestone of doc.milestones) {
5918
6152
  if (typeof milestone === "string" && milestone.trim() !== "")
@@ -5986,7 +6220,7 @@ function projectRegisters(harnessDir) {
5986
6220
  for (const entry of entries) {
5987
6221
  if (!entry.isDirectory())
5988
6222
  continue;
5989
- const registerPath = join8(projectsDir, entry.name, PROJECT_REGISTER_FILE);
6223
+ const registerPath = join12(projectsDir, entry.name, PROJECT_REGISTER_FILE);
5990
6224
  if (!existsSync14(registerPath))
5991
6225
  continue;
5992
6226
  try {
@@ -5998,13 +6232,13 @@ function projectRegisters(harnessDir) {
5998
6232
  return registers;
5999
6233
  }
6000
6234
  function knowledgeDigest(harnessDir) {
6001
- const indexPath = join8(harnessDir, "knowledge", "README.md");
6235
+ const indexPath = join12(harnessDir, "knowledge", "README.md");
6002
6236
  if (!existsSync14(indexPath))
6003
6237
  return null;
6004
6238
  try {
6005
6239
  const categories = new Set;
6006
6240
  let docCount = 0;
6007
- for (const line of readFileSync8(indexPath, "utf8").split(/\r?\n/)) {
6241
+ for (const line of readFileSync11(indexPath, "utf8").split(/\r?\n/)) {
6008
6242
  const row = line.trim().match(/^\|(.+)\|$/);
6009
6243
  if (row === null)
6010
6244
  continue;
@@ -6027,7 +6261,7 @@ function knowledgeDigest(harnessDir) {
6027
6261
  }
6028
6262
  function compassDirection(compassPath) {
6029
6263
  try {
6030
- const content = readFileSync8(compassPath, "utf8");
6264
+ const content = readFileSync11(compassPath, "utf8");
6031
6265
  const section = content.match(/^## Direction lock[^\n]*\n+([\s\S]*?)(?=\n## |$)/m);
6032
6266
  if (section === null)
6033
6267
  return null;
@@ -6055,12 +6289,12 @@ function steeringCompassPath(harnessDir) {
6055
6289
  for (const entry of entries) {
6056
6290
  if (!entry.isDirectory())
6057
6291
  continue;
6058
- const compassPath = join8(iterationsDir, entry.name, "delivery-compass.md");
6292
+ const compassPath = join12(iterationsDir, entry.name, "delivery-compass.md");
6059
6293
  if (!existsSync14(compassPath))
6060
6294
  continue;
6061
6295
  let content;
6062
6296
  try {
6063
- content = readFileSync8(compassPath, "utf8");
6297
+ content = readFileSync11(compassPath, "utf8");
6064
6298
  } catch {
6065
6299
  continue;
6066
6300
  }
@@ -6074,7 +6308,7 @@ function steeringCompassPath(harnessDir) {
6074
6308
  function iterationGateSource(harnessDir) {
6075
6309
  if (harnessDir === null)
6076
6310
  return;
6077
- const statusPath = join8(harnessDir, STATUS_FILE);
6311
+ const statusPath = join12(harnessDir, STATUS_FILE);
6078
6312
  if (!existsSync14(statusPath))
6079
6313
  return;
6080
6314
  const compass = steeringCompassPath(harnessDir);
@@ -6083,7 +6317,7 @@ function iterationGateSource(harnessDir) {
6083
6317
  const selection = resolveReadWorkflow(harnessDir);
6084
6318
  if (selection.kind === "error")
6085
6319
  return;
6086
- const snapshotPath = join8(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
6320
+ const snapshotPath = join12(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
6087
6321
  try {
6088
6322
  const snapshotDoc = readJson(snapshotPath);
6089
6323
  const compassDoc = parseCompassFrontmatter(compass.compassPath);
@@ -6116,13 +6350,14 @@ async function preStepCatalogListener(ctx, resolver, explicitKey, cache, ttlMs,
6116
6350
  const cwd = sessionCwdOf(payload.agent);
6117
6351
  const harnessDir = resolver.forWorkspace(cwd);
6118
6352
  const key = explicitKey ?? cwd ?? "";
6119
- const sources = catalogSourcesFor(ctx, cache, register, key, harnessDir, ttlMs);
6353
+ const catalogPayload = catalogPayloadFor(ctx, cache, register, key, harnessDir, ttlMs);
6120
6354
  const messages = [...decision.messages];
6121
- const text = renderEngineStatusCatalog(sources);
6355
+ const text = renderEngineStatusCatalog(catalogPayload);
6122
6356
  const digestKey = agentDigestKey(payload.agent, cwd);
6123
6357
  const prior = digests.get(digestKey);
6124
6358
  if (prior === undefined || prior.turn !== payload.turn || prior.text !== text) {
6125
- messages.push(createUserMessage({ source: sources, content: [{ type: "text", text }] }));
6359
+ messages.push(createUserMessage({ source: engineStatusSource(), content: [{ type: "text", text }] }));
6360
+ persistEngineStatusSnapshot(ctx, harnessDir, cwd, payload.turn, catalogPayload, payload.agent);
6126
6361
  }
6127
6362
  digests.set(digestKey, { turn: payload.turn, text });
6128
6363
  return { kind: "enter", messages };
@@ -6135,10 +6370,208 @@ function agentDigestKey(agent, cwd) {
6135
6370
  const id = agent?.id;
6136
6371
  return `${typeof id === "string" ? id : "<unknown>"}\x00${cwd ?? ""}`;
6137
6372
  }
6373
+ function persistEngineStatusSnapshot(ctx, harnessDir, cwd, turn, catalogPayload, agent) {
6374
+ const sessionId = sessionHeaderIdOf(agent);
6375
+ if (sessionId === undefined || cwd === undefined)
6376
+ return;
6377
+ if (harnessDir === null)
6378
+ return;
6379
+ const result = writeEngineStatusSnapshot(harnessDir, {
6380
+ sessionId,
6381
+ cwd,
6382
+ turn,
6383
+ payload: catalogPayload
6384
+ });
6385
+ if (result.kind === "degraded") {
6386
+ ctx.logger(CATALOG_LOGGER).warn(`engine-status snapshot not persisted for ${sessionId} (readers answer unavailable): ${result.reason}`);
6387
+ return;
6388
+ }
6389
+ if (result.warn !== undefined)
6390
+ ctx.logger(CATALOG_LOGGER).warn(result.warn);
6391
+ }
6392
+
6393
+ // src/engine-status-endpoint.ts
6394
+ import { isAbsolute as isAbsolute3 } from "node:path";
6395
+
6396
+ // ../../node_modules/.bun/@deepseek-ai+dsh-typert-protocol@0.1.5-rc.1+1e4e7adc57ac8890/node_modules/@deepseek-ai/dsh-typert-protocol/lib/index.js
6397
+ import { Service as Service2 } from "@deepseek-ai/cordis";
6398
+ var TYPERT_REMOTE_SEGMENT_PATTERN = /^[A-Za-z0-9_$.-]+$/;
6399
+ function isTypertRemoteSegment(value) {
6400
+ return value !== "." && value !== ".." && TYPERT_REMOTE_SEGMENT_PATTERN.test(value);
6401
+ }
6402
+ function bindTypertRemote(service, serviceKey, options = {}) {
6403
+ validateName("service key", serviceKey);
6404
+ const namespace = options.namespace ?? serviceKey;
6405
+ validateName("namespace", namespace);
6406
+ return Object.freeze({
6407
+ service,
6408
+ serviceKey,
6409
+ namespace
6410
+ });
6411
+ }
6412
+ var TypertRemoteService = class extends Service2 {
6413
+ typertRemote;
6414
+ constructor(ctx, serviceKey, options = {}) {
6415
+ super(ctx, serviceKey);
6416
+ this.typertRemote = bindTypertRemote(this, this.name, options);
6417
+ }
6418
+ };
6419
+ function validateName(subject, value) {
6420
+ if (!isTypertRemoteSegment(value))
6421
+ throw new TypeError(`typert-protocol: ${subject} must contain only RPC endpoint segment characters`);
6422
+ }
6423
+
6424
+ // src/engine-status-wire.ts
6425
+ var MSTAR_ENGINE_STATUS_NAMESPACE = "mstar";
6426
+ var MSTAR_ENGINE_STATUS_METHOD = "engineStatus";
6427
+
6428
+ // src/engine-status-endpoint.ts
6429
+ var CONTRIBUTING_PACKAGE = "@mstar-harness/dsh";
6430
+ var ENDPOINT_LOGGER = "mstar-engine-status-endpoint";
6431
+ function unavailable(reason) {
6432
+ return { status: "unavailable", reason };
6433
+ }
6434
+ function nonEmptyString2(value) {
6435
+ return typeof value === "string" && value.trim() !== "" ? value : undefined;
6436
+ }
6437
+ function headerCwdOf(value) {
6438
+ const header = value?.header;
6439
+ return nonEmptyString2(header?.cwd);
6440
+ }
6441
+ function isRefusedPath(cwd) {
6442
+ if (cwd.includes("\x00"))
6443
+ return true;
6444
+ if (!isAbsolute3(cwd))
6445
+ return true;
6446
+ return cwd.split(/[\\/]+/).includes("..");
6447
+ }
6448
+
6449
+ class MstarEngineStatusGateway extends TypertRemoteService {
6450
+ resolver;
6451
+ bootHarnessDir;
6452
+ constructor(ctx, options) {
6453
+ super(ctx, MSTAR_ENGINE_STATUS_NAMESPACE);
6454
+ this.resolver = options.resolver;
6455
+ this.bootHarnessDir = options.bootHarnessDir;
6456
+ }
6457
+ async engineStatus(sessionId, cwd) {
6458
+ try {
6459
+ return await this.serve(sessionId, cwd);
6460
+ } catch (error) {
6461
+ this.ctx.logger(ENDPOINT_LOGGER).warn(`engineStatus failed for ${String(sessionId)} (answering unavailable): ${error?.message ?? error}`);
6462
+ return unavailable("internal-error");
6463
+ }
6464
+ }
6465
+ async serve(sessionId, cwd) {
6466
+ const sid = nonEmptyString2(sessionId);
6467
+ if (sid === undefined)
6468
+ return unavailable("invalid-session-id");
6469
+ const claimed = nonEmptyString2(cwd);
6470
+ if (claimed === undefined)
6471
+ return unavailable("invalid-cwd");
6472
+ if (isRefusedPath(claimed))
6473
+ return unavailable("cwd-refused");
6474
+ const session = await this.resolveSessionCwd(sid);
6475
+ if (session.kind !== "ok")
6476
+ return unavailable(session.reason);
6477
+ const harnessDir = this.bootHarnessDir ?? this.resolver.forWorkspace(session.cwd);
6478
+ if (harnessDir === null || harnessDir === "")
6479
+ return unavailable("no-harness-dir");
6480
+ const read = readEngineStatusSnapshot(harnessDir, sid);
6481
+ if (read.kind !== "ok")
6482
+ return unavailable(`store-${read.reason}`);
6483
+ const entry = read.entry;
6484
+ if (entry.cwd !== claimed)
6485
+ return unavailable("cwd-mismatch");
6486
+ if (entry.cwd !== session.cwd)
6487
+ return unavailable("session-cwd-mismatch");
6488
+ return {
6489
+ status: "ok",
6490
+ sessionId: sid,
6491
+ cwd: entry.cwd,
6492
+ at: entry.at,
6493
+ turn: entry.turn,
6494
+ payload: entry.payload
6495
+ };
6496
+ }
6497
+ async resolveSessionCwd(sessionId) {
6498
+ const sessions = this.ctx.get("sessions");
6499
+ const live = typeof sessions?.get === "function" ? sessions.get(sessionId) : undefined;
6500
+ const liveCwd = headerCwdOf(live);
6501
+ if (liveCwd !== undefined)
6502
+ return { kind: "ok", cwd: liveCwd, source: "live" };
6503
+ const controller = this.ctx.get("sessionController");
6504
+ if (typeof controller?.inspect !== "function") {
6505
+ return { kind: "unavailable", reason: live === undefined ? "session-absent" : "session-cwd-absent" };
6506
+ }
6507
+ let inspection;
6508
+ try {
6509
+ inspection = await controller.inspect(sessionId);
6510
+ } catch {
6511
+ return { kind: "unavailable", reason: "session-inspect-failed" };
6512
+ }
6513
+ const persistedCwd = headerCwdOf(inspection);
6514
+ if (persistedCwd === undefined)
6515
+ return { kind: "unavailable", reason: "session-cwd-absent" };
6516
+ return { kind: "ok", cwd: persistedCwd, source: "persisted" };
6517
+ }
6518
+ }
6519
+ function mstarEngineStatusContribution() {
6520
+ return {
6521
+ package: CONTRIBUTING_PACKAGE,
6522
+ face: "host",
6523
+ schemas: [],
6524
+ model: { services: [], events: [], objects: [] },
6525
+ invocations: [
6526
+ {
6527
+ id: `${CONTRIBUTING_PACKAGE}#${MSTAR_ENGINE_STATUS_NAMESPACE}/${MSTAR_ENGINE_STATUS_METHOD}`,
6528
+ service: MSTAR_ENGINE_STATUS_NAMESPACE,
6529
+ namespace: MSTAR_ENGINE_STATUS_NAMESPACE,
6530
+ method: MSTAR_ENGINE_STATUS_METHOD,
6531
+ invocation: { kind: "direct" },
6532
+ parameters: [
6533
+ { name: "sessionId", wire: "sessionId", source: "json", codec: { mode: "src-json" } },
6534
+ { name: "cwd", wire: "cwd", source: "json", codec: { mode: "src-json" } }
6535
+ ],
6536
+ result: { mode: "src-json" }
6537
+ }
6538
+ ]
6539
+ };
6540
+ }
6541
+ function engineStatusServicePresent(ctx) {
6542
+ try {
6543
+ return ctx.get(MSTAR_ENGINE_STATUS_NAMESPACE) !== undefined;
6544
+ } catch {
6545
+ return false;
6546
+ }
6547
+ }
6548
+ function installEngineStatusEndpoint(ctx, options) {
6549
+ if (engineStatusServicePresent(ctx)) {
6550
+ ctx.logger(ENDPOINT_LOGGER).debug("mstar engine-status gateway already registered — kept as-is (multi-fiber dedupe)");
6551
+ } else {
6552
+ try {
6553
+ new MstarEngineStatusGateway(ctx, options);
6554
+ } catch (error) {
6555
+ if (!(error instanceof Error) || !error.message.includes("has been registered"))
6556
+ throw error;
6557
+ ctx.logger(ENDPOINT_LOGGER).debug("mstar engine-status gateway registered concurrently — kept the first (multi-fiber dedupe)");
6558
+ }
6559
+ }
6560
+ ctx.inject(["typert"], (tctx) => {
6561
+ try {
6562
+ return tctx.typert.register(mstarEngineStatusContribution());
6563
+ } catch (error) {
6564
+ if (!(error instanceof Error) || !error.message.includes("already registered"))
6565
+ throw error;
6566
+ tctx.logger(ENDPOINT_LOGGER).debug("mstar engine-status endpoints registered concurrently — none on this fiber (multi-fiber dedupe)");
6567
+ return () => {};
6568
+ }
6569
+ });
6570
+ }
6138
6571
 
6139
6572
  // src/gates/status.ts
6140
6573
  import { existsSync as existsSync15, readdirSync as readdirSync7 } from "node:fs";
6141
- import { basename as basename5, join as join12, relative as relative7, resolve as resolve10 } from "node:path";
6574
+ import { basename as basename5, join as join14, relative as relative7, resolve as resolve10 } from "node:path";
6142
6575
  var LOGGER_NAME = "mstar/status-gate";
6143
6576
  function harnessDocKindOfTarget(harnessDir, targetPath) {
6144
6577
  const resolved = resolve10(targetPath);
@@ -6154,8 +6587,8 @@ function harnessDocKindOfTarget(harnessDir, targetPath) {
6154
6587
  workflowDir = resolveWorkflowDir(harnessDir, { harnessDir });
6155
6588
  projectDir = resolveProjectDir(harnessDir, { harnessDir });
6156
6589
  } catch {
6157
- workflowDir = join12(harnessDir, "workflows");
6158
- projectDir = join12(harnessDir, "projects");
6590
+ workflowDir = join14(harnessDir, "workflows");
6591
+ projectDir = join14(harnessDir, "projects");
6159
6592
  }
6160
6593
  if (name === WORKFLOW_SNAPSHOT_FILE && /^[^/]+\/snapshot\.json$/.test(relative7(workflowDir, resolved)))
6161
6594
  return "snapshot";
@@ -6219,7 +6652,7 @@ function projectRegisterDocs(harnessDir) {
6219
6652
  for (const entry of entries) {
6220
6653
  if (!entry.isDirectory())
6221
6654
  continue;
6222
- const registerPath = join12(projectsDir, entry.name, PROJECT_REGISTER_FILE);
6655
+ const registerPath = join14(projectsDir, entry.name, PROJECT_REGISTER_FILE);
6223
6656
  if (!existsSync15(registerPath))
6224
6657
  continue;
6225
6658
  try {
@@ -6293,8 +6726,8 @@ async function editIntentListener(ctx, resolver, config, adapter, target, actor,
6293
6726
  }
6294
6727
 
6295
6728
  // src/gates/skill-lint.ts
6296
- import { existsSync as existsSync16, readFileSync as readFileSync11 } from "node:fs";
6297
- import { basename as basename8, dirname as dirname9, resolve as resolve12, sep as sep2 } from "node:path";
6729
+ import { existsSync as existsSync16, readFileSync as readFileSync13 } from "node:fs";
6730
+ import { basename as basename8, dirname as dirname10, resolve as resolve12, sep as sep2 } from "node:path";
6298
6731
  var SKILL_LINT_LOGGER = "mstar/skill-lint";
6299
6732
 
6300
6733
  class SkillLintVetoError extends Error {
@@ -6335,7 +6768,7 @@ function lintSkillDoc(doc, options = {}) {
6335
6768
  return violations.length === 0 ? { ok: true, violations } : { ok: false, violations };
6336
6769
  }
6337
6770
  function lintSkillWrite(doc, options) {
6338
- const skillId = basename8(dirname9(resolve12(options.target)));
6771
+ const skillId = basename8(dirname10(resolve12(options.target)));
6339
6772
  const result = lintSkillDoc(doc, { skillId });
6340
6773
  if (options.hard && !result.ok) {
6341
6774
  throw new SkillLintVetoError(options.target, result.violations);
@@ -6354,7 +6787,7 @@ function isSkillTarget(roots, target) {
6354
6787
  return roots.some((root) => resolvedPath.startsWith(resolve12(root) + sep2));
6355
6788
  }
6356
6789
  function skillNameOf(target) {
6357
- return basename8(dirname9(target.displayPath));
6790
+ return basename8(dirname10(target.displayPath));
6358
6791
  }
6359
6792
  function skillCanonicalForm(target) {
6360
6793
  return resolveSkillRoot("dsh", { skill: skillNameOf(target), rel: "SKILL.md" });
@@ -6371,7 +6804,7 @@ function gateSkillIntent(ctx, harnessDir, config, target) {
6371
6804
  return;
6372
6805
  let doc;
6373
6806
  try {
6374
- doc = readFileSync11(skillPath, "utf8");
6807
+ doc = readFileSync13(skillPath, "utf8");
6375
6808
  } catch (error) {
6376
6809
  ctx.logger(SKILL_LINT_LOGGER).error(`skill lint degraded to allow (cannot read ${skillPath}): ${error.message}`);
6377
6810
  ctx.emit("mstar/skill-lint", {
@@ -6384,7 +6817,7 @@ function gateSkillIntent(ctx, harnessDir, config, target) {
6384
6817
  });
6385
6818
  return;
6386
6819
  }
6387
- const result = lintSkillDoc(doc, { skillId: basename8(dirname9(skillPath)) });
6820
+ const result = lintSkillDoc(doc, { skillId: basename8(dirname10(skillPath)) });
6388
6821
  if (result.ok)
6389
6822
  return;
6390
6823
  const hard = resolveSeamHard(harnessDir, config);
@@ -6418,8 +6851,8 @@ async function skillWriteIntentListener(ctx, resolver, config, target, actor, ne
6418
6851
  }
6419
6852
 
6420
6853
  // src/gates/seams.ts
6421
- import { existsSync as existsSync17, readFileSync as readFileSync13, readdirSync as readdirSync10 } from "node:fs";
6422
- import { basename as basename10, dirname as dirname10, join as join14, resolve as resolve14, sep as sep3 } from "node:path";
6854
+ import { existsSync as existsSync17, readFileSync as readFileSync14, readdirSync as readdirSync10 } from "node:fs";
6855
+ import { basename as basename10, dirname as dirname11, join as join17, resolve as resolve14, sep as sep3 } from "node:path";
6423
6856
 
6424
6857
  // ../engine/dist/audit.js
6425
6858
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
@@ -6651,8 +7084,8 @@ function rolesDirOf(path) {
6651
7084
  const segments = resolve14(path).split(sep3);
6652
7085
  const idx = segments.indexOf("mstar-roles");
6653
7086
  if (idx === -1)
6654
- return dirname10(path);
6655
- return idx === 0 ? sep3 : join14(sep3, ...segments.slice(1, idx + 1));
7087
+ return dirname11(path);
7088
+ return idx === 0 ? sep3 : join17(sep3, ...segments.slice(1, idx + 1));
6656
7089
  }
6657
7090
  function isSeamTarget(seam, harnessDir, target) {
6658
7091
  const path = resolve14(target.displayPath);
@@ -6666,7 +7099,7 @@ function isSeamTarget(seam, harnessDir, target) {
6666
7099
  case "compound": {
6667
7100
  if (harnessDir === null)
6668
7101
  return false;
6669
- return path.startsWith(resolve14(join14(harnessDir, "knowledge")) + sep3) && isMarkdownDoc(path);
7102
+ return path.startsWith(resolve14(join17(harnessDir, "knowledge")) + sep3) && isMarkdownDoc(path);
6670
7103
  }
6671
7104
  case "roles":
6672
7105
  return isRolesTarget(path);
@@ -6684,10 +7117,10 @@ function auditSecretsViolations(findings, file) {
6684
7117
  function validateDesignDoc(doc, path) {
6685
7118
  const violations = [...validateDesignTokenFrontmatter(doc).violations];
6686
7119
  const isDark = basename10(path) === "DESIGN.dark.md";
6687
- const sibling = join14(dirname10(path), isDark ? "DESIGN.md" : "DESIGN.dark.md");
7120
+ const sibling = join17(dirname11(path), isDark ? "DESIGN.md" : "DESIGN.dark.md");
6688
7121
  if (existsSync17(sibling)) {
6689
- const light = isDark ? readFileSync13(sibling, "utf8") : doc;
6690
- const dark = isDark ? doc : readFileSync13(sibling, "utf8");
7122
+ const light = isDark ? readFileSync14(sibling, "utf8") : doc;
7123
+ const dark = isDark ? doc : readFileSync14(sibling, "utf8");
6691
7124
  violations.push(...assertLightDarkParity(light, dark).violations);
6692
7125
  }
6693
7126
  return violations.length === 0 ? { ok: true, violations } : { ok: false, violations };
@@ -6701,21 +7134,21 @@ function validateAuditDoc(doc, path) {
6701
7134
  function validateCompoundDoc(doc, _path, harnessDir) {
6702
7135
  const violations = [...validateSchemaYaml(doc).violations];
6703
7136
  if (harnessDir !== null) {
6704
- violations.push(...referenceExists(dirname10(harnessDir), doc).violations);
7137
+ violations.push(...referenceExists(dirname11(harnessDir), doc).violations);
6705
7138
  }
6706
7139
  return violations.length === 0 ? { ok: true, violations } : { ok: false, violations };
6707
7140
  }
6708
- function validateRolesState(rolesDir, skillsRoot = dirname10(rolesDir)) {
7141
+ function validateRolesState(rolesDir, skillsRoot = dirname11(rolesDir)) {
6709
7142
  const violations = [...validateRoleMapping(rolesDir).violations];
6710
7143
  const skillTexts = {};
6711
7144
  for (const entry of readdirSync10(skillsRoot, { withFileTypes: true })) {
6712
7145
  if (!entry.isDirectory() || !entry.name.startsWith("mstar-"))
6713
7146
  continue;
6714
- const skillFile = join14(skillsRoot, entry.name, "SKILL.md");
7147
+ const skillFile = join17(skillsRoot, entry.name, "SKILL.md");
6715
7148
  if (!existsSync17(skillFile))
6716
7149
  continue;
6717
7150
  try {
6718
- skillTexts[entry.name] = readFileSync13(skillFile, "utf8");
7151
+ skillTexts[entry.name] = readFileSync14(skillFile, "utf8");
6719
7152
  } catch {}
6720
7153
  }
6721
7154
  violations.push(...lintLoadOrder(skillTexts).violations);
@@ -6750,7 +7183,7 @@ function gateSeamIntent(ctx, harnessDir, config, seam, target) {
6750
7183
  return;
6751
7184
  let doc;
6752
7185
  try {
6753
- doc = readFileSync13(path, "utf8");
7186
+ doc = readFileSync14(path, "utf8");
6754
7187
  } catch (error) {
6755
7188
  logger.error(`seam lint degraded to allow (cannot read ${path}): ${error.message}`);
6756
7189
  emitSeamAdvisory(ctx, seam, target.displayPath, { ok: true, violations: [] }, false, { degraded: true });
@@ -6816,8 +7249,8 @@ function lintRolesWrite(doc, options) {
6816
7249
  }
6817
7250
 
6818
7251
  // src/gates/tools.ts
6819
- import { existsSync as existsSync18, readFileSync as readFileSync14 } from "node:fs";
6820
- import { join as join17, resolve as resolve16 } from "node:path";
7252
+ import { existsSync as existsSync18, readFileSync as readFileSync15 } from "node:fs";
7253
+ import { join as join19, resolve as resolve16 } from "node:path";
6821
7254
  import { defineTool } from "@deepseek-ai/dsh-tools";
6822
7255
  var ITERATION_VIOLATION_SCHEMA = {
6823
7256
  type: "object",
@@ -7038,10 +7471,10 @@ function registerSeamTools(ctx, resolver) {
7038
7471
  isConcurrencySafe: () => false,
7039
7472
  async execute(args) {
7040
7473
  const abs = resolve16(args.dir);
7041
- const lightPath = join17(abs, "DESIGN.md");
7474
+ const lightPath = join19(abs, "DESIGN.md");
7042
7475
  if (!existsSync18(lightPath))
7043
7476
  throw new Error(`design file not found: ${lightPath}`);
7044
- const light = readFileSync14(lightPath, "utf8");
7477
+ const light = readFileSync15(lightPath, "utf8");
7045
7478
  const result = validateDesignDoc(light, lightPath);
7046
7479
  const level = completenessLevel(light);
7047
7480
  return {
@@ -7094,7 +7527,7 @@ function registerSeamTools(ctx, resolver) {
7094
7527
  const abs = resolve16(args.plan_path);
7095
7528
  if (!existsSync18(abs))
7096
7529
  throw new Error(`plan file not found: ${abs}`);
7097
- const text = readFileSync14(abs, "utf8");
7530
+ const text = readFileSync15(abs, "utf8");
7098
7531
  const result = validateAuditDoc(text, abs);
7099
7532
  return { ok: result.ok, violations: result.violations.map(iterationViolationView), secrets: result.findings };
7100
7533
  }
@@ -7134,7 +7567,7 @@ function registerSeamTools(ctx, resolver) {
7134
7567
  const abs = resolve16(args.doc_path);
7135
7568
  if (!existsSync18(abs))
7136
7569
  throw new Error(`knowledge doc not found: ${abs}`);
7137
- const text = readFileSync14(abs, "utf8");
7570
+ const text = readFileSync15(abs, "utf8");
7138
7571
  const base = validateCompoundDoc(text, abs, args.repo_root !== undefined ? null : resolver.forAgent(exec.agent));
7139
7572
  const violations = [...base.violations];
7140
7573
  if (args.repo_root !== undefined) {
@@ -7177,7 +7610,7 @@ function registerSeamTools(ctx, resolver) {
7177
7610
  isConcurrencySafe: () => false,
7178
7611
  async execute(args) {
7179
7612
  const rolesDir = resolve16(args.roles_dir);
7180
- if (!existsSync18(join17(rolesDir, "SKILL.md")))
7613
+ if (!existsSync18(join19(rolesDir, "SKILL.md")))
7181
7614
  throw new Error(`roles dir not found: ${rolesDir}`);
7182
7615
  const result = validateRolesState(rolesDir, args.skills_root !== undefined ? resolve16(args.skills_root) : undefined);
7183
7616
  return { ok: result.ok, violations: result.violations.map(iterationViolationView) };
@@ -7188,8 +7621,8 @@ function registerSeamTools(ctx, resolver) {
7188
7621
 
7189
7622
  // src/gates/adapter.ts
7190
7623
  import { existsSync as existsSync19 } from "node:fs";
7191
- import { join as join19 } from "node:path";
7192
- import { Service as Service2 } from "@deepseek-ai/cordis";
7624
+ import { join as join20 } from "node:path";
7625
+ import { Service as Service3 } from "@deepseek-ai/cordis";
7193
7626
  var HOST_LOGGER = "mstar/host-adapter";
7194
7627
  function mergeLeasesMatch(left, right) {
7195
7628
  const a = left ?? {};
@@ -7197,7 +7630,7 @@ function mergeLeasesMatch(left, right) {
7197
7630
  return ["holder", "claimed_at", "plan_id", "source_branch", "target_branch"].every((key) => a[key] === b[key]);
7198
7631
  }
7199
7632
 
7200
- class DshHostAdapter extends Service2 {
7633
+ class DshHostAdapter extends Service3 {
7201
7634
  host = "dsh";
7202
7635
  resolver;
7203
7636
  config;
@@ -7279,7 +7712,7 @@ class DshHostAdapter extends Service2 {
7279
7712
  if (harnessDir !== null) {
7280
7713
  const selection = resolveActiveWorkflow(harnessDir);
7281
7714
  if (selection.kind === "active") {
7282
- const snapshotPath = join19(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
7715
+ const snapshotPath = join20(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
7283
7716
  try {
7284
7717
  const snapshot = readJson(snapshotPath);
7285
7718
  const stored = snapshot?.integration_merge_lease;
@@ -7305,8 +7738,8 @@ class DshHostAdapter extends Service2 {
7305
7738
  }
7306
7739
 
7307
7740
  // src/gates/agent-personas.ts
7308
- import { readFileSync as readFileSync15, readdirSync as readdirSync12, statSync as statSync7 } from "node:fs";
7309
- import { join as join20, resolve as resolve17, sep as sep5 } from "node:path";
7741
+ import { readFileSync as readFileSync16, readdirSync as readdirSync12, statSync as statSync7 } from "node:fs";
7742
+ import { join as join21, resolve as resolve17, sep as sep5 } from "node:path";
7310
7743
  var ROLE_ID_PATTERN = /^[a-z0-9-]{1,32}$/;
7311
7744
  var defaultCache = new Map;
7312
7745
  function personaFor(roleId, lookup, warn) {
@@ -7334,7 +7767,7 @@ function subagentRoleIds(agentsDir) {
7334
7767
  const roleId = name.slice(0, -3);
7335
7768
  let content;
7336
7769
  try {
7337
- content = readFileSync15(join20(agentsDir, name), "utf8");
7770
+ content = readFileSync16(join21(agentsDir, name), "utf8");
7338
7771
  } catch {
7339
7772
  continue;
7340
7773
  }
@@ -7364,7 +7797,7 @@ function defaultFromMirror(agentsDir, roleId, warn) {
7364
7797
  return hit.text;
7365
7798
  let content;
7366
7799
  try {
7367
- content = readFileSync15(file, "utf8");
7800
+ content = readFileSync16(file, "utf8");
7368
7801
  } catch {
7369
7802
  return;
7370
7803
  }
@@ -7595,8 +8028,8 @@ function log2(level, message) {
7595
8028
  }
7596
8029
 
7597
8030
  // src/gates/workflow-ledger.ts
7598
- import { readFileSync as readFileSync16, renameSync as renameSync3, writeFileSync as writeFileSync5 } from "node:fs";
7599
- import { join as join21 } from "node:path";
8031
+ import { readFileSync as readFileSync17, renameSync as renameSync4, writeFileSync as writeFileSync7 } from "node:fs";
8032
+ import { join as join22 } from "node:path";
7600
8033
  var WORKFLOW_LEDGER_LOGGER = "mstar/workflow-ledger";
7601
8034
  var TOOL_WORKFLOW_RUN_START = "tool-workflow/run-start";
7602
8035
  var TOOL_WORKFLOW_AGENT_START = "tool-workflow/agent-start";
@@ -7640,7 +8073,7 @@ function loadWatermark(workflowDir, fresh = false) {
7640
8073
  return cached;
7641
8074
  const watermark = new Map;
7642
8075
  try {
7643
- const raw = readFileSync16(join21(workflowDir, WORKFLOW_LEDGER_WATERMARK_FILE), "utf8");
8076
+ const raw = readFileSync17(join22(workflowDir, WORKFLOW_LEDGER_WATERMARK_FILE), "utf8");
7644
8077
  const record = asRecord(JSON.parse(raw));
7645
8078
  const cursors = asRecord(record?.cursors);
7646
8079
  if (cursors !== undefined) {
@@ -7663,10 +8096,10 @@ function loadWatermark(workflowDir, fresh = false) {
7663
8096
  }
7664
8097
  function saveWatermark(workflowDir, watermark) {
7665
8098
  try {
7666
- const file = join21(workflowDir, WORKFLOW_LEDGER_WATERMARK_FILE);
8099
+ const file = join22(workflowDir, WORKFLOW_LEDGER_WATERMARK_FILE);
7667
8100
  const tmp = `${file}.tmp`;
7668
- writeFileSync5(tmp, JSON.stringify({ v: 1, cursors: Object.fromEntries(watermark) }));
7669
- renameSync3(tmp, file);
8101
+ writeFileSync7(tmp, JSON.stringify({ v: 1, cursors: Object.fromEntries(watermark) }));
8102
+ renameSync4(tmp, file);
7670
8103
  } catch (error) {
7671
8104
  log3("warn", `workflow-ledger watermark write failed for ${workflowDir} — in-memory only (restart re-records): ${errorMessage3(error)}`);
7672
8105
  }
@@ -7879,8 +8312,8 @@ function registerWorkflowLedger(ctx, resolver, workflowAskCache) {
7879
8312
  }
7880
8313
 
7881
8314
  // src/gates/goal-bridge.ts
7882
- import { existsSync as existsSync20, readFileSync as readFileSync17, readdirSync as readdirSync13 } from "node:fs";
7883
- import { join as join22 } from "node:path";
8315
+ import { existsSync as existsSync20, readFileSync as readFileSync18, readdirSync as readdirSync13 } from "node:fs";
8316
+ import { join as join23 } from "node:path";
7884
8317
  var GOAL_BRIDGE_LOGGER = "mstar/goal-bridge";
7885
8318
  var DEFAULT_MAX_GOAL_ROUNDS = 256;
7886
8319
  var FLOW_SEQUENCE = "iteration-start → per-plan cycles → iteration-close → PR delivery → merge-ready";
@@ -7907,12 +8340,12 @@ function projectRegisterPointer(harnessDir) {
7907
8340
  for (const entry of readdirSync13(projectsDir, { withFileTypes: true })) {
7908
8341
  if (!entry.isDirectory())
7909
8342
  continue;
7910
- const registerPath = join22(projectsDir, entry.name, PROJECT_REGISTER_FILE);
8343
+ const registerPath = join23(projectsDir, entry.name, PROJECT_REGISTER_FILE);
7911
8344
  if (existsSync20(registerPath))
7912
8345
  return registerPath;
7913
8346
  }
7914
8347
  } catch {}
7915
- return join22(projectsDir, _DEFAULT_PROJECT, PROJECT_REGISTER_FILE);
8348
+ return join23(projectsDir, _DEFAULT_PROJECT, PROJECT_REGISTER_FILE);
7916
8349
  }
7917
8350
  function isRootLikeAgent(agent) {
7918
8351
  const header = agent?.session?.header;
@@ -7934,12 +8367,12 @@ function steeringCompass(harnessDir) {
7934
8367
  for (const entry of entries) {
7935
8368
  if (!entry.isDirectory())
7936
8369
  continue;
7937
- const compassPath = join22(iterationsDir, entry.name, "delivery-compass.md");
8370
+ const compassPath = join23(iterationsDir, entry.name, "delivery-compass.md");
7938
8371
  if (!existsSync20(compassPath))
7939
8372
  continue;
7940
8373
  let content;
7941
8374
  try {
7942
- content = readFileSync17(compassPath, "utf8");
8375
+ content = readFileSync18(compassPath, "utf8");
7943
8376
  } catch {
7944
8377
  continue;
7945
8378
  }
@@ -8116,7 +8549,7 @@ function registerGoalBridge(ctx, resolver, config) {
8116
8549
 
8117
8550
  // src/gates/plan-mode-bridge.ts
8118
8551
  import { existsSync as existsSync21 } from "node:fs";
8119
- import { join as join23 } from "node:path";
8552
+ import { join as join24 } from "node:path";
8120
8553
  var PLAN_MODE_BRIDGE_LOGGER = "mstar/plan-mode-bridge";
8121
8554
  var PLAN_STATUS_TODO = "Todo";
8122
8555
  var planModeBridgeLogSink = () => {};
@@ -8132,13 +8565,13 @@ function errorMessage5(error) {
8132
8565
  return error instanceof Error ? error.message : String(error);
8133
8566
  }
8134
8567
  function hasPrepareWindow(harnessDir) {
8135
- const statusPath = join23(harnessDir, STATUS_FILE);
8568
+ const statusPath = join24(harnessDir, STATUS_FILE);
8136
8569
  if (!existsSync21(statusPath))
8137
8570
  return false;
8138
8571
  const selection = resolveReadWorkflow(harnessDir);
8139
8572
  if (selection.kind === "error")
8140
8573
  return false;
8141
- const snapshotPath = join23(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
8574
+ const snapshotPath = join24(harnessDir, selection.dir, WORKFLOW_SNAPSHOT_FILE);
8142
8575
  let doc;
8143
8576
  try {
8144
8577
  doc = readJson(snapshotPath);
@@ -8584,16 +9017,16 @@ function engineStatusProvider(ctx, resolver, bootHarnessDir) {
8584
9017
  const now = Date.now();
8585
9018
  let entry = memo.get(harnessDir);
8586
9019
  if (entry === undefined || now - entry.builtAt >= DEFAULT_CATALOG_TTL_MS) {
8587
- entry = { source: buildCatalogSources(ctx, harnessDir), builtAt: now };
9020
+ entry = { payload: buildCatalogPayload(ctx, harnessDir), builtAt: now };
8588
9021
  memo.set(harnessDir, entry);
8589
9022
  }
8590
- return engineStatusSummary(entry.source);
9023
+ return engineStatusSummary(entry.payload);
8591
9024
  };
8592
9025
  }
8593
9026
  var DIGEST_PLAN_CAP = 8;
8594
- function engineStatusSummary(source) {
8595
- const lines = [`mstar engine status: v${source.version}`];
8596
- const state = source.state;
9027
+ function engineStatusSummary(payload) {
9028
+ const lines = [`mstar engine status: v${payload.version}`];
9029
+ const state = payload.state;
8597
9030
  if (state !== null) {
8598
9031
  const selection = state.selection;
8599
9032
  if (selection.kind === "active") {
@@ -8678,7 +9111,7 @@ function registerMstarCommands(ctx) {
8678
9111
  for (const file of readdirSync14(dir).sort()) {
8679
9112
  if (!file.endsWith(".md"))
8680
9113
  continue;
8681
- const parsed = parseCommandMarkdown(readFileSync18(join24(dir, file), "utf8"));
9114
+ const parsed = parseCommandMarkdown(readFileSync19(join25(dir, file), "utf8"));
8682
9115
  if (parsed === undefined)
8683
9116
  continue;
8684
9117
  commandsCtx.commands.register({
@@ -8871,7 +9304,7 @@ function apply(ctx, config) {
8871
9304
  const explicitKey = bootHarnessDir !== null ? EXPLICIT_CACHE_KEY : undefined;
8872
9305
  const catalogCache = new Map;
8873
9306
  if (explicitKey !== undefined) {
8874
- catalogCache.set(explicitKey, { sources: buildCatalogSources(ctx, bootHarnessDir), builtAt: Date.now() });
9307
+ catalogCache.set(explicitKey, { payload: buildCatalogPayload(ctx, bootHarnessDir), builtAt: Date.now() });
8875
9308
  }
8876
9309
  const catalogInvalidation = createCatalogInvalidation(catalogCache);
8877
9310
  if (explicitKey !== undefined)
@@ -8879,6 +9312,7 @@ function apply(ctx, config) {
8879
9312
  setAgentFlowInvalidator(catalogInvalidation.invalidate);
8880
9313
  const catalogDigests = new Map;
8881
9314
  ctx.on("agent/pre-step", (payload, next) => preStepCatalogListener(ctx, resolver, explicitKey, catalogCache, ttlMs, catalogInvalidation.register, catalogDigests, payload, next));
9315
+ installEngineStatusEndpoint(ctx, { resolver, bootHarnessDir });
8882
9316
  registerSddIterationTools(ctx, resolver);
8883
9317
  registerSeamTools(ctx, resolver);
8884
9318
  }