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.
- package/.agents/skills/harness-decisions/SKILL.md +68 -2
- package/.agents/skills/harness-git-commit/SKILL.md +72 -0
- package/.agents/skills/harness-governor/SKILL.md +2 -2
- package/.agents/skills/harness-ls-lint-setup/SKILL.md +59 -0
- package/.agents/skills/harness-plan/SKILL.md +13 -11
- package/.agents/skills/harness-review/SKILL.md +1 -1
- package/.agents/skills/harness-sentrux-repair/SKILL.md +48 -0
- package/.agents/skills/sentrux/SKILL.md +4 -2
- package/.agents/skills/wiki-save/SKILL.md +1 -1
- package/.pi/PACKAGING.md +6 -0
- package/.pi/SYSTEM.md +21 -3
- package/.pi/agents/harness/ls-lint-steward.md +49 -0
- package/.pi/agents/harness/planning/decompose.md +4 -4
- package/.pi/agents/harness/reviewing/evaluator.md +1 -1
- package/.pi/agents/harness/running/executor.md +1 -1
- package/.pi/agents/harness/sentrux-repair-advisor.md +50 -0
- package/.pi/agents/pi-pi/prompt-expert.md +17 -2
- package/.pi/auto-commit.json +9 -2
- package/.pi/extensions/debate-orchestrator.ts +3 -0
- package/.pi/extensions/harness-anchored-edit.ts +7 -9
- package/.pi/extensions/harness-ask-user.ts +13 -34
- package/.pi/extensions/harness-debate-tools.ts +43 -4
- package/.pi/extensions/harness-live-widget.ts +28 -19
- package/.pi/extensions/harness-run-context.ts +278 -115
- package/.pi/extensions/harness-web-tools.ts +598 -471
- package/.pi/extensions/ls-lint-rules-sync.ts +103 -0
- package/.pi/extensions/observation-bus.ts +4 -0
- package/.pi/extensions/policy-gate.ts +270 -229
- package/.pi/extensions/sentrux-rules-sync.ts +2 -0
- package/.pi/extensions/soundboard.ts +48 -48
- package/.pi/harness/README.md +4 -0
- package/.pi/harness/agents.manifest.json +15 -7
- package/.pi/harness/agents.policy.yaml +49 -82
- package/.pi/harness/docs/adrs/0052-ls-lint-naming-lifecycle.md +45 -0
- package/.pi/harness/docs/adrs/0052-sentrux-structured-repair.md +38 -0
- package/.pi/harness/docs/adrs/0053-plan-task-clarification-gate.md +39 -0
- package/.pi/harness/docs/adrs/0054-harness-native-ask-user.md +40 -0
- package/.pi/harness/docs/adrs/0055-auto-commit-coauthor-lifecycle.md +40 -0
- package/.pi/harness/docs/adrs/README.md +5 -0
- package/.pi/harness/docs/practice-map.md +10 -5
- package/.pi/harness/evals/smoke/ls-lint-stub.json +10 -0
- package/.pi/harness/evolution/self-healing-rules.json +16 -0
- package/.pi/harness/ls-lint/naming.manifest.json +128 -0
- package/.pi/harness/sentrux/architecture.manifest.json +1 -1
- package/.pi/harness/specs/auto-commit.schema.json +63 -0
- package/.pi/harness/specs/ls-lint-manifest-proposal.schema.json +80 -0
- package/.pi/harness/specs/ls-lint-signal.schema.json +47 -0
- package/.pi/harness/specs/naming-manifest.schema.json +54 -0
- package/.pi/harness/specs/plan-task-clarification.schema.json +88 -0
- package/.pi/harness/specs/sentrux-diagnostics.schema.json +173 -0
- package/.pi/harness/specs/sentrux-repair-plan.schema.json +133 -0
- package/.pi/harness/specs/sentrux-report.schema.json +119 -0
- package/.pi/harness/specs/sentrux-signal.schema.json +34 -1
- package/.pi/lib/agents-policy.d.mts +26 -51
- package/.pi/lib/agents-policy.mjs +41 -28
- package/.pi/lib/agt/build-evaluation-context.ts +136 -64
- package/.pi/lib/ask-user/constants.mjs +3 -0
- package/.pi/lib/ask-user/constants.ts +4 -0
- package/.pi/lib/ask-user/contracts/glimpse-parse.ts +56 -0
- package/.pi/lib/ask-user/contracts/glimpse-payload-build.ts +58 -0
- package/.pi/lib/ask-user/contracts/glimpse-payload.ts +38 -0
- package/.pi/lib/ask-user/core/questionnaire.ts +74 -0
- package/.pi/lib/ask-user/dialog.ts +2 -314
- package/.pi/lib/ask-user/fallback.ts +2 -78
- package/.pi/lib/ask-user/format.ts +85 -0
- package/.pi/lib/ask-user/glimpseui.d.ts +10 -0
- package/.pi/lib/ask-user/index.ts +114 -0
- package/.pi/lib/ask-user/merge-task-clarification.ts +98 -0
- package/.pi/lib/ask-user/policy.mjs +43 -0
- package/.pi/lib/ask-user/policy.ts +104 -0
- package/.pi/lib/ask-user/presenters/glimpse.ts +130 -0
- package/.pi/lib/ask-user/presenters/headless.ts +131 -0
- package/.pi/lib/ask-user/presenters/select.ts +60 -0
- package/.pi/lib/ask-user/presenters/tui.ts +373 -0
- package/.pi/lib/ask-user/presenters/types.ts +13 -0
- package/.pi/lib/ask-user/render.ts +40 -9
- package/.pi/lib/ask-user/schema.ts +66 -13
- package/.pi/lib/ask-user/types.ts +60 -3
- package/.pi/lib/ask-user/validate-core.mjs +193 -7
- package/.pi/lib/ask-user/validate.ts +53 -34
- package/.pi/lib/harness-anchored-edit/package.json +3 -0
- package/.pi/lib/harness-artifact-gate.ts +75 -21
- package/.pi/lib/harness-auto-commit-config.mjs +321 -0
- package/.pi/lib/harness-lens/clients/lsp/client.ts +62 -39
- package/.pi/lib/harness-lens/clients/tool-policy.ts +73 -181
- package/.pi/lib/harness-lens/index.ts +241 -108
- package/.pi/lib/harness-lens/tools/lsp-navigation.ts +10 -8
- package/.pi/lib/harness-repair-brief.ts +84 -25
- package/.pi/lib/harness-run-context.ts +42 -52
- package/.pi/lib/harness-sentrux-parse.mjs +272 -0
- package/.pi/lib/harness-sentrux-root.mjs +78 -0
- package/.pi/lib/harness-slash-completions.ts +116 -0
- package/.pi/lib/harness-spawn-topology.ts +121 -87
- package/.pi/lib/harness-subagent-submit-registry.ts +10 -0
- package/.pi/lib/harness-subagents-bridge.ts +4 -1
- package/.pi/lib/harness-ui-state.ts +95 -48
- package/.pi/lib/plan-approval/dialog.ts +5 -0
- package/.pi/lib/plan-approval/validate.ts +1 -1
- package/.pi/lib/plan-approval-readiness.ts +32 -0
- package/.pi/lib/plan-debate-gate.ts +154 -114
- package/.pi/lib/plan-task-clarification.ts +158 -0
- package/.pi/prompts/harness-auto.md +2 -2
- package/.pi/prompts/harness-ls-lint-steward.md +43 -0
- package/.pi/prompts/harness-plan.md +58 -8
- package/.pi/prompts/harness-review.md +40 -6
- package/.pi/prompts/harness-run.md +33 -11
- package/.pi/prompts/harness-setup.md +72 -3
- package/.pi/prompts/harness-steer.md +2 -1
- package/.pi/prompts/wiki-save.md +5 -4
- package/.pi/scripts/README.md +8 -0
- package/.pi/scripts/generate-agents-policy-yaml.mjs +14 -2
- package/.pi/scripts/harness-auto-commit-bootstrap.mjs +96 -0
- package/.pi/scripts/harness-cli-verify.sh +47 -0
- package/.pi/scripts/harness-git-churn.mjs +77 -0
- package/.pi/scripts/harness-git-commit.mjs +173 -0
- package/.pi/scripts/harness-ls-lint-bootstrap.mjs +142 -0
- package/.pi/scripts/harness-ls-lint-cli.mjs +184 -0
- package/.pi/scripts/harness-seed-project-contracts.mjs +47 -0
- package/.pi/scripts/harness-sentrux-diagnostics.mjs +230 -0
- package/.pi/scripts/harness-sentrux-report.mjs +256 -0
- package/.pi/scripts/harness-verify.mjs +288 -125
- package/.pi/scripts/ls-lint-rules-sync.mjs +265 -0
- package/.pi/scripts/run-tests.mjs +1 -0
- package/.pi/settings.example.json +1 -0
- package/.sentrux/rules.toml +1 -1
- package/AGENTS.md +1 -0
- package/CHANGELOG.md +25 -0
- package/README.md +13 -4
- package/package.json +5 -1
- package/vendor/pi-vcc/src/hooks/before-compact.ts +86 -60
package/.pi/auto-commit.json
CHANGED
|
@@ -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
|
-
"
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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(
|
|
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 {
|
|
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
|
|
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
|
|
39
|
-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
|
91
|
-
|
|
92
|
-
if (
|
|
93
|
-
|
|
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
|
|