dsh-openwrite 0.2.24 → 0.2.26

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 (39) hide show
  1. package/README.md +17 -6
  2. package/docs/COST_MEASUREMENT.md +2 -2
  3. package/docs/DEVELOPMENT.md +1 -1
  4. package/docs/DSH_STORE.md +7 -1
  5. package/docs/GITEE_EMBEDDING_FIX.md +40 -0
  6. package/docs/INSTALL.md +21 -1
  7. package/docs/ISSUES_105_113.md +15 -0
  8. package/docs/ISSUES_88_95.md +4 -4
  9. package/docs/ISSUES_98_100.md +61 -0
  10. package/docs/ISSUE_109_REPAIRS.md +40 -0
  11. package/docs/OPENCODE_GO.md +31 -0
  12. package/docs/PLUGIN_MAINTENANCE.md +1 -1
  13. package/docs/RELEASE_ACCEPTANCE.md +18 -0
  14. package/package.json +11 -8
  15. package/packages/openwrite-bridge/lib/client.d.ts +2 -0
  16. package/packages/openwrite-bridge/lib/client.js +26 -2
  17. package/packages/openwrite-bridge/lib/domain.js +22 -3
  18. package/packages/openwrite-bridge/lib/index.d.ts +2 -0
  19. package/packages/openwrite-bridge/lib/index.js +3 -1
  20. package/packages/openwrite-bridge/lib/managed-runtime.d.ts +6 -0
  21. package/packages/openwrite-bridge/lib/managed-runtime.js +11 -1
  22. package/packages/openwrite-bridge/lib/tool-policy.js +2 -0
  23. package/packages/openwrite-bridge/lib/tools.js +103 -8
  24. package/packages/openwrite-bridge/package.json +6 -5
  25. package/packages/studio-panel/lib/client.js +1628 -580
  26. package/packages/studio-panel/lib/client.js.map +1 -1
  27. package/packages/studio-panel/lib/types/client/SerialWritingView.d.ts +6 -0
  28. package/packages/studio-panel/lib/types/client/benchmark-options.d.ts +1 -0
  29. package/packages/studio-panel/lib/types/client/dto.d.ts +3 -1
  30. package/packages/studio-panel/lib/types/client/locales.d.ts +1 -1
  31. package/packages/studio-panel/package.json +4 -3
  32. package/plugin.mjs +20 -10
  33. package/preset-definition.mjs +7 -1
  34. package/presets/openwrite/agent.cordis.yml +11 -0
  35. package/release/{openwrite-5.8.11-py3-none-any.whl → openwrite-5.8.14-py3-none-any.whl} +0 -0
  36. package/release/runtime-manifest.json +5 -5
  37. package/release/source.json +3 -3
  38. package/scripts/safe-upgrade.mjs +211 -0
  39. package/vendor/dsh-dog/package.json +10 -9
@@ -0,0 +1,6 @@
1
+ import type { ModelNavigationGuard } from './ModelView.tsx';
2
+ import type { OperationsViewProps } from './OperationsView.tsx';
3
+ /** Deterministic chapter diagnostics and author-owned serial-writing assets. */
4
+ export declare function SerialWritingView({ fetchStudioApi, postStudioApi, t, onNavigationGuardChange }: Pick<OperationsViewProps, 'fetchStudioApi' | 'postStudioApi' | 't'> & {
5
+ onNavigationGuardChange?: (guard: ModelNavigationGuard | null) => void;
6
+ }): import("react").JSX.Element;
@@ -21,6 +21,7 @@ export interface BenchmarkOptions {
21
21
  hasManuscript: boolean;
22
22
  available: boolean;
23
23
  reason: string;
24
+ rewriteAvailable: boolean;
24
25
  }[];
25
26
  nextChapterId: string;
26
27
  defaultOutlineStart: number;
@@ -46,6 +46,8 @@ export type ConnectionTestResultDto = {
46
46
  latency_ms: number | null;
47
47
  tested_at: string;
48
48
  reply: string;
49
+ dimension: number | null;
50
+ vectors: number | null;
49
51
  };
50
52
  export declare function parseConnectionTestResult(value: unknown): ConnectionTestResultDto;
51
53
  /** Read-only payload of POST /model/profiles/delete-preview (enveloped). */
@@ -89,7 +91,7 @@ export type ResultRefDto = {
89
91
  };
90
92
  export declare function parseResultRef(value: unknown): ResultRefDto | null;
91
93
  export type ExportFormatDto = 'md' | 'txt' | 'epub';
