Merge branch 'dev' of https://github.com/QLHazyCoder/FlowPilot into dev
This commit is contained in:
@@ -13575,6 +13575,7 @@ const kiroPublisher = self.MultiPageBackgroundKiroPublisherKiroRs?.createKiroRsP
|
||||
completeNodeFromBackground,
|
||||
fetchImpl: typeof fetch === 'function' ? fetch.bind(globalThis) : null,
|
||||
getState,
|
||||
maybeSubmitFlowContribution,
|
||||
setState,
|
||||
});
|
||||
const step10Executor = self.MultiPageBackgroundStep10?.createStep10Executor({
|
||||
|
||||
@@ -478,15 +478,6 @@
|
||||
},
|
||||
});
|
||||
await log('步骤 8:桌面授权回调已捕获,Token 换取成功。', 'ok', nodeId);
|
||||
await maybeSubmitFlowContribution({
|
||||
...currentState,
|
||||
...payload,
|
||||
}, {
|
||||
nodeId,
|
||||
trigger: 'kiro-step-8',
|
||||
}).catch(async (error) => {
|
||||
await log(`步骤 8:Kiro 公共贡献提交异常,已保留桌面授权结果:${getErrorMessage(error)}`, 'warn', nodeId);
|
||||
});
|
||||
await completeNodeFromBackground(nodeId, payload);
|
||||
return payload;
|
||||
}
|
||||
|
||||
@@ -295,6 +295,7 @@
|
||||
completeNodeFromBackground,
|
||||
fetchImpl = typeof fetch === 'function' ? fetch.bind(globalThis) : null,
|
||||
getState = async () => ({}),
|
||||
maybeSubmitFlowContribution = async () => ({ ok: true, skipped: true, reason: 'not_configured' }),
|
||||
setState = async () => {},
|
||||
} = deps;
|
||||
|
||||
@@ -329,10 +330,59 @@
|
||||
await setState(nextPatch);
|
||||
}
|
||||
|
||||
function shouldUseContributionUpload(state = {}) {
|
||||
return Boolean(state?.accountContributionEnabled)
|
||||
&& cleanString(state?.activeFlowId || state?.flowId).toLowerCase() === 'kiro'
|
||||
&& cleanString(state?.contributionAdapterId).toLowerCase() === 'kiro-builder-id';
|
||||
}
|
||||
|
||||
async function executeKiroUploadCredential(state = {}) {
|
||||
const nodeId = String(state?.nodeId || 'kiro-upload-credential').trim();
|
||||
const currentState = await getState();
|
||||
try {
|
||||
if (shouldUseContributionUpload(currentState)) {
|
||||
await applyRuntimeState(currentState, {
|
||||
session: {
|
||||
currentStage: 'upload',
|
||||
lastError: '',
|
||||
lastWarning: '',
|
||||
},
|
||||
upload: {
|
||||
targetId: 'contribution',
|
||||
status: 'uploading',
|
||||
error: '',
|
||||
},
|
||||
});
|
||||
|
||||
await log('步骤 9:正在上传 Builder ID 到贡献池...', 'info', nodeId);
|
||||
const contributionResult = await maybeSubmitFlowContribution(currentState, {
|
||||
nodeId,
|
||||
trigger: 'kiro-step-9',
|
||||
});
|
||||
if (!contributionResult?.ok || contributionResult?.skipped) {
|
||||
throw new Error(contributionResult?.message || 'Kiro 贡献上传失败。');
|
||||
}
|
||||
|
||||
const uploadedAt = Date.now();
|
||||
const payload = await applyRuntimeState(currentState, {
|
||||
session: {
|
||||
currentStage: 'upload',
|
||||
lastError: '',
|
||||
},
|
||||
upload: {
|
||||
targetId: 'contribution',
|
||||
status: 'uploaded',
|
||||
error: '',
|
||||
credentialId: contributionResult.contributionId || '',
|
||||
lastMessage: contributionResult.message || '贡献上传成功',
|
||||
lastUploadedAt: uploadedAt,
|
||||
},
|
||||
});
|
||||
await log(`步骤 9:贡献上传完成,状态:${contributionResult.message || '贡献上传成功'}`, 'ok', nodeId);
|
||||
await completeNodeFromBackground(nodeId, payload);
|
||||
return;
|
||||
}
|
||||
|
||||
const targetId = resolveKiroTargetId(currentState);
|
||||
const targetConfig = resolveKiroTargetConfig(currentState, targetId);
|
||||
const baseUrl = normalizeKiroRsBaseUrl(targetConfig.baseUrl);
|
||||
|
||||
@@ -305,6 +305,7 @@
|
||||
'submit-signup-email': '注册并输入手机号',
|
||||
'fetch-signup-code': '获取手机验证码',
|
||||
});
|
||||
const KIRO_CONTRIBUTION_STEP_TITLE = '贡献上传';
|
||||
|
||||
function isPlusModeEnabled(options = {}) {
|
||||
return Boolean(options?.plusModeEnabled || options?.plusMode);
|
||||
@@ -415,6 +416,10 @@
|
||||
return step.title;
|
||||
}
|
||||
|
||||
function isKiroContributionModeEnabled(options = {}) {
|
||||
return Boolean(options?.accountContributionEnabled || options?.state?.accountContributionEnabled);
|
||||
}
|
||||
|
||||
const FLOW_DEFINITION_BUILDERS = Object.freeze({
|
||||
openai: {
|
||||
getAllSteps() {
|
||||
@@ -462,7 +467,10 @@
|
||||
getPlusPaymentStepTitle() {
|
||||
return '';
|
||||
},
|
||||
resolveStepTitle(step) {
|
||||
resolveStepTitle(step, options = {}) {
|
||||
if (step?.key === 'kiro-upload-credential' && isKiroContributionModeEnabled(options)) {
|
||||
return KIRO_CONTRIBUTION_STEP_TITLE;
|
||||
}
|
||||
return step?.title || '';
|
||||
},
|
||||
},
|
||||
|
||||
@@ -868,6 +868,9 @@ function getStepDefinitionsForMode(plusModeEnabled = false, options = {}) {
|
||||
const phoneSignupReloginAfterBindEmailEnabled = typeof options === 'string'
|
||||
? currentPhoneSignupReloginAfterBindEmailEnabled
|
||||
: Boolean(options.phoneSignupReloginAfterBindEmailEnabled ?? currentPhoneSignupReloginAfterBindEmailEnabled);
|
||||
const accountContributionEnabled = typeof options === 'string'
|
||||
? Boolean(typeof latestState !== 'undefined' ? latestState?.accountContributionEnabled : false)
|
||||
: Boolean(options.accountContributionEnabled ?? (typeof latestState !== 'undefined' ? latestState?.accountContributionEnabled : false));
|
||||
const activeFlowId = typeof options === 'string'
|
||||
? ((typeof latestState !== 'undefined' ? latestState?.activeFlowId : '') || defaultFlowId)
|
||||
: (options.activeFlowId || (typeof latestState !== 'undefined' ? latestState?.activeFlowId : '') || defaultFlowId);
|
||||
@@ -878,6 +881,7 @@ function getStepDefinitionsForMode(plusModeEnabled = false, options = {}) {
|
||||
plusAccountAccessStrategy: normalizePlusAccountAccessStrategy(rawPlusAccountAccessStrategy),
|
||||
signupMethod: normalizeSignupMethod(rawSignupMethod),
|
||||
phoneSignupReloginAfterBindEmailEnabled,
|
||||
accountContributionEnabled,
|
||||
}) || [])
|
||||
.sort((left, right) => {
|
||||
const leftOrder = Number.isFinite(left.order) ? left.order : left.id;
|
||||
@@ -903,6 +907,9 @@ function getWorkflowNodesForMode(plusModeEnabled = false, options = {}) {
|
||||
const phoneSignupReloginAfterBindEmailEnabled = typeof options === 'string'
|
||||
? currentPhoneSignupReloginAfterBindEmailEnabled
|
||||
: Boolean(options.phoneSignupReloginAfterBindEmailEnabled ?? currentPhoneSignupReloginAfterBindEmailEnabled);
|
||||
const accountContributionEnabled = typeof options === 'string'
|
||||
? Boolean(typeof latestState !== 'undefined' ? latestState?.accountContributionEnabled : false)
|
||||
: Boolean(options.accountContributionEnabled ?? (typeof latestState !== 'undefined' ? latestState?.accountContributionEnabled : false));
|
||||
const activeFlowId = typeof options === 'string'
|
||||
? ((typeof latestState !== 'undefined' ? latestState?.activeFlowId : '') || defaultFlowId)
|
||||
: (options.activeFlowId || (typeof latestState !== 'undefined' ? latestState?.activeFlowId : '') || defaultFlowId);
|
||||
@@ -913,6 +920,7 @@ function getWorkflowNodesForMode(plusModeEnabled = false, options = {}) {
|
||||
plusAccountAccessStrategy: normalizePlusAccountAccessStrategy(rawPlusAccountAccessStrategy),
|
||||
signupMethod: normalizeSignupMethod(rawSignupMethod),
|
||||
phoneSignupReloginAfterBindEmailEnabled,
|
||||
accountContributionEnabled,
|
||||
});
|
||||
if (Array.isArray(nodes) && nodes.length) {
|
||||
return nodes.slice().sort((left, right) => {
|
||||
@@ -980,6 +988,10 @@ function rebuildStepDefinitionState(plusModeEnabled = false, options = {}) {
|
||||
const phoneSignupReloginAfterBindEmailEnabled = typeof options === 'string'
|
||||
? currentPhoneSignupReloginAfterBindEmailEnabled
|
||||
: Boolean(options.phoneSignupReloginAfterBindEmailEnabled ?? currentPhoneSignupReloginAfterBindEmailEnabled);
|
||||
const accountContributionEnabled = Boolean(
|
||||
options.accountContributionEnabled
|
||||
?? (typeof latestState !== 'undefined' ? latestState?.accountContributionEnabled : false)
|
||||
);
|
||||
currentPlusPaymentMethod = normalizePlusPaymentMethod(rawPaymentMethod);
|
||||
currentPlusAccountAccessStrategy = normalizePlusAccountAccessStrategy(rawPlusAccountAccessStrategy);
|
||||
currentSignupMethod = normalizeSignupMethod(rawSignupMethod);
|
||||
@@ -998,6 +1010,7 @@ function rebuildStepDefinitionState(plusModeEnabled = false, options = {}) {
|
||||
plusAccountAccessStrategy: currentPlusAccountAccessStrategy,
|
||||
signupMethod: currentSignupMethod,
|
||||
phoneSignupReloginAfterBindEmailEnabled: currentPhoneSignupReloginAfterBindEmailEnabled,
|
||||
accountContributionEnabled,
|
||||
});
|
||||
const nextWorkflowNodes = typeof getWorkflowNodesForMode === 'function'
|
||||
? getWorkflowNodesForMode(currentPlusModeEnabled, {
|
||||
@@ -1006,6 +1019,7 @@ function rebuildStepDefinitionState(plusModeEnabled = false, options = {}) {
|
||||
plusAccountAccessStrategy: currentPlusAccountAccessStrategy,
|
||||
signupMethod: currentSignupMethod,
|
||||
phoneSignupReloginAfterBindEmailEnabled: currentPhoneSignupReloginAfterBindEmailEnabled,
|
||||
accountContributionEnabled,
|
||||
})
|
||||
: stepDefinitions.map((step) => ({
|
||||
nodeId: String(step.key || step.id || '').trim(),
|
||||
@@ -10170,6 +10184,10 @@ function syncStepDefinitionsForMode(plusModeEnabled = false, plusPaymentMethodOr
|
||||
? inputPhoneSignupReloginAfterBindEmail.checked
|
||||
: currentPhoneSignupReloginAfterBindEmailEnabled)
|
||||
);
|
||||
const nextAccountContributionEnabled = Boolean(
|
||||
options.accountContributionEnabled
|
||||
?? (typeof latestState !== 'undefined' ? latestState?.accountContributionEnabled : false)
|
||||
);
|
||||
const nextPaymentMethod = normalizePlusPaymentMethod(rawPaymentMethod);
|
||||
const nextActiveFlowId = String(
|
||||
options.activeFlowId
|
||||
@@ -10196,6 +10214,7 @@ function syncStepDefinitionsForMode(plusModeEnabled = false, plusPaymentMethodOr
|
||||
|| nextPlusAccountAccessStrategy !== currentPlusAccountAccessStrategy
|
||||
|| nextSignupMethod !== currentSignupMethod
|
||||
|| nextPhoneSignupReloginAfterBindEmailEnabled !== currentPhoneSignupReloginAfterBindEmailEnabled
|
||||
|| nextAccountContributionEnabled !== Boolean(typeof latestState !== 'undefined' ? latestState?.accountContributionEnabled : false)
|
||||
|| nextActiveFlowId !== currentFlowId
|
||||
|| paymentTitleChanged;
|
||||
if (!shouldRender) {
|
||||
@@ -10208,6 +10227,7 @@ function syncStepDefinitionsForMode(plusModeEnabled = false, plusPaymentMethodOr
|
||||
plusAccountAccessStrategy: nextPlusAccountAccessStrategy,
|
||||
signupMethod: nextSignupMethod,
|
||||
phoneSignupReloginAfterBindEmailEnabled: nextPhoneSignupReloginAfterBindEmailEnabled,
|
||||
accountContributionEnabled: nextAccountContributionEnabled,
|
||||
});
|
||||
renderStepsList();
|
||||
}
|
||||
@@ -10234,6 +10254,7 @@ function syncStepDefinitionsFromUiState(stateOverrides = {}) {
|
||||
plusAccountAccessStrategy: stepDefinitionState.plusAccountAccessStrategy,
|
||||
signupMethod: stepDefinitionState.signupMethod,
|
||||
phoneSignupReloginAfterBindEmailEnabled: Boolean(nextState?.phoneSignupReloginAfterBindEmailEnabled),
|
||||
accountContributionEnabled: Boolean(nextState?.accountContributionEnabled),
|
||||
});
|
||||
return stepDefinitionState;
|
||||
}
|
||||
@@ -10257,6 +10278,7 @@ function applySettingsState(state) {
|
||||
plusPaymentMethod: state?.plusPaymentMethod,
|
||||
signupMethod: stepDefinitionState.signupMethod,
|
||||
phoneSignupReloginAfterBindEmailEnabled: Boolean(state?.phoneSignupReloginAfterBindEmailEnabled),
|
||||
accountContributionEnabled: Boolean(state?.accountContributionEnabled),
|
||||
});
|
||||
}
|
||||
const fallbackIpProxyService = '711proxy';
|
||||
|
||||
@@ -171,6 +171,65 @@ test('kiro publisher reads latest kiro.rs key from background state instead of s
|
||||
assert.equal(completed[0].nodeId, 'kiro-upload-credential');
|
||||
});
|
||||
|
||||
test('kiro publisher routes step 9 through public contribution upload when contribution mode is enabled', async () => {
|
||||
const api = loadPublisherApi();
|
||||
const requests = [];
|
||||
const completed = [];
|
||||
let liveState = {
|
||||
activeFlowId: 'kiro',
|
||||
flowId: 'kiro',
|
||||
accountContributionEnabled: true,
|
||||
contributionAdapterId: 'kiro-builder-id',
|
||||
kiroTargetId: 'kiro-rs',
|
||||
kiroRuntime: {
|
||||
register: {
|
||||
email: 'aws-user@example.com',
|
||||
},
|
||||
desktopAuth: {
|
||||
region: 'us-east-1',
|
||||
clientId: 'client-001',
|
||||
clientSecret: 'secret-001',
|
||||
refreshToken: 'refresh-token-001',
|
||||
},
|
||||
upload: {
|
||||
targetId: 'kiro-rs',
|
||||
},
|
||||
},
|
||||
};
|
||||
const publisher = api.createKiroRsPublisher({
|
||||
addLog: async () => {},
|
||||
completeNodeFromBackground: async (nodeId, payload) => {
|
||||
completed.push({ nodeId, payload });
|
||||
},
|
||||
fetchImpl: async (url, options = {}) => {
|
||||
requests.push({ url, options });
|
||||
throw new Error('kiro.rs upload should not be called in contribution mode');
|
||||
},
|
||||
getState: async () => ({ ...liveState }),
|
||||
maybeSubmitFlowContribution: async (_state, options = {}) => ({
|
||||
ok: true,
|
||||
skipped: false,
|
||||
contributionId: 'kiro-contribution-009',
|
||||
message: `贡献链路成功:${options.trigger || 'unknown'}`,
|
||||
}),
|
||||
setState: async (updates = {}) => {
|
||||
liveState = { ...liveState, ...updates };
|
||||
},
|
||||
});
|
||||
|
||||
await publisher.executeKiroUploadCredential({
|
||||
nodeId: 'kiro-upload-credential',
|
||||
});
|
||||
|
||||
assert.equal(requests.length, 0);
|
||||
assert.equal(completed.length, 1);
|
||||
assert.equal(completed[0].nodeId, 'kiro-upload-credential');
|
||||
assert.equal(completed[0].payload.kiroRuntime.upload.targetId, 'contribution');
|
||||
assert.equal(completed[0].payload.kiroRuntime.upload.status, 'uploaded');
|
||||
assert.equal(completed[0].payload.kiroRuntime.upload.credentialId, 'kiro-contribution-009');
|
||||
assert.equal(completed[0].payload.kiroRuntime.upload.lastMessage, '贡献链路成功:kiro-step-9');
|
||||
});
|
||||
|
||||
test('kiro publisher trims api key and includes fallback Authorization header during connection check', async () => {
|
||||
const api = loadPublisherApi();
|
||||
const requests = [];
|
||||
|
||||
@@ -210,8 +210,10 @@ test('Kiro contribution adapter redacts server errors that echo submitted secret
|
||||
assert.equal(combined.includes('client-secret-super-long'), false);
|
||||
});
|
||||
|
||||
test('Kiro desktop authorization runner is wired to submit public contribution after step 8', () => {
|
||||
const source = fs.readFileSync('background/kiro/desktop-authorize-runner.js', 'utf8');
|
||||
assert.match(source, /maybeSubmitFlowContribution/);
|
||||
assert.match(source, /trigger:\s*'kiro-step-8'/);
|
||||
test('Kiro public contribution is triggered from step 9 instead of step 8', () => {
|
||||
const desktopSource = fs.readFileSync('background/kiro/desktop-authorize-runner.js', 'utf8');
|
||||
const publisherSource = fs.readFileSync('background/kiro/publisher-kiro-rs.js', 'utf8');
|
||||
assert.doesNotMatch(desktopSource, /trigger:\s*'kiro-step-8'/);
|
||||
assert.match(publisherSource, /maybeSubmitFlowContribution/);
|
||||
assert.match(publisherSource, /trigger:\s*'kiro-step-9'/);
|
||||
});
|
||||
|
||||
@@ -190,6 +190,8 @@ test('step definitions module exposes ordered normal and Plus step metadata', ()
|
||||
assert.equal(kiroSteps[6].title, '启动桌面授权');
|
||||
assert.equal(kiroSteps[7].title, '完成桌面授权');
|
||||
assert.equal(kiroSteps[8].title, '上传凭据到 kiro.rs');
|
||||
const kiroContributionSteps = api.getSteps({ activeFlowId: 'kiro', accountContributionEnabled: true });
|
||||
assert.equal(kiroContributionSteps[8].title, '贡献上传');
|
||||
assert.deepStrictEqual(api.getStepIds({ activeFlowId: 'kiro' }), [1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
||||
assert.equal(api.getLastStepId({ activeFlowId: 'kiro' }), 9);
|
||||
assert.deepStrictEqual(
|
||||
|
||||
Reference in New Issue
Block a user