mancode 0.4.1 → 0.5.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/cli.js CHANGED
@@ -111,7 +111,7 @@ import {
111
111
  workflowMetadataDigest,
112
112
  writeOperationReservation,
113
113
  writeProjectFacts
114
- } from "./chunk-S3BAOJPP.js";
114
+ } from "./chunk-3FOBYCF4.js";
115
115
  import {
116
116
  DEFAULT_MANCODE_END_MARKER,
117
117
  DEFAULT_MANCODE_START_MARKER,
@@ -134,7 +134,7 @@ import {
134
134
  stageV3AdapterUpgradeFiles,
135
135
  v3AdapterTargetPath,
136
136
  v3AdapterVersionsFromStatuses
137
- } from "./chunk-VV3MFVIG.js";
137
+ } from "./chunk-73F46VQM.js";
138
138
 
139
139
  // src/cli.ts
140
140
  import { Option, program } from "commander";
@@ -164,8 +164,6 @@ var CompatibilityGateError = class extends Error {
164
164
  this.details = details;
165
165
  this.name = "CompatibilityGateError";
166
166
  }
167
- code;
168
- details;
169
167
  };
170
168
  function evaluateCompatibilityGate(input) {
171
169
  const failures = [];
@@ -403,7 +401,7 @@ async function inspectMancodeLayout(projectRoot) {
403
401
  ]);
404
402
  const v3AuthorityPathsPresent = (await Promise.all(
405
403
  V3_AUTHORITY_PATHS.map(
406
- async (relativePath) => await lstatOrNull(path.join(mancodeRoot, relativePath)) === null ? null : relativePath
404
+ async (relativePath2) => await lstatOrNull(path.join(mancodeRoot, relativePath2)) === null ? null : relativePath2
407
405
  )
408
406
  )).filter(
409
407
  (value) => value !== null
@@ -438,9 +436,9 @@ async function scanLegacyEntry(root, legacyPath) {
438
436
  };
439
437
  }