92
- export type ExportPurposeDto = 'backup' | 'delivery';
94
+ export type ExportPurposeDto = 'backup' | 'delivery' | 'personal_archive';
93
95
  export type ExportChapterDto = {
94
96
  chapter_id: string;
95
97
  number: number;
@@ -2,7 +2,7 @@
2
2
  /** Dictionary namespace owned by this plugin. */
3
3
  export declare const NS = "studio-panel";
4
4
  /** The studio-panel dictionary key set (the source of truth for both locales). */
5
- export type StudioPanelKey = 'view.overview' | 'view.writing' | 'view.studio' | 'view.reviewWs' | 'view.outline' | 'view.assets' | 'view.tasks' | 'view.benchmark' | 'view.models' | 'view.graph' | 'view.research' | 'view.search' | 'view.creation' | 'view.library' | 'view.operations' | 'creation.chapters' | 'creation.searchChapters' | 'creation.clearSearch' | 'creation.chaptersEmpty' | 'creation.previousChapter' | 'creation.nextChapter' | 'creation.jumpChapter' | 'creation.chapterDuplicate' | 'creation.order.loading' | 'creation.order.unavailable' | 'creation.order.refresh' | 'creation.order.invalid' | 'creation.order.missingCount' | 'creation.order.move' | 'creation.order.volume' | 'creation.order.position' | 'creation.order.positionHelp' | 'creation.order.applyMove' | 'creation.order.blocked' | 'creation.order.moveComplete' | 'creation.order.conflict' | 'creation.mode.edit' | 'creation.mode.reader' | 'creation.writing.bookProgress' | 'creation.writing.chapterTarget' | 'creation.writing.chapterProgress' | 'creation.reader.title' | 'creation.reader.readOnly' | 'creation.reader.loading' | 'creation.reader.refresh' | 'creation.reader.openEditor' | 'creation.reader.path' | 'creation.reader.documentId' | 'creation.reader.revision' | 'creation.reader.revisionUnavailable' | 'creation.showChapters' | 'creation.hideChapters' | 'creation.inspector' | 'creation.showInspector' | 'creation.hideInspector' | 'creation.editorLoading' | 'creation.documentLoading' | 'creation.inspectorLoading' | 'creation.inspectorLoadingSlow' | 'creation.empty' | 'creation.acceptance.title' | 'creation.acceptance.loading' | 'creation.acceptance.current' | 'creation.acceptance.pending' | 'creation.acceptance.drift' | 'creation.acceptance.baselinePending' | 'creation.acceptance.needsReview' | 'creation.acceptance.failed' | 'creation.acceptance.unknown' | 'creation.acceptance.unavailable' | 'creation.acceptance.currentRevision' | 'creation.acceptance.acceptedRevision' | 'creation.acceptance.operation' | 'creation.acceptance.stale' | 'creation.acceptance.refresh' | 'creation.acceptance.baseline' | 'creation.acceptance.external' | 'creation.acceptance.resume' | 'creation.acceptance.acknowledge' | 'creation.acceptance.confirmBaseline' | 'creation.acceptance.confirmExternal' | 'creation.acceptance.confirmAcknowledge' | 'creation.context' | 'creation.review' | 'creation.revisions' | 'creation.activity' | 'creation.activity.loading' | 'creation.activity.unavailable' | 'creation.activity.invalid' | 'creation.activity.target' | 'creation.activity.remaining' | 'creation.activity.sprint' | 'creation.activity.sprintAdded' | 'creation.activity.sprintDeleted' | 'creation.activity.sprintNet' | 'creation.activity.sprintRevision' | 'creation.activity.sprintSaved' | 'creation.activity.identity' | 'creation.activity.recent' | 'creation.activity.empty' | 'creation.foreshadow.title' | 'creation.foreshadow.empty' | 'creation.foreshadow.due' | 'creation.foreshadow.overdue' | 'creation.foreshadow.toPlant' | 'creation.foreshadow.open' | 'creation.foreshadow.close' | 'creation.foreshadow.plant' | 'creation.foreshadow.reveal' | 'creation.foreshadow.status' | 'creation.foreshadow.weight' | 'creation.foreshadow.layer' | 'creation.foreshadow.source' | 'creation.contextEmpty' | 'creation.context.packet' | 'creation.context.current' | 'creation.context.stale' | 'creation.context.previousStale' | 'creation.context.requestBudget' | 'creation.context.sessionBudget' | 'creation.context.outputReserve' | 'creation.context.actualUsage' | 'creation.context.reported' | 'creation.context.unavailable' | 'creation.context.sessionSeparate' | 'creation.context.retrieval' | 'creation.context.sources' | 'creation.context.protected' | 'creation.context.noSnippet' | 'creation.context.reason' | 'creation.context.missing' | 'creation.context.excluded' | 'creation.context.fullText' | 'creation.reviewEmpty' | 'creation.review.stale' | 'creation.review.casUnavailable' | 'creation.review.refreshRequired' | 'creation.review.closure' | 'creation.review.closureProposal' | 'creation.review.closureRevision' | 'creation.review.outcome.resolved' | 'creation.review.outcome.retained' | 'creation.review.outcome.regressed' | 'creation.review.selectionSummary' | 'creation.review.instruction' | 'creation.review.createRevision' | 'creation.review.rereview' | 'creation.review.revisionStarted' | 'creation.review.rereviewStarted' | 'creation.revisionsEmpty' | 'creation.history.title' | 'creation.history.snapshot' | 'creation.history.snapshotName' | 'creation.history.snapshotCreated' | 'creation.history.empty' | 'creation.history.units' | 'creation.history.loading' | 'creation.history.compare' | 'creation.history.restorePreview' | 'creation.history.closePreview' | 'creation.history.noChanges' | 'creation.history.restore' | 'creation.history.restoreConfirm' | 'creation.history.restored' | 'creation.history.previewFailed' | 'creation.history.reason.autosave' | 'creation.history.reason.manual' | 'creation.history.reason.aiRevision' | 'creation.history.reason.fullRewrite' | 'creation.history.reason.restore' | 'creation.proposals.title' | 'creation.proposals.noRationale' | 'creation.proposals.range' | 'creation.proposals.evidence' | 'creation.proposals.reviewRevision' | 'creation.proposals.sourceRevision' | 'creation.proposals.noHunks' | 'creation.proposals.originalCandidate' | 'creation.proposals.reject' | 'creation.proposals.regenerate' | 'creation.proposals.applySelected' | 'creation.proposals.appliedNeedsReview' | 'creation.proposals.sourceConflict' | 'creation.selection.title' | 'creation.selection.expand' | 'creation.selection.compress' | 'creation.selection.naturalize' | 'creation.selection.reviewFix' | 'creation.selection.working' | 'creation.selection.staged' | 'creation.selection.empty' | 'creation.selection.saveRequired' | 'creation.selection.reviewRequired' | 'creation.selection.noIssues' | 'creation.selection.annotate' | 'creation.notes.title' | 'creation.notes.note' | 'creation.notes.color' | 'creation.notes.submit' | 'creation.notes.cancel' | 'creation.notes.working' | 'creation.notes.saved' | 'creation.notes.empty' | 'creation.notes.rangeLost' | 'creation.notes.saveRequired' | 'creation.notes.locate' | 'creation.notes.resolve' | 'creation.notes.resolved' | 'creation.notes.attached' | 'creation.notes.relocated' | 'creation.notes.detached' | 'creation.notes.quote' | 'creation.notes.color.amber' | 'creation.notes.color.rose' | 'creation.notes.color.sky' | 'creation.notes.color.lime' | 'creation.notes.color.violet' | 'creation.marker.insert' | 'creation.marker.title' | 'creation.marker.purpose' | 'creation.marker.state' | 'creation.marker.relation' | 'creation.marker.field' | 'creation.marker.oldState' | 'creation.marker.newState' | 'creation.marker.source' | 'creation.marker.target' | 'creation.marker.description' | 'creation.marker.pickCharacter' | 'creation.marker.insertNow' | 'creation.marker.cancel' | 'creation.marker.empty' | 'creation.marker.newline' | 'creation.marker.reserved' | 'creation.marker.needId' | 'creation.mentions.title' | 'creation.mentions.mention' | 'creation.mentions.card' | 'creation.mentions.aliases' | 'creation.mentions.close' | 'creation.mentions.ambiguous' | 'creation.mentions.choose' | 'creation.mentions.conflict' | 'creation.mentions.noSummary' | 'creation.issues' | 'creation.changedElsewhere' | 'creation.conflict' | 'creation.reload' | 'creation.overwrite' | 'creation.discardConfirm' | 'creation.overwriteConfirm' | 'creation.closePanel' | 'creation.draft.available' | 'creation.draft.conflict' | 'creation.draft.updated' | 'creation.draft.preview' | 'creation.draft.restore' | 'creation.draft.dismiss' | 'creation.draft.unavailable' | 'creation.status.idle' | 'creation.status.loading' | 'creation.status.saved' | 'creation.status.dirty' | 'creation.status.saving' | 'creation.status.conflict' | 'creation.status.offline' | 'operations.transfer' | 'operations.transferHint' | 'operations.project' | 'operations.create.new' | 'operations.create.id' | 'operations.create.title' | 'operations.create.submit' | 'operations.create.done' | 'operations.create.failed' | 'operations.create.pickHint' | 'operations.init.hint' | 'operations.init.submit' | 'operations.cancel' | 'workspace.unbound' | 'workspace.notInitialized' | 'workspace.bind.hint' | 'workspace.bind.pick' | 'workspace.bind.failed' | 'operations.create.titleHint' | 'tool.family.status' | 'tool.family.context' | 'tool.family.manuscript' | 'tool.family.revision' | 'tool.family.task' | 'tool.family.search' | 'tool.family.asset' | 'tool.family.outline' | 'tool.running' | 'tool.failed' | 'tool.succeeded' | 'tool.openChapter' | 'turn.changed' | 'turn.partial' | 'turn.failed' | 'turn.refreshFailed' | 'turn.history' | 'turn.proposed' | 'turn.rejected' | 'turn.entityChanges' | 'turn.before' | 'turn.after' | 'turn.missing' | 'turn.truncated' | 'turn.sourceRevision' | 'turn.resultRevision' | 'turn.committed' | 'turn.trace' | 'turn.modelCalls' | 'turn.days' | 'turn.accept' | 'turn.reject' | 'turn.retry' | 'turn.undo' | 'turn.applied' | 'turn.retried' | 'turn.undone' | 'resolving' | 'loading' | 'unreachable' | 'retry' | 'refresh' | 'openExternal' | 'outline.empty' | 'outline.drafted' | 'outline.planned' | 'outline.draftedCount' | 'outline.addChild' | 'outline.addAfter' | 'outline.addVolume' | 'outline.expandAll' | 'outline.collapseAll' | 'outline.del' | 'outline.confirmDelete' | 'outline.newTitlePlaceholder' | 'outline.opConflict' | 'outline.opFailed' | 'outline.summaryEmpty' | 'tools.title' | 'tools.export' | 'tools.export.done' | 'tools.export.failed' | 'tools.export.purpose' | 'tools.export.purpose.backup' | 'tools.export.purpose.delivery' | 'tools.export.format' | 'tools.export.preflight' | 'tools.export.loading' | 'tools.export.unavailable' | 'tools.export.refresh' | 'tools.export.revision' | 'tools.export.ready' | 'tools.export.blocked' | 'tools.export.download' | 'tools.export.order' | 'tools.export.orderEmpty' | 'tools.export.units' | 'tools.export.structure' | 'tools.export.structure.duplicates' | 'tools.export.structure.missing' | 'tools.export.structure.empty' | 'tools.export.structure.unreadable' | 'tools.export.clear' | 'tools.export.writingUnits' | 'tools.export.total' | 'tools.export.bookTarget' | 'tools.export.chapterTarget' | 'tools.export.completion' | 'tools.metadata.edit' | 'tools.metadata.save' | 'tools.metadata.cancel' | 'tools.metadata.hint' | 'tools.export.metadata' | 'tools.export.metadata.title' | 'tools.export.metadata.author' | 'tools.export.metadata.language' | 'tools.export.reviews' | 'tools.export.reviews.missing' | 'tools.export.reviews.current' | 'tools.export.reviews.stale' | 'tools.export.reviews.approved' | 'tools.export.reviews.notApproved' | 'tools.export.acceptance' | 'tools.export.acceptance.blocking' | 'tools.export.acceptance.blockingState' | 'tools.export.acceptance.needsReview' | 'tools.export.status' | 'tools.export.blockers' | 'tools.export.warnings' | 'tools.export.none' | 'tools.export.stale' | 'tools.sync' | 'tools.sync.done' | 'tools.sync.failed' | 'tools.import' | 'tools.import.empty' | 'tools.import.failed' | 'tools.import.done' | 'tools.import.choose' | 'tools.import.noFile' | 'tools.import.start' | 'tools.import.startAuto' | 'tools.import.preview' | 'tools.import.plan' | 'tools.import.conflicts' | 'tools.import.force' | 'tools.import.confirm' | 'tools.import.workspace.title' | 'tools.import.workspace.ownHint' | 'tools.import.workspace.operations' | 'tools.import.workspace.empty' | 'tools.import.workspace.new' | 'tools.import.workspace.file' | 'tools.import.workspace.arc' | 'tools.import.workspace.prepare' | 'tools.import.workspace.prepared' | 'tools.import.workspace.select' | 'tools.import.workspace.chapters' | 'tools.import.workspace.structure' | 'tools.import.workspace.chapterId' | 'tools.import.workspace.chapterTitle' | 'tools.import.workspace.chapterContent' | 'tools.import.workspace.moveUp' | 'tools.import.workspace.moveDown' | 'tools.import.workspace.remove' | 'tools.import.workspace.addChapter' | 'tools.import.workspace.newChapter' | 'tools.import.workspace.saveStructure' | 'tools.import.workspace.structureSaved' | 'tools.import.workspace.confirmStructure' | 'tools.import.workspace.confirmPrompt' | 'tools.import.workspace.confirmed' | 'tools.import.workspace.run' | 'tools.import.workspace.resume' | 'tools.import.workspace.taskStarted' | 'tools.import.workspace.discard' | 'tools.import.workspace.discardPrompt' | 'tools.import.workspace.discarded' | 'tools.import.workspace.recoverable' | 'tools.import.workspace.notRecoverable' | 'tools.import.stage.snapshot' | 'tools.import.stage.split' | 'tools.import.stage.structure_confirmed' | 'tools.import.stage.published' | 'tools.import.stage.acceptance' | 'tools.import.stage.reconcile' | 'tools.import.stage.synthesis' | 'tools.import.stage.complete' | 'tools.archive.title' | 'tools.archive.hint' | 'tools.archive.failed' | 'tools.archive.preflight' | 'tools.archive.create' | 'tools.archive.created' | 'tools.archive.list' | 'tools.archive.empty' | 'tools.archive.download' | 'tools.archive.downloaded' | 'tools.archive.files' | 'tools.archive.size' | 'tools.archive.categories' | 'tools.archive.includes' | 'tools.archive.excludes' | 'tools.archive.missing' | 'tools.archive.references' | 'tools.archive.referencePlan' | 'tools.archive.restore' | 'tools.archive.targetRoot' | 'tools.archive.pickTarget' | 'tools.archive.targetNovelId' | 'tools.archive.referencePolicy' | 'tools.archive.preserveRelative' | 'tools.archive.rewriteNovelId' | 'tools.archive.previewRestore' | 'tools.archive.restoreReady' | 'tools.archive.restoreBlocked' | 'tools.archive.conflicts' | 'tools.archive.pathRewrites' | 'tools.archive.rewrittenFiles' | 'tools.archive.rewrittenReferences' | 'tools.archive.preservedReferences' | 'tools.archive.referenceWarnings' | 'tools.archive.referenceConflicts' | 'tools.archive.tasksArchived' | 'tools.archive.autoResume' | 'tools.archive.noAutoResume' | 'tools.archive.confirmRestore' | 'tools.archive.restoreConfirm' | 'tools.archive.restoreStarted' | 'tasks.cancel' | 'tasks.cancel.title' | 'tasks.cancel.confirm' | 'tasks.cancel.done' | 'tasks.cancel.failed' | 'tasks.retry' | 'tasks.retry.title' | 'tasks.retry.notRecoverable' | 'tasks.retry.done' | 'tasks.retry.failed' | 'tasks.summary.total' | 'tasks.summary.updated' | 'tasks.filter.type' | 'tasks.filter.typeAll' | 'tasks.filter.chapter' | 'tasks.filter.keyword' | 'tasks.sort.newest' | 'tasks.sort.oldest' | 'tasks.sort.toggle' | 'tasks.progress.unknown' | 'tasks.phase.unknown' | 'tasks.confirm' | 'tasks.confirm.title' | 'tasks.confirm.done' | 'tasks.confirm.failed' | 'tasks.cancel.armYes' | 'tasks.cancel.armNo' | 'tasks.list' | 'tasks.detail.open' | 'tasks.detail.close' | 'tasks.detail.copyId' | 'tasks.detail.copied' | 'tasks.detail.events' | 'tasks.detail.eventsLoading' | 'tasks.detail.eventsEmpty' | 'tasks.detail.eventsFailed' | 'tasks.field.id' | 'tasks.field.type' | 'tasks.field.status' | 'tasks.field.phase' | 'tasks.field.chapter' | 'tasks.field.progress' | 'tasks.field.attempt' | 'tasks.field.created' | 'tasks.field.started' | 'tasks.field.updated' | 'tasks.field.completed' | 'tasks.field.summary' | 'tasks.field.resultRef' | 'tasks.field.failedStage' | 'tasks.field.errorCode' | 'tasks.field.recoverable' | 'tasks.field.yes' | 'tasks.field.no' | 'tasks.failure.cancelled' | 'tasks.failure.recoverable' | 'tasks.failure.provider' | 'tasks.failure.input' | 'tasks.failure.system' | 'tasks.jump.benchmark' | 'tasks.jump.research' | 'tasks.jump.chapter' | 'tasks.jump.review' | 'tasks.jump.unavailable' | 'tasks.jump.chapterHint' | 'tasks.jump.reviewHint' | 'tasks.jump.chapterMissing' | 'research.launch' | 'research.launch.placeholder' | 'research.launch.submit' | 'research.launch.submitting' | 'research.launch.submitted' | 'research.launch.failed' | 'research.launch.hint' | 'tasks.result.toggle' | 'tasks.result.score' | 'tasks.result.issues' | 'search.preview.back' | 'search.preview.openCreation' | 'search.preview.jumpReady' | 'search.preview.identityMismatch' | 'search.preview.locatorCurrent' | 'search.preview.locatorStale' | 'search.preview.locatorUnverified' | 'search.preview.revisionUnavailable' | 'search.change.title' | 'search.change.serverOwned' | 'search.change.unavailable' | 'search.change.currentLine' | 'search.change.replacement' | 'search.change.preview' | 'search.change.previewing' | 'search.change.sourceRevision' | 'search.change.resultRevision' | 'search.change.reject' | 'search.change.confirmApply' | 'search.change.applying' | 'search.change.refreshRequired' | 'search.change.invalidApply' | 'search.change.invalidReject' | 'search.change.applied' | 'search.change.rejected' | 'search.change.refresh' | 'assets.empty' | 'assets.other' | 'assets.stages' | 'assets.aliases' | 'assets.segment.characters' | 'assets.segment.world' | 'assets.segment.progression' | 'assets.segment.references' | 'assets.segment.core' | 'assets.segment.empty' | 'assets.references.empty' | 'assets.core.empty' | 'assets.detail.loading' | 'assets.draft.restored' | 'assets.draft.unsaved' | 'assets.draft.conflict' | 'assets.detail.relations' | 'assets.detail.index' | 'assets.list.detail_refs' | 'assets.list.taboos' | 'assets.edit.linesHint' | 'assets.relation.confirmed' | 'assets.relation.registered' | 'assets.relation.incoming' | 'assets.searchPlaceholder' | 'assets.edit.open' | 'assets.edit.name' | 'assets.edit.summary' | 'assets.edit.tags' | 'assets.edit.listHint' | 'assets.edit.save' | 'assets.edit.saving' | 'assets.edit.cancel' | 'assets.edit.conflict' | 'assets.edit.conflictRefresh' | 'assets.edit.addRelation' | 'assets.edit.removeRelation' | 'assets.edit.relationTarget' | 'assets.edit.relationNote' | 'assets.edit.derivedRelations' | 'assets.edit.body' | 'assets.edit.liveLoading' | 'assets.edit.optional' | 'assets.field.tier' | 'assets.field.personality' | 'assets.field.goal' | 'assets.field.fear' | 'assets.field.appearance' | 'assets.field.voice' | 'assets.field.current_state' | 'assets.field.organization' | 'assets.field.progression_system' | 'assets.field.progression_stage' | 'assets.field.status' | 'assets.field.kind' | 'assets.field.type' | 'assets.field.subtype' | 'assets.field.state_updated_at' | 'assets.field.role' | 'assets.edit.liveFailed' | 'assets.selectHint' | 'assets.create.open' | 'assets.create.submit' | 'assets.create.idHint' | 'assets.create.tier' | 'assets.create.type' | 'assets.create.progressionKind' | 'assets.create.stages' | 'assets.create.stageId' | 'assets.create.stageName' | 'assets.create.addStage' | 'tasks.empty' | 'tasks.filter.all' | 'tasks.attempt' | 'tasks.status.pending' | 'tasks.status.running' | 'tasks.status.awaiting_confirmation' | 'tasks.status.completed' | 'tasks.status.failed' | 'tasks.status.cancelled' | 'tasks.status.interrupted' | 'tasks.phase.queued' | 'tasks.phase.reading' | 'tasks.phase.preparing' | 'tasks.phase.model' | 'tasks.phase.validating' | 'tasks.phase.committing' | 'tasks.phase.complete' | 'tasks.type.chapter_write' | 'tasks.type.chapter_review' | 'tasks.type.continuous_write' | 'tasks.type.revision' | 'tasks.type.source_operation' | 'tasks.type.reference_operation' | 'tasks.type.manuscript_import' | 'tasks.type.project_restore' | 'tasks.type.research' | 'tasks.type.model_benchmark' | 'graph.foreshadowing' | 'graph.relationships' | 'graph.nodes' | 'graph.connections' | 'graph.relayout' | 'graph.weight' | 'graph.target' | 'graph.truncated' | 'graph.validation.errors' | 'graph.empty.foreshadowing' | 'graph.empty.relationships' | 'graph.entityType' | 'graph.entityStatus' | 'graph.search' | 'graph.connectedOnly' | 'graph.neighbors' | 'graph.edgeType' | 'graph.origin' | 'graph.source' | 'graph.confirmed' | 'dag.quality' | 'dag.coverage' | 'dag.gate' | 'dag.delivery' | 'dag.current' | 'dag.stale' | 'dag.toRevision' | 'dag.toRevisionDone' | 'dag.toRevisionFailed' | 'graph.unresolved' | 'graph.kind.character' | 'graph.kind.faction' | 'graph.kind.place' | 'graph.kind.concept' | 'graph.kind.other' | 'graph.truth' | 'graph.truth.currentState' | 'graph.truth.ledger' | 'graph.truth.relationships' | 'graph.workflows' | 'graph.workflow.currentStage' | 'graph.empty.truth' | 'graph.empty.truthDoc' | 'graph.empty.workflows' | 'graph.reviewDag' | 'graph.reviewFramework' | 'graph.reviewDomains' | 'graph.reviewChecks' | 'graph.reviewCriteria' | 'graph.deliveryDag' | 'graph.filter.all' | 'graph.filter.anomaly' | 'graph.filter.blocker' | 'graph.expandChecks' | 'graph.collapseChecks' | 'graph.empty.dag' | 'benchmark.title' | 'benchmark.taskType' | 'benchmark.executionEvidence' | 'benchmark.evidence' | 'benchmark.status.skipped' | 'benchmark.status.stale' | 'benchmark.task.chapter' | 'benchmark.task.outline' | 'benchmark.task.chapterHint' | 'benchmark.task.outlineHint' | 'benchmark.planner' | 'benchmark.nextChapter' | 'benchmark.chapterWritten' | 'benchmark.chapterPlanned' | 'benchmark.chapterUnavailable' | 'benchmark.customChapter' | 'benchmark.chapterId' | 'benchmark.outlineOrigin' | 'benchmark.continueOutline' | 'benchmark.customOutlineStart' | 'benchmark.outlineStart' | 'benchmark.outlineCount' | 'benchmark.rangeFrom' | 'benchmark.rangeTo' | 'benchmark.chapterUnit' | 'benchmark.invalidRange' | 'benchmark.outlineRangeHint' | 'benchmark.earliestOutlineStart' | 'benchmark.invalidChapter' | 'benchmark.historicalChapterHint' | 'benchmark.autoDag' | 'benchmark.executedDag' | 'benchmark.dagAutomatic' | 'benchmark.afterStage' | 'benchmark.reviewScope' | 'benchmark.isolatedHint' | 'benchmark.pipelineUnavailable' | 'benchmark.actualChapters' | 'benchmark.pipelineFinished' | 'benchmark.pipelineStatus' | 'benchmark.reviewIncomplete' | 'benchmark.partialScore' | 'benchmark.reviewIncompleteHint' | 'benchmark.completeReviews' | 'benchmark.reportedCoverage' | 'benchmark.coveragePending' | 'benchmark.factsPendingTitle' | 'benchmark.factsPendingHint' | 'benchmark.selectModels' | 'benchmark.description' | 'benchmark.configure' | 'benchmark.modelHint' | 'benchmark.advanced' | 'benchmark.history' | 'benchmark.results' | 'benchmark.noProfiles' | 'benchmark.chooseModels' | 'benchmark.workload' | 'benchmark.submitting' | 'benchmark.noCandidates' | 'benchmark.noEvaluations' | 'benchmark.plannedCandidates' | 'benchmark.plannedEvaluations' | 'benchmark.task' | 'benchmark.mode' | 'benchmark.mode.framework' | 'benchmark.mode.creative' | 'benchmark.mode.unknown' | 'benchmark.reviewer' | 'benchmark.chapter' | 'benchmark.repeats' | 'benchmark.words' | 'benchmark.concurrency' | 'benchmark.run' | 'benchmark.empty' | 'benchmark.select' | 'benchmark.averageScore' | 'benchmark.output' | 'benchmark.candidate' | 'benchmark.candidates' | 'benchmark.evaluations' | 'benchmark.writer' | 'benchmark.path' | 'benchmark.status' | 'benchmark.actualWords' | 'benchmark.finishReason' | 'benchmark.error' | 'benchmark.coverage' | 'benchmark.gate' | 'benchmark.delivery' | 'benchmark.productionGate' | 'benchmark.productionGateMissing' | 'benchmark.domains' | 'benchmark.latency' | 'benchmark.usage' | 'benchmark.cost' | 'benchmark.inputTokens' | 'benchmark.outputTokens' | 'benchmark.reasoningTokens' | 'benchmark.totalTokens' | 'benchmark.actualCost' | 'benchmark.costCoverage' | 'benchmark.effectiveRate' | 'benchmark.runs' | 'benchmark.sameInputGroup' | 'benchmark.comparisonIncomplete' | 'benchmark.inputProvenance' | 'benchmark.runPhases' | 'benchmark.phase.created' | 'benchmark.phase.started' | 'benchmark.phase.completed' | 'benchmark.contextHash' | 'benchmark.comparisonKey' | 'benchmark.promptVersion' | 'benchmark.rubricVersion' | 'benchmark.blindReview' | 'benchmark.contextStrategy' | 'benchmark.manifestVersion' | 'benchmark.tokenEstimator' | 'benchmark.packetRevision' | 'benchmark.sourceRevision' | 'benchmark.estimatedTokens' | 'benchmark.characters' | 'benchmark.contextSources' | 'benchmark.sourcePresent' | 'benchmark.sourceMissing' | 'benchmark.responseIdentity' | 'models.title' | 'models.list' | 'models.editor' | 'models.new' | 'models.empty' | 'models.id' | 'models.label' | 'models.provider' | 'models.protocol.openai' | 'models.protocol.anthropic' | 'models.modelId' | 'models.baseUrl' | 'models.apiFormat' | 'models.context' | 'models.output' | 'models.credential' | 'models.embeddingProvider' | 'models.embeddingModel' | 'models.embeddingCredential' | 'models.credentialHint' | 'models.remember' | 'models.save' | 'models.chatTest' | 'models.embeddingTest' | 'models.delete' | 'models.delete.confirm' | 'models.delete.blocked' | 'models.delete.wouldFail' | 'models.test.untested' | 'models.test.ok' | 'models.test.failed' | 'models.dependencies' | 'models.dependenciesHint' | 'models.fallback' | 'models.chooseFallback' | 'models.routes' | 'models.routesSave' | 'models.saved' | 'models.deleted' | 'models.chatOk' | 'models.embeddingOk' | 'models.configured' | 'models.missing' | 'models.routesSaved' | 'models.group.basic' | 'models.group.connection' | 'models.group.generation' | 'models.group.embedding' | 'models.group.credentials' | 'models.group.routeUsage' | 'models.temperature' | 'models.timeout' | 'models.embeddingBaseUrl' | 'models.validation.required' | 'models.validation.positive' | 'models.validation.temperature' | 'models.unsavedChanges' | 'models.unsavedDiscard' | 'models.unsavedKeep' | 'models.test.loading' | 'models.usedByRoutes' | 'models.noRoutes' | 'models.delete.resultingRoutes' | 'models.embeddingEmpty' | 'models.embeddingConfigured' | 'models.embeddingMissing' | 'models.active' | 'models.inactive' | 'models.route.goethe' | 'models.route.dante' | 'models.route.chapter_write' | 'models.route.review' | 'models.route.source_extract' | 'models.route.revision' | 'models.route.search' | 'models.route.research' | 'models.routesImpact' | 'models.routesUnchanged' | 'models.routesUnassigned' | 'models.embedConfigured' | 'models.embedMissing' | 'models.capability.chat' | 'models.capability.embedding' | 'research.reports' | 'research.unavailable' | 'research.empty' | 'research.selectHint' | 'research.report.loading' | 'research.quality' | 'research.language' | 'research.filter.keyword' | 'research.filter.status' | 'research.filter.sources' | 'research.filter.all' | 'research.status.succeeded' | 'research.status.failed' | 'research.status.needsReview' | 'research.status.unknown' | 'research.sourcesAvailable' | 'research.sourcesUnavailable' | 'research.sourcesEmpty' | 'research.sources' | 'research.sourceCheck' | 'research.source.cited' | 'research.source.uncited' | 'research.exportMarkdown' | 'research.referenceOnly' | 'research.prompt' | 'research.taskId' | 'research.episodeId' | 'research.model' | 'research.searchProvider' | 'research.createdAt' | 'research.completedAt' | 'research.latency' | 'research.wordCount' | 'research.tokens' | 'research.cost' | 'research.sourcesStatus' | 'research.metrics' | 'search.placeholder' | 'search.hint' | 'search.empty' | 'search.indexed' | 'search.timeout' | 'search.scope.all' | 'search.scope.outline' | 'search.scope.core' | 'search.scope.characters' | 'search.scope.settings' | 'search.scope.continuity' | 'search.scope.chapters' | 'search.scope.sources' | 'assets.references' | 'reference.intent.reference' | 'reference.intent.continuation' | 'reference.intent.canon' | 'reference.intent.migration' | 'reference.structure.awaiting_confirmation' | 'reference.structure.confirmed' | 'reference.analysis.complete' | 'reference.analysis.pending' | 'reference.chars' | 'reference.content.loading' | 'reference.content.full' | 'review.running' | 'review.passed' | 'review.failed' | 'review.score' | 'review.issues' | 'review.suggestion' | 'review.quote' | 'review.dimension' | 'review.coverage' | 'review.gate' | 'review.delivery' | 'review.execution' | 'review.priority' | 'review.severity.critical' | 'review.severity.warning' | 'review.severity.info' | 'review.severity.blocker' | 'review.severity.high' | 'review.severity.medium' | 'review.severity.low' | 'review.priority.blocker' | 'review.priority.high' | 'review.priority.medium' | 'review.priority.low' | 'review.status.pass' | 'review.status.blocked' | 'review.status.inconclusive' | 'review.status.revise' | 'review.status.completed' | 'review.status.partial' | 'review.status.failed' | 'review.status.stale' | 'review.status.unknown' | 'review.rawTitle';
5
+ export type StudioPanelKey = 'serial.used' | 'serial.recoverTransaction' | 'serial.title' | 'serial.hint' | 'serial.saved' | 'serial.audit' | 'serial.scope' | 'serial.all' | 'serial.words' | 'serial.payoffs' | 'serial.overdue' | 'serial.promiseHint' | 'serial.chapter' | 'serial.promise' | 'serial.budget' | 'serial.function' | 'serial.payoffIds' | 'serial.actual' | 'serial.saveOutline' | 'serial.streak' | 'serial.metrics' | 'serial.hanzi' | 'serial.paragraphs' | 'serial.sentences' | 'serial.paragraphLengths' | 'serial.nounDensity' | 'serial.dialogue' | 'serial.duplicate' | 'serial.assets' | 'serial.assetsHint' | 'serial.term' | 'serial.forbidden' | 'serial.minimum' | 'serial.example' | 'serial.replacement' | 'serial.remove' | 'serial.addTerm' | 'serial.reviewTerms' | 'serial.nouns' | 'serial.threshold' | 'serial.groups' | 'serial.groupsHint' | 'serial.character' | 'serial.detail' | 'serial.addGroup' | 'serial.saveAssets' | 'serial.anchors' | 'serial.anchorHint' | 'serial.drift' | 'serial.driftHint' | 'serial.frozen' | 'serial.unfrozen' | 'serial.kind' | 'serial.impact' | 'serial.note' | 'serial.addDrift' | 'serial.growth' | 'serial.escape' | 'serial.dilution' | 'serial.snowball' | 'serial.local' | 'serial.section' | 'serial.arc' | 'serial.decision' | 'serial.absorb' | 'serial.recover' | 'serial.freeze' | 'serial.target' | 'serial.reconcile' | 'serial.historical' | 'serial.discard' | 'serial.activity' | 'serial.heartbeat' | 'serial.modelElapsed' | 'tools.export.purpose.personal_archive' | 'view.overview' | 'view.writing' | 'view.studio' | 'view.reviewWs' | 'view.outline' | 'view.assets' | 'view.tasks' | 'view.benchmark' | 'view.models' | 'view.graph' | 'view.research' | 'view.search' | 'view.creation' | 'view.library' | 'view.operations' | 'creation.chapters' | 'creation.searchChapters' | 'creation.clearSearch' | 'creation.chaptersEmpty' | 'creation.previousChapter' | 'creation.nextChapter' | 'creation.jumpChapter' | 'creation.chapterDuplicate' | 'creation.order.loading' | 'creation.order.unavailable' | 'creation.order.refresh' | 'creation.order.invalid' | 'creation.order.missingCount' | 'creation.order.move' | 'creation.order.volume' | 'creation.order.position' | 'creation.order.positionHelp' | 'creation.order.applyMove' | 'creation.order.blocked' | 'creation.order.moveComplete' | 'creation.order.conflict' | 'creation.mode.edit' | 'creation.mode.reader' | 'creation.writing.bookProgress' | 'creation.writing.chapterTarget' | 'creation.writing.chapterProgress' | 'creation.reader.title' | 'creation.reader.readOnly' | 'creation.reader.loading' | 'creation.reader.refresh' | 'creation.reader.openEditor' | 'creation.reader.path' | 'creation.reader.documentId' | 'creation.reader.revision' | 'creation.reader.revisionUnavailable' | 'creation.showChapters' | 'creation.hideChapters' | 'creation.inspector' | 'creation.showInspector' | 'creation.hideInspector' | 'creation.editorLoading' | 'creation.documentLoading' | 'creation.inspectorLoading' | 'creation.inspectorLoadingSlow' | 'creation.empty' | 'creation.acceptance.title' | 'creation.acceptance.loading' | 'creation.acceptance.current' | 'creation.acceptance.pending' | 'creation.acceptance.drift' | 'creation.acceptance.baselinePending' | 'creation.acceptance.needsReview' | 'creation.acceptance.failed' | 'creation.acceptance.unknown' | 'creation.acceptance.unavailable' | 'creation.acceptance.currentRevision' | 'creation.acceptance.acceptedRevision' | 'creation.acceptance.operation' | 'creation.acceptance.stale' | 'creation.acceptance.refresh' | 'creation.acceptance.baseline' | 'creation.acceptance.external' | 'creation.acceptance.resume' | 'creation.acceptance.acknowledge' | 'creation.acceptance.confirmBaseline' | 'creation.acceptance.confirmExternal' | 'creation.acceptance.confirmAcknowledge' | 'creation.context' | 'creation.review' | 'creation.revisions' | 'creation.activity' | 'creation.activity.loading' | 'creation.activity.unavailable' | 'creation.activity.invalid' | 'creation.activity.target' | 'creation.activity.remaining' | 'creation.activity.sprint' | 'creation.activity.sprintAdded' | 'creation.activity.sprintDeleted' | 'creation.activity.sprintNet' | 'creation.activity.sprintRevision' | 'creation.activity.sprintSaved' | 'creation.activity.identity' | 'creation.activity.recent' | 'creation.activity.empty' | 'creation.foreshadow.title' | 'creation.foreshadow.empty' | 'creation.foreshadow.due' | 'creation.foreshadow.overdue' | 'creation.foreshadow.toPlant' | 'creation.foreshadow.open' | 'creation.foreshadow.close' | 'creation.foreshadow.plant' | 'creation.foreshadow.reveal' | 'creation.foreshadow.status' | 'creation.foreshadow.weight' | 'creation.foreshadow.layer' | 'creation.foreshadow.source' | 'creation.contextEmpty' | 'creation.context.packet' | 'creation.context.current' | 'creation.context.stale' | 'creation.context.previousStale' | 'creation.context.requestBudget' | 'creation.context.sessionBudget' | 'creation.context.outputReserve' | 'creation.context.actualUsage' | 'creation.context.reported' | 'creation.context.unavailable' | 'creation.context.sessionSeparate' | 'creation.context.retrieval' | 'creation.context.sources' | 'creation.context.protected' | 'creation.context.noSnippet' | 'creation.context.reason' | 'creation.context.missing' | 'creation.context.excluded' | 'creation.context.fullText' | 'creation.reviewEmpty' | 'creation.review.stale' | 'creation.review.casUnavailable' | 'creation.review.refreshRequired' | 'creation.review.closure' | 'creation.review.closureProposal' | 'creation.review.closureRevision' | 'creation.review.outcome.resolved' | 'creation.review.outcome.retained' | 'creation.review.outcome.regressed' | 'creation.review.selectionSummary' | 'creation.review.instruction' | 'creation.review.createRevision' | 'creation.review.rereview' | 'creation.review.revisionStarted' | 'creation.review.rereviewStarted' | 'creation.revisionsEmpty' | 'creation.history.title' | 'creation.history.snapshot' | 'creation.history.snapshotName' | 'creation.history.snapshotCreated' | 'creation.history.empty' | 'creation.history.units' | 'creation.history.loading' | 'creation.history.compare' | 'creation.history.restorePreview' | 'creation.history.closePreview' | 'creation.history.noChanges' | 'creation.history.restore' | 'creation.history.restoreConfirm' | 'creation.history.restored' | 'creation.history.previewFailed' | 'creation.history.reason.autosave' | 'creation.history.reason.manual' | 'creation.history.reason.aiRevision' | 'creation.history.reason.fullRewrite' | 'creation.history.reason.restore' | 'creation.proposals.title' | 'creation.proposals.noRationale' | 'creation.proposals.range' | 'creation.proposals.evidence' | 'creation.proposals.reviewRevision' | 'creation.proposals.sourceRevision' | 'creation.proposals.noHunks' | 'creation.proposals.originalCandidate' | 'creation.proposals.reject' | 'creation.proposals.regenerate' | 'creation.proposals.applySelected' | 'creation.proposals.appliedNeedsReview' | 'creation.proposals.sourceConflict' | 'creation.selection.title' | 'creation.selection.expand' | 'creation.selection.compress' | 'creation.selection.naturalize' | 'creation.selection.reviewFix' | 'creation.selection.working' | 'creation.selection.staged' | 'creation.selection.empty' | 'creation.selection.saveRequired' | 'creation.selection.reviewRequired' | 'creation.selection.noIssues' | 'creation.selection.annotate' | 'creation.notes.title' | 'creation.notes.note' | 'creation.notes.color' | 'creation.notes.submit' | 'creation.notes.cancel' | 'creation.notes.working' | 'creation.notes.saved' | 'creation.notes.empty' | 'creation.notes.rangeLost' | 'creation.notes.saveRequired' | 'creation.notes.locate' | 'creation.notes.resolve' | 'creation.notes.resolved' | 'creation.notes.attached' | 'creation.notes.relocated' | 'creation.notes.detached' | 'creation.notes.quote' | 'creation.notes.color.amber' | 'creation.notes.color.rose' | 'creation.notes.color.sky' | 'creation.notes.color.lime' | 'creation.notes.color.violet' | 'creation.marker.insert' | 'creation.marker.title' | 'creation.marker.purpose' | 'creation.marker.state' | 'creation.marker.relation' | 'creation.marker.field' | 'creation.marker.oldState' | 'creation.marker.newState' | 'creation.marker.source' | 'creation.marker.target' | 'creation.marker.description' | 'creation.marker.pickCharacter' | 'creation.marker.insertNow' | 'creation.marker.cancel' | 'creation.marker.empty' | 'creation.marker.newline' | 'creation.marker.reserved' | 'creation.marker.needId' | 'creation.mentions.title' | 'creation.mentions.mention' | 'creation.mentions.card' | 'creation.mentions.aliases' | 'creation.mentions.close' | 'creation.mentions.ambiguous' | 'creation.mentions.choose' | 'creation.mentions.conflict' | 'creation.mentions.noSummary' | 'creation.issues' | 'creation.changedElsewhere' | 'creation.conflict' | 'creation.reload' | 'creation.overwrite' | 'creation.discardConfirm' | 'creation.overwriteConfirm' | 'creation.closePanel' | 'creation.draft.available' | 'creation.draft.conflict' | 'creation.draft.updated' | 'creation.draft.preview' | 'creation.draft.restore' | 'creation.draft.dismiss' | 'creation.draft.unavailable' | 'creation.status.idle' | 'creation.status.loading' | 'creation.status.saved' | 'creation.status.dirty' | 'creation.status.saving' | 'creation.status.conflict' | 'creation.status.offline' | 'operations.transfer' | 'operations.transferHint' | 'operations.project' | 'operations.create.new' | 'operations.create.id' | 'operations.create.title' | 'operations.create.submit' | 'operations.create.done' | 'operations.create.failed' | 'operations.create.pickHint' | 'operations.init.hint' | 'operations.init.submit' | 'operations.cancel' | 'workspace.unbound' | 'workspace.notInitialized' | 'workspace.bind.hint' | 'workspace.bind.pick' | 'workspace.bind.failed' | 'operations.create.titleHint' | 'tool.family.status' | 'tool.family.context' | 'tool.family.manuscript' | 'tool.family.revision' | 'tool.family.task' | 'tool.family.search' | 'tool.family.asset' | 'tool.family.outline' | 'tool.running' | 'tool.failed' | 'tool.succeeded' | 'tool.openChapter' | 'turn.changed' | 'turn.partial' | 'turn.failed' | 'turn.refreshFailed' | 'turn.history' | 'turn.proposed' | 'turn.rejected' | 'turn.entityChanges' | 'turn.before' | 'turn.after' | 'turn.missing' | 'turn.truncated' | 'turn.sourceRevision' | 'turn.resultRevision' | 'turn.committed' | 'turn.trace' | 'turn.modelCalls' | 'turn.days' | 'turn.accept' | 'turn.reject' | 'turn.retry' | 'turn.undo' | 'turn.applied' | 'turn.retried' | 'turn.undone' | 'resolving' | 'loading' | 'unreachable' | 'retry' | 'refresh' | 'openExternal' | 'outline.empty' | 'outline.drafted' | 'outline.planned' | 'outline.draftedCount' | 'outline.addChild' | 'outline.addAfter' | 'outline.addVolume' | 'outline.expandAll' | 'outline.collapseAll' | 'outline.del' | 'outline.confirmDelete' | 'outline.newTitlePlaceholder' | 'outline.opConflict' | 'outline.opFailed' | 'outline.summaryEmpty' | 'tools.title' | 'tools.export' | 'tools.export.done' | 'tools.export.failed' | 'tools.export.purpose' | 'tools.export.purpose.backup' | 'tools.export.purpose.delivery' | 'tools.export.format' | 'tools.export.preflight' | 'tools.export.loading' | 'tools.export.unavailable' | 'tools.export.refresh' | 'tools.export.revision' | 'tools.export.ready' | 'tools.export.blocked' | 'tools.export.download' | 'tools.export.order' | 'tools.export.orderEmpty' | 'tools.export.units' | 'tools.export.structure' | 'tools.export.structure.duplicates' | 'tools.export.structure.missing' | 'tools.export.structure.empty' | 'tools.export.structure.unreadable' | 'tools.export.clear' | 'tools.export.writingUnits' | 'tools.export.total' | 'tools.export.bookTarget' | 'tools.export.chapterTarget' | 'tools.export.completion' | 'tools.metadata.edit' | 'tools.metadata.save' | 'tools.metadata.cancel' | 'tools.metadata.hint' | 'tools.export.metadata' | 'tools.export.metadata.title' | 'tools.export.metadata.author' | 'tools.export.metadata.language' | 'tools.export.reviews' | 'tools.export.reviews.missing' | 'tools.export.reviews.current' | 'tools.export.reviews.stale' | 'tools.export.reviews.approved' | 'tools.export.reviews.notApproved' | 'tools.export.acceptance' | 'tools.export.acceptance.blocking' | 'tools.export.acceptance.blockingState' | 'tools.export.acceptance.needsReview' | 'tools.export.status' | 'tools.export.blockers' | 'tools.export.warnings' | 'tools.export.none' | 'tools.export.stale' | 'tools.sync' | 'tools.sync.done' | 'tools.sync.failed' | 'tools.import' | 'tools.import.empty' | 'tools.import.failed' | 'tools.import.done' | 'tools.import.choose' | 'tools.import.noFile' | 'tools.import.start' | 'tools.import.startAuto' | 'tools.import.preview' | 'tools.import.plan' | 'tools.import.conflicts' | 'tools.import.force' | 'tools.import.confirm' | 'tools.import.workspace.title' | 'tools.import.workspace.ownHint' | 'tools.import.workspace.operations' | 'tools.import.workspace.empty' | 'tools.import.workspace.new' | 'tools.import.workspace.file' | 'tools.import.workspace.arc' | 'tools.import.workspace.prepare' | 'tools.import.workspace.prepared' | 'tools.import.workspace.select' | 'tools.import.workspace.chapters' | 'tools.import.workspace.structure' | 'tools.import.workspace.chapterId' | 'tools.import.workspace.chapterTitle' | 'tools.import.workspace.chapterContent' | 'tools.import.workspace.moveUp' | 'tools.import.workspace.moveDown' | 'tools.import.workspace.remove' | 'tools.import.workspace.addChapter' | 'tools.import.workspace.newChapter' | 'tools.import.workspace.saveStructure' | 'tools.import.workspace.structureSaved' | 'tools.import.workspace.confirmStructure' | 'tools.import.workspace.confirmPrompt' | 'tools.import.workspace.confirmed' | 'tools.import.workspace.run' | 'tools.import.workspace.resume' | 'tools.import.workspace.taskStarted' | 'tools.import.workspace.discard' | 'tools.import.workspace.discardPrompt' | 'tools.import.workspace.discarded' | 'tools.import.workspace.recoverable' | 'tools.import.workspace.notRecoverable' | 'tools.import.stage.snapshot' | 'tools.import.stage.split' | 'tools.import.stage.structure_confirmed' | 'tools.import.stage.published' | 'tools.import.stage.acceptance' | 'tools.import.stage.reconcile' | 'tools.import.stage.synthesis' | 'tools.import.stage.complete' | 'tools.archive.title' | 'tools.archive.hint' | 'tools.archive.failed' | 'tools.archive.preflight' | 'tools.archive.create' | 'tools.archive.created' | 'tools.archive.list' | 'tools.archive.empty' | 'tools.archive.download' | 'tools.archive.downloaded' | 'tools.archive.files' | 'tools.archive.size' | 'tools.archive.categories' | 'tools.archive.includes' | 'tools.archive.excludes' | 'tools.archive.missing' | 'tools.archive.references' | 'tools.archive.referencePlan' | 'tools.archive.restore' | 'tools.archive.targetRoot' | 'tools.archive.pickTarget' | 'tools.archive.targetNovelId' | 'tools.archive.referencePolicy' | 'tools.archive.preserveRelative' | 'tools.archive.rewriteNovelId' | 'tools.archive.previewRestore' | 'tools.archive.restoreReady' | 'tools.archive.restoreBlocked' | 'tools.archive.conflicts' | 'tools.archive.pathRewrites' | 'tools.archive.rewrittenFiles' | 'tools.archive.rewrittenReferences' | 'tools.archive.preservedReferences' | 'tools.archive.referenceWarnings' | 'tools.archive.referenceConflicts' | 'tools.archive.tasksArchived' | 'tools.archive.autoResume' | 'tools.archive.noAutoResume' | 'tools.archive.confirmRestore' | 'tools.archive.restoreConfirm' | 'tools.archive.restoreStarted' | 'tasks.cancel' | 'tasks.cancel.title' | 'tasks.cancel.confirm' | 'tasks.cancel.done' | 'tasks.cancel.failed' | 'tasks.retry' | 'tasks.retry.title' | 'tasks.retry.notRecoverable' | 'tasks.retry.done' | 'tasks.retry.failed' | 'tasks.summary.total' | 'tasks.summary.updated' | 'tasks.filter.type' | 'tasks.filter.typeAll' | 'tasks.filter.chapter' | 'tasks.filter.keyword' | 'tasks.sort.newest' | 'tasks.sort.oldest' | 'tasks.sort.toggle' | 'tasks.progress.unknown' | 'tasks.phase.unknown' | 'tasks.confirm' | 'tasks.confirm.title' | 'tasks.confirm.done' | 'tasks.confirm.failed' | 'tasks.cancel.armYes' | 'tasks.cancel.armNo' | 'tasks.list' | 'tasks.detail.open' | 'tasks.detail.close' | 'tasks.detail.copyId' | 'tasks.detail.copied' | 'tasks.detail.events' | 'tasks.detail.eventsLoading' | 'tasks.detail.eventsEmpty' | 'tasks.detail.eventsFailed' | 'tasks.field.id' | 'tasks.field.type' | 'tasks.field.status' | 'tasks.field.phase' | 'tasks.field.chapter' | 'tasks.field.progress' | 'tasks.field.attempt' | 'tasks.field.created' | 'tasks.field.started' | 'tasks.field.updated' | 'tasks.field.completed' | 'tasks.field.summary' | 'tasks.field.resultRef' | 'tasks.field.failedStage' | 'tasks.field.errorCode' | 'tasks.field.recoverable' | 'tasks.field.yes' | 'tasks.field.no' | 'tasks.failure.cancelled' | 'tasks.failure.recoverable' | 'tasks.failure.provider' | 'tasks.failure.input' | 'tasks.failure.system' | 'tasks.jump.benchmark' | 'tasks.jump.research' | 'tasks.jump.chapter' | 'tasks.jump.review' | 'tasks.jump.unavailable' | 'tasks.jump.chapterHint' | 'tasks.jump.reviewHint' | 'tasks.jump.chapterMissing' | 'research.launch' | 'research.launch.placeholder' | 'research.launch.submit' | 'research.launch.submitting' | 'research.launch.submitted' | 'research.launch.failed' | 'research.launch.hint' | 'tasks.result.toggle' | 'tasks.result.score' | 'tasks.result.issues' | 'search.preview.back' | 'search.preview.openCreation' | 'search.preview.jumpReady' | 'search.preview.identityMismatch' | 'search.preview.locatorCurrent' | 'search.preview.locatorStale' | 'search.preview.locatorUnverified' | 'search.preview.revisionUnavailable' | 'search.change.title' | 'search.change.serverOwned' | 'search.change.unavailable' | 'search.change.currentLine' | 'search.change.replacement' | 'search.change.preview' | 'search.change.previewing' | 'search.change.sourceRevision' | 'search.change.resultRevision' | 'search.change.reject' | 'search.change.confirmApply' | 'search.change.applying' | 'search.change.refreshRequired' | 'search.change.invalidApply' | 'search.change.invalidReject' | 'search.change.applied' | 'search.change.rejected' | 'search.change.refresh' | 'assets.empty' | 'assets.other' | 'assets.stages' | 'assets.aliases' | 'assets.segment.characters' | 'assets.segment.world' | 'assets.segment.progression' | 'assets.segment.references' | 'assets.segment.core' | 'assets.segment.empty' | 'assets.references.empty' | 'assets.core.empty' | 'assets.detail.loading' | 'assets.draft.restored' | 'assets.draft.unsaved' | 'assets.draft.conflict' | 'assets.detail.relations' | 'assets.detail.index' | 'assets.list.detail_refs' | 'assets.list.taboos' | 'assets.edit.linesHint' | 'assets.relation.confirmed' | 'assets.relation.registered' | 'assets.relation.incoming' | 'assets.searchPlaceholder' | 'assets.edit.open' | 'assets.edit.name' | 'assets.edit.summary' | 'assets.edit.tags' | 'assets.edit.listHint' | 'assets.edit.save' | 'assets.edit.saving' | 'assets.edit.cancel' | 'assets.edit.conflict' | 'assets.edit.conflictRefresh' | 'assets.edit.addRelation' | 'assets.edit.removeRelation' | 'assets.edit.relationTarget' | 'assets.edit.relationNote' | 'assets.edit.derivedRelations' | 'assets.edit.body' | 'assets.edit.liveLoading' | 'assets.edit.optional' | 'assets.field.tier' | 'assets.field.personality' | 'assets.field.goal' | 'assets.field.fear' | 'assets.field.appearance' | 'assets.field.voice' | 'assets.field.current_state' | 'assets.field.organization' | 'assets.field.progression_system' | 'assets.field.progression_stage' | 'assets.field.status' | 'assets.field.kind' | 'assets.field.type' | 'assets.field.subtype' | 'assets.field.state_updated_at' | 'assets.field.role' | 'assets.edit.liveFailed' | 'assets.selectHint' | 'assets.create.open' | 'assets.create.submit' | 'assets.create.idHint' | 'assets.create.tier' | 'assets.create.type' | 'assets.create.progressionKind' | 'assets.create.stages' | 'assets.create.stageId' | 'assets.create.stageName' | 'assets.create.addStage' | 'tasks.empty' | 'tasks.filter.all' | 'tasks.attempt' | 'tasks.status.pending' | 'tasks.status.running' | 'tasks.status.awaiting_confirmation' | 'tasks.status.completed' | 'tasks.status.failed' | 'tasks.status.cancelled' | 'tasks.status.interrupted' | 'tasks.phase.queued' | 'tasks.phase.reading' | 'tasks.phase.preparing' | 'tasks.phase.model' | 'tasks.phase.validating' | 'tasks.phase.committing' | 'tasks.phase.complete' | 'tasks.type.chapter_write' | 'tasks.type.chapter_review' | 'tasks.type.continuous_write' | 'tasks.type.revision' | 'tasks.type.source_operation' | 'tasks.type.reference_operation' | 'tasks.type.manuscript_import' | 'tasks.type.project_restore' | 'tasks.type.research' | 'tasks.type.model_benchmark' | 'graph.foreshadowing' | 'graph.relationships' | 'graph.nodes' | 'graph.connections' | 'graph.relayout' | 'graph.weight' | 'graph.target' | 'graph.truncated' | 'graph.validation.errors' | 'graph.empty.foreshadowing' | 'graph.empty.relationships' | 'graph.entityType' | 'graph.entityStatus' | 'graph.search' | 'graph.connectedOnly' | 'graph.neighbors' | 'graph.edgeType' | 'graph.origin' | 'graph.source' | 'graph.confirmed' | 'dag.quality' | 'dag.coverage' | 'dag.gate' | 'dag.delivery' | 'dag.current' | 'dag.stale' | 'dag.toRevision' | 'dag.toRevisionDone' | 'dag.toRevisionFailed' | 'graph.unresolved' | 'graph.kind.character' | 'graph.kind.faction' | 'graph.kind.place' | 'graph.kind.concept' | 'graph.kind.other' | 'graph.truth' | 'graph.truth.currentState' | 'graph.truth.ledger' | 'graph.truth.relationships' | 'graph.workflows' | 'graph.workflow.currentStage' | 'graph.empty.truth' | 'graph.empty.truthDoc' | 'graph.empty.workflows' | 'graph.reviewDag' | 'graph.reviewFramework' | 'graph.reviewDomains' | 'graph.reviewChecks' | 'graph.reviewCriteria' | 'graph.deliveryDag' | 'graph.filter.all' | 'graph.filter.anomaly' | 'graph.filter.blocker' | 'graph.expandChecks' | 'graph.collapseChecks' | 'graph.empty.dag' | 'benchmark.title' | 'benchmark.taskType' | 'benchmark.executionEvidence' | 'benchmark.evidence' | 'benchmark.status.skipped' | 'benchmark.status.stale' | 'benchmark.task.chapter' | 'benchmark.task.outline' | 'benchmark.task.chapterHint' | 'benchmark.task.outlineHint' | 'benchmark.planner' | 'benchmark.nextChapter' | 'benchmark.chapterWritten' | 'benchmark.chapterPlanned' | 'benchmark.chapterUnavailable' | 'benchmark.customChapter' | 'benchmark.chapterId' | 'benchmark.outlineOrigin' | 'benchmark.continueOutline' | 'benchmark.customOutlineStart' | 'benchmark.outlineStart' | 'benchmark.outlineCount' | 'benchmark.rangeFrom' | 'benchmark.rangeTo' | 'benchmark.chapterUnit' | 'benchmark.invalidRange' | 'benchmark.outlineRangeHint' | 'benchmark.earliestOutlineStart' | 'benchmark.invalidChapter' | 'benchmark.historicalChapterHint' | 'benchmark.autoDag' | 'benchmark.executedDag' | 'benchmark.dagAutomatic' | 'benchmark.afterStage' | 'benchmark.reviewScope' | 'benchmark.isolatedHint' | 'benchmark.pipelineUnavailable' | 'benchmark.actualChapters' | 'benchmark.pipelineFinished' | 'benchmark.pipelineStatus' | 'benchmark.reviewIncomplete' | 'benchmark.partialScore' | 'benchmark.reviewIncompleteHint' | 'benchmark.completeReviews' | 'benchmark.reportedCoverage' | 'benchmark.coveragePending' | 'benchmark.factsPendingTitle' | 'benchmark.factsPendingHint' | 'benchmark.selectModels' | 'benchmark.description' | 'benchmark.configure' | 'benchmark.modelHint' | 'benchmark.advanced' | 'benchmark.history' | 'benchmark.results' | 'benchmark.noProfiles' | 'benchmark.chooseModels' | 'benchmark.workload' | 'benchmark.submitting' | 'benchmark.noCandidates' | 'benchmark.noEvaluations' | 'benchmark.plannedCandidates' | 'benchmark.plannedEvaluations' | 'benchmark.task' | 'benchmark.mode' | 'benchmark.mode.framework' | 'benchmark.mode.creative' | 'benchmark.mode.unknown' | 'benchmark.reviewer' | 'benchmark.chapter' | 'benchmark.repeats' | 'benchmark.words' | 'benchmark.concurrency' | 'benchmark.run' | 'benchmark.empty' | 'benchmark.select' | 'benchmark.averageScore' | 'benchmark.output' | 'benchmark.candidate' | 'benchmark.candidates' | 'benchmark.evaluations' | 'benchmark.writer' | 'benchmark.path' | 'benchmark.status' | 'benchmark.actualWords' | 'benchmark.finishReason' | 'benchmark.error' | 'benchmark.coverage' | 'benchmark.gate' | 'benchmark.delivery' | 'benchmark.productionGate' | 'benchmark.productionGateMissing' | 'benchmark.domains' | 'benchmark.latency' | 'benchmark.usage' | 'benchmark.cost' | 'benchmark.inputTokens' | 'benchmark.outputTokens' | 'benchmark.reasoningTokens' | 'benchmark.totalTokens' | 'benchmark.actualCost' | 'benchmark.costCoverage' | 'benchmark.effectiveRate' | 'benchmark.runs' | 'benchmark.sameInputGroup' | 'benchmark.comparisonIncomplete' | 'benchmark.inputProvenance' | 'benchmark.runPhases' | 'benchmark.phase.created' | 'benchmark.phase.started' | 'benchmark.phase.completed' | 'benchmark.contextHash' | 'benchmark.comparisonKey' | 'benchmark.promptVersion' | 'benchmark.rubricVersion' | 'benchmark.blindReview' | 'benchmark.contextStrategy' | 'benchmark.manifestVersion' | 'benchmark.tokenEstimator' | 'benchmark.packetRevision' | 'benchmark.sourceRevision' | 'benchmark.estimatedTokens' | 'benchmark.characters' | 'benchmark.contextSources' | 'benchmark.sourcePresent' | 'benchmark.sourceMissing' | 'benchmark.responseIdentity' | 'models.title' | 'models.list' | 'models.editor' | 'models.new' | 'models.empty' | 'models.id' | 'models.label' | 'models.provider' | 'models.protocol.openai' | 'models.protocol.anthropic' | 'models.modelId' | 'models.baseUrl' | 'models.apiFormat' | 'models.context' | 'models.output' | 'models.credential' | 'models.embeddingProvider' | 'models.embeddingProviderOpenai' | 'models.embeddingProviderLocal' | 'models.embeddingProviderUnknown' | 'models.embeddingProviderOpenaiHint' | 'models.embeddingProviderLocalHint' | 'models.embeddingLocalPreset' | 'models.vectorDimensionsLocalHint' | 'models.embeddingModel' | 'models.embeddingCredential' | 'models.credentialHint' | 'models.remember' | 'models.save' | 'models.chatTest' | 'models.embeddingTest' | 'models.vectorParameters' | 'models.vectorDimension' | 'models.vectorMaxTokens' | 'models.vectorCount' | 'models.vectorDimensionsHint' | 'models.test.invalidResponseHint' | 'models.test.unsupportedHint' | 'models.delete' | 'models.delete.confirm' | 'models.delete.blocked' | 'models.delete.wouldFail' | 'models.test.untested' | 'models.test.ok' | 'models.test.failed' | 'models.dependencies' | 'models.dependenciesHint' | 'models.fallback' | 'models.chooseFallback' | 'models.routes' | 'models.routesSave' | 'models.saved' | 'models.deleted' | 'models.chatOk' | 'models.embeddingOk' | 'models.configured' | 'models.missing' | 'models.routesSaved' | 'models.group.basic' | 'models.group.connection' | 'models.group.generation' | 'models.group.embedding' | 'models.group.credentials' | 'models.group.routeUsage' | 'models.temperature' | 'models.timeout' | 'models.embeddingBaseUrl' | 'models.validation.required' | 'models.validation.positive' | 'models.validation.temperature' | 'models.validation.embeddingProvider' | 'models.unsavedChanges' | 'models.unsavedDiscard' | 'models.unsavedKeep' | 'models.test.loading' | 'models.usedByRoutes' | 'models.noRoutes' | 'models.delete.resultingRoutes' | 'models.embeddingEmpty' | 'models.embeddingConfigured' | 'models.embeddingMissing' | 'models.active' | 'models.inactive' | 'models.route.goethe' | 'models.route.dante' | 'models.route.chapter_write' | 'models.route.review' | 'models.route.source_extract' | 'models.route.revision' | 'models.route.search' | 'models.route.research' | 'models.routesImpact' | 'models.routesUnchanged' | 'models.routesUnassigned' | 'models.embedConfigured' | 'models.embedMissing' | 'models.capability.chat' | 'models.capability.embedding' | 'research.reports' | 'research.unavailable' | 'research.empty' | 'research.selectHint' | 'research.report.loading' | 'research.quality' | 'research.language' | 'research.filter.keyword' | 'research.filter.status' | 'research.filter.sources' | 'research.filter.all' | 'research.status.succeeded' | 'research.status.failed' | 'research.status.needsReview' | 'research.status.unknown' | 'research.sourcesAvailable' | 'research.sourcesUnavailable' | 'research.sourcesEmpty' | 'research.sources' | 'research.sourceCheck' | 'research.source.cited' | 'research.source.uncited' | 'research.exportMarkdown' | 'research.referenceOnly' | 'research.prompt' | 'research.taskId' | 'research.episodeId' | 'research.model' | 'research.searchProvider' | 'research.createdAt' | 'research.completedAt' | 'research.latency' | 'research.wordCount' | 'research.tokens' | 'research.cost' | 'research.sourcesStatus' | 'research.metrics' | 'search.placeholder' | 'search.hint' | 'search.empty' | 'search.indexed' | 'search.timeout' | 'search.scope.all' | 'search.scope.outline' | 'search.scope.core' | 'search.scope.characters' | 'search.scope.settings' | 'search.scope.continuity' | 'search.scope.chapters' | 'search.scope.sources' | 'assets.references' | 'reference.intent.reference' | 'reference.intent.continuation' | 'reference.intent.canon' | 'reference.intent.migration' | 'reference.structure.awaiting_confirmation' | 'reference.structure.confirmed' | 'reference.analysis.complete' | 'reference.analysis.pending' | 'reference.chars' | 'reference.content.loading' | 'reference.content.full' | 'review.running' | 'review.passed' | 'review.failed' | 'review.score' | 'review.issues' | 'review.suggestion' | 'review.quote' | 'review.dimension' | 'review.coverage' | 'review.gate' | 'review.delivery' | 'review.execution' | 'review.priority' | 'review.severity.critical' | 'review.severity.warning' | 'review.severity.info' | 'review.severity.blocker' | 'review.severity.high' | 'review.severity.medium' | 'review.severity.low' | 'review.priority.blocker' | 'review.priority.high' | 'review.priority.medium' | 'review.priority.low' | 'review.status.pass' | 'review.status.blocked' | 'review.status.inconclusive' | 'review.status.revise' | 'review.status.completed' | 'review.status.partial' | 'review.status.failed' | 'review.status.stale' | 'review.status.unknown' | 'review.rawTitle';
6
6
  declare module '@deepseek-ai/dsh-client-ui-slots' {
7
7
  interface LocaleNamespaceMap {
8
8
  /** The 稿件/大纲/资产 view tab labels and panel state strings. */
@@ -35,12 +35,13 @@
35
35
  "platform": "web"
36
36
  },
37
37
  "compatibility": {
38
- "dsh": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.2.0-rc.2 || 0.2.1-rc.2",
38
+ "dsh": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3",
39
39
  "dshReleases": {
40
40
  "0.1.2-rc.1": "compatible",
41
41
  "0.1.5-alpha.1": "compatible",
42
42
  "0.2.0-rc.2": "compatible",
43
- "0.2.1-rc.2": "compatible"
43
+ "0.2.1-rc.2": "compatible",
44
+ "0.2.1-rc.3": "compatible"
44
45
  }
45
46
  }
46
47
  },
@@ -70,7 +71,7 @@
70
71
  },
