@fitlab-ai/agent-infra 0.9.14 → 0.9.15
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.md +10 -0
- package/README.zh-CN.md +10 -0
- package/bin/internal-cli.sh +45 -0
- package/dist/bin/internal-cli.js +93 -30
- package/dist/lib/agent-clients/adapters/codex-lifecycle/capability-store.js +165 -27
- package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +3 -2
- package/dist/lib/defaults.json +103 -103
- package/dist/lib/fs/durable-write.js +37 -0
- package/dist/lib/fs/file-lock.js +111 -0
- package/dist/lib/host-control/audit.js +19 -0
- package/dist/lib/host-control/client.js +142 -0
- package/dist/lib/host-control/command.js +49 -0
- package/dist/lib/host-control/path.js +160 -0
- package/dist/lib/host-control/secure-fs.js +140 -0
- package/dist/lib/host-control/server.js +159 -0
- package/dist/lib/host-control/service.js +112 -0
- package/dist/lib/init.js +11 -2
- package/dist/lib/internal/cli-route-inventory.js +3 -1
- package/dist/lib/internal/codex-lifecycle.js +6 -6
- package/dist/lib/internal/demo-promotion.js +322 -0
- package/dist/lib/internal/demo-transcript.js +454 -0
- package/dist/lib/internal/host-control.js +28 -0
- package/dist/lib/internal/manual-validation.js +322 -0
- package/dist/lib/internal/platform-pr.js +18 -4
- package/dist/lib/internal/release-workflow.js +63 -84
- package/dist/lib/internal/sandbox-control.js +149 -2
- package/dist/lib/internal/task-artifact.js +15 -262
- package/dist/lib/internal/task-create.js +6 -5
- package/dist/lib/internal/task-event.js +37 -37
- package/dist/lib/internal/task-operation-registry.js +101 -3
- package/dist/lib/internal/task-review.js +8 -53
- package/dist/lib/internal/task-validate.js +30 -10
- package/dist/lib/owned-path.js +33 -0
- package/dist/lib/platform/check-status.js +11 -0
- package/dist/lib/platform/comment-safety.js +4 -1
- package/dist/lib/platform/completion-backfill.js +1 -1
- package/dist/lib/platform/github-data.js +241 -0
- package/dist/lib/platform/github-provider.js +15 -20
- package/dist/lib/platform/issue-comments.js +2 -2
- package/dist/lib/platform/issues.js +1 -179
- package/dist/lib/platform/pr-checks.js +12 -65
- package/dist/lib/platform/pr-summary.js +55 -3
- package/dist/lib/platform/pull-requests.js +2 -105
- package/dist/lib/platform/snapshots.js +2 -0
- package/dist/lib/platform/verification-sync.js +127 -142
- package/dist/lib/release/workflow.js +1 -1
- package/dist/lib/sandbox/commands/create.js +7 -2
- package/dist/lib/sandbox/commands/rm.js +3 -1514
- package/dist/lib/sandbox/control/audit.js +203 -0
- package/dist/lib/sandbox/control/client.js +93 -54
- package/dist/lib/sandbox/control/executor.js +129 -65
- package/dist/lib/sandbox/control/finalization-response.js +27 -0
- package/dist/lib/sandbox/control/identity-sentinel.js +107 -0
- package/dist/lib/sandbox/control/lifecycle.js +36 -2
- package/dist/lib/sandbox/control/native-file-lock.js +6 -98
- package/dist/lib/sandbox/control/protocol.js +55 -4
- package/dist/lib/sandbox/control/server.js +491 -120
- package/dist/lib/sandbox/control/state.js +58 -0
- package/dist/lib/sandbox/control/task-workflow.js +74 -0
- package/dist/lib/sandbox/control/workflow-executor.js +99 -0
- package/dist/lib/sandbox/index.js +2 -2
- package/dist/lib/sandbox/recovery.js +28 -4
- package/dist/lib/sandbox/removal.js +1717 -0
- package/dist/lib/sandbox/task-cleanup.js +217 -0
- package/dist/lib/sandbox/workspace-view.js +13 -14
- package/dist/lib/task/activity-intent.js +2 -1
- package/dist/lib/task/activity-log.js +30 -24
- package/dist/lib/task/artifact-command.js +101 -0
- package/dist/lib/task/artifact-lifecycle.js +30 -28
- package/dist/lib/task/artifact-name.js +36 -0
- package/dist/lib/task/artifact-operations.js +23 -69
- package/dist/lib/task/artifact-receipts.js +3 -15
- package/dist/lib/task/artifact-repair-intent.js +87 -16
- package/dist/lib/task/artifact-schema.js +6 -14
- package/dist/lib/task/capabilities.js +12 -19
- package/dist/lib/task/codex-orchestration.js +71 -25
- package/dist/lib/task/commit-identity.js +28 -0
- package/dist/lib/task/commit-operation.js +2 -16
- package/dist/lib/task/control-authority.js +371 -5
- package/dist/lib/task/control-recovery.js +128 -0
- package/dist/lib/task/create.js +62 -9
- package/dist/lib/task/decision-details.js +2 -46
- package/dist/lib/task/events.js +120 -9
- package/dist/lib/task/finalization-state.js +9 -0
- package/dist/lib/task/human-override.js +3 -6
- package/dist/lib/task/implementation-inputs.js +3 -3
- package/dist/lib/task/intermediate-cleanup.js +383 -0
- package/dist/lib/task/invalidation.js +18 -65
- package/dist/lib/task/ledger-intents.js +7 -22
- package/dist/lib/task/ledger.js +1 -3
- package/dist/lib/task/lifecycle.js +19 -1
- package/dist/lib/task/local-artifact-finalization.js +132 -157
- package/dist/lib/task/manual-validation-completion.js +26 -0
- package/dist/lib/task/manual-validation-evidence.js +130 -0
- package/dist/lib/task/manual-validation-receipt.js +101 -0
- package/dist/lib/task/manual-validation-shared.js +40 -0
- package/dist/lib/task/manual-validation-transaction.js +243 -0
- package/dist/lib/task/markdown.js +47 -0
- package/dist/lib/task/orchestration.js +14 -17
- package/dist/lib/task/qualification-audit.js +20 -34
- package/dist/lib/task/review-artifacts.js +2 -18
- package/dist/lib/task/review-command.js +25 -0
- package/dist/lib/task/review-finalization.js +125 -193
- package/dist/lib/task/review-fingerprint.js +2 -2
- package/dist/lib/task/sections.js +34 -56
- package/dist/lib/task/verification-engine.js +116 -323
- package/dist/lib/task/verification.js +1 -1
- package/dist/lib/task/workflow-command.js +17 -0
- package/dist/lib/task/workflow-warning-intents.js +0 -16
- package/dist/lib/task/workflow-warnings.js +28 -2
- package/dist/lib/update.js +2 -0
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/agent-clients/adapters/codex-lifecycle/capability-store.ts +223 -33
- package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +3 -2
- package/lib/fs/durable-write.ts +29 -0
- package/lib/fs/file-lock.ts +113 -0
- package/lib/host-control/audit.ts +22 -0
- package/lib/host-control/client.ts +172 -0
- package/lib/host-control/command.ts +60 -0
- package/lib/host-control/path.ts +167 -0
- package/lib/host-control/secure-fs.ts +135 -0
- package/lib/host-control/server.ts +180 -0
- package/lib/host-control/service.ts +133 -0
- package/lib/init.ts +15 -2
- package/lib/internal/cli-route-inventory.ts +3 -1
- package/lib/internal/codex-lifecycle.ts +6 -6
- package/lib/internal/demo-promotion.ts +354 -0
- package/lib/internal/demo-transcript.ts +419 -0
- package/lib/internal/host-control.ts +28 -0
- package/lib/internal/manual-validation.ts +306 -0
- package/lib/internal/platform-pr.ts +15 -4
- package/lib/internal/release-workflow.ts +74 -82
- package/lib/internal/sandbox-control.ts +162 -1
- package/lib/internal/task-artifact.ts +13 -216
- package/lib/internal/task-create.ts +5 -5
- package/lib/internal/task-event.ts +20 -11
- package/lib/internal/task-operation-registry.ts +111 -3
- package/lib/internal/task-review.ts +6 -51
- package/lib/internal/task-validate.ts +26 -10
- package/lib/owned-path.ts +26 -0
- package/lib/platform/check-status.ts +9 -0
- package/lib/platform/comment-safety.ts +5 -0
- package/lib/platform/completion-backfill.ts +1 -1
- package/lib/platform/github-data.ts +322 -0
- package/lib/platform/github-provider.ts +15 -20
- package/lib/platform/issue-comments.ts +3 -4
- package/lib/platform/issues.ts +4 -245
- package/lib/platform/pr-checks.ts +13 -77
- package/lib/platform/pr-summary.ts +61 -5
- package/lib/platform/pull-requests.ts +3 -170
- package/lib/platform/snapshots.ts +53 -0
- package/lib/platform/verification-sync.ts +145 -155
- package/lib/release/workflow.ts +3 -3
- package/lib/sandbox/commands/create.ts +7 -6
- package/lib/sandbox/commands/rm.ts +3 -1909
- package/lib/sandbox/control/audit.ts +253 -0
- package/lib/sandbox/control/client.ts +109 -66
- package/lib/sandbox/control/executor.ts +134 -74
- package/lib/sandbox/control/finalization-response.ts +29 -0
- package/lib/sandbox/control/identity-sentinel.ts +137 -0
- package/lib/sandbox/control/lifecycle.ts +45 -3
- package/lib/sandbox/control/native-file-lock.ts +6 -107
- package/lib/sandbox/control/protocol.ts +75 -6
- package/lib/sandbox/control/server.ts +538 -123
- package/lib/sandbox/control/state.ts +78 -0
- package/lib/sandbox/control/task-workflow.ts +95 -0
- package/lib/sandbox/control/workflow-executor.ts +102 -0
- package/lib/sandbox/index.ts +2 -2
- package/lib/sandbox/recovery.ts +28 -5
- package/lib/sandbox/removal.ts +2144 -0
- package/lib/sandbox/task-cleanup.ts +209 -0
- package/lib/sandbox/workspace-view.ts +17 -15
- package/lib/task/activity-intent.ts +2 -2
- package/lib/task/activity-log.ts +27 -19
- package/lib/task/artifact-command.ts +104 -0
- package/lib/task/artifact-lifecycle.ts +31 -26
- package/lib/task/artifact-name.ts +55 -0
- package/lib/task/artifact-operations.ts +22 -68
- package/lib/task/artifact-receipts.ts +3 -14
- package/lib/task/artifact-repair-intent.ts +99 -18
- package/lib/task/artifact-schema.ts +5 -34
- package/lib/task/capabilities.ts +13 -22
- package/lib/task/codex-orchestration.ts +85 -24
- package/lib/task/commit-identity.ts +31 -0
- package/lib/task/commit-operation.ts +2 -16
- package/lib/task/control-authority.ts +502 -5
- package/lib/task/control-recovery.ts +174 -0
- package/lib/task/create.ts +63 -8
- package/lib/task/decision-details.ts +3 -71
- package/lib/task/events.ts +131 -10
- package/lib/task/finalization-state.ts +11 -0
- package/lib/task/human-override.ts +3 -8
- package/lib/task/implementation-inputs.ts +3 -3
- package/lib/task/intermediate-cleanup.ts +455 -0
- package/lib/task/invalidation.ts +18 -62
- package/lib/task/ledger-intents.ts +7 -24
- package/lib/task/ledger.ts +1 -3
- package/lib/task/lifecycle.ts +17 -1
- package/lib/task/local-artifact-finalization.ts +148 -182
- package/lib/task/manual-validation-completion.ts +40 -0
- package/lib/task/manual-validation-evidence.ts +209 -0
- package/lib/task/manual-validation-receipt.ts +152 -0
- package/lib/task/manual-validation-shared.ts +50 -0
- package/lib/task/manual-validation-transaction.ts +304 -0
- package/lib/task/markdown.ts +70 -0
- package/lib/task/orchestration.ts +19 -19
- package/lib/task/qualification-audit.ts +22 -33
- package/lib/task/review-artifacts.ts +1 -20
- package/lib/task/review-command.ts +23 -0
- package/lib/task/review-finalization.ts +131 -259
- package/lib/task/review-fingerprint.ts +2 -2
- package/lib/task/sections.ts +33 -54
- package/lib/task/verification-engine.ts +110 -366
- package/lib/task/verification-types.ts +17 -0
- package/lib/task/verification.ts +1 -1
- package/lib/task/workflow-command.ts +18 -0
- package/lib/task/workflow-warning-intents.ts +0 -13
- package/lib/task/workflow-warnings.ts +21 -2
- package/lib/update.ts +6 -0
- package/package.json +6 -6
- package/templates/.agents/hooks/lifecycle-delegation.js +6 -6
- package/templates/.agents/rules/testing-discipline.en.md +2 -0
- package/templates/.agents/rules/testing-discipline.zh-CN.md +2 -0
- package/templates/.agents/scripts/package.json +3 -0
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +32 -20
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +32 -20
- package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -1
- package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -1
- package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +2 -0
- package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +2 -0
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +16 -7
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +16 -7
- package/templates/.agents/skills/complete-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/release/SKILL.en.md +7 -3
- package/templates/.agents/skills/release/SKILL.zh-CN.md +7 -3
- package/templates/.agents/skills/run-manual-validation/SKILL.en.md +20 -3
- package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +20 -3
- package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.en.md +4 -1
- package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.zh-CN.md +4 -1
- package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +2 -0
- package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +2 -0
- package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/test/SKILL.en.md +17 -6
- package/templates/.agents/skills/test/SKILL.zh-CN.md +17 -6
- package/templates/.claude/commands/run-manual-validation.en.md +1 -1
- package/templates/.claude/commands/run-manual-validation.zh-CN.md +1 -1
- package/dist/lib/platform/adapters.js +0 -56
- package/lib/platform/adapters.ts +0 -197
package/lib/task/sections.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { FrontmatterScalar } from './frontmatter.ts';
|
|
2
|
+
import { scanVisibleMarkdown } from './markdown.ts';
|
|
2
3
|
|
|
3
4
|
function escapeRegExp(value: string): string {
|
|
4
5
|
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
@@ -93,12 +94,14 @@ function parseTable(
|
|
|
93
94
|
throw new DocumentMutationError('TASK_DOCUMENT_INVALID', 'table section is ambiguous');
|
|
94
95
|
}
|
|
95
96
|
const section = sections[0]!;
|
|
97
|
+
const visibleStarts = new Set(scanVisibleMarkdown(content).lines.map((line) => line.start));
|
|
96
98
|
const sectionLines = linesOf(content).filter(
|
|
97
99
|
(line) => line.start >= section.bodyStart && line.start < section.end
|
|
98
100
|
);
|
|
99
101
|
const firstContent = sectionLines.findIndex((line) => line.text.trim() !== '');
|
|
100
102
|
const tables: number[] = [];
|
|
101
103
|
for (let index = 0; index + 1 < sectionLines.length; index += 1) {
|
|
104
|
+
if (!visibleStarts.has(sectionLines[index]!.start) || !visibleStarts.has(sectionLines[index + 1]!.start)) continue;
|
|
102
105
|
const header = splitTableCells(sectionLines[index]!.text);
|
|
103
106
|
const separator = splitTableCells(sectionLines[index + 1]!.text);
|
|
104
107
|
if (!header || !separator || header.cells.length !== input.columns.length) continue;
|
|
@@ -173,24 +176,24 @@ function documentEol(content: string): '\n' | '\r\n' {
|
|
|
173
176
|
|
|
174
177
|
function matchingSections(content: string, aliases: readonly string[]) {
|
|
175
178
|
const allowed = new Set(aliases);
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
if (nextHeading && nextHeading[1]!.length <= level) {
|
|
185
|
-
end = lines[i]!.start;
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
return { heading: match[2]!, line, bodyStart: line.end, end };
|
|
179
|
+
const lines = new Map(linesOf(content).map((line) => [line.start, line]));
|
|
180
|
+
const headings = scanVisibleMarkdown(content).headings.filter((heading) => heading.level === 2 || heading.level === 3);
|
|
181
|
+
return headings
|
|
182
|
+
.map((heading, index) => {
|
|
183
|
+
if (!allowed.has(heading.text)) return null;
|
|
184
|
+
const next = headings.slice(index + 1).find((candidate) => candidate.level <= heading.level);
|
|
185
|
+
const line = lines.get(heading.start)!;
|
|
186
|
+
return { heading: heading.text, level: heading.level, line, bodyStart: line.end, end: next?.start ?? content.length };
|
|
190
187
|
})
|
|
191
188
|
.filter((match): match is NonNullable<typeof match> => match !== null);
|
|
192
189
|
}
|
|
193
190
|
|
|
191
|
+
// Select the first visible section at the requested level, in document order.
|
|
192
|
+
function findSectionRange(content: string, aliases: readonly string[], level: 2 | 3 = 2) {
|
|
193
|
+
const section = matchingSections(content, aliases).find((candidate) => candidate.level === level);
|
|
194
|
+
return section ? { start: section.line.start, bodyStart: section.bodyStart, end: section.end, heading: section.heading } : null;
|
|
195
|
+
}
|
|
196
|
+
|
|
194
197
|
function validateAliases(aliases: readonly string[], name: string): void {
|
|
195
198
|
if (!Array.isArray(aliases) || aliases.length === 0 || aliases.some((alias) => !alias || /[\r\n]/.test(alias))) {
|
|
196
199
|
throw new DocumentMutationError('MUTATION_INVALID', `${name} must contain headings`);
|
|
@@ -351,11 +354,13 @@ function mutateTableRow(content: string, mutation: TableRowMutation): TableMutat
|
|
|
351
354
|
);
|
|
352
355
|
}
|
|
353
356
|
const section = sections[0]!;
|
|
357
|
+
const visibleStarts = new Set(scanVisibleMarkdown(content).lines.map((line) => line.start));
|
|
354
358
|
const sectionLines = linesOf(content).filter(
|
|
355
359
|
(line) => line.start >= section.bodyStart && line.start < section.end
|
|
356
360
|
);
|
|
357
361
|
const tables: { headerIndex: number; cells: string[] }[] = [];
|
|
358
362
|
for (let i = 0; i + 1 < sectionLines.length; i += 1) {
|
|
363
|
+
if (!visibleStarts.has(sectionLines[i]!.start) || !visibleStarts.has(sectionLines[i + 1]!.start)) continue;
|
|
359
364
|
const header = splitTableCells(sectionLines[i]!.text);
|
|
360
365
|
const separator = splitTableCells(sectionLines[i + 1]!.text);
|
|
361
366
|
if (!header || !separator || header.cells.length !== mutation.columns.length) continue;
|
|
@@ -477,24 +482,11 @@ function mutateTableRow(content: string, mutation: TableRowMutation): TableMutat
|
|
|
477
482
|
* lines are trimmed. Returns '' when no alias heading is present.
|
|
478
483
|
*/
|
|
479
484
|
function extractSection(content: string, aliases: string[]): string {
|
|
480
|
-
const
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
start = i + 1;
|
|
486
|
-
break;
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
if (start === -1) return '';
|
|
490
|
-
let end = lines.length;
|
|
491
|
-
for (let i = start; i < lines.length; i += 1) {
|
|
492
|
-
if (/^##\s+/.test(lines[i]!)) {
|
|
493
|
-
end = i;
|
|
494
|
-
break;
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
return lines.slice(start, end).join('\n').replace(/^\n+/, '').replace(/\n+$/, '');
|
|
485
|
+
const headings = scanVisibleMarkdown(content).headings.filter((heading) => heading.level === 2);
|
|
486
|
+
const index = headings.findIndex((heading) => aliases.includes(heading.text));
|
|
487
|
+
if (index === -1) return '';
|
|
488
|
+
return content.slice(headings[index]!.end + 1, headings[index + 1]?.start ?? content.length)
|
|
489
|
+
.replace(/^(?:\r?\n)+|(?:\r?\n)+$/g, '');
|
|
498
490
|
}
|
|
499
491
|
|
|
500
492
|
/**
|
|
@@ -503,10 +495,8 @@ function extractSection(content: string, aliases: string[]): string {
|
|
|
503
495
|
* alias when none is present.
|
|
504
496
|
*/
|
|
505
497
|
function findSectionHeading(content: string, aliases: string[]): string {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
}
|
|
509
|
-
return aliases[0]!;
|
|
498
|
+
const headings = scanVisibleMarkdown(content).headings.filter((heading) => heading.level === 2);
|
|
499
|
+
return aliases.find((alias) => headings.some((heading) => heading.text === alias)) ?? aliases[0]!;
|
|
510
500
|
}
|
|
511
501
|
|
|
512
502
|
/**
|
|
@@ -518,27 +508,16 @@ function findSectionHeading(content: string, aliases: string[]): string {
|
|
|
518
508
|
* and trailing blank lines are trimmed. Returns '' when no match is present.
|
|
519
509
|
*/
|
|
520
510
|
function extractSubSection(content: string, headingPrefix: string): string {
|
|
521
|
-
const
|
|
522
|
-
const headRe = new RegExp(
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
break;
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
if (start === -1) return '';
|
|
531
|
-
let end = lines.length;
|
|
532
|
-
for (let i = start + 1; i < lines.length; i += 1) {
|
|
533
|
-
if (/^###?\s+/.test(lines[i]!)) {
|
|
534
|
-
end = i;
|
|
535
|
-
break;
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
return lines.slice(start, end).join('\n').replace(/^\n+/, '').replace(/\n+$/, '');
|
|
511
|
+
const headings = scanVisibleMarkdown(content).headings.filter((heading) => heading.level === 2 || heading.level === 3);
|
|
512
|
+
const headRe = new RegExp(`^${escapeRegExp(headingPrefix)}(?![\\w-])`);
|
|
513
|
+
const index = headings.findIndex((heading) => heading.level === 3 && headRe.test(heading.text));
|
|
514
|
+
if (index === -1) return '';
|
|
515
|
+
return content.slice(headings[index]!.start, headings[index + 1]?.start ?? content.length)
|
|
516
|
+
.replace(/^(?:\r?\n)+|(?:\r?\n)+$/g, '');
|
|
539
517
|
}
|
|
540
518
|
|
|
541
519
|
export {
|
|
520
|
+
findSectionRange,
|
|
542
521
|
extractSection,
|
|
543
522
|
findSectionHeading,
|
|
544
523
|
extractSubSection,
|