@basou/core 0.14.1 → 0.15.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/index.d.ts CHANGED
@@ -5002,15 +5002,26 @@ declare function readManifest(paths: BasouPaths): Promise<Manifest>;
5002
5002
  declare const GENERATED_START = "<!-- BASOU:GENERATED:START -->";
5003
5003
  /** Marker line that ends the auto-generated region. */
5004
5004
  declare const GENERATED_END = "<!-- BASOU:GENERATED:END -->";
5005
+ /** Marker line that begins a managed protocol block in a foreign instruction file. */
5006
+ declare const PROTOCOL_START = "<!-- BASOU:PROTOCOLS:START -->";
5007
+ /** Marker line that ends a managed protocol block. */
5008
+ declare const PROTOCOL_END = "<!-- BASOU:PROTOCOLS:END -->";
5009
+ /** A start/end marker pair. Both lines are matched whole-line, exact. */
5010
+ type Markers = {
5011
+ start: string;
5012
+ end: string;
5013
+ };
5005
5014
  /**
5006
5015
  * Result of parsing a markdown body for the BASOU:GENERATED marker region.
5007
5016
  *
5008
5017
  * The spec mandates strict line-level matching (see
5009
5018
  * `docs/spec/generated-markdown.md#102-marker-convention`): a marker is
5010
5019
  * only recognized when an entire line is exactly the marker string.
5011
- * Leading/trailing whitespace, comment compression, and BOM are treated as
5012
- * legacy formats (`no_markers`) so that re-generation refuses to silently
5013
- * overwrite a mismatched manual edit.
5020
+ * Leading/trailing whitespace and comment compression are treated as legacy
5021
+ * formats (`no_markers`) so that re-generation refuses to silently overwrite a
5022
+ * mismatched manual edit. A leading UTF-8 BOM is the one exception: it is
5023
+ * tolerated (stripped for matching, re-prepended on render) so a BOM-prefixed
5024
+ * file round-trips instead of duplicating the block.
5014
5025
  */