71
72
  "peerDependencies": {
72
73
  "@deepseek-ai/cordis": "4.0.2 || ~4.0.4",
73
- "@deepseek-ai/dsh-host-webserver": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.2.0-rc.2 || 0.2.1-rc.2",
74
+ "@deepseek-ai/dsh-host-webserver": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3",
74
75
  "react": "^18.2.0",
75
76
  "react-dom": "^18.2.0"
76
77
  },
package/plugin.mjs CHANGED
@@ -4,7 +4,7 @@ import { lock } from 'proper-lockfile'
4
4
  import { resolveDshHome } from '@deepseek-ai/dsh-home-paths'
5
5
  import { join } from 'node:path'
6
6
  import { fileURLToPath } from 'node:url'
7
- import { presetDefinition } from './preset-definition.mjs'
7
+ import { legacyPresetIds, presetDefinition } from './preset-definition.mjs'
8
8
 
9
9
  export const name = 'dsh-openwrite'
10
10
 
@@ -23,7 +23,7 @@ async function digestTree(dir) {
23
23
  return hash.digest('hex')
24
24
  }
25
25
 
26
- /** A versioned preset leaves existing authored copies and session identities alone. */
26
+ /** Keep legacy filesystem presets and resolve durable session identities on upgrade. */
27
27
  export async function apply(ctx) {
28
28
  const home = resolveDshHome()
29
29
  const source = fileURLToPath(new URL('./presets/openwrite/', import.meta.url))
@@ -60,8 +60,8 @@ export async function apply(ctx) {
60
60
  }
61
61
  await writeFile(lease, JSON.stringify({ pid: process.pid }), { mode: 0o600 })
62
62
  })
