forkit-connect 0.1.5 → 0.1.6
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/QUICKSTART.md +10 -1
- package/README.md +12 -1
- package/dist/cli.js +763 -37
- package/dist/launcher.js +471 -73
- package/dist/resource-meter.d.ts +15 -0
- package/dist/resource-meter.js +60 -0
- package/dist/v1/api.d.ts +41 -0
- package/dist/v1/api.js +57 -0
- package/dist/v1/daemon.js +9 -0
- package/dist/v1/repo-discovery.d.ts +42 -0
- package/dist/v1/repo-discovery.js +206 -0
- package/dist/v1/runtime-activity.d.ts +55 -0
- package/dist/v1/runtime-activity.js +388 -0
- package/dist/v1/runtime-context.d.ts +18 -0
- package/dist/v1/runtime-context.js +96 -0
- package/dist/v1/runtime-editor-activity.d.ts +47 -0
- package/dist/v1/runtime-editor-activity.js +821 -0
- package/dist/v1/runtime-observation-runner.d.ts +49 -0
- package/dist/v1/runtime-observation-runner.js +508 -0
- package/dist/v1/runtime-observer.d.ts +50 -0
- package/dist/v1/runtime-observer.js +867 -0
- package/dist/v1/runtime-registration.d.ts +58 -0
- package/dist/v1/runtime-registration.js +319 -0
- package/dist/v1/service.d.ts +44 -1
- package/dist/v1/service.js +165 -10
- package/dist/v1/state.d.ts +4 -1
- package/dist/v1/state.js +28 -0
- package/dist/v1/types.d.ts +14 -0
- package/package.json +1 -1
package/dist/launcher.js
CHANGED
|
@@ -500,6 +500,64 @@ function safeStringRecordValue(record, keys) {
|
|
|
500
500
|
}
|
|
501
501
|
return null;
|
|
502
502
|
}
|
|
503
|
+
function normalizeDiscoveryRegistrationFailure(message) {
|
|
504
|
+
const normalized = String(message || '').trim();
|
|
505
|
+
if (!normalized) {
|
|
506
|
+
return {
|
|
507
|
+
code: null,
|
|
508
|
+
message: 'Registration failed.',
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
if (normalized === 'GOVERNED_PASSPORT_CAPACITY_REACHED') {
|
|
512
|
+
return {
|
|
513
|
+
code: normalized,
|
|
514
|
+
message: 'Governed passport capacity is full for this account.',
|
|
515
|
+
nextActions: [
|
|
516
|
+
'Use an existing published passport for runtime review or C2 work.',
|
|
517
|
+
'Free capacity or upgrade before creating another governed registration.',
|
|
518
|
+
'If you only need local observation for now, keep the item in review instead of registering it yet.',
|
|
519
|
+
],
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
if (normalized === 'DRAFT_LIMIT_REACHED') {
|
|
523
|
+
return {
|
|
524
|
+
code: normalized,
|
|
525
|
+
message: 'Draft capacity is full for this account.',
|
|
526
|
+
nextActions: [
|
|
527
|
+
'Clear an old draft or upgrade before creating another draft.',
|
|
528
|
+
'Use an existing passport if you only need runtime review or C2 testing.',
|
|
529
|
+
],
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
if (normalized === 'SIMILAR_PASSPORT_EXISTS') {
|
|
533
|
+
return {
|
|
534
|
+
code: normalized,
|
|
535
|
+
message: 'A similar passport already exists in Forkit. Review existing records before creating a new one.',
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
if (normalized === 'WORKSPACE_PROJECT_BINDING_REQUIRED') {
|
|
539
|
+
return {
|
|
540
|
+
code: normalized,
|
|
541
|
+
message: 'Choose a governed workspace and project before registering this item.',
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
if (normalized === 'DRAFT_CREATION_NOT_ALLOWED_BY_BINDING') {
|
|
545
|
+
return {
|
|
546
|
+
code: normalized,
|
|
547
|
+
message: 'This binding does not currently allow draft creation. Update consent or switch scope first.',
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
if (normalized.startsWith('DRAFT_CREATE_FAILED:')) {
|
|
551
|
+
return {
|
|
552
|
+
code: normalized,
|
|
553
|
+
message: 'Forkit could not create the draft on the backend right now. Retry in a moment.',
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
return {
|
|
557
|
+
code: null,
|
|
558
|
+
message: normalized,
|
|
559
|
+
};
|
|
560
|
+
}
|
|
503
561
|
function buildPassportHistory(binding, events) {
|
|
504
562
|
const modelParts = parseModelKeyParts(binding.modelKey);
|
|
505
563
|
const modelName = (0, heartbeat_1.readBoundModelName)(binding.modelKey);
|
|
@@ -1949,6 +2007,34 @@ function renderLauncherHtml(launcherToken) {
|
|
|
1949
2007
|
align-items: start;
|
|
1950
2008
|
}
|
|
1951
2009
|
|
|
2010
|
+
.review-resolution-actions {
|
|
2011
|
+
display: grid;
|
|
2012
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
2013
|
+
gap: 10px;
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
.review-resolution-actions[hidden] {
|
|
2017
|
+
display: none;
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
.review-resolution-button {
|
|
2021
|
+
min-height: 44px;
|
|
2022
|
+
border-radius: 14px;
|
|
2023
|
+
border: 1px solid rgba(241, 235, 223, 0.12);
|
|
2024
|
+
background: rgba(255,255,255,0.04);
|
|
2025
|
+
color: #fff8ef;
|
|
2026
|
+
font-size: 0.88rem;
|
|
2027
|
+
font-weight: 600;
|
|
2028
|
+
cursor: pointer;
|
|
2029
|
+
padding: 0 12px;
|
|
2030
|
+
transition: background 160ms ease, border-color 160ms ease;
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
.review-resolution-button:hover {
|
|
2034
|
+
background: rgba(255,255,255,0.08);
|
|
2035
|
+
border-color: rgba(157, 238, 245, 0.18);
|
|
2036
|
+
}
|
|
2037
|
+
|
|
1952
2038
|
.quick-review-primary {
|
|
1953
2039
|
min-height: 52px;
|
|
1954
2040
|
border: 1px solid rgba(157, 238, 245, 0.2);
|
|
@@ -6391,6 +6477,10 @@ function renderLauncherHtml(launcherToken) {
|
|
|
6391
6477
|
</div>
|
|
6392
6478
|
</div>
|
|
6393
6479
|
</div>
|
|
6480
|
+
<div class="review-resolution-actions" id="quick-review-resolution" hidden>
|
|
6481
|
+
<button class="review-resolution-button" id="quick-review-resolution-primary" type="button" hidden></button>
|
|
6482
|
+
<button class="review-resolution-button" id="quick-review-resolution-secondary" type="button" hidden></button>
|
|
6483
|
+
</div>
|
|
6394
6484
|
</section>
|
|
6395
6485
|
</div>
|
|
6396
6486
|
</div>
|
|
@@ -6770,6 +6860,10 @@ function renderLauncherHtml(launcherToken) {
|
|
|
6770
6860
|
<button class="secondary" id="discovery-review-defer" type="button" disabled>Defer 24h</button>
|
|
6771
6861
|
<button class="danger" id="discovery-review-ignore" type="button" disabled>Ignore</button>
|
|
6772
6862
|
</div>
|
|
6863
|
+
<div class="review-resolution-actions" id="discovery-review-resolution" hidden>
|
|
6864
|
+
<button class="review-resolution-button" id="discovery-review-resolution-primary" type="button" hidden></button>
|
|
6865
|
+
<button class="review-resolution-button" id="discovery-review-resolution-secondary" type="button" hidden></button>
|
|
6866
|
+
</div>
|
|
6773
6867
|
</section>
|
|
6774
6868
|
|
|
6775
6869
|
<ul class="discovery-note-list">
|
|
@@ -7274,6 +7368,9 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7274
7368
|
if (!match) return false;
|
|
7275
7369
|
selectedPassportId = match.id;
|
|
7276
7370
|
passportHistoryVisible = Boolean(options && options.showHistory);
|
|
7371
|
+
selectedWorkspaceScope = ALL_SCOPE_VALUE;
|
|
7372
|
+
selectedProjectScope = ALL_SCOPE_VALUE;
|
|
7373
|
+
renderGlobalLaunchHeaderAndCards();
|
|
7277
7374
|
setView('passports', { skipRouteUpdate: true });
|
|
7278
7375
|
renderPassportsRows();
|
|
7279
7376
|
updateRoute('passports', { passport: match.gaid || match.id, ...(passportHistoryVisible ? { focus: 'history' } : {}) });
|
|
@@ -7298,6 +7395,29 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7298
7395
|
return false;
|
|
7299
7396
|
}
|
|
7300
7397
|
|
|
7398
|
+
async function completeRegistrationSuccess(item, result) {
|
|
7399
|
+
const message = result && typeof result.message === 'string' && result.message.trim()
|
|
7400
|
+
? result.message.trim()
|
|
7401
|
+
: 'Registration updated.';
|
|
7402
|
+
await refreshAll();
|
|
7403
|
+
const preferredPassportGaid = String(result && (result.passportGaid || result.gaid) || '').trim();
|
|
7404
|
+
if (preferredPassportGaid && focusPassportByGaid(preferredPassportGaid, { showHistory: false })) {
|
|
7405
|
+
setActivityMessage(message, 'ok');
|
|
7406
|
+
return true;
|
|
7407
|
+
}
|
|
7408
|
+
if (item && await openDiscoveryContext({
|
|
7409
|
+
...item,
|
|
7410
|
+
passportGaid: preferredPassportGaid || item.passportGaid,
|
|
7411
|
+
matchedPassportGaid: preferredPassportGaid || item.matchedPassportGaid,
|
|
7412
|
+
})) {
|
|
7413
|
+
setActivityMessage(message, 'ok');
|
|
7414
|
+
return true;
|
|
7415
|
+
}
|
|
7416
|
+
setView('passports');
|
|
7417
|
+
setActivityMessage(message, 'ok');
|
|
7418
|
+
return false;
|
|
7419
|
+
}
|
|
7420
|
+
|
|
7301
7421
|
function getSelectedDiscoveryItem(itemsOverride) {
|
|
7302
7422
|
const items = Array.isArray(itemsOverride)
|
|
7303
7423
|
? itemsOverride
|
|
@@ -7357,6 +7477,204 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7357
7477
|
status.className = 'quick-review-status' + (tone ? ' ' + tone : '');
|
|
7358
7478
|
}
|
|
7359
7479
|
|
|
7480
|
+
function resetReviewResolutionActions(prefix) {
|
|
7481
|
+
setReviewResolutionActions(prefix, []);
|
|
7482
|
+
}
|
|
7483
|
+
|
|
7484
|
+
function derivePassportResolutionQuery(item) {
|
|
7485
|
+
if (!item || typeof item !== 'object') return '';
|
|
7486
|
+
return [
|
|
7487
|
+
item.modelName,
|
|
7488
|
+
item.name,
|
|
7489
|
+
item.selector,
|
|
7490
|
+
item.sourceMeta,
|
|
7491
|
+
].map((value) => String(value || '').trim()).find(Boolean) || '';
|
|
7492
|
+
}
|
|
7493
|
+
|
|
7494
|
+
function getReviewPrimaryLabel(item) {
|
|
7495
|
+
if (!item) return 'Review';
|
|
7496
|
+
if (item.kind === 'runtime') {
|
|
7497
|
+
return item.statusTone === 'error' ? 'Open runtime fix' : 'Open runtime review';
|
|
7498
|
+
}
|
|
7499
|
+
if (item.statusLabel === 'Draft created') {
|
|
7500
|
+
return 'Open draft';
|
|
7501
|
+
}
|
|
7502
|
+
if (item.passportGaid) {
|
|
7503
|
+
return 'Open passport';
|
|
7504
|
+
}
|
|
7505
|
+
if (item.matchedPassportGaid) {
|
|
7506
|
+
return 'Use existing passport';
|
|
7507
|
+
}
|
|
7508
|
+
if (item.actionLabel === 'Retry') {
|
|
7509
|
+
return 'Retry registration';
|
|
7510
|
+
}
|
|
7511
|
+
if (item.actionLabel === 'Open' || item.actionLabel === 'Review') {
|
|
7512
|
+
return 'Review in context';
|
|
7513
|
+
}
|
|
7514
|
+
return 'Approve & register';
|
|
7515
|
+
}
|
|
7516
|
+
|
|
7517
|
+
function getReviewActionSummary(item) {
|
|
7518
|
+
if (!item) return 'Review';
|
|
7519
|
+
if (item.kind === 'runtime') {
|
|
7520
|
+
return item.statusTone === 'error' ? 'Resolve runtime attention' : 'Open runtime lane';
|
|
7521
|
+
}
|
|
7522
|
+
if (item.statusLabel === 'Draft created') {
|
|
7523
|
+
return 'Continue the existing draft';
|
|
7524
|
+
}
|
|
7525
|
+
if (item.passportGaid) {
|
|
7526
|
+
return 'Open the linked passport';
|
|
7527
|
+
}
|
|
7528
|
+
if (item.matchedPassportGaid) {
|
|
7529
|
+
return 'Use the matching passport';
|
|
7530
|
+
}
|
|
7531
|
+
if (item.actionLabel === 'Retry') {
|
|
7532
|
+
return 'Retry registration here';
|
|
7533
|
+
}
|
|
7534
|
+
if (item.actionLabel === 'Open' || item.actionLabel === 'Review') {
|
|
7535
|
+
return 'Open full review';
|
|
7536
|
+
}
|
|
7537
|
+
return 'Approve and register here';
|
|
7538
|
+
}
|
|
7539
|
+
|
|
7540
|
+
function getReviewDetailText(item) {
|
|
7541
|
+
if (!item) return 'Review local metadata, then decide what happens next.';
|
|
7542
|
+
if (item.kind === 'runtime') {
|
|
7543
|
+
return item.statusTone === 'error'
|
|
7544
|
+
? 'Runtime attention is required before linked models can keep registering cleanly.'
|
|
7545
|
+
: 'Open runtime review to confirm health, scope, and connected models.';
|
|
7546
|
+
}
|
|
7547
|
+
if (item.statusLabel === 'Draft created') {
|
|
7548
|
+
return 'A draft already exists. Continue it in Passports instead of creating another one.';
|
|
7549
|
+
}
|
|
7550
|
+
if (item.matchedPassportGaid && !item.passportGaid) {
|
|
7551
|
+
return 'Forkit Connect found a matching passport. Reuse it before creating anything new.';
|
|
7552
|
+
}
|
|
7553
|
+
if (item.passportGaid) {
|
|
7554
|
+
return 'This item is already linked. Open the passport to inspect lineage, scope, and runtime state.';
|
|
7555
|
+
}
|
|
7556
|
+
if (item.actionLabel === 'Retry') {
|
|
7557
|
+
return 'Registration failed earlier. Review the latest local metadata and retry when the scope is ready.';
|
|
7558
|
+
}
|
|
7559
|
+
return item.detailSummary || item.statusMeta || 'Review local metadata, then decide what happens next.';
|
|
7560
|
+
}
|
|
7561
|
+
|
|
7562
|
+
function formatLauncherActionFeedback(result, fallbackMessage) {
|
|
7563
|
+
const base = result && typeof result.message === 'string' && result.message.trim()
|
|
7564
|
+
? result.message.trim()
|
|
7565
|
+
: fallbackMessage;
|
|
7566
|
+
const nextActions = result && Array.isArray(result.nextActions)
|
|
7567
|
+
? result.nextActions.map((item) => String(item || '').trim()).filter(Boolean)
|
|
7568
|
+
: [];
|
|
7569
|
+
const resolutionActions = result && result.code === 'GOVERNED_PASSPORT_CAPACITY_REACHED'
|
|
7570
|
+
? [{ id: 'passports', label: 'Use existing passport' }]
|
|
7571
|
+
: result && result.code === 'DRAFT_LIMIT_REACHED'
|
|
7572
|
+
? [{ id: 'passports', label: 'Review existing drafts' }]
|
|
7573
|
+
: result && (result.code === 'WORKSPACE_PROJECT_BINDING_REQUIRED' || result.code === 'DRAFT_CREATION_NOT_ALLOWED_BY_BINDING')
|
|
7574
|
+
? [{ id: 'scope', label: 'Set workspace' }]
|
|
7575
|
+
: result && result.code === 'SIMILAR_PASSPORT_EXISTS'
|
|
7576
|
+
? [{ id: 'passports', label: 'Open matching passport' }]
|
|
7577
|
+
: [];
|
|
7578
|
+
return {
|
|
7579
|
+
message: nextActions.length ? (base + ' Next: ' + nextActions[0]) : base,
|
|
7580
|
+
activity: nextActions.length ? (base + ' Next: ' + nextActions.join(' ')) : base,
|
|
7581
|
+
actionSummary: result && result.code === 'GOVERNED_PASSPORT_CAPACITY_REACHED'
|
|
7582
|
+
? 'Capacity full · use an existing passport or free space'
|
|
7583
|
+
: result && result.code === 'DRAFT_LIMIT_REACHED'
|
|
7584
|
+
? 'Draft capacity full · use an existing passport, clear a draft, or upgrade'
|
|
7585
|
+
: result && result.code === 'SIMILAR_PASSPORT_EXISTS'
|
|
7586
|
+
? 'Matching passport exists · reuse it instead of creating another'
|
|
7587
|
+
: result && (result.code === 'WORKSPACE_PROJECT_BINDING_REQUIRED' || result.code === 'DRAFT_CREATION_NOT_ALLOWED_BY_BINDING')
|
|
7588
|
+
? 'Scope required · choose workspace and project'
|
|
7589
|
+
: null,
|
|
7590
|
+
resolutionActions,
|
|
7591
|
+
};
|
|
7592
|
+
}
|
|
7593
|
+
|
|
7594
|
+
function setReviewResolutionActions(prefix, actions) {
|
|
7595
|
+
const wrapper = document.getElementById(prefix + '-resolution');
|
|
7596
|
+
const primary = document.getElementById(prefix + '-resolution-primary');
|
|
7597
|
+
const secondary = document.getElementById(prefix + '-resolution-secondary');
|
|
7598
|
+
if (!wrapper || !primary || !secondary) return;
|
|
7599
|
+
const normalized = Array.isArray(actions) ? actions.slice(0, 2) : [];
|
|
7600
|
+
[primary, secondary].forEach((button, index) => {
|
|
7601
|
+
const action = normalized[index];
|
|
7602
|
+
if (!action) {
|
|
7603
|
+
button.hidden = true;
|
|
7604
|
+
button.dataset.action = '';
|
|
7605
|
+
button.textContent = '';
|
|
7606
|
+
return;
|
|
7607
|
+
}
|
|
7608
|
+
button.hidden = false;
|
|
7609
|
+
button.dataset.action = String(action.id || '').trim();
|
|
7610
|
+
button.textContent = String(action.label || '').trim();
|
|
7611
|
+
});
|
|
7612
|
+
wrapper.hidden = normalized.length === 0;
|
|
7613
|
+
}
|
|
7614
|
+
|
|
7615
|
+
async function handleReviewResolutionAction(prefix, action) {
|
|
7616
|
+
const item = prefix === 'quick-review' ? getQuickReviewItem() : getSelectedDiscoveryItem();
|
|
7617
|
+
if (action === 'passports') {
|
|
7618
|
+
if (!latestPassports) {
|
|
7619
|
+
await refreshPassports();
|
|
7620
|
+
}
|
|
7621
|
+
const preferredPassportGaid = String(item && (item.passportGaid || item.matchedPassportGaid) || '').trim();
|
|
7622
|
+
if (preferredPassportGaid && focusPassportByGaid(preferredPassportGaid, { showHistory: true })) {
|
|
7623
|
+
if (prefix === 'quick-review') {
|
|
7624
|
+
setQuickReviewPanelOpen(false);
|
|
7625
|
+
}
|
|
7626
|
+
setActivityMessage('Opened the matching local passport for review.', 'ok');
|
|
7627
|
+
return;
|
|
7628
|
+
}
|
|
7629
|
+
const query = derivePassportResolutionQuery(item);
|
|
7630
|
+
const searchInput = document.getElementById('passports-search');
|
|
7631
|
+
const statusFilter = document.getElementById('passports-status-filter');
|
|
7632
|
+
if (searchInput) {
|
|
7633
|
+
searchInput.value = query;
|
|
7634
|
+
}
|
|
7635
|
+
if (statusFilter) {
|
|
7636
|
+
statusFilter.value = '';
|
|
7637
|
+
}
|
|
7638
|
+
selectedWorkspaceScope = ALL_SCOPE_VALUE;
|
|
7639
|
+
selectedProjectScope = ALL_SCOPE_VALUE;
|
|
7640
|
+
renderGlobalLaunchHeaderAndCards();
|
|
7641
|
+
setView('passports');
|
|
7642
|
+
renderPassportsRows();
|
|
7643
|
+
const filtered = getPassportItemsFiltered();
|
|
7644
|
+
if (filtered.length > 0) {
|
|
7645
|
+
selectedPassportId = filtered[0].id;
|
|
7646
|
+
renderPassportsRows();
|
|
7647
|
+
setActivityMessage(
|
|
7648
|
+
query
|
|
7649
|
+
? ('Showing local passports that match ' + query + '.')
|
|
7650
|
+
: 'Showing available local passports for reuse.',
|
|
7651
|
+
'ok',
|
|
7652
|
+
);
|
|
7653
|
+
} else {
|
|
7654
|
+
setActivityMessage(
|
|
7655
|
+
query
|
|
7656
|
+
? ('No local passport matches ' + query + ' yet. Check existing Forkit.dev records or free local capacity first.')
|
|
7657
|
+
: 'No local passports are available yet. Check existing Forkit.dev records or free local capacity first.',
|
|
7658
|
+
'warn',
|
|
7659
|
+
);
|
|
7660
|
+
}
|
|
7661
|
+
if (searchInput) {
|
|
7662
|
+
searchInput.focus();
|
|
7663
|
+
searchInput.select();
|
|
7664
|
+
}
|
|
7665
|
+
if (prefix === 'quick-review') {
|
|
7666
|
+
setQuickReviewPanelOpen(false);
|
|
7667
|
+
}
|
|
7668
|
+
return;
|
|
7669
|
+
}
|
|
7670
|
+
if (action === 'scope' && item) {
|
|
7671
|
+
if (prefix === 'quick-review') {
|
|
7672
|
+
setQuickReviewPanelOpen(false);
|
|
7673
|
+
}
|
|
7674
|
+
await openRegistrationScopeDialog(item);
|
|
7675
|
+
}
|
|
7676
|
+
}
|
|
7677
|
+
|
|
7360
7678
|
function setQuickReviewOptionsOpen(open) {
|
|
7361
7679
|
const button = document.getElementById('quick-review-options');
|
|
7362
7680
|
const menu = document.getElementById('quick-review-options-menu');
|
|
@@ -7459,6 +7777,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7459
7777
|
anchor.hidden = true;
|
|
7460
7778
|
setQuickReviewPanelOpen(false);
|
|
7461
7779
|
quickReviewScopeCacheKey = null;
|
|
7780
|
+
resetReviewResolutionActions('quick-review');
|
|
7462
7781
|
return;
|
|
7463
7782
|
}
|
|
7464
7783
|
|
|
@@ -7470,22 +7789,14 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7470
7789
|
setText('quick-review-title', item.name);
|
|
7471
7790
|
setText('quick-review-badge', item.kind === 'runtime' ? 'Runtime' : item.kind === 'agent' ? 'Agent' : 'Model');
|
|
7472
7791
|
setText('quick-review-meta', item.subtitle + ' · ' + item.source);
|
|
7473
|
-
setText('quick-review-detail', item
|
|
7792
|
+
setText('quick-review-detail', getReviewDetailText(item));
|
|
7474
7793
|
setQuickReviewStatus(item.statusLabel + (item.statusMeta ? ' · ' + item.statusMeta : ''), item.statusTone === 'muted' ? '' : item.statusTone);
|
|
7794
|
+
resetReviewResolutionActions('quick-review');
|
|
7475
7795
|
|
|
7476
|
-
const
|
|
7477
|
-
const primaryLabel = item.kind === 'runtime'
|
|
7478
|
-
? 'Open runtime review'
|
|
7479
|
-
: opensExisting
|
|
7480
|
-
? (item.passportGaid || item.matchedPassportGaid ? 'Open passport' : 'Review in context')
|
|
7481
|
-
: 'Approve & register';
|
|
7796
|
+
const primaryLabel = getReviewPrimaryLabel(item);
|
|
7482
7797
|
setText(
|
|
7483
7798
|
'quick-review-action-summary',
|
|
7484
|
-
item
|
|
7485
|
-
? 'Open runtime lane'
|
|
7486
|
-
: opensExisting
|
|
7487
|
-
? (item.passportGaid || item.matchedPassportGaid ? 'Open linked passport' : 'Open full review')
|
|
7488
|
-
: 'Approve and register here',
|
|
7799
|
+
getReviewActionSummary(item),
|
|
7489
7800
|
);
|
|
7490
7801
|
if (primaryButton) {
|
|
7491
7802
|
primaryButton.textContent = primaryLabel;
|
|
@@ -7594,17 +7905,19 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7594
7905
|
});
|
|
7595
7906
|
if (primaryButton) primaryButton.disabled = false;
|
|
7596
7907
|
if (!result.ok) {
|
|
7597
|
-
|
|
7598
|
-
|
|
7908
|
+
const feedback = formatLauncherActionFeedback(result, 'Registration failed.');
|
|
7909
|
+
setQuickReviewStatus(feedback.message, 'warn');
|
|
7910
|
+
setActivityMessage(feedback.activity, 'warn');
|
|
7911
|
+
if (feedback.actionSummary) {
|
|
7912
|
+
setText('quick-review-action-summary', feedback.actionSummary);
|
|
7913
|
+
}
|
|
7914
|
+
setReviewResolutionActions('quick-review', feedback.resolutionActions || []);
|
|
7599
7915
|
return;
|
|
7600
7916
|
}
|
|
7917
|
+
resetReviewResolutionActions('quick-review');
|
|
7601
7918
|
setQuickReviewStatus(result.message || 'Registration updated.', 'ok');
|
|
7602
|
-
setActivityMessage(result.message || 'Registration updated.', 'ok');
|
|
7603
|
-
await refreshAll();
|
|
7604
7919
|
setQuickReviewPanelOpen(false);
|
|
7605
|
-
|
|
7606
|
-
await openDiscoveryContext(item);
|
|
7607
|
-
}
|
|
7920
|
+
await completeRegistrationSuccess(item, result);
|
|
7608
7921
|
}
|
|
7609
7922
|
|
|
7610
7923
|
async function submitQuickReviewDefer() {
|
|
@@ -7620,6 +7933,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7620
7933
|
setQuickReviewStatus(result.message || 'Review deferred.', result.ok ? 'ok' : 'warn');
|
|
7621
7934
|
setActivityMessage(result.message || 'Review deferred.', result.ok ? 'ok' : 'warn');
|
|
7622
7935
|
await refreshAll();
|
|
7936
|
+
resetReviewResolutionActions('quick-review');
|
|
7623
7937
|
setQuickReviewOptionsOpen(false);
|
|
7624
7938
|
}
|
|
7625
7939
|
|
|
@@ -7636,6 +7950,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7636
7950
|
setQuickReviewStatus(result.message || 'Item ignored locally.', result.ok ? 'ok' : 'warn');
|
|
7637
7951
|
setActivityMessage(result.message || 'Item ignored locally.', result.ok ? 'ok' : 'warn');
|
|
7638
7952
|
await refreshAll();
|
|
7953
|
+
resetReviewResolutionActions('quick-review');
|
|
7639
7954
|
setQuickReviewOptionsOpen(false);
|
|
7640
7955
|
}
|
|
7641
7956
|
|
|
@@ -7703,26 +8018,23 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7703
8018
|
setText('discovery-review-detail', 'Registering creates or updates a Forkit Passport. Nothing is published automatically.');
|
|
7704
8019
|
if (scopeWrap) scopeWrap.hidden = true;
|
|
7705
8020
|
setDiscoveryReviewStatus('Select an item to continue.', '');
|
|
8021
|
+
resetReviewResolutionActions('discovery-review');
|
|
7706
8022
|
setDiscoveryReviewButtons({ primaryLabel: 'Review', primaryEnabled: false, deferEnabled: false, ignoreEnabled: false });
|
|
7707
8023
|
return;
|
|
7708
8024
|
}
|
|
7709
8025
|
|
|
7710
8026
|
const typeLabel = item.typeLabel || item.kind;
|
|
7711
8027
|
const needsScope = canReviewRegister(item);
|
|
7712
|
-
const
|
|
7713
|
-
const primaryLabel = item.kind === 'runtime'
|
|
7714
|
-
? 'Open runtime review'
|
|
7715
|
-
: opensExisting
|
|
7716
|
-
? (item.passportGaid || item.matchedPassportGaid ? 'Open passport' : 'Review in context')
|
|
7717
|
-
: 'Approve and register';
|
|
8028
|
+
const primaryLabel = getReviewPrimaryLabel(item);
|
|
7718
8029
|
|
|
7719
8030
|
setText('discovery-review-kicker', typeLabel);
|
|
7720
8031
|
setText('discovery-review-title', item.name);
|
|
7721
8032
|
setText('discovery-review-meta', item.subtitle + ' · ' + item.source);
|
|
7722
|
-
setText('discovery-review-detail', item
|
|
8033
|
+
setText('discovery-review-detail', getReviewDetailText(item));
|
|
7723
8034
|
setDiscoveryReviewStatus(item.statusLabel + (item.statusMeta ? ' · ' + item.statusMeta : ''), item.statusTone === 'muted' ? '' : item.statusTone);
|
|
8035
|
+
resetReviewResolutionActions('discovery-review');
|
|
7724
8036
|
setDiscoveryReviewButtons({
|
|
7725
|
-
primaryLabel,
|
|
8037
|
+
primaryLabel: getReviewPrimaryLabel(item),
|
|
7726
8038
|
primaryEnabled: item.inboxGroup !== 'ignored',
|
|
7727
8039
|
deferEnabled: canReviewDefer(item),
|
|
7728
8040
|
ignoreEnabled: canReviewIgnore(item),
|
|
@@ -7812,16 +8124,15 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7812
8124
|
});
|
|
7813
8125
|
if (primaryButton) primaryButton.disabled = false;
|
|
7814
8126
|
if (!result.ok) {
|
|
7815
|
-
|
|
7816
|
-
|
|
8127
|
+
const feedback = formatLauncherActionFeedback(result, 'Registration failed.');
|
|
8128
|
+
setDiscoveryReviewStatus(feedback.message, 'warn');
|
|
8129
|
+
setActivityMessage(feedback.activity, 'warn');
|
|
8130
|
+
setReviewResolutionActions('discovery-review', feedback.resolutionActions || []);
|
|
7817
8131
|
return;
|
|
7818
8132
|
}
|
|
8133
|
+
resetReviewResolutionActions('discovery-review');
|
|
7819
8134
|
setDiscoveryReviewStatus(result.message || 'Registration updated.', 'ok');
|
|
7820
|
-
|
|
7821
|
-
await refreshAll();
|
|
7822
|
-
if (result.gaid || result.passportGaid) {
|
|
7823
|
-
await openDiscoveryContext(item);
|
|
7824
|
-
}
|
|
8135
|
+
await completeRegistrationSuccess(item, result);
|
|
7825
8136
|
}
|
|
7826
8137
|
|
|
7827
8138
|
async function submitDiscoveryReviewDefer() {
|
|
@@ -7837,6 +8148,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7837
8148
|
setDiscoveryReviewStatus(result.message || 'Review deferred.', result.ok ? 'ok' : 'warn');
|
|
7838
8149
|
setActivityMessage(result.message || 'Review deferred.', result.ok ? 'ok' : 'warn');
|
|
7839
8150
|
await refreshAll();
|
|
8151
|
+
resetReviewResolutionActions('discovery-review');
|
|
7840
8152
|
}
|
|
7841
8153
|
|
|
7842
8154
|
async function submitDiscoveryReviewIgnore() {
|
|
@@ -7852,6 +8164,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7852
8164
|
setDiscoveryReviewStatus(result.message || 'Item ignored locally.', result.ok ? 'ok' : 'warn');
|
|
7853
8165
|
setActivityMessage(result.message || 'Item ignored locally.', result.ok ? 'ok' : 'warn');
|
|
7854
8166
|
await refreshAll();
|
|
8167
|
+
resetReviewResolutionActions('discovery-review');
|
|
7855
8168
|
}
|
|
7856
8169
|
|
|
7857
8170
|
function setProfileAvatar(rootId, imageId, initialsId, initials, avatarUrl) {
|
|
@@ -8562,6 +8875,30 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8562
8875
|
});
|
|
8563
8876
|
}
|
|
8564
8877
|
|
|
8878
|
+
function focusScopeField(fieldId) {
|
|
8879
|
+
const field = document.getElementById(fieldId);
|
|
8880
|
+
if (field && typeof field.focus === 'function') {
|
|
8881
|
+
window.setTimeout(() => {
|
|
8882
|
+
field.focus();
|
|
8883
|
+
if (typeof field.select === 'function') {
|
|
8884
|
+
field.select();
|
|
8885
|
+
}
|
|
8886
|
+
}, 0);
|
|
8887
|
+
}
|
|
8888
|
+
}
|
|
8889
|
+
|
|
8890
|
+
function openScopeCreateWorkspaceFlow(statusMessage, tone) {
|
|
8891
|
+
toggleScopeCreatePanel('scope-create-workspace-panel', true);
|
|
8892
|
+
setScopeStatus(statusMessage || 'Create a governed workspace for this registration flow.', tone || '');
|
|
8893
|
+
focusScopeField('scope-create-workspace-name');
|
|
8894
|
+
}
|
|
8895
|
+
|
|
8896
|
+
function openScopeCreateProjectFlow(statusMessage, tone) {
|
|
8897
|
+
toggleScopeCreatePanel('scope-create-project-panel', true);
|
|
8898
|
+
setScopeStatus(statusMessage || 'Create a governed project inside the selected workspace.', tone || '');
|
|
8899
|
+
focusScopeField('scope-create-project-only-name');
|
|
8900
|
+
}
|
|
8901
|
+
|
|
8565
8902
|
function setScopeCreateButtonsEnabled(enabled) {
|
|
8566
8903
|
['scope-open-create-workspace', 'scope-open-create-project'].forEach((id) => {
|
|
8567
8904
|
const button = document.getElementById(id);
|
|
@@ -8574,11 +8911,11 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8574
8911
|
async function loadScopeProjects(workspaceId, selectedProjectId) {
|
|
8575
8912
|
const projectSelect = document.getElementById('scope-project-select');
|
|
8576
8913
|
const registerButton = document.getElementById('scope-register-button');
|
|
8577
|
-
if (!projectSelect) return;
|
|
8914
|
+
if (!projectSelect) return false;
|
|
8578
8915
|
if (!workspaceId) {
|
|
8579
8916
|
setScopeOptions(projectSelect, [{ id: '', label: 'Account scope / no project' }], '');
|
|
8580
8917
|
if (registerButton) registerButton.disabled = false;
|
|
8581
|
-
return;
|
|
8918
|
+
return true;
|
|
8582
8919
|
}
|
|
8583
8920
|
setScopeOptions(projectSelect, [{ id: '', label: 'Loading projects...' }], '');
|
|
8584
8921
|
try {
|
|
@@ -8591,21 +8928,37 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8591
8928
|
setScopeOptions(projectSelect, options, selectedProjectId || (options[0] && options[0].id) || '');
|
|
8592
8929
|
if (!payload.ok) {
|
|
8593
8930
|
setScopeStatus(payload.message || 'Project list unavailable. Create a project here, then retry.', 'warn');
|
|
8931
|
+
return false;
|
|
8594
8932
|
} else if (!projects.length) {
|
|
8595
|
-
|
|
8933
|
+
openScopeCreateProjectFlow('No governed project exists in this workspace yet. Create one here to continue.', 'warn');
|
|
8934
|
+
return false;
|
|
8596
8935
|
}
|
|
8597
8936
|
if (registerButton) {
|
|
8598
8937
|
registerButton.disabled = !projects.length;
|
|
8599
8938
|
}
|
|
8939
|
+
return projects.length > 0;
|
|
8600
8940
|
} catch {
|
|
8601
8941
|
setScopeOptions(projectSelect, [{ id: '', label: 'Project list unavailable' }], '');
|
|
8602
8942
|
setScopeStatus('Project list unavailable. Create a project here, then retry.', 'warn');
|
|
8603
8943
|
if (registerButton) {
|
|
8604
8944
|
registerButton.disabled = true;
|
|
8605
8945
|
}
|
|
8946
|
+
return false;
|
|
8606
8947
|
}
|
|
8607
8948
|
}
|
|
8608
8949
|
|
|
8950
|
+
async function continuePendingScopeRegistration(statusMessage) {
|
|
8951
|
+
const item = pendingDiscoveryRegistration;
|
|
8952
|
+
if (!item) return false;
|
|
8953
|
+
const workspaceSelect = document.getElementById('scope-workspace-select');
|
|
8954
|
+
const projectSelect = document.getElementById('scope-project-select');
|
|
8955
|
+
const workspaceId = workspaceSelect ? String(workspaceSelect.value || '').trim() : '';
|
|
8956
|
+
const projectId = projectSelect ? String(projectSelect.value || '').trim() : '';
|
|
8957
|
+
if (!workspaceId || !projectId) return false;
|
|
8958
|
+
setScopeStatus(statusMessage || 'Continuing registration…', 'warn');
|
|
8959
|
+
return submitRegistrationScopeDialog();
|
|
8960
|
+
}
|
|
8961
|
+
|
|
8609
8962
|
async function createScopeWorkspace() {
|
|
8610
8963
|
const nameInput = document.getElementById('scope-create-workspace-name');
|
|
8611
8964
|
const descriptionInput = document.getElementById('scope-create-workspace-description');
|
|
@@ -8638,12 +8991,20 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8638
8991
|
if (firstProjectInput) firstProjectInput.value = '';
|
|
8639
8992
|
toggleScopeCreatePanel(null, false);
|
|
8640
8993
|
const workspaceSelect = document.getElementById('scope-workspace-select');
|
|
8994
|
+
const projectSelect = document.getElementById('scope-project-select');
|
|
8641
8995
|
const createdWorkspaceId = result.workspace && result.workspace.id ? result.workspace.id : '';
|
|
8996
|
+
const createdProjectId = result.project && result.project.id ? result.project.id : '';
|
|
8642
8997
|
scopeAccessSnapshot = result.scope || scopeAccessSnapshot;
|
|
8643
8998
|
if (workspaceSelect && createdWorkspaceId) {
|
|
8644
8999
|
await openRegistrationScopeDialog(pendingDiscoveryRegistration);
|
|
8645
9000
|
workspaceSelect.value = createdWorkspaceId;
|
|
8646
|
-
await loadScopeProjects(createdWorkspaceId,
|
|
9001
|
+
const hasProjects = await loadScopeProjects(createdWorkspaceId, createdProjectId);
|
|
9002
|
+
if (projectSelect && createdProjectId) {
|
|
9003
|
+
projectSelect.value = createdProjectId;
|
|
9004
|
+
}
|
|
9005
|
+
if (hasProjects && createdProjectId && await continuePendingScopeRegistration('Workspace and project created. Continuing registration...')) {
|
|
9006
|
+
return;
|
|
9007
|
+
}
|
|
8647
9008
|
}
|
|
8648
9009
|
setScopeStatus(result.message || 'Workspace created.', 'ok');
|
|
8649
9010
|
}
|
|
@@ -8681,10 +9042,14 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8681
9042
|
if (nameInput) nameInput.value = '';
|
|
8682
9043
|
if (descriptionInput) descriptionInput.value = '';
|
|
8683
9044
|
toggleScopeCreatePanel(null, false);
|
|
8684
|
-
|
|
9045
|
+
const createdProjectId = result.project && result.project.id ? result.project.id : '';
|
|
9046
|
+
const hasProjects = await loadScopeProjects(workspaceId, createdProjectId);
|
|
8685
9047
|
const projectSelect = document.getElementById('scope-project-select');
|
|
8686
|
-
if (projectSelect &&
|
|
8687
|
-
projectSelect.value =
|
|
9048
|
+
if (projectSelect && createdProjectId) {
|
|
9049
|
+
projectSelect.value = createdProjectId;
|
|
9050
|
+
}
|
|
9051
|
+
if (hasProjects && createdProjectId && await continuePendingScopeRegistration('Project created. Continuing registration...')) {
|
|
9052
|
+
return;
|
|
8688
9053
|
}
|
|
8689
9054
|
setScopeStatus(result.message || 'Project created.', 'ok');
|
|
8690
9055
|
}
|
|
@@ -8730,18 +9095,20 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8730
9095
|
if (governedMode && !options.length) {
|
|
8731
9096
|
options.push({ id: '', label: 'No governed workspaces yet' });
|
|
8732
9097
|
registerButton.disabled = true;
|
|
8733
|
-
|
|
9098
|
+
openScopeCreateWorkspaceFlow('No governed workspace exists yet. Create one here to continue.', 'warn');
|
|
8734
9099
|
}
|
|
8735
9100
|
const selectedWorkspace = payload.currentWorkspaceId || (options[0] && options[0].id) || '';
|
|
8736
9101
|
setScopeOptions(workspaceSelect, options, selectedWorkspace);
|
|
8737
|
-
await loadScopeProjects(workspaceSelect.value, payload.currentProjectId || '');
|
|
8738
|
-
registerButton.disabled = !payload.ok || (governedMode && !String(workspaceSelect.value || '').trim());
|
|
8739
|
-
|
|
8740
|
-
|
|
8741
|
-
|
|
8742
|
-
|
|
8743
|
-
|
|
8744
|
-
|
|
9102
|
+
const hasProjects = await loadScopeProjects(workspaceSelect.value, payload.currentProjectId || '');
|
|
9103
|
+
registerButton.disabled = !payload.ok || (governedMode && (!String(workspaceSelect.value || '').trim() || !hasProjects));
|
|
9104
|
+
if (payload.ok && (!governedMode || hasProjects)) {
|
|
9105
|
+
setScopeStatus(governedMode ? 'Ready to register in governed scope.' : 'Ready to register.', '');
|
|
9106
|
+
} else if (!payload.ok) {
|
|
9107
|
+
setScopeStatus(
|
|
9108
|
+
payload.message || (governedMode ? 'Workspace list unavailable.' : 'Workspace list unavailable. Account scope is still available.'),
|
|
9109
|
+
'warn',
|
|
9110
|
+
);
|
|
9111
|
+
}
|
|
8745
9112
|
} catch {
|
|
8746
9113
|
setScopeOptions(workspaceSelect, governedMode ? [] : [{ id: '', label: 'Account scope / no workspace' }], '');
|
|
8747
9114
|
await loadScopeProjects(governedMode ? (workspaceSelect.value || '') : '', '');
|
|
@@ -8761,7 +9128,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8761
9128
|
|
|
8762
9129
|
async function submitRegistrationScopeDialog() {
|
|
8763
9130
|
const item = pendingDiscoveryRegistration;
|
|
8764
|
-
if (!item) return;
|
|
9131
|
+
if (!item) return false;
|
|
8765
9132
|
const workspaceSelect = document.getElementById('scope-workspace-select');
|
|
8766
9133
|
const projectSelect = document.getElementById('scope-project-select');
|
|
8767
9134
|
const registerButton = document.getElementById('scope-register-button');
|
|
@@ -8769,7 +9136,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8769
9136
|
const projectId = projectSelect ? projectSelect.value : '';
|
|
8770
9137
|
if (workspaceId && !projectId) {
|
|
8771
9138
|
setScopeStatus('Select a project for the chosen workspace, or use account scope.', 'warn');
|
|
8772
|
-
return;
|
|
9139
|
+
return false;
|
|
8773
9140
|
}
|
|
8774
9141
|
if (registerButton) registerButton.disabled = true;
|
|
8775
9142
|
const endpoint = item.kind === 'agent' ? '/api/discovery/connect-agent' : '/api/discovery/connect-model';
|
|
@@ -8781,14 +9148,14 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8781
9148
|
});
|
|
8782
9149
|
if (registerButton) registerButton.disabled = false;
|
|
8783
9150
|
if (!result.ok) {
|
|
8784
|
-
|
|
8785
|
-
|
|
8786
|
-
|
|
9151
|
+
const feedback = formatLauncherActionFeedback(result, 'Registration failed.');
|
|
9152
|
+
setScopeStatus(feedback.message, 'warn');
|
|
9153
|
+
setActivityMessage(feedback.activity, 'warn');
|
|
9154
|
+
return false;
|
|
8787
9155
|
}
|
|
8788
9156
|
closeRegistrationScopeDialog();
|
|
8789
|
-
|
|
8790
|
-
|
|
8791
|
-
setView('passports');
|
|
9157
|
+
await completeRegistrationSuccess(item, result);
|
|
9158
|
+
return true;
|
|
8792
9159
|
}
|
|
8793
9160
|
|
|
8794
9161
|
const VIEW_TITLES = {
|
|
@@ -9640,6 +10007,18 @@ function renderLauncherHtml(launcherToken) {
|
|
|
9640
10007
|
void submitQuickReviewPrimary();
|
|
9641
10008
|
});
|
|
9642
10009
|
}
|
|
10010
|
+
const quickReviewResolutionPrimary = document.getElementById('quick-review-resolution-primary');
|
|
10011
|
+
if (quickReviewResolutionPrimary) {
|
|
10012
|
+
quickReviewResolutionPrimary.addEventListener('click', () => {
|
|
10013
|
+
void handleReviewResolutionAction('quick-review', String(quickReviewResolutionPrimary.dataset.action || '').trim());
|
|
10014
|
+
});
|
|
10015
|
+
}
|
|
10016
|
+
const quickReviewResolutionSecondary = document.getElementById('quick-review-resolution-secondary');
|
|
10017
|
+
if (quickReviewResolutionSecondary) {
|
|
10018
|
+
quickReviewResolutionSecondary.addEventListener('click', () => {
|
|
10019
|
+
void handleReviewResolutionAction('quick-review', String(quickReviewResolutionSecondary.dataset.action || '').trim());
|
|
10020
|
+
});
|
|
10021
|
+
}
|
|
9643
10022
|
const quickReviewOptionsButton = document.getElementById('quick-review-options');
|
|
9644
10023
|
if (quickReviewOptionsButton) {
|
|
9645
10024
|
quickReviewOptionsButton.addEventListener('click', (event) => {
|
|
@@ -9706,6 +10085,18 @@ function renderLauncherHtml(launcherToken) {
|
|
|
9706
10085
|
void submitDiscoveryReviewPrimary();
|
|
9707
10086
|
});
|
|
9708
10087
|
}
|
|
10088
|
+
const discoveryReviewResolutionPrimary = document.getElementById('discovery-review-resolution-primary');
|
|
10089
|
+
if (discoveryReviewResolutionPrimary) {
|
|
10090
|
+
discoveryReviewResolutionPrimary.addEventListener('click', () => {
|
|
10091
|
+
void handleReviewResolutionAction('discovery-review', String(discoveryReviewResolutionPrimary.dataset.action || '').trim());
|
|
10092
|
+
});
|
|
10093
|
+
}
|
|
10094
|
+
const discoveryReviewResolutionSecondary = document.getElementById('discovery-review-resolution-secondary');
|
|
10095
|
+
if (discoveryReviewResolutionSecondary) {
|
|
10096
|
+
discoveryReviewResolutionSecondary.addEventListener('click', () => {
|
|
10097
|
+
void handleReviewResolutionAction('discovery-review', String(discoveryReviewResolutionSecondary.dataset.action || '').trim());
|
|
10098
|
+
});
|
|
10099
|
+
}
|
|
9709
10100
|
const discoveryReviewDeferBtn = document.getElementById('discovery-review-defer');
|
|
9710
10101
|
if (discoveryReviewDeferBtn) {
|
|
9711
10102
|
discoveryReviewDeferBtn.addEventListener('click', () => {
|
|
@@ -9896,12 +10287,10 @@ function renderLauncherHtml(launcherToken) {
|
|
|
9896
10287
|
});
|
|
9897
10288
|
});
|
|
9898
10289
|
document.getElementById('scope-open-create-workspace').addEventListener('click', () => {
|
|
9899
|
-
|
|
9900
|
-
setScopeStatus('Create a governed workspace for this registration flow.', '');
|
|
10290
|
+
openScopeCreateWorkspaceFlow('Create a governed workspace for this registration flow.', '');
|
|
9901
10291
|
});
|
|
9902
10292
|
document.getElementById('scope-open-create-project').addEventListener('click', () => {
|
|
9903
|
-
|
|
9904
|
-
setScopeStatus('Create a governed project inside the selected workspace.', '');
|
|
10293
|
+
openScopeCreateProjectFlow('Create a governed project inside the selected workspace.', '');
|
|
9905
10294
|
});
|
|
9906
10295
|
document.getElementById('scope-cancel-create-workspace').addEventListener('click', () => {
|
|
9907
10296
|
toggleScopeCreatePanel(null, false);
|
|
@@ -10411,8 +10800,13 @@ function createLauncherApp(options) {
|
|
|
10411
10800
|
});
|
|
10412
10801
|
}
|
|
10413
10802
|
catch (error) {
|
|
10414
|
-
const
|
|
10415
|
-
response.status(400).json({
|
|
10803
|
+
const normalizedFailure = normalizeDiscoveryRegistrationFailure(error instanceof Error ? error.message : 'model_connect_failed');
|
|
10804
|
+
response.status(400).json({
|
|
10805
|
+
ok: false,
|
|
10806
|
+
code: normalizedFailure.code,
|
|
10807
|
+
message: normalizedFailure.message,
|
|
10808
|
+
nextActions: normalizedFailure.nextActions ?? [],
|
|
10809
|
+
});
|
|
10416
10810
|
}
|
|
10417
10811
|
});
|
|
10418
10812
|
app.post('/api/discovery/connect-agent', async (request, response) => {
|
|
@@ -10445,15 +10839,14 @@ function createLauncherApp(options) {
|
|
|
10445
10839
|
? String(agentMetadata.registration_error_status)
|
|
10446
10840
|
: safeStringRecordValue(agentMetadata, ['registration_error_status', 'registrationErrorStatus']);
|
|
10447
10841
|
if (trackingStatus === 'registration_failed') {
|
|
10448
|
-
const
|
|
10449
|
-
||
|
|
10450
|
-
|
|
10451
|
-
: registrationErrorStatus
|
|
10452
|
-
? ('Agent registration failed with backend status ' + registrationErrorStatus + '.')
|
|
10453
|
-
: 'Agent registration failed.');
|
|
10842
|
+
const normalizedFailure = normalizeDiscoveryRegistrationFailure(registrationErrorCode
|
|
10843
|
+
|| registrationErrorMessage
|
|
10844
|
+
|| (registrationErrorStatus ? `DRAFT_CREATE_FAILED:${registrationErrorStatus}` : 'agent_connect_failed'));
|
|
10454
10845
|
response.json({
|
|
10455
10846
|
ok: false,
|
|
10456
|
-
|
|
10847
|
+
code: normalizedFailure.code,
|
|
10848
|
+
message: normalizedFailure.message,
|
|
10849
|
+
nextActions: normalizedFailure.nextActions ?? [],
|
|
10457
10850
|
agentId: agent.agent_id,
|
|
10458
10851
|
agentName: agent.agent_name,
|
|
10459
10852
|
action: 'retry',
|
|
@@ -10480,8 +10873,13 @@ function createLauncherApp(options) {
|
|
|
10480
10873
|
});
|
|
10481
10874
|
}
|
|
10482
10875
|
catch (error) {
|
|
10483
|
-
const
|
|
10484
|
-
response.status(400).json({
|
|
10876
|
+
const normalizedFailure = normalizeDiscoveryRegistrationFailure(error instanceof Error ? error.message : 'agent_connect_failed');
|
|
10877
|
+
response.status(400).json({
|
|
10878
|
+
ok: false,
|
|
10879
|
+
code: normalizedFailure.code,
|
|
10880
|
+
message: normalizedFailure.message,
|
|
10881
|
+
nextActions: normalizedFailure.nextActions ?? [],
|
|
10882
|
+
});
|
|
10485
10883
|
}
|
|
10486
10884
|
});
|
|
10487
10885
|
app.post('/api/discovery/review/defer', (request, response) => {
|