ultimate-pi 0.20.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/.agents/skills/harness-decisions/SKILL.md +68 -2
  2. package/.agents/skills/harness-git-commit/SKILL.md +72 -0
  3. package/.agents/skills/harness-governor/SKILL.md +2 -2
  4. package/.agents/skills/harness-ls-lint-setup/SKILL.md +59 -0
  5. package/.agents/skills/harness-plan/SKILL.md +13 -11
  6. package/.agents/skills/harness-review/SKILL.md +1 -1
  7. package/.agents/skills/harness-sentrux-repair/SKILL.md +48 -0
  8. package/.agents/skills/sentrux/SKILL.md +4 -2
  9. package/.agents/skills/wiki-save/SKILL.md +1 -1
  10. package/.pi/PACKAGING.md +6 -0
  11. package/.pi/SYSTEM.md +21 -3
  12. package/.pi/agents/harness/ls-lint-steward.md +49 -0
  13. package/.pi/agents/harness/planning/decompose.md +4 -4
  14. package/.pi/agents/harness/reviewing/evaluator.md +1 -1
  15. package/.pi/agents/harness/running/executor.md +1 -1
  16. package/.pi/agents/harness/sentrux-repair-advisor.md +50 -0
  17. package/.pi/agents/pi-pi/prompt-expert.md +17 -2
  18. package/.pi/auto-commit.json +9 -2
  19. package/.pi/extensions/debate-orchestrator.ts +3 -0
  20. package/.pi/extensions/harness-anchored-edit.ts +7 -9
  21. package/.pi/extensions/harness-ask-user.ts +13 -34
  22. package/.pi/extensions/harness-debate-tools.ts +43 -4
  23. package/.pi/extensions/harness-live-widget.ts +28 -19
  24. package/.pi/extensions/harness-run-context.ts +278 -115
  25. package/.pi/extensions/harness-web-tools.ts +598 -471
  26. package/.pi/extensions/ls-lint-rules-sync.ts +103 -0
  27. package/.pi/extensions/observation-bus.ts +4 -0
  28. package/.pi/extensions/policy-gate.ts +270 -229
  29. package/.pi/extensions/sentrux-rules-sync.ts +2 -0
  30. package/.pi/extensions/soundboard.ts +48 -48
  31. package/.pi/harness/README.md +4 -0
  32. package/.pi/harness/agents.manifest.json +15 -7
  33. package/.pi/harness/agents.policy.yaml +49 -82
  34. package/.pi/harness/docs/adrs/0052-ls-lint-naming-lifecycle.md +45 -0
  35. package/.pi/harness/docs/adrs/0052-sentrux-structured-repair.md +38 -0
  36. package/.pi/harness/docs/adrs/0053-plan-task-clarification-gate.md +39 -0
  37. package/.pi/harness/docs/adrs/0054-harness-native-ask-user.md +40 -0
  38. package/.pi/harness/docs/adrs/0055-auto-commit-coauthor-lifecycle.md +40 -0
  39. package/.pi/harness/docs/adrs/README.md +5 -0
  40. package/.pi/harness/docs/practice-map.md +10 -5
  41. package/.pi/harness/evals/smoke/ls-lint-stub.json +10 -0
  42. package/.pi/harness/evolution/self-healing-rules.json +16 -0
  43. package/.pi/harness/ls-lint/naming.manifest.json +128 -0
  44. package/.pi/harness/sentrux/architecture.manifest.json +1 -1
  45. package/.pi/harness/specs/auto-commit.schema.json +63 -0
  46. package/.pi/harness/specs/ls-lint-manifest-proposal.schema.json +80 -0
  47. package/.pi/harness/specs/ls-lint-signal.schema.json +47 -0
  48. package/.pi/harness/specs/naming-manifest.schema.json +54 -0
  49. package/.pi/harness/specs/plan-task-clarification.schema.json +88 -0
  50. package/.pi/harness/specs/sentrux-diagnostics.schema.json +173 -0
  51. package/.pi/harness/specs/sentrux-repair-plan.schema.json +133 -0
  52. package/.pi/harness/specs/sentrux-report.schema.json +119 -0
  53. package/.pi/harness/specs/sentrux-signal.schema.json +34 -1
  54. package/.pi/lib/agents-policy.d.mts +26 -51
  55. package/.pi/lib/agents-policy.mjs +41 -28
  56. package/.pi/lib/agt/build-evaluation-context.ts +136 -64
  57. package/.pi/lib/ask-user/constants.mjs +3 -0
  58. package/.pi/lib/ask-user/constants.ts +4 -0
  59. package/.pi/lib/ask-user/contracts/glimpse-parse.ts +56 -0
  60. package/.pi/lib/ask-user/contracts/glimpse-payload-build.ts +58 -0
  61. package/.pi/lib/ask-user/contracts/glimpse-payload.ts +38 -0
  62. package/.pi/lib/ask-user/core/questionnaire.ts +74 -0
  63. package/.pi/lib/ask-user/dialog.ts +2 -314
  64. package/.pi/lib/ask-user/fallback.ts +2 -78
  65. package/.pi/lib/ask-user/format.ts +85 -0
  66. package/.pi/lib/ask-user/glimpseui.d.ts +10 -0
  67. package/.pi/lib/ask-user/index.ts +114 -0
  68. package/.pi/lib/ask-user/merge-task-clarification.ts +98 -0
  69. package/.pi/lib/ask-user/policy.mjs +43 -0
  70. package/.pi/lib/ask-user/policy.ts +104 -0
  71. package/.pi/lib/ask-user/presenters/glimpse.ts +130 -0
  72. package/.pi/lib/ask-user/presenters/headless.ts +131 -0
  73. package/.pi/lib/ask-user/presenters/select.ts +60 -0
  74. package/.pi/lib/ask-user/presenters/tui.ts +373 -0
  75. package/.pi/lib/ask-user/presenters/types.ts +13 -0
  76. package/.pi/lib/ask-user/render.ts +40 -9
  77. package/.pi/lib/ask-user/schema.ts +66 -13
  78. package/.pi/lib/ask-user/types.ts +60 -3
  79. package/.pi/lib/ask-user/validate-core.mjs +193 -7
  80. package/.pi/lib/ask-user/validate.ts +53 -34
  81. package/.pi/lib/harness-anchored-edit/package.json +3 -0
  82. package/.pi/lib/harness-artifact-gate.ts +75 -21
  83. package/.pi/lib/harness-auto-commit-config.mjs +321 -0
  84. package/.pi/lib/harness-lens/clients/lsp/client.ts +62 -39
  85. package/.pi/lib/harness-lens/clients/tool-policy.ts +73 -181
  86. package/.pi/lib/harness-lens/index.ts +241 -108
  87. package/.pi/lib/harness-lens/tools/lsp-navigation.ts +10 -8
  88. package/.pi/lib/harness-repair-brief.ts +84 -25
  89. package/.pi/lib/harness-run-context.ts +42 -52
  90. package/.pi/lib/harness-sentrux-parse.mjs +272 -0
  91. package/.pi/lib/harness-sentrux-root.mjs +78 -0
  92. package/.pi/lib/harness-slash-completions.ts +116 -0
  93. package/.pi/lib/harness-spawn-topology.ts +121 -87
  94. package/.pi/lib/harness-subagent-submit-registry.ts +10 -0
  95. package/.pi/lib/harness-subagents-bridge.ts +4 -1
  96. package/.pi/lib/harness-ui-state.ts +95 -48
  97. package/.pi/lib/plan-approval/dialog.ts +5 -0
  98. package/.pi/lib/plan-approval/validate.ts +1 -1
  99. package/.pi/lib/plan-approval-readiness.ts +32 -0
  100. package/.pi/lib/plan-debate-gate.ts +154 -114
  101. package/.pi/lib/plan-task-clarification.ts +158 -0
  102. package/.pi/prompts/harness-auto.md +2 -2
  103. package/.pi/prompts/harness-ls-lint-steward.md +43 -0
  104. package/.pi/prompts/harness-plan.md +58 -8
  105. package/.pi/prompts/harness-review.md +40 -6
  106. package/.pi/prompts/harness-run.md +33 -11
  107. package/.pi/prompts/harness-setup.md +72 -3
  108. package/.pi/prompts/harness-steer.md +2 -1
  109. package/.pi/prompts/wiki-save.md +5 -4
  110. package/.pi/scripts/README.md +8 -0
  111. package/.pi/scripts/generate-agents-policy-yaml.mjs +14 -2
  112. package/.pi/scripts/harness-auto-commit-bootstrap.mjs +96 -0
  113. package/.pi/scripts/harness-cli-verify.sh +47 -0
  114. package/.pi/scripts/harness-git-churn.mjs +77 -0
  115. package/.pi/scripts/harness-git-commit.mjs +173 -0
  116. package/.pi/scripts/harness-ls-lint-bootstrap.mjs +142 -0
  117. package/.pi/scripts/harness-ls-lint-cli.mjs +184 -0
  118. package/.pi/scripts/harness-seed-project-contracts.mjs +47 -0
  119. package/.pi/scripts/harness-sentrux-diagnostics.mjs +230 -0
  120. package/.pi/scripts/harness-sentrux-report.mjs +256 -0
  121. package/.pi/scripts/harness-verify.mjs +288 -125
  122. package/.pi/scripts/ls-lint-rules-sync.mjs +265 -0
  123. package/.pi/scripts/run-tests.mjs +1 -0
  124. package/.pi/settings.example.json +1 -0
  125. package/.sentrux/rules.toml +1 -1
  126. package/AGENTS.md +1 -0
  127. package/CHANGELOG.md +25 -0
  128. package/README.md +13 -4
  129. package/package.json +5 -1
  130. package/vendor/pi-vcc/src/hooks/before-compact.ts +86 -60