63
- // Preset files are package-managed UI entries. Remove only our unmodified
64
- // copy after its last live host stops; authored copies and session logs remain.
63
+ // 0.1 resolves session identities through these directories. They must outlive
64
+ // a host and a plugin upgrade; removing them strands historical sessions.
65
65
  ctx.effect(() => async () => withLock(async () => {
66
66
  await rm(lease, { force: true })
67
67
  for (const entry of await readdir(leases)) {
@@ -72,16 +72,26 @@ export async function apply(ctx) {
72
72
  catch (error) { if (error.code === 'ESRCH') await rm(file, { force: true }) }
73
73
  } catch { /* unknown files never grant deletion authority */ }
74
74
  }
75
- if ((await readdir(leases)).length !== 0) return
76
- const owned = await readFile(marker, 'utf8').then(JSON.parse).catch(() => null)
77
- if (owned?.source === expected && owned.tree === await digestTree(destination).catch(() => null)) {
78
- await rm(destination, { recursive: true })
79
- }
80
75
  }))
81
76
  // 0.1 discovers the managed directory above; 0.2 only accepts registered
82
77
  // definitions. The declaring context owns registration and its resolution base.
83
78
  ctx.inject(['agentPresets'], async function* (presetCtx) {
84
79
  if (typeof presetCtx.agentPresets.register !== 'function') return
85
- yield await presetCtx.agentPresets.register(await presetDefinition(version, true))
80
+ const definition = await presetDefinition(version, true)
81
+ yield await presetCtx.agentPresets.register(definition)
82
+ const ids = new Set([...legacyPresetIds, id,
83
+ ...(await readdir(join(home, '.agent-presets'))).filter(name => /^openwrite-\d+-\d+-\d+(?:-[a-z0-9-]+)?$/.test(name)),
84
+ ])
85
+ for (const legacyId of ids) {
86
+ // An author-supplied definition wins; readDocument checks presence without
87
+ // waiting for host activation (list/resolve would deadlock startup).
88
+ if (typeof presetCtx.agentPresets.readDocument === 'function') {
89
+ try { await presetCtx.agentPresets.readDocument(legacyId); continue }
90
+ catch (error) { if (error?.code !== 'agent-preset/not-found') throw error }
91
+ }
92
+ yield await presetCtx.agentPresets.register({ ...definition, id: legacyId,
93
+ order: 1000, name: `${definition.name}(历史会话 ${legacyId})`,
94
+ })
95
+ }
86
96
  })