5015
5026
  type MarkerSection = {
5016
5027
  kind: "ok";
@@ -5057,11 +5068,13 @@ declare function writeMarkdownFile(filePath: string, body: string): Promise<void
5057
5068
  * - `multiple_pairs`: more than one START or END line.
5058
5069
  * - `wrong_order`: END appears before START.
5059
5070
  *
5060
- * Matching is strict: leading/trailing whitespace, BOM, and comment
5061
- * compression (`<!--BASOU:...-->`) all bypass the marker and are treated
5062
- * as legacy content.
5071
+ * Matching is strict: leading/trailing whitespace and comment compression
5072
+ * (`<!--BASOU:...-->`) bypass the marker and are treated as legacy content. A
5073
+ * leading UTF-8 BOM is the exception: it is stripped before matching and
5074
+ * re-prepended to `before`, so a marker on the first line of a BOM-prefixed
5075
+ * file still matches and the file round-trips.
5063
5076
  */
5064
- declare function parseMarkers(content: string): MarkerSection;
5077
+ declare function parseMarkers(content: string, markers?: Markers): MarkerSection;
5065
5078
  /**
5066
5079
  * Build the final markdown body by replacing the BASOU:GENERATED region.
5067
5080
  *
@@ -5073,7 +5086,18 @@ declare function parseMarkers(content: string): MarkerSection;
5073
5086
  * The caller passes `fileLabel` (e.g. `"handoff.md"` or `"decisions.md"`)
5074
5087
  * so the error message is informative without leaking an absolute path.
5075
5088
  */
5076
- declare function renderWithMarkers(existing: string | null, generated: string, fileLabel: string): string;
5089
+ declare function renderWithMarkers(existing: string | null, generated: string, fileLabel: string, markers?: Markers): string;
5090
+ /**
5091
+ * Remove a marker region from `existing`, returning the body without the block.
5092
+ *
5093
+ * - `no_markers`: returns `existing` unchanged (nothing to remove).
5094
+ * - `ok`: drops both marker lines and the generated region, collapsing the
5095
+ * single newline that terminated the END marker line so no stray blank line
5096
+ * is left behind.
5097
+ * - any other parse result: throws a pathless error referencing `fileLabel`
5098
+ * (mismatched markers must not be silently rewritten).
5099
+ */
5100
+ declare function removeMarkerSection(existing: string, fileLabel: string, markers?: Markers): string;
5077
5101
 
5078
5102
  /**
5079
5103
  * Options for {@link importSessionFromJson}. All fields are optional.
@@ -5300,4 +5324,4 @@ declare function overwriteYamlFile(filePath: string, value: unknown): Promise<vo
5300
5324
  */
5301
5325
  declare const BASOU_CORE_VERSION = "0.1.0";
5302
5326
 
5303
- export { ACTIVE_GAP_CAP_MS, type ActiveTimeBasis, type AdapterOutputEvent, type AdoptCandidate, type AdoptCandidateKind, type AppendBasouGitignoreOptions, type AppendBasouGitignoreResult, type AppendEventToExistingInput, type AppendEventToExistingResult, type Approval, type ApprovalApprovedEvent, type ApprovalExpiredEvent, ApprovalIdSchema, type ApprovalLocation, type ApprovalRejectedEvent, type ApprovalRequestedEvent, ApprovalSchema, type ApprovalStatus, ApprovalStatusSchema, type ArchivePlan, type ArchiveTaskInput, type ArchiveTaskResult, type AttachTaskInput, type AttachUpdateTaskStatusInput, type AttachableStatus, BASOU_CORE_VERSION, type BasouPaths, type BulkChainResult, CLAUDE_IMPORT_SOURCE, CODEX_IMPORT_SOURCE, type CaptureMode, type ChainBreakReason, type ChainTailState, type ChainVerdict, type ChainVerdictStatus, type ChainedEvents, ChildProcessRunner, type CitedReview, type ClaudeTranscriptRecord, type ClaudeTranscriptToPayloadOptions, type CodexRolloutRecord, type CodexRolloutToPayloadOptions, type CommandExecutedEvent, type CommandLookup, type CreateAdHocSessionInput, type CreateAdHocSessionResult, type CreateAdHocTaskInput, type CreateManifestInput, type CreateTaskInput, type CreateTaskResult, type DayWorkStats, DecisionIdSchema, type DecisionRecordedEvent, type DecisionsRendererInput, type DecisionsRendererResult, type DeleteTaskInput, type DeleteTaskResult, type DiffResult, type EditTaskInput, type EditTaskResult, type Event, EventIdSchema, EventSchema, EventSourceSchema, type ExistingViewLink, FailedToFinalizeError, type FileChange, type FileChangeStatus, type FileChangedEvent, GENERATED_END, GENERATED_START, type GitSnapshot, type GitSnapshotEvent, type GitignorePlanSummary, type HandoffRendererInput, type HandoffRendererResult, ID_PREFIXES, type IdPrefix, type ImportSessionOptions, type ImportSessionResult, type InstructionFileFact, type InstructionSymlinkFact, type InstructionSymlinkState, IsoTimestampSchema, JSON_SCHEMA_VERSION, type JsonSchemaArtifact, type LoadSessionEntriesOptions, type LoadTaskEntriesOptions, type LoadedApproval, type LockHandle, type LockScope, type Manifest, ManifestSchema, type MarkerSection, type MeasureAvailability, type NoteAddedEvent, type OrientationRendererInput, type OrientationRendererResult, type OrientationSummary, type PrefixedId, type PresetAction, type PresetCollision, type PresetMarkerConflict, type PresetMarkerKind, type PresetPlanSummary, type PresetRepo, type ProcessRunner, type PublishKind, type PublishTarget, type RechainOptions, type RechainResult, type ReconcileAllResult, type ReconcileAllTasksInput, type ReconcileAllTasksOptions, type ReconcileFailure, type ReconcileResult, type ReconcileTaskInput, type RefreshLinkageInput, type RefreshLinkageResult, type ReimportOptions, type ReimportResult, type RenamePlan, type ReplayOptions, type ReplayWarning, type RepoEntry, type RepoGitignoreFacts, type RepoGitignorePlan, type RepoLanguage, type RepoPresetFacts, type RepoPresetPlan, type RepoSymlinkFacts, type RepoSymlinkPlan, type RepoVisibility, type RepoWiringFacts, type ReportApprovalItem, type ReportData, type ReportDecisionItem, type ReportRendererInput, type ReportRendererResult, type ReportSessionItem, type ReportTaskItem, type ReviewGapRepoSummary, type ReviewGapUnit, type ReviewGapVerdict, type ReviewGapsInput, type ReviewGapsSummary, type RiskLevel, RiskLevelSchema, type RosterAdoptionPlan, type RosterDriftSummary, type RunOptions, type RunResult, STUCK_THRESHOLD_MS, type SanitizePathOptions, type SanitizeRelatedFilesResult, SchemaVersionSchema, type Session, type SessionEndedEvent, type SessionEntry, SessionIdSchema, type SessionImportPayload, SessionImportPayloadSchema, type SessionInnerImportInput, SessionInnerImportSchema, type SessionIntegrity, SessionIntegritySchema, type SessionMetrics, SessionMetricsSchema, SessionSchema, type SessionSkipReason, type SessionSourceKind, SessionSourceKindSchema, type SessionStartedEvent, type SessionStatus, type SessionStatusChangedEvent, SessionStatusSchema, type SessionWorkStats, type SourceRootsReconcile, type SourceWorkStats, type StatusCount, StatusSchema, type StatusSnapshot, type SuspectReason, type SymlinkCollision, type SymlinkConflict, type SymlinkPlanSummary, type Task, type TaskArchivedEvent, type TaskCreatedEvent, type TaskDeletedEvent, type TaskDocument, TaskIdSchema, type TaskLinkageRefreshedEvent, type TaskReconciledEvent, TaskSchema, type TaskSkipReason, type TaskStatus, type TaskStatusChangedEvent, type TaskStatusCount, TaskStatusSchema, TaskWriteAfterEventError, type TaskWriteAfterEventPhase, type TokenTotals, type UpdateAdHocTaskStatusInput, type UpdateTaskStatusInput, type UpdateTaskStatusResult, type ViewCollision, type ViewConflict, type ViewLinkState, type ViewRepoFact, type ViewStrayUnknown, type WiringRisk, type WiringSummary, type WorkStatsInput, type WorkStatsResult, type WorkStatsTotals, WorkspaceIdSchema, type WorkspaceViewPlan, type WriteEventsBulkOptions, type WriteTaskFileMode, acquireLock, appendBasouGitignore, appendChainedEvent, appendChainedEventLocked, appendEvent, appendEventToExistingSession, archiveTask, assertBasouRootSafe, basouPaths, buildJsonSchemas, buildStatusSnapshot, chainEvents, chainRawJsonLines, classifySuspect, claudeCodeAdapterMetadata, claudeTranscriptToImportPayload, codexRolloutToImportPayload, computeWorkStats, createAdHocSessionWithEvent, createManifest, createTaskWithEvent, deleteTask, editTask, ensureBasouDirectory, enumerateApprovals, enumerateArchivedTaskIds, enumerateSessionDirs, enumerateTaskIds, finalizeSessionYaml, findErrorCode, findReviewGaps, formatDurationMs, genesisHash, getDiff, getSnapshot, importSessionFromJson, inspectChainTail, isGitNotFound, isImportDerivedSource, isLazyExpired, isRenderable, isValidPrefixedId, lineHash, linkYamlFile, loadApproval, loadSessionEntries, loadTaskEntries, normalizeRepoKey, normalizeRepoPath, overwriteYamlFile, parseDuration, parseMarkers, pathBasename, planArchive, planGitignore, planRename, planRosterAdoption, planWorkspaceView, prefixedUlid, readAllEvents, readManifest, readMarkdownFile, readSessionYaml, readStatus, readTaskFile, readTaskFileWithArchiveFallback, readYamlFile, rechainSessionInPlace, reconcileAllTasks, reconcileSourceRoots, reconcileTask, refreshTaskLinkedSessions, reimportPreservingId, renderDecisions, renderHandoff, renderOrientation, renderPresetBlock, renderReport, renderWithMarkers, replayEvents, resolveBasouRepositoryRoot, resolveClaudeCodeCommand, resolveRepositoryRoot, resolveSessionId, resolveTaskId, safeSimpleGit, sanitizePath, sanitizeRelatedFiles, sanitizeWorkingDirectory, serializeEventLine, serializeJsonSchema, sessionWorkStatsFromEvents, summarizeAdapterOutput, summarizeOrientation, summarizePresetPlan, summarizeRosterDrift, summarizeSymlinkPlan, summarizeWiring, tryRemoteUrl, ulid, unknownManifestKeys, updateTaskStatusWithEvent, verifyEventsChain, writeEventsBulk, writeManifest, writeMarkdownFile, writeStatus, writeTaskFile, writeYamlFile };
5327
+ export { ACTIVE_GAP_CAP_MS, type ActiveTimeBasis, type AdapterOutputEvent, type AdoptCandidate, type AdoptCandidateKind, type AppendBasouGitignoreOptions, type AppendBasouGitignoreResult, type AppendEventToExistingInput, type AppendEventToExistingResult, type Approval, type ApprovalApprovedEvent, type ApprovalExpiredEvent, ApprovalIdSchema, type ApprovalLocation, type ApprovalRejectedEvent, type ApprovalRequestedEvent, ApprovalSchema, type ApprovalStatus, ApprovalStatusSchema, type ArchivePlan, type ArchiveTaskInput, type ArchiveTaskResult, type AttachTaskInput, type AttachUpdateTaskStatusInput, type AttachableStatus, BASOU_CORE_VERSION, type BasouPaths, type BulkChainResult, CLAUDE_IMPORT_SOURCE, CODEX_IMPORT_SOURCE, type CaptureMode, type ChainBreakReason, type ChainTailState, type ChainVerdict, type ChainVerdictStatus, type ChainedEvents, ChildProcessRunner, type CitedReview, type ClaudeTranscriptRecord, type ClaudeTranscriptToPayloadOptions, type CodexRolloutRecord, type CodexRolloutToPayloadOptions, type CommandExecutedEvent, type CommandLookup, type CreateAdHocSessionInput, type CreateAdHocSessionResult, type CreateAdHocTaskInput, type CreateManifestInput, type CreateTaskInput, type CreateTaskResult, type DayWorkStats, DecisionIdSchema, type DecisionRecordedEvent, type DecisionsRendererInput, type DecisionsRendererResult, type DeleteTaskInput, type DeleteTaskResult, type DiffResult, type EditTaskInput, type EditTaskResult, type Event, EventIdSchema, EventSchema, EventSourceSchema, type ExistingViewLink, FailedToFinalizeError, type FileChange, type FileChangeStatus, type FileChangedEvent, GENERATED_END, GENERATED_START, type GitSnapshot, type GitSnapshotEvent, type GitignorePlanSummary, type HandoffRendererInput, type HandoffRendererResult, ID_PREFIXES, type IdPrefix, type ImportSessionOptions, type ImportSessionResult, type InstructionFileFact, type InstructionSymlinkFact, type InstructionSymlinkState, IsoTimestampSchema, JSON_SCHEMA_VERSION, type JsonSchemaArtifact, type LoadSessionEntriesOptions, type LoadTaskEntriesOptions, type LoadedApproval, type LockHandle, type LockScope, type Manifest, ManifestSchema, type MarkerSection, type Markers, type MeasureAvailability, type NoteAddedEvent, type OrientationRendererInput, type OrientationRendererResult, type OrientationSummary, PROTOCOL_END, PROTOCOL_START, type PrefixedId, type PresetAction, type PresetCollision, type PresetMarkerConflict, type PresetMarkerKind, type PresetPlanSummary, type PresetRepo, type ProcessRunner, type PublishKind, type PublishTarget, type RechainOptions, type RechainResult, type ReconcileAllResult, type ReconcileAllTasksInput, type ReconcileAllTasksOptions, type ReconcileFailure, type ReconcileResult, type ReconcileTaskInput, type RefreshLinkageInput, type RefreshLinkageResult, type ReimportOptions, type ReimportResult, type RenamePlan, type ReplayOptions, type ReplayWarning, type RepoEntry, type RepoGitignoreFacts, type RepoGitignorePlan, type RepoLanguage, type RepoPresetFacts, type RepoPresetPlan, type RepoSymlinkFacts, type RepoSymlinkPlan, type RepoVisibility, type RepoWiringFacts, type ReportApprovalItem, type ReportData, type ReportDecisionItem, type ReportRendererInput, type ReportRendererResult, type ReportSessionItem, type ReportTaskItem, type ReviewGapRepoSummary, type ReviewGapUnit, type ReviewGapVerdict, type ReviewGapsInput, type ReviewGapsSummary, type RiskLevel, RiskLevelSchema, type RosterAdoptionPlan, type RosterDriftSummary, type RunOptions, type RunResult, STUCK_THRESHOLD_MS, type SanitizePathOptions, type SanitizeRelatedFilesResult, SchemaVersionSchema, type Session, type SessionEndedEvent, type SessionEntry, SessionIdSchema, type SessionImportPayload, SessionImportPayloadSchema, type SessionInnerImportInput, SessionInnerImportSchema, type SessionIntegrity, SessionIntegritySchema, type SessionMetrics, SessionMetricsSchema, SessionSchema, type SessionSkipReason, type SessionSourceKind, SessionSourceKindSchema, type SessionStartedEvent, type SessionStatus, type SessionStatusChangedEvent, SessionStatusSchema, type SessionWorkStats, type SourceRootsReconcile, type SourceWorkStats, type StatusCount, StatusSchema, type StatusSnapshot, type SuspectReason, type SymlinkCollision, type SymlinkConflict, type SymlinkPlanSummary, type Task, type TaskArchivedEvent, type TaskCreatedEvent, type TaskDeletedEvent, type TaskDocument, TaskIdSchema, type TaskLinkageRefreshedEvent, type TaskReconciledEvent, TaskSchema, type TaskSkipReason, type TaskStatus, type TaskStatusChangedEvent, type TaskStatusCount, TaskStatusSchema, TaskWriteAfterEventError, type TaskWriteAfterEventPhase, type TokenTotals, type UpdateAdHocTaskStatusInput, type UpdateTaskStatusInput, type UpdateTaskStatusResult, type ViewCollision, type ViewConflict, type ViewLinkState, type ViewRepoFact, type ViewStrayUnknown, type WiringRisk, type WiringSummary, type WorkStatsInput, type WorkStatsResult, type WorkStatsTotals, WorkspaceIdSchema, type WorkspaceViewPlan, type WriteEventsBulkOptions, type WriteTaskFileMode, acquireLock, appendBasouGitignore, appendChainedEvent, appendChainedEventLocked, appendEvent, appendEventToExistingSession, archiveTask, assertBasouRootSafe, basouPaths, buildJsonSchemas, buildStatusSnapshot, chainEvents, chainRawJsonLines, classifySuspect, claudeCodeAdapterMetadata, claudeTranscriptToImportPayload, codexRolloutToImportPayload, computeWorkStats, createAdHocSessionWithEvent, createManifest, createTaskWithEvent, deleteTask, editTask, ensureBasouDirectory, enumerateApprovals, enumerateArchivedTaskIds, enumerateSessionDirs, enumerateTaskIds, finalizeSessionYaml, findErrorCode, findReviewGaps, formatDurationMs, genesisHash, getDiff, getSnapshot, importSessionFromJson, inspectChainTail, isGitNotFound, isImportDerivedSource, isLazyExpired, isRenderable, isValidPrefixedId, lineHash, linkYamlFile, loadApproval, loadSessionEntries, loadTaskEntries, normalizeRepoKey, normalizeRepoPath, overwriteYamlFile, parseDuration, parseMarkers, pathBasename, planArchive, planGitignore, planRename, planRosterAdoption, planWorkspaceView, prefixedUlid, readAllEvents, readManifest, readMarkdownFile, readSessionYaml, readStatus, readTaskFile, readTaskFileWithArchiveFallback, readYamlFile, rechainSessionInPlace, reconcileAllTasks, reconcileSourceRoots, reconcileTask, refreshTaskLinkedSessions, reimportPreservingId, removeMarkerSection, renderDecisions, renderHandoff, renderOrientation, renderPresetBlock, renderReport, renderWithMarkers, replayEvents, resolveBasouRepositoryRoot, resolveClaudeCodeCommand, resolveRepositoryRoot, resolveSessionId, resolveTaskId, safeSimpleGit, sanitizePath, sanitizeRelatedFiles, sanitizeWorkingDirectory, serializeEventLine, serializeJsonSchema, sessionWorkStatsFromEvents, summarizeAdapterOutput, summarizeOrientation, summarizePresetPlan, summarizeRosterDrift, summarizeSymlinkPlan, summarizeWiring, tryRemoteUrl, ulid, unknownManifestKeys, updateTaskStatusWithEvent, verifyEventsChain, writeEventsBulk, writeManifest, writeMarkdownFile, writeStatus, writeTaskFile, writeYamlFile };
package/dist/index.js CHANGED
@@ -6505,6 +6505,9 @@ function hasErrorCode5(error) {
6505
6505
  import { readFile as readFile9 } from "fs/promises";
6506
6506
  var GENERATED_START = "<!-- BASOU:GENERATED:START -->";
6507
6507
  var GENERATED_END = "<!-- BASOU:GENERATED:END -->";
6508
+ var PROTOCOL_START = "<!-- BASOU:PROTOCOLS:START -->";
6509
+ var PROTOCOL_END = "<!-- BASOU:PROTOCOLS:END -->";
6510
+ var DEFAULT_MARKERS = { start: GENERATED_START, end: GENERATED_END };
6508
6511
  async function readMarkdownFile(filePath) {
6509
6512
  try {
6510
6513
  return await readFile9(filePath, "utf8");
@@ -6520,13 +6523,15 @@ async function writeMarkdownFile(filePath, body) {
6520
6523
  throw new Error("Failed to write markdown file", { cause: error });
6521
6524
  }
6522
6525
  }
6523
- function parseMarkers(content) {
6524
- const lines = content.split(/\r?\n/);
6526
+ function parseMarkers(content, markers = DEFAULT_MARKERS) {
6527
+ const bom = content.charCodeAt(0) === 65279 ? "\uFEFF" : "";
6528
+ const body = bom === "" ? content : content.slice(1);
6529
+ const lines = body.split(/\r?\n/);
6525
6530
  const startLines = [];
6526
6531
  const endLines = [];
6527
6532
  for (let i = 0; i < lines.length; i++) {
6528
- if (lines[i] === GENERATED_START) startLines.push(i);
6529
- else if (lines[i] === GENERATED_END) endLines.push(i);
6533
+ if (lines[i] === markers.start) startLines.push(i);
6534
+ else if (lines[i] === markers.end) endLines.push(i);
6530
6535
  }
6531
6536
  if (startLines.length === 0 && endLines.length === 0) return { kind: "no_markers" };
6532
6537
  if (startLines.length === 0) return { kind: "missing_start" };
@@ -6535,30 +6540,30 @@ function parseMarkers(content) {
6535
6540
  const startLineIdx = startLines[0];
6536
6541
  const endLineIdx = endLines[0];
6537
6542
  if (endLineIdx < startLineIdx) return { kind: "wrong_order" };
6538
- const startOffset = lineStartOffset(content, startLineIdx);
6539
- const endLineStart = lineStartOffset(content, endLineIdx);
6540
- const startLineEnd = startOffset + GENERATED_START.length;
6541
- const endLineEnd = endLineStart + GENERATED_END.length;
6542
- const before = content.slice(0, startOffset);
6543
- const afterStartNewline = skipOneNewline(content, startLineEnd);
6544
- const beforeEndNewline = trimOneNewline(content, endLineStart);
6545
- const generated = content.slice(afterStartNewline, beforeEndNewline);
6546
- const after = content.slice(endLineEnd);
6543
+ const startOffset = lineStartOffset(body, startLineIdx);
6544
+ const endLineStart = lineStartOffset(body, endLineIdx);
6545
+ const startLineEnd = startOffset + markers.start.length;
6546
+ const endLineEnd = endLineStart + markers.end.length;
6547
+ const before = bom + body.slice(0, startOffset);
6548
+ const afterStartNewline = skipOneNewline(body, startLineEnd);
6549
+ const beforeEndNewline = trimOneNewline(body, endLineStart);
6550
+ const generated = body.slice(afterStartNewline, beforeEndNewline);
6551
+ const after = body.slice(endLineEnd);
6547
6552
  return { kind: "ok", before, generated, after };
6548
6553
  }
6549
- function renderWithMarkers(existing, generated, fileLabel) {
6554
+ function renderWithMarkers(existing, generated, fileLabel, markers = DEFAULT_MARKERS) {
6550
6555
  const normalized = generated.endsWith("\n") ? generated : `${generated}
6551
6556
  `;
6552
6557
  if (existing === null) {
6553
- return `${GENERATED_START}
6554
- ${normalized}${GENERATED_END}
6558
+ return `${markers.start}
6559
+ ${normalized}${markers.end}
6555
6560
  `;
6556
6561
  }
6557
- const section = parseMarkers(existing);
6562
+ const section = parseMarkers(existing, markers);
6558
6563
  switch (section.kind) {
6559
6564
  case "ok":
6560
- return `${section.before}${GENERATED_START}
6561
- ${normalized}${GENERATED_END}${section.after}`;
6565
+ return `${section.before}${markers.start}
6566
+ ${normalized}${markers.end}${section.after}`;
6562
6567
  case "no_markers":
6563
6568
  throw new Error(`Markers missing in ${fileLabel}`);
6564
6569
  case "missing_start":
@@ -6568,6 +6573,22 @@ ${normalized}${GENERATED_END}${section.after}`;
6568
6573
  throw new Error(`Markers mismatched in ${fileLabel}`);
6569
6574
  }
6570
6575
  }
6576
+ function removeMarkerSection(existing, fileLabel, markers = DEFAULT_MARKERS) {
6577
+ const section = parseMarkers(existing, markers);
6578
+ switch (section.kind) {
6579
+ case "no_markers":
6580
+ return existing;
6581
+ case "ok": {
6582
+ const after = section.after.replace(/^\r?\n/, "");
6583
+ return section.before + after;
6584
+ }
6585
+ case "missing_start":
6586
+ case "missing_end":
6587
+ case "multiple_pairs":
6588
+ case "wrong_order":
6589
+ throw new Error(`Markers mismatched in ${fileLabel}`);
6590
+ }
6591
+ }
6571
6592
  function lineStartOffset(content, lineIdx) {
6572
6593
  if (lineIdx === 0) return 0;
6573
6594
  let offset = 0;
@@ -7008,6 +7029,8 @@ export {
7008
7029
  IsoTimestampSchema,
7009
7030
  JSON_SCHEMA_VERSION,
7010
7031
  ManifestSchema,
7032
+ PROTOCOL_END,
7033
+ PROTOCOL_START,
7011
7034
  RiskLevelSchema,
7012
7035
  STUCK_THRESHOLD_MS,
7013
7036
  SchemaVersionSchema,
@@ -7098,6 +7121,7 @@ export {
7098
7121
  reconcileTask,
7099
7122
  refreshTaskLinkedSessions,
7100
7123
  reimportPreservingId,
7124
+ removeMarkerSection,
7101
7125
  renderDecisions,
7102
7126
  renderHandoff,
7103
7127
  renderOrientation,