mancode 0.5.2 → 0.5.4
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/README.en.md +295 -325
- package/README.md +244 -282
- package/dist/{chunk-2JOKDC3X.js → chunk-PQDAFZYS.js} +9 -2
- package/dist/chunk-PQDAFZYS.js.map +1 -0
- package/dist/cli.js +82 -33
- package/dist/cli.js.map +1 -1
- package/dist/{v3-adapter-DBVEX5H5.js → v3-adapter-NEN5F32W.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-2JOKDC3X.js.map +0 -1
- /package/dist/{v3-adapter-DBVEX5H5.js.map → v3-adapter-NEN5F32W.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -115,9 +115,11 @@ import {
|
|
|
115
115
|
import {
|
|
116
116
|
DEFAULT_MANCODE_END_MARKER,
|
|
117
117
|
DEFAULT_MANCODE_START_MARKER,
|
|
118
|
+
INTERFACE_EMOJI_ICON_GUIDANCE,
|
|
118
119
|
V3_ADAPTER_FILE_TARGETS,
|
|
119
120
|
V3_ADAPTER_PLATFORMS,
|
|
120
121
|
V3_ADAPTER_VERSION,
|
|
122
|
+
VISUAL_DIRECTION_SELECTION_GUIDANCE,
|
|
121
123
|
adapterManagedContentDigest,
|
|
122
124
|
applyV3AdapterFilePlan,
|
|
123
125
|
assertV3AdapterInstallable,
|
|
@@ -134,7 +136,7 @@ import {
|
|
|
134
136
|
stageV3AdapterUpgradeFiles,
|
|
135
137
|
v3AdapterTargetPath,
|
|
136
138
|
v3AdapterVersionsFromStatuses
|
|
137
|
-
} from "./chunk-
|
|
139
|
+
} from "./chunk-PQDAFZYS.js";
|
|
138
140
|
|
|
139
141
|
// src/cli.ts
|
|
140
142
|
import { Option, program } from "commander";
|
|
@@ -9883,7 +9885,7 @@ async function activateLegacyMigration(input) {
|
|
|
9883
9885
|
for (const action of payload.actions.filter(
|
|
9884
9886
|
(action2) => action2.kind === "v3_adapter_file"
|
|
9885
9887
|
)) {
|
|
9886
|
-
const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-
|
|
9888
|
+
const { applyV3AdapterFilePlan: applyV3AdapterFilePlan2 } = await import("./v3-adapter-NEN5F32W.js");
|
|
9887
9889
|
await applyV3AdapterFilePlan2(root, action);
|
|
9888
9890
|
}
|
|
9889
9891
|
journal = await completeActivationStep(
|
|
@@ -13739,7 +13741,7 @@ async function upgradeV3Adapters(input) {
|
|
|
13739
13741
|
if (unfinished.length > 0) {
|
|
13740
13742
|
throw new Error("MANCODE_ADAPTER_UPGRADE_OPERATION_PENDING");
|
|
13741
13743
|
}
|
|
13742
|
-
const actualVersions = await import("./v3-adapter-
|
|
13744
|
+
const actualVersions = await import("./v3-adapter-NEN5F32W.js").then(
|
|
13743
13745
|
({ inspectV3AdapterVersions: inspectV3AdapterVersions2 }) => inspectV3AdapterVersions2(
|
|
13744
13746
|
root,
|
|
13745
13747
|
managedAdapterNames(project.manifest.managedAdapters)
|
|
@@ -14652,7 +14654,8 @@ trigger: <\u5177\u4F53\u4E8B\u5B9E>
|
|
|
14652
14654
|
- \u6539\u52A8\u5B64\u7ACB\u4E86\u67D0\u4E2A import / \u53D8\u91CF / \u51FD\u6570 \u2192 \u79FB\u9664\u5B83
|
|
14653
14655
|
- \u4E0D\u79FB\u9664\u6539\u52A8\u524D\u5C31\u5B58\u5728\u7684\u6B7B\u4EE3\u7801\uFF08\u63D0\u4E00\u53E5\u5C31\u884C\uFF09
|
|
14654
14656
|
- \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
|
|
14655
|
-
- \
|
|
14657
|
+
- \u754C\u9762\u56FE\u6807\u3001\u5BFC\u822A\u3001\u6309\u94AE\u3001\u64CD\u4F5C\u548C\u72B6\u6001\u6807\u8BC6\u7981\u6B62\u4F7F\u7528\u8868\u60C5\u7B26\u53F7\uFF1B\u804A\u5929\u6D88\u606F\u3001\u7528\u6237\u8F93\u5165\u3001\u6B63\u6587\u548C\u4E1A\u52A1\u6570\u636E\u53EF\u4EE5\u5305\u542B\u8868\u60C5\u3002\u6CA1\u6709\u53EF\u7528\u56FE\u6807\u5E93\u65F6\u4F7F\u7528\u6E05\u6670\u6587\u5B57\u6807\u7B7E\u6216\u8BF7\u6C42\u5B89\u88C5\u56FE\u6807\u5E93\uFF0C\u4E0D\u80FD\u9000\u56DE\u8868\u60C5\u56FE\u6807
|
|
14658
|
+
- \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\u201C\u4F01\u4E1A\u7EA7\u201D\u201C\u7B80\u6D01\u201D\u201C\u73B0\u4EE3\u201D\u201C\u9AD8\u7EA7\u201D\u201C\u4E0D\u82B1\u54E8\u201D\u7B49\u5BBD\u6CDB\u5F62\u5BB9\u8BCD\u53EA\u662F\u7EA6\u675F\uFF0C\u4E0D\u7B97\u5DF2\u7ECF\u9009\u5B9A\u89C6\u89C9\u65B9\u5411\uFF1B\u5C40\u90E8 UI \u4FEE\u590D\u6216\u5DF2\u6709\u65B9\u5411\u5185\u7684\u5DE5\u4F5C\u76F4\u63A5\u6267\u884C
|
|
14656
14659
|
|
|
14657
14660
|
---
|
|
14658
14661
|
|
|
@@ -15059,6 +15062,8 @@ const state = readJson(path.join(mancodeDir, 'state.json')) || {};
|
|
|
15059
15062
|
const profile = readJson(path.join(mancodeDir, 'project-profile.json')) || {};
|
|
15060
15063
|
const mode = typeof state.currentMode === 'string' ? state.currentMode : '';
|
|
15061
15064
|
const output = [];
|
|
15065
|
+
const interfaceEmojiIconGuidance = ${JSON.stringify(INTERFACE_EMOJI_ICON_GUIDANCE)};
|
|
15066
|
+
const visualDirectionSelectionGuidance = ${JSON.stringify(VISUAL_DIRECTION_SELECTION_GUIDANCE)};
|
|
15062
15067
|
|
|
15063
15068
|
if (mode === 'solo') {
|
|
15064
15069
|
output.push(
|
|
@@ -15122,9 +15127,25 @@ if (
|
|
|
15122
15127
|
);
|
|
15123
15128
|
}
|
|
15124
15129
|
|
|
15125
|
-
const
|
|
15130
|
+
const strongUiPattern = /\b(?:ui|ux|front-?end|html|web ?page|page|button|icon|lucide|layout|css|card|modal|dialog|header|footer|sidebar|navigation|navbar|menu|dropdown|tooltip|toast|avatar|badge|dashboard|status indicator)s?\b|界面|页面|网页|前端|按钮|图标|布局|弹窗|导航|菜单|卡片|状态标识|状态图标|美化|优化.*界面|调整.*样式/iu;
|
|
15131
|
+
const weakVisualPattern = /\b(?:component|style|design|color|font|theme|input|visual|aesthetic)s?\b|样式|颜色|字体|主题|组件|输入框|审美|视觉|美观|好看/iu;
|
|
15132
|
+
const hasStrongUiSignal = strongUiPattern.test(userPrompt);
|
|
15133
|
+
const hasWeakVisualSignal = weakVisualPattern.test(userPrompt);
|
|
15134
|
+
const isUiPrompt =
|
|
15135
|
+
hasStrongUiSignal ||
|
|
15136
|
+
(profile.uiAssets === 'detected' && hasWeakVisualSignal);
|
|
15126
15137
|
|
|
15127
|
-
if (
|
|
15138
|
+
if (isUiPrompt) {
|
|
15139
|
+
output.push(
|
|
15140
|
+
'## mancode UI design baseline',
|
|
15141
|
+
'',
|
|
15142
|
+
interfaceEmojiIconGuidance,
|
|
15143
|
+
visualDirectionSelectionGuidance,
|
|
15144
|
+
'',
|
|
15145
|
+
);
|
|
15146
|
+
}
|
|
15147
|
+
|
|
15148
|
+
if (profile.uiAssets === 'detected' && isUiPrompt) {
|
|
15128
15149
|
appendAestheticSummary(
|
|
15129
15150
|
output,
|
|
15130
15151
|
readJson(path.join(mancodeDir, 'aesthetics', 'style-tokens.json')),
|
|
@@ -15266,11 +15287,13 @@ trigger: <\u5177\u4F53\u4E8B\u5B9E>
|
|
|
15266
15287
|
\u8FD9\u662F\u53EA\u8BFB\u8BCA\u65AD\u3002\u4FDD\u7559 requirements\u3001plan\u3001review/verification ledger\u3001claims\u3001handoff \u548C metadata\uFF1B\u4E0D\u8C03\u7528\u901A\u7528 \`workflow update\`\uFF0C\u4E0D\u5199 blocked/currentStep/planning\uFF0C\u4E0D\u5F52\u6863\u65E7\u6587\u4EF6\uFF0C\u4E0D\u91CA\u653E claim\uFF0C\u4E0D\u53D6\u6D88 handoff\uFF0C\u4E5F\u4E0D\u5BA3\u79F0\u5DF2\u56DE\u5230 Step 2\u3002
|
|
15267
15288
|
|
|
15268
15289
|
### UI \u4EFB\u52A1\uFF08\u6761\u4EF6\u6267\u884C\uFF09
|
|
15269
|
-
\
|
|
15270
|
-
|
|
15271
|
-
|
|
15272
|
-
|
|
15273
|
-
|
|
15290
|
+
\u4EFB\u52A1\u6D89\u53CA\u754C\u9762\u65F6\uFF1A
|
|
15291
|
+
- ${INTERFACE_EMOJI_ICON_GUIDANCE}
|
|
15292
|
+
- ${VISUAL_DIRECTION_SELECTION_GUIDANCE}
|
|
15293
|
+
- project-profile \u786E\u8BA4\u6709 UI \u8D44\u4EA7\u65F6\uFF0CUserPromptSubmit hook \u4F1A\u6CE8\u5165\u9879\u76EE\u5BA1\u7F8E token\uFF08\u5982\u6709\uFF09
|
|
15294
|
+
- \u4E25\u683C\u4F7F\u7528\u5DF2\u6709 token \u548C\u7EC4\u4EF6\uFF1B\u6CA1\u6709\u53EF\u9760 token \u65F6\u5148\u68C0\u67E5\u73B0\u6709\u754C\u9762\uFF0C\u518D\u63D0\u51FA\u6700\u5C0F\u4E00\u81F4\u65B9\u6848
|
|
15295
|
+
- \u4E0D\u628A\u7279\u5B9A\u6846\u67B6\u3001\u7EC4\u4EF6\u540D\u3001\u8272\u677F\u6216\u4EA4\u4E92\u8303\u5F0F\u5F53\u4F5C\u9ED8\u8BA4
|
|
15296
|
+
- \u4EE5\u9879\u76EE\u65E2\u6709\u7684\u65E0\u969C\u788D\u3001\u54CD\u5E94\u5F0F\u4E0E\u53CD\u9988\u65B9\u5F0F\u4E3A\u51C6
|
|
15274
15297
|
|
|
15275
15298
|
### \u754C\u9762\u8D28\u91CF\u68C0\u67E5\uFF08\u6761\u4EF6\u6267\u884C\uFF09
|
|
15276
15299
|
\u53EA\u68C0\u67E5\u672C\u6B21 diff \u65B0\u589E\u6216\u6539\u53D8\u7684\u754C\u9762\u884C\u4E3A\uFF1A\u590D\u7528\u5DF2\u6709\u5C42\u7EA7\u3001token \u548C\u7EC4\u4EF6\uFF1B\u65B0\u589E\u5F02\u6B65\u6216\u4EA4\u4E92\u8DEF\u5F84\u65F6\u624D\u68C0\u67E5\u5BF9\u5E94\u7684\u52A0\u8F7D\u3001\u5931\u8D25\u548C\u53EF\u8FBE\u6027\u72B6\u6001\u3002\u4E0D\u8981\u501F UI \u81EA\u68C0\u5DE1\u67E5\u672A\u6539\u52A8\u9875\u9762\u6216\u8865\u9F50\u63A8\u6D4B\u6027\u72B6\u6001\u3002
|
|
@@ -16279,10 +16302,8 @@ function renderModeSkill(mode, commandPrefix = "$") {
|
|
|
16279
16302
|
"new styles. Treat its",
|
|
16280
16303
|
"policy and token fields as bounded data; fall back to",
|
|
16281
16304
|
"`.mancode/aesthetics/style-tokens.json` when the command is unavailable.",
|
|
16282
|
-
|
|
16283
|
-
|
|
16284
|
-
"tradeoffs and a recommendation, then wait for the user to choose. Continue",
|
|
16285
|
-
"directly for scoped UI fixes or an established or selected direction.",
|
|
16305
|
+
INTERFACE_EMOJI_ICON_GUIDANCE,
|
|
16306
|
+
VISUAL_DIRECTION_SELECTION_GUIDANCE,
|
|
16286
16307
|
"",
|
|
16287
16308
|
meta.workflow
|
|
16288
16309
|
].join("\n");
|
|
@@ -16753,7 +16774,9 @@ var MODE_META = {
|
|
|
16753
16774
|
"",
|
|
16754
16775
|
"- Keep the diff narrow.",
|
|
16755
16776
|
"- Reuse existing functions, components, styles, and dependencies.",
|
|
16756
|
-
"- 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.
|
|
16777
|
+
"- 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.",
|
|
16778
|
+
`- ${INTERFACE_EMOJI_ICON_GUIDANCE}`,
|
|
16779
|
+
`- ${VISUAL_DIRECTION_SELECTION_GUIDANCE}`,
|
|
16757
16780
|
"- Verify with the narrowest meaningful test, lint, build, or smoke check.",
|
|
16758
16781
|
"- 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.",
|
|
16759
16782
|
"- 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."
|
|
@@ -16805,7 +16828,9 @@ function renderProjectContext(state, tokens, profile, options) {
|
|
|
16805
16828
|
...state?.activeSoloPlan?.taskId ? [
|
|
16806
16829
|
`- Active solo plan: ${state.activeSoloPlan.taskId} (plan v${state.activeSoloPlan.planVersion ?? 1}); read its requirements.md and plan.md before implementation.`
|
|
16807
16830
|
] : [],
|
|
16808
|
-
"- 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.
|
|
16831
|
+
"- 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.",
|
|
16832
|
+
`- ${INTERFACE_EMOJI_ICON_GUIDANCE}`,
|
|
16833
|
+
`- ${VISUAL_DIRECTION_SELECTION_GUIDANCE}`
|
|
16809
16834
|
].join("\n");
|
|
16810
16835
|
}
|
|
16811
16836
|
function renderPracticeRules() {
|
|
@@ -17227,7 +17252,9 @@ function renderSoloRule() {
|
|
|
17227
17252
|
"",
|
|
17228
17253
|
"- Keep the diff narrow.",
|
|
17229
17254
|
"- Reuse existing functions, components, styles, and dependencies.",
|
|
17230
|
-
"- 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.
|
|
17255
|
+
"- 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. A design policy never expands confirmed task scope.",
|
|
17256
|
+
`- ${INTERFACE_EMOJI_ICON_GUIDANCE}`,
|
|
17257
|
+
`- ${VISUAL_DIRECTION_SELECTION_GUIDANCE}`,
|
|
17231
17258
|
"- Verify with the narrowest meaningful test, lint, build, or smoke check.",
|
|
17232
17259
|
"- Perform one bounded self-check limited to the current diff. Do not start another reviewer, create a review artifact, or repeat the review.",
|
|
17233
17260
|
"- 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.",
|
|
@@ -26008,13 +26035,14 @@ async function configureDesignPolicy(input) {
|
|
|
26008
26035
|
if (currentRevision !== input.expectedRevision) {
|
|
26009
26036
|
throw new Error("MANCODE_EXPECTED_REVISION_CONFLICT");
|
|
26010
26037
|
}
|
|
26038
|
+
const emojiPolicy = input.emojiPolicy ?? current?.emojiPolicy ?? DEFAULT_DESIGN_POLICY.emojiPolicy;
|
|
26011
26039
|
const next = parseDesignPolicy({
|
|
26012
26040
|
...current ?? DEFAULT_DESIGN_POLICY,
|
|
26013
26041
|
revision: currentRevision + 1,
|
|
26014
26042
|
enabled: input.enabled ?? current?.enabled ?? true,
|
|
26015
26043
|
preset: input.preset ?? current?.preset ?? DEFAULT_DESIGN_POLICY.preset,
|
|
26016
26044
|
iconPolicy: input.iconPolicy ?? current?.iconPolicy ?? DEFAULT_DESIGN_POLICY.iconPolicy,
|
|
26017
|
-
emojiPolicy:
|
|
26045
|
+
emojiPolicy: emojiPolicy === "allow" ? "forbid-as-interface-icon" : emojiPolicy,
|
|
26018
26046
|
motionPolicy: input.motionPolicy ?? current?.motionPolicy ?? DEFAULT_DESIGN_POLICY.motionPolicy,
|
|
26019
26047
|
browserValidation: input.browserValidation ?? current?.browserValidation ?? DEFAULT_DESIGN_POLICY.browserValidation,
|
|
26020
26048
|
lastOperationId: operationId,
|
|
@@ -26134,12 +26162,14 @@ async function designStatus(rootDir = process2.cwd(), options = {}) {
|
|
|
26134
26162
|
policyStatus: policyResult.status,
|
|
26135
26163
|
policy: policyResult.policy,
|
|
26136
26164
|
effectivePreset: policyResult.policy?.enabled === true ? policyResult.policy.preset : "preserve",
|
|
26165
|
+
effectiveEmojiPolicy: "forbid-as-interface-icon",
|
|
26137
26166
|
policyPath: relativePath(rootDir, designPolicyPath(rootDir)),
|
|
26138
|
-
warning: policyResult.warning
|
|
26167
|
+
warning: effectivePolicyWarning(policyResult.policy, policyResult.warning)
|
|
26139
26168
|
};
|
|
26140
26169
|
return printResult(options.json, payload, [
|
|
26141
26170
|
`Design policy: ${payload.policyStatus}`,
|
|
26142
26171
|
`Effective preset: ${payload.effectivePreset}`,
|
|
26172
|
+
`Effective emoji policy: ${payload.effectiveEmojiPolicy}`,
|
|
26143
26173
|
`Revision: ${payload.policy?.revision ?? 0}`,
|
|
26144
26174
|
...payload.warning === null ? [] : [`Warning: ${payload.warning}`]
|
|
26145
26175
|
]);
|
|
@@ -26162,7 +26192,7 @@ async function designContext(rootDir = process2.cwd(), options = {}) {
|
|
|
26162
26192
|
]);
|
|
26163
26193
|
const configured = policyResult.policy;
|
|
26164
26194
|
const active = configured?.enabled === true;
|
|
26165
|
-
const policy = active ? configured : disabledPolicy();
|
|
26195
|
+
const policy = effectivePolicy(active ? configured : disabledPolicy());
|
|
26166
26196
|
const rootUiDetected = profile?.uiAssets === "detected";
|
|
26167
26197
|
const scopedUiDetected = style.scopeRoot !== "." && style.lastScanned !== null;
|
|
26168
26198
|
const applicable = rootUiDetected || scopedUiDetected;
|
|
@@ -26185,10 +26215,16 @@ async function designContext(rootDir = process2.cwd(), options = {}) {
|
|
|
26185
26215
|
doNotExpandTaskScope: true,
|
|
26186
26216
|
reuseExistingDesignSystem: true,
|
|
26187
26217
|
dependencyChangesRequireTaskApproval: true,
|
|
26188
|
-
experimentalDoesNotAuthorizeProductChanges: true
|
|
26218
|
+
experimentalDoesNotAuthorizeProductChanges: true,
|
|
26219
|
+
interfaceEmojiIconsForbidden: true,
|
|
26220
|
+
contentEmojiAllowed: true,
|
|
26221
|
+
iconFallbackMustNotBeEmoji: true
|
|
26189
26222
|
} : {
|
|
26190
26223
|
doNotExpandTaskScope: true,
|
|
26191
|
-
reuseExistingDesignSystem: true
|
|
26224
|
+
reuseExistingDesignSystem: true,
|
|
26225
|
+
interfaceEmojiIconsForbidden: true,
|
|
26226
|
+
contentEmojiAllowed: true,
|
|
26227
|
+
iconFallbackMustNotBeEmoji: true
|
|
26192
26228
|
},
|
|
26193
26229
|
project: {
|
|
26194
26230
|
kind: profile?.projectKind ?? "unknown",
|
|
@@ -26198,7 +26234,7 @@ async function designContext(rootDir = process2.cwd(), options = {}) {
|
|
|
26198
26234
|
guidance: designGuidance(policy),
|
|
26199
26235
|
qualityGates: designQualityGates(policy),
|
|
26200
26236
|
style,
|
|
26201
|
-
warning: policyResult.warning
|
|
26237
|
+
warning: effectivePolicyWarning(configured, policyResult.warning)
|
|
26202
26238
|
};
|
|
26203
26239
|
return printResult(options.json, payload, [
|
|
26204
26240
|
`Applicable: ${payload.applicable ? "yes" : "no"}`,
|
|
@@ -26237,6 +26273,7 @@ async function designConfigure(rootDir, options) {
|
|
|
26237
26273
|
);
|
|
26238
26274
|
}
|
|
26239
26275
|
try {
|
|
26276
|
+
const legacyEmojiAllow = options.emoji === "allow";
|
|
26240
26277
|
const result2 = await configureDesignPolicy({
|
|
26241
26278
|
projectRoot: rootDir,
|
|
26242
26279
|
expectedRevision,
|
|
@@ -26244,9 +26281,11 @@ async function designConfigure(rootDir, options) {
|
|
|
26244
26281
|
confirmExperimental: options.confirmExperimental,
|
|
26245
26282
|
...values
|
|
26246
26283
|
});
|
|
26247
|
-
|
|
26284
|
+
const warning = legacyEmojiAllow ? "--emoji allow is deprecated and was normalized to forbid-as-interface-icon; emoji remains allowed in user-authored content, chat messages, editorial copy, and domain data." : null;
|
|
26285
|
+
return printResult(options.json, { schemaVersion: 1, ...result2, warning }, [
|
|
26248
26286
|
`Design policy configured: ${result2.policy.preset}`,
|
|
26249
|
-
`Revision: ${result2.policy.revision}
|
|
26287
|
+
`Revision: ${result2.policy.revision}`,
|
|
26288
|
+
...warning === null ? [] : [`Warning: ${warning}`]
|
|
26250
26289
|
]);
|
|
26251
26290
|
} catch (error) {
|
|
26252
26291
|
const code = errorCode3(error, "MANCODE_DESIGN_CONFIGURE_FAILED");
|
|
@@ -26304,7 +26343,7 @@ function parseConfigureValues(options) {
|
|
|
26304
26343
|
return {
|
|
26305
26344
|
preset: options.preset,
|
|
26306
26345
|
iconPolicy: options.icons,
|
|
26307
|
-
emojiPolicy: options.emoji,
|
|
26346
|
+
emojiPolicy: options.emoji === "allow" ? "forbid-as-interface-icon" : options.emoji,
|
|
26308
26347
|
motionPolicy: options.motion,
|
|
26309
26348
|
browserValidation: options.browserValidation
|
|
26310
26349
|
};
|
|
@@ -26389,22 +26428,28 @@ async function styleFreshness(rootDir, scopeRoot, lastScanned, sourceFiles) {
|
|
|
26389
26428
|
function disabledPolicy() {
|
|
26390
26429
|
return {
|
|
26391
26430
|
...DEFAULT_DESIGN_POLICY,
|
|
26392
|
-
emojiPolicy: "allow",
|
|
26393
26431
|
motionPolicy: "minimal",
|
|
26394
26432
|
browserValidation: "off"
|
|
26395
26433
|
};
|
|
26396
26434
|
}
|
|
26435
|
+
function effectivePolicy(policy) {
|
|
26436
|
+
return policy.emojiPolicy === "forbid-as-interface-icon" ? policy : { ...policy, emojiPolicy: "forbid-as-interface-icon" };
|
|
26437
|
+
}
|
|
26438
|
+
function effectivePolicyWarning(policy, warning) {
|
|
26439
|
+
const legacyWarning = policy?.emojiPolicy === "allow" ? 'The legacy emoji policy "allow" is constrained to forbid-as-interface-icon; emoji remains allowed in user-authored content, chat messages, editorial copy, and domain data.' : null;
|
|
26440
|
+
return [warning, legacyWarning].filter(Boolean).join(" ") || null;
|
|
26441
|
+
}
|
|
26397
26442
|
function designGuidance(policy) {
|
|
26398
26443
|
return [
|
|
26399
26444
|
directionSelectionGuidance(),
|
|
26400
26445
|
presetGuidance(policy.preset),
|
|
26401
26446
|
iconGuidance(policy.iconPolicy),
|
|
26402
|
-
emojiGuidance(
|
|
26447
|
+
emojiGuidance(),
|
|
26403
26448
|
motionGuidance(policy.motionPolicy)
|
|
26404
26449
|
];
|
|
26405
26450
|
}
|
|
26406
26451
|
function directionSelectionGuidance() {
|
|
26407
|
-
return
|
|
26452
|
+
return VISUAL_DIRECTION_SELECTION_GUIDANCE;
|
|
26408
26453
|
}
|
|
26409
26454
|
function presetGuidance(preset) {
|
|
26410
26455
|
if (preset === "refine") {
|
|
@@ -26418,8 +26463,8 @@ function presetGuidance(preset) {
|
|
|
26418
26463
|
function iconGuidance(policy) {
|
|
26419
26464
|
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.";
|
|
26420
26465
|
}
|
|
26421
|
-
function emojiGuidance(
|
|
26422
|
-
return
|
|
26466
|
+
function emojiGuidance() {
|
|
26467
|
+
return INTERFACE_EMOJI_ICON_GUIDANCE.replace("Never use", "Do not use");
|
|
26423
26468
|
}
|
|
26424
26469
|
function motionGuidance(policy) {
|
|
26425
26470
|
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.";
|
|
@@ -26429,6 +26474,7 @@ function designQualityGates(policy) {
|
|
|
26429
26474
|
return [
|
|
26430
26475
|
"Preserve task-critical workflows, keyboard access, visible focus, readable contrast, and responsive behavior on changed surfaces.",
|
|
26431
26476
|
"Check changed surfaces for clipping, unintended overlap, horizontal overflow, and unstable layout.",
|
|
26477
|
+
"Inspect changed navigation, buttons, controls, actions, and status indicators to confirm that no emoji is used as an interface icon; do not flag emoji in user-authored content, chat messages, editorial copy, or domain data.",
|
|
26432
26478
|
browserGate
|
|
26433
26479
|
];
|
|
26434
26480
|
}
|
|
@@ -49174,7 +49220,10 @@ designProgram.command("context").description("Emit bounded UI design context for
|
|
|
49174
49220
|
designProgram.command("configure").description("CAS-update the optional project design policy").requiredOption(
|
|
49175
49221
|
"--expected-revision <n>",
|
|
49176
49222
|
"Current policy revision; use 0 when absent"
|
|
49177
|
-
).option("--preset <preset>", "preserve, refine, or experimental").option("--icons <policy>", "existing-first or lucide").option(
|
|
49223
|
+
).option("--preset <preset>", "preserve, refine, or experimental").option("--icons <policy>", "existing-first or lucide").option(
|
|
49224
|
+
"--emoji <policy>",
|
|
49225
|
+
"forbid-as-interface-icon; legacy allow is normalized"
|
|
49226
|
+
).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) => {
|
|
49178
49227
|
process.exitCode = await designConfigure(process.cwd(), options);
|
|
49179
49228
|
});
|
|
49180
49229
|
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) => {
|