feat(wechat): MindSpace public draft push with 143 host defaults
Add public-page WeChat draft button, publication standard conversion for poem/prose/generic pages, and quick push APIs. Default Studio release SSH targets to john@180.159.29.143 with 105 edge upstream via 10.10.0.2. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,6 +2,8 @@ import crypto from 'node:crypto';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { createAgentRunGateway } from '../agent-run-gateway.mjs';
|
||||
import { releaseMaterializedPageDeliveryContracts } from '../mindspace-delivery-contract.mjs';
|
||||
import { resolvePublishDir } from '../user-publish.mjs';
|
||||
import { createGoalRunService } from '../goal-run-service.mjs';
|
||||
import { isDirectChatSessionId } from '../direct-chat-service.mjs';
|
||||
import {
|
||||
@@ -288,6 +290,16 @@ export function bootstrapPortalGatewayServices({
|
||||
sessionId,
|
||||
sinceMs: runStartedAtMs,
|
||||
}),
|
||||
releaseUserPageDeliveryContractsOnSuccess: async ({
|
||||
userId,
|
||||
relativePaths,
|
||||
}) =>
|
||||
releaseMaterializedPageDeliveryContracts({
|
||||
pool,
|
||||
userId,
|
||||
relativePaths,
|
||||
publishDir: resolvePublishDir(h5Root, { id: userId }),
|
||||
}),
|
||||
isSessionExternallyBusy: ({ sessionId }) =>
|
||||
isSessionPageDeliveryActive(sessionId),
|
||||
validateRunDeliverables,
|
||||
|
||||
@@ -3,6 +3,10 @@ import {
|
||||
quickPlazaFromChat,
|
||||
quickPlazaFromPublicHtml,
|
||||
} from '../mindspace-chat-plaza.mjs';
|
||||
import {
|
||||
getQuickWechatDraftFromPublicHtmlStatus,
|
||||
quickWechatDraftFromPublicHtml,
|
||||
} from '../mindspace-chat-wechat-draft.mjs';
|
||||
|
||||
function assertRouter(api) {
|
||||
if (
|
||||
@@ -41,6 +45,11 @@ export function attachPortalMindSpaceChatShareRoutes(
|
||||
getQuickPlazaFromPublicHtmlStatusFn =
|
||||
getQuickPlazaFromPublicHtmlStatus,
|
||||
quickPlazaFromPublicHtmlFn = quickPlazaFromPublicHtml,
|
||||
getWechatMpConfig = () => null,
|
||||
getWechatPageDraft = () => null,
|
||||
getQuickWechatDraftFromPublicHtmlStatusFn =
|
||||
getQuickWechatDraftFromPublicHtmlStatus,
|
||||
quickWechatDraftFromPublicHtmlFn = quickWechatDraftFromPublicHtml,
|
||||
now = Date.now,
|
||||
logger = console,
|
||||
} = {},
|
||||
@@ -268,4 +277,90 @@ export function attachPortalMindSpaceChatShareRoutes(
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
api.get(
|
||||
'/mindspace/v1/pages/quick-wechat-draft-from-public-html/status',
|
||||
async (req, res) => {
|
||||
const pages = getMindSpacePages();
|
||||
const publications = getMindSpacePublications();
|
||||
const chatSave = getMindSpaceChatSave();
|
||||
const draftService = getWechatPageDraft?.();
|
||||
if (!pages || !chatSave || !draftService) {
|
||||
return sendError(
|
||||
res,
|
||||
req,
|
||||
503,
|
||||
'wechat_draft_unavailable',
|
||||
'公众号草稿推送未启用',
|
||||
);
|
||||
}
|
||||
try {
|
||||
const relativePath = String(
|
||||
req.query?.relative_path ??
|
||||
req.query?.relativePath ??
|
||||
'',
|
||||
).trim();
|
||||
const result = await getQuickWechatDraftFromPublicHtmlStatusFn({
|
||||
user: req.currentUser,
|
||||
relativePath,
|
||||
mindSpacePages: pages,
|
||||
mindSpacePublications: publications,
|
||||
readWorkspaceHtml: (input) => chatSave.readWorkspaceHtml(input),
|
||||
getWechatMpConfig,
|
||||
getWechatPageDraft: () => draftService,
|
||||
});
|
||||
return sendData(res, req, result);
|
||||
} catch (error) {
|
||||
return handleMindSpaceError(res, req, error);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
api.post(
|
||||
'/mindspace/v1/pages/quick-wechat-draft-from-public-html',
|
||||
async (req, res) => {
|
||||
const pages = getMindSpacePages();
|
||||
const publications = getMindSpacePublications();
|
||||
const chatSave = getMindSpaceChatSave();
|
||||
const draftService = getWechatPageDraft?.();
|
||||
if (!pages || !chatSave || !draftService) {
|
||||
return sendError(
|
||||
res,
|
||||
req,
|
||||
503,
|
||||
'wechat_draft_unavailable',
|
||||
'公众号草稿推送未启用',
|
||||
);
|
||||
}
|
||||
const startedAt = now();
|
||||
try {
|
||||
const relativePath = String(
|
||||
req.body?.relative_path ??
|
||||
req.body?.relativePath ??
|
||||
'',
|
||||
).trim();
|
||||
const result = await quickWechatDraftFromPublicHtmlFn({
|
||||
user: req.currentUser,
|
||||
relativePath,
|
||||
mindSpacePages: pages,
|
||||
mindSpacePublications: publications,
|
||||
readWorkspaceHtml: (input) => chatSave.readWorkspaceHtml(input),
|
||||
getWechatPageDraft: () => draftService,
|
||||
});
|
||||
logger.info('[quick-wechat-draft-public-html] ok', {
|
||||
ms: now() - startedAt,
|
||||
pageId: result.pageId ?? result.run?.pageId,
|
||||
draftMediaId: result.draftMediaId,
|
||||
relativePath,
|
||||
});
|
||||
return sendData(res, req, result, 201);
|
||||
} catch (error) {
|
||||
logger.error('[quick-wechat-draft-public-html] error:', {
|
||||
ms: now() - startedAt,
|
||||
error,
|
||||
});
|
||||
return handleMindSpaceError(res, req, error);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -121,6 +121,8 @@ test('chat share module preserves route inventory and order', () => {
|
||||
'POST /mindspace/v1/pages/quick-plaza-from-chat',
|
||||
'GET /mindspace/v1/pages/quick-plaza-from-public-html/status',
|
||||
'POST /mindspace/v1/pages/quick-plaza-from-public-html',
|
||||
'GET /mindspace/v1/pages/quick-wechat-draft-from-public-html/status',
|
||||
'POST /mindspace/v1/pages/quick-wechat-draft-from-public-html',
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -350,6 +352,16 @@ test('chat share routes preserve availability gates and MindSpace fallback error
|
||||
assert.equal(res.body.error.code, 'plaza_unavailable');
|
||||
}
|
||||
|
||||
for (const route of [
|
||||
'GET /mindspace/v1/pages/quick-wechat-draft-from-public-html/status',
|
||||
'POST /mindspace/v1/pages/quick-wechat-draft-from-public-html',
|
||||
]) {
|
||||
const res = createResponseRecorder();
|
||||
await unavailableApi.routes.get(route)(createRequest(), res);
|
||||
assert.equal(res.statusCode, 503, route);
|
||||
assert.equal(res.body.error.code, 'wechat_draft_unavailable');
|
||||
}
|
||||
|
||||
const failureApi = createRouterRecorder();
|
||||
const failure = new Error('share failed');
|
||||
const dependencies = createDependencies({
|
||||
|
||||
Reference in New Issue
Block a user