@@ -2,7 +2,8 @@
2
2
  "dryRun": false,
3
3
  "coAuthor": {
4
4
  "login": "pi-mono",
5
- "email": "261679550+pi-mono@users.noreply.github.com"
5
+ "email": "261679550+pi-mono@users.noreply.github.com",
6
+ "required": true
6
7
  },
7
8
  "branch": {
8
9
  "strategy": "auto-feature-branch",
@@ -15,6 +16,12 @@
15
16
  "ignore": true
16
17
  },
17
18
  "message": {
18
- "scopeDefault": "harness"
19
+ "template": "{type}({scope}): {subject}",
20
+ "templateNoScope": "{type}: {subject}",
21
+ "typeDefault": "chore",
22
+ "scopeDefault": "harness",
23
+ "bodySeparator": "\n\n",
24
+ "coAuthorTrailer": "Co-authored-by: {login} <{email}>",
25
+ "maxSubjectLength": 72
19
26
  }
20
27
  }
@@ -18,6 +18,7 @@ import {
18
18
  } from "../lib/debate-bus-state.js";
19
19
  import { isHarnessProjectEnabled } from "../lib/harness-project-config.js";
20
20
  import { getRunIdFromSession } from "../lib/harness-run-context.js";
21
+ import { completeDebateOpen } from "../lib/harness-slash-completions.js";
21
22
  import { normalizePlanDebateId } from "../lib/plan-debate-id.js";
