forkit-connect 0.1.10 → 0.1.11
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/cli.js +31 -18
- package/dist/launcher.js +183 -90
- package/dist/v1/service.d.ts +1 -0
- package/dist/v1/service.js +16 -6
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -942,7 +942,7 @@ function buildInteractiveOverviewSections(service, sessionState, accountLimits)
|
|
|
942
942
|
sections.push({
|
|
943
943
|
title: 'Inbox',
|
|
944
944
|
lines: [
|
|
945
|
-
shellLine('
|
|
945
|
+
shellLine('Private review', overview.draft_first_count),
|
|
946
946
|
shellLine('Ready to connect', otherReadyCount),
|
|
947
947
|
shellLine('Needs confirmation', overview.needs_confirmation_count),
|
|
948
948
|
shellLine('Connected', overview.connected_count),
|
|
@@ -972,7 +972,7 @@ function buildInteractiveOverviewSections(service, sessionState, accountLimits)
|
|
|
972
972
|
lines: [
|
|
973
973
|
shellLine('Workspace', formatScopeReferenceLabel(preparedWorkspace || null, 'workspace')),
|
|
974
974
|
shellLine('Project', formatScopeReferenceLabel(preparedProject || null, 'project')),
|
|
975
|
-
shellLine('
|
|
975
|
+
shellLine('Private review', overview.draft_first_count),
|
|
976
976
|
shellLine('Ready to connect', otherReadyCount),
|
|
977
977
|
shellLine('Needs confirmation', overview.needs_confirmation_count),
|
|
978
978
|
],
|
|
@@ -1433,7 +1433,7 @@ function formatSmartInboxActionLabel(item) {
|
|
|
1433
1433
|
if (item.item_type === 'model'
|
|
1434
1434
|
&& item.recommended_action === 'create_passport_draft'
|
|
1435
1435
|
&& String(item.details_received_automatically.registration_flow_state || '').trim() === 'private_draft_required') {
|
|
1436
|
-
return '
|
|
1436
|
+
return 'Continue Registration';
|
|
1437
1437
|
}
|
|
1438
1438
|
return formatSmartInboxActionValue(item.recommended_action, item.item_type, String(item.details_received_automatically.connectable_model_name || '').trim());
|
|
1439
1439
|
}
|
|
@@ -1488,7 +1488,7 @@ function printPublicStatusOverview(status) {
|
|
|
1488
1488
|
console.log(`- scope=${status.workspace_id && status.project_id ? `${status.workspace_id} / ${status.project_id}` : 'not selected'}`);
|
|
1489
1489
|
console.log(`- daemon=${status.daemon_status}`);
|
|
1490
1490
|
console.log(`- local inventory=models ${status.models_discovered} · agents ${status.agents_discovered} · runtimes ${status.runtimes_discovered}`);
|
|
1491
|
-
console.log(`- review queue=
|
|
1491
|
+
console.log(`- review queue=private review ${status.draft_first_count} · ready ${otherReadyCount} · needs review ${status.needs_confirmation_count}`);
|
|
1492
1492
|
console.log(`- connected records=${status.connected_count}`);
|
|
1493
1493
|
console.log(`- pending runtime sync=${status.c2_sync_pending}`);
|
|
1494
1494
|
console.log(`- privacy=${status.privacy_mode}`);
|
|
@@ -2131,7 +2131,7 @@ async function run() {
|
|
|
2131
2131
|
{
|
|
2132
2132
|
title: 'Queue',
|
|
2133
2133
|
lines: [
|
|
2134
|
-
shellLine('
|
|
2134
|
+
shellLine('Private review', payload.draft_first_count),
|
|
2135
2135
|
shellLine('Ready to connect', otherReadyCount),
|
|
2136
2136
|
shellLine('Needs confirmation', payload.needs_confirmation_count),
|
|
2137
2137
|
shellLine('Connected', payload.connected_count),
|
|
@@ -3892,11 +3892,11 @@ async function run() {
|
|
|
3892
3892
|
if (raw === 'MODEL_SELECTION_AMBIGUOUS')
|
|
3893
3893
|
return 'Model selection is ambiguous. Use a full discoveryHash.';
|
|
3894
3894
|
if (raw === 'DRAFT_ALREADY_EXISTS')
|
|
3895
|
-
return '
|
|
3895
|
+
return 'Registration is already started privately for this model. No duplicate registration was created.';
|
|
3896
3896
|
if (raw === 'SIMILAR_PASSPORT_EXISTS')
|
|
3897
|
-
return 'A similar or existing passport already exists in your Forkit.dev account. Review existing records before creating
|
|
3897
|
+
return 'A similar or existing passport already exists in your Forkit.dev account. Review existing records before creating another registration.';
|
|
3898
3898
|
if (raw === 'INVALID_DRAFT_VISIBILITY')
|
|
3899
|
-
return '
|
|
3899
|
+
return 'Forkit needs one private review step before this passport can finish publishing. Continue the registration from inbox/start first.';
|
|
3900
3900
|
if (raw === 'WORKSPACE_PROJECT_BINDING_REQUIRED')
|
|
3901
3901
|
return 'No governed workspace/project scope is linked yet. Select or create scope first.';
|
|
3902
3902
|
if (raw === 'DRAFT_CREATION_NOT_ALLOWED_BY_BINDING')
|
|
@@ -3907,13 +3907,13 @@ async function run() {
|
|
|
3907
3907
|
if (action === 'already_bound')
|
|
3908
3908
|
return 'Model is already connected to an existing passport.';
|
|
3909
3909
|
if (action === 'already_pending')
|
|
3910
|
-
return '
|
|
3910
|
+
return 'Registration already started privately. No duplicate registration was created.';
|
|
3911
3911
|
if (action === 'passport_registered')
|
|
3912
|
-
return 'Passport
|
|
3912
|
+
return 'Passport registered successfully.';
|
|
3913
3913
|
if (action === 'draft_created')
|
|
3914
|
-
return '
|
|
3914
|
+
return 'Private review started. Continue registration from inbox/start.';
|
|
3915
3915
|
if (action === 'draft_queued')
|
|
3916
|
-
return '
|
|
3916
|
+
return 'Registration saved locally and will sync when backend access is available.';
|
|
3917
3917
|
return action;
|
|
3918
3918
|
};
|
|
3919
3919
|
const accountLimits = await loadCliAccountLimits().catch(() => null);
|
|
@@ -3937,7 +3937,9 @@ async function run() {
|
|
|
3937
3937
|
});
|
|
3938
3938
|
const runRegisterOne = async (targetModelSelector, displayNameHint) => {
|
|
3939
3939
|
try {
|
|
3940
|
-
const result = await service.connectDetectedModel(targetModelSelector)
|
|
3940
|
+
const result = await service.connectDetectedModel(targetModelSelector, hasFlag('--draft-only')
|
|
3941
|
+
? { destination: 'draft', visibility: 'private' }
|
|
3942
|
+
: { destination: 'passport', visibility: 'public' });
|
|
3941
3943
|
return {
|
|
3942
3944
|
ok: true,
|
|
3943
3945
|
model: result.model.model,
|
|
@@ -4501,7 +4503,10 @@ async function run() {
|
|
|
4501
4503
|
return;
|
|
4502
4504
|
}
|
|
4503
4505
|
try {
|
|
4504
|
-
const result = await service.connectDetectedModel(selector
|
|
4506
|
+
const result = await service.connectDetectedModel(selector, {
|
|
4507
|
+
destination: 'passport',
|
|
4508
|
+
visibility: 'public',
|
|
4509
|
+
});
|
|
4505
4510
|
if (result.action === 'already_bound') {
|
|
4506
4511
|
console.log('Model is already bound to a Passport.');
|
|
4507
4512
|
if (result.gaid) {
|
|
@@ -4510,14 +4515,22 @@ async function run() {
|
|
|
4510
4515
|
return;
|
|
4511
4516
|
}
|
|
4512
4517
|
if (result.action === 'already_pending') {
|
|
4513
|
-
console.log('
|
|
4518
|
+
console.log('Registration already started privately for this model.');
|
|
4514
4519
|
if (result.draftId) {
|
|
4515
4520
|
console.log(`Draft ID: ${result.draftId}`);
|
|
4516
4521
|
}
|
|
4517
4522
|
return;
|
|
4518
4523
|
}
|
|
4524
|
+
if (result.action === 'passport_registered') {
|
|
4525
|
+
console.log('Passport registered successfully.');
|
|
4526
|
+
console.log(`Model: ${result.model.model}`);
|
|
4527
|
+
if (result.gaid) {
|
|
4528
|
+
console.log(`Passport GAID: ${result.gaid}`);
|
|
4529
|
+
}
|
|
4530
|
+
return;
|
|
4531
|
+
}
|
|
4519
4532
|
if (result.action === 'draft_created') {
|
|
4520
|
-
console.log('
|
|
4533
|
+
console.log('Registration started privately for review.');
|
|
4521
4534
|
console.log(`Model: ${result.model.model}`);
|
|
4522
4535
|
if (result.draftId) {
|
|
4523
4536
|
console.log(`Draft ID: ${result.draftId}`);
|
|
@@ -4527,9 +4540,9 @@ async function run() {
|
|
|
4527
4540
|
}
|
|
4528
4541
|
return;
|
|
4529
4542
|
}
|
|
4530
|
-
console.log('
|
|
4543
|
+
console.log('Registration saved locally and will sync when Forkit Connect can reach Forkit.dev.');
|
|
4531
4544
|
console.log(`Model: ${result.model.model}`);
|
|
4532
|
-
console.log('Complete login later and run scan or queue processing to
|
|
4545
|
+
console.log('Complete login later and run scan or queue processing to continue it.');
|
|
4533
4546
|
return;
|
|
4534
4547
|
}
|
|
4535
4548
|
catch (error) {
|
package/dist/launcher.js
CHANGED
|
@@ -434,7 +434,7 @@ function formatBindingStatusLabel(status) {
|
|
|
434
434
|
return { label: 'Published', meta: 'Live on Forkit.dev', tone: 'ok' };
|
|
435
435
|
}
|
|
436
436
|
if (normalized === 'pending') {
|
|
437
|
-
return { label: '
|
|
437
|
+
return { label: 'Private review', meta: 'In progress', tone: 'warn' };
|
|
438
438
|
}
|
|
439
439
|
if (normalized === 'ignored') {
|
|
440
440
|
return { label: 'Archived', meta: 'Not active locally', tone: 'muted' };
|
|
@@ -449,7 +449,7 @@ function formatPassportHistoryLabel(type) {
|
|
|
449
449
|
return { label: 'Passport linked', tone: 'ok' };
|
|
450
450
|
case 'model_draft_created':
|
|
451
451
|
case 'model_draft_synced':
|
|
452
|
-
return { label: '
|
|
452
|
+
return { label: 'Private review started', tone: 'warn' };
|
|
453
453
|
case 'passport_draft_requested':
|
|
454
454
|
case 'model_draft_queued':
|
|
455
455
|
return { label: 'Registration queued', tone: 'warn' };
|
|
@@ -538,10 +538,10 @@ function normalizeDiscoveryRegistrationFailure(message) {
|
|
|
538
538
|
if (normalized === 'INVALID_DRAFT_VISIBILITY') {
|
|
539
539
|
return {
|
|
540
540
|
code: normalized,
|
|
541
|
-
message: '
|
|
541
|
+
message: 'Forkit needs one private review step before this passport can finish publishing.',
|
|
542
542
|
nextActions: [
|
|
543
|
-
'
|
|
544
|
-
'
|
|
543
|
+
'Continue registration privately first.',
|
|
544
|
+
'Publish only after Forkit has finished the private review step.',
|
|
545
545
|
],
|
|
546
546
|
};
|
|
547
547
|
}
|
|
@@ -694,17 +694,17 @@ function buildDiscovery(service) {
|
|
|
694
694
|
actionTone = 'muted';
|
|
695
695
|
}
|
|
696
696
|
else if (draftPending) {
|
|
697
|
-
statusLabel = '
|
|
698
|
-
statusMeta = '
|
|
697
|
+
statusLabel = 'Registration in progress';
|
|
698
|
+
statusMeta = 'Forkit already started this privately. Continue it in Passports instead of starting over.';
|
|
699
699
|
statusTone = 'warn';
|
|
700
|
-
actionLabel = '
|
|
700
|
+
actionLabel = 'Continue';
|
|
701
701
|
actionTone = 'accent';
|
|
702
702
|
}
|
|
703
703
|
else if (registrationState === 'private_draft_required') {
|
|
704
|
-
statusLabel = '
|
|
705
|
-
statusMeta = registrationGuidance ?? '
|
|
704
|
+
statusLabel = 'Finish privately first';
|
|
705
|
+
statusMeta = registrationGuidance ?? 'Forkit needs one private review step before this passport can finish publishing.';
|
|
706
706
|
statusTone = 'warn';
|
|
707
|
-
actionLabel = '
|
|
707
|
+
actionLabel = 'Continue';
|
|
708
708
|
actionTone = 'accent';
|
|
709
709
|
}
|
|
710
710
|
else if (group === 'connected') {
|
|
@@ -741,6 +741,7 @@ function buildDiscovery(service) {
|
|
|
741
741
|
recommendedAction: entry.recommended_action,
|
|
742
742
|
workspaceId: entry.workspaceId,
|
|
743
743
|
projectId: entry.projectId,
|
|
744
|
+
draftId: binding?.draftId ?? null,
|
|
744
745
|
passportGaid: entry.passport_gaid,
|
|
745
746
|
matchedPassportGaid: entry.matched_passport_gaid,
|
|
746
747
|
detailSummary: verificationSummary ?? scopeSuggestion ?? matchReason,
|
|
@@ -791,10 +792,10 @@ function buildDiscovery(service) {
|
|
|
791
792
|
actionTone = 'accent';
|
|
792
793
|
}
|
|
793
794
|
else if (draftId || trackingStatus === 'draft_created') {
|
|
794
|
-
statusLabel = '
|
|
795
|
-
statusMeta = '
|
|
795
|
+
statusLabel = 'Registration in progress';
|
|
796
|
+
statusMeta = 'Forkit already started this privately. Continue it in Passports.';
|
|
796
797
|
statusTone = 'warn';
|
|
797
|
-
actionLabel = '
|
|
798
|
+
actionLabel = 'Continue';
|
|
798
799
|
actionTone = 'accent';
|
|
799
800
|
}
|
|
800
801
|
else if (group === 'connected' || linkedPassportGaid) {
|
|
@@ -835,6 +836,7 @@ function buildDiscovery(service) {
|
|
|
835
836
|
recommendedAction: entry.recommended_action,
|
|
836
837
|
workspaceId: entry.workspaceId,
|
|
837
838
|
projectId: entry.projectId,
|
|
839
|
+
draftId,
|
|
838
840
|
passportGaid: linkedPassportGaid,
|
|
839
841
|
matchedPassportGaid: entry.matched_passport_gaid,
|
|
840
842
|
detailSummary: statusMeta,
|
|
@@ -929,7 +931,7 @@ function buildDiscovery(service) {
|
|
|
929
931
|
localDetection: state.detected_runtimes.length > 0 || state.detected_models.length > 0 ? 'active' : 'attention',
|
|
930
932
|
metadataExtraction: state.detected_models.length > 0 ? 'active' : 'attention',
|
|
931
933
|
duplicateMatching: inbox.existing_passport_match_candidates.length > 0 || state.model_bindings.length > 0 ? 'active' : 'attention',
|
|
932
|
-
passportReadiness: `${draftFirstCount}
|
|
934
|
+
passportReadiness: `${draftFirstCount} private review · ${otherReadyCount} ready · ${inbox.summary.needs_confirmation_count} review · ${inbox.summary.connected_count} linked`,
|
|
933
935
|
},
|
|
934
936
|
groups: {
|
|
935
937
|
ready_to_connect: inbox.groups.ready_to_connect.length,
|
|
@@ -6454,7 +6456,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
6454
6456
|
<div class="quick-review-summary-grid">
|
|
6455
6457
|
<div class="quick-review-summary-pill">
|
|
6456
6458
|
<span class="quick-review-summary-label">Action</span>
|
|
6457
|
-
<span class="quick-review-summary-value" id="quick-review-action-summary">
|
|
6459
|
+
<span class="quick-review-summary-value" id="quick-review-action-summary">Register on this account now</span>
|
|
6458
6460
|
</div>
|
|
6459
6461
|
<div class="quick-review-summary-pill">
|
|
6460
6462
|
<span class="quick-review-summary-label">Scope</span>
|
|
@@ -7252,7 +7254,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7252
7254
|
<div class="scope-modal-backdrop" id="scope-modal" hidden>
|
|
7253
7255
|
<div class="scope-modal" role="dialog" aria-modal="true" aria-labelledby="scope-modal-title">
|
|
7254
7256
|
<h3 id="scope-modal-title">Choose registration scope</h3>
|
|
7255
|
-
<p id="scope-modal-copy">
|
|
7257
|
+
<p id="scope-modal-copy">Register on your account now, or choose a governed workspace/project when you need governed ownership.</p>
|
|
7256
7258
|
<div class="scope-field-grid">
|
|
7257
7259
|
<div class="scope-field">
|
|
7258
7260
|
<label for="scope-workspace-select">Workspace</label>
|
|
@@ -7400,9 +7402,53 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7400
7402
|
return true;
|
|
7401
7403
|
}
|
|
7402
7404
|
|
|
7405
|
+
function focusPassportByDraftId(draftId, options) {
|
|
7406
|
+
const normalizedDraftId = String(draftId || '').trim();
|
|
7407
|
+
if (!normalizedDraftId) return false;
|
|
7408
|
+
const passports = latestPassports && Array.isArray(latestPassports.items) ? latestPassports.items : [];
|
|
7409
|
+
const match = passports.find((entry) => String(entry.draftId || '').trim() === normalizedDraftId);
|
|
7410
|
+
if (!match) return false;
|
|
7411
|
+
selectedPassportId = match.id;
|
|
7412
|
+
passportHistoryVisible = Boolean(options && options.showHistory);
|
|
7413
|
+
selectedWorkspaceScope = ALL_SCOPE_VALUE;
|
|
7414
|
+
selectedProjectScope = ALL_SCOPE_VALUE;
|
|
7415
|
+
renderGlobalLaunchHeaderAndCards();
|
|
7416
|
+
setView('passports', { skipRouteUpdate: true });
|
|
7417
|
+
renderPassportsRows();
|
|
7418
|
+
updateRoute('passports', { passport: match.gaid || match.id, ...(passportHistoryVisible ? { focus: 'history' } : {}) });
|
|
7419
|
+
return true;
|
|
7420
|
+
}
|
|
7421
|
+
|
|
7422
|
+
function getReviewScopeMode(workspaceId, projectId) {
|
|
7423
|
+
return String(workspaceId || '').trim() && String(projectId || '').trim() ? 'workspace' : 'solo';
|
|
7424
|
+
}
|
|
7425
|
+
|
|
7426
|
+
function isContinuationReviewItem(item) {
|
|
7427
|
+
return Boolean(item && (
|
|
7428
|
+
item.actionLabel === 'Continue'
|
|
7429
|
+
|| item.statusLabel === 'Registration in progress'
|
|
7430
|
+
|| item.statusLabel === 'Finish privately first'
|
|
7431
|
+
));
|
|
7432
|
+
}
|
|
7433
|
+
|
|
7434
|
+
function shouldOpenReviewContext(item) {
|
|
7435
|
+
return Boolean(
|
|
7436
|
+
item
|
|
7437
|
+
&& (
|
|
7438
|
+
item.kind === 'runtime'
|
|
7439
|
+
|| item.passportGaid
|
|
7440
|
+
|| item.matchedPassportGaid
|
|
7441
|
+
|| item.actionLabel === 'Open'
|
|
7442
|
+
|| item.actionLabel === 'Review'
|
|
7443
|
+
|| isContinuationReviewItem(item)
|
|
7444
|
+
)
|
|
7445
|
+
);
|
|
7446
|
+
}
|
|
7447
|
+
|
|
7403
7448
|
async function openDiscoveryContext(item) {
|
|
7404
7449
|
if (!item) return false;
|
|
7405
7450
|
const preferredPassportGaid = String(item.passportGaid || item.matchedPassportGaid || '').trim();
|
|
7451
|
+
const preferredDraftId = String(item.draftId || '').trim();
|
|
7406
7452
|
if (preferredPassportGaid) {
|
|
7407
7453
|
if (!latestPassports) {
|
|
7408
7454
|
await refreshPassports();
|
|
@@ -7411,6 +7457,14 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7411
7457
|
return true;
|
|
7412
7458
|
}
|
|
7413
7459
|
}
|
|
7460
|
+
if (preferredDraftId) {
|
|
7461
|
+
if (!latestPassports) {
|
|
7462
|
+
await refreshPassports();
|
|
7463
|
+
}
|
|
7464
|
+
if (focusPassportByDraftId(preferredDraftId, { showHistory: true })) {
|
|
7465
|
+
return true;
|
|
7466
|
+
}
|
|
7467
|
+
}
|
|
7414
7468
|
if (item.kind === 'model' || item.kind === 'agent') {
|
|
7415
7469
|
await openRegistrationScopeDialog(item);
|
|
7416
7470
|
return true;
|
|
@@ -7514,13 +7568,14 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7514
7568
|
].map((value) => String(value || '').trim()).find(Boolean) || '';
|
|
7515
7569
|
}
|
|
7516
7570
|
|
|
7517
|
-
function getReviewPrimaryLabel(item) {
|
|
7571
|
+
function getReviewPrimaryLabel(item, scopeMode) {
|
|
7572
|
+
const effectiveScopeMode = scopeMode === 'workspace' ? 'workspace' : 'solo';
|
|
7518
7573
|
if (!item) return 'Review';
|
|
7519
7574
|
if (item.kind === 'runtime') {
|
|
7520
7575
|
return item.statusTone === 'error' ? 'Open runtime fix' : 'Open runtime review';
|
|
7521
7576
|
}
|
|
7522
|
-
if (item
|
|
7523
|
-
return '
|
|
7577
|
+
if (isContinuationReviewItem(item)) {
|
|
7578
|
+
return 'Continue registration';
|
|
7524
7579
|
}
|
|
7525
7580
|
if (item.passportGaid) {
|
|
7526
7581
|
return 'Open passport';
|
|
@@ -7534,16 +7589,17 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7534
7589
|
if (item.actionLabel === 'Open' || item.actionLabel === 'Review') {
|
|
7535
7590
|
return 'Review in context';
|
|
7536
7591
|
}
|
|
7537
|
-
return '
|
|
7592
|
+
return effectiveScopeMode === 'workspace' ? 'Register in workspace' : 'Register solo';
|
|
7538
7593
|
}
|
|
7539
7594
|
|
|
7540
|
-
function getReviewActionSummary(item) {
|
|
7595
|
+
function getReviewActionSummary(item, scopeMode) {
|
|
7596
|
+
const effectiveScopeMode = scopeMode === 'workspace' ? 'workspace' : 'solo';
|
|
7541
7597
|
if (!item) return 'Review';
|
|
7542
7598
|
if (item.kind === 'runtime') {
|
|
7543
7599
|
return item.statusTone === 'error' ? 'Resolve runtime attention' : 'Open runtime lane';
|
|
7544
7600
|
}
|
|
7545
|
-
if (item
|
|
7546
|
-
return 'Continue the
|
|
7601
|
+
if (isContinuationReviewItem(item)) {
|
|
7602
|
+
return 'Continue the private review step before this passport finishes publishing';
|
|
7547
7603
|
}
|
|
7548
7604
|
if (item.passportGaid) {
|
|
7549
7605
|
return 'Open the linked passport';
|
|
@@ -7557,7 +7613,9 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7557
7613
|
if (item.actionLabel === 'Open' || item.actionLabel === 'Review') {
|
|
7558
7614
|
return 'Open full review';
|
|
7559
7615
|
}
|
|
7560
|
-
return
|
|
7616
|
+
return effectiveScopeMode === 'workspace'
|
|
7617
|
+
? 'Register this item in the selected workspace'
|
|
7618
|
+
: 'Register this item on your account now';
|
|
7561
7619
|
}
|
|
7562
7620
|
|
|
7563
7621
|
function getReviewDetailText(item) {
|
|
@@ -7567,8 +7625,11 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7567
7625
|
? 'Runtime attention is required before linked models can keep registering cleanly.'
|
|
7568
7626
|
: 'Open runtime review to confirm health, scope, and connected models.';
|
|
7569
7627
|
}
|
|
7570
|
-
if (item.statusLabel === '
|
|
7571
|
-
return '
|
|
7628
|
+
if (item.statusLabel === 'Registration in progress') {
|
|
7629
|
+
return 'Forkit already started this registration privately. Continue it in Passports instead of creating a second record.';
|
|
7630
|
+
}
|
|
7631
|
+
if (item.statusLabel === 'Finish privately first') {
|
|
7632
|
+
return 'Forkit needs one private review step before it can publish this passport. Continue registration and finish the private step first.';
|
|
7572
7633
|
}
|
|
7573
7634
|
if (item.matchedPassportGaid && !item.passportGaid) {
|
|
7574
7635
|
return 'Forkit Connect found a matching passport. Reuse it before creating anything new.';
|
|
@@ -7608,7 +7669,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7608
7669
|
: result && result.code === 'SIMILAR_PASSPORT_EXISTS'
|
|
7609
7670
|
? 'Matching passport exists · reuse it instead of creating another'
|
|
7610
7671
|
: result && result.code === 'INVALID_DRAFT_VISIBILITY'
|
|
7611
|
-
? '
|
|
7672
|
+
? 'Private review first · continue registration privately before publishing'
|
|
7612
7673
|
: result && (result.code === 'WORKSPACE_PROJECT_BINDING_REQUIRED' || result.code === 'DRAFT_CREATION_NOT_ALLOWED_BY_BINDING')
|
|
7613
7674
|
? 'Scope required · choose workspace and project'
|
|
7614
7675
|
: null,
|
|
@@ -7751,8 +7812,8 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7751
7812
|
const primaryButton = document.getElementById('quick-review-primary');
|
|
7752
7813
|
if (!projectSelect) return;
|
|
7753
7814
|
if (!workspaceId) {
|
|
7754
|
-
setScopeOptions(projectSelect, [{ id: '', label:
|
|
7755
|
-
if (primaryButton) primaryButton.disabled =
|
|
7815
|
+
setScopeOptions(projectSelect, [{ id: '', label: 'Solo registration / no project' }], '');
|
|
7816
|
+
if (primaryButton) primaryButton.disabled = false;
|
|
7756
7817
|
updateQuickReviewScopeSummary(governedMode);
|
|
7757
7818
|
return;
|
|
7758
7819
|
}
|
|
@@ -7818,10 +7879,10 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7818
7879
|
setQuickReviewStatus(item.statusLabel + (item.statusMeta ? ' · ' + item.statusMeta : ''), item.statusTone === 'muted' ? '' : item.statusTone);
|
|
7819
7880
|
resetReviewResolutionActions('quick-review');
|
|
7820
7881
|
|
|
7821
|
-
const primaryLabel = getReviewPrimaryLabel(item);
|
|
7882
|
+
const primaryLabel = getReviewPrimaryLabel(item, 'solo');
|
|
7822
7883
|
setText(
|
|
7823
7884
|
'quick-review-action-summary',
|
|
7824
|
-
getReviewActionSummary(item),
|
|
7885
|
+
getReviewActionSummary(item, 'solo'),
|
|
7825
7886
|
);
|
|
7826
7887
|
if (primaryButton) {
|
|
7827
7888
|
primaryButton.textContent = primaryLabel;
|
|
@@ -7863,27 +7924,32 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7863
7924
|
const response = await apiFetch('/api/scope/access');
|
|
7864
7925
|
const payload = await response.json();
|
|
7865
7926
|
scopeAccessSnapshot = payload;
|
|
7866
|
-
const governedMode = payload && payload.operatingMode === 'governed';
|
|
7927
|
+
const governedMode = Boolean(payload && payload.operatingMode === 'governed');
|
|
7867
7928
|
const workspaces = payload.ok && Array.isArray(payload.workspaces) ? payload.workspaces : [];
|
|
7868
7929
|
const options = [
|
|
7869
|
-
|
|
7930
|
+
{ id: '', label: 'Register solo / account scope' },
|
|
7870
7931
|
...workspaces.map((workspace) => ({ id: workspace.id, label: workspace.name || workspace.id })),
|
|
7871
7932
|
];
|
|
7872
|
-
|
|
7873
|
-
options.push({ id: '', label: 'No governed workspaces yet' });
|
|
7874
|
-
}
|
|
7875
|
-
const selectedWorkspace = item.workspaceId || payload.currentWorkspaceId || (options[0] && options[0].id) || '';
|
|
7933
|
+
const selectedWorkspace = item.workspaceId || '';
|
|
7876
7934
|
setScopeOptions(workspaceSelect, options, selectedWorkspace);
|
|
7877
7935
|
await loadQuickReviewProjects(selectedWorkspace, item.projectId || payload.currentProjectId || '', governedMode);
|
|
7936
|
+
const reviewScopeMode = getReviewScopeMode(
|
|
7937
|
+
selectedWorkspace,
|
|
7938
|
+
item.projectId || payload.currentProjectId || '',
|
|
7939
|
+
);
|
|
7878
7940
|
setQuickReviewStatus(
|
|
7879
7941
|
payload.ok
|
|
7880
|
-
? (
|
|
7942
|
+
? (reviewScopeMode === 'workspace'
|
|
7881
7943
|
? 'Choose the governed workspace and project for this registration.'
|
|
7882
|
-
: '
|
|
7944
|
+
: 'Solo registration is ready. Choose governed scope only when needed.')
|
|
7883
7945
|
: (payload.message || 'Workspace access is unavailable right now.'),
|
|
7884
7946
|
payload.ok ? '' : 'warn',
|
|
7885
7947
|
);
|
|
7886
7948
|
updateQuickReviewScopeSummary(governedMode);
|
|
7949
|
+
if (primaryButton) {
|
|
7950
|
+
primaryButton.textContent = getReviewPrimaryLabel(item, reviewScopeMode);
|
|
7951
|
+
}
|
|
7952
|
+
setText('quick-review-action-summary', getReviewActionSummary(item, reviewScopeMode));
|
|
7887
7953
|
} catch {
|
|
7888
7954
|
setScopeOptions(workspaceSelect, [{ id: '', label: 'Workspace list unavailable' }], '');
|
|
7889
7955
|
setScopeOptions(projectSelect, [{ id: '', label: 'Project list unavailable' }], '');
|
|
@@ -7899,7 +7965,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7899
7965
|
const item = getQuickReviewItem();
|
|
7900
7966
|
if (!item) return;
|
|
7901
7967
|
selectedDiscoveryId = item.id;
|
|
7902
|
-
if (item
|
|
7968
|
+
if (shouldOpenReviewContext(item)) {
|
|
7903
7969
|
await openDiscoveryContext(item);
|
|
7904
7970
|
setQuickReviewPanelOpen(false);
|
|
7905
7971
|
return;
|
|
@@ -7913,15 +7979,11 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7913
7979
|
const primaryButton = document.getElementById('quick-review-primary');
|
|
7914
7980
|
const workspaceId = workspaceSelect ? String(workspaceSelect.value || '').trim() : '';
|
|
7915
7981
|
const projectId = projectSelect ? String(projectSelect.value || '').trim() : '';
|
|
7916
|
-
const governedMode = scopeAccessSnapshot && scopeAccessSnapshot.operatingMode === 'governed';
|
|
7982
|
+
const governedMode = Boolean(scopeAccessSnapshot && scopeAccessSnapshot.operatingMode === 'governed');
|
|
7917
7983
|
if (workspaceId && !projectId) {
|
|
7918
7984
|
setQuickReviewStatus('Select a project for the chosen workspace, or switch back to account scope.', 'warn');
|
|
7919
7985
|
return;
|
|
7920
7986
|
}
|
|
7921
|
-
if (!workspaceId && governedMode) {
|
|
7922
|
-
setQuickReviewStatus('Choose the governed workspace and project before registering here.', 'warn');
|
|
7923
|
-
return;
|
|
7924
|
-
}
|
|
7925
7987
|
if (primaryButton) primaryButton.disabled = true;
|
|
7926
7988
|
const endpoint = item.kind === 'agent' ? '/api/discovery/connect-agent' : '/api/discovery/connect-model';
|
|
7927
7989
|
const result = await postAction(endpoint, 'Registering with Forkit Connect...', {
|
|
@@ -8000,8 +8062,8 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8000
8062
|
const primaryButton = document.getElementById('discovery-review-primary');
|
|
8001
8063
|
if (!projectSelect) return;
|
|
8002
8064
|
if (!workspaceId) {
|
|
8003
|
-
setScopeOptions(projectSelect, [{ id: '', label:
|
|
8004
|
-
if (primaryButton) primaryButton.disabled =
|
|
8065
|
+
setScopeOptions(projectSelect, [{ id: '', label: 'Solo registration / no project' }], '');
|
|
8066
|
+
if (primaryButton) primaryButton.disabled = false;
|
|
8005
8067
|
return;
|
|
8006
8068
|
}
|
|
8007
8069
|
setScopeOptions(projectSelect, [{ id: '', label: 'Loading projects...' }], '');
|
|
@@ -8050,7 +8112,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8050
8112
|
|
|
8051
8113
|
const typeLabel = item.typeLabel || item.kind;
|
|
8052
8114
|
const needsScope = canReviewRegister(item);
|
|
8053
|
-
const primaryLabel = getReviewPrimaryLabel(item);
|
|
8115
|
+
const primaryLabel = getReviewPrimaryLabel(item, 'solo');
|
|
8054
8116
|
|
|
8055
8117
|
setText('discovery-review-kicker', typeLabel);
|
|
8056
8118
|
setText('discovery-review-title', item.name);
|
|
@@ -8059,7 +8121,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8059
8121
|
setDiscoveryReviewStatus(item.statusLabel + (item.statusMeta ? ' · ' + item.statusMeta : ''), item.statusTone === 'muted' ? '' : item.statusTone);
|
|
8060
8122
|
resetReviewResolutionActions('discovery-review');
|
|
8061
8123
|
setDiscoveryReviewButtons({
|
|
8062
|
-
primaryLabel: getReviewPrimaryLabel(item),
|
|
8124
|
+
primaryLabel: getReviewPrimaryLabel(item, 'solo'),
|
|
8063
8125
|
primaryEnabled: item.inboxGroup !== 'ignored',
|
|
8064
8126
|
deferEnabled: canReviewDefer(item),
|
|
8065
8127
|
ignoreEnabled: canReviewIgnore(item),
|
|
@@ -8088,26 +8150,33 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8088
8150
|
const response = await apiFetch('/api/scope/access');
|
|
8089
8151
|
const payload = await response.json();
|
|
8090
8152
|
scopeAccessSnapshot = payload;
|
|
8091
|
-
const governedMode = payload && payload.operatingMode === 'governed';
|
|
8153
|
+
const governedMode = Boolean(payload && payload.operatingMode === 'governed');
|
|
8092
8154
|
const workspaces = payload.ok && Array.isArray(payload.workspaces) ? payload.workspaces : [];
|
|
8093
8155
|
const options = [
|
|
8094
|
-
|
|
8156
|
+
{ id: '', label: 'Register solo / account scope' },
|
|
8095
8157
|
...workspaces.map((workspace) => ({ id: workspace.id, label: workspace.name || workspace.id })),
|
|
8096
8158
|
];
|
|
8097
|
-
|
|
8098
|
-
options.push({ id: '', label: 'No governed workspaces yet' });
|
|
8099
|
-
}
|
|
8100
|
-
const selectedWorkspace = item.workspaceId || payload.currentWorkspaceId || (options[0] && options[0].id) || '';
|
|
8159
|
+
const selectedWorkspace = item.workspaceId || '';
|
|
8101
8160
|
setScopeOptions(workspaceSelect, options, selectedWorkspace);
|
|
8102
8161
|
await loadDiscoveryReviewProjects(selectedWorkspace, item.projectId || payload.currentProjectId || '', governedMode);
|
|
8162
|
+
const reviewScopeMode = getReviewScopeMode(
|
|
8163
|
+
selectedWorkspace,
|
|
8164
|
+
item.projectId || payload.currentProjectId || '',
|
|
8165
|
+
);
|
|
8103
8166
|
setDiscoveryReviewStatus(
|
|
8104
8167
|
payload.ok
|
|
8105
|
-
? (
|
|
8168
|
+
? (reviewScopeMode === 'workspace'
|
|
8106
8169
|
? 'Choose the governed workspace and project for this registration.'
|
|
8107
|
-
: '
|
|
8170
|
+
: 'Solo registration is ready. Choose governed scope only when needed.')
|
|
8108
8171
|
: (payload.message || 'Workspace access is unavailable right now.'),
|
|
8109
8172
|
payload.ok ? '' : 'warn',
|
|
8110
8173
|
);
|
|
8174
|
+
setDiscoveryReviewButtons({
|
|
8175
|
+
primaryLabel: getReviewPrimaryLabel(item, reviewScopeMode),
|
|
8176
|
+
primaryEnabled: item.inboxGroup !== 'ignored',
|
|
8177
|
+
deferEnabled: canReviewDefer(item),
|
|
8178
|
+
ignoreEnabled: canReviewIgnore(item),
|
|
8179
|
+
});
|
|
8111
8180
|
} catch {
|
|
8112
8181
|
setScopeOptions(workspaceSelect, [{ id: '', label: 'Workspace list unavailable' }], '');
|
|
8113
8182
|
setScopeOptions(projectSelect, [{ id: '', label: 'Project list unavailable' }], '');
|
|
@@ -8124,7 +8193,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8124
8193
|
async function submitDiscoveryReviewPrimary() {
|
|
8125
8194
|
const item = getSelectedDiscoveryItem();
|
|
8126
8195
|
if (!item) return;
|
|
8127
|
-
if (item
|
|
8196
|
+
if (shouldOpenReviewContext(item)) {
|
|
8128
8197
|
await openDiscoveryContext(item);
|
|
8129
8198
|
return;
|
|
8130
8199
|
}
|
|
@@ -9091,7 +9160,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
9091
9160
|
registerButton.disabled = true;
|
|
9092
9161
|
setText('scope-modal-title', 'Register ' + item.name);
|
|
9093
9162
|
let governedMode = latestSummary && latestSummary.operatingMode === 'governed';
|
|
9094
|
-
setText('scope-modal-copy', 'Checking account scope and
|
|
9163
|
+
setText('scope-modal-copy', 'Checking account scope and any governed workspace options...');
|
|
9095
9164
|
if (createWorkspaceButton) createWorkspaceButton.hidden = true;
|
|
9096
9165
|
if (createProjectButton) createProjectButton.hidden = true;
|
|
9097
9166
|
setScopeCreateButtonsEnabled(false);
|
|
@@ -9106,40 +9175,38 @@ function renderLauncherHtml(launcherToken) {
|
|
|
9106
9175
|
setText(
|
|
9107
9176
|
'scope-modal-copy',
|
|
9108
9177
|
governedMode
|
|
9109
|
-
? '
|
|
9110
|
-
: '
|
|
9178
|
+
? 'Register on your account now, or choose a governed workspace/project when you want governed ownership. You can create missing scope here.'
|
|
9179
|
+
: 'Solo registration is available now. Choose a governed workspace/project only when you want governed operations.',
|
|
9111
9180
|
);
|
|
9112
9181
|
if (createWorkspaceButton) createWorkspaceButton.hidden = !governedMode;
|
|
9113
9182
|
if (createProjectButton) createProjectButton.hidden = !governedMode;
|
|
9114
9183
|
setScopeCreateButtonsEnabled(governedMode);
|
|
9115
9184
|
const workspaces = payload.ok && Array.isArray(payload.workspaces) ? payload.workspaces : [];
|
|
9116
9185
|
const options = [
|
|
9117
|
-
|
|
9186
|
+
{ id: '', label: 'Register solo / account scope' },
|
|
9118
9187
|
...workspaces.map((workspace) => ({ id: workspace.id, label: workspace.name || workspace.id })),
|
|
9119
9188
|
];
|
|
9120
|
-
if (governedMode &&
|
|
9121
|
-
options.push({ id: '', label: 'No governed workspaces yet' });
|
|
9122
|
-
registerButton.disabled = true;
|
|
9189
|
+
if (governedMode && workspaces.length === 0) {
|
|
9123
9190
|
openScopeCreateWorkspaceFlow('No governed workspace exists yet. Create one here to continue.', 'warn');
|
|
9124
9191
|
}
|
|
9125
|
-
const selectedWorkspace =
|
|
9192
|
+
const selectedWorkspace = item.workspaceId || '';
|
|
9126
9193
|
setScopeOptions(workspaceSelect, options, selectedWorkspace);
|
|
9127
9194
|
const hasProjects = await loadScopeProjects(workspaceSelect.value, payload.currentProjectId || '');
|
|
9128
|
-
registerButton.disabled = !payload.ok || (
|
|
9129
|
-
if (payload.ok && (!
|
|
9130
|
-
setScopeStatus(
|
|
9195
|
+
registerButton.disabled = !payload.ok || (Boolean(String(workspaceSelect.value || '').trim()) && !hasProjects);
|
|
9196
|
+
if (payload.ok && (!String(workspaceSelect.value || '').trim() || hasProjects)) {
|
|
9197
|
+
setScopeStatus(String(workspaceSelect.value || '').trim() ? 'Ready to register in governed scope.' : 'Ready to register solo.', '');
|
|
9131
9198
|
} else if (!payload.ok) {
|
|
9132
9199
|
setScopeStatus(
|
|
9133
|
-
payload.message ||
|
|
9200
|
+
payload.message || 'Workspace list unavailable. Solo registration is still available.',
|
|
9134
9201
|
'warn',
|
|
9135
9202
|
);
|
|
9136
9203
|
}
|
|
9137
9204
|
} catch {
|
|
9138
|
-
setScopeOptions(workspaceSelect,
|
|
9139
|
-
await loadScopeProjects(
|
|
9140
|
-
registerButton.disabled =
|
|
9205
|
+
setScopeOptions(workspaceSelect, [{ id: '', label: 'Register solo / account scope' }], '');
|
|
9206
|
+
await loadScopeProjects('', '');
|
|
9207
|
+
registerButton.disabled = false;
|
|
9141
9208
|
setScopeCreateButtonsEnabled(false);
|
|
9142
|
-
setScopeStatus(
|
|
9209
|
+
setScopeStatus('Workspace list unavailable. Solo registration is still available.', 'warn');
|
|
9143
9210
|
}
|
|
9144
9211
|
}
|
|
9145
9212
|
|
|
@@ -9165,7 +9232,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
9165
9232
|
}
|
|
9166
9233
|
if (registerButton) registerButton.disabled = true;
|
|
9167
9234
|
const endpoint = item.kind === 'agent' ? '/api/discovery/connect-agent' : '/api/discovery/connect-model';
|
|
9168
|
-
const pendingMessage = item.kind === 'agent' ? 'Registering agent...' : '
|
|
9235
|
+
const pendingMessage = item.kind === 'agent' ? 'Registering agent...' : 'Registering model...';
|
|
9169
9236
|
setScopeStatus('Registering with Forkit Connect...', 'warn');
|
|
9170
9237
|
const result = await postAction(endpoint, pendingMessage, {
|
|
9171
9238
|
method: 'POST',
|
|
@@ -10076,17 +10143,25 @@ function renderLauncherHtml(launcherToken) {
|
|
|
10076
10143
|
const quickReviewWorkspaceSelect = document.getElementById('quick-review-workspace');
|
|
10077
10144
|
if (quickReviewWorkspaceSelect) {
|
|
10078
10145
|
quickReviewWorkspaceSelect.addEventListener('change', () => {
|
|
10146
|
+
const item = getQuickReviewItem();
|
|
10079
10147
|
const selectedWorkspaceId = String(quickReviewWorkspaceSelect.value || '').trim();
|
|
10080
|
-
const governedMode = scopeAccessSnapshot && scopeAccessSnapshot.operatingMode === 'governed';
|
|
10148
|
+
const governedMode = Boolean(scopeAccessSnapshot && scopeAccessSnapshot.operatingMode === 'governed');
|
|
10081
10149
|
quickReviewScopeCacheKey = null;
|
|
10082
10150
|
void loadQuickReviewProjects(selectedWorkspaceId, '', governedMode);
|
|
10083
10151
|
updateQuickReviewScopeSummary(governedMode);
|
|
10084
10152
|
setQuickReviewStatus(
|
|
10085
10153
|
selectedWorkspaceId
|
|
10086
10154
|
? 'Choose the governed project for this registration.'
|
|
10087
|
-
: '
|
|
10155
|
+
: 'Solo registration stays available. Choose governed scope only when needed.',
|
|
10088
10156
|
'',
|
|
10089
10157
|
);
|
|
10158
|
+
const primaryButton = document.getElementById('quick-review-primary');
|
|
10159
|
+
if (primaryButton && item) {
|
|
10160
|
+
primaryButton.textContent = getReviewPrimaryLabel(item, selectedWorkspaceId ? 'workspace' : 'solo');
|
|
10161
|
+
}
|
|
10162
|
+
if (item) {
|
|
10163
|
+
setText('quick-review-action-summary', getReviewActionSummary(item, selectedWorkspaceId ? 'workspace' : 'solo'));
|
|
10164
|
+
}
|
|
10090
10165
|
});
|
|
10091
10166
|
}
|
|
10092
10167
|
const quickReviewProjectSelect = document.getElementById('quick-review-project');
|
|
@@ -10097,10 +10172,18 @@ function renderLauncherHtml(launcherToken) {
|
|
|
10097
10172
|
? String(quickReviewWorkspaceSelect.value || '').trim()
|
|
10098
10173
|
: '';
|
|
10099
10174
|
const selectedProjectId = String(quickReviewProjectSelect.value || '').trim();
|
|
10100
|
-
const governedMode = scopeAccessSnapshot && scopeAccessSnapshot.operatingMode === 'governed';
|
|
10175
|
+
const governedMode = Boolean(scopeAccessSnapshot && scopeAccessSnapshot.operatingMode === 'governed');
|
|
10101
10176
|
updateQuickReviewScopeSummary(governedMode);
|
|
10102
10177
|
if (primaryButton) {
|
|
10103
|
-
primaryButton.disabled = Boolean(selectedWorkspaceId && !selectedProjectId
|
|
10178
|
+
primaryButton.disabled = Boolean(selectedWorkspaceId && !selectedProjectId);
|
|
10179
|
+
const item = getQuickReviewItem();
|
|
10180
|
+
if (item) {
|
|
10181
|
+
primaryButton.textContent = getReviewPrimaryLabel(item, selectedWorkspaceId && selectedProjectId ? 'workspace' : 'solo');
|
|
10182
|
+
}
|
|
10183
|
+
}
|
|
10184
|
+
const item = getQuickReviewItem();
|
|
10185
|
+
if (item) {
|
|
10186
|
+
setText('quick-review-action-summary', getReviewActionSummary(item, selectedWorkspaceId && selectedProjectId ? 'workspace' : 'solo'));
|
|
10104
10187
|
}
|
|
10105
10188
|
});
|
|
10106
10189
|
}
|
|
@@ -10139,15 +10222,21 @@ function renderLauncherHtml(launcherToken) {
|
|
|
10139
10222
|
discoveryReviewWorkspaceSelect.addEventListener('change', () => {
|
|
10140
10223
|
const selectedItem = getSelectedDiscoveryItem();
|
|
10141
10224
|
const selectedWorkspaceId = String(discoveryReviewWorkspaceSelect.value || '').trim();
|
|
10142
|
-
const governedMode = scopeAccessSnapshot && scopeAccessSnapshot.operatingMode === 'governed';
|
|
10225
|
+
const governedMode = Boolean(scopeAccessSnapshot && scopeAccessSnapshot.operatingMode === 'governed');
|
|
10143
10226
|
void loadDiscoveryReviewProjects(selectedWorkspaceId, '', governedMode);
|
|
10144
10227
|
if (selectedItem && canReviewRegister(selectedItem)) {
|
|
10145
10228
|
setDiscoveryReviewStatus(
|
|
10146
10229
|
selectedWorkspaceId
|
|
10147
10230
|
? 'Choose the governed project for this registration.'
|
|
10148
|
-
: '
|
|
10231
|
+
: 'Solo registration stays available. Choose governed scope only when needed.',
|
|
10149
10232
|
'',
|
|
10150
10233
|
);
|
|
10234
|
+
setDiscoveryReviewButtons({
|
|
10235
|
+
primaryLabel: getReviewPrimaryLabel(selectedItem, selectedWorkspaceId ? 'workspace' : 'solo'),
|
|
10236
|
+
primaryEnabled: selectedItem.inboxGroup !== 'ignored',
|
|
10237
|
+
deferEnabled: canReviewDefer(selectedItem),
|
|
10238
|
+
ignoreEnabled: canReviewIgnore(selectedItem),
|
|
10239
|
+
});
|
|
10151
10240
|
}
|
|
10152
10241
|
});
|
|
10153
10242
|
}
|
|
@@ -10160,9 +10249,10 @@ function renderLauncherHtml(launcherToken) {
|
|
|
10160
10249
|
? String(discoveryReviewWorkspaceSelect.value || '').trim()
|
|
10161
10250
|
: '';
|
|
10162
10251
|
const selectedProjectId = String(discoveryReviewProjectSelect.value || '').trim();
|
|
10163
|
-
const governedMode = scopeAccessSnapshot && scopeAccessSnapshot.operatingMode === 'governed';
|
|
10252
|
+
const governedMode = Boolean(scopeAccessSnapshot && scopeAccessSnapshot.operatingMode === 'governed');
|
|
10164
10253
|
if (primaryButton && selectedItem && canReviewRegister(selectedItem)) {
|
|
10165
|
-
primaryButton.disabled = Boolean(selectedWorkspaceId && !selectedProjectId
|
|
10254
|
+
primaryButton.disabled = Boolean(selectedWorkspaceId && !selectedProjectId);
|
|
10255
|
+
primaryButton.textContent = getReviewPrimaryLabel(selectedItem, selectedWorkspaceId && selectedProjectId ? 'workspace' : 'solo');
|
|
10166
10256
|
}
|
|
10167
10257
|
});
|
|
10168
10258
|
}
|
|
@@ -10806,16 +10896,19 @@ function createLauncherApp(options) {
|
|
|
10806
10896
|
else {
|
|
10807
10897
|
await options.service.bindWorkspaceProject(null, null);
|
|
10808
10898
|
}
|
|
10809
|
-
const result = await options.service.connectDetectedModel(selector
|
|
10899
|
+
const result = await options.service.connectDetectedModel(selector, {
|
|
10900
|
+
destination: 'passport',
|
|
10901
|
+
visibility: 'public',
|
|
10902
|
+
});
|
|
10810
10903
|
const message = result.action === 'already_bound'
|
|
10811
10904
|
? 'Model is already connected to a Passport.'
|
|
10812
10905
|
: result.action === 'already_pending'
|
|
10813
|
-
? '
|
|
10906
|
+
? 'Registration is already in progress for this model.'
|
|
10814
10907
|
: result.action === 'passport_registered'
|
|
10815
|
-
? 'Passport registered
|
|
10908
|
+
? 'Passport registered successfully.'
|
|
10816
10909
|
: result.action === 'draft_created'
|
|
10817
|
-
? '
|
|
10818
|
-
: '
|
|
10910
|
+
? 'Registration started privately for review before publishing.'
|
|
10911
|
+
: 'Registration was saved locally and will continue when Forkit Connect can sync again.';
|
|
10819
10912
|
response.json({
|
|
10820
10913
|
ok: true,
|
|
10821
10914
|
message,
|
|
@@ -10885,7 +10978,7 @@ function createLauncherApp(options) {
|
|
|
10885
10978
|
: passportGaid
|
|
10886
10979
|
? 'Agent is already registered.'
|
|
10887
10980
|
: draftId
|
|
10888
|
-
? 'Agent registration
|
|
10981
|
+
? 'Agent registration started privately for review.'
|
|
10889
10982
|
: 'Agent connected locally. Registration is still available.';
|
|
10890
10983
|
response.json({
|
|
10891
10984
|
ok: true,
|
package/dist/v1/service.d.ts
CHANGED
|
@@ -742,6 +742,7 @@ export declare class ConnectV1Service {
|
|
|
742
742
|
connectDetectedModel(selector: string, options?: {
|
|
743
743
|
visibility?: 'private' | 'public';
|
|
744
744
|
destination?: 'draft' | 'passport';
|
|
745
|
+
allowPrivateFallback?: boolean;
|
|
745
746
|
}): Promise<ConnectSelectionResult>;
|
|
746
747
|
private resolveRuntimePassportSelection;
|
|
747
748
|
connectRuntimeSuggestion(selector: string): Promise<ConnectSelectionResult>;
|
package/dist/v1/service.js
CHANGED
|
@@ -7834,10 +7834,13 @@ class ConnectV1Service {
|
|
|
7834
7834
|
const soloDraftAllowed = draftBindingStatus.allowed && draftBindingStatus.reasonCode === 'solo_passport_draft_allowed';
|
|
7835
7835
|
const localScopedDraftAllowed = draftBindingStatus.allowed && draftBindingStatus.reasonCode === 'local_workspace_project_draft_allowed';
|
|
7836
7836
|
const model = this.resolveModelSelection(selector, state);
|
|
7837
|
-
const requestedDestination = options?.destination === '
|
|
7838
|
-
const requestedVisibility = options?.visibility === '
|
|
7839
|
-
? '
|
|
7840
|
-
: '
|
|
7837
|
+
const requestedDestination = options?.destination === 'draft' ? 'draft' : 'passport';
|
|
7838
|
+
const requestedVisibility = options?.visibility === 'private'
|
|
7839
|
+
? 'private'
|
|
7840
|
+
: requestedDestination === 'passport'
|
|
7841
|
+
? 'public'
|
|
7842
|
+
: 'private';
|
|
7843
|
+
const allowPrivateFallback = options?.allowPrivateFallback !== false;
|
|
7841
7844
|
this.clearModelReviewDeferral(model);
|
|
7842
7845
|
this.updateDetectedModelRegistrationHint(model, {
|
|
7843
7846
|
trackingStatus: null,
|
|
@@ -7992,10 +7995,17 @@ class ConnectV1Service {
|
|
|
7992
7995
|
this.updateDetectedModelRegistrationHint(model, {
|
|
7993
7996
|
trackingStatus: 'private_draft_required',
|
|
7994
7997
|
errorCode: backendCode,
|
|
7995
|
-
errorMessage: '
|
|
7998
|
+
errorMessage: 'Forkit needs one private review step before this passport can finish publishing.',
|
|
7996
7999
|
errorStatus: result.status,
|
|
7997
|
-
guidance: '
|
|
8000
|
+
guidance: 'Forkit is continuing this registration privately first. Finish the review step there before publishing.',
|
|
7998
8001
|
});
|
|
8002
|
+
if (allowPrivateFallback && requestedDestination === 'passport' && requestedVisibility === 'public') {
|
|
8003
|
+
return this.connectDetectedModel(selector, {
|
|
8004
|
+
destination: 'draft',
|
|
8005
|
+
visibility: 'private',
|
|
8006
|
+
allowPrivateFallback: false,
|
|
8007
|
+
});
|
|
8008
|
+
}
|
|
7999
8009
|
}
|
|
8000
8010
|
this.observeBackendCommunicationState({
|
|
8001
8011
|
passportGaid: bindingWithRuntime?.gaid ?? null,
|