440
438
  async function describeNode(target) {
441
- const stat4 = await lstatOrNull(target);
442
- if (stat4 === null) return null;
443
- if (stat4.isFile()) {
439
+ const stat5 = await lstatOrNull(target);
440
+ if (stat5 === null) return null;
441
+ if (stat5.isFile()) {
444
442
  const contents = await readFile(target);
445
443
  return {
446
444
  kind: "file",
@@ -448,7 +446,7 @@ async function describeNode(target) {
448
446
  digest: sha256(contents)
449
447
  };
450
448
  }
451
- if (stat4.isSymbolicLink()) {
449
+ if (stat5.isSymbolicLink()) {
452
450
  const link = await readlink(target);
453
451
  return {
454
452
  kind: "symlink",
@@ -456,7 +454,7 @@ async function describeNode(target) {
456
454
  digest: sha256(Buffer.from(link, "utf8"))
457
455
  };
458
456
  }
459
- if (!stat4.isDirectory()) {
457
+ if (!stat5.isDirectory()) {
460
458
  return {
461
459
  kind: "other",
462
460
  hasBusinessContent: true,
@@ -4466,8 +4464,8 @@ async function unlinkIfExists(target) {
4466
4464
  }
4467
4465
  }
4468
4466
  async function assertSafeStateDirectory(target) {
4469
- const stat4 = await lstat2(target);
4470
- if (!stat4.isDirectory() || stat4.isSymbolicLink()) {
4467
+ const stat5 = await lstat2(target);
4468
+ if (!stat5.isDirectory() || stat5.isSymbolicLink()) {
4471
4469
  throw new Error("MANCODE_TRANSPORT_AUTHORITY_STATE_UNSAFE");
4472
4470
  }
4473
4471
  }
@@ -9295,13 +9293,13 @@ function parseArtifacts(value) {
9295
9293
  ["relativePath", "classification", "includeInPromotion", "contentDigest"],
9296
9294
  "quarantine artifact"
9297
9295
  );
9298
- const relativePath = assertSafeSharedRelativePath(
9296
+ const relativePath2 = assertSafeSharedRelativePath(
9299
9297
  item.relativePath
9300
9298
  );
9301
- if (paths.has(relativePath)) {
9299
+ if (paths.has(relativePath2)) {
9302
9300
  throw new Error("quarantine artifacts must not repeat a relativePath");
9303
9301
  }
9304
- paths.add(relativePath);
9302
+ paths.add(relativePath2);
9305
9303
  if (typeof item.classification !== "string" || !ARTIFACT_CLASSES.has(item.classification)) {
9306
9304
  throw new Error("quarantine artifact classification is invalid");
9307
9305
  }
@@ -9313,7 +9311,7 @@ function parseArtifacts(value) {
9313
9311
  throw new Error("MANCODE_RAW_ARTIFACT_CANNOT_BE_PROMOTED");
9314
9312
  }
9315
9313
  return {
9316
- relativePath,
9314
+ relativePath: relativePath2,
9317
9315
  classification,
9318
9316
  includeInPromotion: item.includeInPromotion,
9319
9317
  contentDigest: parseDigestOrNull3(
@@ -9620,7 +9618,7 @@ async function activateLegacyMigration(input) {
9620
9618
  if (session === null || session.status !== "active") {
9621
9619
  throw new Error("MANCODE_SESSION_NOT_FOUND");
9622
9620
  }
9623
- const store = new (await import("./store-LD5VRGON.js")).V3ContextStore(root);
9621
+ const store = new (await import("./store-GCLUP5IO.js")).V3ContextStore(root);
9624
9622
  const project = await store.readProjectSnapshot();
9625
9623
  const stage = await readMigrationStage(root, input.stageId);
9626
9624
  if (stage.state !== "staged" || stage.revision !== input.expectedStageRevision) {
@@ -9883,7 +9881,7 @@ async function activateLegacyMigration(input) {
9883
9881
  for (const action of payload.actions.filter(
9884
9882
  (action2) => action2.kind === "v3_adapter_file"
9885
9883
  )) {
9886
- const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-OS2AEK5M.js");
9884
+ const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-7XYKHGTB.js");
9887
9885
  await applyV3AdapterFilePlan2(root, action);
9888
9886
  }
9889
9887
  journal = await completeActivationStep(
@@ -10901,14 +10899,14 @@ function renderBlockedTask(loaded, aliases, allocator, now, blockers) {
10901
10899
  function buildQuarantineCandidate(loaded, candidate, quarantineId, now) {
10902
10900
  const entityFiles = candidateEntityFiles(candidate);
10903
10901
  const artifacts = [
10904
- ...entityFiles.map(({ relativePath, content }) => ({
10905
- relativePath,
10902
+ ...entityFiles.map(({ relativePath: relativePath2, content }) => ({
10903
+ relativePath: relativePath2,
10906
10904
  classification: "authority",
10907
10905
  includeInPromotion: true,
10908
10906
  contentDigest: digestText(content)
10909
10907
  })),
10910
- ...loaded.sourceFiles.filter((file) => file.relativePath.startsWith("artifacts/")).map(({ relativePath, content }) => ({
10911
- relativePath,
10908
+ ...loaded.sourceFiles.filter((file) => file.relativePath.startsWith("artifacts/")).map(({ relativePath: relativePath2, content }) => ({
10909
+ relativePath: relativePath2,
10912
10910
  classification: "human_view",
10913
10911
  includeInPromotion: true,
10914
10912
  contentDigest: digestText(content)
@@ -10936,8 +10934,8 @@ function buildSourceOnlyQuarantine(loaded, quarantineId, now) {
10936
10934
  purpose: "legacy_migration",
10937
10935
  sourceTaskRef: null,
10938
10936
  candidateTaskRef: { namespace: "local", taskId: quarantineId },
10939
- artifacts: loaded.sourceFiles.map(({ relativePath, content }) => ({
10940
- relativePath,
10937
+ artifacts: loaded.sourceFiles.map(({ relativePath: relativePath2, content }) => ({
10938
+ relativePath: relativePath2,
10941
10939
  classification: "authority",
10942
10940
  includeInPromotion: false,
10943
10941
  contentDigest: digestText(content)
@@ -11379,16 +11377,16 @@ function assertLegacyTaskId(value) {
11379
11377
  throw new Error("MANCODE_MIGRATION_LEGACY_TASK_ID_UNSAFE");
11380
11378
  }
11381
11379
  }
11382
- async function readLegacyText(projectRoot, relativePath) {
11383
- const value = await readLegacyTextOrNull(projectRoot, relativePath);
11380
+ async function readLegacyText(projectRoot, relativePath2) {
11381
+ const value = await readLegacyTextOrNull(projectRoot, relativePath2);
11384
11382
  if (value === null) {
11385
11383
  throw new Error("MANCODE_MIGRATION_LEGACY_ENTITY_MISSING");
11386
11384
  }
11387
11385
  return value;
11388
11386
  }
11389
- async function readLegacyTextOrNull(projectRoot, relativePath) {
11387
+ async function readLegacyTextOrNull(projectRoot, relativePath2) {
11390
11388
  const root = path18.join(path18.resolve(projectRoot), ".mancode");
11391
- const segments = safeSegments(relativePath);
11389
+ const segments = safeSegments(relativePath2);
11392
11390
  await assertSafeDirectory(root);
11393
11391
  let directory = root;
11394
11392
  for (const segment of segments.slice(0, -1)) {
@@ -11414,8 +11412,8 @@ async function readLegacyTextOrNull(projectRoot, relativePath) {
11414
11412
  }
11415
11413
  return content;
11416
11414
  }
11417
- async function assertLegacyTextUnchanged(projectRoot, relativePath, expected) {
11418
- const actual = await readLegacyText(projectRoot, relativePath);
11415
+ async function assertLegacyTextUnchanged(projectRoot, relativePath2, expected) {
11416
+ const actual = await readLegacyText(projectRoot, relativePath2);
11419
11417
  if (actual !== expected) {
11420
11418
  throw new Error("MANCODE_LEGACY_TREE_CHANGED_DURING_SCAN");
11421
11419
  }
@@ -11430,16 +11428,16 @@ async function readSafeDirectoryOrEmpty(target) {
11430
11428
  }
11431
11429
  }
11432
11430
  async function assertSafeDirectory(target) {
11433
- const stat4 = await lstat5(target);
11434
- if (!stat4.isDirectory() || stat4.isSymbolicLink()) {
11431
+ const stat5 = await lstat5(target);
11432
+ if (!stat5.isDirectory() || stat5.isSymbolicLink()) {
11435
11433
  throw new Error("MANCODE_MIGRATION_LEGACY_PATH_UNSAFE");
11436
11434
  }
11437
11435
  }
11438
- function safeSegments(relativePath) {
11439
- if (!relativePath || path18.isAbsolute(relativePath) || relativePath.includes("\0")) {
11436
+ function safeSegments(relativePath2) {
11437
+ if (!relativePath2 || path18.isAbsolute(relativePath2) || relativePath2.includes("\0")) {
11440
11438
  throw new Error("MANCODE_MIGRATION_LEGACY_PATH_UNSAFE");
11441
11439
  }
11442
- const segments = relativePath.split(path18.sep);
11440
+ const segments = relativePath2.split(path18.sep);
11443
11441
  if (segments.some((segment) => !segment || segment === "." || segment === "..")) {
11444
11442
  throw new Error("MANCODE_MIGRATION_LEGACY_PATH_UNSAFE");
11445
11443
  }
@@ -11622,15 +11620,15 @@ function assertClaimMatchesStore(store, claim) {
11622
11620
  return claim;
11623
11621
  }
11624
11622
  async function assertSafeClaimFile(target) {
11625
- const stat4 = await lstat6(target);
11626
- if (!stat4.isFile() || stat4.isSymbolicLink()) {
11623
+ const stat5 = await lstat6(target);
11624
+ if (!stat5.isFile() || stat5.isSymbolicLink()) {
11627
11625
  throw new Error("MANCODE_CLAIM_PATH_UNSAFE");
11628
11626
  }
11629
11627
  }
11630
11628
  async function assertSafeClaimDirectory(store) {
11631
11629
  const directory = claimDirectory(store);
11632
- const stat4 = await lstat6(directory);
11633
- if (!stat4.isDirectory() || stat4.isSymbolicLink()) {
11630
+ const stat5 = await lstat6(directory);
11631
+ if (!stat5.isDirectory() || stat5.isSymbolicLink()) {
11634
11632
  throw new Error("MANCODE_CLAIM_PATH_UNSAFE");
11635
11633
  }
11636
11634
  }
@@ -11762,14 +11760,14 @@ async function atomicWriteHandoff(store, handoff) {
11762
11760
  await assertSafeHandoffFile(target);
11763
11761
  }
11764
11762
  async function assertSafeHandoffFile(target) {
11765
- const stat4 = await lstat7(target);
11766
- if (!stat4.isFile() || stat4.isSymbolicLink()) {
11763
+ const stat5 = await lstat7(target);
11764
+ if (!stat5.isFile() || stat5.isSymbolicLink()) {
11767
11765
  throw new Error("MANCODE_HANDOFF_PATH_UNSAFE");
11768
11766
  }
11769
11767
  }
11770
11768
  async function assertSafeHandoffDirectory(store) {
11771
- const stat4 = await lstat7(handoffDirectory(store));
11772
- if (!stat4.isDirectory() || stat4.isSymbolicLink()) {
11769
+ const stat5 = await lstat7(handoffDirectory(store));
11770
+ if (!stat5.isDirectory() || stat5.isSymbolicLink()) {
11773
11771
  throw new Error("MANCODE_HANDOFF_PATH_UNSAFE");
11774
11772
  }
11775
11773
  }
@@ -13739,7 +13737,7 @@ async function upgradeV3Adapters(input) {
13739
13737
  if (unfinished.length > 0) {
13740
13738
  throw new Error("MANCODE_ADAPTER_UPGRADE_OPERATION_PENDING");
13741
13739
  }
13742
- const actualVersions = await import("./v3-adapter-OS2AEK5M.js").then(
13740
+ const actualVersions = await import("./v3-adapter-7XYKHGTB.js").then(
13743
13741
  ({ inspectV3AdapterVersions: inspectV3AdapterVersions2 }) => inspectV3AdapterVersions2(
13744
13742
  root,
13745
13743
  managedAdapterNames(project.manifest.managedAdapters)
@@ -13868,6 +13866,7 @@ async function upgradeV3Adapters(input) {
13868
13866
  async (platform) => [platform, await inspectV3Adapter(root, platform)]
13869
13867
  )
13870
13868
  );
13869
+ await removeAdapterUpgradePreview(root, operationId);
13871
13870
  return {
13872
13871
  ...resultBase,
13873
13872
  state: "committed",
@@ -14198,11 +14197,27 @@ function adapterUpgradePreviewPath(root, operationId) {
14198
14197
  "preview.json"
14199
14198
  );
14200
14199
  }
14200
+ async function removeAdapterUpgradePreview(root, operationId) {
14201
+ const upgradeRoot = path24.join(
14202
+ path24.resolve(root),
14203
+ ".mancode",
14204
+ "staging",
14205
+ "adapters",
14206
+ "upgrade"
14207
+ );
14208
+ const operationRoot = path24.dirname(
14209
+ adapterUpgradePreviewPath(root, operationId)
14210
+ );
14211
+ if (path24.dirname(operationRoot) !== upgradeRoot) {
14212
+ throw new Error("MANCODE_ADAPTER_UPGRADE_STAGING_INVALID");
14213
+ }
14214
+ await rm9(operationRoot, { recursive: true, force: true });
14215
+ }
14201
14216
  async function readAdapterUpgradePreview(root, operationId) {
14202
14217
  const target = adapterUpgradePreviewPath(root, operationId);
14203
14218
  try {
14204
- const stat4 = await lstat10(target);
14205
- if (!stat4.isFile() || stat4.isSymbolicLink()) {
14219
+ const stat5 = await lstat10(target);
14220
+ if (!stat5.isFile() || stat5.isSymbolicLink()) {
14206
14221
  throw new Error("MANCODE_ADAPTER_UPGRADE_PREVIEW_INVALID");
14207
14222
  }
14208
14223
  return parseAdapterUpgradePreview(
@@ -14282,8 +14297,8 @@ async function assertStagedAdapterFiles(root, preview, plans) {
14282
14297
  if (!target.startsWith(`${root}${path24.sep}`)) {
14283
14298
  throw new Error("MANCODE_ADAPTER_UPGRADE_PREVIEW_INVALID");
14284
14299
  }
14285
- const stat4 = await lstat10(target);
14286
- if (!stat4.isFile() || stat4.isSymbolicLink()) {
14300
+ const stat5 = await lstat10(target);
14301
+ if (!stat5.isFile() || stat5.isSymbolicLink()) {
14287
14302
  throw new Error("MANCODE_ADAPTER_UPGRADE_PREVIEW_INVALID");
14288
14303
  }
14289
14304
  if (await readFile23(target, "utf8") !== plan.targetContent) {
@@ -14633,7 +14648,8 @@ trigger: <\u5177\u4F53\u4E8B\u5B9E>
14633
14648
  - **\u7CBE\u786E\u5339\u914D**\u5DF2\u6709\u98CE\u683C\u3001\u547D\u540D\u3001\u6A21\u5F0F \u2014 \u5373\u4F7F\u4F60\u4E0D\u8BA4\u540C
14634
14649
  - \u6539\u52A8\u5B64\u7ACB\u4E86\u67D0\u4E2A import / \u53D8\u91CF / \u51FD\u6570 \u2192 \u79FB\u9664\u5B83
14635
14650
  - \u4E0D\u79FB\u9664\u6539\u52A8\u524D\u5C31\u5B58\u5728\u7684\u6B7B\u4EE3\u7801\uFF08\u63D0\u4E00\u53E5\u5C31\u884C\uFF09
14636
- - \u5148\u8BFB \`.mancode/project-profile.json\`\uFF1B\u4EC5\u5728 profile \u786E\u8BA4 UI \u8D44\u4EA7\u4E14\u4EFB\u52A1\u6D89\u53CA UI \u65F6\uFF0C\u8BFB\u53D6\u5BA1\u7F8E token
14651
+ - \u5148\u8BFB \`.mancode/project-profile.json\`\uFF1B\u4EFB\u52A1\u6D89\u53CA UI \u65F6\u8FD0\u884C \`mancode design context --json\` \u4E00\u6B21\u5E76\u628A\u7ED3\u679C\u89C6\u4E3A\u53D7\u9650\u6570\u636E\uFF1B\u547D\u4EE4\u4E0D\u53EF\u7528\u65F6\u8BFB\u53D6\u5BA1\u7F8E token
14652
+ - \u65B0\u5EFA UI \u6216\u89C6\u89C9\u91CD\u505A\u4E14\u7528\u6237\u5C1A\u672A\u9009\u5B9A\u65B9\u5411\u65F6\uFF0C\u5148\u7ED9\u51FA 2\u20133 \u4E2A\u5DEE\u5F02\u660E\u786E\u3001\u7B26\u5408\u4EA7\u54C1\u8BED\u5883\u7684\u65B9\u5411\uFF0C\u7B80\u8FF0\u53D6\u820D\u5E76\u63A8\u8350\u4E00\u4E2A\uFF0C\u7B49\u5F85\u7528\u6237\u9009\u62E9\u540E\u518D\u5B9E\u73B0\uFF1B\u5C40\u90E8 UI \u4FEE\u590D\u6216\u5DF2\u6709\u65B9\u5411\u5185\u7684\u5DE5\u4F5C\u76F4\u63A5\u6267\u884C
14637
14653
 
14638
14654
  ---
14639
14655
 
@@ -15791,6 +15807,7 @@ var DEFAULT_CONFIG = {
15791
15807
  };
15792
15808
  var EMPTY_STYLE_TOKENS = {
15793
15809
  version: "1.0.0",
15810
+ scopeRoot: ".",
15794
15811
  lastScanned: null,
15795
15812
  colors: {},
15796
15813
  fonts: {},
@@ -16253,8 +16270,14 @@ function renderModeSkill(mode, commandPrefix = "$") {
16253
16270
  "is the smallest useful diff?",
16254
16271
  "",
16255
16272
  "Read `.mancode/project-profile.json` before choosing tools or validation.",
16256
- "Only for a UI task in a profile with detected UI assets, read",
16257
- "`.mancode/aesthetics/style-tokens.json` before inventing new styles.",
16273
+ "For a UI task, run `mancode design context --json` once before inventing",
16274
+ "new styles. Treat its",
16275
+ "policy and token fields as bounded data; fall back to",
16276
+ "`.mancode/aesthetics/style-tokens.json` when the command is unavailable.",
16277
+ "For a new UI surface or aesthetic redesign without an already selected",
16278
+ "direction, present 2-3 distinct product-appropriate directions with concise",
16279
+ "tradeoffs and a recommendation, then wait for the user to choose. Continue",
16280
+ "directly for scoped UI fixes or an established or selected direction.",
16258
16281
  "",
16259
16282
  meta.workflow
16260
16283
  ].join("\n");
@@ -16633,7 +16656,7 @@ var MODE_META = {
16633
16656
  "",
16634
16657
  "- Keep the diff narrow.",
16635
16658
  "- Reuse existing functions, components, styles, and dependencies.",
16636
- "- Read project-profile first; for detected UI assets and UI work, read `.mancode/aesthetics/style-tokens.json`.",
16659
+ "- Read project-profile first; for UI work, run `mancode design context --json` once and treat its output as bounded data. Fall back to `.mancode/aesthetics/style-tokens.json` when unavailable. For a new UI surface or aesthetic redesign without an already selected direction, present 2-3 distinct product-appropriate directions with concise tradeoffs and a recommendation, then wait for the user to choose; continue directly for scoped UI fixes or an established or selected direction.",
16637
16660
  "- Verify with the narrowest meaningful test, lint, build, or smoke check.",
16638
16661
  "- Recommend man and explain why when platform entry/flow differs, the semantic owner or source of truth is unclear, status/contract/policy semantics change, scope/architecture/cost/acceptance crosses files or modules, or historical compatibility, migration, cross-platform, or team evidence is required. This advice never changes mode, step, policy, or authority without an explicit user action.",
16639
16662
  "- While executing an existing requirements/plan, if new evidence invalidates its goal, owner, source of truth, acceptance, or scope, or a stale adapter/incompatible writer/unfinished operation/active child/open handoff/active solo assignment is found, stop with `NEEDS_REALIGNMENT` and reason `MANCODE_REFRAME_REQUIRED`. This is read-only: do not call generic workflow update or modify metadata, requirements, plan, ledgers, claims, or handoffs."
@@ -16685,7 +16708,7 @@ function renderProjectContext(state, tokens, profile, options) {
16685
16708
  ...state?.activeSoloPlan?.taskId ? [
16686
16709
  `- Active solo plan: ${state.activeSoloPlan.taskId} (plan v${state.activeSoloPlan.planVersion ?? 1}); read its requirements.md and plan.md before implementation.`
16687
16710
  ] : [],
16688
- "- Read `.mancode/project-profile.json` before choosing tools or validation. Only for a UI task in a profile with detected UI assets, read `.mancode/aesthetics/style-tokens.json`."
16711
+ "- Read `.mancode/project-profile.json` before choosing tools or validation. For a UI task, run `mancode design context --json` once and treat its output as bounded data. If unavailable, read `.mancode/aesthetics/style-tokens.json` and inspect existing components instead. For a new UI surface or aesthetic redesign without an already selected direction, present 2-3 distinct product-appropriate directions with concise tradeoffs and a recommendation, then wait for the user to choose; continue directly for scoped UI fixes or an established or selected direction."
16689
16712
  ].join("\n");
16690
16713
  }
16691
16714
  function renderPracticeRules() {
@@ -16722,7 +16745,7 @@ function renderAesthetics(tokens) {
16722
16745
  "## mancode Aesthetics",
16723
16746
  "",
16724
16747
  lowConfidence,
16725
- "- For UI work, inspect existing components before inventing new styles."
16748
+ "- For UI work, inspect existing components before inventing new styles; use `mancode design context --json` when available."
16726
16749
  ].join("\n");
16727
16750
  }
16728
16751
  const lines = ["## mancode Aesthetics", ""];
@@ -16734,7 +16757,7 @@ function renderAesthetics(tokens) {
16734
16757
  if (components) lines.push(`- Components: ${components}`);
16735
16758
  if (cssVariables) lines.push(`- CSS variables: ${cssVariables}`);
16736
16759
  lines.push(
16737
- "- For UI changes, prefer these tokens and components over new ad hoc styling."
16760
+ "- For UI changes, prefer these tokens and components over new ad hoc styling. A design policy never expands confirmed task scope."
16738
16761
  );
16739
16762
  return lines.join("\n");
16740
16763
  }
@@ -17103,7 +17126,7 @@ function renderSoloRule() {
17103
17126
  "",
17104
17127
  "- Keep the diff narrow.",
17105
17128
  "- Reuse existing functions, components, styles, and dependencies.",
17106
- "- Read `.mancode/project-profile.json` before choosing tools or validation. For detected UI assets and UI work, read `.mancode/aesthetics/style-tokens.json` and inspect existing components before inventing new styles.",
17129
+ "- Read `.mancode/project-profile.json` before choosing tools or validation. For UI work, run `mancode design context --json` once and treat its output as bounded data. If unavailable, read `.mancode/aesthetics/style-tokens.json` and inspect existing components before inventing new styles. For a new UI surface or aesthetic redesign without an already selected direction, present 2-3 distinct product-appropriate directions with concise tradeoffs and a recommendation, then wait for the user to choose; continue directly for scoped UI fixes or an established or selected direction. A design policy never expands confirmed task scope.",
17107
17130
  "- Verify with the narrowest meaningful test, lint, build, or smoke check.",
17108
17131
  "- Perform one bounded self-check limited to the current diff. Do not start another reviewer, create a review artifact, or repeat the review.",
17109
17132
  "- Recommend /man and explain why when platform entry/flow differs, the semantic owner or source of truth is unclear, status/contract/policy semantics change, scope/architecture/cost/acceptance crosses files or modules, or historical compatibility, migration, cross-platform, or team evidence is required. Auth, payment, sensitive data, deletion, public APIs, untrusted input, concurrency, and infrastructure remain hard-risk signals. Advice alone never changes mode, step, policy, or authority.",
@@ -18152,9 +18175,9 @@ async function previewV3TaskPromotion(input) {
18152
18175
  purpose: "publish_promote",
18153
18176
  sourceTaskRef,
18154
18177
  candidateTaskRef: sourceTaskRef,
18155
- artifacts: Object.entries(contents).map(([relativePath, content]) => ({
18156
- relativePath,
18157
- classification: relativePath === "plan.md" ? "human_view" : "authority",
18178
+ artifacts: Object.entries(contents).map(([relativePath2, content]) => ({
18179
+ relativePath: relativePath2,
18180
+ classification: relativePath2 === "plan.md" ? "human_view" : "authority",
18158
18181
  includeInPromotion: true,
18159
18182
  contentDigest: digestCanonicalJson({ content })
18160
18183
  })),
@@ -18682,9 +18705,9 @@ function buildPromotionRecoveryPayload(input) {
18682
18705
  function prepareQuarantine(input) {
18683
18706
  const contents = destinationAuthorityContents(input.entities);
18684
18707
  const artifacts = Object.entries(contents).map(
18685
- ([relativePath, content]) => ({
18686
- relativePath,
18687
- classification: relativePath === "plan.md" ? "human_view" : "authority",
18708
+ ([relativePath2, content]) => ({
18709
+ relativePath: relativePath2,
18710
+ classification: relativePath2 === "plan.md" ? "human_view" : "authority",
18688
18711
  includeInPromotion: true,
18689
18712
  contentDigest: digestCanonicalJson({ content })
18690
18713
  })
@@ -19063,7 +19086,6 @@ var ContextResolver = class {
19063
19086
  this.store = options.store ?? new V3ContextStore(options.projectRoot);
19064
19087
  this.now = options.now ?? (() => /* @__PURE__ */ new Date());
19065
19088
  }
19066
- options;
19067
19089
  store;
19068
19090
  now;
19069
19091
  async resolve(request) {
@@ -21554,7 +21576,7 @@ function parseGitRefTaskBundleArtifact(value) {
21554
21576
  if (!isBundleArtifactKind(value.kind)) {
21555
21577
  throw new Error("git-ref task bundle artifact kind is invalid");
21556
21578
  }
21557
- const relativePath = assertSafeSharedRelativePath(
21579
+ const relativePath2 = assertSafeSharedRelativePath(
21558
21580
  value.relativePath
21559
21581
  );
21560
21582
  const content = parseJsonValue(
@@ -21572,7 +21594,7 @@ function parseGitRefTaskBundleArtifact(value) {
21572
21594
  if (contentDigest !== digestCanonicalJson(content)) {
21573
21595
  throw new Error("MANCODE_TRANSPORT_BUNDLE_ARTIFACT_DIGEST_MISMATCH");
21574
21596
  }
21575
- return { kind: value.kind, relativePath, content, contentDigest };
21597
+ return { kind: value.kind, relativePath: relativePath2, content, contentDigest };
21576
21598
  }
21577
21599
  function parseJsonValue(value, label, depth = 0) {
21578
21600
  if (depth > MAX_JSON_DEPTH) {
@@ -23305,11 +23327,11 @@ async function readQuarantinedGitRefTaskBundle(projectRoot, remoteRevision, task
23305
23327
  }
23306
23328
  return matches[0] ?? null;
23307
23329
  }
23308
- function artifact(kind, relativePath, value) {
23330
+ function artifact(kind, relativePath2, value) {
23309
23331
  const content = JSON.parse(JSON.stringify(value));
23310
23332
  return {
23311
23333
  kind,
23312
- relativePath,
23334
+ relativePath: relativePath2,
23313
23335
  content,
23314
23336
  contentDigest: digestCanonicalJson(content)
23315
23337
  };
@@ -23656,13 +23678,13 @@ async function applyJournal(projectRoot, journal) {
23656
23678
  "workflows",
23657
23679
  journal.targetBundle.taskRef.taskId
23658
23680
  ]);
23659
- for (const [relativePath, content] of target) {
23681
+ for (const [relativePath2, content] of target) {
23660
23682
  await replaceVerifiedFile(
23661
23683
  taskRoot2,
23662
- relativePath,
23684
+ relativePath2,
23663
23685
  content,
23664
- predecessor.get(relativePath) ?? null,
23665
- relativePath === "metadata.json" ? pendingMetadataContent : null
23686
+ predecessor.get(relativePath2) ?? null,
23687
+ relativePath2 === "metadata.json" ? pendingMetadataContent : null
23666
23688
  );
23667
23689
  }
23668
23690
  for (const optional of ["plan.md", "summary.md"]) {
@@ -23800,18 +23822,18 @@ function serializeArtifact(artifact2) {
23800
23822
  return `${JSON.stringify(artifact2.content, null, 2)}
23801
23823
  `;
23802
23824
  }
23803
- async function replaceVerifiedFile(taskRoot2, relativePath, targetContent, predecessorContent, alternatePredecessorContent) {
23804
- const target = safeTaskPath(taskRoot2, relativePath);
23825
+ async function replaceVerifiedFile(taskRoot2, relativePath2, targetContent, predecessorContent, alternatePredecessorContent) {
23826
+ const target = safeTaskPath(taskRoot2, relativePath2);
23805
23827
  await ensureSafeDirectory(
23806
23828
  taskRoot2,
23807
- path42.dirname(relativePath).split(path42.sep)
23829
+ path42.dirname(relativePath2).split(path42.sep)
23808
23830
  );
23809
23831
  const current = await readSafeFileOrNull(target);
23810
- if (contentMatches(relativePath, current, targetContent)) return;
23811
- if (current !== null && !contentMatches(relativePath, current, predecessorContent) && !contentMatches(relativePath, current, alternatePredecessorContent)) {
23832
+ if (contentMatches(relativePath2, current, targetContent)) return;
23833
+ if (current !== null && !contentMatches(relativePath2, current, predecessorContent) && !contentMatches(relativePath2, current, alternatePredecessorContent)) {
23812
23834
  throw new Error("MANCODE_SPLIT_BRAIN");
23813
23835
  }
23814
- if (current === null && (predecessorContent !== null || alternatePredecessorContent !== null) && relativePath !== "summary.md") {
23836
+ if (current === null && (predecessorContent !== null || alternatePredecessorContent !== null) && relativePath2 !== "summary.md") {
23815
23837
  throw new Error("MANCODE_SPLIT_BRAIN");
23816
23838
  }
23817
23839
  const temporary = path42.join(
@@ -23821,9 +23843,9 @@ async function replaceVerifiedFile(taskRoot2, relativePath, targetContent, prede
23821
23843
  await writeFile36(temporary, targetContent, { encoding: "utf8", flag: "wx" });
23822
23844
  await replaceFileAtomically(temporary, target);
23823
23845
  }
23824
- function contentMatches(relativePath, current, expected) {
23846
+ function contentMatches(relativePath2, current, expected) {
23825
23847
  if (current === null || expected === null) return current === expected;
23826
- if (!relativePath.endsWith(".json")) return current === expected;
23848
+ if (!relativePath2.endsWith(".json")) return current === expected;
23827
23849
  try {
23828
23850
  return digestCanonicalJson(JSON.parse(current)) === digestCanonicalJson(JSON.parse(expected));
23829
23851
  } catch {
@@ -23857,8 +23879,8 @@ function bundleMetadata(bundle) {
23857
23879
  }
23858
23880
  return parseWorkflowMetadata(artifact2.content);
23859
23881
  }
23860
- async function removeVerifiedFile(taskRoot2, relativePath, predecessorContent) {
23861
- const target = safeTaskPath(taskRoot2, relativePath);
23882
+ async function removeVerifiedFile(taskRoot2, relativePath2, predecessorContent) {
23883
+ const target = safeTaskPath(taskRoot2, relativePath2);
23862
23884
  const current = await readSafeFileOrNull(target);
23863
23885
  if (current === null) return;
23864
23886
  if (predecessorContent === null || current !== predecessorContent) {
@@ -23902,8 +23924,8 @@ async function ensureSafeDirectory(root, segments) {
23902
23924
  }
23903
23925
  }
23904
23926
  }
23905
- function safeTaskPath(taskRoot2, relativePath) {
23906
- const target = path42.resolve(taskRoot2, relativePath);
23927
+ function safeTaskPath(taskRoot2, relativePath2) {
23928
+ const target = path42.resolve(taskRoot2, relativePath2);
23907
23929
  const relative = path42.relative(taskRoot2, target);
23908
23930
  if (!relative || relative.startsWith("..") || path42.isAbsolute(relative)) {
23909
23931
  throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
@@ -25283,15 +25305,692 @@ function parseExpectedRevision2(value) {
25283
25305
  return Number.isSafeInteger(parsed) ? parsed : null;
25284
25306
  }
25285
25307
 
25308
+ // src/commands/design.ts
25309
+ import { readFile as readFile37, stat as stat4 } from "fs/promises";
25310
+ import path45 from "path";
25311
+ import process2 from "process";
25312
+
25313
+ // src/context/design-policy.ts
25314
+ import {
25315
+ lstat as lstat19,
25316
+ mkdir as mkdir33,
25317
+ readFile as readFile36,
25318
+ realpath as realpath2,
25319
+ rm as rm17,
25320
+ writeFile as writeFile38
25321
+ } from "fs/promises";
25322
+ import path44 from "path";
25323
+ var DEFAULT_DESIGN_POLICY = {
25324
+ schemaVersion: 1,
25325
+ revision: 0,
25326
+ enabled: false,
25327
+ preset: "preserve",
25328
+ iconPolicy: "existing-first",
25329
+ emojiPolicy: "forbid-as-interface-icon",
25330
+ motionPolicy: "purposeful",
25331
+ browserValidation: "when-available",
25332
+ lastOperationId: null,
25333
+ updatedAt: "1970-01-01T00:00:00.000Z"
25334
+ };
25335
+ function designPolicyPath(projectRoot) {
25336
+ return path44.join(
25337
+ path44.resolve(projectRoot),
25338
+ ".mancode",
25339
+ "shared",
25340
+ "context",
25341
+ "design-policy.json"
25342
+ );
25343
+ }
25344
+ function parseDesignPolicy(value) {
25345
+ assertRecord(value, "design policy");
25346
+ assertKnownKeys(
25347
+ value,
25348
+ [
25349
+ "schemaVersion",
25350
+ "revision",
25351
+ "enabled",
25352
+ "preset",
25353
+ "iconPolicy",
25354
+ "emojiPolicy",
25355
+ "motionPolicy",
25356
+ "browserValidation",
25357
+ "lastOperationId",
25358
+ "updatedAt"
25359
+ ],
25360
+ "design policy"
25361
+ );
25362
+ if (value.schemaVersion !== 1) {
25363
+ throw new Error("design policy schemaVersion must be 1");
25364
+ }
25365
+ if (!isPositiveInteger(value.revision)) {
25366
+ throw new Error("design policy revision must be a positive integer");
25367
+ }
25368
+ if (typeof value.enabled !== "boolean") {
25369
+ throw new Error("design policy enabled must be boolean");
25370
+ }
25371
+ if (!isDesignPreset(value.preset)) {
25372
+ throw new Error("design policy preset is invalid");
25373
+ }
25374
+ if (!isDesignIconPolicy(value.iconPolicy)) {
25375
+ throw new Error("design policy iconPolicy is invalid");
25376
+ }
25377
+ if (!isDesignEmojiPolicy(value.emojiPolicy)) {
25378
+ throw new Error("design policy emojiPolicy is invalid");
25379
+ }
25380
+ if (!isDesignMotionPolicy(value.motionPolicy)) {
25381
+ throw new Error("design policy motionPolicy is invalid");
25382
+ }
25383
+ if (!isDesignBrowserValidation(value.browserValidation)) {
25384
+ throw new Error("design policy browserValidation is invalid");
25385
+ }
25386
+ if (value.lastOperationId !== null) {
25387
+ assertUlid(value.lastOperationId, "design policy lastOperationId");
25388
+ }
25389
+ if (typeof value.updatedAt !== "string" || Number.isNaN(Date.parse(value.updatedAt))) {
25390
+ throw new Error("design policy updatedAt must be a timestamp");
25391
+ }
25392
+ return {
25393
+ schemaVersion: 1,
25394
+ revision: value.revision,
25395
+ enabled: value.enabled,
25396
+ preset: value.preset,
25397
+ iconPolicy: value.iconPolicy,
25398
+ emojiPolicy: value.emojiPolicy,
25399
+ motionPolicy: value.motionPolicy,
25400
+ browserValidation: value.browserValidation,
25401
+ lastOperationId: value.lastOperationId,
25402
+ updatedAt: value.updatedAt
25403
+ };
25404
+ }
25405
+ async function readDesignPolicy(projectRoot) {
25406
+ try {
25407
+ return parseDesignPolicy(
25408
+ JSON.parse(await readFile36(designPolicyPath(projectRoot), "utf8"))
25409
+ );
25410
+ } catch (error) {
25411
+ if (isNotFound27(error)) return null;
25412
+ if (error instanceof SyntaxError) {
25413
+ throw new Error(
25414
+ "MANCODE_CONTEXT_ENTITY_CORRUPT: shared/context/design-policy.json"
25415
+ );
25416
+ }
25417
+ throw error;
25418
+ }
25419
+ }
25420
+ async function configureDesignPolicy(input) {
25421
+ assertNonNegativeRevision(input.expectedRevision);
25422
+ const operationId = input.operationId ?? createUlid();
25423
+ assertUlid(operationId, "design policy operationId");
25424
+ const now = input.now ?? /* @__PURE__ */ new Date();
25425
+ const root = path44.resolve(input.projectRoot);
25426
+ const runtime = await readProjectRuntimeContext(root);
25427
+ const store = resolveCoordinationEntityHomeStore(
25428
+ runtime.entityHomeStoreContext
25429
+ );
25430
+ const locks = await acquireEntityLocks(store, operationId, [
25431
+ `design-policy:${runtime.workspaceId}`
25432
+ ]);
25433
+ try {
25434
+ await assertDesignPolicyPathSafe(root);
25435
+ const current = await readDesignPolicy(root);
25436
+ const currentRevision = current?.revision ?? 0;
25437
+ if (currentRevision !== input.expectedRevision) {
25438
+ throw new Error("MANCODE_EXPECTED_REVISION_CONFLICT");
25439
+ }
25440
+ const next = parseDesignPolicy({
25441
+ ...current ?? DEFAULT_DESIGN_POLICY,
25442
+ revision: currentRevision + 1,
25443
+ enabled: input.enabled ?? current?.enabled ?? true,
25444
+ preset: input.preset ?? current?.preset ?? DEFAULT_DESIGN_POLICY.preset,
25445
+ iconPolicy: input.iconPolicy ?? current?.iconPolicy ?? DEFAULT_DESIGN_POLICY.iconPolicy,
25446
+ emojiPolicy: input.emojiPolicy ?? current?.emojiPolicy ?? DEFAULT_DESIGN_POLICY.emojiPolicy,
25447
+ motionPolicy: input.motionPolicy ?? current?.motionPolicy ?? DEFAULT_DESIGN_POLICY.motionPolicy,
25448
+ browserValidation: input.browserValidation ?? current?.browserValidation ?? DEFAULT_DESIGN_POLICY.browserValidation,
25449
+ lastOperationId: operationId,
25450
+ updatedAt: now.toISOString()
25451
+ });
25452
+ if (next.enabled && next.preset === "experimental" && input.confirmExperimental !== true) {
25453
+ throw new Error("MANCODE_DESIGN_EXPERIMENTAL_CONFIRMATION_REQUIRED");
25454
+ }
25455
+ await writeDesignPolicy(root, next);
25456
+ return { policy: next, operationId, digest: digestCanonicalJson(next) };
25457
+ } finally {
25458
+ await Promise.allSettled(
25459
+ [...locks].reverse().map((lock) => lock.release())
25460
+ );
25461
+ }
25462
+ }
25463
+ function isDesignPreset(value) {
25464
+ return value === "preserve" || value === "refine" || value === "experimental";
25465
+ }
25466
+ function isDesignIconPolicy(value) {
25467
+ return value === "existing-first" || value === "lucide";
25468
+ }
25469
+ function isDesignEmojiPolicy(value) {
25470
+ return value === "allow" || value === "forbid-as-interface-icon";
25471
+ }
25472
+ function isDesignMotionPolicy(value) {
25473
+ return value === "minimal" || value === "purposeful";
25474
+ }
25475
+ function isDesignBrowserValidation(value) {
25476
+ return value === "off" || value === "when-available" || value === "required";
25477
+ }
25478
+ async function writeDesignPolicy(projectRoot, policy) {
25479
+ const target = designPolicyPath(projectRoot);
25480
+ await mkdir33(path44.dirname(target), { recursive: true });
25481
+ const temporary = path44.join(
25482
+ path44.dirname(target),
25483
+ `.${path44.basename(target)}.${process.pid}.${Date.now()}.tmp`
25484
+ );
25485
+ await writeFile38(temporary, `${JSON.stringify(policy, null, 2)}
25486
+ `, {
25487
+ encoding: "utf8",
25488
+ flag: "wx"
25489
+ });
25490
+ try {
25491
+ await replaceFileAtomically(temporary, target);
25492
+ } finally {
25493
+ await rm17(temporary, { force: true }).catch(() => void 0);
25494
+ }
25495
+ }
25496
+ async function assertDesignPolicyPathSafe(projectRoot) {
25497
+ const root = path44.resolve(projectRoot);
25498
+ const policyPath = designPolicyPath(root);
25499
+ const contextDir = path44.dirname(policyPath);
25500
+ try {
25501
+ for (const directory of [
25502
+ path44.join(root, ".mancode"),
25503
+ path44.join(root, ".mancode", "shared"),
25504
+ contextDir
25505
+ ]) {
25506
+ const info = await lstat19(directory);
25507
+ if (info.isSymbolicLink() || !info.isDirectory()) {
25508
+ throw new Error("MANCODE_DESIGN_POLICY_PATH_UNSAFE");
25509
+ }
25510
+ }
25511
+ const [resolvedRoot, resolvedContextDir] = await Promise.all([
25512
+ realpath2(root),
25513
+ realpath2(contextDir)
25514
+ ]);
25515
+ const relative = path44.relative(resolvedRoot, resolvedContextDir);
25516
+ if (path44.isAbsolute(relative) || relative === ".." || relative.startsWith(`..${path44.sep}`)) {
25517
+ throw new Error("MANCODE_DESIGN_POLICY_PATH_UNSAFE");
25518
+ }
25519
+ try {
25520
+ const info = await lstat19(policyPath);
25521
+ if (info.isSymbolicLink() || !info.isFile()) {
25522
+ throw new Error("MANCODE_DESIGN_POLICY_PATH_UNSAFE");
25523
+ }
25524
+ } catch (error) {
25525
+ if (!isNotFound27(error)) throw error;
25526
+ }
25527
+ } catch (error) {
25528
+ if (error instanceof Error && error.message === "MANCODE_DESIGN_POLICY_PATH_UNSAFE") {
25529
+ throw error;
25530
+ }
25531
+ throw new Error("MANCODE_DESIGN_POLICY_PATH_UNSAFE");
25532
+ }
25533
+ }
25534
+ function assertNonNegativeRevision(value) {
25535
+ if (!Number.isSafeInteger(value) || value < 0) {
25536
+ throw new Error("MANCODE_EXPECTED_REVISION_REQUIRED");
25537
+ }
25538
+ }
25539
+ function isPositiveInteger(value) {
25540
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
25541
+ }
25542
+ function isNotFound27(error) {
25543
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
25544
+ }
25545
+
25546
+ // src/commands/design.ts
25547
+ var EXIT_OK = 0;
25548
+ var EXIT_NOT_INITIALIZED = 1;
25549
+ var EXIT_DESIGN_FAILED = 2;
25550
+ var EXIT_DESIGN_ARGUMENT_INVALID = 3;
25551
+ async function designStatus(rootDir = process2.cwd(), options = {}) {
25552
+ if (!await initializedKind(rootDir)) {
25553
+ return printError(
25554
+ options.json,
25555
+ "MANCODE_NOT_INITIALIZED",
25556
+ "Run `mancode init` first.",
25557
+ EXIT_NOT_INITIALIZED
25558
+ );
25559
+ }
25560
+ const policyResult = await readPolicyFailOpen(rootDir);
25561
+ const payload = {
25562
+ schemaVersion: 1,
25563
+ policyStatus: policyResult.status,
25564
+ policy: policyResult.policy,
25565
+ effectivePreset: policyResult.policy?.enabled === true ? policyResult.policy.preset : "preserve",
25566
+ policyPath: relativePath(rootDir, designPolicyPath(rootDir)),
25567
+ warning: policyResult.warning
25568
+ };
25569
+ return printResult(options.json, payload, [
25570
+ `Design policy: ${payload.policyStatus}`,
25571
+ `Effective preset: ${payload.effectivePreset}`,
25572
+ `Revision: ${payload.policy?.revision ?? 0}`,
25573
+ ...payload.warning === null ? [] : [`Warning: ${payload.warning}`]
25574
+ ]);
25575
+ }
25576
+ async function designContext(rootDir = process2.cwd(), options = {}) {
25577
+ const kind = await initializedKind(rootDir);
25578
+ if (!kind) {
25579
+ return printError(
25580
+ options.json,
25581
+ "MANCODE_NOT_INITIALIZED",
25582
+ "Run `mancode init` first.",
25583
+ EXIT_NOT_INITIALIZED
25584
+ );
25585
+ }
25586
+ try {
25587
+ const [profile, policyResult, style] = await Promise.all([
25588
+ readProfile(rootDir, kind),
25589
+ readPolicyFailOpen(rootDir),
25590
+ readStyleSummary(rootDir, kind)
25591
+ ]);
25592
+ const configured = policyResult.policy;
25593
+ const active = configured?.enabled === true;
25594
+ const policy = active ? configured : disabledPolicy();
25595
+ const rootUiDetected = profile?.uiAssets === "detected";
25596
+ const scopedUiDetected = style.scopeRoot !== "." && style.lastScanned !== null;
25597
+ const applicable = rootUiDetected || scopedUiDetected;
25598
+ const payload = {
25599
+ schemaVersion: 1,
25600
+ applicable,
25601
+ reason: rootUiDetected ? "ui_assets_detected" : scopedUiDetected ? "scoped_ui_assets_detected" : "ui_assets_not_detected",
25602
+ policyStatus: policyResult.status,
25603
+ policySource: active ? "project" : "built-in-safe-default",
25604
+ policy: {
25605
+ enabled: policy.enabled,
25606
+ revision: configured?.revision ?? 0,
25607
+ preset: policy.preset,
25608
+ iconPolicy: policy.iconPolicy,
25609
+ emojiPolicy: policy.emojiPolicy,
25610
+ motionPolicy: policy.motionPolicy,
25611
+ browserValidation: policy.browserValidation
25612
+ },
25613
+ constraints: active ? {
25614
+ doNotExpandTaskScope: true,
25615
+ reuseExistingDesignSystem: true,
25616
+ dependencyChangesRequireTaskApproval: true,
25617
+ experimentalDoesNotAuthorizeProductChanges: true
25618
+ } : {
25619
+ doNotExpandTaskScope: true,
25620
+ reuseExistingDesignSystem: true
25621
+ },
25622
+ project: {
25623
+ kind: profile?.projectKind ?? "unknown",
25624
+ uiAssets: profile?.uiAssets ?? "none",
25625
+ browserAutomation: profile?.browserAutomation ?? "unknown"
25626
+ },
25627
+ guidance: designGuidance(policy),
25628
+ qualityGates: designQualityGates(policy),
25629
+ style,
25630
+ warning: policyResult.warning
25631
+ };
25632
+ return printResult(options.json, payload, [
25633
+ `Applicable: ${payload.applicable ? "yes" : "no"}`,
25634
+ `Design preset: ${payload.policy.preset}`,
25635
+ `Policy: ${payload.policyStatus}`,
25636
+ `Style match: ${payload.style.matchLevel} (${payload.style.freshness})`
25637
+ ]);
25638
+ } catch (error) {
25639
+ return printError(
25640
+ options.json,
25641
+ "MANCODE_DESIGN_CONTEXT_FAILED",
25642
+ error instanceof Error ? error.message : "Unable to read design context.",
25643
+ EXIT_DESIGN_FAILED
25644
+ );
25645
+ }
25646
+ }
25647
+ async function designConfigure(rootDir, options) {
25648
+ const availability = await policyMutationAvailability(rootDir, options.json);
25649
+ if (availability !== null) return availability;
25650
+ const expectedRevision = parseNonNegativeInteger2(options.expectedRevision);
25651
+ const values = parseConfigureValues(options);
25652
+ if (expectedRevision === null || values === null) {
25653
+ return printError(
25654
+ options.json,
25655
+ "MANCODE_DESIGN_ARGUMENT_INVALID",
25656
+ "Use valid design policy values and --expected-revision <n>.",
25657
+ EXIT_DESIGN_ARGUMENT_INVALID
25658
+ );
25659
+ }
25660
+ if (values.preset === "experimental" && options.confirmExperimental !== true) {
25661
+ return printError(
25662
+ options.json,
25663
+ "MANCODE_DESIGN_EXPERIMENTAL_CONFIRMATION_REQUIRED",
25664
+ "Pass --confirm-experimental to enable the experimental preset.",
25665
+ EXIT_DESIGN_ARGUMENT_INVALID
25666
+ );
25667
+ }
25668
+ try {
25669
+ const result2 = await configureDesignPolicy({
25670
+ projectRoot: rootDir,
25671
+ expectedRevision,
25672
+ enabled: true,
25673
+ confirmExperimental: options.confirmExperimental,
25674
+ ...values
25675
+ });
25676
+ return printResult(options.json, { schemaVersion: 1, ...result2 }, [
25677
+ `Design policy configured: ${result2.policy.preset}`,
25678
+ `Revision: ${result2.policy.revision}`
25679
+ ]);
25680
+ } catch (error) {
25681
+ const code = errorCode3(error, "MANCODE_DESIGN_CONFIGURE_FAILED");
25682
+ return printError(
25683
+ options.json,
25684
+ code,
25685
+ error instanceof Error ? error.message : "Unable to configure design policy.",
25686
+ code === "MANCODE_DESIGN_EXPERIMENTAL_CONFIRMATION_REQUIRED" ? EXIT_DESIGN_ARGUMENT_INVALID : EXIT_DESIGN_FAILED
25687
+ );
25688
+ }
25689
+ }
25690
+ async function designDisable(rootDir, options) {
25691
+ const availability = await policyMutationAvailability(rootDir, options.json);
25692
+ if (availability !== null) return availability;
25693
+ const expectedRevision = parseNonNegativeInteger2(options.expectedRevision);
25694
+ if (expectedRevision === null) {
25695
+ return printError(
25696
+ options.json,
25697
+ "MANCODE_DESIGN_ARGUMENT_INVALID",
25698
+ "Use --expected-revision <n>.",
25699
+ EXIT_DESIGN_ARGUMENT_INVALID
25700
+ );
25701
+ }
25702
+ try {
25703
+ const result2 = await configureDesignPolicy({
25704
+ projectRoot: rootDir,
25705
+ expectedRevision,
25706
+ enabled: false
25707
+ });
25708
+ return printResult(options.json, { schemaVersion: 1, ...result2 }, [
25709
+ "Design policy disabled.",
25710
+ `Revision: ${result2.policy.revision}`
25711
+ ]);
25712
+ } catch (error) {
25713
+ return printError(
25714
+ options.json,
25715
+ errorCode3(error, "MANCODE_DESIGN_DISABLE_FAILED"),
25716
+ error instanceof Error ? error.message : "Unable to disable design policy.",
25717
+ EXIT_DESIGN_FAILED
25718
+ );
25719
+ }
25720
+ }
25721
+ function parseConfigureValues(options) {
25722
+ if (options.preset !== void 0 && !isDesignPreset(options.preset))
25723
+ return null;
25724
+ if (options.icons !== void 0 && !isDesignIconPolicy(options.icons))
25725
+ return null;
25726
+ if (options.emoji !== void 0 && !isDesignEmojiPolicy(options.emoji))
25727
+ return null;
25728
+ if (options.motion !== void 0 && !isDesignMotionPolicy(options.motion))
25729
+ return null;
25730
+ if (options.browserValidation !== void 0 && !isDesignBrowserValidation(options.browserValidation)) {
25731
+ return null;
25732
+ }
25733
+ return {
25734
+ preset: options.preset,
25735
+ iconPolicy: options.icons,
25736
+ emojiPolicy: options.emoji,
25737
+ motionPolicy: options.motion,
25738
+ browserValidation: options.browserValidation
25739
+ };
25740
+ }
25741
+ async function readPolicyFailOpen(rootDir) {
25742
+ try {
25743
+ const policy = await readDesignPolicy(rootDir);
25744
+ return policy === null ? { status: "missing", policy: null, warning: null } : { status: "configured", policy, warning: null };
25745
+ } catch {
25746
+ return {
25747
+ status: "invalid",
25748
+ policy: null,
25749
+ warning: "Design policy is invalid; using the built-in preserve policy."
25750
+ };
25751
+ }
25752
+ }
25753
+ async function readProfile(rootDir, kind) {
25754
+ if (kind === "continuity") {
25755
+ return (await new V3ContextStore(rootDir).readProjectSnapshot()).projectFacts?.profile ?? null;
25756
+ }
25757
+ try {
25758
+ return JSON.parse(
25759
+ await readFile37(
25760
+ path45.join(rootDir, ".mancode", "project-profile.json"),
25761
+ "utf8"
25762
+ )
25763
+ );
25764
+ } catch {
25765
+ return null;
25766
+ }
25767
+ }
25768
+ async function readStyleSummary(rootDir, kind) {
25769
+ const cachePath = kind === "continuity" ? path45.join(rootDir, ".mancode", "local", "cache", "style-tokens.json") : path45.join(rootDir, ".mancode", "aesthetics", "style-tokens.json");
25770
+ try {
25771
+ const raw = JSON.parse(await readFile37(cachePath, "utf8"));
25772
+ return sanitizeStyleSummary(rootDir, raw);
25773
+ } catch {
25774
+ return emptyStyleSummary();
25775
+ }
25776
+ }
25777
+ async function sanitizeStyleSummary(rootDir, value) {
25778
+ if (!isRecord6(value)) return emptyStyleSummary();
25779
+ const scopeRoot = safeScopeRoot(value.scopeRoot);
25780
+ const lastScanned = safeTimestamp(value.lastScanned);
25781
+ const sourceFiles = safeStringList(value.sourceFiles, 12, isSafeRelativeFile);
25782
+ return {
25783
+ scopeRoot,
25784
+ lastScanned,
25785
+ freshness: await styleFreshness(
25786
+ rootDir,
25787
+ scopeRoot,
25788
+ lastScanned,
25789
+ sourceFiles
25790
+ ),
25791
+ matchLevel: safeMatchLevel(value.matchLevel),
25792
+ uiLibrary: safeShortText(value.uiLibrary),
25793
+ darkMode: safeShortText(value.darkMode),
25794
+ colors: safeStringRecord(value.colors, 8),
25795
+ fonts: safeFontRecord(value.fonts, 4),
25796
+ components: safeStringList(
25797
+ value.components,
25798
+ 8,
25799
+ (item) => /^[A-Z][A-Za-z0-9]{0,79}$/.test(item)
25800
+ ),
25801
+ cssVariables: safeStringRecord(value.cssVariables, 8),
25802
+ sourceFiles
25803
+ };
25804
+ }
25805
+ async function styleFreshness(rootDir, scopeRoot, lastScanned, sourceFiles) {
25806
+ if (lastScanned === null || sourceFiles.length === 0) return "unavailable";
25807
+ const scannedAt = Date.parse(lastScanned);
25808
+ for (const file of sourceFiles) {
25809
+ try {
25810
+ const info = await stat4(path45.resolve(rootDir, scopeRoot, file));
25811
+ if (info.mtimeMs > scannedAt) return "stale";
25812
+ } catch {
25813
+ return "stale";
25814
+ }
25815
+ }
25816
+ return "fresh";
25817
+ }
25818
+ function disabledPolicy() {
25819
+ return {
25820
+ ...DEFAULT_DESIGN_POLICY,
25821
+ emojiPolicy: "allow",
25822
+ motionPolicy: "minimal",
25823
+ browserValidation: "off"
25824
+ };
25825
+ }
25826
+ function designGuidance(policy) {
25827
+ return [
25828
+ directionSelectionGuidance(),
25829
+ presetGuidance(policy.preset),
25830
+ iconGuidance(policy.iconPolicy),
25831
+ emojiGuidance(policy.emojiPolicy),
25832
+ motionGuidance(policy.motionPolicy)
25833
+ ];
25834
+ }
25835
+ function directionSelectionGuidance() {
25836
+ return "Before implementing a new UI surface or an aesthetic redesign when the user has not chosen a visual direction, present 2-3 distinct, product-appropriate directions with concise tradeoffs and a recommendation, then wait for the user to choose. Continue directly for scoped UI fixes or work within an established or already selected direction.";
25837
+ }
25838
+ function presetGuidance(preset) {
25839
+ if (preset === "refine") {
25840
+ return "Preserve the product structure while improving hierarchy, typography, spacing, interaction states, and responsive behavior within the task scope.";
25841
+ }
25842
+ if (preset === "experimental") {
25843
+ return "After the user chooses a direction, execute one coherent, product-appropriate visual system. For brand, campaign, editorial, portfolio, or launch surfaces, make the first viewport the strongest brand signal and carry its visual motif through the full page; for task-oriented products, prioritize workflow clarity over spectacle. Advanced composition and purposeful motion are allowed only within the task scope and must not obscure core workflows.";
25844
+ }
25845
+ return "Retain the existing visual hierarchy, layout, component system, and interaction patterns; make only task-required UI changes.";
25846
+ }
25847
+ function iconGuidance(policy) {
25848
+ return policy === "lucide" ? "Use Lucide for interface icons when it is already available; adding or replacing a dependency requires explicit task approval." : "Reuse the project's existing icon system; do not introduce another icon library without explicit task approval.";
25849
+ }
25850
+ function emojiGuidance(policy) {
25851
+ return policy === "forbid-as-interface-icon" ? "Do not use emoji as interface icons." : "Follow the existing product conventions for emoji.";
25852
+ }
25853
+ function motionGuidance(policy) {
25854
+ return policy === "purposeful" ? "Use motion only to clarify hierarchy, state changes, or spatial relationships, and preserve reduced-motion accessibility." : "Keep motion minimal and preserve reduced-motion accessibility.";
25855
+ }
25856
+ function designQualityGates(policy) {
25857
+ const browserGate = policy.browserValidation === "required" ? "Validate changed UI in a browser at relevant desktop and mobile viewports before completion; report a blocker if browser validation is unavailable." : policy.browserValidation === "when-available" ? "When existing browser tooling is available, validate changed UI at relevant desktop and mobile viewports." : "Use the project checks already available; browser automation is not required by this policy.";
25858
+ return [
25859
+ "Preserve task-critical workflows, keyboard access, visible focus, readable contrast, and responsive behavior on changed surfaces.",
25860
+ "Check changed surfaces for clipping, unintended overlap, horizontal overflow, and unstable layout.",
25861
+ browserGate
25862
+ ];
25863
+ }
25864
+ function emptyStyleSummary() {
25865
+ return {
25866
+ scopeRoot: ".",
25867
+ lastScanned: null,
25868
+ freshness: "unavailable",
25869
+ matchLevel: "none",
25870
+ uiLibrary: null,
25871
+ darkMode: null,
25872
+ colors: {},
25873
+ fonts: {},
25874
+ components: [],
25875
+ cssVariables: {},
25876
+ sourceFiles: []
25877
+ };
25878
+ }
25879
+ async function initializedKind(rootDir) {
25880
+ if (await exists(path45.join(rootDir, ".mancode", "schema.json"))) {
25881
+ return "continuity";
25882
+ }
25883
+ if (await exists(path45.join(rootDir, ".mancode", "state.json")))
25884
+ return "legacy";
25885
+ return null;
25886
+ }
25887
+ async function policyMutationAvailability(rootDir, json) {
25888
+ const kind = await initializedKind(rootDir);
25889
+ if (kind === null) {
25890
+ return printError(
25891
+ json,
25892
+ "MANCODE_NOT_INITIALIZED",
25893
+ "Run `mancode init` first.",
25894
+ EXIT_NOT_INITIALIZED
25895
+ );
25896
+ }
25897
+ if (kind === "legacy") {
25898
+ return printError(
25899
+ json,
25900
+ "MANCODE_DESIGN_POLICY_REQUIRES_CONTINUITY",
25901
+ "Legacy projects can read the safe preserve context but cannot configure a shared design policy.",
25902
+ EXIT_DESIGN_FAILED
25903
+ );
25904
+ }
25905
+ return null;
25906
+ }
25907
+ function safeStringRecord(value, limit) {
25908
+ if (!isRecord6(value)) return {};
25909
+ return Object.fromEntries(
25910
+ Object.entries(value).filter(
25911
+ (entry) => /^[A-Za-z0-9_-]{1,80}$/.test(entry[0]) && typeof entry[1] === "string" && entry[1].length <= 120 && /^[#\w\s,.%()/+-]+$/.test(entry[1])
25912
+ ).slice(0, limit)
25913
+ );
25914
+ }
25915
+ function safeFontRecord(value, limit) {
25916
+ if (!isRecord6(value)) return {};
25917
+ return Object.fromEntries(
25918
+ Object.entries(value).filter(
25919
+ ([key, item]) => /^[A-Za-z0-9_-]{1,80}$/.test(key) && Array.isArray(item)
25920
+ ).map(([key, item]) => [
25921
+ key,
25922
+ item.filter(
25923
+ (font) => typeof font === "string" && font.length <= 80 && /^[\w\s,'"-]+$/.test(font)
25924
+ ).slice(0, 6)
25925
+ ]).filter(([, fonts]) => fonts.length > 0).slice(0, limit)
25926
+ );
25927
+ }
25928
+ function safeStringList(value, limit, predicate) {
25929
+ if (!Array.isArray(value)) return [];
25930
+ return value.filter(
25931
+ (item) => typeof item === "string" && predicate(item)
25932
+ ).slice(0, limit);
25933
+ }
25934
+ function safeScopeRoot(value) {
25935
+ if (value === void 0 || value === ".") return ".";
25936
+ return typeof value === "string" && isSafeRelativeFile(value) ? value : ".";
25937
+ }
25938
+ function safeTimestamp(value) {
25939
+ return typeof value === "string" && !Number.isNaN(Date.parse(value)) ? value : null;
25940
+ }
25941
+ function safeMatchLevel(value) {
25942
+ return value === "high" || value === "low" ? value : "none";
25943
+ }
25944
+ function safeShortText(value) {
25945
+ return typeof value === "string" && value.length <= 100 && /^[A-Za-z0-9@/_. -]+$/.test(value) ? value : null;
25946
+ }
25947
+ function isSafeRelativeFile(value) {
25948
+ return value.length <= 240 && !path45.isAbsolute(value) && !value.includes("\0") && value.split(/[\\/]/).every((part) => part !== "" && part !== "." && part !== "..");
25949
+ }
25950
+ function parseNonNegativeInteger2(value) {
25951
+ if (value === void 0 || !/^\d+$/.test(value)) return null;
25952
+ const parsed = Number(value);
25953
+ return Number.isSafeInteger(parsed) ? parsed : null;
25954
+ }
25955
+ function relativePath(rootDir, target) {
25956
+ return path45.relative(path45.resolve(rootDir), target).split(path45.sep).join("/");
25957
+ }
25958
+ function isRecord6(value) {
25959
+ return typeof value === "object" && value !== null && !Array.isArray(value);
25960
+ }
25961
+ async function exists(target) {
25962
+ try {
25963
+ await stat4(target);
25964
+ return true;
25965
+ } catch {
25966
+ return false;
25967
+ }
25968
+ }
25969
+ function printResult(json, payload, lines) {
25970
+ if (json) console.log(JSON.stringify(payload));
25971
+ else for (const line of lines) console.log(line);
25972
+ return EXIT_OK;
25973
+ }
25974
+ function printError(json, code, message, exitCode) {
25975
+ if (json) console.log(JSON.stringify({ error: { code, message } }));
25976
+ else console.error(`${code}: ${message}`);
25977
+ return exitCode;
25978
+ }
25979
+ function errorCode3(error, fallback) {
25980
+ if (!(error instanceof Error)) return fallback;
25981
+ const match = error.message.match(/\bMANCODE_[A-Z0-9_]+\b/);
25982
+ return match?.[0] ?? fallback;
25983
+ }
25984
+
25286
25985
  // src/commands/init.ts
25287
25986
  import { promises as fs4 } from "fs";
25288
25987
  import os from "os";
25289
- import path49 from "path";
25290
- import process5 from "process";
25988
+ import path51 from "path";
25989
+ import process6 from "process";
25291
25990
 
25292
25991
  // src/installers/platform-status.ts
25293
25992
  import { promises as fs } from "fs";
25294
- import path44 from "path";
25993
+ import path46 from "path";
25295
25994
  async function checkPlatformStatus(rootDir, platform, installed) {
25296
25995
  const readiness = await checkPlatformReadiness(rootDir, platform);
25297
25996
  return {
@@ -25308,13 +26007,13 @@ async function checkPlatformReadiness(rootDir, platform) {
25308
26007
  if (platform === "claude-code") {
25309
26008
  const [hasSoloSkill, registered, hasHookFiles] = await Promise.all([
25310
26009
  fileMatches(
25311
- path44.join(rootDir, ".claude", "skills", "solo", "SKILL.md"),
26010
+ path46.join(rootDir, ".claude", "skills", "solo", "SKILL.md"),
25312
26011
  (content) => isGeneratedClaudeSkill(content, "solo")
25313
26012
  ),
25314
26013
  claudeHooksRegistered(rootDir),
25315
26014
  pathsExist([
25316
- path44.join(rootDir, ".mancode", "hooks", "session-start.mjs"),
25317
- path44.join(rootDir, ".mancode", "hooks", "user-prompt-submit.mjs")
26015
+ path46.join(rootDir, ".mancode", "hooks", "session-start.mjs"),
26016
+ path46.join(rootDir, ".mancode", "hooks", "user-prompt-submit.mjs")
25318
26017
  ])
25319
26018
  ]);
25320
26019
  const present = hasSoloSkill && registered && hasHookFiles;
@@ -25330,7 +26029,7 @@ async function checkPlatformReadiness(rootDir, platform) {
25330
26029
  if (platform === "cursor") {
25331
26030
  const hasCoreRules = await allManagedSkills(
25332
26031
  MANCODE_CURSOR_CORE_RULE_FILES.map(
25333
- (file) => path44.join(rootDir, ".cursor", "rules", file)
26032
+ (file) => path46.join(rootDir, ".cursor", "rules", file)
25334
26033
  ),
25335
26034
  [CURSOR_RULE_MANAGED_MARKER]
25336
26035
  );
@@ -25345,13 +26044,13 @@ async function checkPlatformReadiness(rootDir, platform) {
25345
26044
  const [hasRules, hasCommands] = await Promise.all([
25346
26045
  allManagedSkills(
25347
26046
  MANCODE_CURSOR_RULE_FILES.map(
25348
- (file) => path44.join(rootDir, ".cursor", "rules", file)
26047
+ (file) => path46.join(rootDir, ".cursor", "rules", file)
25349
26048
  ),
25350
26049
  [CURSOR_RULE_MANAGED_MARKER]
25351
26050
  ),
25352
26051
  allManagedSkills(
25353
26052
  MODE_NAMES.map(
25354
- (mode) => path44.join(rootDir, ".cursor", "commands", `${mode}.md`)
26053
+ (mode) => path46.join(rootDir, ".cursor", "commands", `${mode}.md`)
25355
26054
  ),
25356
26055
  [MODE_FILE_MANAGED_MARKER]
25357
26056
  )
@@ -25364,7 +26063,7 @@ async function checkPlatformReadiness(rootDir, platform) {
25364
26063
  };
25365
26064
  }
25366
26065
  if (platform === "codex") {
25367
- const hasBlock2 = await fileHasManagedBlock(path44.join(rootDir, "AGENTS.md"));
26066
+ const hasBlock2 = await fileHasManagedBlock(path46.join(rootDir, "AGENTS.md"));
25368
26067
  if (!hasBlock2) {
25369
26068
  return {
25370
26069
  present: false,
@@ -25381,9 +26080,9 @@ async function checkPlatformReadiness(rootDir, platform) {
25381
26080
  readyDetail: "managed block present"
25382
26081
  };
25383
26082
  }
25384
- const skillsDir = path44.join(rootDir, ".agents", "skills");
26083
+ const skillsDir = path46.join(rootDir, ".agents", "skills");
25385
26084
  const hasSkills = await allManagedSkills(
25386
- MODE_NAMES.map((mode) => path44.join(skillsDir, mode, "SKILL.md")),
26085
+ MODE_NAMES.map((mode) => path46.join(skillsDir, mode, "SKILL.md")),
25387
26086
  MANCODE_AGENT_SKILL_MARKERS
25388
26087
  );
25389
26088
  return {
@@ -25395,7 +26094,7 @@ async function checkPlatformReadiness(rootDir, platform) {
25395
26094
  }
25396
26095
  if (platform === "zcode") {
25397
26096
  const hasBlock2 = await fileHasManagedBlock(
25398
- path44.join(rootDir, "AGENTS.md"),
26097
+ path46.join(rootDir, "AGENTS.md"),
25399
26098
  ZCODE_MANCODE_START_MARKER,
25400
26099
  ZCODE_MANCODE_END_MARKER
25401
26100
  );
@@ -25415,9 +26114,9 @@ async function checkPlatformReadiness(rootDir, platform) {
25415
26114
  readyDetail: "managed block present"
25416
26115
  };
25417
26116
  }
25418
- const skillsDir = path44.join(rootDir, ".agents", "skills");
26117
+ const skillsDir = path46.join(rootDir, ".agents", "skills");
25419
26118
  const hasSkills = await allManagedSkills(
25420
- MODE_NAMES.map((mode) => path44.join(skillsDir, mode, "SKILL.md")),
26119
+ MODE_NAMES.map((mode) => path46.join(skillsDir, mode, "SKILL.md")),
25421
26120
  MANCODE_AGENT_SKILL_MARKERS
25422
26121
  );
25423
26122
  return {
@@ -25428,7 +26127,7 @@ async function checkPlatformReadiness(rootDir, platform) {
25428
26127
  };
25429
26128
  }
25430
26129
  const hasBlock = await fileHasManagedBlock(
25431
- path44.join(rootDir, ".github", "copilot-instructions.md")
26130
+ path46.join(rootDir, ".github", "copilot-instructions.md")
25432
26131
  );
25433
26132
  if (!hasBlock) {
25434
26133
  return {
@@ -25439,9 +26138,9 @@ async function checkPlatformReadiness(rootDir, platform) {
25439
26138
  };
25440
26139
  }
25441
26140
  if (!await isPlatformMinimal(rootDir, "copilot")) {
25442
- const promptsDir = path44.join(rootDir, ".github", "prompts");
26141
+ const promptsDir = path46.join(rootDir, ".github", "prompts");
25443
26142
  const hasPrompts = await allManagedSkills(
25444
- MODE_NAMES.map((mode) => path44.join(promptsDir, `${mode}.prompt.md`)),
26143
+ MODE_NAMES.map((mode) => path46.join(promptsDir, `${mode}.prompt.md`)),
25445
26144
  [MODE_FILE_MANAGED_MARKER]
25446
26145
  );
25447
26146
  return {
@@ -25474,13 +26173,13 @@ async function allManagedSkills(paths, markers) {
25474
26173
  async function claudeFullContentReady(rootDir) {
25475
26174
  const skillChecks = MVP2_SKILLS.map(
25476
26175
  (skill) => fileMatches(
25477
- path44.join(rootDir, ".claude", "skills", skill.name, "SKILL.md"),
26176
+ path46.join(rootDir, ".claude", "skills", skill.name, "SKILL.md"),
25478
26177
  (content) => isGeneratedClaudeSkill(content, skill.name)
25479
26178
  )
25480
26179
  );
25481
26180
  const agentChecks = ALL_AGENTS.map(
25482
26181
  (agent) => fileMatches(
25483
- path44.join(rootDir, ".claude", "agents", `${agent.name}.md`),
26182
+ path46.join(rootDir, ".claude", "agents", `${agent.name}.md`),
25484
26183
  (content) => isGeneratedClaudeAgent(content, agent.name)
25485
26184
  )
25486
26185
  );
@@ -25508,13 +26207,13 @@ async function fileHasAnyMarker(filePath, needles) {
25508
26207
  async function isPlatformMinimal(rootDir, platform) {
25509
26208
  try {
25510
26209
  const raw = await fs.readFile(
25511
- path44.join(rootDir, ".mancode", "config.json"),
26210
+ path46.join(rootDir, ".mancode", "config.json"),
25512
26211
  "utf-8"
25513
26212
  );
25514
26213
  const config = JSON.parse(raw);
25515
- if (!isRecord6(config.platformOptions)) return false;
26214
+ if (!isRecord7(config.platformOptions)) return false;
25516
26215
  const options = config.platformOptions[platform];
25517
- return isRecord6(options) && options.minimal === true;
26216
+ return isRecord7(options) && options.minimal === true;
25518
26217
  } catch {
25519
26218
  return false;
25520
26219
  }
@@ -25530,7 +26229,7 @@ async function fileHasManagedBlock(filePath, startMarker = DEFAULT_MANCODE_START
25530
26229
  async function claudeHooksRegistered(rootDir) {
25531
26230
  try {
25532
26231
  const raw = await fs.readFile(
25533
- path44.join(rootDir, ".claude", "settings.json"),
26232
+ path46.join(rootDir, ".claude", "settings.json"),
25534
26233
  "utf-8"
25535
26234
  );
25536
26235
  const settings = JSON.parse(raw);
@@ -25540,9 +26239,9 @@ async function claudeHooksRegistered(rootDir) {
25540
26239
  }
25541
26240
  }
25542
26241
  function hooksRegistered(settings) {
25543
- if (!isRecord6(settings)) return false;
26242
+ if (!isRecord7(settings)) return false;
25544
26243
  const hooks = settings.hooks;
25545
- if (!isRecord6(hooks)) return false;
26244
+ if (!isRecord7(hooks)) return false;
25546
26245
  return hasHookCommand(hooks.SessionStart, ".mancode/hooks/session-start.mjs") && hasHookCommand(
25547
26246
  hooks.UserPromptSubmit,
25548
26247
  ".mancode/hooks/user-prompt-submit.mjs"
@@ -25551,9 +26250,9 @@ function hooksRegistered(settings) {
25551
26250
  function hasHookCommand(value, needle) {
25552
26251
  if (!Array.isArray(value)) return false;
25553
26252
  return value.some((group) => {
25554
- if (!isRecord6(group) || !Array.isArray(group.hooks)) return false;
26253
+ if (!isRecord7(group) || !Array.isArray(group.hooks)) return false;
25555
26254
  return group.hooks.some((hook) => {
25556
- if (!isRecord6(hook) || typeof hook.command !== "string") return false;
26255
+ if (!isRecord7(hook) || typeof hook.command !== "string") return false;
25557
26256
  return hook.command.includes(needle);
25558
26257
  });
25559
26258
  });
@@ -25566,15 +26265,15 @@ async function pathExists4(p) {
25566
26265
  return false;
25567
26266
  }
25568
26267
  }
25569
- function isRecord6(value) {
26268
+ function isRecord7(value) {
25570
26269
  return typeof value === "object" && value !== null;
25571
26270
  }
25572
26271
 
25573
26272
  // src/system/detect-team.ts
25574
26273
  import { execFile as execFile6 } from "child_process";
25575
26274
  import { access as access2 } from "fs/promises";
25576
- import path45 from "path";
25577
- import process2 from "process";
26275
+ import path47 from "path";
26276
+ import process3 from "process";
25578
26277
  import { promisify as promisify6 } from "util";
25579
26278
  var execFileAsync = promisify6(execFile6);
25580
26279
  var NO_TEAM = {
@@ -25584,7 +26283,7 @@ var NO_TEAM = {
25584
26283
  hasRemote: false
25585
26284
  };
25586
26285
  var GIT_ENV = {
25587
- ...process2.env,
26286
+ ...process3.env,
25588
26287
  GIT_PAGER: "cat",
25589
26288
  PAGER: "cat",
25590
26289
  GIT_TERMINAL_PROMPT: "0"
@@ -25683,7 +26382,7 @@ async function anyPathExists(projectRoot, candidates) {
25683
26382
  const results = await Promise.all(
25684
26383
  candidates.map(async (candidate) => {
25685
26384
  try {
25686
- await access2(path45.join(projectRoot, candidate));
26385
+ await access2(path47.join(projectRoot, candidate));
25687
26386
  return true;
25688
26387
  } catch {
25689
26388
  return false;
@@ -25706,10 +26405,10 @@ function emptySignals(isGitRepository) {
25706
26405
 
25707
26406
  // src/system/detect.ts
25708
26407
  import { execFile as execFile7 } from "child_process";
25709
- import process3 from "process";
26408
+ import process4 from "process";
25710
26409
  import { promisify as promisify7 } from "util";
25711
26410
  var execFileAsync2 = promisify7(execFile7);
25712
- async function detectSystemDeps(env = process3.env) {
26411
+ async function detectSystemDeps(env = process4.env) {
25713
26412
  try {
25714
26413
  await execFileAsync2("git", ["--version"], {
25715
26414
  env,
@@ -25724,18 +26423,18 @@ async function detectSystemDeps(env = process3.env) {
25724
26423
  // src/system/init-onboarding.ts
25725
26424
  import { execFileSync } from "child_process";
25726
26425
  import { promises as fs2 } from "fs";
25727
- import path46 from "path";
25728
- import process4 from "process";
26426
+ import path48 from "path";
26427
+ import process5 from "process";
25729
26428
  import { stdin, stdout } from "process";
25730
26429
  import { createInterface } from "readline/promises";
25731
26430
  var ALL_PLATFORMS = Object.keys(PLATFORM_INSTALLERS);
25732
26431
  var cachedNativeSystemLocale;
25733
- function detectInitLocale(override, environment = process4.env, systemLocale = Intl.DateTimeFormat().resolvedOptions().locale, nativeLocale) {
26432
+ function detectInitLocale(override, environment = process5.env, systemLocale = Intl.DateTimeFormat().resolvedOptions().locale, nativeLocale) {
25734
26433
  if (override) return parseLocale(override);
25735
26434
  const resolvedNativeLocale = nativeLocale === void 0 ? getNativeSystemLocale() : nativeLocale;
25736
26435
  return parseLocale(resolvedNativeLocale) ?? detectEnvironmentLocale(environment) ?? parseLocale(systemLocale) ?? "en";
25737
26436
  }
25738
- function detectNativeSystemLocale(platform = process4.platform, runCommand = runLocaleCommand) {
26437
+ function detectNativeSystemLocale(platform = process5.platform, runCommand = runLocaleCommand) {
25739
26438
  if (platform === "darwin") {
25740
26439
  const languages = runCommand("defaults", ["read", "-g", "AppleLanguages"]);
25741
26440
  const primaryLanguage = parsePrimaryAppleLanguage(languages);
@@ -25819,7 +26518,7 @@ function parsePlatformSelection(value) {
25819
26518
  }
25820
26519
  return [...new Set(choices)];
25821
26520
  }
25822
- async function detectPlatformHints(rootDir, environment = process4.env) {
26521
+ async function detectPlatformHints(rootDir, environment = process5.env) {
25823
26522
  const hints = /* @__PURE__ */ new Set();
25824
26523
  if (environment.CLAUDECODE || environment.CLAUDE_CODE)
25825
26524
  hints.add("claude-code");
@@ -25827,17 +26526,17 @@ async function detectPlatformHints(rootDir, environment = process4.env) {
25827
26526
  if (environment.CURSOR_TRACE_ID) hints.add("cursor");
25828
26527
  if (environment.COPILOT_AGENT || environment.GITHUB_COPILOT)
25829
26528
  hints.add("copilot");
25830
- const exists = async (relative) => {
26529
+ const exists2 = async (relative) => {
25831
26530
  try {
25832
- await fs2.access(path46.join(rootDir, relative));
26531
+ await fs2.access(path48.join(rootDir, relative));
25833
26532
  return true;
25834
26533
  } catch {
25835
26534
  return false;
25836
26535
  }
25837
26536
  };
25838
- if (await exists(".claude")) hints.add("claude-code");
25839
- if (await exists(".cursor")) hints.add("cursor");
25840
- if (await exists(".github/copilot-instructions.md")) hints.add("copilot");
26537
+ if (await exists2(".claude")) hints.add("claude-code");
26538
+ if (await exists2(".cursor")) hints.add("cursor");
26539
+ if (await exists2(".github/copilot-instructions.md")) hints.add("copilot");
25841
26540
  return ALL_PLATFORMS.filter((platform) => hints.has(platform));
25842
26541
  }
25843
26542
  function createTerminalPrompter() {
@@ -25905,10 +26604,10 @@ function createTerminalPrompter() {
25905
26604
 
25906
26605
  // src/system/scan-aesthetics.ts
25907
26606
  import { promises as fs3 } from "fs";
25908
- import path47 from "path";
26607
+ import path49 from "path";
25909
26608
  var MAX_COMPONENT_SCAN_DEPTH = 12;
25910
26609
  var MAX_COMPONENT_FILES = 2e3;
25911
- async function scanAesthetics(projectRoot, uiLibrary = null) {
26610
+ async function scanAesthetics(projectRoot, uiLibrary = null, scopeRoot = ".") {
25912
26611
  const sourceFiles = [];
25913
26612
  const configResult = await findTailwindConfig(projectRoot);
25914
26613
  let colors = {};
@@ -25941,12 +26640,13 @@ async function scanAesthetics(projectRoot, uiLibrary = null) {
25941
26640
  } else if (await hasTailwindDep(projectRoot) || uiLibrary) {
25942
26641
  matchLevel = "low";
25943
26642
  }
25944
- if (uiLibrary && await pathExists5(path47.join(projectRoot, "package.json"))) {
26643
+ if (uiLibrary && await pathExists5(path49.join(projectRoot, "package.json"))) {
25945
26644
  sourceFiles.push("package.json");
25946
26645
  }
25947
26646
  sourceFiles.push(...cssScan.sourceFiles);
25948
26647
  return {
25949
26648
  version: "1.0.0",
26649
+ scopeRoot,
25950
26650
  lastScanned: (/* @__PURE__ */ new Date()).toISOString(),
25951
26651
  colors,
25952
26652
  fonts,
@@ -25966,7 +26666,7 @@ async function findTailwindConfig(projectRoot) {
25966
26666
  "tailwind.config.mjs"
25967
26667
  ];
25968
26668
  for (const name of candidates) {
25969
- const absPath = path47.join(projectRoot, name);
26669
+ const absPath = path49.join(projectRoot, name);
25970
26670
  if (await pathExists5(absPath)) {
25971
26671
  return { absPath, relPath: name };
25972
26672
  }
@@ -26193,7 +26893,7 @@ async function scanComponents(projectRoot) {
26193
26893
  const names = /* @__PURE__ */ new Set();
26194
26894
  let visitedFiles = 0;
26195
26895
  for (const relRoot of roots) {
26196
- const absRoot = path47.join(projectRoot, relRoot);
26896
+ const absRoot = path49.join(projectRoot, relRoot);
26197
26897
  if (!await pathExists5(absRoot)) continue;
26198
26898
  visitedFiles = await collectComponentNames(absRoot, names, 0, visitedFiles);
26199
26899
  if (visitedFiles >= MAX_COMPONENT_FILES) break;
@@ -26213,7 +26913,7 @@ async function collectComponentNames(dir, names, depth, visitedFiles) {
26213
26913
  }
26214
26914
  for (const entry of entries) {
26215
26915
  if (fileCount >= MAX_COMPONENT_FILES) return fileCount;
26216
- const abs = path47.join(dir, entry);
26916
+ const abs = path49.join(dir, entry);
26217
26917
  let info;
26218
26918
  try {
26219
26919
  info = await fs3.lstat(abs);
@@ -26234,7 +26934,7 @@ async function collectComponentNames(dir, names, depth, visitedFiles) {
26234
26934
  ""
26235
26935
  );
26236
26936
  if (base === "index") {
26237
- base = path47.basename(dir);
26937
+ base = path49.basename(dir);
26238
26938
  }
26239
26939
  if (base.startsWith(".")) continue;
26240
26940
  const componentName = toPascalCase(base);
@@ -26256,7 +26956,7 @@ async function scanCssVariables(projectRoot) {
26256
26956
  const variables = {};
26257
26957
  const sourceFiles = [];
26258
26958
  for (const relPath of candidates) {
26259
- const absPath = path47.join(projectRoot, relPath);
26959
+ const absPath = path49.join(projectRoot, relPath);
26260
26960
  if (!await pathExists5(absPath)) continue;
26261
26961
  const content = await fs3.readFile(absPath, "utf-8");
26262
26962
  const found = extractCssVariables(content);
@@ -26302,7 +27002,7 @@ function toPascalCase(value) {
26302
27002
  async function hasTailwindDep(projectRoot) {
26303
27003
  try {
26304
27004
  const raw = await fs3.readFile(
26305
- path47.join(projectRoot, "package.json"),
27005
+ path49.join(projectRoot, "package.json"),
26306
27006
  "utf-8"
26307
27007
  );
26308
27008
  const pkg = JSON.parse(raw);
@@ -26327,15 +27027,15 @@ async function pathExists5(p) {
26327
27027
 
26328
27028
  // src/context/greenfield-init.ts
26329
27029
  import {
26330
- lstat as lstat19,
26331
- mkdir as mkdir33,
26332
- readFile as readFile36,
27030
+ lstat as lstat20,
27031
+ mkdir as mkdir34,
27032
+ readFile as readFile38,
26333
27033
  rename as rename10,
26334
- rm as rm17,
26335
- writeFile as writeFile38
27034
+ rm as rm18,
27035
+ writeFile as writeFile39
26336
27036
  } from "fs/promises";
26337
- import path48 from "path";
26338
- var JOURNAL_RELATIVE_DIRECTORY = path48.join(
27037
+ import path50 from "path";
27038
+ var JOURNAL_RELATIVE_DIRECTORY = path50.join(
26339
27039
  "local",
26340
27040
  "runtime",
26341
27041
  "initialization"
@@ -26358,7 +27058,7 @@ async function stageGreenfieldInitialization(input) {
26358
27058
  normalized.operationId
26359
27059
  );
26360
27060
  try {
26361
- await mkdir33(stagingRoot);
27061
+ await mkdir34(stagingRoot);
26362
27062
  } catch (error) {
26363
27063
  if (isAlreadyExists22(error)) {
26364
27064
  throw new Error("MANCODE_GREENFIELD_STAGING_EXISTS");
@@ -26384,7 +27084,7 @@ async function stageGreenfieldInitialization(input) {
26384
27084
  operationId: normalized.operationId,
26385
27085
  workspaceId: normalized.workspaceId,
26386
27086
  state: "staged",
26387
- stagingDirectoryName: path48.basename(stagingRoot),
27087
+ stagingDirectoryName: path50.basename(stagingRoot),
26388
27088
  targetDirectoryName: ".mancode",
26389
27089
  manifestDigest: digestCanonicalJson(manifest),
26390
27090
  configDigest: digestCanonicalJson(config),
@@ -26415,7 +27115,7 @@ async function stageGreenfieldInitialization(input) {
26415
27115
  return journal;
26416
27116
  }
26417
27117
  async function publishGreenfieldInitialization(input) {
26418
- const root = path48.resolve(input.projectRoot);
27118
+ const root = path50.resolve(input.projectRoot);
26419
27119
  assertUlid(input.operationId, "greenfield operationId");
26420
27120
  const stagingRoot = greenfieldStagingPath(root, input.operationId);
26421
27121
  const targetRoot = greenfieldTargetPath(root);
@@ -26450,10 +27150,10 @@ async function initializeGreenfield(input, publication) {
26450
27150
  }
26451
27151
  function greenfieldStagingPath(projectRoot, operationId) {
26452
27152
  assertUlid(operationId, "greenfield operationId");
26453
- return path48.join(path48.resolve(projectRoot), `.mancode.init-${operationId}`);
27153
+ return path50.join(path50.resolve(projectRoot), `.mancode.init-${operationId}`);
26454
27154
  }
26455
27155
  function greenfieldTargetPath(projectRoot) {
26456
- return path48.join(path48.resolve(projectRoot), ".mancode");
27156
+ return path50.join(path50.resolve(projectRoot), ".mancode");
26457
27157
  }
26458
27158
  function parseGreenfieldInitializationJournal(value) {
26459
27159
  assertRecord(value, "greenfield initialization journal");
@@ -26589,7 +27289,7 @@ async function finishPublishedInitialization(input, stagedJournal) {
26589
27289
  activatedAt: (input.now ?? /* @__PURE__ */ new Date()).toISOString()
26590
27290
  };
26591
27291
  assertSchemaManifestTransition(manifest, activeManifest);
26592
- await writeJson(path48.join(targetRoot, "schema.json"), activeManifest);
27292
+ await writeJson(path50.join(targetRoot, "schema.json"), activeManifest);
26593
27293
  throwIfOperationCrashInjected(
26594
27294
  "greenfield_initialize",
26595
27295
  "activate-v3-manifest"
@@ -26605,46 +27305,46 @@ async function finishPublishedInitialization(input, stagedJournal) {
26605
27305
  }
26606
27306
  async function writeGreenfieldLayout(stagingRoot, manifest, config, policy, projectFacts, journal) {
26607
27307
  await Promise.all([
26608
- mkdir33(path48.join(stagingRoot, "shared", "context"), { recursive: true }),
26609
- mkdir33(path48.join(stagingRoot, "shared", "memory", "decisions"), {
27308
+ mkdir34(path50.join(stagingRoot, "shared", "context"), { recursive: true }),
27309
+ mkdir34(path50.join(stagingRoot, "shared", "memory", "decisions"), {
26610
27310
  recursive: true
26611
27311
  }),
26612
- mkdir33(path48.join(stagingRoot, "shared", "team", "actors"), {
27312
+ mkdir34(path50.join(stagingRoot, "shared", "team", "actors"), {
26613
27313
  recursive: true
26614
27314
  }),
26615
- mkdir33(path48.join(stagingRoot, "shared", "team", "handoffs"), {
27315
+ mkdir34(path50.join(stagingRoot, "shared", "team", "handoffs"), {
26616
27316
  recursive: true
26617
27317
  }),
26618
- mkdir33(path48.join(stagingRoot, "shared", "team", "events"), {
27318
+ mkdir34(path50.join(stagingRoot, "shared", "team", "events"), {
26619
27319
  recursive: true
26620
27320
  }),
26621
- mkdir33(path48.join(stagingRoot, "shared", "team", "transport"), {
27321
+ mkdir34(path50.join(stagingRoot, "shared", "team", "transport"), {
26622
27322
  recursive: true
26623
27323
  }),
26624
- mkdir33(path48.join(stagingRoot, "local", "sessions"), { recursive: true }),
26625
- mkdir33(path48.join(stagingRoot, JOURNAL_RELATIVE_DIRECTORY), {
27324
+ mkdir34(path50.join(stagingRoot, "local", "sessions"), { recursive: true }),
27325
+ mkdir34(path50.join(stagingRoot, JOURNAL_RELATIVE_DIRECTORY), {
26626
27326
  recursive: true
26627
27327
  }),
26628
- mkdir33(path48.join(stagingRoot, "local", "workflows"), { recursive: true }),
26629
- mkdir33(path48.join(stagingRoot, "local", "overlays"), { recursive: true }),
26630
- mkdir33(path48.join(stagingRoot, "local", "quarantine"), { recursive: true }),
26631
- mkdir33(path48.join(stagingRoot, "local", "publish"), { recursive: true }),
26632
- mkdir33(path48.join(stagingRoot, "local", "cache"), { recursive: true }),
26633
- mkdir33(path48.join(stagingRoot, "runtime", "non-git", journal.workspaceId), {
27328
+ mkdir34(path50.join(stagingRoot, "local", "workflows"), { recursive: true }),
27329
+ mkdir34(path50.join(stagingRoot, "local", "overlays"), { recursive: true }),
27330
+ mkdir34(path50.join(stagingRoot, "local", "quarantine"), { recursive: true }),
27331
+ mkdir34(path50.join(stagingRoot, "local", "publish"), { recursive: true }),
27332
+ mkdir34(path50.join(stagingRoot, "local", "cache"), { recursive: true }),
27333
+ mkdir34(path50.join(stagingRoot, "runtime", "non-git", journal.workspaceId), {
26634
27334
  recursive: true
26635
27335
  })
26636
27336
  ]);
26637
27337
  await Promise.all([
26638
- writeJson(path48.join(stagingRoot, "schema.json"), manifest),
26639
- writeJson(path48.join(stagingRoot, "shared", "config.json"), config),
26640
- writeJson(path48.join(stagingRoot, "shared", "team", "policy.json"), policy),
27338
+ writeJson(path50.join(stagingRoot, "schema.json"), manifest),
27339
+ writeJson(path50.join(stagingRoot, "shared", "config.json"), config),
27340
+ writeJson(path50.join(stagingRoot, "shared", "team", "policy.json"), policy),
26641
27341
  writeJson(
26642
- path48.join(stagingRoot, "shared", "context", "project.json"),
27342
+ path50.join(stagingRoot, "shared", "context", "project.json"),
26643
27343
  projectFacts
26644
27344
  ),
26645
27345
  writeJson(journalPath2(stagingRoot, journal.operationId), journal),
26646
- writeFile38(
26647
- path48.join(stagingRoot, ".gitignore"),
27346
+ writeFile39(
27347
+ path50.join(stagingRoot, ".gitignore"),
26648
27348
  `${V3_IGNORE.join("\n")}
26649
27349
  `,
26650
27350
  { encoding: "utf8", flag: "wx" }
@@ -26653,14 +27353,14 @@ async function writeGreenfieldLayout(stagingRoot, manifest, config, policy, proj
26653
27353
  }
26654
27354
  async function readGreenfieldJournal(root, operationId) {
26655
27355
  try {
26656
- const raw = await readFile36(journalPath2(root, operationId), "utf8");
27356
+ const raw = await readFile38(journalPath2(root, operationId), "utf8");
26657
27357
  const journal = parseGreenfieldInitializationJournal(JSON.parse(raw));
26658
27358
  if (journal.operationId !== operationId) {
26659
27359
  throw new Error("MANCODE_GREENFIELD_JOURNAL_CORRUPT");
26660
27360
  }
26661
27361
  return journal;
26662
27362
  } catch (error) {
26663
- if (error instanceof SyntaxError || isNotFound27(error)) {
27363
+ if (error instanceof SyntaxError || isNotFound28(error)) {
26664
27364
  throw new Error("MANCODE_GREENFIELD_JOURNAL_CORRUPT");
26665
27365
  }
26666
27366
  throw error;
@@ -26669,10 +27369,10 @@ async function readGreenfieldJournal(root, operationId) {
26669
27369
  async function readManifest(root) {
26670
27370
  try {
26671
27371
  return parseSchemaManifest(
26672
- JSON.parse(await readFile36(path48.join(root, "schema.json"), "utf8"))
27372
+ JSON.parse(await readFile38(path50.join(root, "schema.json"), "utf8"))
26673
27373
  );
26674
27374
  } catch (error) {
26675
- if (error instanceof SyntaxError || isNotFound27(error)) {
27375
+ if (error instanceof SyntaxError || isNotFound28(error)) {
26676
27376
  throw new Error("MANCODE_GREENFIELD_REPAIR_REQUIRED");
26677
27377
  }
26678
27378
  throw error;
@@ -26707,7 +27407,7 @@ async function readConfig(root) {
26707
27407
  try {
26708
27408
  config = parseProjectConfig(
26709
27409
  JSON.parse(
26710
- await readFile36(path48.join(root, "shared", "config.json"), "utf8")
27410
+ await readFile38(path50.join(root, "shared", "config.json"), "utf8")
26711
27411
  )
26712
27412
  );
26713
27413
  } catch (error) {
@@ -26723,8 +27423,8 @@ async function readPolicy(root) {
26723
27423
  try {
26724
27424
  policy = parseTeamPolicy(
26725
27425
  JSON.parse(
26726
- await readFile36(
26727
- path48.join(root, "shared", "team", "policy.json"),
27426
+ await readFile38(
27427
+ path50.join(root, "shared", "team", "policy.json"),
26728
27428
  "utf8"
26729
27429
  )
26730
27430
  )
@@ -26741,14 +27441,14 @@ async function readProjectFactsAt(root) {
26741
27441
  try {
26742
27442
  return parseProjectFacts(
26743
27443
  JSON.parse(
26744
- await readFile36(
26745
- path48.join(root, "shared", "context", "project.json"),
27444
+ await readFile38(
27445
+ path50.join(root, "shared", "context", "project.json"),
26746
27446
  "utf8"
26747
27447
  )
26748
27448
  )
26749
27449
  );
26750
27450
  } catch (error) {
26751
- if (error instanceof SyntaxError || isNotFound27(error)) {
27451
+ if (error instanceof SyntaxError || isNotFound28(error)) {
26752
27452
  throw new Error("MANCODE_GREENFIELD_REPAIR_REQUIRED");
26753
27453
  }
26754
27454
  throw error;
@@ -26781,7 +27481,7 @@ function normalizeInput(input) {
26781
27481
  parseSchemaManifest(manifest);
26782
27482
  return {
26783
27483
  ...input,
26784
- projectRoot: path48.resolve(input.projectRoot),
27484
+ projectRoot: path50.resolve(input.projectRoot),
26785
27485
  projectConfig: config,
26786
27486
  teamPolicy: policy,
26787
27487
  projectFacts: input.projectFacts === void 0 ? void 0 : parseProjectFacts(input.projectFacts)
@@ -26879,16 +27579,16 @@ function initializationProjectFacts(input, now) {
26879
27579
  }
26880
27580
  function journalPath2(root, operationId) {
26881
27581
  assertUlid(operationId, "greenfield operationId");
26882
- return path48.join(root, JOURNAL_RELATIVE_DIRECTORY, `${operationId}.json`);
27582
+ return path50.join(root, JOURNAL_RELATIVE_DIRECTORY, `${operationId}.json`);
26883
27583
  }
26884
27584
  async function writeJson(target, value) {
26885
- const directory = path48.dirname(target);
26886
- await mkdir33(directory, { recursive: true });
26887
- const temporary = path48.join(
27585
+ const directory = path50.dirname(target);
27586
+ await mkdir34(directory, { recursive: true });
27587
+ const temporary = path50.join(
26888
27588
  directory,
26889
- `.${path48.basename(target)}.${process.pid}.${Date.now()}.tmp`
27589
+ `.${path50.basename(target)}.${process.pid}.${Date.now()}.tmp`
26890
27590
  );
26891
- await writeFile38(temporary, `${JSON.stringify(value, null, 2)}
27591
+ await writeFile39(temporary, `${JSON.stringify(value, null, 2)}
26892
27592
  `, {
26893
27593
  encoding: "utf8",
26894
27594
  flag: "wx"
@@ -26912,13 +27612,13 @@ function isState(value) {
26912
27612
  }
26913
27613
  async function lstatOrNull4(target) {
26914
27614
  try {
26915
- return await lstat19(target);
27615
+ return await lstat20(target);
26916
27616
  } catch (error) {
26917
- if (isNotFound27(error)) return null;
27617
+ if (isNotFound28(error)) return null;
26918
27618
  throw error;
26919
27619
  }
26920
27620
  }
26921
- function isNotFound27(error) {
27621
+ function isNotFound28(error) {
26922
27622
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
26923
27623
  }
26924
27624
  function isAlreadyExists22(error) {
@@ -26989,7 +27689,7 @@ async function initializeV3Project(input) {
26989
27689
  }
26990
27690
 
26991
27691
  // src/commands/init.ts
26992
- var EXIT_OK = 0;
27692
+ var EXIT_OK2 = 0;
26993
27693
  var EXIT_ALREADY_INITIALIZED = 1;
26994
27694
  var EXIT_NOT_A_PROJECT_DIR = 2;
26995
27695
  var EXIT_USER_CANCEL = 3;
@@ -27000,15 +27700,15 @@ function resolveInitAuthority(options) {
27000
27700
  if (options.v3 || options.fromCli) return "v3";
27001
27701
  return "legacy";
27002
27702
  }
27003
- async function init(rootDir = process5.cwd(), options = {}) {
27703
+ async function init(rootDir = process6.cwd(), options = {}) {
27004
27704
  if (options.v3 && options.legacy) {
27005
27705
  console.error("\u2717 --v3 and --legacy cannot be used together.");
27006
27706
  return EXIT_INIT_FAILED;
27007
27707
  }
27008
27708
  const authority = resolveInitAuthority(options);
27009
- const mancodeDir = path49.join(rootDir, ".mancode");
27010
- const stateFile = path49.join(mancodeDir, "state.json");
27011
- const v3SchemaFile = path49.join(mancodeDir, "schema.json");
27709
+ const mancodeDir = path51.join(rootDir, ".mancode");
27710
+ const stateFile = path51.join(mancodeDir, "state.json");
27711
+ const v3SchemaFile = path51.join(mancodeDir, "schema.json");
27012
27712
  const wasInitialized = await pathExists6(stateFile);
27013
27713
  let mutationSnapshots = [];
27014
27714
  let directorySnapshots = [];
@@ -27076,7 +27776,7 @@ async function init(rootDir = process5.cwd(), options = {}) {
27076
27776
  }
27077
27777
  return initializeV3(rootDir, options);
27078
27778
  }
27079
- const isGitRepo = await pathExists6(path49.join(rootDir, ".git"));
27779
+ const isGitRepo = await pathExists6(path51.join(rootDir, ".git"));
27080
27780
  const hasManifest = await hasProjectManifest(rootDir);
27081
27781
  let isGenericProject = false;
27082
27782
  if (!isGitRepo && !hasManifest) {
@@ -27194,8 +27894,8 @@ async function init(rootDir = process5.cwd(), options = {}) {
27194
27894
  const managedFiles = getInitManagedFilePaths(rootDir, selectedPlatforms);
27195
27895
  mutationSnapshots = await snapshotFiles(managedFiles);
27196
27896
  directorySnapshots = await snapshotDirectories(managedFiles, [
27197
- path49.join(mancodeDir, "workflows"),
27198
- path49.join(mancodeDir, "preseason-reports")
27897
+ path51.join(mancodeDir, "workflows"),
27898
+ path51.join(mancodeDir, "preseason-reports")
27199
27899
  ]);
27200
27900
  const team = await detectTeamStatus(rootDir);
27201
27901
  const platformMinimal = Object.fromEntries(
@@ -27256,7 +27956,7 @@ async function init(rootDir = process5.cwd(), options = {}) {
27256
27956
  `;
27257
27957
  await fs4.writeFile(stateFile, stateContent, "utf-8");
27258
27958
  await fs4.writeFile(
27259
- path49.join(mancodeDir, "project-profile.json"),
27959
+ path51.join(mancodeDir, "project-profile.json"),
27260
27960
  `${JSON.stringify(profile, null, 2)}
27261
27961
  `,
27262
27962
  "utf-8"
@@ -27293,7 +27993,7 @@ async function init(rootDir = process5.cwd(), options = {}) {
27293
27993
  )
27294
27994
  );
27295
27995
  const tokens = await scanAesthetics(rootDir, uiLibrary);
27296
- const tokensPath = path49.join(
27996
+ const tokensPath = path51.join(
27297
27997
  mancodeDir,
27298
27998
  "aesthetics",
27299
27999
  "style-tokens.json"
@@ -27428,7 +28128,7 @@ async function init(rootDir = process5.cwd(), options = {}) {
27428
28128
  )
27429
28129
  );
27430
28130
  }
27431
- return EXIT_OK;
28131
+ return EXIT_OK2;
27432
28132
  } catch (err) {
27433
28133
  await restoreFiles(mutationSnapshots);
27434
28134
  await removeNewEmptyDirectories(directorySnapshots);
@@ -27457,7 +28157,7 @@ async function initializeV3(rootDir, options) {
27457
28157
  );
27458
28158
  return EXIT_INIT_FAILED;
27459
28159
  }
27460
- const schemaPath = path49.join(rootDir, ".mancode", "schema.json");
28160
+ const schemaPath = path51.join(rootDir, ".mancode", "schema.json");
27461
28161
  let existingV3 = false;
27462
28162
  let registeredAdapters = /* @__PURE__ */ new Set();
27463
28163
  if (await pathExists6(schemaPath)) {
@@ -27546,7 +28246,7 @@ async function initializeV3(rootDir, options) {
27546
28246
  } else {
27547
28247
  console.log(` mancode bootstrap: ${selectedPlatforms.join(", ")}`);
27548
28248
  }
27549
- return EXIT_OK;
28249
+ return EXIT_OK2;
27550
28250
  } catch (error) {
27551
28251
  printV3InitError(error);
27552
28252
  return EXIT_INIT_FAILED;
@@ -27560,7 +28260,7 @@ function printV3InitError(error) {
27560
28260
  }
27561
28261
  }
27562
28262
  async function updateConfigOptions(mancodeDir, patch, preserveInstalledPlatforms) {
27563
- const configPath = path49.join(mancodeDir, "config.json");
28263
+ const configPath = path51.join(mancodeDir, "config.json");
27564
28264
  let config = {};
27565
28265
  try {
27566
28266
  config = JSON.parse(await fs4.readFile(configPath, "utf-8"));
@@ -27569,7 +28269,7 @@ async function updateConfigOptions(mancodeDir, patch, preserveInstalledPlatforms
27569
28269
  const existingPlatforms = Array.isArray(config.platforms) ? config.platforms.filter(
27570
28270
  (platform) => typeof platform === "string"
27571
28271
  ) : [];
27572
- const existingPlatformOptions = isRecord7(config.platformOptions) ? config.platformOptions : {};
28272
+ const existingPlatformOptions = isRecord8(config.platformOptions) ? config.platformOptions : {};
27573
28273
  const definedPatch = Object.fromEntries(
27574
28274
  Object.entries(patch).filter(([, value]) => value !== void 0)
27575
28275
  );
@@ -27593,7 +28293,7 @@ async function updateConfigOptions(mancodeDir, patch, preserveInstalledPlatforms
27593
28293
  async function readExistingInitPreferences(mancodeDir) {
27594
28294
  try {
27595
28295
  const config = JSON.parse(
27596
- await fs4.readFile(path49.join(mancodeDir, "config.json"), "utf-8")
28296
+ await fs4.readFile(path51.join(mancodeDir, "config.json"), "utf-8")
27597
28297
  );
27598
28298
  const preferences = {
27599
28299
  platforms: Array.isArray(config.platforms) ? config.platforms.filter(
@@ -27607,10 +28307,10 @@ async function readExistingInitPreferences(mancodeDir) {
27607
28307
  if (config.teamMode === "auto" || config.teamMode === "on" || config.teamMode === "off") {
27608
28308
  preferences.teamMode = config.teamMode;
27609
28309
  }
27610
- if (isRecord7(config.platformOptions)) {
28310
+ if (isRecord8(config.platformOptions)) {
27611
28311
  for (const platform of preferences.platforms) {
27612
28312
  const platformOptions = config.platformOptions[platform];
27613
- if (isRecord7(platformOptions) && platformOptions.minimal === true) {
28313
+ if (isRecord8(platformOptions) && platformOptions.minimal === true) {
27614
28314
  preferences.minimalByPlatform[platform] = true;
27615
28315
  }
27616
28316
  }
@@ -27659,13 +28359,13 @@ async function selectInitPlatforms(input) {
27659
28359
  }
27660
28360
  async function hasProjectManifest(rootDir) {
27661
28361
  for (const name of PROJECT_MANIFESTS) {
27662
- if (await pathExists6(path49.join(rootDir, name))) return true;
28362
+ if (await pathExists6(path51.join(rootDir, name))) return true;
27663
28363
  }
27664
28364
  return false;
27665
28365
  }
27666
28366
  async function canInitializeGenericProject(rootDir) {
27667
- const resolved = path49.resolve(rootDir);
27668
- if (resolved === path49.parse(resolved).root || resolved === path49.resolve(os.homedir())) {
28367
+ const resolved = path51.resolve(rootDir);
28368
+ if (resolved === path51.parse(resolved).root || resolved === path51.resolve(os.homedir())) {
27669
28369
  return { ok: false, reason: "unsafe" };
27670
28370
  }
27671
28371
  try {
@@ -27679,11 +28379,11 @@ async function canInitializeGenericProject(rootDir) {
27679
28379
  }
27680
28380
  }
27681
28381
  async function validateV3CliProjectBoundary(rootDir, options, locale, legacyInitialized) {
27682
- const isGitRepo = await pathExists6(path49.join(rootDir, ".git"));
28382
+ const isGitRepo = await pathExists6(path51.join(rootDir, ".git"));
27683
28383
  const hasManifest = await hasProjectManifest(rootDir);
27684
28384
  if (isGitRepo || hasManifest) return null;
27685
28385
  const v3Initialized = await pathExists6(
27686
- path49.join(rootDir, ".mancode", "schema.json")
28386
+ path51.join(rootDir, ".mancode", "schema.json")
27687
28387
  );
27688
28388
  const legacyAuthorityPresent = legacyInitialized || (await scanLegacyAuthority(rootDir)).authorityPresent;
27689
28389
  const genericSafety = await canInitializeGenericProject(rootDir);
@@ -27812,7 +28512,7 @@ function getInitManagedFilePaths(rootDir, platforms) {
27812
28512
  files.push(`.github/prompts/${mode}.prompt.md`);
27813
28513
  }
27814
28514
  }
27815
- return [...new Set(files.map((file) => path49.join(rootDir, file)))];
28515
+ return [...new Set(files.map((file) => path51.join(rootDir, file)))];
27816
28516
  }
27817
28517
  async function snapshotFiles(filePaths) {
27818
28518
  return Promise.all(
@@ -27831,10 +28531,10 @@ async function snapshotFiles(filePaths) {
27831
28531
  async function snapshotDirectories(filePaths, additionalDirectories = []) {
27832
28532
  const directories = new Set(additionalDirectories);
27833
28533
  for (const filePath of filePaths) {
27834
- let current = path49.dirname(filePath);
27835
- while (current !== path49.dirname(current)) {
28534
+ let current = path51.dirname(filePath);
28535
+ while (current !== path51.dirname(current)) {
27836
28536
  directories.add(current);
27837
- current = path49.dirname(current);
28537
+ current = path51.dirname(current);
27838
28538
  }
27839
28539
  }
27840
28540
  return Promise.all(
@@ -27850,7 +28550,7 @@ async function restoreFiles(snapshots) {
27850
28550
  await fs4.rm(snapshot.filePath, { force: true });
27851
28551
  continue;
27852
28552
  }
27853
- await fs4.mkdir(path49.dirname(snapshot.filePath), { recursive: true });
28553
+ await fs4.mkdir(path51.dirname(snapshot.filePath), { recursive: true });
27854
28554
  await fs4.writeFile(snapshot.filePath, snapshot.content, "utf-8");
27855
28555
  }
27856
28556
  }
@@ -27863,7 +28563,7 @@ async function removeNewEmptyDirectories(snapshots) {
27863
28563
  }
27864
28564
  }
27865
28565
  }
27866
- function isRecord7(value) {
28566
+ function isRecord8(value) {
27867
28567
  return typeof value === "object" && value !== null && !Array.isArray(value);
27868
28568
  }
27869
28569
  function isNodeError6(error) {
@@ -27917,15 +28617,15 @@ async function pathExists6(p) {
27917
28617
 
27918
28618
  // src/commands/install.ts
27919
28619
  import { promises as fs5 } from "fs";
27920
- import path50 from "path";
27921
- import process6 from "process";
27922
- var EXIT_OK2 = 0;
27923
- var EXIT_NOT_INITIALIZED = 1;
28620
+ import path52 from "path";
28621
+ import process7 from "process";
28622
+ var EXIT_OK3 = 0;
28623
+ var EXIT_NOT_INITIALIZED2 = 1;
27924
28624
  var EXIT_UNSUPPORTED_PLATFORM = 2;
27925
28625
  var EXIT_INSTALL_FAILED = 3;
27926
- async function install(rootDir = process6.cwd(), platform = "claude-code", options = {}) {
27927
- const stateFile = path50.join(rootDir, ".mancode", "state.json");
27928
- const v3SchemaFile = path50.join(rootDir, ".mancode", "schema.json");
28626
+ async function install(rootDir = process7.cwd(), platform = "claude-code", options = {}) {
28627
+ const stateFile = path52.join(rootDir, ".mancode", "state.json");
28628
+ const v3SchemaFile = path52.join(rootDir, ".mancode", "schema.json");
27929
28629
  if (await pathExists7(v3SchemaFile)) {
27930
28630
  return installV3(rootDir, platform, options);
27931
28631
  }
@@ -27939,7 +28639,7 @@ async function install(rootDir = process6.cwd(), platform = "claude-code", optio
27939
28639
  if (!await pathExists7(stateFile)) {
27940
28640
  console.error("\u2717 mancode not initialized.");
27941
28641
  console.error(" Run `mancode init` first.");
27942
- return EXIT_NOT_INITIALIZED;
28642
+ return EXIT_NOT_INITIALIZED2;
27943
28643
  }
27944
28644
  const installer = getPlatformInstaller(platform);
27945
28645
  if (!installer) {
@@ -27972,7 +28672,7 @@ async function install(rootDir = process6.cwd(), platform = "claude-code", optio
27972
28672
  `\u2139\uFE0F ${formatPlatformName(platform)} adapter already installed.`
27973
28673
  );
27974
28674
  console.log(" Run with --force to reinstall.");
27975
- return EXIT_OK2;
28675
+ return EXIT_OK3;
27976
28676
  }
27977
28677
  console.log(
27978
28678
  `\u2139\uFE0F ${formatPlatformName(platform)} adapter already installed; switching to minimal install.`
@@ -28014,7 +28714,7 @@ async function install(rootDir = process6.cwd(), platform = "claude-code", optio
28014
28714
  })
28015
28715
  });
28016
28716
  console.log(`\u2713 ${formatPlatformName(platform)} adapter installed.`);
28017
- return EXIT_OK2;
28717
+ return EXIT_OK3;
28018
28718
  }
28019
28719
  async function installV3(rootDir, platform, options) {
28020
28720
  const installer = getPlatformInstaller(platform);
@@ -28036,7 +28736,7 @@ async function installV3(rootDir, platform, options) {
28036
28736
  for (const entry of staged.modeEntries) {
28037
28737
  console.log(` ${entry.stagingTarget}`);
28038
28738
  }
28039
- return EXIT_OK2;
28739
+ return EXIT_OK3;
28040
28740
  }
28041
28741
  if (project.manifest.activationState !== "v3_active") {
28042
28742
  throw new Error("MANCODE_V3_ADAPTER_INSTALL_REQUIRES_ACTIVE");
@@ -28069,7 +28769,7 @@ async function installV3(rootDir, platform, options) {
28069
28769
  );
28070
28770
  for (const target of installed.filePlans)
28071
28771
  console.log(` ${target.target}`);
28072
- return EXIT_OK2;
28772
+ return EXIT_OK3;
28073
28773
  } catch (err) {
28074
28774
  const message = err instanceof Error ? err.message : String(err);
28075
28775
  console.error(
@@ -28086,7 +28786,7 @@ function printUnsupportedPlatform(platform) {
28086
28786
  }
28087
28787
  }
28088
28788
  async function readConfig2(rootDir) {
28089
- const configPath = path50.join(rootDir, ".mancode", "config.json");
28789
+ const configPath = path52.join(rootDir, ".mancode", "config.json");
28090
28790
  try {
28091
28791
  const raw = await fs5.readFile(configPath, "utf-8");
28092
28792
  return { config: JSON.parse(raw), valid: true };
@@ -28101,7 +28801,7 @@ function isNodeError7(err) {
28101
28801
  return err instanceof Error && "code" in err;
28102
28802
  }
28103
28803
  async function updateConfig(rootDir, config) {
28104
- const configPath = path50.join(rootDir, ".mancode", "config.json");
28804
+ const configPath = path52.join(rootDir, ".mancode", "config.json");
28105
28805
  const content = `${JSON.stringify(config, null, 2)}
28106
28806
  `;
28107
28807
  await fs5.writeFile(configPath, content, "utf-8");
@@ -28116,28 +28816,28 @@ function withDefaultConfig(config, fallbackPlatform) {
28116
28816
  return {
28117
28817
  ...merged,
28118
28818
  platforms,
28119
- hooks: isRecord8(config.hooks) ? config.hooks : DEFAULT_CONFIG.hooks,
28120
- logging: isRecord8(config.logging) ? config.logging : DEFAULT_CONFIG.logging
28819
+ hooks: isRecord9(config.hooks) ? config.hooks : DEFAULT_CONFIG.hooks,
28820
+ logging: isRecord9(config.logging) ? config.logging : DEFAULT_CONFIG.logging
28121
28821
  };
28122
28822
  }
28123
28823
  function updatePlatformOptions(value, platform, options) {
28124
- const platformOptions = isRecord8(value) ? { ...value } : {};
28824
+ const platformOptions = isRecord9(value) ? { ...value } : {};
28125
28825
  const existing = platformOptions[platform];
28126
28826
  platformOptions[platform] = {
28127
- ...isRecord8(existing) ? existing : {},
28827
+ ...isRecord9(existing) ? existing : {},
28128
28828
  minimal: options.minimal === true
28129
28829
  };
28130
28830
  return platformOptions;
28131
28831
  }
28132
28832
  function readConfiguredMinimal(value, platform) {
28133
- if (!isRecord8(value)) return false;
28833
+ if (!isRecord9(value)) return false;
28134
28834
  const platformOptions = value[platform];
28135
- return isRecord8(platformOptions) && platformOptions.minimal === true;
28835
+ return isRecord9(platformOptions) && platformOptions.minimal === true;
28136
28836
  }
28137
28837
  async function readStatePlatform(rootDir) {
28138
28838
  try {
28139
28839
  const raw = await fs5.readFile(
28140
- path50.join(rootDir, ".mancode", "state.json"),
28840
+ path52.join(rootDir, ".mancode", "state.json"),
28141
28841
  "utf-8"
28142
28842
  );
28143
28843
  const state = JSON.parse(raw);
@@ -28154,17 +28854,17 @@ async function pathExists7(p) {
28154
28854
  return false;
28155
28855
  }
28156
28856
  }
28157
- function isRecord8(value) {
28857
+ function isRecord9(value) {
28158
28858
  return typeof value === "object" && value !== null && !Array.isArray(value);
28159
28859
  }
28160
28860
 
28161
28861
  // src/commands/list-platforms.ts
28162
28862
  import { promises as fs6 } from "fs";
28163
- import path51 from "path";
28164
- import process7 from "process";
28165
- var EXIT_OK3 = 0;
28166
- async function listPlatforms(rootDir = process7.cwd()) {
28167
- if (await pathExists8(path51.join(rootDir, ".mancode", "schema.json"))) {
28863
+ import path53 from "path";
28864
+ import process8 from "process";
28865
+ var EXIT_OK4 = 0;
28866
+ async function listPlatforms(rootDir = process8.cwd()) {
28867
+ if (await pathExists8(path53.join(rootDir, ".mancode", "schema.json"))) {
28168
28868
  return listV3Platforms(rootDir);
28169
28869
  }
28170
28870
  const installed = new Set(await readInstalledPlatforms(rootDir));
@@ -28175,7 +28875,7 @@ async function listPlatforms(rootDir = process7.cwd()) {
28175
28875
  console.log(formatPlatformLine(platform, installed.has(platform.name)));
28176
28876
  }
28177
28877
  console.log("");
28178
- return EXIT_OK3;
28878
+ return EXIT_OK4;
28179
28879
  }
28180
28880
  async function listV3Platforms(rootDir) {
28181
28881
  const platforms = getPlatformInstallers();
@@ -28195,12 +28895,12 @@ async function listV3Platforms(rootDir) {
28195
28895
  );
28196
28896
  }
28197
28897
  console.log("");
28198
- return EXIT_OK3;
28898
+ return EXIT_OK4;
28199
28899
  }
28200
28900
  async function readInstalledPlatforms(rootDir) {
28201
28901
  try {
28202
28902
  const raw = await fs6.readFile(
28203
- path51.join(rootDir, ".mancode", "config.json"),
28903
+ path53.join(rootDir, ".mancode", "config.json"),
28204
28904
  "utf-8"
28205
28905
  );
28206
28906
  const config = JSON.parse(raw);
@@ -28232,8 +28932,8 @@ function describePlatform(platform) {
28232
28932
  }
28233
28933
 
28234
28934
  // src/commands/manps.ts
28235
- import { access as access4, readFile as readFile38 } from "fs/promises";
28236
- import path53 from "path";
28935
+ import { access as access4, readFile as readFile40 } from "fs/promises";
28936
+ import path55 from "path";
28237
28937
  import { createInterface as createInterface2 } from "readline/promises";
28238
28938
 
28239
28939
  // src/system/preseason.ts
@@ -28242,14 +28942,14 @@ import { createHash as createHash8 } from "crypto";
28242
28942
  import { existsSync, readFileSync } from "fs";
28243
28943
  import {
28244
28944
  access as access3,
28245
- lstat as lstat20,
28246
- mkdir as mkdir34,
28247
- readFile as readFile37,
28945
+ lstat as lstat21,
28946
+ mkdir as mkdir35,
28947
+ readFile as readFile39,
28248
28948
  readdir as readdir18,
28249
28949
  rename as rename11,
28250
- writeFile as writeFile39
28950
+ writeFile as writeFile40
28251
28951
  } from "fs/promises";
28252
- import path52 from "path";
28952
+ import path54 from "path";
28253
28953
  var PRESEASON_AREAS = [
28254
28954
  "all",
28255
28955
  "deps",
@@ -28314,7 +29014,7 @@ var SCANNERS = [
28314
29014
  {
28315
29015
  name: "aesthetic-drift",
28316
29016
  areas: ["all"],
28317
- scan: ({ projectRoot, files }) => scanAestheticDrift(projectRoot, files)
29017
+ scan: ({ projectRoot, files, pkg }) => scanAestheticDrift(projectRoot, files, pkg)
28318
29018
  },
28319
29019
  {
28320
29020
  name: "architecture",
@@ -28329,10 +29029,10 @@ async function runPreseasonScan(projectRoot, area = "all", options = {}) {
28329
29029
  const needsFiles = normalizedArea === "all" || normalizedArea === "dead-code" || normalizedArea === "config";
28330
29030
  const files = needsFiles ? await listProjectFiles(projectRoot) : [];
28331
29031
  const issues = (await scanArea(projectRoot, normalizedArea, pkg, files)).slice(0, 20);
28332
- const storageRoot = options.storageRoot ?? path52.join(projectRoot, ".mancode");
28333
- const reportDir = path52.join(storageRoot, "preseason-reports");
28334
- await mkdir34(reportDir, { recursive: true });
28335
- const issueDbPath = path52.join(storageRoot, "preseason-issues.json");
29032
+ const storageRoot = options.storageRoot ?? path54.join(projectRoot, ".mancode");
29033
+ const reportDir = path54.join(storageRoot, "preseason-reports");
29034
+ await mkdir35(reportDir, { recursive: true });
29035
+ const issueDbPath = path54.join(storageRoot, "preseason-issues.json");
28336
29036
  const reportPath = await allocateReportPath(
28337
29037
  reportDir,
28338
29038
  `${generatedAt.replace(/[:.]/g, "-")}-${normalizedArea}`
@@ -28346,9 +29046,9 @@ async function runPreseasonScan(projectRoot, area = "all", options = {}) {
28346
29046
  issueDbPath
28347
29047
  };
28348
29048
  const database = await buildIssueDatabase(projectRoot, report);
28349
- await writeFile39(reportPath, renderPreseasonReport(report), "utf-8");
28350
- await writeFile39(
28351
- path52.join(storageRoot, "preseason-report.md"),
29049
+ await writeFile40(reportPath, renderPreseasonReport(report), "utf-8");
29050
+ await writeFile40(
29051
+ path54.join(storageRoot, "preseason-report.md"),
28352
29052
  renderPreseasonReport(report),
28353
29053
  "utf-8"
28354
29054
  );
@@ -28356,7 +29056,7 @@ async function runPreseasonScan(projectRoot, area = "all", options = {}) {
28356
29056
  return report;
28357
29057
  }
28358
29058
  async function runPreseasonRemediation(projectRoot, issues, options = {}) {
28359
- const issueDbPath = options.issueDbPath ?? path52.join(projectRoot, ".mancode", "preseason-issues.json");
29059
+ const issueDbPath = options.issueDbPath ?? path54.join(projectRoot, ".mancode", "preseason-issues.json");
28360
29060
  const database = await readIssueDatabase(issueDbPath);
28361
29061
  const keys = new Set(issues.map((issue) => issueKey(issue)));
28362
29062
  const targets = database.issues.filter(
@@ -28434,7 +29134,7 @@ async function runPreseasonRemediation(projectRoot, issues, options = {}) {
28434
29134
  write2(" Decision: skipped.");
28435
29135
  }
28436
29136
  database.updatedAt = now;
28437
- await writeFile39(
29137
+ await writeFile40(
28438
29138
  issueDbPath,
28439
29139
  `${JSON.stringify(database, null, 2)}
28440
29140
  `,
@@ -28466,7 +29166,7 @@ async function scanArea(projectRoot, area, pkg, files) {
28466
29166
  async function allocateReportPath(reportDir, baseName) {
28467
29167
  for (let attempt = 0; attempt < 1e3; attempt++) {
28468
29168
  const suffix = attempt === 0 ? "" : `-${attempt + 1}`;
28469
- const candidate = path52.join(reportDir, `${baseName}${suffix}.md`);
29169
+ const candidate = path54.join(reportDir, `${baseName}${suffix}.md`);
28470
29170
  if (!existsSync(candidate)) return candidate;
28471
29171
  }
28472
29172
  throw new Error(`unable to allocate preseason report path: ${baseName}`);
@@ -28515,18 +29215,18 @@ async function walk(root, current, results, depth) {
28515
29215
  }
28516
29216
  for (const entry of entries) {
28517
29217
  if (IGNORE_DIRS.has(entry)) continue;
28518
- const abs = path52.join(current, entry);
28519
- const rel = path52.relative(root, abs);
29218
+ const abs = path54.join(current, entry);
29219
+ const rel = path54.relative(root, abs);
28520
29220
  let info;
28521
29221
  try {
28522
- info = await lstat20(abs);
29222
+ info = await lstat21(abs);
28523
29223
  } catch {
28524
29224
  continue;
28525
29225
  }
28526
29226
  if (info.isSymbolicLink()) continue;
28527
29227
  if (info.isDirectory()) {
28528
29228
  await walk(root, abs, results, depth + 1);
28529
- } else if (SOURCE_EXTENSIONS.has(path52.extname(entry)) || entry === "package.json") {
29229
+ } else if (SOURCE_EXTENSIONS.has(path54.extname(entry)) || entry === "package.json") {
28530
29230
  results.push(rel);
28531
29231
  if (results.length >= MAX_PROJECT_FILES) return;
28532
29232
  }
@@ -28534,7 +29234,7 @@ async function walk(root, current, results, depth) {
28534
29234
  }
28535
29235
  async function readPackageJson(projectRoot) {
28536
29236
  try {
28537
- const raw = await readFile37(path52.join(projectRoot, "package.json"), "utf-8");
29237
+ const raw = await readFile39(path54.join(projectRoot, "package.json"), "utf-8");
28538
29238
  return JSON.parse(raw);
28539
29239
  } catch {
28540
29240
  return null;
@@ -28627,7 +29327,7 @@ function scanTodos(projectRoot, files) {
28627
29327
  const matches = [];
28628
29328
  for (const file of files) {
28629
29329
  if (matches.length >= 7) break;
28630
- const abs = path52.join(projectRoot, file);
29330
+ const abs = path54.join(projectRoot, file);
28631
29331
  matches.push(...readTodoIssues(abs, file, matches.length));
28632
29332
  }
28633
29333
  return matches.slice(0, 7);
@@ -28668,7 +29368,7 @@ function scanTestGaps(files) {
28668
29368
  if (sourceFiles.length === 0) return [];
28669
29369
  const tests = new Set(files.filter((file) => file.startsWith("tests/")));
28670
29370
  const missing = sourceFiles.filter((file) => {
28671
- const base = path52.basename(file).replace(/\.(ts|tsx|js|jsx)$/, "");
29371
+ const base = path54.basename(file).replace(/\.(ts|tsx|js|jsx)$/, "");
28672
29372
  return !Array.from(tests).some((test) => test.includes(base));
28673
29373
  }).slice(0, 4);
28674
29374
  return missing.map((file, index) => ({
@@ -28677,13 +29377,13 @@ function scanTestGaps(files) {
28677
29377
  type: "tests",
28678
29378
  title: "Core source file has no obvious test",
28679
29379
  file,
28680
- detail: `No matching test file was found for ${path52.basename(file)}.`,
29380
+ detail: `No matching test file was found for ${path54.basename(file)}.`,
28681
29381
  recommendation: "Add focused coverage for the public behavior or document why this module is exercised indirectly."
28682
29382
  }));
28683
29383
  }
28684
29384
  function scanConfig(projectRoot, files) {
28685
29385
  const issues = [];
28686
- if (!files.includes(".gitignore") && !pathExistsSync(path52.join(projectRoot, ".gitignore"))) {
29386
+ if (!files.includes(".gitignore") && !pathExistsSync(path54.join(projectRoot, ".gitignore"))) {
28687
29387
  issues.push({
28688
29388
  id: "config-gitignore",
28689
29389
  severity: "P1",
@@ -28694,7 +29394,7 @@ function scanConfig(projectRoot, files) {
28694
29394
  recommendation: "Add a .gitignore that excludes dependencies, build output, coverage, and local env files."
28695
29395
  });
28696
29396
  }
28697
- if (!files.includes(".editorconfig") && !pathExistsSync(path52.join(projectRoot, ".editorconfig"))) {
29397
+ if (!files.includes(".editorconfig") && !pathExistsSync(path54.join(projectRoot, ".editorconfig"))) {
28698
29398
  issues.push({
28699
29399
  id: "config-editorconfig",
28700
29400
  severity: "P2",
@@ -28707,13 +29407,13 @@ function scanConfig(projectRoot, files) {
28707
29407
  }
28708
29408
  return issues;
28709
29409
  }
28710
- function scanAestheticDrift(projectRoot, files) {
29410
+ function scanAestheticDrift(projectRoot, files, pkg) {
28711
29411
  const issues = [];
28712
29412
  const frontendFiles = files.filter((file) => /\.(tsx|jsx|css)$/.test(file));
28713
29413
  for (const file of frontendFiles) {
28714
29414
  let content;
28715
29415
  try {
28716
- content = readFileSyncSafe(path52.join(projectRoot, file));
29416
+ content = readFileSyncSafe(path54.join(projectRoot, file));
28717
29417
  } catch {
28718
29418
  continue;
28719
29419
  }
@@ -28730,10 +29430,41 @@ function scanAestheticDrift(projectRoot, files) {
28730
29430
  break;
28731
29431
  }
28732
29432
  }
29433
+ const iconSystems = detectedIconSystems(pkg);
29434
+ if (iconSystems.length > 1) {
29435
+ issues.push({
29436
+ id: "aesthetics-mixed-icon-systems",
29437
+ severity: "P2",
29438
+ type: "aesthetics",
29439
+ title: "Multiple icon systems declared",
29440
+ file: "package.json",
29441
+ detail: `Multiple icon systems are declared: ${iconSystems.join(", ")}.`,
29442
+ recommendation: "Use the configured design policy for new interface work; remove a redundant package only after confirming it has no active imports."
29443
+ });
29444
+ }
28733
29445
  return issues;
28734
29446
  }
29447
+ function detectedIconSystems(pkg) {
29448
+ if (!pkg) return [];
29449
+ const packages = Object.keys({
29450
+ ...pkg.dependencies,
29451
+ ...pkg.devDependencies
29452
+ });
29453
+ const systems = [
29454
+ ["Lucide", /^lucide(?:-|$)/],
29455
+ ["Heroicons", /^@heroicons\//],
29456
+ [
29457
+ "Material Icons",
29458
+ /^(?:@mui\/icons-material|@material-design-icons\/|material-icons(?:-|$)|material-symbols(?:-|$))/
29459
+ ],
29460
+ ["Phosphor", /^(?:@phosphor-icons\/|phosphor-(?:react|icons)(?:-|$))/],
29461
+ ["Font Awesome", /^@fortawesome\/(?:free|pro|sharp)-.+-svg-icons$/],
29462
+ ["React Icons", /^react-icons$/]
29463
+ ];
29464
+ return systems.filter(([, pattern]) => packages.some((name) => pattern.test(name))).map(([name]) => name);
29465
+ }
28735
29466
  async function scanArchitecture(projectRoot) {
28736
- const localBinary = path52.join(
29467
+ const localBinary = path54.join(
28737
29468
  projectRoot,
28738
29469
  "node_modules",
28739
29470
  ".bin",
@@ -28781,7 +29512,7 @@ async function hasDependencyCruiserConfig(projectRoot) {
28781
29512
  "dependency-cruiser.config.mjs"
28782
29513
  ];
28783
29514
  const results = await Promise.all(
28784
- files.map((file) => pathExists9(path52.join(projectRoot, file)))
29515
+ files.map((file) => pathExists9(path54.join(projectRoot, file)))
28785
29516
  );
28786
29517
  return results.some(Boolean);
28787
29518
  }
@@ -28849,15 +29580,15 @@ function parseDepcruiseJson(output) {
28849
29580
  }
28850
29581
  }
28851
29582
  function extractDepcruiseViolations(value) {
28852
- if (!isRecord9(value)) return [];
28853
- const rawViolations = Array.isArray(value.violations) ? value.violations : isRecord9(value.summary) && Array.isArray(value.summary.violations) ? value.summary.violations : [];
29583
+ if (!isRecord10(value)) return [];
29584
+ const rawViolations = Array.isArray(value.violations) ? value.violations : isRecord10(value.summary) && Array.isArray(value.summary.violations) ? value.summary.violations : [];
28854
29585
  return rawViolations.map((violation) => normalizeDepcruiseViolation(violation)).filter(
28855
29586
  (violation) => violation !== null
28856
29587
  );
28857
29588
  }
28858
29589
  function normalizeDepcruiseViolation(value) {
28859
- if (!isRecord9(value)) return null;
28860
- const rule = isRecord9(value.rule) ? value.rule : {};
29590
+ if (!isRecord10(value)) return null;
29591
+ const rule = isRecord10(value.rule) ? value.rule : {};
28861
29592
  const from = typeof value.from === "string" ? value.from : "";
28862
29593
  const to = typeof value.to === "string" ? value.to : void 0;
28863
29594
  const ruleName = typeof rule.name === "string" ? rule.name : typeof value.name === "string" ? value.name : "unnamed-rule";
@@ -28887,9 +29618,9 @@ function inferCommands(pkg) {
28887
29618
  return ["lint", "test", "build"].filter((name) => scripts[name]).map((name) => `npm run ${name}`);
28888
29619
  }
28889
29620
  async function buildIssueDatabase(projectRoot, report) {
28890
- const reportRef = path52.relative(projectRoot, report.reportPath);
29621
+ const reportRef = path54.relative(projectRoot, report.reportPath);
28891
29622
  const run = {
28892
- id: path52.basename(report.reportPath, ".md"),
29623
+ id: path54.basename(report.reportPath, ".md"),
28893
29624
  generatedAt: report.generatedAt,
28894
29625
  area: report.area,
28895
29626
  reportPath: reportRef,
@@ -28931,7 +29662,7 @@ async function buildIssueDatabase(projectRoot, report) {
28931
29662
  async function readIssueDatabase(issueDbPath) {
28932
29663
  let raw;
28933
29664
  try {
28934
- raw = await readFile37(issueDbPath, "utf-8");
29665
+ raw = await readFile39(issueDbPath, "utf-8");
28935
29666
  } catch (err) {
28936
29667
  if (isNodeError8(err) && err.code === "ENOENT") {
28937
29668
  return emptyIssueDatabase();
@@ -28952,7 +29683,7 @@ async function readIssueDatabase(issueDbPath) {
28952
29683
  }
28953
29684
  async function writeJsonAtomic3(file, value) {
28954
29685
  const tmp = `${file}.tmp-${Date.now()}-${Math.random().toString(36).slice(2)}`;
28955
- await writeFile39(tmp, `${JSON.stringify(value, null, 2)}
29686
+ await writeFile40(tmp, `${JSON.stringify(value, null, 2)}
28956
29687
  `, "utf-8");
28957
29688
  await rename11(tmp, file);
28958
29689
  }
@@ -28995,20 +29726,20 @@ function compareIssueRecords(a, b) {
28995
29726
  }
28996
29727
  async function applySafeRemediation(projectRoot, issue) {
28997
29728
  if (issue.id === "config-gitignore" && issue.file === ".gitignore") {
28998
- const gitignorePath = path52.join(projectRoot, ".gitignore");
29729
+ const gitignorePath = path54.join(projectRoot, ".gitignore");
28999
29730
  if (pathExistsSync(gitignorePath)) {
29000
29731
  return { applied: false };
29001
29732
  }
29002
- await writeFile39(gitignorePath, `${DEFAULT_GITIGNORE}
29733
+ await writeFile40(gitignorePath, `${DEFAULT_GITIGNORE}
29003
29734
  `, "utf-8");
29004
29735
  return { applied: true, action: "created .gitignore" };
29005
29736
  }
29006
29737
  if (issue.id === "config-editorconfig" && issue.file === ".editorconfig") {
29007
- const editorconfigPath = path52.join(projectRoot, ".editorconfig");
29738
+ const editorconfigPath = path54.join(projectRoot, ".editorconfig");
29008
29739
  if (pathExistsSync(editorconfigPath)) {
29009
29740
  return { applied: false };
29010
29741
  }
29011
- await writeFile39(editorconfigPath, `${DEFAULT_EDITORCONFIG}
29742
+ await writeFile40(editorconfigPath, `${DEFAULT_EDITORCONFIG}
29012
29743
  `, "utf-8");
29013
29744
  return { applied: true, action: "created .editorconfig" };
29014
29745
  }
@@ -29044,10 +29775,10 @@ async function inferSafePackageScript(projectRoot, scriptName) {
29044
29775
  }
29045
29776
  }
29046
29777
  async function addPackageScript(projectRoot, scriptName, script) {
29047
- const packagePath = path52.join(projectRoot, "package.json");
29778
+ const packagePath = path54.join(projectRoot, "package.json");
29048
29779
  let pkg;
29049
29780
  try {
29050
- pkg = JSON.parse(await readFile37(packagePath, "utf-8"));
29781
+ pkg = JSON.parse(await readFile39(packagePath, "utf-8"));
29051
29782
  } catch {
29052
29783
  return false;
29053
29784
  }
@@ -29057,7 +29788,7 @@ async function addPackageScript(projectRoot, scriptName, script) {
29057
29788
  ...scripts,
29058
29789
  [scriptName]: script
29059
29790
  };
29060
- await writeFile39(packagePath, `${JSON.stringify(pkg, null, 2)}
29791
+ await writeFile40(packagePath, `${JSON.stringify(pkg, null, 2)}
29061
29792
  `, "utf-8");
29062
29793
  return true;
29063
29794
  }
@@ -29147,17 +29878,17 @@ async function pathExists9(file) {
29147
29878
  function isNodeError8(err) {
29148
29879
  return err instanceof Error && "code" in err;
29149
29880
  }
29150
- function isRecord9(value) {
29881
+ function isRecord10(value) {
29151
29882
  return typeof value === "object" && value !== null;
29152
29883
  }
29153
29884
 
29154
29885
  // src/commands/manps.ts
29155
- var EXIT_OK4 = 0;
29156
- var EXIT_NOT_INITIALIZED2 = 1;
29886
+ var EXIT_OK5 = 0;
29887
+ var EXIT_NOT_INITIALIZED3 = 1;
29157
29888
  var EXIT_SCAN_FAILED = 2;
29158
29889
  var EXIT_INVALID_ARG = 3;
29159
29890
  async function manps(rootDir, area = "all", options = {}) {
29160
- const v3SchemaPath = path53.join(rootDir, ".mancode", "schema.json");
29891
+ const v3SchemaPath = path55.join(rootDir, ".mancode", "schema.json");
29161
29892
  const v3Activation = await readV3ActivationState(v3SchemaPath);
29162
29893
  if (v3Activation !== null && v3Activation !== "v3_active" && v3Activation !== "dual_read") {
29163
29894
  const message = `manps is unavailable while mancode activation is ${v3Activation}`;
@@ -29170,7 +29901,7 @@ async function manps(rootDir, area = "all", options = {}) {
29170
29901
  return EXIT_SCAN_FAILED;
29171
29902
  }
29172
29903
  const v3Initialized = v3Activation === "v3_active";
29173
- const initialized = v3Initialized || await pathExists10(path53.join(rootDir, ".mancode", "state.json"));
29904
+ const initialized = v3Initialized || await pathExists10(path55.join(rootDir, ".mancode", "state.json"));
29174
29905
  if (!initialized) {
29175
29906
  if (options.json) {
29176
29907
  console.log(JSON.stringify({ error: "not initialized" }, null, 2));
@@ -29178,12 +29909,12 @@ async function manps(rootDir, area = "all", options = {}) {
29178
29909
  console.error("\u2717 mancode not initialized.");
29179
29910
  console.error(" Run `mancode init` first.");
29180
29911
  }
29181
- return EXIT_NOT_INITIALIZED2;
29912
+ return EXIT_NOT_INITIALIZED3;
29182
29913
  }
29183
29914
  let report;
29184
29915
  try {
29185
29916
  report = await runPreseasonScan(rootDir, area, {
29186
- storageRoot: v3Initialized ? path53.join(rootDir, ".mancode", "local") : void 0
29917
+ storageRoot: v3Initialized ? path55.join(rootDir, ".mancode", "local") : void 0
29187
29918
  });
29188
29919
  } catch (err) {
29189
29920
  const message = err instanceof Error ? err.message : String(err);
@@ -29241,7 +29972,7 @@ async function manps(rootDir, area = "all", options = {}) {
29241
29972
  }
29242
29973
  if (options.json) {
29243
29974
  console.log(JSON.stringify({ ...report, remediation }, null, 2));
29244
- return EXIT_OK4;
29975
+ return EXIT_OK5;
29245
29976
  }
29246
29977
  const p0 = report.issues.filter((issue) => issue.severity === "P0").length;
29247
29978
  const p1 = report.issues.filter((issue) => issue.severity === "P1").length;
@@ -29252,8 +29983,8 @@ async function manps(rootDir, area = "all", options = {}) {
29252
29983
  console.log(
29253
29984
  `Issues: ${report.issues.length} total (P0 ${p0}, P1 ${p1}, P2 ${p2})`
29254
29985
  );
29255
- console.log(`Report: ${path53.relative(rootDir, report.reportPath)}`);
29256
- console.log(`Issue DB: ${path53.relative(rootDir, report.issueDbPath)}`);
29986
+ console.log(`Report: ${path55.relative(rootDir, report.reportPath)}`);
29987
+ console.log(`Issue DB: ${path55.relative(rootDir, report.issueDbPath)}`);
29257
29988
  if (report.issues.length > 0) {
29258
29989
  console.log("");
29259
29990
  for (const issue of report.issues.slice(0, 7)) {
@@ -29269,10 +30000,10 @@ async function manps(rootDir, area = "all", options = {}) {
29269
30000
  console.log(` Skipped: ${remediation.skipped}`);
29270
30001
  console.log(` Fixed: ${remediation.fixed}`);
29271
30002
  console.log(
29272
- ` Issue DB: ${path53.relative(rootDir, remediation.issueDbPath)}`
30003
+ ` Issue DB: ${path55.relative(rootDir, remediation.issueDbPath)}`
29273
30004
  );
29274
30005
  }
29275
- return EXIT_OK4;
30006
+ return EXIT_OK5;
29276
30007
  }
29277
30008
  async function runRemediation(rootDir, report, options, silent = false) {
29278
30009
  const write2 = silent ? () => {
@@ -29330,7 +30061,7 @@ async function readV3ActivationState(schemaPath) {
29330
30061
  if (!await pathExists10(schemaPath)) return null;
29331
30062
  try {
29332
30063
  const manifest = parseSchemaManifest(
29333
- JSON.parse(await readFile38(schemaPath, "utf8"))
30064
+ JSON.parse(await readFile40(schemaPath, "utf8"))
29334
30065
  );
29335
30066
  return manifest.activationState;
29336
30067
  } catch {
@@ -29339,9 +30070,9 @@ async function readV3ActivationState(schemaPath) {
29339
30070
  }
29340
30071
 
29341
30072
  // src/commands/migrate.ts
29342
- import { readFile as readFile39 } from "fs/promises";
29343
- import path54 from "path";
29344
- var EXIT_OK5 = 0;
30073
+ import { readFile as readFile41 } from "fs/promises";
30074
+ import path56 from "path";
30075
+ var EXIT_OK6 = 0;
29345
30076
  var EXIT_INVALID_ARG2 = 2;
29346
30077
  var EXIT_MIGRATION_BLOCKED = 3;
29347
30078
  async function migrateContext(rootDir, options) {
@@ -29353,7 +30084,7 @@ async function migrateContext(rootDir, options) {
29353
30084
  options.rollback !== void 0
29354
30085
  ].filter(Boolean).length;
29355
30086
  if (selected !== 1) {
29356
- return printError(
30087
+ return printError2(
29357
30088
  options.json,
29358
30089
  "MANCODE_MIGRATION_ARGUMENT_INVALID",
29359
30090
  "Choose exactly one migration operation.",
@@ -29362,16 +30093,16 @@ async function migrateContext(rootDir, options) {
29362
30093
  }
29363
30094
  try {
29364
30095
  if (options.dryRun) {
29365
- return printResult(options.json, await dryRunLegacyMigration(rootDir));
30096
+ return printResult2(options.json, await dryRunLegacyMigration(rootDir));
29366
30097
  }
29367
30098
  if (options.stage) {
29368
- return printResult(
30099
+ return printResult2(
29369
30100
  options.json,
29370
30101
  await stageLegacyMigration({ projectRoot: rootDir })
29371
30102
  );
29372
30103
  }
29373
30104
  if (options.status) {
29374
- return printResult(options.json, {
30105
+ return printResult2(options.json, {
29375
30106
  schemaVersion: 1,
29376
30107
  stages: await listMigrationStages(rootDir)
29377
30108
  });
@@ -29382,7 +30113,7 @@ async function migrateContext(rootDir, options) {
29382
30113
  assertUlid(options.session, "migration activation session");
29383
30114
  if (options.rollback !== void 0) {
29384
30115
  assertUlid(options.rollback, "migration rollback operation");
29385
- return printResult(
30116
+ return printResult2(
29386
30117
  options.json,
29387
30118
  await rollbackLegacyMigration({
29388
30119
  projectRoot: rootDir,
@@ -29393,7 +30124,7 @@ async function migrateContext(rootDir, options) {
29393
30124
  );
29394
30125
  }
29395
30126
  const stageId = await selectStageId(rootDir, options.stageId);
29396
- return printResult(
30127
+ return printResult2(
29397
30128
  options.json,
29398
30129
  await activateLegacyMigration({
29399
30130
  projectRoot: rootDir,
@@ -29405,9 +30136,9 @@ async function migrateContext(rootDir, options) {
29405
30136
  })
29406
30137
  );
29407
30138
  } catch (error) {
29408
- return printError(
30139
+ return printError2(
29409
30140
  options.json,
29410
- errorCode3(error),
30141
+ errorCode4(error),
29411
30142
  error instanceof Error ? error.message : "Migration failed.",
29412
30143
  EXIT_MIGRATION_BLOCKED
29413
30144
  );
@@ -29427,11 +30158,11 @@ async function migrateContextResolve(rootDir, legacyTaskId, options) {
29427
30158
  ownerActorId: owner,
29428
30159
  implementationScope
29429
30160
  });
29430
- return printResult(options.json, result2);
30161
+ return printResult2(options.json, result2);
29431
30162
  } catch (error) {
29432
- return printError(
30163
+ return printError2(
29433
30164
  options.json,
29434
- errorCode3(error),
30165
+ errorCode4(error),
29435
30166
  error instanceof Error ? error.message : "Migration resolution failed.",
29436
30167
  EXIT_MIGRATION_BLOCKED
29437
30168
  );
@@ -29466,14 +30197,14 @@ async function readScopeFile(rootDir, file) {
29466
30197
  if (!file.trim() || file.includes("\0")) {
29467
30198
  throw new Error("MANCODE_MIGRATION_SCOPE_FILE_INVALID");
29468
30199
  }
29469
- const resolved = path54.resolve(rootDir, file);
29470
- const relative = path54.relative(path54.resolve(rootDir), resolved);
29471
- if (relative === ".." || relative.startsWith(`..${path54.sep}`) || path54.isAbsolute(relative)) {
30200
+ const resolved = path56.resolve(rootDir, file);
30201
+ const relative = path56.relative(path56.resolve(rootDir), resolved);
30202
+ if (relative === ".." || relative.startsWith(`..${path56.sep}`) || path56.isAbsolute(relative)) {
29472
30203
  throw new Error("MANCODE_MIGRATION_SCOPE_FILE_INVALID");
29473
30204
  }
29474
30205
  try {
29475
30206
  return JSON.parse(
29476
- await readFile39(resolved, "utf8")
30207
+ await readFile41(resolved, "utf8")
29477
30208
  );
29478
30209
  } catch (error) {
29479
30210
  if (error instanceof SyntaxError) {
@@ -29482,15 +30213,15 @@ async function readScopeFile(rootDir, file) {
29482
30213
  throw error;
29483
30214
  }
29484
30215
  }
29485
- function printResult(json, result2) {
30216
+ function printResult2(json, result2) {
29486
30217
  if (json) {
29487
30218
  console.log(JSON.stringify(result2, null, 2));
29488
30219
  } else {
29489
30220
  console.log(JSON.stringify(result2, null, 2));
29490
30221
  }
29491
- return EXIT_OK5;
30222
+ return EXIT_OK6;
29492
30223
  }
29493
- function printError(json, code, message, exitCode) {
30224
+ function printError2(json, code, message, exitCode) {
29494
30225
  const result2 = { schemaVersion: 1, error: { code, message } };
29495
30226
  if (json) {
29496
30227
  console.log(JSON.stringify(result2, null, 2));
@@ -29500,7 +30231,7 @@ function printError(json, code, message, exitCode) {
29500
30231
  }
29501
30232
  return exitCode;
29502
30233
  }
29503
- function errorCode3(error) {
30234
+ function errorCode4(error) {
29504
30235
  if (error instanceof Error && error.message.startsWith("MANCODE_")) {
29505
30236
  return error.message.split(":", 1)[0] ?? "MANCODE_MIGRATION_FAILED";
29506
30237
  }
@@ -29573,12 +30304,12 @@ async function runOperationMutation(rootDir, operationId, options, mode) {
29573
30304
  }
29574
30305
 
29575
30306
  // src/context/project-policy-upgrade.ts
29576
- import { lstat as lstat21, mkdir as mkdir35, readFile as readFile40, rm as rm18, writeFile as writeFile40 } from "fs/promises";
29577
- import path55 from "path";
30307
+ import { lstat as lstat22, mkdir as mkdir36, readFile as readFile42, rm as rm19, writeFile as writeFile41 } from "fs/promises";
30308
+ import path57 from "path";
29578
30309
  var UPGRADE_OPERATION = "project_policy_upgrade";
29579
30310
  async function dryRunProjectPolicyUpgrade(input) {
29580
30311
  assertPolicyVersion(input.policyVersion);
29581
- const root = path55.resolve(input.projectRoot);
30312
+ const root = path57.resolve(input.projectRoot);
29582
30313
  const project = await new V3ContextStore(root).readProjectSnapshot();
29583
30314
  const beforeDigest = digestManifest(project.manifest);
29584
30315
  const now = input.now ?? /* @__PURE__ */ new Date();
@@ -29622,7 +30353,7 @@ async function dryRunProjectPolicyUpgrade(input) {
29622
30353
  async function upgradeProjectPolicy(input) {
29623
30354
  assertPolicyVersion(input.policyVersion);
29624
30355
  assertUlid(input.sessionId, "project policy upgrade sessionId");
29625
- const root = path55.resolve(input.projectRoot);
30356
+ const root = path57.resolve(input.projectRoot);
29626
30357
  const now = input.now ?? /* @__PURE__ */ new Date();
29627
30358
  const operationId = input.operationId;
29628
30359
  if (operationId === void 0) {
@@ -29832,7 +30563,7 @@ async function collectUpgradeBlockers(root, project) {
29832
30563
  try {
29833
30564
  await assertUpgradePreflight(root, project);
29834
30565
  } catch (error) {
29835
- blockers.push(errorCode4(error));
30566
+ blockers.push(errorCode5(error));
29836
30567
  }
29837
30568
  return [...new Set(blockers)];
29838
30569
  }
@@ -29876,24 +30607,24 @@ function buildV2Manifest(manifest, operationId) {
29876
30607
  return candidate;
29877
30608
  }
29878
30609
  async function readSchemaContent(root) {
29879
- return readFile40(path55.join(root, ".mancode", "schema.json"), "utf8");
30610
+ return readFile42(path57.join(root, ".mancode", "schema.json"), "utf8");
29880
30611
  }
29881
30612
  async function writeSchemaContent(root, operationId, content) {
29882
- const directory = path55.join(root, ".mancode");
29883
- const target = path55.join(directory, "schema.json");
29884
- const stat4 = await lstat21(target);
29885
- if (!stat4.isFile() || stat4.isSymbolicLink()) {
30613
+ const directory = path57.join(root, ".mancode");
30614
+ const target = path57.join(directory, "schema.json");
30615
+ const stat5 = await lstat22(target);
30616
+ if (!stat5.isFile() || stat5.isSymbolicLink()) {
29886
30617
  throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
29887
30618
  }
29888
- const temporary = path55.join(
30619
+ const temporary = path57.join(
29889
30620
  directory,
29890
30621
  `.schema.json.${operationId}.${process.pid}.tmp`
29891
30622
  );
29892
- await writeFile40(temporary, content, { encoding: "utf8", flag: "wx" });
30623
+ await writeFile41(temporary, content, { encoding: "utf8", flag: "wx" });
29893
30624
  try {
29894
30625
  await replaceFileAtomically(temporary, target);
29895
30626
  } catch (error) {
29896
- await rm18(temporary, { force: true });
30627
+ await rm19(temporary, { force: true });
29897
30628
  throw error;
29898
30629
  }
29899
30630
  }
@@ -29954,22 +30685,22 @@ function assertPolicyVersion(value) {
29954
30685
  );
29955
30686
  }
29956
30687
  }
29957
- function errorCode4(error) {
30688
+ function errorCode5(error) {
29958
30689
  return error instanceof Error && error.message.startsWith("MANCODE_") ? error.message.split(":", 1)[0] ?? "MANCODE_PROJECT_UPGRADE_BLOCKED" : "MANCODE_PROJECT_UPGRADE_BLOCKED";
29959
30690
  }
29960
30691
  async function releaseLocks3(locks) {
29961
30692
  await Promise.allSettled([...locks].reverse().map((lock) => lock.release()));
29962
30693
  }
29963
30694
  function projectUpgradePreviewRoot(root, operationId) {
29964
- return path55.join(root, ".mancode", "staging", "project-upgrade", operationId);
30695
+ return path57.join(root, ".mancode", "staging", "project-upgrade", operationId);
29965
30696
  }
29966
30697
  async function stageProjectPolicyUpgrade(root, receipt, manifestContent) {
29967
30698
  const directory = projectUpgradePreviewRoot(root, receipt.operationId);
29968
- const receiptPath = path55.join(directory, "preview.json");
29969
- const manifestPath = path55.join(directory, "schema.json");
29970
- await mkdir35(path55.dirname(directory), { recursive: true });
30699
+ const receiptPath = path57.join(directory, "preview.json");
30700
+ const manifestPath = path57.join(directory, "schema.json");
30701
+ await mkdir36(path57.dirname(directory), { recursive: true });
29971
30702
  try {
29972
- await mkdir35(directory);
30703
+ await mkdir36(directory);
29973
30704
  } catch (error) {
29974
30705
  if (isAlreadyExists23(error)) {
29975
30706
  throw new Error("MANCODE_PROJECT_UPGRADE_PREVIEW_EXISTS");
@@ -29977,25 +30708,25 @@ async function stageProjectPolicyUpgrade(root, receipt, manifestContent) {
29977
30708
  throw error;
29978
30709
  }
29979
30710
  try {
29980
- await writeFile40(receiptPath, `${JSON.stringify(receipt, null, 2)}
30711
+ await writeFile41(receiptPath, `${JSON.stringify(receipt, null, 2)}
29981
30712
  `, {
29982
30713
  encoding: "utf8",
29983
30714
  flag: "wx"
29984
30715
  });
29985
- await writeFile40(manifestPath, manifestContent, {
30716
+ await writeFile41(manifestPath, manifestContent, {
29986
30717
  encoding: "utf8",
29987
30718
  flag: "wx"
29988
30719
  });
29989
30720
  } catch (error) {
29990
- await rm18(directory, { recursive: true, force: true });
30721
+ await rm19(directory, { recursive: true, force: true });
29991
30722
  throw error;
29992
30723
  }
29993
30724
  }
29994
30725
  async function assertProjectPolicyUpgradePreview(root, operationId, project) {
29995
30726
  const directory = projectUpgradePreviewRoot(root, operationId);
29996
30727
  const [receiptContent, manifestContent] = await Promise.all([
29997
- readSafePreviewFile(path55.join(directory, "preview.json")),
29998
- readSafePreviewFile(path55.join(directory, "schema.json"))
30728
+ readSafePreviewFile(path57.join(directory, "preview.json")),
30729
+ readSafePreviewFile(path57.join(directory, "schema.json"))
29999
30730
  ]);
30000
30731
  let receipt;
30001
30732
  try {
@@ -30018,13 +30749,13 @@ async function assertProjectPolicyUpgradePreview(root, operationId, project) {
30018
30749
  }
30019
30750
  async function readSafePreviewFile(target) {
30020
30751
  try {
30021
- const stat4 = await lstat21(target);
30022
- if (!stat4.isFile() || stat4.isSymbolicLink()) {
30752
+ const stat5 = await lstat22(target);
30753
+ if (!stat5.isFile() || stat5.isSymbolicLink()) {
30023
30754
  throw new Error("MANCODE_PROJECT_UPGRADE_PREVIEW_INVALID");
30024
30755
  }
30025
- return readFile40(target, "utf8");
30756
+ return readFile42(target, "utf8");
30026
30757
  } catch (error) {
30027
- if (isNotFound28(error)) {
30758
+ if (isNotFound29(error)) {
30028
30759
  throw new Error("MANCODE_PROJECT_UPGRADE_PREVIEW_REQUIRED");
30029
30760
  }
30030
30761
  throw error;
@@ -30057,7 +30788,7 @@ function parseProjectPolicyUpgradePreviewReceipt(value) {
30057
30788
  createdAt: record.createdAt
30058
30789
  };
30059
30790
  }
30060
- function isNotFound28(error) {
30791
+ function isNotFound29(error) {
30061
30792
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
30062
30793
  }
30063
30794
  function isAlreadyExists23(error) {
@@ -30111,22 +30842,22 @@ async function projectUpgrade(rootDir, options) {
30111
30842
  // src/commands/refresh-project.ts
30112
30843
  import { randomUUID } from "crypto";
30113
30844
  import { promises as fs7 } from "fs";
30114
- import path56 from "path";
30115
- import process8 from "process";
30116
- var EXIT_OK6 = 0;
30117
- var EXIT_NOT_INITIALIZED3 = 1;
30845
+ import path58 from "path";
30846
+ import process9 from "process";
30847
+ var EXIT_OK7 = 0;
30848
+ var EXIT_NOT_INITIALIZED4 = 1;
30118
30849
  var EXIT_CORRUPT_STATE = 2;
30119
30850
  var EXIT_REFRESH_FAILED = 3;
30120
- async function refreshProject(rootDir = process8.cwd()) {
30121
- const mancodeDir = path56.join(rootDir, ".mancode");
30122
- const statePath = path56.join(mancodeDir, "state.json");
30123
- if (await pathExists11(path56.join(mancodeDir, "schema.json"))) {
30851
+ async function refreshProject(rootDir = process9.cwd()) {
30852
+ const mancodeDir = path58.join(rootDir, ".mancode");
30853
+ const statePath = path58.join(mancodeDir, "state.json");
30854
+ if (await pathExists11(path58.join(mancodeDir, "schema.json"))) {
30124
30855
  return refreshV3Project(rootDir);
30125
30856
  }
30126
30857
  if (!await pathExists11(statePath)) {
30127
30858
  console.error("\u2717 mancode not initialized.");
30128
30859
  console.error(" Run `mancode init` first.");
30129
- return EXIT_NOT_INITIALIZED3;
30860
+ return EXIT_NOT_INITIALIZED4;
30130
30861
  }
30131
30862
  const state = await readRequiredState(statePath);
30132
30863
  if (!state) {
@@ -30139,12 +30870,12 @@ async function refreshProject(rootDir = process8.cwd()) {
30139
30870
  const [profile, team, hasGit, hasManifest] = await Promise.all([
30140
30871
  detectProjectProfile(rootDir),
30141
30872
  detectTeamStatus(rootDir),
30142
- pathExists11(path56.join(rootDir, ".git")),
30873
+ pathExists11(path58.join(rootDir, ".git")),
30143
30874
  hasProjectManifest2(rootDir)
30144
30875
  ]);
30145
30876
  const uiLibrary = primaryUiLibrary(profile);
30146
30877
  const stack = [...profile.languages, ...profile.frameworks];
30147
- const config = await readJson2(path56.join(mancodeDir, "config.json"));
30878
+ const config = await readJson2(path58.join(mancodeDir, "config.json"));
30148
30879
  const configuredTeam = config.forceTeamMode === true ? true : config.teamMode === "on" ? true : config.teamMode === "off" ? false : team.isTeam;
30149
30880
  const nextState = {
30150
30881
  ...state,
@@ -30156,7 +30887,7 @@ async function refreshProject(rootDir = process8.cwd()) {
30156
30887
  };
30157
30888
  await writeProjectFacts2(
30158
30889
  statePath,
30159
- path56.join(mancodeDir, "project-profile.json"),
30890
+ path58.join(mancodeDir, "project-profile.json"),
30160
30891
  `${JSON.stringify(nextState, null, 2)}
30161
30892
  `,
30162
30893
  `${JSON.stringify(profile, null, 2)}
@@ -30184,7 +30915,7 @@ async function refreshProject(rootDir = process8.cwd()) {
30184
30915
  console.log(
30185
30916
  " Run `mancode refresh-style` if UI files or dependencies changed."
30186
30917
  );
30187
- return EXIT_OK6;
30918
+ return EXIT_OK7;
30188
30919
  } catch (error) {
30189
30920
  const message = error instanceof Error ? error.message : String(error);
30190
30921
  console.error(`\u2717 Project refresh failed: ${message}`);
@@ -30214,7 +30945,7 @@ async function refreshV3Project(rootDir) {
30214
30945
  console.log(
30215
30946
  " mancode adapters remain unchanged because their bootstrap is static."
30216
30947
  );
30217
- return EXIT_OK6;
30948
+ return EXIT_OK7;
30218
30949
  } catch (error) {
30219
30950
  const message = error instanceof Error ? error.message : String(error);
30220
30951
  console.error(`\u2717 mancode project facts refresh failed: ${message}`);
@@ -30223,7 +30954,7 @@ async function refreshV3Project(rootDir) {
30223
30954
  }
30224
30955
  async function hasProjectManifest2(rootDir) {
30225
30956
  for (const manifest of PROJECT_MANIFESTS) {
30226
- if (await pathExists11(path56.join(rootDir, manifest))) return true;
30957
+ if (await pathExists11(path58.join(rootDir, manifest))) return true;
30227
30958
  }
30228
30959
  return false;
30229
30960
  }
@@ -30289,9 +31020,9 @@ async function readOptionalText(filePath) {
30289
31020
  }
30290
31021
  }
30291
31022
  function temporaryPath(filePath) {
30292
- return path56.join(
30293
- path56.dirname(filePath),
30294
- `.${path56.basename(filePath)}.${process8.pid}.${randomUUID()}.tmp`
31023
+ return path58.join(
31024
+ path58.dirname(filePath),
31025
+ `.${path58.basename(filePath)}.${process9.pid}.${randomUUID()}.tmp`
30295
31026
  );
30296
31027
  }
30297
31028
  async function refreshStaticPlatforms(rootDir, config, fallbackPlatform, stack, uiLibrary, profile) {
@@ -30320,14 +31051,14 @@ function configuredPlatforms(config, fallbackPlatform) {
30320
31051
  );
30321
31052
  }
30322
31053
  function platformIsMinimal(config, platform) {
30323
- if (!isRecord10(config.platformOptions)) return false;
31054
+ if (!isRecord11(config.platformOptions)) return false;
30324
31055
  const options = config.platformOptions[platform];
30325
- return isRecord10(options) && options.minimal === true;
31056
+ return isRecord11(options) && options.minimal === true;
30326
31057
  }
30327
31058
  async function readJson2(filePath) {
30328
31059
  try {
30329
31060
  const value = JSON.parse(await fs7.readFile(filePath, "utf-8"));
30330
- return isRecord10(value) ? value : {};
31061
+ return isRecord11(value) ? value : {};
30331
31062
  } catch {
30332
31063
  return {};
30333
31064
  }
@@ -30337,14 +31068,14 @@ async function readRequiredState(filePath) {
30337
31068
  try {
30338
31069
  const raw = await fs7.readFile(filePath, "utf-8");
30339
31070
  const parsed = JSON.parse(raw);
30340
- if (!isRecord10(parsed)) return null;
31071
+ if (!isRecord11(parsed)) return null;
30341
31072
  state = parsed;
30342
31073
  } catch {
30343
31074
  return null;
30344
31075
  }
30345
31076
  return typeof state.version === "string" && typeof state.currentMode === "string" && typeof state.platform === "string" ? state : null;
30346
31077
  }
30347
- function isRecord10(value) {
31078
+ function isRecord11(value) {
30348
31079
  return typeof value === "object" && value !== null && !Array.isArray(value);
30349
31080
  }
30350
31081
  function isNodeError9(error) {
@@ -30361,52 +31092,62 @@ async function pathExists11(filePath) {
30361
31092
 
30362
31093
  // src/commands/refresh-style.ts
30363
31094
  import { promises as fs8 } from "fs";
30364
- import path57 from "path";
30365
- import process9 from "process";
30366
- var EXIT_OK7 = 0;
30367
- var EXIT_NOT_INITIALIZED4 = 1;
31095
+ import path59 from "path";
31096
+ import process10 from "process";
31097
+ var EXIT_OK8 = 0;
31098
+ var EXIT_NOT_INITIALIZED5 = 1;
30368
31099
  var EXIT_V3_REFRESH_FAILED = 2;
30369
- async function refreshStyle(rootDir = process9.cwd()) {
30370
- const stateFile = path57.join(rootDir, ".mancode", "state.json");
30371
- if (await pathExists12(path57.join(rootDir, ".mancode", "schema.json"))) {
30372
- return refreshV3Style(rootDir);
31100
+ async function refreshStyle(rootDir = process10.cwd(), options = {}) {
31101
+ const scanTarget = await resolveScanTarget(rootDir, options.root);
31102
+ if (scanTarget === null) {
31103
+ console.error("\u2717 style scan root must stay inside the project root.");
31104
+ return EXIT_V3_REFRESH_FAILED;
31105
+ }
31106
+ const stateFile = path59.join(rootDir, ".mancode", "state.json");
31107
+ if (await pathExists12(path59.join(rootDir, ".mancode", "schema.json"))) {
31108
+ return refreshV3Style(rootDir, scanTarget.root, scanTarget.scopeRoot);
30373
31109
  }
30374
31110
  if (!await pathExists12(stateFile)) {
30375
31111
  console.error("\u2717 mancode not initialized.");
30376
31112
  console.error(" Run `mancode init` first.");
30377
- return EXIT_NOT_INITIALIZED4;
31113
+ return EXIT_NOT_INITIALIZED5;
30378
31114
  }
30379
31115
  console.log("\u2713 \u5237\u65B0\u9879\u76EE profile...");
30380
31116
  const profile = await detectProjectProfile(rootDir);
30381
- const profilePath = path57.join(rootDir, ".mancode", "project-profile.json");
31117
+ const profilePath = path59.join(rootDir, ".mancode", "project-profile.json");
30382
31118
  await fs8.writeFile(
30383
31119
  profilePath,
30384
31120
  `${JSON.stringify(profile, null, 2)}
30385
31121
  `,
30386
31122
  "utf-8"
30387
31123
  );
30388
- const uiLibraryHint = primaryUiLibrary(profile);
31124
+ const scanProfile = scanTarget.scopeRoot === "." ? profile : await detectProjectProfile(scanTarget.root);
31125
+ const uiLibraryHint = primaryUiLibrary(scanProfile);
30389
31126
  await refreshLegacyStateContext(rootDir, profile, uiLibraryHint);
30390
31127
  console.log(
30391
31128
  ` \u7C7B\u578B: ${profile.projectKind} | UI: ${profile.uiAssets} | \u6D4F\u89C8\u5668: ${profile.browserAutomation}`
30392
31129
  );
30393
- if (profile.uiAssets !== "detected") {
31130
+ if (scanProfile.uiAssets !== "detected") {
30394
31131
  console.log(
30395
31132
  "\u2139\uFE0F No UI assets detected in project profile. Skipping style scan."
30396
31133
  );
30397
31134
  console.log(" Updated .mancode/project-profile.json.");
30398
31135
  await printStaticPlatformRefreshHint(rootDir);
30399
- return EXIT_OK7;
31136
+ return EXIT_OK8;
30400
31137
  }
30401
31138
  console.log("\u2713 \u626B\u63CF\u9879\u76EE\u8BBE\u8BA1 token...");
30402
- const tokens = await scanAesthetics(rootDir, uiLibraryHint);
30403
- const tokensPath = path57.join(
31139
+ const tokens = await scanAesthetics(
31140
+ scanTarget.root,
31141
+ uiLibraryHint,
31142
+ scanTarget.scopeRoot
31143
+ );
31144
+ const tokensPath = path59.join(
30404
31145
  rootDir,
30405
31146
  ".mancode",
30406
31147
  "aesthetics",
30407
31148
  "style-tokens.json"
30408
31149
  );
30409
- await fs8.mkdir(path57.dirname(tokensPath), { recursive: true });
31150
+ await fs8.mkdir(path59.dirname(tokensPath), { recursive: true });
30410
31151
  await fs8.writeFile(
30411
31152
  tokensPath,
30412
31153
  `${JSON.stringify(tokens, null, 2)}
@@ -30419,7 +31160,7 @@ async function refreshStyle(rootDir = process9.cwd()) {
30419
31160
  "\u5DF2\u66F4\u65B0 .mancode/project-profile.json \u548C .mancode/aesthetics/style-tokens.json"
30420
31161
  );
30421
31162
  await printStaticPlatformRefreshHint(rootDir);
30422
- return EXIT_OK7;
31163
+ return EXIT_OK8;
30423
31164
  }
30424
31165
  function printAestheticsSummary(tokens) {
30425
31166
  console.log("");
@@ -30460,7 +31201,7 @@ function printAestheticsSummary(tokens) {
30460
31201
  console.log(` \u5339\u914D\u5EA6: ${tokens.matchLevel}`);
30461
31202
  }
30462
31203
  }
30463
- async function refreshV3Style(rootDir) {
31204
+ async function refreshV3Style(rootDir, scanRoot, scopeRoot) {
30464
31205
  try {
30465
31206
  const project = await new V3ContextStore(rootDir).readProjectSnapshot();
30466
31207
  if (project.manifest.activationState !== "v3_active") {
@@ -30468,7 +31209,8 @@ async function refreshV3Style(rootDir) {
30468
31209
  }
30469
31210
  console.log("\u2713 \u5237\u65B0 mancode \u9879\u76EE profile...");
30470
31211
  const profile = await detectProjectProfile(rootDir);
30471
- const uiLibraryHint = primaryUiLibrary(profile);
31212
+ const scanProfile = scopeRoot === "." ? profile : await detectProjectProfile(scanRoot);
31213
+ const uiLibraryHint = primaryUiLibrary(scanProfile);
30472
31214
  await writeProjectFacts(
30473
31215
  rootDir,
30474
31216
  createProjectFacts(profile, {
@@ -30478,24 +31220,24 @@ async function refreshV3Style(rootDir) {
30478
31220
  console.log(
30479
31221
  ` \u7C7B\u578B: ${profile.projectKind} | UI: ${profile.uiAssets} | \u6D4F\u89C8\u5668: ${profile.browserAutomation}`
30480
31222
  );
30481
- const tokensPath = path57.join(
31223
+ const tokensPath = path59.join(
30482
31224
  rootDir,
30483
31225
  ".mancode",
30484
31226
  "local",
30485
31227
  "cache",
30486
31228
  "style-tokens.json"
30487
31229
  );
30488
- if (profile.uiAssets !== "detected") {
31230
+ if (scanProfile.uiAssets !== "detected") {
30489
31231
  await fs8.rm(tokensPath, { force: true });
30490
31232
  console.log(
30491
31233
  "\u2139\uFE0F No UI assets detected in project profile. Skipping style scan."
30492
31234
  );
30493
31235
  console.log(" Updated mancode project facts.");
30494
- return EXIT_OK7;
31236
+ return EXIT_OK8;
30495
31237
  }
30496
31238
  console.log("\u2713 \u626B\u63CF\u9879\u76EE\u8BBE\u8BA1 token...");
30497
- const tokens = await scanAesthetics(rootDir, uiLibraryHint);
30498
- await fs8.mkdir(path57.dirname(tokensPath), { recursive: true });
31239
+ const tokens = await scanAesthetics(scanRoot, uiLibraryHint, scopeRoot);
31240
+ await fs8.mkdir(path59.dirname(tokensPath), { recursive: true });
30499
31241
  await fs8.writeFile(
30500
31242
  tokensPath,
30501
31243
  `${JSON.stringify(tokens, null, 2)}
@@ -30507,7 +31249,7 @@ async function refreshV3Style(rootDir) {
30507
31249
  console.log(
30508
31250
  "\u5DF2\u66F4\u65B0 .mancode/shared/context/project.json \u548C .mancode/local/cache/style-tokens.json"
30509
31251
  );
30510
- return EXIT_OK7;
31252
+ return EXIT_OK8;
30511
31253
  } catch (error) {
30512
31254
  const message = error instanceof Error ? error.message : String(error);
30513
31255
  console.error(`\u2717 mancode style refresh failed: ${message}`);
@@ -30529,7 +31271,7 @@ async function printStaticPlatformRefreshHint(rootDir) {
30529
31271
  );
30530
31272
  }
30531
31273
  async function refreshLegacyStateContext(rootDir, profile, uiLibrary) {
30532
- const statePath = path57.join(rootDir, ".mancode", "state.json");
31274
+ const statePath = path59.join(rootDir, ".mancode", "state.json");
30533
31275
  try {
30534
31276
  const state = JSON.parse(await fs8.readFile(statePath, "utf-8"));
30535
31277
  const stack = [...profile.languages, ...profile.frameworks];
@@ -30553,7 +31295,7 @@ async function refreshLegacyStateContext(rootDir, profile, uiLibrary) {
30553
31295
  async function readInstalledPlatforms2(rootDir) {
30554
31296
  try {
30555
31297
  const raw = await fs8.readFile(
30556
- path57.join(rootDir, ".mancode", "config.json"),
31298
+ path59.join(rootDir, ".mancode", "config.json"),
30557
31299
  "utf-8"
30558
31300
  );
30559
31301
  const config = JSON.parse(raw);
@@ -30572,12 +31314,32 @@ async function pathExists12(p) {
30572
31314
  return false;
30573
31315
  }
30574
31316
  }
31317
+ async function resolveScanTarget(rootDir, requestedRoot) {
31318
+ const projectRoot = await fs8.realpath(path59.resolve(rootDir)).catch(() => null);
31319
+ if (projectRoot === null) return null;
31320
+ if (requestedRoot === void 0 || requestedRoot === ".") {
31321
+ return { root: projectRoot, scopeRoot: "." };
31322
+ }
31323
+ if (path59.isAbsolute(requestedRoot) || requestedRoot.includes("\0") || requestedRoot.split(/[\\/]/).some((segment) => segment === "" || segment === "." || segment === "..")) {
31324
+ return null;
31325
+ }
31326
+ const candidate = await fs8.realpath(path59.resolve(projectRoot, requestedRoot)).catch(() => null);
31327
+ if (candidate === null) return null;
31328
+ const relative = path59.relative(projectRoot, candidate);
31329
+ if (relative.startsWith(`..${path59.sep}`) || relative === ".." || path59.isAbsolute(relative)) {
31330
+ return null;
31331
+ }
31332
+ return {
31333
+ root: candidate,
31334
+ scopeRoot: relative.split(path59.sep).join("/") || "."
31335
+ };
31336
+ }
30575
31337
 
30576
31338
  // src/commands/status.ts
30577
31339
  import { spawn } from "child_process";
30578
31340
  import { promises as fs9 } from "fs";
30579
- import path58 from "path";
30580
- import process10 from "process";
31341
+ import path60 from "path";
31342
+ import process11 from "process";
30581
31343
 
30582
31344
  // src/team/assessment.ts
30583
31345
  function assessTeam(input) {
@@ -30728,19 +31490,19 @@ function assertTimestamp3(value) {
30728
31490
 
30729
31491
  // src/commands/status.ts
30730
31492
  var HOOK_ESTIMATE_TIMEOUT_MS = 2e3;
30731
- var EXIT_OK8 = 0;
30732
- var EXIT_NOT_INITIALIZED5 = 1;
31493
+ var EXIT_OK9 = 0;
31494
+ var EXIT_NOT_INITIALIZED6 = 1;
30733
31495
  var EXIT_CORRUPT_STATE2 = 2;
30734
- async function status(rootDir = process10.cwd(), options = {}) {
30735
- const stateFile = path58.join(rootDir, ".mancode", "state.json");
30736
- const v3SchemaFile = path58.join(rootDir, ".mancode", "schema.json");
31496
+ async function status(rootDir = process11.cwd(), options = {}) {
31497
+ const stateFile = path60.join(rootDir, ".mancode", "state.json");
31498
+ const v3SchemaFile = path60.join(rootDir, ".mancode", "schema.json");
30737
31499
  if (await pathExists13(v3SchemaFile)) {
30738
31500
  return statusV3(rootDir, options);
30739
31501
  }
30740
31502
  if (!await pathExists13(stateFile)) {
30741
31503
  console.error("\u2717 mancode not initialized.");
30742
31504
  console.error(" Run `mancode init` to get started.");
30743
- return EXIT_NOT_INITIALIZED5;
31505
+ return EXIT_NOT_INITIALIZED6;
30744
31506
  }
30745
31507
  let state;
30746
31508
  try {
@@ -30797,7 +31559,7 @@ async function status(rootDir = process10.cwd(), options = {}) {
30797
31559
  } else {
30798
31560
  printText(result2);
30799
31561
  }
30800
- return EXIT_OK8;
31562
+ return EXIT_OK9;
30801
31563
  }
30802
31564
  async function statusV3(rootDir, options) {
30803
31565
  try {
@@ -30938,7 +31700,7 @@ async function statusV3(rootDir, options) {
30938
31700
  } else {
30939
31701
  printV3Text(result2);
30940
31702
  }
30941
- return EXIT_OK8;
31703
+ return EXIT_OK9;
30942
31704
  } catch (error) {
30943
31705
  const message = error instanceof Error ? error.message : String(error);
30944
31706
  console.error("\u2717 .mancode/schema.json is corrupt or incomplete.");
@@ -30967,7 +31729,7 @@ function toContinuityStatus(result2) {
30967
31729
  };
30968
31730
  }
30969
31731
  async function readV3StatusSession(rootDir) {
30970
- const sessionId = process10.env.MANCODE_SESSION_ID;
31732
+ const sessionId = process11.env.MANCODE_SESSION_ID;
30971
31733
  if (sessionId === void 0 || !sessionId) return null;
30972
31734
  try {
30973
31735
  assertUlid(sessionId, "status sessionId");
@@ -30978,10 +31740,10 @@ async function readV3StatusSession(rootDir) {
30978
31740
  }
30979
31741
  async function shouldRefreshProject(rootDir, state) {
30980
31742
  if (state.projectMode !== "generic") return false;
30981
- const hasGit = await pathExists13(path58.join(rootDir, ".git"));
31743
+ const hasGit = await pathExists13(path60.join(rootDir, ".git"));
30982
31744
  if (hasGit) return true;
30983
31745
  for (const manifest of PROJECT_MANIFESTS) {
30984
- if (await pathExists13(path58.join(rootDir, manifest))) return true;
31746
+ if (await pathExists13(path60.join(rootDir, manifest))) return true;
30985
31747
  }
30986
31748
  return false;
30987
31749
  }
@@ -31025,19 +31787,19 @@ async function getCurrentWorkflow(rootDir, taskId) {
31025
31787
  }
31026
31788
  async function getProjectName(rootDir) {
31027
31789
  try {
31028
- const raw = await fs9.readFile(path58.join(rootDir, "package.json"), "utf-8");
31790
+ const raw = await fs9.readFile(path60.join(rootDir, "package.json"), "utf-8");
31029
31791
  const pkg = JSON.parse(raw);
31030
31792
  if (pkg.name && typeof pkg.name === "string") {
31031
31793
  return pkg.name;
31032
31794
  }
31033
31795
  } catch {
31034
31796
  }
31035
- return path58.basename(rootDir);
31797
+ return path60.basename(rootDir);
31036
31798
  }
31037
31799
  async function readConfig3(rootDir) {
31038
31800
  try {
31039
31801
  const raw = await fs9.readFile(
31040
- path58.join(rootDir, ".mancode", "config.json"),
31802
+ path60.join(rootDir, ".mancode", "config.json"),
31041
31803
  "utf-8"
31042
31804
  );
31043
31805
  return JSON.parse(raw);
@@ -31065,9 +31827,9 @@ function getEffectiveTeamStatus(state, config, detected) {
31065
31827
  }
31066
31828
  async function checkHooks(rootDir) {
31067
31829
  const [sessionStart, userPromptSubmit, registered] = await Promise.all([
31068
- pathExists13(path58.join(rootDir, ".mancode", "hooks", "session-start.mjs")),
31830
+ pathExists13(path60.join(rootDir, ".mancode", "hooks", "session-start.mjs")),
31069
31831
  pathExists13(
31070
- path58.join(rootDir, ".mancode", "hooks", "user-prompt-submit.mjs")
31832
+ path60.join(rootDir, ".mancode", "hooks", "user-prompt-submit.mjs")
31071
31833
  ),
31072
31834
  isRegistered(rootDir)
31073
31835
  ]);
@@ -31076,7 +31838,7 @@ async function checkHooks(rootDir) {
31076
31838
  async function isRegistered(rootDir) {
31077
31839
  try {
31078
31840
  const raw = await fs9.readFile(
31079
- path58.join(rootDir, ".claude", "settings.json"),
31841
+ path60.join(rootDir, ".claude", "settings.json"),
31080
31842
  "utf-8"
31081
31843
  );
31082
31844
  const settings = JSON.parse(raw);
@@ -31086,9 +31848,9 @@ async function isRegistered(rootDir) {
31086
31848
  }
31087
31849
  }
31088
31850
  function hooksRegistered2(settings) {
31089
- if (!isRecord11(settings)) return false;
31851
+ if (!isRecord12(settings)) return false;
31090
31852
  const hooks = settings.hooks;
31091
- if (!isRecord11(hooks)) return false;
31853
+ if (!isRecord12(hooks)) return false;
31092
31854
  return hasHookCommand2(hooks.SessionStart, ".mancode/hooks/session-start.mjs") && hasHookCommand2(
31093
31855
  hooks.UserPromptSubmit,
31094
31856
  ".mancode/hooks/user-prompt-submit.mjs"
@@ -31097,15 +31859,15 @@ function hooksRegistered2(settings) {
31097
31859
  function hasHookCommand2(value, needle) {
31098
31860
  if (!Array.isArray(value)) return false;
31099
31861
  return value.some((group) => {
31100
- if (!isRecord11(group) || !Array.isArray(group.hooks)) return false;
31862
+ if (!isRecord12(group) || !Array.isArray(group.hooks)) return false;
31101
31863
  return group.hooks.some((hook) => {
31102
- if (!isRecord11(hook) || typeof hook.command !== "string") return false;
31864
+ if (!isRecord12(hook) || typeof hook.command !== "string") return false;
31103
31865
  return hook.command.includes(needle);
31104
31866
  });
31105
31867
  });
31106
31868
  }
31107
31869
  async function estimateHookInjection(rootDir) {
31108
- const hookPath = path58.join(
31870
+ const hookPath = path60.join(
31109
31871
  rootDir,
31110
31872
  ".mancode",
31111
31873
  "hooks",
@@ -31126,7 +31888,7 @@ async function estimateHookInjection(rootDir) {
31126
31888
  }
31127
31889
  function runHookEstimate(rootDir, hookPath) {
31128
31890
  return new Promise((resolve, reject) => {
31129
- const child = spawn(process10.execPath, [hookPath], {
31891
+ const child = spawn(process11.execPath, [hookPath], {
31130
31892
  cwd: rootDir,
31131
31893
  stdio: ["pipe", "pipe", "ignore"]
31132
31894
  });
@@ -31324,7 +32086,7 @@ function formatTeamStatus(team) {
31324
32086
  function workflowStepMax(mode) {
31325
32087
  return maxWorkflowStep(mode);
31326
32088
  }
31327
- function isRecord11(value) {
32089
+ function isRecord12(value) {
31328
32090
  return typeof value === "object" && value !== null;
31329
32091
  }
31330
32092
  async function pathExists13(p) {
@@ -32602,8 +33364,8 @@ function assertPositiveRevision2(value, label) {
32602
33364
  }
32603
33365
 
32604
33366
  // src/team/git-ref-handoff-repair.ts
32605
- import { lstat as lstat22, mkdir as mkdir36, readFile as readFile41, readdir as readdir19, writeFile as writeFile41 } from "fs/promises";
32606
- import path59 from "path";
33367
+ import { lstat as lstat23, mkdir as mkdir37, readFile as readFile43, readdir as readdir19, writeFile as writeFile42 } from "fs/promises";
33368
+ import path61 from "path";
32607
33369
 
32608
33370
  // src/team/git-ref-operation.ts
32609
33371
  import { execFile as execFileCallback6 } from "child_process";
@@ -32739,7 +33501,7 @@ function openMutationContext(manifest, input) {
32739
33501
  }
32740
33502
  function prepareOwnershipFence(context, taskBundle, expectedPredecessorBundleDigest) {
32741
33503
  const metadata = metadataFromBundle2(taskBundle);
32742
- assertRemoteTaskEligible(metadata);
33504
+ assertRemoteTaskCoordination(metadata);
32743
33505
  assertTaskBundleIdentity(taskBundle, context.taskRef);
32744
33506
  if (metadata.ownerActorId === null) {
32745
33507
  throw new Error("MANCODE_TASK_OWNER_REQUIRED");
@@ -32748,6 +33510,7 @@ function prepareOwnershipFence(context, taskBundle, expectedPredecessorBundleDig
32748
33510
  throw new Error("MANCODE_TASK_BUNDLE_DIVERGED");
32749
33511
  }
32750
33512
  if (context.fence === null) {
33513
+ assertRemoteTaskEligible(metadata);
32751
33514
  if (metadata.ownerActorId !== context.input.actorId || metadata.ownershipEpoch !== 0 || taskBundle.ownershipEpoch !== 0) {
32752
33515
  throw new Error("MANCODE_TASK_OWNER_REQUIRED");
32753
33516
  }
@@ -32760,6 +33523,7 @@ function prepareOwnershipFence(context, taskBundle, expectedPredecessorBundleDig
32760
33523
  throw new Error("MANCODE_TASK_REVISION_CONFLICT");
32761
33524
  }
32762
33525
  if (taskBundle.taskRevision === context.fence.taskRevision) {
33526
+ assertRemoteTaskRebindEligible(metadata);
32763
33527
  if (taskBundle.aggregateDigest !== context.fence.aggregateDigest) {
32764
33528
  throw new Error("MANCODE_SPLIT_BRAIN");
32765
33529
  }
@@ -32774,6 +33538,7 @@ function prepareOwnershipFence(context, taskBundle, expectedPredecessorBundleDig
32774
33538
  taskBundle
32775
33539
  );
32776
33540
  }
33541
+ assertRemoteTaskEligible(metadata);
32777
33542
  }
32778
33543
  const codeHeadChanged = context.taskBundle !== null && (taskBundle.codeRef.branch !== context.taskBundle.codeRef.branch || taskBundle.codeRef.head !== context.taskBundle.codeRef.head);
32779
33544
  const fence = buildFence(context, taskBundle, metadata.ownerActorId);
@@ -33372,7 +34137,19 @@ function metadataFromBundle2(taskBundle) {
33372
34137
  return metadata;
33373
34138
  }
33374
34139
  function assertRemoteTaskEligible(metadata) {
33375
- if (metadata.workflowMode !== "manteam" || metadata.coordination !== "team" || metadata.status !== "in_progress") {
34140
+ assertRemoteTaskCoordination(metadata);
34141
+ if (metadata.status !== "in_progress") {
34142
+ throw new Error("MANCODE_REMOTE_COORDINATION_TASK_INVALID");
34143
+ }
34144
+ }
34145
+ function assertRemoteTaskRebindEligible(metadata) {
34146
+ assertRemoteTaskCoordination(metadata);
34147
+ if (metadata.status !== "in_progress" && metadata.status !== "blocked") {
34148
+ throw new Error("MANCODE_REMOTE_COORDINATION_TASK_INVALID");
34149
+ }
34150
+ }
34151
+ function assertRemoteTaskCoordination(metadata) {
34152
+ if (metadata.workflowMode !== "manteam" || metadata.coordination !== "team") {
33376
34153
  throw new Error("MANCODE_REMOTE_COORDINATION_TASK_INVALID");
33377
34154
  }
33378
34155
  }
@@ -35166,7 +35943,7 @@ async function recoverGitRefHandoffRepairs(projectRoot) {
35166
35943
  }
35167
35944
  async function recoverGitRefHandoffRepair(projectRoot, operationId, transportReceipt) {
35168
35945
  assertUlid(operationId, "git-ref handoff repair operationId");
35169
- const root = path59.resolve(projectRoot);
35946
+ const root = path61.resolve(projectRoot);
35170
35947
  let journal = await requireJournal2(root, operationId);
35171
35948
  if (journal.state === "committed" || journal.state === "aborted") {
35172
35949
  return recoveryResult2(journal);
@@ -35245,7 +36022,7 @@ async function recoverGitRefHandoffRepair(projectRoot, operationId, transportRec
35245
36022
  }
35246
36023
  }
35247
36024
  async function prepareHandoffRepairWhileTaskLocked(projectRoot, rawPrepared) {
35248
- const root = path59.resolve(projectRoot);
36025
+ const root = path61.resolve(projectRoot);
35249
36026
  const prepared2 = parsePrepared2(rawPrepared);
35250
36027
  const runtime = await readProjectRuntimeContext(root);
35251
36028
  const previousMetadata = bundleMetadata2(prepared2.predecessorBundle);
@@ -35308,7 +36085,7 @@ async function restorePredecessorMetadata2(projectRoot, journal) {
35308
36085
  );
35309
36086
  }
35310
36087
  async function replaceMetadataVerified(projectRoot, expected, targetMetadata, alternateExpected) {
35311
- const target = path59.join(
36088
+ const target = path61.join(
35312
36089
  taskRootPath(projectRoot, targetMetadata.taskRef),
35313
36090
  "metadata.json"
35314
36091
  );
@@ -35434,7 +36211,7 @@ async function createJournal3(projectRoot, journal) {
35434
36211
  await ensureJournalDirectory2(projectRoot);
35435
36212
  const target = journalPath3(projectRoot, journal.operationId);
35436
36213
  try {
35437
- await writeFile41(target, serialize13(journal), {
36214
+ await writeFile42(target, serialize13(journal), {
35438
36215
  encoding: "utf8",
35439
36216
  flag: "wx"
35440
36217
  });
@@ -35453,10 +36230,10 @@ async function replaceJournal3(projectRoot, journal) {
35453
36230
  async function requireJournal2(projectRoot, operationId) {
35454
36231
  try {
35455
36232
  return parseJournal3(
35456
- JSON.parse(await readFile41(journalPath3(projectRoot, operationId), "utf8"))
36233
+ JSON.parse(await readFile43(journalPath3(projectRoot, operationId), "utf8"))
35457
36234
  );
35458
36235
  } catch (error) {
35459
- if (error instanceof SyntaxError || isNotFound29(error)) {
36236
+ if (error instanceof SyntaxError || isNotFound30(error)) {
35460
36237
  throw new Error("MANCODE_HANDOFF_REPAIR_JOURNAL_NOT_FOUND");
35461
36238
  }
35462
36239
  throw error;
@@ -35467,7 +36244,7 @@ async function listJournals2(projectRoot) {
35467
36244
  try {
35468
36245
  entries = await readdir19(journalDirectory2(projectRoot));
35469
36246
  } catch (error) {
35470
- if (isNotFound29(error)) return [];
36247
+ if (isNotFound30(error)) return [];
35471
36248
  throw error;
35472
36249
  }
35473
36250
  const journals = [];
@@ -35476,8 +36253,8 @@ async function listJournals2(projectRoot) {
35476
36253
  journals.push(
35477
36254
  parseJournal3(
35478
36255
  JSON.parse(
35479
- await readFile41(
35480
- path59.join(journalDirectory2(projectRoot), entry),
36256
+ await readFile43(
36257
+ path61.join(journalDirectory2(projectRoot), entry),
35481
36258
  "utf8"
35482
36259
  )
35483
36260
  )
@@ -35487,43 +36264,43 @@ async function listJournals2(projectRoot) {
35487
36264
  return journals;
35488
36265
  }
35489
36266
  async function readSafeFile2(target) {
35490
- const before = await lstat22(target);
36267
+ const before = await lstat23(target);
35491
36268
  if (!before.isFile() || before.isSymbolicLink()) {
35492
36269
  throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
35493
36270
  }
35494
- const content = await readFile41(target, "utf8");
35495
- const after = await lstat22(target);
36271
+ const content = await readFile43(target, "utf8");
36272
+ const after = await lstat23(target);
35496
36273
  if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
35497
36274
  throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
35498
36275
  }
35499
36276
  return content;
35500
36277
  }
35501
36278
  async function atomicWrite2(target, content) {
35502
- const temporary = path59.join(
35503
- path59.dirname(target),
35504
- `.${path59.basename(target)}.${process.pid}.${Date.now()}.tmp`
36279
+ const temporary = path61.join(
36280
+ path61.dirname(target),
36281
+ `.${path61.basename(target)}.${process.pid}.${Date.now()}.tmp`
35505
36282
  );
35506
- await writeFile41(temporary, content, { encoding: "utf8", flag: "wx" });
36283
+ await writeFile42(temporary, content, { encoding: "utf8", flag: "wx" });
35507
36284
  await replaceFileAtomically(temporary, target);
35508
36285
  }
35509
36286
  async function ensureJournalDirectory2(projectRoot) {
35510
- let current = path59.resolve(projectRoot);
36287
+ let current = path61.resolve(projectRoot);
35511
36288
  for (const segment of [".mancode", "local", "journals", "git-ref-handoff"]) {
35512
- current = path59.join(current, segment);
36289
+ current = path61.join(current, segment);
35513
36290
  try {
35514
- await mkdir36(current);
36291
+ await mkdir37(current);
35515
36292
  } catch (error) {
35516
36293
  if (!isAlreadyExists24(error)) throw error;
35517
36294
  }
35518
- const entry = await lstat22(current);
36295
+ const entry = await lstat23(current);
35519
36296
  if (!entry.isDirectory() || entry.isSymbolicLink()) {
35520
36297
  throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
35521
36298
  }
35522
36299
  }
35523
36300
  }
35524
36301
  function journalDirectory2(projectRoot) {
35525
- return path59.join(
35526
- path59.resolve(projectRoot),
36302
+ return path61.join(
36303
+ path61.resolve(projectRoot),
35527
36304
  ".mancode",
35528
36305
  "local",
35529
36306
  "journals",
@@ -35532,7 +36309,7 @@ function journalDirectory2(projectRoot) {
35532
36309
  }
35533
36310
  function journalPath3(projectRoot, operationId) {
35534
36311
  assertUlid(operationId, "git-ref handoff repair operationId");
35535
- return path59.join(journalDirectory2(projectRoot), `${operationId}.json`);
36312
+ return path61.join(journalDirectory2(projectRoot), `${operationId}.json`);
35536
36313
  }
35537
36314
  function serialize13(value) {
35538
36315
  return `${JSON.stringify(value, null, 2)}
@@ -35547,7 +36324,7 @@ function parseTimestamp15(value) {
35547
36324
  function isAlreadyExists24(error) {
35548
36325
  return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
35549
36326
  }
35550
- function isNotFound29(error) {
36327
+ function isNotFound30(error) {
35551
36328
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
35552
36329
  }
35553
36330
 
@@ -35631,8 +36408,8 @@ function parseReceipt(value) {
35631
36408
  }
35632
36409
 
35633
36410
  // src/team/policy-operation.ts
35634
- import { lstat as lstat23, mkdir as mkdir37, readdir as readdir20, unlink as unlink3, writeFile as writeFile42 } from "fs/promises";
35635
- import path60 from "path";
36411
+ import { lstat as lstat24, mkdir as mkdir38, readdir as readdir20, unlink as unlink3, writeFile as writeFile43 } from "fs/promises";
36412
+ import path62 from "path";
35636
36413
  async function updateTeamPolicy(input) {
35637
36414
  const operationId = input.operationId ?? createUlid();
35638
36415
  const eventId = createUlid();
@@ -35643,7 +36420,7 @@ async function updateTeamPolicy(input) {
35643
36420
  throw new Error("MANCODE_TEAM_POLICY_INVALID");
35644
36421
  }
35645
36422
  const now = input.now ?? /* @__PURE__ */ new Date();
35646
- const root = path60.resolve(input.projectRoot);
36423
+ const root = path62.resolve(input.projectRoot);
35647
36424
  const runtime = await readProjectRuntimeContext(root);
35648
36425
  const store = resolveCoordinationEntityHomeStore(
35649
36426
  runtime.entityHomeStoreContext
@@ -35724,7 +36501,7 @@ async function applyTeamTransportSet(input, write2) {
35724
36501
  }
35725
36502
  const remote = transportRemote(input.mode, input.remote);
35726
36503
  const now = input.now ?? /* @__PURE__ */ new Date();
35727
- const root = path60.resolve(input.projectRoot);
36504
+ const root = path62.resolve(input.projectRoot);
35728
36505
  const runtime = await readProjectRuntimeContext(root);
35729
36506
  const store = resolveCoordinationEntityHomeStore(
35730
36507
  runtime.entityHomeStoreContext
@@ -35857,9 +36634,9 @@ async function assertTransportAuthorityEmpty(projectRoot, store) {
35857
36634
  listClaims(store),
35858
36635
  listHandoffs(store),
35859
36636
  directoryHasEntries(taskHeadDirectory(store)),
35860
- directoryHasEntries(path60.join(store.root, "transport-migrations")),
36637
+ directoryHasEntries(path62.join(store.root, "transport-migrations")),
35861
36638
  directoryHasEntries(
35862
- path60.join(projectRoot, ".mancode", "shared", "team", "transport")
36639
+ path62.join(projectRoot, ".mancode", "shared", "team", "transport")
35863
36640
  ),
35864
36641
  pathExists14(gitRefCachePath(projectRoot))
35865
36642
  ]);
@@ -35889,21 +36666,21 @@ function assertPositiveRevision5(value, label) {
35889
36666
  }
35890
36667
  }
35891
36668
  function teamPolicyPath(projectRoot) {
35892
- return path60.join(projectRoot, ".mancode", "shared", "team", "policy.json");
36669
+ return path62.join(projectRoot, ".mancode", "shared", "team", "policy.json");
35893
36670
  }
35894
36671
  function projectConfigPath(projectRoot) {
35895
- return path60.join(projectRoot, ".mancode", "shared", "config.json");
36672
+ return path62.join(projectRoot, ".mancode", "shared", "config.json");
35896
36673
  }
35897
36674
  async function writeJsonAtomic4(target, value) {
35898
- await mkdir37(path60.dirname(target), { recursive: true });
35899
- await assertPlainDirectory(path60.dirname(target));
36675
+ await mkdir38(path62.dirname(target), { recursive: true });
36676
+ await assertPlainDirectory(path62.dirname(target));
35900
36677
  await assertPlainFileOrMissing(target);
35901
- const temporary = path60.join(
35902
- path60.dirname(target),
35903
- `.${path60.basename(target)}.${process.pid}.${createUlid()}.tmp`
36678
+ const temporary = path62.join(
36679
+ path62.dirname(target),
36680
+ `.${path62.basename(target)}.${process.pid}.${createUlid()}.tmp`
35904
36681
  );
35905
36682
  try {
35906
- await writeFile42(temporary, `${JSON.stringify(value, null, 2)}
36683
+ await writeFile43(temporary, `${JSON.stringify(value, null, 2)}
35907
36684
  `, {
35908
36685
  encoding: "utf8",
35909
36686
  flag: "wx"
@@ -35915,61 +36692,61 @@ async function writeJsonAtomic4(target, value) {
35915
36692
  }
35916
36693
  }
35917
36694
  async function assertPlainDirectory(target) {
35918
- const entry = await lstat23(target);
36695
+ const entry = await lstat24(target);
35919
36696
  if (!entry.isDirectory() || entry.isSymbolicLink()) {
35920
36697
  throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
35921
36698
  }
35922
36699
  }
35923
36700
  async function assertPlainFileOrMissing(target) {
35924
36701
  try {
35925
- const entry = await lstat23(target);
36702
+ const entry = await lstat24(target);
35926
36703
  if (!entry.isFile() || entry.isSymbolicLink()) {
35927
36704
  throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
35928
36705
  }
35929
36706
  } catch (error) {
35930
- if (isNotFound30(error)) return;
36707
+ if (isNotFound31(error)) return;
35931
36708
  throw error;
35932
36709
  }
35933
36710
  }
35934
36711
  async function directoryHasEntries(target) {
35935
36712
  try {
35936
- const entry = await lstat23(target);
36713
+ const entry = await lstat24(target);
35937
36714
  if (!entry.isDirectory() || entry.isSymbolicLink()) {
35938
36715
  throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
35939
36716
  }
35940
36717
  return (await readdir20(target)).length > 0;
35941
36718
  } catch (error) {
35942
- if (isNotFound30(error)) return false;
36719
+ if (isNotFound31(error)) return false;
35943
36720
  throw error;
35944
36721
  }
35945
36722
  }
35946
36723
  async function pathExists14(target) {
35947
36724
  try {
35948
- await lstat23(target);
36725
+ await lstat24(target);
35949
36726
  return true;
35950
36727
  } catch (error) {
35951
- if (isNotFound30(error)) return false;
36728
+ if (isNotFound31(error)) return false;
35952
36729
  throw error;
35953
36730
  }
35954
36731
  }
35955
36732
  async function releaseLocks4(locks) {
35956
36733
  await Promise.allSettled([...locks].reverse().map((lock) => lock.release()));
35957
36734
  }
35958
- function isNotFound30(error) {
36735
+ function isNotFound31(error) {
35959
36736
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
35960
36737
  }
35961
36738
 
35962
36739
  // src/team/transport-migration-adapters.ts
35963
36740
  import {
35964
- lstat as lstat24,
35965
- mkdir as mkdir38,
35966
- readFile as readFile42,
36741
+ lstat as lstat25,
36742
+ mkdir as mkdir39,
36743
+ readFile as readFile44,
35967
36744
  readdir as readdir21,
35968
36745
  rename as rename12,
35969
36746
  unlink as unlink4,
35970
- writeFile as writeFile43
36747
+ writeFile as writeFile44
35971
36748
  } from "fs/promises";
35972
- import path61 from "path";
36749
+ import path63 from "path";
35973
36750
 
35974
36751
  // src/team/transport-migration.ts
35975
36752
  var DIGEST_PATTERN7 = /^sha256:[a-f0-9]{64}$/;
@@ -36932,7 +37709,7 @@ function parseTaskSnapshot(value) {
36932
37709
  assertUlid(ownerActorId, "transport migration task ownerActorId");
36933
37710
  }
36934
37711
  const taskRevision = parsePositiveInteger5(value.taskRevision, "taskRevision");
36935
- const ownershipEpoch = parseNonNegativeInteger2(
37712
+ const ownershipEpoch = parseNonNegativeInteger3(
36936
37713
  value.ownershipEpoch,
36937
37714
  "ownershipEpoch"
36938
37715
  );
@@ -37009,7 +37786,7 @@ function parsePositiveInteger5(value, label) {
37009
37786
  }
37010
37787
  return value;
37011
37788
  }
37012
- function parseNonNegativeInteger2(value, label) {
37789
+ function parseNonNegativeInteger3(value, label) {
37013
37790
  if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
37014
37791
  throw new Error(`${label} must be a non-negative integer`);
37015
37792
  }
@@ -37041,7 +37818,7 @@ function compareUtf813(left, right) {
37041
37818
  var STAGE_DIRECTORY = "transport-migrations";
37042
37819
  var COLLECTIONS = ["claims", "handoffs", "task-heads"];
37043
37820
  async function createTransportMigrationFileAdapters(input) {
37044
- const projectRoot = path61.resolve(input.projectRoot);
37821
+ const projectRoot = path63.resolve(input.projectRoot);
37045
37822
  assertUlid(input.actorId, "transport migration adapter actorId");
37046
37823
  if (input.operationId !== void 0) {
37047
37824
  assertUlid(input.operationId, "transport migration adapter operationId");
@@ -37093,9 +37870,8 @@ async function createTransportMigrationFileAdapters(input) {
37093
37870
  var FileSystemTransportMigrationConfigAdapter = class {
37094
37871
  constructor(projectRoot, coordinationStore) {
37095
37872
  this.coordinationStore = coordinationStore;
37096
- this.projectRoot = path61.resolve(projectRoot);
37873
+ this.projectRoot = path63.resolve(projectRoot);
37097
37874
  }
37098
- coordinationStore;
37099
37875
  projectRoot;
37100
37876
  async read() {
37101
37877
  return readProjectConfigFile(this.projectRoot);
@@ -37136,9 +37912,6 @@ var LocalTransportMigrationSourceAdapter = class {
37136
37912
  this.authorityId = authorityId;
37137
37913
  this.coordinationDomainId = coordinationDomainId2;
37138
37914
  }
37139
- context;
37140
- authorityId;
37141
- coordinationDomainId;
37142
37915
  mode = "local";
37143
37916
  remote = null;
37144
37917
  async freeze(input) {
@@ -37345,9 +38118,6 @@ var GitRefTransportMigrationSourceAdapter = class {
37345
38118
  this.store = store;
37346
38119
  this.remote = requireRemote(context.sourceConfig.transport.remote);
37347
38120
  }
37348
- context;
37349
- authorityId;
37350
- store;
37351
38121
  mode = "git-ref";
37352
38122
  remote;
37353
38123
  async freeze(input) {
@@ -37475,9 +38245,6 @@ var FileStagedTransportTarget = class {
37475
38245
  this.authorityId = authorityId;
37476
38246
  this.coordinationDomainId = coordinationDomainId2;
37477
38247
  }
37478
- context;
37479
- authorityId;
37480
- coordinationDomainId;
37481
38248
  async stage(manifestValue) {
37482
38249
  const manifest = parseTransportMigrationManifest(manifestValue);
37483
38250
  this.assertManifestTarget(manifest);
@@ -37956,27 +38723,27 @@ async function publishMigrationActorProfiles(projectRoot, profiles) {
37956
38723
  }
37957
38724
  }
37958
38725
  async function archiveLocalCoordinationCollections(store, operationId) {
37959
- const archiveRoot = path61.join(
38726
+ const archiveRoot = path63.join(
37960
38727
  store.root,
37961
38728
  STAGE_DIRECTORY,
37962
38729
  "archive",
37963
38730
  operationId
37964
38731
  );
37965
- await mkdir38(archiveRoot, { recursive: true });
38732
+ await mkdir39(archiveRoot, { recursive: true });
37966
38733
  const directories = {
37967
38734
  claims: claimDirectory(store),
37968
38735
  handoffs: handoffDirectory(store),
37969
38736
  "task-heads": taskHeadDirectory(store)
37970
38737
  };
37971
38738
  for (const name of COLLECTIONS) {
37972
- const archived = path61.join(archiveRoot, name);
37973
- const absent = path61.join(archiveRoot, `${name}.absent`);
38739
+ const archived = path63.join(archiveRoot, name);
38740
+ const absent = path63.join(archiveRoot, `${name}.absent`);
37974
38741
  if (await pathKind(archived) === "directory" || await pathKind(absent) === "file") {
37975
38742
  continue;
37976
38743
  }
37977
38744
  const sourceKind = await pathKind(directories[name]);
37978
38745
  if (sourceKind === null) {
37979
- await writeFile43(absent, "\n", { encoding: "utf8", flag: "wx" });
38746
+ await writeFile44(absent, "\n", { encoding: "utf8", flag: "wx" });
37980
38747
  continue;
37981
38748
  }
37982
38749
  if (sourceKind !== "directory") {
@@ -37991,7 +38758,7 @@ async function listActorProfiles(projectRoot) {
37991
38758
  try {
37992
38759
  entries = await readdir21(directory);
37993
38760
  } catch (error) {
37994
- if (isNotFound31(error)) return [];
38761
+ if (isNotFound32(error)) return [];
37995
38762
  throw error;
37996
38763
  }
37997
38764
  const profiles = [];
@@ -38008,19 +38775,19 @@ async function listActorProfiles(projectRoot) {
38008
38775
  return profiles;
38009
38776
  }
38010
38777
  async function listSharedTaskRefs(projectRoot) {
38011
- const directory = path61.join(projectRoot, ".mancode", "shared", "workflows");
38778
+ const directory = path63.join(projectRoot, ".mancode", "shared", "workflows");
38012
38779
  let entries;
38013
38780
  try {
38014
38781
  entries = await readdir21(directory);
38015
38782
  } catch (error) {
38016
- if (isNotFound31(error)) return [];
38783
+ if (isNotFound32(error)) return [];
38017
38784
  throw error;
38018
38785
  }
38019
38786
  const refs = [];
38020
38787
  for (const taskId of entries.sort(compareUtf814)) {
38021
38788
  assertUlid(taskId, "shared workflow directory");
38022
- const stat4 = await lstat24(path61.join(directory, taskId));
38023
- if (!stat4.isDirectory() || stat4.isSymbolicLink()) {
38789
+ const stat5 = await lstat25(path63.join(directory, taskId));
38790
+ if (!stat5.isDirectory() || stat5.isSymbolicLink()) {
38024
38791
  throw new Error("MANCODE_CONTEXT_PATH_UNSAFE");
38025
38792
  }
38026
38793
  refs.push({ namespace: "shared", taskId });
@@ -38031,7 +38798,7 @@ async function readTaskSnapshotOrNull(projectRoot, taskRef) {
38031
38798
  try {
38032
38799
  return await new V3ContextStore(projectRoot).readTaskSnapshot(taskRef);
38033
38800
  } catch (error) {
38034
- if (error instanceof Error && (error.message === "MANCODE_TASK_NOT_FOUND" || isNotFound31(error))) {
38801
+ if (error instanceof Error && (error.message === "MANCODE_TASK_NOT_FOUND" || isNotFound32(error))) {
38035
38802
  return null;
38036
38803
  }
38037
38804
  throw error;
@@ -38093,7 +38860,7 @@ async function readStagedRecord(store, operationId) {
38093
38860
  );
38094
38861
  }
38095
38862
  function stagedPath(store, operationId) {
38096
- return path61.join(
38863
+ return path63.join(
38097
38864
  store.root,
38098
38865
  STAGE_DIRECTORY,
38099
38866
  "staged",
@@ -38101,7 +38868,7 @@ function stagedPath(store, operationId) {
38101
38868
  );
38102
38869
  }
38103
38870
  function establishedPath(store, operationId) {
38104
- return path61.join(
38871
+ return path63.join(
38105
38872
  store.root,
38106
38873
  STAGE_DIRECTORY,
38107
38874
  "established",
@@ -38109,12 +38876,12 @@ function establishedPath(store, operationId) {
38109
38876
  );
38110
38877
  }
38111
38878
  function projectConfigPath2(projectRoot) {
38112
- return path61.join(projectRoot, ".mancode", "shared", "config.json");
38879
+ return path63.join(projectRoot, ".mancode", "shared", "config.json");
38113
38880
  }
38114
38881
  async function readProjectConfigFile(projectRoot) {
38115
38882
  try {
38116
38883
  return parseProjectConfig(
38117
- JSON.parse(await readFile42(projectConfigPath2(projectRoot), "utf8"))
38884
+ JSON.parse(await readFile44(projectConfigPath2(projectRoot), "utf8"))
38118
38885
  );
38119
38886
  } catch (error) {
38120
38887
  if (error instanceof SyntaxError) {
@@ -38124,14 +38891,14 @@ async function readProjectConfigFile(projectRoot) {
38124
38891
  }
38125
38892
  }
38126
38893
  async function writeJsonAtomic5(target, value) {
38127
- await mkdir38(path61.dirname(target), { recursive: true });
38128
- await assertPlainDirectory2(path61.dirname(target));
38129
- const temporary = path61.join(
38130
- path61.dirname(target),
38131
- `.${path61.basename(target)}.${process.pid}.${createUlid()}.tmp`
38894
+ await mkdir39(path63.dirname(target), { recursive: true });
38895
+ await assertPlainDirectory2(path63.dirname(target));
38896
+ const temporary = path63.join(
38897
+ path63.dirname(target),
38898
+ `.${path63.basename(target)}.${process.pid}.${createUlid()}.tmp`
38132
38899
  );
38133
38900
  try {
38134
- await writeFile43(temporary, serialize14(value), {
38901
+ await writeFile44(temporary, serialize14(value), {
38135
38902
  encoding: "utf8",
38136
38903
  flag: "wx"
38137
38904
  });
@@ -38142,10 +38909,10 @@ async function writeJsonAtomic5(target, value) {
38142
38909
  }
38143
38910
  }
38144
38911
  async function writeJsonExclusiveOrEqual(target, value, parser, conflictCode) {
38145
- await mkdir38(path61.dirname(target), { recursive: true });
38146
- await assertPlainDirectory2(path61.dirname(target));
38912
+ await mkdir39(path63.dirname(target), { recursive: true });
38913
+ await assertPlainDirectory2(path63.dirname(target));
38147
38914
  try {
38148
- await writeFile43(target, serialize14(value), { encoding: "utf8", flag: "wx" });
38915
+ await writeFile44(target, serialize14(value), { encoding: "utf8", flag: "wx" });
38149
38916
  } catch (error) {
38150
38917
  if (!isAlreadyExists25(error)) throw error;
38151
38918
  const existing = await readJsonOrNull5(target, parser, conflictCode);
@@ -38157,18 +38924,18 @@ async function writeJsonExclusiveOrEqual(target, value, parser, conflictCode) {
38157
38924
  }
38158
38925
  async function readJsonOrNull5(target, parser, corruptCode) {
38159
38926
  try {
38160
- const before = await lstat24(target);
38927
+ const before = await lstat25(target);
38161
38928
  if (!before.isFile() || before.isSymbolicLink()) {
38162
38929
  throw new Error("MANCODE_TRANSPORT_MIGRATION_STAGE_UNSAFE");
38163
38930
  }
38164
- const parsed = parser(JSON.parse(await readFile42(target, "utf8")));
38165
- const after = await lstat24(target);
38931
+ const parsed = parser(JSON.parse(await readFile44(target, "utf8")));
38932
+ const after = await lstat25(target);
38166
38933
  if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
38167
38934
  throw new Error("MANCODE_TRANSPORT_MIGRATION_STAGE_UNSAFE");
38168
38935
  }
38169
38936
  return parsed;
38170
38937
  } catch (error) {
38171
- if (isNotFound31(error)) return null;
38938
+ if (isNotFound32(error)) return null;
38172
38939
  if (error instanceof SyntaxError) throw new Error(corruptCode);
38173
38940
  throw error;
38174
38941
  }
@@ -38220,19 +38987,19 @@ function requireRemote(value) {
38220
38987
  }
38221
38988
  async function pathKind(target) {
38222
38989
  try {
38223
- const stat4 = await lstat24(target);
38224
- if (stat4.isSymbolicLink()) return "other";
38225
- if (stat4.isFile()) return "file";
38226
- if (stat4.isDirectory()) return "directory";
38990
+ const stat5 = await lstat25(target);
38991
+ if (stat5.isSymbolicLink()) return "other";
38992
+ if (stat5.isFile()) return "file";
38993
+ if (stat5.isDirectory()) return "directory";
38227
38994
  return "other";
38228
38995
  } catch (error) {
38229
- if (isNotFound31(error)) return null;
38996
+ if (isNotFound32(error)) return null;
38230
38997
  throw error;
38231
38998
  }
38232
38999
  }
38233
39000
  async function assertPlainDirectory2(target) {
38234
- const stat4 = await lstat24(target);
38235
- if (!stat4.isDirectory() || stat4.isSymbolicLink()) {
39001
+ const stat5 = await lstat25(target);
39002
+ if (!stat5.isDirectory() || stat5.isSymbolicLink()) {
38236
39003
  throw new Error("MANCODE_TRANSPORT_MIGRATION_STAGE_UNSAFE");
38237
39004
  }
38238
39005
  }
@@ -38240,7 +39007,7 @@ async function unlinkIfExists2(target) {
38240
39007
  try {
38241
39008
  await unlink4(target);
38242
39009
  } catch (error) {
38243
- if (!isNotFound31(error)) throw error;
39010
+ if (!isNotFound32(error)) throw error;
38244
39011
  }
38245
39012
  }
38246
39013
  function serialize14(value) {
@@ -38253,7 +39020,7 @@ function compareUtf814(left, right) {
38253
39020
  function isAlreadyExists25(error) {
38254
39021
  return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
38255
39022
  }
38256
- function isNotFound31(error) {
39023
+ function isNotFound32(error) {
38257
39024
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
38258
39025
  }
38259
39026
 
@@ -39662,12 +40429,12 @@ function parseActorId2(value) {
39662
40429
  function parseHandoffId(value) {
39663
40430
  return parseUlidArgument(value, "MANCODE_HANDOFF_ID_INVALID");
39664
40431
  }
39665
- function parseUlidArgument(value, errorCode5) {
40432
+ function parseUlidArgument(value, errorCode6) {
39666
40433
  try {
39667
40434
  assertUlid(value, "value");
39668
40435
  return value;
39669
40436
  } catch {
39670
- throw new Error(errorCode5);
40437
+ throw new Error(errorCode6);
39671
40438
  }
39672
40439
  }
39673
40440
  function parseTransportMode3(value) {
@@ -39693,23 +40460,23 @@ function parsePositiveInteger6(value) {
39693
40460
  }
39694
40461
 
39695
40462
  // src/commands/uninstall.ts
39696
- import { access as access5, readFile as readFile43, rm as rm19, writeFile as writeFile44 } from "fs/promises";
39697
- import path62 from "path";
39698
- import process11 from "process";
39699
- var EXIT_OK9 = 0;
39700
- var EXIT_NOT_INITIALIZED6 = 1;
40463
+ import { access as access5, readFile as readFile45, rm as rm20, writeFile as writeFile45 } from "fs/promises";
40464
+ import path64 from "path";
40465
+ import process12 from "process";
40466
+ var EXIT_OK10 = 0;
40467
+ var EXIT_NOT_INITIALIZED7 = 1;
39701
40468
  var EXIT_UNSUPPORTED_PLATFORM2 = 2;
39702
40469
  var EXIT_V3_AUTHORITY_PROTECTED = 3;
39703
- async function uninstall(rootDir = process11.cwd(), platform, options = {}) {
39704
- const stateFile = path62.join(rootDir, ".mancode", "state.json");
39705
- const v3SchemaFile = path62.join(rootDir, ".mancode", "schema.json");
40470
+ async function uninstall(rootDir = process12.cwd(), platform, options = {}) {
40471
+ const stateFile = path64.join(rootDir, ".mancode", "state.json");
40472
+ const v3SchemaFile = path64.join(rootDir, ".mancode", "schema.json");
39706
40473
  if (await pathExists15(v3SchemaFile)) {
39707
40474
  return uninstallV3(rootDir, platform, options);
39708
40475
  }
39709
40476
  if (!await pathExists15(stateFile)) {
39710
40477
  console.error("\u2717 mancode not initialized.");
39711
40478
  console.error(" Run `mancode init` first.");
39712
- return EXIT_NOT_INITIALIZED6;
40479
+ return EXIT_NOT_INITIALIZED7;
39713
40480
  }
39714
40481
  const removeAll = !platform || options.all;
39715
40482
  if (platform) {
@@ -39734,7 +40501,7 @@ async function uninstall(rootDir = process11.cwd(), platform, options = {}) {
39734
40501
  await uninstallPlatform(rootDir, platform ?? "claude-code");
39735
40502
  }
39736
40503
  console.log("\u2713 Uninstall complete.");
39737
- return EXIT_OK9;
40504
+ return EXIT_OK10;
39738
40505
  }
39739
40506
  async function uninstallV3(rootDir, platform, options) {
39740
40507
  if (!platform || options.all) {
@@ -39765,7 +40532,7 @@ async function uninstallV3(rootDir, platform, options) {
39765
40532
  console.log(
39766
40533
  `\u2713 Removed ${formatPlatformName(platform)} mancode bootstrap.`
39767
40534
  );
39768
- return EXIT_OK9;
40535
+ return EXIT_OK10;
39769
40536
  } catch (error) {
39770
40537
  const message = error instanceof Error ? error.message : String(error);
39771
40538
  console.error(`\u2717 mancode bootstrap removal failed: ${message}`);
@@ -39793,7 +40560,7 @@ async function uninstallAll(rootDir) {
39793
40560
  await uninstallPlatform(rootDir, p);
39794
40561
  }
39795
40562
  console.log("\u2713 Removing .mancode/ directory...");
39796
- await rm19(path62.join(rootDir, ".mancode"), {
40563
+ await rm20(path64.join(rootDir, ".mancode"), {
39797
40564
  recursive: true,
39798
40565
  force: true
39799
40566
  });
@@ -39803,10 +40570,10 @@ async function uninstallClaudeCode(rootDir) {
39803
40570
  await cleanClaudeSettings(rootDir);
39804
40571
  }
39805
40572
  async function cleanClaudeSettings(rootDir) {
39806
- const settingsPath = path62.join(rootDir, ".claude", "settings.json");
40573
+ const settingsPath = path64.join(rootDir, ".claude", "settings.json");
39807
40574
  let content;
39808
40575
  try {
39809
- content = await readFile43(settingsPath, "utf-8");
40576
+ content = await readFile45(settingsPath, "utf-8");
39810
40577
  } catch {
39811
40578
  return;
39812
40579
  }
@@ -39817,14 +40584,14 @@ async function cleanClaudeSettings(rootDir) {
39817
40584
  return;
39818
40585
  }
39819
40586
  const cleanedHooks = {};
39820
- if (isRecord12(settings.hooks)) {
40587
+ if (isRecord13(settings.hooks)) {
39821
40588
  for (const [event, value] of Object.entries(settings.hooks)) {
39822
40589
  const cleaned = cleanClaudeHookValue(value);
39823
40590
  if (cleaned !== void 0) cleanedHooks[event] = cleaned;
39824
40591
  }
39825
40592
  settings.hooks = Object.keys(cleanedHooks).length > 0 ? cleanedHooks : void 0;
39826
40593
  }
39827
- if (isRecord12(settings.skills)) {
40594
+ if (isRecord13(settings.skills)) {
39828
40595
  const retainedSkills = Object.fromEntries(
39829
40596
  Object.entries(settings.skills).filter(
39830
40597
  ([name, value]) => LEGACY_CLAUDE_SKILL_SETTINGS[name] !== value
@@ -39832,7 +40599,7 @@ async function cleanClaudeSettings(rootDir) {
39832
40599
  );
39833
40600
  settings.skills = Object.keys(retainedSkills).length > 0 ? retainedSkills : void 0;
39834
40601
  }
39835
- await writeFile44(
40602
+ await writeFile45(
39836
40603
  settingsPath,
39837
40604
  `${JSON.stringify(settings, null, 2)}
39838
40605
  `,
@@ -39844,7 +40611,7 @@ function cleanClaudeHookValue(value) {
39844
40611
  const entries2 = value.flatMap(cleanClaudeHookEntry);
39845
40612
  return entries2.length > 0 ? entries2 : void 0;
39846
40613
  }
39847
- if (!isRecord12(value)) return value;
40614
+ if (!isRecord13(value)) return value;
39848
40615
  if (Array.isArray(value.hooks) || typeof value.command === "string") {
39849
40616
  const entries2 = cleanClaudeHookEntry(value);
39850
40617
  return entries2.length > 0 ? entries2 : void 0;
@@ -39858,7 +40625,7 @@ function cleanClaudeHookValue(value) {
39858
40625
  }
39859
40626
  function cleanClaudeHookEntry(entry) {
39860
40627
  if (Array.isArray(entry)) return entry.flatMap(cleanClaudeHookEntry);
39861
- if (!isRecord12(entry)) return [entry];
40628
+ if (!isRecord13(entry)) return [entry];
39862
40629
  if (Array.isArray(entry.hooks)) {
39863
40630
  const hooks = entry.hooks.filter((hook) => !isMancodeHookEntry(hook));
39864
40631
  return hooks.length > 0 ? [{ ...entry, hooks }] : [];
@@ -39866,11 +40633,11 @@ function cleanClaudeHookEntry(entry) {
39866
40633
  return isMancodeHookEntry(entry) ? [] : [entry];
39867
40634
  }
39868
40635
  function isMancodeHookEntry(value) {
39869
- return isRecord12(value) && typeof value.command === "string" && isGeneratedMancodeHookCommand(value.command);
40636
+ return isRecord13(value) && typeof value.command === "string" && isGeneratedMancodeHookCommand(value.command);
39870
40637
  }
39871
40638
  function containsLegacyMancodeHookPath2(value) {
39872
40639
  if (Array.isArray(value)) return value.some(containsLegacyMancodeHookPath2);
39873
- if (!isRecord12(value)) return false;
40640
+ if (!isRecord13(value)) return false;
39874
40641
  if (typeof value.command === "string" && value.command.includes(".mancode/hooks/")) {
39875
40642
  return true;
39876
40643
  }
@@ -39881,66 +40648,66 @@ async function uninstallCursor(rootDir) {
39881
40648
  await removeCursorCommands(rootDir);
39882
40649
  }
39883
40650
  async function uninstallCodex(rootDir) {
39884
- const agentsPath = path62.join(rootDir, "AGENTS.md");
40651
+ const agentsPath = path64.join(rootDir, "AGENTS.md");
39885
40652
  try {
39886
- const content = await readFile43(agentsPath, "utf-8");
40653
+ const content = await readFile45(agentsPath, "utf-8");
39887
40654
  const cleaned = removeManagedBlock(content);
39888
40655
  if (cleaned.trim()) {
39889
- await writeFile44(agentsPath, `${cleaned}
40656
+ await writeFile45(agentsPath, `${cleaned}
39890
40657
  `, "utf-8");
39891
40658
  } else {
39892
- await rm19(agentsPath, { force: true });
40659
+ await rm20(agentsPath, { force: true });
39893
40660
  }
39894
40661
  } catch {
39895
40662
  }
39896
40663
  await removeCodexSkills(rootDir);
39897
40664
  }
39898
40665
  async function uninstallCopilot(rootDir) {
39899
- const instructionsPath = path62.join(
40666
+ const instructionsPath = path64.join(
39900
40667
  rootDir,
39901
40668
  ".github",
39902
40669
  "copilot-instructions.md"
39903
40670
  );
39904
40671
  try {
39905
- const content = await readFile43(instructionsPath, "utf-8");
40672
+ const content = await readFile45(instructionsPath, "utf-8");
39906
40673
  const cleaned = removeManagedBlock(content);
39907
40674
  if (cleaned.trim()) {
39908
- await writeFile44(instructionsPath, `${cleaned}
40675
+ await writeFile45(instructionsPath, `${cleaned}
39909
40676
  `, "utf-8");
39910
40677
  } else {
39911
- await rm19(instructionsPath, { force: true });
40678
+ await rm20(instructionsPath, { force: true });
39912
40679
  }
39913
40680
  } catch {
39914
40681
  }
39915
40682
  await removeCopilotPrompts(rootDir);
39916
40683
  }
39917
40684
  async function uninstallZcode(rootDir) {
39918
- const agentsPath = path62.join(rootDir, "AGENTS.md");
40685
+ const agentsPath = path64.join(rootDir, "AGENTS.md");
39919
40686
  try {
39920
- const content = await readFile43(agentsPath, "utf-8");
40687
+ const content = await readFile45(agentsPath, "utf-8");
39921
40688
  const cleaned = removeManagedBlock(
39922
40689
  content,
39923
40690
  ZCODE_MANCODE_START_MARKER,
39924
40691
  ZCODE_MANCODE_END_MARKER
39925
40692
  );
39926
40693
  if (cleaned.trim()) {
39927
- await writeFile44(agentsPath, `${cleaned}
40694
+ await writeFile45(agentsPath, `${cleaned}
39928
40695
  `, "utf-8");
39929
40696
  } else {
39930
- await rm19(agentsPath, { force: true });
40697
+ await rm20(agentsPath, { force: true });
39931
40698
  }
39932
40699
  } catch {
39933
40700
  }
39934
40701
  await removeZcodeSkills(rootDir);
39935
40702
  }
39936
40703
  async function removeFromConfig(rootDir, platform) {
39937
- const configPath = path62.join(rootDir, ".mancode", "config.json");
40704
+ const configPath = path64.join(rootDir, ".mancode", "config.json");
39938
40705
  try {
39939
- const raw = await readFile43(configPath, "utf-8");
40706
+ const raw = await readFile45(configPath, "utf-8");
39940
40707
  const config = JSON.parse(raw);
39941
40708
  if (Array.isArray(config.platforms)) {
39942
40709
  config.platforms = config.platforms.filter((p) => p !== platform);
39943
- if (isRecord12(config.platformOptions)) {
40710
+ if (isRecord13(config.platformOptions)) {
39944
40711
  const platformOptions = Object.fromEntries(
39945
40712
  Object.entries(config.platformOptions).filter(
39946
40713
  ([name]) => name !== platform
@@ -39948,7 +40715,7 @@ async function removeFromConfig(rootDir, platform) {
39948
40715
  );
39949
40716
  config.platformOptions = Object.keys(platformOptions).length > 0 ? platformOptions : void 0;
39950
40717
  }
39951
- await writeFile44(
40718
+ await writeFile45(
39952
40719
  configPath,
39953
40720
  `${JSON.stringify(config, null, 2)}
39954
40721
  `,
@@ -39958,7 +40725,7 @@ async function removeFromConfig(rootDir, platform) {
39958
40725
  } catch {
39959
40726
  }
39960
40727
  }
39961
- function isRecord12(value) {
40728
+ function isRecord13(value) {
39962
40729
  return typeof value === "object" && value !== null && !Array.isArray(value);
39963
40730
  }
39964
40731
  async function pathExists15(p) {
@@ -39971,18 +40738,18 @@ async function pathExists15(p) {
39971
40738
  }
39972
40739
 
39973
40740
  // src/commands/version.ts
39974
- import process12 from "process";
40741
+ import process13 from "process";
39975
40742
  function version() {
39976
- const nodeVersion = process12.version;
39977
- const platform = `${process12.platform}/${process12.arch}`;
40743
+ const nodeVersion = process13.version;
40744
+ const platform = `${process13.platform}/${process13.arch}`;
39978
40745
  console.log(`mancode/${VERSION}`);
39979
40746
  console.log(`node/${nodeVersion.replace("v", "")}`);
39980
40747
  console.log(platform);
39981
40748
  }
39982
40749
 
39983
40750
  // src/commands/workflow.ts
39984
- import { access as access6, readFile as readFile45, rm as rm21, writeFile as writeFile46 } from "fs/promises";
39985
- import path64 from "path";
40751
+ import { access as access6, readFile as readFile47, rm as rm22, writeFile as writeFile47 } from "fs/promises";
40752
+ import path66 from "path";
39986
40753
 
39987
40754
  // src/context/child-result-merge.ts
39988
40755
  async function mergeV3ChildResult(input) {
@@ -43041,14 +43808,14 @@ function updateMetadata4(previous, verification, operationId, updatedAt) {
43041
43808
 
43042
43809
  // src/context/workflow-create.ts
43043
43810
  import {
43044
- lstat as lstat25,
43045
- mkdir as mkdir39,
43046
- readFile as readFile44,
43811
+ lstat as lstat26,
43812
+ mkdir as mkdir40,
43813
+ readFile as readFile46,
43047
43814
  rename as rename13,
43048
- rm as rm20,
43049
- writeFile as writeFile45
43815
+ rm as rm21,
43816
+ writeFile as writeFile46
43050
43817
  } from "fs/promises";
43051
- import path63 from "path";
43818
+ import path65 from "path";
43052
43819
 
43053
43820
  // src/context/creation-resolution.ts
43054
43821
  function resolveWorkflowCreation(request) {
@@ -43158,7 +43925,7 @@ function rejectConflict(provided, expected, label) {
43158
43925
 
43159
43926
  // src/context/workflow-create.ts
43160
43927
  async function createV3Workflow(input) {
43161
- const projectRoot = path63.resolve(requireProjectRoot2(input.projectRoot));
43928
+ const projectRoot = path65.resolve(requireProjectRoot2(input.projectRoot));
43162
43929
  const task = requireText2(input.task, "workflow task");
43163
43930
  const client = requireText2(input.client, "workflow client");
43164
43931
  const now = input.now ?? /* @__PURE__ */ new Date();
@@ -43343,8 +44110,8 @@ async function createV3Workflow(input) {
43343
44110
  throw new Error("MANCODE_REVISION_CONFLICT");
43344
44111
  }
43345
44112
  const taskParent = await ensureSafeTaskParent3(projectRoot, taskRef);
43346
- const targetDirectory = path63.join(taskParent, taskRef.taskId);
43347
- stagingDirectory = path63.join(
44113
+ const targetDirectory = path65.join(taskParent, taskRef.taskId);
44114
+ stagingDirectory = path65.join(
43348
44115
  taskParent,
43349
44116
  `.${taskRef.taskId}.${operationId}.staging`
43350
44117
  );
@@ -43793,10 +44560,10 @@ async function ensureSafeTaskParent3(projectRoot, taskRef) {
43793
44560
  const segments = [".mancode", taskRef.namespace, "workflows"];
43794
44561
  let current = projectRoot;
43795
44562
  for (const segment of segments) {
43796
- current = path63.join(current, segment);
44563
+ current = path65.join(current, segment);
43797
44564
  const existing = await lstatOrNull5(current);
43798
44565
  if (existing === null) {
43799
- await mkdir39(current);
44566
+ await mkdir40(current);
43800
44567
  continue;
43801
44568
  }
43802
44569
  if (!existing.isDirectory() || existing.isSymbolicLink()) {
@@ -43809,7 +44576,7 @@ async function assertDirectoryAbsent(target, code) {
43809
44576
  if (await lstatOrNull5(target) !== null) throw new Error(code);
43810
44577
  }
43811
44578
  async function writeStagedEntities(stagingDirectory, entities) {
43812
- await mkdir39(stagingDirectory);
44579
+ await mkdir40(stagingDirectory);
43813
44580
  await assertDirectory(stagingDirectory);
43814
44581
  await Promise.all([
43815
44582
  writeStagedJson(stagingDirectory, "metadata.json", entities.metadata),
@@ -43829,13 +44596,13 @@ async function writeStagedEntities(stagingDirectory, entities) {
43829
44596
  }
43830
44597
  async function writeStagedJson(stagingDirectory, fileName, value) {
43831
44598
  await assertDirectory(stagingDirectory);
43832
- const target = path63.join(stagingDirectory, fileName);
43833
- await writeFile45(target, `${JSON.stringify(value, null, 2)}
44599
+ const target = path65.join(stagingDirectory, fileName);
44600
+ await writeFile46(target, `${JSON.stringify(value, null, 2)}
43834
44601
  `, {
43835
44602
  encoding: "utf8",
43836
44603
  flag: "wx"
43837
44604
  });
43838
- const entry = await lstat25(target);
44605
+ const entry = await lstat26(target);
43839
44606
  if (!entry.isFile() || entry.isSymbolicLink()) {
43840
44607
  throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
43841
44608
  }
@@ -43867,13 +44634,13 @@ async function validateStagedEntities(stagingDirectory) {
43867
44634
  });
43868
44635
  }
43869
44636
  async function readStagedJson(stagingDirectory, fileName, parser) {
43870
- const target = path63.join(stagingDirectory, fileName);
43871
- const before = await lstat25(target);
44637
+ const target = path65.join(stagingDirectory, fileName);
44638
+ const before = await lstat26(target);
43872
44639
  if (!before.isFile() || before.isSymbolicLink()) {
43873
44640
  throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
43874
44641
  }
43875
- const parsed = parser(JSON.parse(await readFile44(target, "utf8")));
43876
- const after = await lstat25(target);
44642
+ const parsed = parser(JSON.parse(await readFile46(target, "utf8")));
44643
+ const after = await lstat26(target);
43877
44644
  if (!after.isFile() || after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) {
43878
44645
  throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
43879
44646
  }
@@ -43964,20 +44731,20 @@ async function abortPreparedCreate(store, journal, stagingDirectory, now) {
43964
44731
  { canAbort: true }
43965
44732
  );
43966
44733
  } finally {
43967
- await rm20(stagingDirectory, { recursive: true, force: true });
44734
+ await rm21(stagingDirectory, { recursive: true, force: true });
43968
44735
  }
43969
44736
  }
43970
44737
  async function assertDirectory(target) {
43971
- const entry = await lstat25(target);
44738
+ const entry = await lstat26(target);
43972
44739
  if (!entry.isDirectory() || entry.isSymbolicLink()) {
43973
44740
  throw new Error("MANCODE_ARTIFACT_PATH_UNSAFE");
43974
44741
  }
43975
44742
  }
43976
44743
  async function lstatOrNull5(target) {
43977
44744
  try {
43978
- return await lstat25(target);
44745
+ return await lstat26(target);
43979
44746
  } catch (error) {
43980
- if (isNotFound32(error)) return null;
44747
+ if (isNotFound33(error)) return null;
43981
44748
  throw error;
43982
44749
  }
43983
44750
  }
@@ -43997,7 +44764,7 @@ function requireText2(value, label) {
43997
44764
  }
43998
44765
  return value.trim();
43999
44766
  }
44000
- function isNotFound32(error) {
44767
+ function isNotFound33(error) {
44001
44768
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
44002
44769
  }
44003
44770
 
@@ -44894,7 +45661,7 @@ function compareUtf817(left, right) {
44894
45661
 
44895
45662
  // src/commands/requirements-input.ts
44896
45663
  function normalizeRequirementsInput(value, requestedTaskRef, now = /* @__PURE__ */ new Date(), options = {}) {
44897
- if (isRecord13(value) && "schemaVersion" in value) {
45664
+ if (isRecord14(value) && "schemaVersion" in value) {
44898
45665
  return parseRequirementsLedger(value);
44899
45666
  }
44900
45667
  const serialized = JSON.stringify(value);
@@ -44962,20 +45729,20 @@ function buildCanonicalRequirements(semantic, requestedTaskRef, now) {
44962
45729
  contentDigest: requirementsLedgerDigest(draft)
44963
45730
  });
44964
45731
  }
44965
- function isRecord13(value) {
45732
+ function isRecord14(value) {
44966
45733
  return typeof value === "object" && value !== null && !Array.isArray(value);
44967
45734
  }
44968
45735
 
44969
45736
  // src/commands/workflow.ts
44970
- var EXIT_OK10 = 0;
44971
- var EXIT_NOT_INITIALIZED7 = 1;
45737
+ var EXIT_OK11 = 0;
45738
+ var EXIT_NOT_INITIALIZED8 = 1;
44972
45739
  var EXIT_INVALID_ARG3 = 2;
44973
45740
  async function workflow(rootDir, subcommand, args = [], options = {}) {
44974
45741
  const v3Activation = await readV3ActivationState2(rootDir);
44975
45742
  if (v3Activation === "v3_active") {
44976
45743
  return workflowV3(rootDir, subcommand, args, options);
44977
45744
  }
44978
- if (!await pathExists16(path64.join(rootDir, ".mancode", "state.json"))) {
45745
+ if (!await pathExists16(path66.join(rootDir, ".mancode", "state.json"))) {
44979
45746
  if (v3Activation !== null) {
44980
45747
  return printV3Error(
44981
45748
  options.json,
@@ -44989,7 +45756,7 @@ async function workflow(rootDir, subcommand, args = [], options = {}) {
44989
45756
  console.error("\u2717 mancode not initialized.");
44990
45757
  console.error(" Run `mancode init` to get started.");
44991
45758
  }
44992
- return EXIT_NOT_INITIALIZED7;
45759
+ return EXIT_NOT_INITIALIZED8;
44993
45760
  }
44994
45761
  switch (subcommand) {
44995
45762
  case "create":
@@ -45105,7 +45872,7 @@ async function workflowListV3(rootDir, args, options) {
45105
45872
  }
45106
45873
  if (workflows.length === 0) {
45107
45874
  console.log("No mancode workflows.");
45108
- return EXIT_OK10;
45875
+ return EXIT_OK11;
45109
45876
  }
45110
45877
  const active = workflows.filter(
45111
45878
  (item) => ["in_progress", "planned", "blocked"].includes(item.status)
@@ -45117,7 +45884,7 @@ async function workflowListV3(rootDir, args, options) {
45117
45884
  for (const metadata of workflows) {
45118
45885
  console.log(formatV3WorkflowRow(metadata));
45119
45886
  }
45120
- return EXIT_OK10;
45887
+ return EXIT_OK11;
45121
45888
  } catch (error) {
45122
45889
  return printV3Error(
45123
45890
  options.json,
@@ -45175,7 +45942,7 @@ async function workflowShowV3(rootDir, args, options) {
45175
45942
  if (snapshot.aggregateError !== null) {
45176
45943
  console.log(`Aggregate: ${snapshot.aggregateError}`);
45177
45944
  }
45178
- return EXIT_OK10;
45945
+ return EXIT_OK11;
45179
45946
  } catch (error) {
45180
45947
  return printV3Error(
45181
45948
  options.json,
@@ -46067,8 +46834,8 @@ function parseV3ParticipantActorIds(values) {
46067
46834
  return values;
46068
46835
  }
46069
46836
  async function readWorkflowInputFile(projectRoot, value) {
46070
- const inputPath = path64.isAbsolute(value) ? value : path64.resolve(projectRoot, value);
46071
- return readFile45(inputPath, "utf8");
46837
+ const inputPath = path66.isAbsolute(value) ? value : path66.resolve(projectRoot, value);
46838
+ return readFile47(inputPath, "utf8");
46072
46839
  }
46073
46840
  async function readWorkflowJsonInputFile(projectRoot, value) {
46074
46841
  return JSON.parse(await readWorkflowInputFile(projectRoot, value));
@@ -46141,7 +46908,7 @@ async function readV3ActivationState2(rootDir) {
46141
46908
  try {
46142
46909
  const manifest = parseSchemaManifest(
46143
46910
  JSON.parse(
46144
- await readFile45(path64.join(rootDir, ".mancode", "schema.json"), "utf8")
46911
+ await readFile47(path66.join(rootDir, ".mancode", "schema.json"), "utf8")
46145
46912
  )
46146
46913
  );
46147
46914
  return manifest.activationState === "v3_active" ? "v3_active" : "other";
@@ -46186,21 +46953,21 @@ async function workflowRequirements(rootDir, args, options) {
46186
46953
  "requirements can only be finalized for an in-progress man or manteam workflow at step 1 or 2"
46187
46954
  );
46188
46955
  }
46189
- const workflowPath = path64.join(rootDir, ".mancode", "workflows", taskId);
46190
- const jsonPath = path64.join(workflowPath, "requirements.json");
46191
- const markdownPath = path64.join(workflowPath, "requirements.md");
46192
- const metadataPath3 = path64.join(workflowPath, "metadata.json");
46956
+ const workflowPath = path66.join(rootDir, ".mancode", "workflows", taskId);
46957
+ const jsonPath = path66.join(workflowPath, "requirements.json");
46958
+ const markdownPath = path66.join(workflowPath, "requirements.md");
46959
+ const metadataPath3 = path66.join(workflowPath, "metadata.json");
46193
46960
  let originalJson;
46194
46961
  let originalMarkdown;
46195
46962
  let originalMetadata;
46196
46963
  try {
46197
- const inputPath = path64.isAbsolute(options.file) ? options.file : path64.resolve(rootDir, options.file);
46198
- const input = await readFile45(inputPath, "utf-8");
46964
+ const inputPath = path66.isAbsolute(options.file) ? options.file : path66.resolve(rootDir, options.file);
46965
+ const input = await readFile47(inputPath, "utf-8");
46199
46966
  const requirements = parseRequirementsLedger2(input);
46200
46967
  [originalJson, originalMarkdown, originalMetadata] = await Promise.all([
46201
46968
  readOptionalText2(jsonPath),
46202
46969
  readOptionalText2(markdownPath),
46203
- readFile45(metadataPath3, "utf-8")
46970
+ readFile47(metadataPath3, "utf-8")
46204
46971
  ]);
46205
46972
  await writeRequirementsArtifacts(rootDir, taskId, requirements);
46206
46973
  await updateWorkflow(rootDir, taskId, {
@@ -46223,14 +46990,14 @@ async function workflowRequirements(rootDir, args, options) {
46223
46990
  `Finalized requirements: ${taskId} (${requirementsAreReady2(requirements) ? "ready" : "needs_clarification"})`
46224
46991
  );
46225
46992
  }
46226
- return EXIT_OK10;
46993
+ return EXIT_OK11;
46227
46994
  } catch (error) {
46228
46995
  let rollbackIncomplete = false;
46229
46996
  if (originalJson !== void 0 && originalMarkdown !== void 0 && originalMetadata !== void 0) {
46230
46997
  const rollback = await Promise.allSettled([
46231
46998
  restoreOptionalText(jsonPath, originalJson),
46232
46999
  restoreOptionalText(markdownPath, originalMarkdown),
46233
- writeFile46(metadataPath3, originalMetadata, "utf-8")
47000
+ writeFile47(metadataPath3, originalMetadata, "utf-8")
46234
47001
  ]);
46235
47002
  rollbackIncomplete = rollback.some(
46236
47003
  (result2) => result2.status === "rejected"
@@ -46259,7 +47026,7 @@ async function workflowVerify(rootDir, args, options) {
46259
47026
  return invalidArg(options, `verification not initialized: ${taskId}`);
46260
47027
  }
46261
47028
  outputVerificationLedger(ledger, options);
46262
- return EXIT_OK10;
47029
+ return EXIT_OK11;
46263
47030
  }
46264
47031
  if (meta.verificationPolicyVersion !== 1 || (action === "init" ? meta.currentStep !== 6 : meta.currentStep !== 6 && meta.currentStep !== 9) || meta.planDecision !== "governed_execution" || meta.status !== "in_progress" && meta.status !== "blocked") {
46265
47032
  return invalidArg(
@@ -46318,7 +47085,7 @@ async function workflowVerify(rootDir, args, options) {
46318
47085
  );
46319
47086
  }
46320
47087
  if (options.evidenceFile) {
46321
- const evidencePath = path64.isAbsolute(options.evidenceFile) ? options.evidenceFile : path64.resolve(rootDir, options.evidenceFile);
47088
+ const evidencePath = path66.isAbsolute(options.evidenceFile) ? options.evidenceFile : path66.resolve(rootDir, options.evidenceFile);
46322
47089
  if (!await pathExists16(evidencePath)) {
46323
47090
  return invalidArg(
46324
47091
  options,
@@ -46368,7 +47135,7 @@ async function workflowVerify(rootDir, args, options) {
46368
47135
  );
46369
47136
  if (transitionError) return invalidArg(options, transitionError);
46370
47137
  outputVerificationLedger(ledger, options);
46371
- return EXIT_OK10;
47138
+ return EXIT_OK11;
46372
47139
  } catch (error) {
46373
47140
  return invalidArg(
46374
47141
  options,
@@ -46378,17 +47145,17 @@ async function workflowVerify(rootDir, args, options) {
46378
47145
  }
46379
47146
  async function commitVerificationTransition(rootDir, meta, ledger) {
46380
47147
  const ledgerPath = verificationLedgerPath(rootDir, meta.taskId);
46381
- const metadataPath3 = path64.join(
47148
+ const metadataPath3 = path66.join(
46382
47149
  rootDir,
46383
47150
  ".mancode",
46384
47151
  "workflows",
46385
47152
  meta.taskId,
46386
47153
  "metadata.json"
46387
47154
  );
46388
- const specPath = path64.join(rootDir, ".mancode", "memory", "spec.md");
47155
+ const specPath = path66.join(rootDir, ".mancode", "memory", "spec.md");
46389
47156
  const [originalLedger, originalMetadata, originalSpec] = await Promise.all([
46390
47157
  readOptionalText2(ledgerPath),
46391
- readFile45(metadataPath3, "utf-8"),
47158
+ readFile47(metadataPath3, "utf-8"),
46392
47159
  readOptionalText2(specPath)
46393
47160
  ]);
46394
47161
  const wasVerificationBlocked = meta.status === "blocked" && meta.blockingReason?.startsWith("[verification]");
@@ -46417,7 +47184,7 @@ async function commitVerificationTransition(rootDir, meta, ledger) {
46417
47184
  } catch (error) {
46418
47185
  const rollback = await Promise.allSettled([
46419
47186
  restoreOptionalText(ledgerPath, originalLedger),
46420
- writeFile46(metadataPath3, originalMetadata, "utf-8"),
47187
+ writeFile47(metadataPath3, originalMetadata, "utf-8"),
46421
47188
  restoreOptionalText(specPath, originalSpec)
46422
47189
  ]);
46423
47190
  const message = error instanceof Error ? error.message : "verification transition failed";
@@ -46452,7 +47219,7 @@ async function workflowReview(rootDir, args, options) {
46452
47219
  if (!ledger)
46453
47220
  return invalidArg(options, `review not initialized: ${taskId}`);
46454
47221
  outputReviewLedger(ledger, options);
46455
- return EXIT_OK10;
47222
+ return EXIT_OK11;
46456
47223
  }
46457
47224
  if (meta.status !== "in_progress" || meta.currentStep < 6) {
46458
47225
  return invalidArg(
@@ -46482,7 +47249,7 @@ async function workflowReview(rootDir, args, options) {
46482
47249
  if (error) return invalidArg(options, error);
46483
47250
  const ledger = await readReviewLedger(rootDir, taskId);
46484
47251
  outputReviewLedger(ledger, options);
46485
- return EXIT_OK10;
47252
+ return EXIT_OK11;
46486
47253
  } catch (error) {
46487
47254
  return invalidArg(
46488
47255
  options,
@@ -46539,7 +47306,7 @@ async function workflowReview(rootDir, args, options) {
46539
47306
  );
46540
47307
  }
46541
47308
  outputReviewLedger(ledger, options);
46542
- return EXIT_OK10;
47309
+ return EXIT_OK11;
46543
47310
  } catch (error) {
46544
47311
  return invalidArg(
46545
47312
  options,
@@ -46549,7 +47316,7 @@ async function workflowReview(rootDir, args, options) {
46549
47316
  }
46550
47317
  async function commitReviewSkip(rootDir, meta, reason) {
46551
47318
  const ledgerPath = reviewLedgerPath(rootDir, meta.taskId);
46552
- const metadataPath3 = path64.join(
47319
+ const metadataPath3 = path66.join(
46553
47320
  rootDir,
46554
47321
  ".mancode",
46555
47322
  "workflows",
@@ -46558,7 +47325,7 @@ async function commitReviewSkip(rootDir, meta, reason) {
46558
47325
  );
46559
47326
  const [originalLedger, originalMetadata] = await Promise.all([
46560
47327
  readOptionalText2(ledgerPath),
46561
- readFile45(metadataPath3, "utf-8")
47328
+ readFile47(metadataPath3, "utf-8")
46562
47329
  ]);
46563
47330
  try {
46564
47331
  await initializeSkippedReview(rootDir, meta.taskId, reason);
@@ -46569,7 +47336,7 @@ async function commitReviewSkip(rootDir, meta, reason) {
46569
47336
  } catch (error) {
46570
47337
  const rollback = await Promise.allSettled([
46571
47338
  restoreOptionalText(ledgerPath, originalLedger),
46572
- writeFile46(metadataPath3, originalMetadata, "utf-8")
47339
+ writeFile47(metadataPath3, originalMetadata, "utf-8")
46573
47340
  ]);
46574
47341
  const message = error instanceof Error ? error.message : "review skip failed";
46575
47342
  return rollback.some((result2) => result2.status === "rejected") ? `${message}; rollback was incomplete` : message;
@@ -46629,7 +47396,7 @@ async function workflowCreate(rootDir, args, options) {
46629
47396
  error instanceof Error ? error.message : "unable to create workflow"
46630
47397
  );
46631
47398
  }
46632
- return EXIT_OK10;
47399
+ return EXIT_OK11;
46633
47400
  }
46634
47401
  async function workflowUpdate(rootDir, taskId, options) {
46635
47402
  if (!taskId) {
@@ -46764,7 +47531,7 @@ async function workflowUpdate(rootDir, taskId, options) {
46764
47531
  } else {
46765
47532
  console.log(`Updated workflow: ${taskId}`);
46766
47533
  }
46767
- return EXIT_OK10;
47534
+ return EXIT_OK11;
46768
47535
  }
46769
47536
  async function workflowHandoff(rootDir, taskId, options) {
46770
47537
  if (!taskId || !isValidWorkflowTaskId(taskId)) {
@@ -46789,18 +47556,18 @@ async function workflowHandoff(rootDir, taskId, options) {
46789
47556
  "solo handoff requires an undecided in-progress workflow at step 4 with ready requirements"
46790
47557
  );
46791
47558
  }
46792
- const workflowPath = path64.join(rootDir, ".mancode", "workflows", taskId);
46793
- if (!await pathExists16(path64.join(workflowPath, "requirements.md")) || !await pathExists16(path64.join(workflowPath, "plan.md"))) {
47559
+ const workflowPath = path66.join(rootDir, ".mancode", "workflows", taskId);
47560
+ if (!await pathExists16(path66.join(workflowPath, "requirements.md")) || !await pathExists16(path66.join(workflowPath, "plan.md"))) {
46794
47561
  return invalidArg(
46795
47562
  options,
46796
47563
  "solo handoff requires requirements.md and plan.md"
46797
47564
  );
46798
47565
  }
46799
- const statePath = path64.join(rootDir, ".mancode", "state.json");
47566
+ const statePath = path66.join(rootDir, ".mancode", "state.json");
46800
47567
  let originalState;
46801
47568
  let state;
46802
47569
  try {
46803
- originalState = await readFile45(statePath, "utf-8");
47570
+ originalState = await readFile47(statePath, "utf-8");
46804
47571
  state = JSON.parse(originalState);
46805
47572
  } catch {
46806
47573
  return invalidArg(
@@ -46861,7 +47628,7 @@ async function workflowHandoff(rootDir, taskId, options) {
46861
47628
  } else {
46862
47629
  console.log(`Handed off plan to solo: ${taskId}`);
46863
47630
  }
46864
- return EXIT_OK10;
47631
+ return EXIT_OK11;
46865
47632
  }
46866
47633
  async function workflowCompleteHandoff(rootDir, taskId, options) {
46867
47634
  const meta = await readWorkflow(rootDir, taskId);
@@ -46871,11 +47638,11 @@ async function workflowCompleteHandoff(rootDir, taskId, options) {
46871
47638
  `workflow is not an active solo handoff: ${taskId}`
46872
47639
  );
46873
47640
  }
46874
- const statePath = path64.join(rootDir, ".mancode", "state.json");
47641
+ const statePath = path66.join(rootDir, ".mancode", "state.json");
46875
47642
  let originalState;
46876
47643
  let state;
46877
47644
  try {
46878
- originalState = await readFile45(statePath, "utf-8");
47645
+ originalState = await readFile47(statePath, "utf-8");
46879
47646
  state = JSON.parse(originalState);
46880
47647
  } catch {
46881
47648
  return invalidArg(
@@ -46913,7 +47680,7 @@ async function workflowCompleteHandoff(rootDir, taskId, options) {
46913
47680
  } else {
46914
47681
  console.log(`Completed solo handoff: ${taskId}`);
46915
47682
  }
46916
- return EXIT_OK10;
47683
+ return EXIT_OK11;
46917
47684
  }
46918
47685
  async function workflowDecide(rootDir, taskId, options) {
46919
47686
  if (!taskId || !isValidWorkflowTaskId(taskId)) {
@@ -46938,18 +47705,18 @@ async function workflowDecide(rootDir, taskId, options) {
46938
47705
  `workflow is not ready for a plan-only decision: ${taskId}`
46939
47706
  );
46940
47707
  }
46941
- const workflowPath = path64.join(rootDir, ".mancode", "workflows", taskId);
46942
- if (!await pathExists16(path64.join(workflowPath, "requirements.md")) || !await pathExists16(path64.join(workflowPath, "plan.md"))) {
47708
+ const workflowPath = path66.join(rootDir, ".mancode", "workflows", taskId);
47709
+ if (!await pathExists16(path66.join(workflowPath, "requirements.md")) || !await pathExists16(path66.join(workflowPath, "plan.md"))) {
46943
47710
  return invalidArg(
46944
47711
  options,
46945
47712
  "plan-only requires requirements.md and plan.md"
46946
47713
  );
46947
47714
  }
46948
- const statePath = path64.join(rootDir, ".mancode", "state.json");
47715
+ const statePath = path66.join(rootDir, ".mancode", "state.json");
46949
47716
  let originalState;
46950
47717
  let state;
46951
47718
  try {
46952
- originalState = await readFile45(statePath, "utf-8");
47719
+ originalState = await readFile47(statePath, "utf-8");
46953
47720
  state = JSON.parse(originalState);
46954
47721
  } catch {
46955
47722
  return invalidArg(
@@ -46998,28 +47765,28 @@ async function workflowDecide(rootDir, taskId, options) {
46998
47765
  } else {
46999
47766
  console.log(`Saved plan without execution: ${taskId}`);
47000
47767
  }
47001
- return EXIT_OK10;
47768
+ return EXIT_OK11;
47002
47769
  }
47003
47770
  async function commitPlanningTransition(args) {
47004
- const metadataPath3 = path64.join(
47771
+ const metadataPath3 = path66.join(
47005
47772
  args.rootDir,
47006
47773
  ".mancode",
47007
47774
  "workflows",
47008
47775
  args.taskId,
47009
47776
  "metadata.json"
47010
47777
  );
47011
- const specPath = path64.join(args.rootDir, ".mancode", "memory", "spec.md");
47778
+ const specPath = path66.join(args.rootDir, ".mancode", "memory", "spec.md");
47012
47779
  let originalMetadata;
47013
47780
  let originalSpec;
47014
47781
  try {
47015
- originalMetadata = await readFile45(metadataPath3, "utf-8");
47782
+ originalMetadata = await readFile47(metadataPath3, "utf-8");
47016
47783
  originalSpec = await readOptionalText2(specPath);
47017
47784
  } catch (error) {
47018
47785
  return error instanceof Error ? `unable to prepare planning transition: ${error.message}` : "unable to prepare planning transition";
47019
47786
  }
47020
47787
  try {
47021
47788
  await updateWorkflow(args.rootDir, args.taskId, args.workflowPatch);
47022
- await writeFile46(
47789
+ await writeFile47(
47023
47790
  args.statePath,
47024
47791
  `${JSON.stringify(args.nextState, null, 2)}
47025
47792
  `,
@@ -47033,9 +47800,9 @@ async function commitPlanningTransition(args) {
47033
47800
  return null;
47034
47801
  } catch (error) {
47035
47802
  const rollback = await Promise.allSettled([
47036
- writeFile46(metadataPath3, originalMetadata, "utf-8"),
47037
- writeFile46(args.statePath, args.originalState, "utf-8"),
47038
- originalSpec === null ? rm21(specPath, { force: true }) : writeFile46(specPath, originalSpec, "utf-8")
47803
+ writeFile47(metadataPath3, originalMetadata, "utf-8"),
47804
+ writeFile47(args.statePath, args.originalState, "utf-8"),
47805
+ originalSpec === null ? rm22(specPath, { force: true }) : writeFile47(specPath, originalSpec, "utf-8")
47039
47806
  ]);
47040
47807
  const message = error instanceof Error ? error.message : "planning transition failed";
47041
47808
  return rollback.some((result2) => result2.status === "rejected") ? `${message}; rollback was incomplete` : message;
@@ -47043,7 +47810,7 @@ async function commitPlanningTransition(args) {
47043
47810
  }
47044
47811
  async function readOptionalText2(filePath) {
47045
47812
  try {
47046
- return await readFile45(filePath, "utf-8");
47813
+ return await readFile47(filePath, "utf-8");
47047
47814
  } catch (error) {
47048
47815
  if (isNodeError10(error) && error.code === "ENOENT") return null;
47049
47816
  throw error;
@@ -47051,10 +47818,10 @@ async function readOptionalText2(filePath) {
47051
47818
  }
47052
47819
  async function restoreOptionalText(filePath, content) {
47053
47820
  if (content === null) {
47054
- await rm21(filePath, { force: true });
47821
+ await rm22(filePath, { force: true });
47055
47822
  return;
47056
47823
  }
47057
- await writeFile46(filePath, content, "utf-8");
47824
+ await writeFile47(filePath, content, "utf-8");
47058
47825
  }
47059
47826
  function readActiveSoloPlan(value) {
47060
47827
  if (!value || typeof value !== "object") return null;
@@ -47072,11 +47839,11 @@ async function workflowList(rootDir, options) {
47072
47839
  const views = attachActiveChildren(workflows);
47073
47840
  if (options.json) {
47074
47841
  console.log(JSON.stringify(views, null, 2));
47075
- return EXIT_OK10;
47842
+ return EXIT_OK11;
47076
47843
  }
47077
47844
  if (workflows.length === 0) {
47078
47845
  console.log("No workflows.");
47079
- return EXIT_OK10;
47846
+ return EXIT_OK11;
47080
47847
  }
47081
47848
  const inProgress = workflows.filter((w) => w.status === "in_progress").length;
47082
47849
  console.log(
@@ -47086,7 +47853,7 @@ async function workflowList(rootDir, options) {
47086
47853
  for (const meta of views) {
47087
47854
  console.log(formatWorkflowRow(meta));
47088
47855
  }
47089
- return EXIT_OK10;
47856
+ return EXIT_OK11;
47090
47857
  }
47091
47858
  async function workflowShow(rootDir, taskId, options) {
47092
47859
  if (!taskId) {
@@ -47123,7 +47890,7 @@ async function workflowShow(rootDir, taskId, options) {
47123
47890
  2
47124
47891
  )
47125
47892
  );
47126
- return EXIT_OK10;
47893
+ return EXIT_OK11;
47127
47894
  }
47128
47895
  console.log(`Workflow: ${meta.taskId}`);
47129
47896
  console.log(`Task: ${meta.task}`);
@@ -47155,7 +47922,7 @@ async function workflowShow(rootDir, taskId, options) {
47155
47922
  }
47156
47923
  }
47157
47924
  }
47158
- return EXIT_OK10;
47925
+ return EXIT_OK11;
47159
47926
  }
47160
47927
  async function workflowClean(rootDir, options) {
47161
47928
  const workflows = await listWorkflows(rootDir);
@@ -47223,7 +47990,7 @@ async function workflowClean(rootDir, options) {
47223
47990
  } else {
47224
47991
  console.log(`Removed ${removed.length} workflow(s).`);
47225
47992
  }
47226
- return EXIT_OK10;
47993
+ return EXIT_OK11;
47227
47994
  }
47228
47995
  function formatWorkflowRow(meta) {
47229
47996
  const stepMax = maxWorkflowStep(meta.mode);
@@ -47693,8 +48460,24 @@ program.command("manps [area]").description("Run deterministic preseason health
47693
48460
  const code = await manps(process.cwd(), area ?? "all", options);
47694
48461
  process.exitCode = code;
47695
48462
  });
47696
- program.command("refresh-style").description("Refresh project profile and rescan applicable design tokens").action(async () => {
47697
- const code = await refreshStyle(process.cwd());
48463
+ var designProgram = program.command("design").description("Inspect and configure project UI design policy");
48464
+ designProgram.command("status").description("Show the configured and effective project design policy").option("--json", "Output as JSON (for scripts)").action(async (options) => {
48465
+ process.exitCode = await designStatus(process.cwd(), options);
48466
+ });
48467
+ designProgram.command("context").description("Emit bounded UI design context for coding agents").option("--json", "Output as JSON (for scripts)").action(async (options) => {
48468
+ process.exitCode = await designContext(process.cwd(), options);
48469
+ });
48470
+ designProgram.command("configure").description("CAS-update the optional project design policy").requiredOption(
48471
+ "--expected-revision <n>",
48472
+ "Current policy revision; use 0 when absent"
48473
+ ).option("--preset <preset>", "preserve, refine, or experimental").option("--icons <policy>", "existing-first or lucide").option("--emoji <policy>", "allow or forbid-as-interface-icon").option("--motion <policy>", "minimal or purposeful").option("--browser-validation <mode>", "off, when-available, or required").option("--confirm-experimental", "Explicitly allow the experimental preset").option("--json", "Output as JSON (for scripts)").action(async (options) => {
48474
+ process.exitCode = await designConfigure(process.cwd(), options);
48475
+ });
48476
+ designProgram.command("disable").description("Disable the project design policy without deleting it").requiredOption("--expected-revision <n>", "Current policy revision").option("--json", "Output as JSON (for scripts)").action(async (options) => {
48477
+ process.exitCode = await designDisable(process.cwd(), options);
48478
+ });
48479
+ program.command("refresh-style").description("Refresh project profile and rescan applicable design tokens").option("--root <path>", "Repository-relative UI project root").action(async (options) => {
48480
+ const code = await refreshStyle(process.cwd(), options);
47698
48481
  process.exitCode = code;
47699
48482
  });
47700
48483
  program.command("refresh-project").description(