87
97
  }
@@ -9,6 +9,12 @@ const schema = JSON_SCHEMA.extend(new Type('tag:yaml.org,2002:js', {
9
9
  construct: value => ({ __jsExpr: value }),
10
10
  }))
11
11
 
12
+ export const stablePresetId = 'openwrite'
13
+
14
+ // These released identities are durable session references, even after their
15
+ // package-managed directories have been removed by older plugin versions.
16
+ export const legacyPresetIds = Array.from({ length: 25 }, (_, i) => `openwrite-0-2-${i + 1}`)
17
+
12
18
  export async function presetDefinition(version, modern = false) {
13
19
  const baseUrl = new URL('./presets/openwrite/', import.meta.url)
14
20
  const plugins = load(await readFile(new URL('agent.cordis.yml', baseUrl), 'utf8'), { schema })
@@ -27,5 +33,5 @@ export async function presetDefinition(version, modern = false) {
27
33
  }
28
34
  adapt(plugins)
29
35
  }
30
- return { ...metadata, id: `openwrite-${version.replace(/[^a-z0-9-]/g, '-')}`, plugins }
36
+ return { ...metadata, id: stablePresetId, order: -1, plugins }
31
37
  }
@@ -47,6 +47,17 @@
47
47
  用户说出这些说法或键入对应斜杠时,先加载同名技能再行动。宿主 /export 是会话日志,不是成稿导出。
