@kienmatu/inkos-studio 1.0.1 → 3.3.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/api/server.d.ts.map +1 -1
- package/dist/api/server.js +106 -6
- package/dist/api/server.js.map +1 -1
- package/dist/api/task-store.d.ts +1 -0
- package/dist/api/task-store.d.ts.map +1 -1
- package/dist/api/task-store.js +3 -0
- package/dist/api/task-store.js.map +1 -1
- package/dist/assets/{FilmWizard-CxoOJ7MQ.js → FilmWizard-DsSZPo5A.js} +1 -1
- package/dist/assets/{FlowView-Bt0EtmEr.js → FlowView-DtborsGc.js} +1 -1
- package/dist/assets/{_baseUniq-ZL9pmMqM.js → _baseUniq-BEIj9tcE.js} +1 -1
- package/dist/assets/{arc-B8qI0bEW.js → arc-C7Rm_CAk.js} +1 -1
- package/dist/assets/{architectureDiagram-Q4EWVU46-BMqx63uW.js → architectureDiagram-Q4EWVU46-DlmfKm7b.js} +1 -1
- package/dist/assets/{blockDiagram-DXYQGD6D-CpTeW9T5.js → blockDiagram-DXYQGD6D-DwWcyB5e.js} +1 -1
- package/dist/assets/{c4Diagram-AHTNJAMY-DEMZhRny.js → c4Diagram-AHTNJAMY-DJr7ig4J.js} +1 -1
- package/dist/assets/channel-D3RJhFng.js +1 -0
- package/dist/assets/{chunk-4BX2VUAB-CATTVIYo.js → chunk-4BX2VUAB-BEbkhxPj.js} +1 -1
- package/dist/assets/{chunk-4TB4RGXK-BVSOdPwi.js → chunk-4TB4RGXK-CKlayWkT.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-roBKSgqh.js → chunk-55IACEB6-Do_NAv20.js} +1 -1
- package/dist/assets/{chunk-EDXVE4YY-DcL-JJvQ.js → chunk-EDXVE4YY-CIaC2_XQ.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-CTt3nqty.js → chunk-FMBD7UC4-DK2fFb-S.js} +1 -1
- package/dist/assets/{chunk-OYMX7WX6-BKloZua_.js → chunk-OYMX7WX6-DOk8ZO7Q.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-CksGJW6L.js → chunk-QZHKN3VN-CWQlxTIX.js} +1 -1
- package/dist/assets/{chunk-YZCP3GAM-DFUs85Mo.js → chunk-YZCP3GAM-BKMKNDs_.js} +1 -1
- package/dist/assets/classDiagram-6PBFFD2Q-Ctnvqnpw.js +1 -0
- package/dist/assets/classDiagram-v2-HSJHXN6E-Ctnvqnpw.js +1 -0
- package/dist/assets/clone-BdOaHqQL.js +1 -0
- package/dist/assets/{cose-bilkent-S5V4N54A-BhjR9QKW.js → cose-bilkent-S5V4N54A-CtsSt-S-.js} +1 -1
- package/dist/assets/{dagre-KV5264BT-S0WgqeWF.js → dagre-KV5264BT-zROnUgJY.js} +1 -1
- package/dist/assets/{diagram-5BDNPKRD-iziIar_1.js → diagram-5BDNPKRD-Ct6aFDWr.js} +1 -1
- package/dist/assets/{diagram-G4DWMVQ6-DGiQ4b3V.js → diagram-G4DWMVQ6-B2bwAps6.js} +1 -1
- package/dist/assets/{diagram-MMDJMWI5-Ctfv9R4Z.js → diagram-MMDJMWI5-CbwZreHT.js} +1 -1
- package/dist/assets/{diagram-TYMM5635-DpzPFDFI.js → diagram-TYMM5635-gKzWLxCO.js} +1 -1
- package/dist/assets/{erDiagram-SMLLAGMA-e51DloYW.js → erDiagram-SMLLAGMA-DipB25lI.js} +1 -1
- package/dist/assets/{flowDiagram-DWJPFMVM-TyuMrie7.js → flowDiagram-DWJPFMVM-C9VuPnc4.js} +1 -1
- package/dist/assets/{ganttDiagram-T4ZO3ILL-sewHvhyH.js → ganttDiagram-T4ZO3ILL-B2dTjD_8.js} +1 -1
- package/dist/assets/{gitGraphDiagram-UUTBAWPF-DI7YNaAi.js → gitGraphDiagram-UUTBAWPF-BZXYA0Ec.js} +1 -1
- package/dist/assets/{graph-iCANBjLp.js → graph-iDCrfqrI.js} +1 -1
- package/dist/assets/{highlighted-body-OFNGDK62-DTkXdU8M.js → highlighted-body-OFNGDK62-CP2BM2l8.js} +1 -1
- package/dist/assets/index-CTu6WYGu.css +1 -0
- package/dist/assets/{index-3FC9cBAw.js → index-PEL5ijWf.js} +179 -179
- package/dist/assets/{infoDiagram-42DDH7IO-KcOGgxDZ.js → infoDiagram-42DDH7IO-Bd7gtY2E.js} +1 -1
- package/dist/assets/{ishikawaDiagram-UXIWVN3A-DN46kos1.js → ishikawaDiagram-UXIWVN3A-HMp96hG2.js} +1 -1
- package/dist/assets/{journeyDiagram-VCZTEJTY-CSnW-uiU.js → journeyDiagram-VCZTEJTY-D36jcF3p.js} +1 -1
- package/dist/assets/{kanban-definition-6JOO6SKY-DgeKhYzm.js → kanban-definition-6JOO6SKY-C4wSbzoj.js} +1 -1
- package/dist/assets/{layout-C3k8b-wj.js → layout-DqXRWJEx.js} +1 -1
- package/dist/assets/{linear-CSj-zsdP.js → linear-QlXzAe7A.js} +1 -1
- package/dist/assets/{min-BkU8UOgQ.js → min-iaA6vGbj.js} +1 -1
- package/dist/assets/{mindmap-definition-QFDTVHPH-jaWIxQM2.js → mindmap-definition-QFDTVHPH-B-PCe4LP.js} +1 -1
- package/dist/assets/{pieDiagram-DEJITSTG-DSCNVEy0.js → pieDiagram-DEJITSTG-DRSPzSKd.js} +1 -1
- package/dist/assets/{quadrantDiagram-34T5L4WZ-6Aki-Mea.js → quadrantDiagram-34T5L4WZ-D-c8JbLY.js} +1 -1
- package/dist/assets/{requirementDiagram-MS252O5E-CIA-stPo.js → requirementDiagram-MS252O5E-CdOoLbvR.js} +1 -1
- package/dist/assets/{sankeyDiagram-XADWPNL6-Dm92baLv.js → sankeyDiagram-XADWPNL6-CQDxnTGB.js} +1 -1
- package/dist/assets/{sequenceDiagram-FGHM5R23-CijKhpBV.js → sequenceDiagram-FGHM5R23-SZbPsgFb.js} +1 -1
- package/dist/assets/{stateDiagram-FHFEXIEX-BoRVlJdY.js → stateDiagram-FHFEXIEX-uFY2njzT.js} +1 -1
- package/dist/assets/stateDiagram-v2-QKLJ7IA2-BJCQ3uMo.js +1 -0
- package/dist/assets/{timeline-definition-GMOUNBTQ-Dgq0GzH4.js → timeline-definition-GMOUNBTQ-n_oY30Kg.js} +1 -1
- package/dist/assets/{value-BU9Hdjc2.js → value-hJ3k-Vla.js} +1 -1
- package/dist/assets/{vennDiagram-DHZGUBPP-DrIu0Q4b.js → vennDiagram-DHZGUBPP-B9VAsWw3.js} +1 -1
- package/dist/assets/{wardley-RL74JXVD-BumycEok.js → wardley-RL74JXVD-DPynk1O-.js} +1 -1
- package/dist/assets/{wardleyDiagram-NUSXRM2D-3fn4THet.js → wardleyDiagram-NUSXRM2D-BxHtrGEZ.js} +1 -1
- package/dist/assets/{xychartDiagram-5P7HB3ND-BMcrjrBB.js → xychartDiagram-5P7HB3ND-B3Hi8GO_.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +2 -2
- package/dist/assets/channel-DxRmlnS_.js +0 -1
- package/dist/assets/classDiagram-6PBFFD2Q-Bkac267_.js +0 -1
- package/dist/assets/classDiagram-v2-HSJHXN6E-Bkac267_.js +0 -1
- package/dist/assets/clone-CmiP6enp.js +0 -1
- package/dist/assets/index-8wiyHNEA.css +0 -1
- package/dist/assets/stateDiagram-v2-QKLJ7IA2-B2UHePPb.js +0 -1
package/dist/api/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,OAAO,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,OAAO,EAuHL,KAAK,aAAa,EAMlB,KAAK,aAAa,EAOnB,MAAM,sBAAsB,CAAC;AAkB9B,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEhD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAItE;AAGD,wBAAgB,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAGtF;AAwgFD,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE;IAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,aAAa,CAAA;CAAO,8EAsjI7I;AAID,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,IAAI,SAAO,EACX,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACxC,OAAO,CAAC,IAAI,CAAC,CA8Cf"}
|
package/dist/api/server.js
CHANGED
|
@@ -4,7 +4,7 @@ import { streamSSE } from "hono/streaming";
|
|
|
4
4
|
import { serve } from "@hono/node-server";
|
|
5
5
|
import { gzipSync } from "node:zlib";
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
7
|
-
import { StateManager, PipelineRunner, createLLMClient, createLogger, createInteractionToolsFromDeps, computeAnalytics, loadProjectConfig, loadProjectSession, processProjectInteractionRequest, resolveSessionActiveBook, listBookSessions, loadBookSession, appendManualSessionMessages, createAndPersistBookSession, renameBookSession, deleteBookSession, migrateBookSession, SessionAlreadyMigratedError, abortAgentSession, runAgentSession, resolveServicePreset, resolveServiceProviderFamily, resolveServiceModelsBaseUrl, guessServiceFromBaseUrl, resolveServiceModel, loadSecrets, saveSecrets, listModelsForService, isApiKeyOptionalForEndpoint, getAllEndpoints, probeModelsFromUpstream, fetchWithProxy, chatCompletion, runWorkerAgent, buildExportArtifact, evaluateBookQuality, ConsolidatorAgent, DetectionConfigSchema, ResearchSearchConfigSchema, GLOBAL_ENV_PATH, COVER_PROVIDER_PRESETS, createPlayDB, PlayStore, buildPlayEntityImagePrompt, buildPlaySceneImagePrompt, generatePlayImage, readPlayImageManifest, readPlayImageSettings, writePlayImageSettings, Scheduler, coverSecretKey, normalizeCoverBaseUrl, resolveCoverProviderPreset, SessionKindSchema, normalizeActionSource as normalizeCoreActionSource, normalizeActionPayload as normalizeCoreActionPayload, normalizePlayMode as normalizeCorePlayMode, normalizeRequestedIntent as normalizeCoreRequestedIntent, normalizeSkillIdList as normalizeCoreSkillIdList, inferLanguage, toWritingLanguage, ingestMaterial, createSkillRegistry, loadAvailableAgentSkills, activatedSkillIds, mergeActivatedSkillGuidance, resolveProductionSkillActivations, parseAgentSkillDocument, getBuiltinPrompt, listBuiltinPromptPacks, listBuiltinPrompts, loadPromptPackPrompt, promptOverridePath, toPosixPath, createGenerateCoverTool, createInteractiveFilmCreationTool, createPlayStartTool, createScriptCreationTool, createShortFictionRunTool, createStoryboardCreationTool, createTranslationCreateTool, createFanficBookTool, createContinuationImportTool, createSpinoffBookTool, createImitationBookTool, createSubAgentTool, createDraftStructureTool, createConnectChoiceTool, createRemoveNodeTool, createLLMTranslationModel, deleteLatestChapter, executeEditTransaction, listChapterVersions, readChapterPlanDocument, readChapterUserBrief, readChapterVersion, saveChapterUserBrief, createTranslationProjectFromFile, loadTranslationChapter, loadTranslationManifest, runTranslationProject, writeTranslationExport, filmLLMDepsFromClient, applyGraphDelta, loadStoryGraph, reviewStoryGraph, exportInk, buildPlayableHtml, analyzeEmotionalArcs, analyzePathDistribution, generateNodeImage, defaultNodeImageDeps, } from "@kienmatu/inkos-core";
|
|
7
|
+
import { StateManager, PipelineRunner, createLLMClient, createLogger, createInteractionToolsFromDeps, computeAnalytics, loadProjectConfig, loadProjectSession, processProjectInteractionRequest, resolveSessionActiveBook, listBookSessions, loadBookSession, appendManualSessionMessages, createAndPersistBookSession, renameBookSession, deleteBookSession, migrateBookSession, SessionAlreadyMigratedError, abortAgentSession, runAgentSession, resolveServicePreset, resolveServiceProviderFamily, resolveServiceModelsBaseUrl, guessServiceFromBaseUrl, resolveServiceModel, loadSecrets, saveSecrets, listModelsForService, isApiKeyOptionalForEndpoint, getAllEndpoints, probeModelsFromUpstream, fetchWithProxy, chatCompletion, runWorkerAgent, buildExportArtifact, createProductionRunSnapshot, evaluateBookQuality, ConsolidatorAgent, DetectionConfigSchema, ResearchSearchConfigSchema, GLOBAL_ENV_PATH, COVER_PROVIDER_PRESETS, createPlayDB, PlayStore, buildPlayEntityImagePrompt, buildPlaySceneImagePrompt, generatePlayImage, readPlayImageManifest, readPlayImageSettings, writePlayImageSettings, Scheduler, coverSecretKey, normalizeCoverBaseUrl, resolveCoverProviderPreset, SessionKindSchema, normalizeActionSource as normalizeCoreActionSource, normalizeActionPayload as normalizeCoreActionPayload, normalizePlayMode as normalizeCorePlayMode, normalizeRequestedIntent as normalizeCoreRequestedIntent, normalizeSkillIdList as normalizeCoreSkillIdList, inferLanguage, toWritingLanguage, ingestMaterial, createSkillRegistry, loadAvailableAgentSkills, activatedSkillIds, mergeActivatedSkillGuidance, resolveProductionSkillActivations, parseAgentSkillDocument, getBuiltinPrompt, listBuiltinPromptPacks, listBuiltinPrompts, loadPromptPackPrompt, promptOverridePath, toPosixPath, createGenerateCoverTool, createInteractiveFilmCreationTool, createPlayStartTool, createScriptCreationTool, createShortFictionRunTool, createStoryboardCreationTool, createTranslationCreateTool, createFanficBookTool, createContinuationImportTool, createSpinoffBookTool, createImitationBookTool, createSubAgentTool, createDraftStructureTool, createConnectChoiceTool, createRemoveNodeTool, createLLMTranslationModel, deleteLatestChapter, executeEditTransaction, listChapterVersions, readChapterPlanDocument, readChapterUserBrief, readChapterVersion, saveChapterUserBrief, createTranslationProjectFromFile, loadTranslationChapter, loadTranslationManifest, runTranslationProject, writeTranslationExport, filmLLMDepsFromClient, applyGraphDelta, loadStoryGraph, reviewStoryGraph, exportInk, buildPlayableHtml, analyzeEmotionalArcs, analyzePathDistribution, generateNodeImage, defaultNodeImageDeps, writeProductionRunSnapshot, } from "@kienmatu/inkos-core";
|
|
8
8
|
import { isConfirmedProductionAction } from "../shared/confirmed-production.js";
|
|
9
9
|
import { summarizeToolResult } from "../shared/tool-result.js";
|
|
10
10
|
import { access, mkdir, readFile, readdir, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
@@ -1267,18 +1267,79 @@ async function executeConfirmedProductionAction(args) {
|
|
|
1267
1267
|
throw new ConfirmedActionExecutionError(message, exec, error);
|
|
1268
1268
|
}
|
|
1269
1269
|
}
|
|
1270
|
-
function
|
|
1270
|
+
function parseProductionObservation(value) {
|
|
1271
1271
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
1272
1272
|
return null;
|
|
1273
1273
|
const record = value;
|
|
1274
|
+
if (typeof record.metric !== "string"
|
|
1275
|
+
|| !["info", "warning", "blocking"].includes(String(record.severity))
|
|
1276
|
+
|| typeof record.repairable !== "boolean"
|
|
1277
|
+
|| (record.evidence !== undefined && typeof record.evidence !== "string")) {
|
|
1278
|
+
return null;
|
|
1279
|
+
}
|
|
1280
|
+
return {
|
|
1281
|
+
metric: record.metric,
|
|
1282
|
+
expected: record.expected,
|
|
1283
|
+
actual: record.actual,
|
|
1284
|
+
severity: record.severity,
|
|
1285
|
+
...(typeof record.evidence === "string" ? { evidence: record.evidence } : {}),
|
|
1286
|
+
repairable: record.repairable,
|
|
1287
|
+
};
|
|
1288
|
+
}
|
|
1289
|
+
function parseStudioShortRun(value, expectedStoryId) {
|
|
1290
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
1291
|
+
return null;
|
|
1292
|
+
const record = value;
|
|
1293
|
+
const status = record.status;
|
|
1294
|
+
const artifacts = Array.isArray(record.artifacts) && record.artifacts.every((item) => typeof item === "string")
|
|
1295
|
+
? record.artifacts
|
|
1296
|
+
: null;
|
|
1297
|
+
const observations = Array.isArray(record.observations)
|
|
1298
|
+
? record.observations.map(parseProductionObservation)
|
|
1299
|
+
: null;
|
|
1274
1300
|
if (record.version !== 1
|
|
1275
1301
|
|| record.kind !== "short-fiction"
|
|
1276
1302
|
|| record.id !== expectedStoryId
|
|
1277
|
-
||
|
|
1303
|
+
|| (status !== "complete" && status !== "needs-review")
|
|
1304
|
+
|| typeof record.stage !== "string"
|
|
1305
|
+
|| !artifacts
|
|
1306
|
+
|| !observations
|
|
1307
|
+
|| observations.some((observation) => observation === null)
|
|
1308
|
+
|| typeof record.updatedAt !== "string"
|
|
1309
|
+
|| (record.model !== undefined && typeof record.model !== "string")
|
|
1310
|
+
|| (record.skillIds !== undefined && (!Array.isArray(record.skillIds) || !record.skillIds.every((item) => typeof item === "string")))
|
|
1311
|
+
|| (record.resumeCursor !== undefined && typeof record.resumeCursor !== "string")
|
|
1312
|
+
|| (record.error !== undefined && typeof record.error !== "string")) {
|
|
1313
|
+
return null;
|
|
1314
|
+
}
|
|
1315
|
+
return {
|
|
1316
|
+
version: 1,
|
|
1317
|
+
kind: "short-fiction",
|
|
1318
|
+
id: expectedStoryId,
|
|
1319
|
+
status,
|
|
1320
|
+
stage: record.stage,
|
|
1321
|
+
artifacts,
|
|
1322
|
+
observations: observations,
|
|
1323
|
+
...(typeof record.model === "string" ? { model: record.model } : {}),
|
|
1324
|
+
...(Array.isArray(record.skillIds) ? { skillIds: record.skillIds } : {}),
|
|
1325
|
+
...(typeof record.resumeCursor === "string" ? { resumeCursor: record.resumeCursor } : {}),
|
|
1326
|
+
...(typeof record.error === "string" ? { error: record.error } : {}),
|
|
1327
|
+
updatedAt: record.updatedAt,
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1330
|
+
function parseVisibleShortRunIndex(value, expectedStoryId) {
|
|
1331
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
1332
|
+
return null;
|
|
1333
|
+
const record = value;
|
|
1334
|
+
const status = record.status;
|
|
1335
|
+
if (record.version !== 1
|
|
1336
|
+
|| record.kind !== "short-fiction"
|
|
1337
|
+
|| record.id !== expectedStoryId
|
|
1338
|
+
|| (status !== "complete" && status !== "needs-review")
|
|
1278
1339
|
|| typeof record.updatedAt !== "string") {
|
|
1279
1340
|
return null;
|
|
1280
1341
|
}
|
|
1281
|
-
return { storyId: expectedStoryId, updatedAt: record.updatedAt };
|
|
1342
|
+
return { storyId: expectedStoryId, status, updatedAt: record.updatedAt };
|
|
1282
1343
|
}
|
|
1283
1344
|
function parseShortStoryTitle(value) {
|
|
1284
1345
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
@@ -1304,15 +1365,16 @@ async function loadStudioShortList(root) {
|
|
|
1304
1365
|
const shortDir = join(shortsDir, storyId);
|
|
1305
1366
|
try {
|
|
1306
1367
|
const status = JSON.parse(await readFile(join(shortDir, "status.json"), "utf-8"));
|
|
1307
|
-
const run =
|
|
1368
|
+
const run = parseVisibleShortRunIndex(status, storyId);
|
|
1308
1369
|
if (!run)
|
|
1309
1370
|
continue;
|
|
1310
1371
|
const story = JSON.parse(await readFile(join(shortDir, "final", "short-story.json"), "utf-8"));
|
|
1311
1372
|
const title = parseShortStoryTitle(story) ?? storyId;
|
|
1312
|
-
await
|
|
1373
|
+
await readFile(join(shortDir, "final", "full.md"), "utf-8");
|
|
1313
1374
|
shorts.push({
|
|
1314
1375
|
storyId,
|
|
1315
1376
|
title,
|
|
1377
|
+
status: run.status,
|
|
1316
1378
|
finalMarkdownPath: toPosixPath(join("shorts", storyId, "final", "full.md")),
|
|
1317
1379
|
updatedAt: run.updatedAt,
|
|
1318
1380
|
});
|
|
@@ -2067,6 +2129,7 @@ export function createStudioServer(initialConfig, root, overrides = {}) {
|
|
|
2067
2129
|
const state = new StateManager(root);
|
|
2068
2130
|
let cachedConfig = initialConfig;
|
|
2069
2131
|
const activeConfirmedTasks = new Map();
|
|
2132
|
+
const confirmedTaskRevisions = new Map();
|
|
2070
2133
|
// 确认式生产任务的单任务名额(sessionId → taskId)。原来的检查是"await 读快照
|
|
2071
2134
|
// → 之后才 set controller"的 check-then-act:两个并发确认请求都能通过检查,
|
|
2072
2135
|
// 双任务同时启动、快照互相覆盖。这里在任何 await 之前同步占位,占位失败的
|
|
@@ -2090,8 +2153,11 @@ export function createStudioServer(initialConfig, root, overrides = {}) {
|
|
|
2090
2153
|
const persistConfirmedTask = async (sessionId, requestedIntent, exec, sourceRequestId) => {
|
|
2091
2154
|
if (deletedSessionIds.has(sessionId))
|
|
2092
2155
|
return;
|
|
2156
|
+
const revision = (confirmedTaskRevisions.get(exec.id) ?? 0) + 1;
|
|
2157
|
+
confirmedTaskRevisions.set(exec.id, revision);
|
|
2093
2158
|
const snapshot = {
|
|
2094
2159
|
version: 1,
|
|
2160
|
+
revision,
|
|
2095
2161
|
sessionId,
|
|
2096
2162
|
...(sourceRequestId ? { sourceRequestId } : {}),
|
|
2097
2163
|
requestedIntent,
|
|
@@ -2102,7 +2168,10 @@ export function createStudioServer(initialConfig, root, overrides = {}) {
|
|
|
2102
2168
|
...(exec.logs ? { logs: [...exec.logs] } : {}),
|
|
2103
2169
|
},
|
|
2104
2170
|
};
|
|
2171
|
+
// Publish the same durable snapshot that refresh recovery reads, so an
|
|
2172
|
+
// already-open task card sees milestone logs without requiring a reload.
|
|
2105
2173
|
await saveStudioTaskSnapshot(root, snapshot);
|
|
2174
|
+
broadcast("task:snapshot", snapshot);
|
|
2106
2175
|
};
|
|
2107
2176
|
const loadReconciledTaskSnapshot = async (sessionId) => {
|
|
2108
2177
|
const task = await loadStudioTaskSnapshot(root, sessionId);
|
|
@@ -4186,6 +4255,7 @@ export function createStudioServer(initialConfig, root, overrides = {}) {
|
|
|
4186
4255
|
}
|
|
4187
4256
|
finally {
|
|
4188
4257
|
activeConfirmedTasks.delete(taskId);
|
|
4258
|
+
confirmedTaskRevisions.delete(taskId);
|
|
4189
4259
|
reservedProductionSessions.delete(reservedSessionId);
|
|
4190
4260
|
}
|
|
4191
4261
|
}
|
|
@@ -5395,6 +5465,36 @@ export function createStudioServer(initialConfig, root, overrides = {}) {
|
|
|
5395
5465
|
const shorts = await loadStudioShortList(root);
|
|
5396
5466
|
return c.json({ shorts });
|
|
5397
5467
|
});
|
|
5468
|
+
app.post("/api/v1/shorts/:id/complete", async (c) => {
|
|
5469
|
+
const storyId = c.req.param("id");
|
|
5470
|
+
if (!isSafeBookId(storyId)) {
|
|
5471
|
+
return c.json({ error: "Invalid short id" }, 400);
|
|
5472
|
+
}
|
|
5473
|
+
const runPath = join("shorts", storyId, "status.json");
|
|
5474
|
+
let raw;
|
|
5475
|
+
try {
|
|
5476
|
+
raw = JSON.parse(await readFile(join(root, runPath), "utf-8"));
|
|
5477
|
+
}
|
|
5478
|
+
catch {
|
|
5479
|
+
return c.json({ error: "Short not found" }, 404);
|
|
5480
|
+
}
|
|
5481
|
+
const run = parseStudioShortRun(raw, storyId);
|
|
5482
|
+
if (!run) {
|
|
5483
|
+
return c.json({ error: "Short status is invalid" }, 409);
|
|
5484
|
+
}
|
|
5485
|
+
if (run.status === "needs-review") {
|
|
5486
|
+
await writeProductionRunSnapshot({
|
|
5487
|
+
rootDir: root,
|
|
5488
|
+
runPath,
|
|
5489
|
+
run: createProductionRunSnapshot({
|
|
5490
|
+
...run,
|
|
5491
|
+
status: "complete",
|
|
5492
|
+
updatedAt: new Date().toISOString(),
|
|
5493
|
+
}),
|
|
5494
|
+
});
|
|
5495
|
+
}
|
|
5496
|
+
return c.json({ ok: true, storyId, status: "complete" });
|
|
5497
|
+
});
|
|
5398
5498
|
app.get("/api/v1/translations", async (c) => {
|
|
5399
5499
|
const translationsDir = join(root, "translations");
|
|
5400
5500
|
let entries = [];
|