forkit-connect 0.1.7 → 0.1.8

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 CHANGED
@@ -1427,6 +1427,11 @@ function formatSmartInboxActionValue(action, itemType, connectableModelName) {
1427
1427
  }
1428
1428
  }
1429
1429
  function formatSmartInboxActionLabel(item) {
1430
+ if (item.item_type === 'model'
1431
+ && item.recommended_action === 'create_passport_draft'
1432
+ && String(item.details_received_automatically.registration_flow_state || '').trim() === 'private_draft_required') {
1433
+ return 'Open Draft Path';
1434
+ }
1430
1435
  return formatSmartInboxActionValue(item.recommended_action, item.item_type, String(item.details_received_automatically.connectable_model_name || '').trim());
1431
1436
  }
1432
1437
  function printInboxGroup(label, items) {
@@ -2850,6 +2855,8 @@ async function run() {
2850
2855
  const detailKeys = [
2851
2856
  'verification_summary',
2852
2857
  'limitations_summary',
2858
+ 'registration_guidance',
2859
+ 'registration_error_message',
2853
2860
  'scope_suggestion',
2854
2861
  'scope_mismatch_reason',
2855
2862
  'connectable_model_name',
package/dist/launcher.js CHANGED
@@ -676,6 +676,9 @@ function buildDiscovery(service) {
676
676
  const registeredPassportName = getInboxDetailText(entry, 'registered_passport_name');
677
677
  const scopeSuggestion = getInboxDetailText(entry, 'scope_suggestion');
678
678
  const verificationSummary = getInboxDetailText(entry, 'verification_summary');
679
+ const registrationState = getInboxDetailText(entry, 'registration_flow_state');
680
+ const registrationGuidance = getInboxDetailText(entry, 'registration_guidance')
681
+ ?? getInboxDetailText(entry, 'registration_error_message');
679
682
  const matchReason = entry.match_reason;
680
683
  const draftPending = binding?.status === 'pending';
681
684
  let statusLabel = 'Ready to register';
@@ -697,6 +700,13 @@ function buildDiscovery(service) {
697
700
  actionLabel = 'Review';
698
701
  actionTone = 'accent';
699
702
  }
703
+ else if (registrationState === 'private_draft_required') {
704
+ statusLabel = 'Draft first';
705
+ statusMeta = registrationGuidance ?? 'This model needs to go through the private draft path before publishing.';
706
+ statusTone = 'warn';
707
+ actionLabel = 'Review';
708
+ actionTone = 'accent';
709
+ }
700
710
  else if (group === 'connected') {
701
711
  statusLabel = 'Registered';
702
712
  statusMeta = registeredPassportName
@@ -408,6 +408,7 @@ export declare class ConnectV1Service {
408
408
  private hasExactBoundPassportForModel;
409
409
  private runtimeHasExactBoundModelDuplicate;
410
410
  private clearModelReviewDeferral;
411
+ private updateDetectedModelRegistrationHint;
411
412
  private buildPassportMatchSuggestionForModel;
412
413
  private normalizeRemotePassportList;
413
414
  private loadRemoteWorkspaceNameMaps;
@@ -2287,6 +2287,33 @@ class ConnectV1Service {
2287
2287
  : item);
2288
2288
  this.stateStore.replaceDetectedModels(nextModels);
2289
2289
  }
2290
+ updateDetectedModelRegistrationHint(model, input) {
2291
+ const nextModels = this.stateStore.readState().detected_models.map((item) => {
2292
+ if (item.discoveryHash !== model.discoveryHash) {
2293
+ return item;
2294
+ }
2295
+ const nextMetadata = {
2296
+ ...(item.metadata && typeof item.metadata === 'object' ? item.metadata : {}),
2297
+ };
2298
+ const assignOrDelete = (key, value) => {
2299
+ if (value === null || value === undefined || value === '') {
2300
+ delete nextMetadata[key];
2301
+ return;
2302
+ }
2303
+ nextMetadata[key] = value;
2304
+ };
2305
+ assignOrDelete('tracking_status', input.trackingStatus ?? null);
2306
+ assignOrDelete('registration_error_code', input.errorCode ?? null);
2307
+ assignOrDelete('registration_error_message', input.errorMessage ?? null);
2308
+ assignOrDelete('registration_error_status', typeof input.errorStatus === 'number' ? input.errorStatus : null);
2309
+ assignOrDelete('registration_guidance', input.guidance ?? null);
2310
+ return {
2311
+ ...item,
2312
+ metadata: nextMetadata,
2313
+ };
2314
+ });
2315
+ this.stateStore.replaceDetectedModels(nextModels);
2316
+ }
2290
2317
  buildPassportMatchSuggestionForModel(state, model, runtimePassport) {
2291
2318
  const registrationKey = (0, discovery_1.buildModelRegistrationKey)(model, state.runtime_identity.runtimeId);
2292
2319
  const candidates = state.model_bindings
@@ -4305,6 +4332,10 @@ class ConnectV1Service {
4305
4332
  const observedProjectId = normalizeDisplayText(modelMetadata.projectId ?? modelMetadata.project_id);
4306
4333
  const scopeSuggestion = this.resolveScopeSuggestion(refreshedState, observedWorkspaceId, observedProjectId);
4307
4334
  const itemId = this.buildInboxItemId('model', model.discoveryHash);
4335
+ const registrationTrackingStatus = normalizeDisplayText(modelMetadata.tracking_status);
4336
+ const registrationErrorMessage = normalizeDisplayText(modelMetadata.registration_error_message);
4337
+ const registrationErrorCode = normalizeDisplayText(modelMetadata.registration_error_code);
4338
+ const registrationGuidance = normalizeDisplayText(modelMetadata.registration_guidance);
4308
4339
  const recommendedAction = binding?.status === 'bound'
4309
4340
  ? 'open_on_forkit'
4310
4341
  : suggestion.match_confidence === 'medium'
@@ -4371,6 +4402,10 @@ class ConnectV1Service {
4371
4402
  registered_workspace_name: binding?.workspaceName ?? null,
4372
4403
  registered_project_name: binding?.projectName ?? null,
4373
4404
  remote_match_source: binding?.remoteMatchSource ?? null,
4405
+ registration_flow_state: registrationTrackingStatus,
4406
+ registration_error_message: registrationErrorMessage,
4407
+ registration_error_code: registrationErrorCode,
4408
+ registration_guidance: registrationGuidance,
4374
4409
  verification_summary: verification.verification,
4375
4410
  limitations_summary: verification.limitations,
4376
4411
  review_disposition: reviewDisposition,
@@ -7798,6 +7833,13 @@ class ConnectV1Service {
7798
7833
  ? 'public'
7799
7834
  : 'private';
7800
7835
  this.clearModelReviewDeferral(model);
7836
+ this.updateDetectedModelRegistrationHint(model, {
7837
+ trackingStatus: null,
7838
+ errorCode: null,
7839
+ errorMessage: null,
7840
+ errorStatus: null,
7841
+ guidance: null,
7842
+ });
7801
7843
  const { payload, registrationKey } = this.buildConnectDraftPayload(model, state, draftScope, {
7802
7844
  visibility: requestedVisibility,
7803
7845
  });
@@ -7939,6 +7981,16 @@ class ConnectV1Service {
7939
7981
  const api = this.getApiClient(state);
7940
7982
  const result = await api.createPassportDraft(payload);
7941
7983
  if (!result.ok) {
7984
+ const backendCode = extractApiErrorCode(result.body) || `DRAFT_CREATE_FAILED:${result.status}`;
7985
+ if (backendCode === 'INVALID_DRAFT_VISIBILITY') {
7986
+ this.updateDetectedModelRegistrationHint(model, {
7987
+ trackingStatus: 'private_draft_required',
7988
+ errorCode: backendCode,
7989
+ errorMessage: 'This registration must start as a private draft before it can be published.',
7990
+ errorStatus: result.status,
7991
+ guidance: 'Open the review flow and continue through the private draft path first.',
7992
+ });
7993
+ }
7942
7994
  this.observeBackendCommunicationState({
7943
7995
  passportGaid: bindingWithRuntime?.gaid ?? null,
7944
7996
  runtimeGaid: runtimePassport?.runtime_gaid ?? null,
@@ -7947,7 +7999,7 @@ class ConnectV1Service {
7947
7999
  body: result.body,
7948
8000
  source: 'draft_sync',
7949
8001
  });
7950
- throw new Error(result.status === 409 ? 'DRAFT_ALREADY_EXISTS' : (extractApiErrorCode(result.body) || `DRAFT_CREATE_FAILED:${result.status}`));
8002
+ throw new Error(result.status === 409 ? 'DRAFT_ALREADY_EXISTS' : backendCode);
7951
8003
  }
7952
8004
  const parsed = this.parseDraftResponse(result);
7953
8005
  let finalGaid = parsed.gaid;
package/dist/v1/state.js CHANGED
@@ -938,8 +938,30 @@ class LocalStateStore {
938
938
  const seen = new Map();
939
939
  for (const model of models) {
940
940
  const existing = state.detected_models.find((item) => item.discoveryHash === model.discoveryHash);
941
+ const nextMetadata = model.metadata && typeof model.metadata === 'object'
942
+ ? { ...model.metadata }
943
+ : {};
944
+ const existingMetadata = existing?.metadata && typeof existing.metadata === 'object'
945
+ ? existing.metadata
946
+ : null;
947
+ if (existingMetadata) {
948
+ for (const key of [
949
+ 'draft_id',
950
+ 'passport_gaid',
951
+ 'tracking_status',
952
+ 'registration_error_code',
953
+ 'registration_error_message',
954
+ 'registration_error_status',
955
+ 'registration_guidance',
956
+ ]) {
957
+ if (!Object.prototype.hasOwnProperty.call(nextMetadata, key) && Object.prototype.hasOwnProperty.call(existingMetadata, key)) {
958
+ nextMetadata[key] = existingMetadata[key];
959
+ }
960
+ }
961
+ }
941
962
  seen.set(model.discoveryHash, {
942
963
  ...model,
964
+ metadata: nextMetadata,
943
965
  status: model.status === 'ignored' || model.status === 'bound'
944
966
  ? model.status
945
967
  : existing?.status === 'ignored' || existing?.status === 'bound'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forkit-connect",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Forkit Connect Local Engine - The Global AI Governance Fabric",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",