48
48
  写法记忆随当前 Workspace 的 OpenWrite 资产走,不另建记忆库。
49
49
 
50
+ 连载工作流:用 novel_writing_assets(action="get") 读取项目术语、范本与角色属性组。
51
+ 长章由 Writer 按节拍分段续写,禁止为了补字数重写已完成正文。写后用
52
+ novel_manuscript_metrics 查看可数体检、重复和重合证据;术语示例只示范用法,范本只学句法。
53
+ 用 novel_outline_audit 读取章组字段、字数、功能与伏笔计数,不把声明的承诺当成已验证剧情。
54
+ 新章纲补 promise、payoff_of、word_budget、function;预算与 writing_targets/预估字数一致。
55
+ 发现偏离时用 novel_drift_entry 记账;节末由作者在 novel_arc_reconcile 中选择吸收、回收或冻结。
56
+ 吸收必须提供实际大纲更新和来源版本;回收必须指定后文章号与计划。超预算冻结后先裁决再写章。
57
+ 外部改写可用 no_model/fast 验收保留正文,但事实域仍是 stale,需完整对账后才可依赖派生事实。
58
+ 历史横评需显式 allow_historical=true;其标签是当前正典隔离改写,不等同可验证的章前因果基线。
59
+ 作者自留导出使用 purpose=personal_archive,质量问题保留在回执中,不能称作通过交付门禁。
60
+
50
61
  规划模式:当项目未初始化、作者意图/人物/设定/大纲存在缺口,或用户要求构思与规划时,