22
23
  import { initPlanMessenger } from "../lib/plan-messenger.js";
23
24
 
@@ -55,6 +56,8 @@ export default function debateOrchestrator(pi: ExtensionAPI) {
55
56
 
56
57
  pi.registerCommand("harness-debate-open", {
57
58
  description: "Open a headless debate session",
59
+ getArgumentCompletions: (prefix) =>
60
+ completeDebateOpen(prefix, process.cwd()),
58
61
  handler: async (args, ctx) => {
59
62
  const runId = getRunId(ctx);
60
63
  const trimmed = args.trim();
@@ -85,14 +85,10 @@ export default function harnessAnchoredEdit(pi: ExtensionAPI): void {
85
85
  parameters: readSchema,
86
86
  async execute(toolCallId, params, signal, onUpdate, ctx) {
87
87
  const base = getReadTool(ctx.cwd);
88
- const result = await base.execute(
89
- toolCallId,
90
- params,
91
- signal,
92
- onUpdate,
93
- ctx,
94
- );
95
- const taskId = anchoredEditTaskId(ctx);
88
+ const result = await base.execute(toolCallId, params, signal, onUpdate);
89
+ const taskId = anchoredEditTaskId({
90
+ sessionId: (ctx as { sessionId?: string }).sessionId,
91
+ });
96
92
  const absolutePath = resolve(ctx.cwd, params.path);
97
93
  for (const block of result.content) {
98
94
  if (block.type !== "text") continue;
@@ -116,7 +112,9 @@ export default function harnessAnchoredEdit(pi: ExtensionAPI): void {
116
112
  ],
117
113
  async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
118
114
  const absolutePath = resolve(ctx.cwd, params.path);
119
- const taskId = anchoredEditTaskId(ctx);
115
+ const taskId = anchoredEditTaskId({
116
+ sessionId: (ctx as { sessionId?: string }).sessionId,
117
+ });
120
118
  const edits = params.edits as AnchoredEdit[];
121
119
 
122
120
  const result = await applyAnchoredEditsToFile(
@@ -1,23 +1,16 @@
1
1
  /**
2
2
  * harness-ask-user — structured user decisions for harness planning and setup.
3
- * Design references: pi-ask-user, @pi-unipi/ask-user, rpiv-ask-user-question (not vendored).
4
3
  */
5
4
 
6
5
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
7
- import { runAskDialog } from "../lib/ask-user/dialog.js";
8
- import { runAskFallback } from "../lib/ask-user/fallback.js";
6
+ import { runAskUser } from "../lib/ask-user/index.js";
9
7
  import { renderAskCall, renderAskResult } from "../lib/ask-user/render.js";
10
8
  import {
11
9
  AskUserParamsSchema,
12
10
  PROMPT_GUIDELINES,
13
11
  PROMPT_SNIPPET,
14
12
  } from "../lib/ask-user/schema.js";
15
- import type { AskUserParams, DialogResult } from "../lib/ask-user/types.js";
16
- import {
17
- formatResultText,
18
- toToolDetails,
19
- validateAskParams,
20
- } from "../lib/ask-user/validate.js";
13
+ import type { AskUserParams } from "../lib/ask-user/types.js";
21
14
  import { claimHarnessGovernanceLoad } from "../lib/extension-load-guard.js";
22
15
 
23
16
  // @ts-expect-error pi extensions run as ESM
@@ -35,36 +28,22 @@ export default function harnessAskUser(pi: ExtensionAPI) {
35
28
  parameters: AskUserParamsSchema,
36
29
 
37
30
  async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
38
- const validated = validateAskParams(params as AskUserParams);
39
- if (typeof validated === "string") {
31
+ const result = await runAskUser(params as AskUserParams, {
32
+ ui: ctx.ui,
33
+ hasUI: ctx.hasUI,
34
+ sessionName: undefined,
35
+ });
36
+
37
+ if ("error" in result) {
40
38
  return {
41
- content: [{ type: "text", text: validated }],
42
- details: {
43
- question: params.question ?? "",
44
- options: [],
45
- response: null,
46
- cancelled: true,
47
- },
39
+ content: [{ type: "text", text: result.error }],
40
+ details: result.details,
48
41
  };
49
42
  }
50
43
 
51
- let outcome: DialogResult;
52
- if (ctx.hasUI) {
53
- outcome = await runAskDialog(ctx.ui, validated);
54
- } else {
55
- outcome = await runAskFallback(ctx.ui, validated);
56
- }
57
-
58
- const details = toToolDetails(
59
- validated,
60
- outcome.response,
61
- outcome.cancelled,
62
- );
63
- const text = formatResultText(outcome.response, outcome.cancelled);
64
-
65
44
  return {
66
- content: [{ type: "text", text }],
67
- details,
45
+ content: result.content,
46
+ details: result.details,
68
47
  };
69
48
  },
70
49
 
@@ -51,7 +51,6 @@ import {
51
51
  withReviewRoundYamlWrite,
52
52
  } from "../lib/harness-debate-workflow-deps.js";
53
53
 
54
- // @ts-expect-error pi extensions run as ESM
55
54
  const MODULE_URL = import.meta.url;
56
55
 
57
56
  function getRunId(ctx: {
@@ -98,9 +97,7 @@ function subagentResults(
98
97
 
99
98
  const USE_SUBMIT_TOOLS = process.env.HARNESS_SUBMIT_TOOLS !== "0";
100
99
 
101
- export default function harnessDebateTools(pi: ExtensionAPI) {
102
- if (!claimHarnessGovernanceLoad("harness-debate-tools", MODULE_URL)) return;
103
-
100
+ function registerHarnessDebateHandler1(pi: ExtensionAPI) {
104
101
  pi.on("tool_result", async (event, ctx) => {
105
102
  if (event.isError || event.toolName !== "subagent") return;
106
103
  const runId = getRunId(ctx);
@@ -171,7 +168,9 @@ export default function harnessDebateTools(pi: ExtensionAPI) {
171
168
  details: { applied, status },
172
169
  });
173
170
  });
171
+ }
174
172
 
173
+ function registerHarnessDebateHandler2(pi: ExtensionAPI) {
175
174
  pi.registerTool({
176
175
  name: "harness_plan_debate_eligibility",
177
176
  label: "Plan Debate Eligibility",
@@ -247,7 +246,9 @@ export default function harnessDebateTools(pi: ExtensionAPI) {
247
246
  };
248
247
  },
249
248
  });
249
+ }
250
250
 
251
+ function registerHarnessDebateHandler3(pi: ExtensionAPI) {
251
252
  pi.registerTool({
252
253
  name: "harness_debate_open",
253
254
  label: "Open Plan Debate",
@@ -332,7 +333,9 @@ export default function harnessDebateTools(pi: ExtensionAPI) {
332
333
  };
333
334
  },
334
335
  });
336
+ }
335
337
 
338
+ function registerHarnessDebateHandler4(pi: ExtensionAPI) {
336
339
  pi.registerTool({
337
340
  name: "harness_messenger_post",
338
341
  label: "Post Debate Messenger Message",
@@ -397,7 +400,9 @@ export default function harnessDebateTools(pi: ExtensionAPI) {
397
400
  };
398
401
  },
399
402
  });
403
+ }
400
404
 
405
+ function registerHarnessDebateHandler5(pi: ExtensionAPI) {
401
406
  pi.registerTool({
402
407
  name: "harness_messenger_read_round",
403
408
  label: "Read Debate Round Transcript",
@@ -422,7 +427,9 @@ export default function harnessDebateTools(pi: ExtensionAPI) {
422
427
  };
423
428
  },
424
429
  });
430
+ }
425
431
 
432
+ function registerHarnessDebateHandler6(pi: ExtensionAPI) {
426
433
  pi.registerTool({
427
434
  name: "harness_debate_submit_round",
428
435
  label: "Submit Plan Review Round",
@@ -551,7 +558,9 @@ export default function harnessDebateTools(pi: ExtensionAPI) {
551
558
  };
552
559
  },
553
560
  });
561
+ }
554
562
 
563
+ function registerHarnessDebateHandler7(pi: ExtensionAPI) {
555
564
  pi.registerTool({
556
565
  name: "harness_debate_consensus",
557
566
  label: "Finalize Plan Debate Consensus",
@@ -590,7 +599,9 @@ export default function harnessDebateTools(pi: ExtensionAPI) {
590
599
  };
591
600
  },
592
601
  });
602
+ }
593
603
 
604
+ function registerHarnessDebateHandler8(pi: ExtensionAPI) {
594
605
  pi.registerTool({
595
606
  name: "harness_debate_apply_lane",
596
607
  label: "Apply Debate Lane YAML + Messenger",
@@ -624,7 +635,9 @@ export default function harnessDebateTools(pi: ExtensionAPI) {
624
635
  };
625
636
  },
626
637
  });
638
+ }
627
639
 
640
+ function registerHarnessDebateHandler9(pi: ExtensionAPI) {
628
641
  pi.registerTool({
629
642
  name: "harness_debate_round_status",
630
643
  label: "Plan Debate Round Status",
@@ -669,7 +682,9 @@ export default function harnessDebateTools(pi: ExtensionAPI) {
669
682
  };
670
683
  },
671
684
  });
685
+ }
672
686
 
687
+ function registerHarnessDebateHandler10(pi: ExtensionAPI) {
673
688
  pi.registerTool({
674
689
  name: "harness_debate_focus_coverage",
675
690
  label: "Plan Debate Focus Coverage",
@@ -712,7 +727,9 @@ export default function harnessDebateTools(pi: ExtensionAPI) {
712
727
  };
713
728
  },
714
729
  });
730
+ }
715
731
 
732
+ function registerHarnessDebateHandler11(pi: ExtensionAPI) {
716
733
  pi.registerTool({
717
734
  name: "harness_debate_advance_thread",
718
735
  label: "Advance Plan Debate Thread",
@@ -746,7 +763,9 @@ export default function harnessDebateTools(pi: ExtensionAPI) {
746
763
  };
747
764
  },
748
765
  });
766
+ }
749
767
 
768
+ function registerHarnessDebateHandler12(pi: ExtensionAPI) {
750
769
  pi.registerTool({
751
770
  name: "harness_plan_scope_check",
752
771
  label: "Plan Scope Drift Check",
@@ -771,3 +790,23 @@ export default function harnessDebateTools(pi: ExtensionAPI) {
771
790
  },
772
791
  });
773
792
  }
793
+
794
+ function registerHarnessDebateToolHandlers(pi: ExtensionAPI) {
795
+ registerHarnessDebateHandler1(pi);
796
+ registerHarnessDebateHandler2(pi);
797
+ registerHarnessDebateHandler3(pi);
798
+ registerHarnessDebateHandler4(pi);
799
+ registerHarnessDebateHandler5(pi);
800
+ registerHarnessDebateHandler6(pi);
801
+ registerHarnessDebateHandler7(pi);
802
+ registerHarnessDebateHandler8(pi);
803
+ registerHarnessDebateHandler9(pi);
804
+ registerHarnessDebateHandler10(pi);
805
+ registerHarnessDebateHandler11(pi);
806
+ registerHarnessDebateHandler12(pi);
807
+ }
808
+
809
+ export default function harnessDebateTools(pi: ExtensionAPI) {
810
+ if (!claimHarnessGovernanceLoad("harness-debate-tools", MODULE_URL)) return;
811
+ registerHarnessDebateToolHandlers(pi);
812
+ }
@@ -84,28 +84,37 @@ function visibleWidth(input: string): number {
84
84
  return width;
85
85
  }
86
86
 
87
+ const WIDE_SINGLE_CODE_POINTS = new Set([0x2329, 0x232a]);
88
+ const WIDE_RANGES: ReadonlyArray<readonly [number, number]> = [
89
+ [0x1100, 0x115f],
90
+ [0x2e80, 0xa4cf],
91
+ [0xac00, 0xd7a3],
92
+ [0xf900, 0xfaff],
93
+ [0xfe10, 0xfe19],
94
+ [0xfe30, 0xfe6f],
95
+ [0xff00, 0xff60],
96
+ [0xffe0, 0xffe6],
97
+ [0x1f300, 0x1faff],
98
+ [0x20000, 0x3fffd],
99
+ ];
100
+
101
+ function inRange(codePoint: number, start: number, end: number): boolean {
102
+ return codePoint >= start && codePoint <= end;
103
+ }
104
+
105
+ function isWideCodePoint(codePoint: number): boolean {
106
+ if (WIDE_SINGLE_CODE_POINTS.has(codePoint)) return true;
107
+ if (inRange(codePoint, 0x2e80, 0xa4cf) && codePoint === 0x303f) return false;
108
+ return WIDE_RANGES.some(([start, end]) => inRange(codePoint, start, end));
109
+ }
110
+
87
111
  function charDisplayWidth(char: string): number {
88
112
  const codePoint = char.codePointAt(0);
89
113
  if (codePoint == null) return 0;
90
- if (codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f)) return 0;
91
- if (codePoint >= 0x300 && codePoint <= 0x36f) return 0;
92
- if (
93
- codePoint >= 0x1100 &&
94
- (codePoint <= 0x115f ||
95
- codePoint === 0x2329 ||
96
- codePoint === 0x232a ||
97
- (codePoint >= 0x2e80 && codePoint <= 0xa4cf && codePoint !== 0x303f) ||
98
- (codePoint >= 0xac00 && codePoint <= 0xd7a3) ||
99
- (codePoint >= 0xf900 && codePoint <= 0xfaff) ||
100
- (codePoint >= 0xfe10 && codePoint <= 0xfe19) ||
101
- (codePoint >= 0xfe30 && codePoint <= 0xfe6f) ||
102
- (codePoint >= 0xff00 && codePoint <= 0xff60) ||
103
- (codePoint >= 0xffe0 && codePoint <= 0xffe6) ||
104
- (codePoint >= 0x1f300 && codePoint <= 0x1faff) ||
105
- (codePoint >= 0x20000 && codePoint <= 0x3fffd))
106
- ) {
107
- return 2;
108
- }
114
+ if (inRange(codePoint, 0x00, 0x1f) || inRange(codePoint, 0x7f, 0x9f))
115
+ return 0;
116
+ if (inRange(codePoint, 0x300, 0x36f)) return 0;
117
+ if (isWideCodePoint(codePoint)) return 2;
109
118
  return 1;
110
119
  }
111
120