forkit-connect 0.1.0 → 0.1.3

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.
@@ -77,6 +77,7 @@ export declare class LocalStateStore {
77
77
  private withDatabase;
78
78
  private getDb;
79
79
  private persistState;
80
+ private persistStateInPlace;
80
81
  private loadRawStateRecord;
81
82
  private readLegacyStateFile;
82
83
  private ensureStateDirectory;
package/dist/v1/state.js CHANGED
@@ -74,6 +74,8 @@ const STATE_SECTION_NAMES = [
74
74
  'sync_queue',
75
75
  'pending_reviews',
76
76
  'lifecycle_monitor_records',
77
+ 'smart_inbox_snapshot',
78
+ 'smart_inbox_snapshot_updated_at',
77
79
  ];
78
80
  function hashCredentialRef(value) {
79
81
  return (0, node_crypto_1.createHash)('sha256').update(value, 'utf8').digest('hex').slice(0, 24);
@@ -430,6 +432,12 @@ function normalizeState(parsed) {
430
432
  sync_queue: Array.isArray(value.sync_queue) ? value.sync_queue : [],
431
433
  pending_reviews: Array.isArray(value.pending_reviews) ? value.pending_reviews : [],
432
434
  lifecycle_monitor_records: Array.isArray(value.lifecycle_monitor_records) ? value.lifecycle_monitor_records : [],
435
+ smart_inbox_snapshot: value.smart_inbox_snapshot && typeof value.smart_inbox_snapshot === 'object'
436
+ ? value.smart_inbox_snapshot
437
+ : null,
438
+ smart_inbox_snapshot_updated_at: typeof value.smart_inbox_snapshot_updated_at === 'string'
439
+ ? value.smart_inbox_snapshot_updated_at
440
+ : null,
433
441
  };
434
442
  }
435
443
  function buildInitialState() {
@@ -478,6 +486,8 @@ function buildInitialState() {
478
486
  sync_queue: [],
479
487
  pending_reviews: [],
480
488
  lifecycle_monitor_records: [],
489
+ smart_inbox_snapshot: null,
490
+ smart_inbox_snapshot_updated_at: null,
481
491
  };
482
492
  }
483
493
  function readJsonFile(filePath) {
@@ -1101,11 +1111,18 @@ class LocalStateStore {
1101
1111
  node_fs_1.default.rmSync(this.paths.legacyStateFile, { force: true });
1102
1112
  }
1103
1113
  mutateState(mutator) {
1104
- const state = this.ensureInitialized();
1105
- mutator(state);
1106
- const normalized = normalizeState(state);
1107
- this.writeState(normalized);
1108
- return normalized;
1114
+ this.ensureInitializedInternal();
1115
+ return this.withDatabase((db) => {
1116
+ const mutate = db.transaction(() => {
1117
+ const raw = this.loadRawStateRecord(db);
1118
+ const state = raw ? normalizeState(raw) : buildInitialState();
1119
+ mutator(state);
1120
+ const normalized = normalizeState(state);
1121
+ this.persistStateInPlace(db, normalized);
1122
+ return normalized;
1123
+ });
1124
+ return mutate.immediate();
1125
+ }, true);
1109
1126
  }
1110
1127
  ensureInitializedInternal() {
1111
1128
  this.withDatabase((db) => {
@@ -1199,6 +1216,12 @@ class LocalStateStore {
1199
1216
  }
1200
1217
  persistState(db, state) {
1201
1218
  const normalized = normalizeState(state);
1219
+ const persist = db.transaction((nextState) => {
1220
+ this.persistStateInPlace(db, nextState);
1221
+ });
1222
+ persist(normalized);
1223
+ }
1224
+ persistStateInPlace(db, state) {
1202
1225
  const updatedAt = nowIso();
1203
1226
  const upsertSection = db.prepare(`
1204
1227
  INSERT INTO connect_state_sections (section_name, payload_json, updated_at)
@@ -1214,13 +1237,10 @@ class LocalStateStore {
1214
1237
  value = excluded.value,
1215
1238
  updated_at = excluded.updated_at
1216
1239
  `);
1217
- const persist = db.transaction((nextState) => {
1218
- for (const sectionName of STATE_SECTION_NAMES) {
1219
- upsertSection.run(sectionName, JSON.stringify(nextState[sectionName] ?? null), updatedAt);
1220
- }
1221
- upsertMeta.run('last_state_write_at', updatedAt, updatedAt);
1222
- });
1223
- persist(normalized);
1240
+ for (const sectionName of STATE_SECTION_NAMES) {
1241
+ upsertSection.run(sectionName, JSON.stringify(state[sectionName] ?? null), updatedAt);
1242
+ }
1243
+ upsertMeta.run('last_state_write_at', updatedAt, updatedAt);
1224
1244
  }
1225
1245
  loadRawStateRecord(db) {
1226
1246
  const rows = db.prepare(`
@@ -12,6 +12,7 @@ export type RegistrationState = 'registered' | 'unregistered' | 'unknown';
12
12
  export type ModelBindingStatus = 'pending' | 'bound' | 'ignored';
13
13
  export type ReviewStatus = 'new_unregistered' | 'known_unregistered' | 'pending_draft' | 'bound_passport' | 'shadow_candidate' | 'provider_unavailable';
14
14
  export type AgentType = 'coding_agent' | 'local_agent_runtime' | 'mcp_server' | 'ide_extension' | 'workflow_automation' | 'unknown_ai_tool';
15
+ export type AgentClass = 'interactive_assistant' | 'background_automation' | 'evaluator_reviewer' | 'orchestrator' | 'retrieval_tool_worker';
15
16
  export type AgentStatus = 'detected' | 'connected' | 'inactive';
16
17
  export type AgentReviewStatus = 'new_agent' | 'known_agent' | 'linked_agent' | 'inactive_agent' | 'unknown_ai_tool';
17
18
  export type AgentDiscoverySource = 'process_scan' | 'daemon_scan' | 'manual_connect' | 'manual_link';
@@ -300,6 +301,16 @@ export interface ExistingPassportMatchSuggestion {
300
301
  match_confidence: RuntimePassportConfidence;
301
302
  match_reason: string;
302
303
  }
304
+ /**
305
+ * SmartRegistrationInboxItem represents a single onboarding candidate in the Smart Inbox.
306
+ *
307
+ * **Scope (M1 Inbox Boundary Contract):**
308
+ * - This inbox is an ONBOARDING/EXCEPTION decision queue, NOT a long-term telemetry surface.
309
+ * - Items represent: unregistered runtimes/models/agents requiring user action, or known items needing exception handling.
310
+ * - Items with status='connected' and no action required are filtered out (deferred to C2 dashboard for telemetry).
311
+ * - `details_received_automatically` EXCLUDES long-term operational data: no cost, token usage, latency buckets, or provider-specific metrics.
312
+ * - This keeps inbox lightweight and focused on registration decisions, not performance analysis.
313
+ */
303
314
  export interface SmartRegistrationInboxItem {
304
315
  item_id: string;
305
316
  item_type: SmartRegistrationInboxItemType;
@@ -316,6 +327,12 @@ export interface SmartRegistrationInboxItem {
316
327
  confidence: RuntimePassportConfidence;
317
328
  recommended_action: SmartRegistrationInboxAction;
318
329
  allowed_actions: SmartRegistrationInboxAction[];
330
+ /**
331
+ * Automatic details captured during discovery/detection.
332
+ * Includes: model name, model digest, runtime name, agent type, match reason.
333
+ * EXCLUDES: cost, token counts, latency, provider metrics, usage aggregations.
334
+ * Kept lightweight to emphasize inbox is for registration decisions, not analytics.
335
+ */
319
336
  details_received_automatically: Record<string, string | number | boolean | null>;
320
337
  safe_metadata_only: true;
321
338
  }
@@ -327,7 +344,27 @@ export interface SmartRegistrationInboxSummary {
327
344
  ignored_count: number;
328
345
  next_recommended_action: SmartRegistrationInboxAction | null;
329
346
  privacy_summary: string;
330
- }
347
+ freshness_state?: 'fresh' | 'syncing' | 'stale';
348
+ snapshot_age_seconds?: number;
349
+ }
350
+ /**
351
+ * SmartRegistrationInbox (M1 Inbox Boundary Contract)
352
+ *
353
+ * **Purpose:** Onboarding/exception decision queue for local runtime/model/agent discovery.
354
+ *
355
+ * **Scope & Boundaries:**
356
+ * - INCLUDES: unregistered runtimes/models/agents requiring user action, exceptions (credential reconnect, unknown versions).
357
+ * - INCLUDES groups: ready_to_connect (high confidence, actionable), needs_confirmation (needs clarification),
358
+ * connected (already linked but may need refresh), ignored (user-deferred).
359
+ * - EXCLUDES: long-term telemetry data (cost, token usage, latency metrics, provider operational stats).
360
+ * - NOT a performance/cost analytics surface; use RuntimeSignalsDashboard + C2 lifecycle events for that.
361
+ *
362
+ * **Items are NOT filtered out when connected and healthy** — user may want to inspect existing connections.
363
+ * Filtering happens at UI level: UX can show "all" or "action required" tabs, but inbox serves both.
364
+ *
365
+ * **Agent Metadata (M2):** Agents in inbox include agent_class enum for classification (interactive_assistant,
366
+ * background_automation, etc.), allowing UI to show agent-specific onboarding workflows.
367
+ */
331
368
  export interface SmartRegistrationInbox {
332
369
  summary: SmartRegistrationInboxSummary;
333
370
  groups: Record<SmartRegistrationInboxGroup, SmartRegistrationInboxItem[]>;
@@ -500,10 +537,17 @@ export interface BuildSession {
500
537
  lifecycle_events: BuildLifecycleEvent[];
501
538
  artifact_refs: BuildArtifactRef[];
502
539
  }
540
+ /**
541
+ * DetectedAgent (M2: Agent Class Metadata)
542
+ *
543
+ * Represents a detected AI agent/process in the local runtime environment.
544
+ * Includes agent_class enum for architectural classification, enabling specialized onboarding workflows.
545
+ */
503
546
  export interface DetectedAgent {
504
547
  agent_id: string;
505
548
  agent_name: string;
506
549
  agent_type: AgentType;
550
+ agent_class?: AgentClass | null;
507
551
  process_name: string | null;
508
552
  process_signature_hash: string;
509
553
  detected_at: string;
@@ -513,9 +557,16 @@ export interface DetectedAgent {
513
557
  discovery_sources: AgentDiscoverySource[];
514
558
  metadata: Record<string, unknown>;
515
559
  }
560
+ /**
561
+ * AgentLink (M2: Agent Class Metadata in linkage)
562
+ *
563
+ * Records the binding between a detected agent and a model it uses.
564
+ * Carries agent_class through the linkage for passport enrichment.
565
+ */
516
566
  export interface AgentLink {
517
567
  link_id: string;
518
568
  agent_id: string;
569
+ agent_class?: AgentClass | null;
519
570
  model_name: string;
520
571
  discoveryHash: string;
521
572
  registrationKey: string | null;
@@ -538,6 +589,7 @@ export interface AgentModelUsageRecord {
538
589
  agent_id: string;
539
590
  agent_name: string;
540
591
  agent_type: AgentType;
592
+ agent_class?: AgentClass | null;
541
593
  process_signature_hash: string;
542
594
  model_name: string;
543
595
  discoveryHash: string;
@@ -852,6 +904,8 @@ export interface ConnectState {
852
904
  sync_queue: SyncQueueItem[];
853
905
  pending_reviews: PendingReview[];
854
906
  lifecycle_monitor_records: LifecycleMonitorRecord[];
907
+ smart_inbox_snapshot: SmartRegistrationInbox | null;
908
+ smart_inbox_snapshot_updated_at: string | null;
855
909
  }
856
910
  export interface OllamaTagResponse {
857
911
  models?: Array<{
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "forkit-connect",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "description": "Forkit Connect Local Engine - The Global AI Governance Fabric",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "engines": {
9
- "node": ">=20.0.0"
9
+ "node": "20.x || 22.x || 24.x"
10
10
  },
11
11
  "files": [
12
12
  "dist",
@@ -14,25 +14,25 @@
14
14
  "QUICKSTART.md"
15
15
  ],
16
16
  "scripts": {
17
- "build": "pnpm run clean && tsc -p tsconfig.build.json",
17
+ "build": "npm run clean && tsc -p tsconfig.build.json && node -e \"const fs = require('node:fs'); if (process.platform !== 'win32') fs.chmodSync('dist/cli.js', 0o755);\"",
18
18
  "dev": "tsc -w -p tsconfig.build.json",
19
- "clean": "rm -rf dist",
20
- "prepack": "pnpm run build && node ./scripts/prune-package-dist.js",
19
+ "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true });\"",
20
+ "prepack": "npm run build && node ./scripts/prune-package-dist.js",
21
21
  "install:ubuntu": "bash ./scripts/install-ubuntu-local.sh",
22
- "smoke:package": "bash ./scripts/smoke-package.sh",
22
+ "smoke:package": "node ./scripts/smoke-package.mjs",
23
+ "smoke:registry": "node ./scripts/smoke-registry.mjs",
23
24
  "desktop:dev": "pnpm run build && node dist/launcher.js",
24
25
  "desktop:build": "pnpm run build && node dist/launcher.js --build-shell",
25
26
  "deploy:local": "bash scripts/deploy-local.sh"
26
27
  },
27
28
  "bin": {
28
- "forkit-connect": "./dist/cli.js"
29
+ "forkit-connect": "dist/cli.js"
29
30
  },
30
31
  "dependencies": {
31
32
  "@modelcontextprotocol/sdk": "^1.0.1",
32
- "better-sqlite3": "^11.10.0",
33
+ "better-sqlite3": "^12.10.0",
33
34
  "cors": "^2.8.6",
34
35
  "express": "^4.19.2",
35
- "keytar": "^7.9.0",
36
36
  "ps-list": "^8.1.1",
37
37
  "uuid": "^10.0.0",
38
38
  "ws": "^8.16.0",