51
62
  先读取 novel_status、novel_outline_read、novel_search 和相关资产;直接生成草案,
52
63
  所有资产与大纲写入都遵循“预览 diff → 用户明确确认 → 应用”的门控。普通讨论不得写入。
@@ -3,7 +3,7 @@
3
3
  "dsh": "0.1.2-rc.1",
4
4
  "uv_version": "0.11.19",
5
5
  "python_version": "3.12.13",
6
- "core_version": "5.8.11",
6
+ "core_version": "5.8.14",
7
7
  "contract_version": 1,
8
8
  "platforms": {
9
9
  "darwin-arm64": {
@@ -56,8 +56,8 @@
56
56
  }
57
57
  },
58
58
  "wheel": {
59
- "file": "openwrite-5.8.11-py3-none-any.whl",
60
- "sha256": "7937914eee6b99cd64fee2ead96a5e6d63e807acae0a610c1c4abf863e814188"
59
+ "file": "openwrite-5.8.14-py3-none-any.whl",
60
+ "sha256": "b96637d9cad364d280122bae9dd59e42be811cd43389ddb704ff4dc110f0acc0"
61
61
  },
62
62
  "requirements": {
63
63
  "file": "requirements.lock",
@@ -66,8 +66,8 @@
66
66
  "sources": {
67
67
  "core": {
68
68
  "repository": "https://github.com/LiPu-jpg/Openwrite",
69
- "branch": "fix/issues-88-95",
70
- "commit": "596709e3f4bbe4eab7ce59513c9f36c4390ad367"
69
+ "branch": "native-core",
70
+ "commit": "3f18d81363909b09fead27339c4a45396cd6af94"
71
71
  },
72
72
  "dog": {
73
73
  "repository": "https://github.com/Fun10165/dsh-dog",
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "repository": "https://github.com/LiPu-jpg/Openwrite",
3
- "commit": "d16623c6b0d2a84d45dffe23c24e641df790175f",
4
- "tree": "e0b2fd0647114e46e6fd188f4fb32b13fadc6b3d",
3
+ "commit": "7522b6cb3b7f37ebaf267519c6051389413aa089",
4
+ "tree": "9e2a2d746f44af554af9192458eb9d8318a6049d",
5
5
  "dirty": false,
6
6
  "acquisition": "git-checkout",
7
- "sourceTreeSha256": "f56f55a7fc46c5cd506ccfbc410a8c494d6c69eb4b155381cc7aef8e4ff079cf",
7
+ "sourceTreeSha256": "5eb9837f32240234f2bb57f4dfc0c384ee63fad50bd074314ffe6f3e98eba72e",
8
8
  "components": [
9
9
  {
10
10
  "name": "@deepseek-ai/schemastery",
@@ -0,0 +1,211 @@
1
+ #!/usr/bin/env node
2
+ // Offline profile upgrades retain the previous complete dependency tree until commit.
3
+ import { cp, mkdir, readFile, readdir, rename, writeFile, open, access, readlink, symlink, unlink } from 'node:fs/promises'
4
+ import { spawn, spawnSync } from 'node:child_process'
5
+ import { join, resolve, relative, isAbsolute, dirname, sep } from 'node:path'
6
+ import { randomUUID, createHash } from 'node:crypto'
7
+ import { homedir } from 'node:os'
8
+ import { pathToFileURL } from 'node:url'
9
+ import { lock as acquireLock } from 'proper-lockfile'
10
+ import yaml from 'js-yaml'
11
+
12
+ const PROFILE = /^[a-zA-Z0-9_-]+$/
13
+ const digest = bytes => createHash('sha256').update(bytes).digest('hex')
14
+ async function exists(path) { try { await access(path); return true } catch (error) { if (error.code === 'ENOENT') return false; throw error } }
15
+ async function save(path, value) {
16
+ const pending = path + '.pending-' + randomUUID()
17
+ await writeFile(pending, JSON.stringify(value, null, 2) + '\n', { mode: 0o600 })
18
+ await rename(pending, path)
19
+ }
20
+
21
+ async function relocateProfileLinks(staging, previous, replacementRoot = staging) {
22
+ const visit = async directory => {
23
+ for (const entry of await readdir(directory, { withFileTypes: true })) {
24
+ const path = join(directory, entry.name)
25
+ if (entry.isSymbolicLink()) {
26
+ const link = await readlink(path)
27
+ if (isAbsolute(link) && (link === previous || link.startsWith(previous + sep))) {
28
+ const moved = join(replacementRoot, relative(previous, link))
29
+ await unlink(path)
30
+ await symlink(process.platform === 'win32' ? moved : relative(dirname(path), moved), path, process.platform === 'win32' ? 'junction' : undefined)
31
+ }
32
+ } else if (entry.isDirectory()) await visit(path)
33
+ }
34
+ }
35
+ await visit(staging)
36
+ const path = join(staging, 'node_modules', '.modules.yaml')
37
+ if (await exists(path)) {
38
+ const modules = yaml.load(await readFile(path, 'utf8'))
39
+ if (modules && typeof modules.virtualStoreDir === 'string' && isAbsolute(modules.virtualStoreDir)) {
40
+ if (!modules.virtualStoreDir.startsWith(previous + sep)) throw new Error('UNSUPPORTED_STORE: profile virtual store is outside its dependency tree')
41
+ modules.virtualStoreDir = relative(join(replacementRoot, 'node_modules'), join(replacementRoot, relative(previous, modules.virtualStoreDir)))
42
+ await writeFile(path, yaml.dump(modules), { mode: 0o600 })
43
+ }
44
+ }
45
+ }
46
+
47
+ /** Refuse mutation while Desktop, dsh, or an OpenWrite managed backend is alive. */
48
+ export async function assertHostStopped(home, profile) {
49
+ const command = process.platform === 'win32' ? 'powershell.exe' : 'ps'
50
+ const args = process.platform === 'win32'
51
+ ? ['-NoProfile', '-NonInteractive', '-Command', 'Get-CimInstance Win32_Process | Select-Object ProcessId,CommandLine | ConvertTo-Json -Compress']
52
+ : ['-axo', 'pid=,command=']
53
+ const result = spawnSync(command, args, { encoding: 'utf8', timeout: 10000, windowsHide: true, maxBuffer: 8 * 1024 ** 2 })
54
+ if (result.error || result.status !== 0) throw new Error('HOST_STATE_UNKNOWN: cannot inspect running processes; no profile files changed')
55
+ const processes = process.platform === 'win32'
56
+ ? [].concat(JSON.parse(result.stdout || '[]')).map(row => ({ pid: row.ProcessId, command: row.CommandLine || '' }))
57
+ : result.stdout.split('\n').flatMap(line => { const match = /^\s*(\d+)\s+(.+)$/.exec(line); return match ? [{ pid: Number(match[1]), command: match[2] }] : [] })
58
+ const active = processes.filter(row => row.pid !== process.pid && (
59
+ /(?:DeepSeek Harness|DSH Desktop|dsh-desktop|dsh-host-desktop|tools\.managed_runtime)/i.test(row.command)
60
+ || /(?:^|[\\/\s])dsh(?:[\\/\s.]|$)/i.test(row.command) && !/\splugin\s/.test(row.command)
61
+ && !/safe-upgrade|openwrite-maintenance/.test(row.command)
62
+ ))
63
+ if (active.length) throw new Error(`HOST_RUNNING: quit DSH Desktop and stop dsh before upgrading ${profile}; active process IDs: ${active.map(row => row.pid).join(', ')}`)
64
+ }
65
+
66
+ async function runInstall(home, profile, spec, log) {
67
+ const bin = process.env.DSH_BIN || 'dsh'
68
+ if (process.platform === 'win32' && !/\.[cm]?js$/.test(bin)) throw new Error('DSH_BIN_REQUIRED: set DSH_BIN to the accepted Desktop runtime lib/bin.js before upgrading')
69
+ const command = /\.[cm]?js$/.test(bin) ? process.execPath : bin
70
+ const args = [...(/\.[cm]?js$/.test(bin) ? [bin] : []), 'plugin', '--profile', profile, 'add', '-w', spec]
71
+ let writes = Promise.resolve()
72
+ const child = spawn(command, args, { env: { ...process.env, DSH_HOME: home }, cwd: home,
73
+ stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true, detached: process.platform !== 'win32' })
74
+ let timer, drainTimer, escalation
75
+ for (const stream of [child.stdout, child.stderr]) stream.on('data', bytes => { writes = writes.then(() => log.write(bytes)) })
76
+ try {
77
+ await new Promise((accept, reject) => {
78
+ timer = setTimeout(() => {
79
+ if (process.platform === 'win32') spawnSync('taskkill', ['/PID', String(child.pid), '/T', '/F'], { windowsHide: true, timeout: 5000 })
80
+ else { try { process.kill(-child.pid, 'SIGKILL') } catch (error) { if (error.code !== 'ESRCH') process.stderr.write(`Installer termination failed: ${error.message}\n`) } }
81
+ escalation = setTimeout(() => { child.stdout.destroy(); child.stderr.destroy(); reject(new Error('INSTALL_TIMEOUT: staged installer exceeded 180 seconds; active profile unchanged')) }, 2000)
82
+ }, 180000)
83
+ child.once('exit', () => { drainTimer = setTimeout(() => { child.stdout.destroy(); child.stderr.destroy() }, 2000) })
84
+ child.once('error', reject)
85
+ child.once('close', (code, signal) => code === 0 ? accept() : reject(new Error(`INSTALL_FAILED: exit=${code}, signal=${signal || ''}`)))
86
+ })
87
+ } finally { clearTimeout(timer); clearTimeout(drainTimer); clearTimeout(escalation); await writes }
88
+ }
89
+
90
+ function profileDirectory(home, profile) {
91
+ if (!PROFILE.test(profile)) throw new Error('Invalid profile name')
92
+ return join(resolve(home), 'profiles', profile)
93
+ }
94
+
95
+ /** Recover a previously approved directory swap without overwriting later edits. */
96
+ export async function recoverUpgrade(home, operationId, options = {}) {
97
+ if (!/^upgrade_[a-f0-9-]+$/.test(operationId)) throw new Error('Invalid upgrade operation ID')
98
+ const root = join(resolve(home), 'openwrite', 'upgrades', operationId)
99
+ const operation = JSON.parse(await readFile(join(root, 'operation.json'), 'utf8'))
100
+ const target = profileDirectory(home, operation.profile)
101
+ await (options.assertStopped || assertHostStopped)(home, operation.profile)
102
+ const previous = join(root, 'previous-profile')
103
+ const release = await acquireLock(join(home, 'profiles'), { realpath: true, retries: 0 })
104
+ try {
105
+ if (!await exists(target) && await exists(previous)) {
106
+ await rename(previous, target)
107
+ operation.status = 'rolled_back'
108
+ } else if (await exists(target)) {
109
+ const actual = digest(await readFile(join(target, 'package.json')))
110
+ if (actual === operation.new_manifest_sha256) operation.status = 'completed'
111
+ else if (actual === operation.old_manifest_sha256) operation.status = 'rolled_back'
112
+ else throw new Error('PROFILE_CHANGED: preserve the backup and reconcile the profile manually')
113
+ } else throw new Error('RECOVERY_REQUIRED: neither active nor previous profile is available')
114
+ await save(join(root, 'operation.json'), operation)
115
+ return { operation_id: operationId, status: operation.status, backup: previous }
116
+ } finally { await release() }
117
+ }
118
+
119
+ /** Stage a complete profile beside the active tree, validate, then swap while stopped. */
120
+ export async function upgradeProfile(home, profile, spec, options = {}) {
121
+ if (typeof spec !== 'string' || !spec || spec.startsWith('-') || /[\r\n]/.test(spec)) throw new Error('A package spec or Release tarball is required')
122
+ const target = profileDirectory(home, profile)
123
+ const stopped = options.assertStopped || assertHostStopped
124
+ await stopped(home, profile)
125
+ const release = await acquireLock(join(home, 'profiles'), { realpath: true, retries: 0 })
126
+ const id = 'upgrade_' + randomUUID()
127
+ const root = join(resolve(home), 'openwrite', 'upgrades', id)
128
+ const stagingName = 'openwrite-stage-' + randomUUID()
129
+ const staging = profileDirectory(home, stagingName)
130
+ const previous = join(root, 'previous-profile')
131
+ const logPath = join(root, 'pnpm.log')
132
+ let log
133
+ let moved = false
134
+ const operation = { operation_id: id, profile, spec, status: 'preparing', created_at: new Date().toISOString() }
135
+ try {
136
+ await mkdir(root, { recursive: true, mode: 0o700 })
137
+ log = await open(logPath, 'wx', 0o600)
138
+ await log.write('Preparing isolated profile installation. The active profile is unchanged.\n')
139
+ const oldManifest = await readFile(join(target, 'package.json'))
140
+ operation.old_manifest_sha256 = digest(oldManifest)
141
+ await save(join(root, 'operation.json'), operation)
142
+ await cp(target, staging, { recursive: true, dereference: false, verbatimSymlinks: true,
143
+ filter: source => !source.includes('/.plugin-manager/') && !source.endsWith('/.plugin-manager') })
144
+ await relocateProfileLinks(staging, target)
145
+ await (options.run || runInstall)(home, stagingName, spec, log)
146
+ const installed = JSON.parse(await readFile(join(staging, 'node_modules', 'dsh-openwrite', 'package.json'), 'utf8'))
147
+ if (installed.name !== 'dsh-openwrite' || !installed.version || !installed.dsh?.bundle?.patch) throw new Error('BUNDLE_INCOMPLETE: staged OpenWrite manifest is invalid')
148
+ const bundleRoot = join(staging, 'node_modules', 'dsh-openwrite')
149
+ const patchPath = resolve(bundleRoot, installed.dsh.bundle.patch)
150
+ if (!patchPath.startsWith(bundleRoot + sep)) throw new Error('BUNDLE_INCOMPLETE: invalid bundle patch path')
151
+ for (const file of [patchPath, ...['plugin.mjs', 'packages/openwrite-bridge/lib/index.js', 'packages/studio-panel/lib/client.js'].map(name => join(bundleRoot, name))]) await access(file)
152
+ operation.new_manifest_sha256 = digest(await readFile(join(staging, 'package.json')))
153
+ if (digest(await readFile(join(target, 'package.json'))) !== operation.old_manifest_sha256) throw new Error('PROFILE_CHANGED: the active profile changed during staging')
154
+ await stopped(home, profile)
155
+ await relocateProfileLinks(staging, staging, target)
156
+ operation.status = 'swapping'
157
+ await save(join(root, 'operation.json'), operation)
158
+ await rename(target, previous)
159
+ moved = true
160
+ await rename(staging, target)
161
+ operation.status = 'completed'
162
+ operation.version = installed.version
163
+ await save(join(root, 'operation.json'), operation)
164
+ await log.write('Upgrade committed. Previous complete profile retained in previous-profile.\n')
165
+ return { operation_id: id, status: operation.status, version: installed.version, backup: previous, log: logPath }
166
+ } catch (error) {
167
+ try { await log?.write(`${error.stack || error.message}\n`) } catch (logError) { process.stderr.write(`Upgrade diagnostic could not be written: ${logError.message}\n`) }
168
+ if (moved && !await exists(target)) {
169
+ try { await rename(previous, target); operation.status = 'rolled_back' }
170
+ catch (rollbackError) { operation.status = 'recovery_required'; await log.write(`Rollback failed: ${rollbackError.message}\n`) }
171
+ } else operation.status = moved ? 'recovery_required' : 'failed'
172
+ await save(join(root, 'operation.json'), operation)
173
+ error.message += `; operation=${id}; log=${logPath}`
174
+ throw error
175
+ } finally { try { await log?.close() } finally { await release() } }
176
+ }
177
+
178
+ /** Disable only an incomplete OpenWrite bundle so a stopped profile can boot for repair. */
179
+ export async function repairProfile(home, profile, apply = false, options = {}) {
180
+ const target = profileDirectory(home, profile)
181
+ const manifestPath = join(target, 'package.json')
182
+ const original = await readFile(manifestPath, 'utf8')
183
+ const manifest = JSON.parse(original)
184
+ let broken = false
185
+ try { const pkg = JSON.parse(await readFile(join(target, 'node_modules', 'dsh-openwrite', 'package.json'), 'utf8')); broken = pkg.name !== 'dsh-openwrite' }
186
+ catch (error) { if (error.code !== 'ENOENT' && !(error instanceof SyntaxError)) throw error; broken = true }
187
+ const enabled = manifest.dsh?.profile?.bundles?.includes('dsh-openwrite') === true
188
+ if (!apply || !broken || !enabled) return { profile, incomplete: broken, enabled, changed: false }
189
+ await (options.assertStopped || assertHostStopped)(home, profile)
190
+ const release = await acquireLock(join(home, 'profiles'), { realpath: true, retries: 0 })
191
+ try {
192
+ if (await readFile(manifestPath, 'utf8') !== original) throw new Error('PROFILE_CHANGED: refresh repair inspection')
193
+ const backup = join(target, 'package.json.openwrite-repair-' + randomUUID())
194
+ await writeFile(backup, original, { mode: 0o600 })
195
+ manifest.dsh.profile.bundles = manifest.dsh.profile.bundles.filter(name => name !== 'dsh-openwrite')
196
+ await save(manifestPath, manifest)
197
+ return { profile, changed: true, backup, incomplete: true, enabled: false }
198
+ } finally { await release() }
199
+ }
200
+
201
+ if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) {
202
+ const value = name => { const i = process.argv.indexOf(name); return i < 0 ? undefined : process.argv[i + 1] }
203
+ const home = resolve(process.env.DSH_HOME || join(homedir(), '.dsh'))
204
+ try {
205
+ const profile = value('--profile') || 'web'
206
+ const result = value('--recover') ? await recoverUpgrade(home, value('--recover'))
207
+ : process.argv.includes('--repair') ? await repairProfile(home, profile, process.argv.includes('--apply'))
208
+ : await upgradeProfile(home, profile, value('--package'))
209
+ console.log(JSON.stringify(result, null, 2))
210
+ } catch (error) { console.error(error.message); process.exitCode = 1 }
211
+ }