4runr-os 1.0.28 → 1.0.37
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/collectors/collector_assets.d.ts +19 -0
- package/dist/collectors/collector_assets.d.ts.map +1 -0
- package/dist/collectors/collector_assets.js +72 -0
- package/dist/collectors/collector_assets.js.map +1 -0
- package/dist/collectors/collector_capabilities.d.ts +19 -0
- package/dist/collectors/collector_capabilities.d.ts.map +1 -0
- package/dist/collectors/collector_capabilities.js +61 -0
- package/dist/collectors/collector_capabilities.js.map +1 -0
- package/dist/collectors/collector_feed.d.ts +30 -0
- package/dist/collectors/collector_feed.d.ts.map +1 -0
- package/dist/collectors/collector_feed.js +78 -0
- package/dist/collectors/collector_feed.js.map +1 -0
- package/dist/collectors/collector_geo.d.ts +12 -0
- package/dist/collectors/collector_geo.d.ts.map +1 -0
- package/dist/collectors/collector_geo.js +248 -0
- package/dist/collectors/collector_geo.js.map +1 -0
- package/dist/collectors/collector_network.d.ts +22 -0
- package/dist/collectors/collector_network.d.ts.map +1 -0
- package/dist/collectors/collector_network.js +83 -0
- package/dist/collectors/collector_network.js.map +1 -0
- package/dist/collectors/collector_posture.d.ts +25 -0
- package/dist/collectors/collector_posture.d.ts.map +1 -0
- package/dist/collectors/collector_posture.js +207 -0
- package/dist/collectors/collector_posture.js.map +1 -0
- package/dist/collectors/collector_resources.d.ts +21 -0
- package/dist/collectors/collector_resources.d.ts.map +1 -0
- package/dist/collectors/collector_resources.js +87 -0
- package/dist/collectors/collector_resources.js.map +1 -0
- package/dist/collectors/helpers.d.ts +21 -0
- package/dist/collectors/helpers.d.ts.map +1 -0
- package/dist/collectors/helpers.js +49 -0
- package/dist/collectors/helpers.js.map +1 -0
- package/dist/core/collectorRegistry.d.ts +43 -0
- package/dist/core/collectorRegistry.d.ts.map +1 -0
- package/dist/core/collectorRegistry.js +76 -0
- package/dist/core/collectorRegistry.js.map +1 -0
- package/dist/core/constants.d.ts +25 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +33 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/eventBus.d.ts +36 -0
- package/dist/core/eventBus.d.ts.map +1 -0
- package/dist/core/eventBus.js +52 -0
- package/dist/core/eventBus.js.map +1 -0
- package/dist/core/types.d.ts +128 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +6 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.js +135 -5
- package/dist/index.js.map +1 -1
- package/dist/state/getCollectorResults.d.ts +18 -0
- package/dist/state/getCollectorResults.d.ts.map +1 -0
- package/dist/state/getCollectorResults.js +25 -0
- package/dist/state/getCollectorResults.js.map +1 -0
- package/dist/state/historyStore.d.ts +35 -0
- package/dist/state/historyStore.d.ts.map +1 -0
- package/dist/state/historyStore.js +58 -0
- package/dist/state/historyStore.js.map +1 -0
- package/dist/state/uiStateBuilder.d.ts +12 -0
- package/dist/state/uiStateBuilder.d.ts.map +1 -0
- package/dist/state/uiStateBuilder.js +169 -0
- package/dist/state/uiStateBuilder.js.map +1 -0
- package/dist/state/uiStateScheduler.d.ts +43 -0
- package/dist/state/uiStateScheduler.d.ts.map +1 -0
- package/dist/state/uiStateScheduler.js +118 -0
- package/dist/state/uiStateScheduler.js.map +1 -0
- package/dist/ui/boot/sequence.d.ts +10 -0
- package/dist/ui/boot/sequence.d.ts.map +1 -0
- package/dist/ui/boot/sequence.js +173 -0
- package/dist/ui/boot/sequence.js.map +1 -0
- package/dist/ui/constraints/layoutSpec.d.ts +47 -0
- package/dist/ui/constraints/layoutSpec.d.ts.map +1 -0
- package/dist/ui/constraints/layoutSpec.js +60 -0
- package/dist/ui/constraints/layoutSpec.js.map +1 -0
- package/dist/ui/constraints/unknownHandling.d.ts +29 -0
- package/dist/ui/constraints/unknownHandling.d.ts.map +1 -0
- package/dist/ui/constraints/unknownHandling.js +60 -0
- package/dist/ui/constraints/unknownHandling.js.map +1 -0
- package/dist/ui/drilldowns/feed.d.ts +11 -0
- package/dist/ui/drilldowns/feed.d.ts.map +1 -0
- package/dist/ui/drilldowns/feed.js +68 -0
- package/dist/ui/drilldowns/feed.js.map +1 -0
- package/dist/ui/drilldowns/index.d.ts +7 -0
- package/dist/ui/drilldowns/index.d.ts.map +1 -0
- package/dist/ui/drilldowns/index.js +8 -0
- package/dist/ui/drilldowns/index.js.map +1 -0
- package/dist/ui/drilldowns/posture.d.ts +11 -0
- package/dist/ui/drilldowns/posture.d.ts.map +1 -0
- package/dist/ui/drilldowns/posture.js +74 -0
- package/dist/ui/drilldowns/posture.js.map +1 -0
- package/dist/ui/navigation/keymaps.d.ts +26 -0
- package/dist/ui/navigation/keymaps.d.ts.map +1 -0
- package/dist/ui/navigation/keymaps.js +135 -0
- package/dist/ui/navigation/keymaps.js.map +1 -0
- package/dist/ui/navigation/palette.d.ts +10 -0
- package/dist/ui/navigation/palette.d.ts.map +1 -0
- package/dist/ui/navigation/palette.js +133 -0
- package/dist/ui/navigation/palette.js.map +1 -0
- package/dist/ui/navigation/state.d.ts +47 -0
- package/dist/ui/navigation/state.d.ts.map +1 -0
- package/dist/ui/navigation/state.js +84 -0
- package/dist/ui/navigation/state.js.map +1 -0
- package/dist/ui/navigation/types.d.ts +38 -0
- package/dist/ui/navigation/types.d.ts.map +1 -0
- package/dist/ui/navigation/types.js +36 -0
- package/dist/ui/navigation/types.js.map +1 -0
- package/dist/ui/panels/active-assets.d.ts +12 -0
- package/dist/ui/panels/active-assets.d.ts.map +1 -0
- package/dist/ui/panels/active-assets.js +83 -0
- package/dist/ui/panels/active-assets.js.map +1 -0
- package/dist/ui/panels/capability-flags.d.ts +12 -0
- package/dist/ui/panels/capability-flags.d.ts.map +1 -0
- package/dist/ui/panels/capability-flags.js +59 -0
- package/dist/ui/panels/capability-flags.js.map +1 -0
- package/dist/ui/panels/command-surface.d.ts +12 -0
- package/dist/ui/panels/command-surface.d.ts.map +1 -0
- package/dist/ui/panels/command-surface.js +55 -0
- package/dist/ui/panels/command-surface.js.map +1 -0
- package/dist/ui/panels/network-origin.d.ts +12 -0
- package/dist/ui/panels/network-origin.d.ts.map +1 -0
- package/dist/ui/panels/network-origin.js +79 -0
- package/dist/ui/panels/network-origin.js.map +1 -0
- package/dist/ui/panels/operations-feed.d.ts +12 -0
- package/dist/ui/panels/operations-feed.d.ts.map +1 -0
- package/dist/ui/panels/operations-feed.js +90 -0
- package/dist/ui/panels/operations-feed.js.map +1 -0
- package/dist/ui/panels/posture.d.ts +12 -0
- package/dist/ui/panels/posture.d.ts.map +1 -0
- package/dist/ui/panels/posture.js +84 -0
- package/dist/ui/panels/posture.js.map +1 -0
- package/dist/ui/panels/resources.d.ts +11 -0
- package/dist/ui/panels/resources.d.ts.map +1 -0
- package/dist/ui/panels/resources.js +88 -0
- package/dist/ui/panels/resources.js.map +1 -0
- package/dist/ui/primitives/Panel.d.ts +25 -0
- package/dist/ui/primitives/Panel.d.ts.map +1 -0
- package/dist/ui/primitives/Panel.js +59 -0
- package/dist/ui/primitives/Panel.js.map +1 -0
- package/dist/ui/rendering/metricRenderer.d.ts +24 -0
- package/dist/ui/rendering/metricRenderer.d.ts.map +1 -0
- package/dist/ui/rendering/metricRenderer.js +86 -0
- package/dist/ui/rendering/metricRenderer.js.map +1 -0
- package/dist/ui/runtime/hub.d.ts +12 -0
- package/dist/ui/runtime/hub.d.ts.map +1 -0
- package/dist/ui/runtime/hub.js +468 -0
- package/dist/ui/runtime/hub.js.map +1 -0
- package/dist/ui/runtime/hubValidation.d.ts +23 -0
- package/dist/ui/runtime/hubValidation.d.ts.map +1 -0
- package/dist/ui/runtime/hubValidation.js +90 -0
- package/dist/ui/runtime/hubValidation.js.map +1 -0
- package/dist/ui/runtime/index.d.ts +29 -0
- package/dist/ui/runtime/index.d.ts.map +1 -0
- package/dist/ui/runtime/index.js +299 -0
- package/dist/ui/runtime/index.js.map +1 -0
- package/dist/ui/runtime/no-tui.d.ts +12 -0
- package/dist/ui/runtime/no-tui.d.ts.map +1 -0
- package/dist/ui/runtime/no-tui.js +77 -0
- package/dist/ui/runtime/no-tui.js.map +1 -0
- package/dist/ui/runtime/state-builder.d.ts +13 -0
- package/dist/ui/runtime/state-builder.d.ts.map +1 -0
- package/dist/ui/runtime/state-builder.js +114 -0
- package/dist/ui/runtime/state-builder.js.map +1 -0
- package/dist/ui/runtime/terminalSizeCheck.d.ts +10 -0
- package/dist/ui/runtime/terminalSizeCheck.d.ts.map +1 -0
- package/dist/ui/runtime/terminalSizeCheck.js +51 -0
- package/dist/ui/runtime/terminalSizeCheck.js.map +1 -0
- package/dist/ui/runtime/tuiLogGate.d.ts +22 -0
- package/dist/ui/runtime/tuiLogGate.d.ts.map +1 -0
- package/dist/ui/runtime/tuiLogGate.js +68 -0
- package/dist/ui/runtime/tuiLogGate.js.map +1 -0
- package/dist/ui/state/types.d.ts +72 -0
- package/dist/ui/state/types.d.ts.map +1 -0
- package/dist/ui/state/types.js +6 -0
- package/dist/ui/state/types.js.map +1 -0
- package/dist/ui/theme/borders.d.ts +20 -0
- package/dist/ui/theme/borders.d.ts.map +1 -0
- package/dist/ui/theme/borders.js +55 -0
- package/dist/ui/theme/borders.js.map +1 -0
- package/dist/ui/theme/tokens.d.ts +28 -0
- package/dist/ui/theme/tokens.d.ts.map +1 -0
- package/dist/ui/theme/tokens.js +50 -0
- package/dist/ui/theme/tokens.js.map +1 -0
- package/dist/ui/theme/typography.d.ts +14 -0
- package/dist/ui/theme/typography.d.ts.map +1 -0
- package/dist/ui/theme/typography.js +30 -0
- package/dist/ui/theme/typography.js.map +1 -0
- package/dist/ui/widgets/flagRow.d.ts +25 -0
- package/dist/ui/widgets/flagRow.d.ts.map +1 -0
- package/dist/ui/widgets/flagRow.js +57 -0
- package/dist/ui/widgets/flagRow.js.map +1 -0
- package/dist/ui/widgets/index.d.ts +9 -0
- package/dist/ui/widgets/index.d.ts.map +1 -0
- package/dist/ui/widgets/index.js +9 -0
- package/dist/ui/widgets/index.js.map +1 -0
- package/dist/ui/widgets/meter.d.ts +18 -0
- package/dist/ui/widgets/meter.d.ts.map +1 -0
- package/dist/ui/widgets/meter.js +38 -0
- package/dist/ui/widgets/meter.js.map +1 -0
- package/dist/ui/widgets/miniMap.d.ts +26 -0
- package/dist/ui/widgets/miniMap.d.ts.map +1 -0
- package/dist/ui/widgets/miniMap.js +94 -0
- package/dist/ui/widgets/miniMap.js.map +1 -0
- package/dist/ui/widgets/sparkline.d.ts +17 -0
- package/dist/ui/widgets/sparkline.d.ts.map +1 -0
- package/dist/ui/widgets/sparkline.js +63 -0
- package/dist/ui/widgets/sparkline.js.map +1 -0
- package/package.json +3 -2
- package/dist/ui/home-view.d.ts +0 -27
- package/dist/ui/home-view.d.ts.map +0 -1
- package/dist/ui/home-view.js +0 -127
- package/dist/ui/home-view.js.map +0 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assets Collector
|
|
3
|
+
* Phase 3: Read from agent registry, count statuses
|
|
4
|
+
*/
|
|
5
|
+
import type { CollectorResult } from '../core/types.js';
|
|
6
|
+
import type { AppState } from '../store.js';
|
|
7
|
+
export type AssetsData = {
|
|
8
|
+
total: number | "UNKNOWN";
|
|
9
|
+
active: number | "UNKNOWN";
|
|
10
|
+
idle: number | "UNKNOWN";
|
|
11
|
+
error: number | "UNKNOWN";
|
|
12
|
+
highlight: string | "UNKNOWN";
|
|
13
|
+
lastAction: string | "NONE" | "UNKNOWN";
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Collect asset registry data
|
|
17
|
+
*/
|
|
18
|
+
export declare function collectAssets(appState: AppState): Promise<CollectorResult<AssetsData>>;
|
|
19
|
+
//# sourceMappingURL=collector_assets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector_assets.d.ts","sourceRoot":"","sources":["../../src/collectors/collector_assets.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kBAAkB,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACzC,CAAC;AAEF;;GAEG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAiE5F"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assets Collector
|
|
3
|
+
* Phase 3: Read from agent registry, count statuses
|
|
4
|
+
*/
|
|
5
|
+
import { getSystemState } from '../system-state.js';
|
|
6
|
+
/**
|
|
7
|
+
* Collect asset registry data
|
|
8
|
+
*/
|
|
9
|
+
export async function collectAssets(appState) {
|
|
10
|
+
try {
|
|
11
|
+
let systemState;
|
|
12
|
+
try {
|
|
13
|
+
systemState = getSystemState(appState, false);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
systemState = null;
|
|
17
|
+
}
|
|
18
|
+
if (!systemState) {
|
|
19
|
+
return {
|
|
20
|
+
status: 'UNAVAILABLE',
|
|
21
|
+
asOf: Date.now(),
|
|
22
|
+
source: 'collector_assets',
|
|
23
|
+
staleAfterMs: 2000,
|
|
24
|
+
reasonCode: 'NO_SYSTEM_STATE',
|
|
25
|
+
message: 'System state not available',
|
|
26
|
+
action: 'system status',
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const assets = systemState.assetRegistrySummary;
|
|
30
|
+
// Get last action from run history
|
|
31
|
+
let lastAction = "NONE";
|
|
32
|
+
if (appState.runHistory.length > 0) {
|
|
33
|
+
const lastRun = appState.runHistory[appState.runHistory.length - 1];
|
|
34
|
+
if (lastRun.status === 'RUNNING') {
|
|
35
|
+
lastAction = `run:${lastRun.runId.substring(0, 8)}`;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
lastAction = `start:${lastRun.agentName}`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const data = {
|
|
42
|
+
total: assets.total,
|
|
43
|
+
active: assets.active,
|
|
44
|
+
idle: assets.idle,
|
|
45
|
+
error: assets.error,
|
|
46
|
+
highlight: assets.highlighted?.name || "UNKNOWN",
|
|
47
|
+
lastAction,
|
|
48
|
+
};
|
|
49
|
+
// Phase 9: Assets are usually LIVE if collected successfully
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
const status = 'LIVE';
|
|
52
|
+
return {
|
|
53
|
+
status,
|
|
54
|
+
asOf: now,
|
|
55
|
+
data,
|
|
56
|
+
source: 'collector_assets',
|
|
57
|
+
staleAfterMs: 2000,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
return {
|
|
62
|
+
status: 'UNAVAILABLE',
|
|
63
|
+
asOf: Date.now(),
|
|
64
|
+
source: 'collector_assets',
|
|
65
|
+
staleAfterMs: 2000,
|
|
66
|
+
reasonCode: 'COLLECTION_ERROR',
|
|
67
|
+
message: error.message || 'Unknown error',
|
|
68
|
+
action: 'system status',
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=collector_assets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector_assets.js","sourceRoot":"","sources":["../../src/collectors/collector_assets.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAWpD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAkB;IACpD,IAAI,CAAC;QACH,IAAI,WAAW,CAAC;QAChB,IAAI,CAAC;YACH,WAAW,GAAG,cAAc,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC;QAED,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO;gBACL,MAAM,EAAE,aAAgC;gBACxC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;gBAChB,MAAM,EAAE,kBAAkB;gBAC1B,YAAY,EAAE,IAAI;gBAClB,UAAU,EAAE,iBAAiB;gBAC7B,OAAO,EAAE,4BAA4B;gBACrC,MAAM,EAAE,eAAe;aACxB,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,WAAW,CAAC,oBAAoB,CAAC;QAEhD,mCAAmC;QACnC,IAAI,UAAU,GAAW,MAAM,CAAC;QAChC,IAAI,QAAQ,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACpE,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACjC,UAAU,GAAG,OAAO,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACN,UAAU,GAAG,SAAS,OAAO,CAAC,SAAS,EAAE,CAAC;YAC5C,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAe;YACvB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,SAAS,EAAE,MAAM,CAAC,WAAW,EAAE,IAAI,IAAI,SAAS;YAChD,UAAU;SACX,CAAC;QAEF,6DAA6D;QAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAoB,MAAM,CAAC;QAEvC,OAAO;YACL,MAAM;YACN,IAAI,EAAE,GAAG;YACT,IAAI;YACJ,MAAM,EAAE,kBAAkB;YAC1B,YAAY,EAAE,IAAI;SACnB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO;YACL,MAAM,EAAE,aAAa;YACrB,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;YAChB,MAAM,EAAE,kBAAkB;YAC1B,YAAY,EAAE,IAAI;YAClB,UAAU,EAAE,kBAAkB;YAC9B,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,eAAe;YACzC,MAAM,EAAE,eAAe;SACxB,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capabilities Collector
|
|
3
|
+
* Phase 3: Report current capability flags based on actual config
|
|
4
|
+
*/
|
|
5
|
+
import type { CollectorResult } from '../core/types.js';
|
|
6
|
+
import type { AppState } from '../store.js';
|
|
7
|
+
export type CapabilitiesData = {
|
|
8
|
+
gateway: "READY" | "DEGRADED" | "UNKNOWN";
|
|
9
|
+
database: "READY" | "NOT_INITIALIZED" | "UNKNOWN";
|
|
10
|
+
memory: "IN_MEMORY" | "PERSISTENT" | "UNKNOWN";
|
|
11
|
+
security: "OPEN" | "BASIC" | "JWT" | "UNKNOWN";
|
|
12
|
+
rateLimit: "ENABLED" | "DISABLED" | "UNKNOWN";
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Collect capability flags
|
|
16
|
+
* Based on actual runtime enforcement, not package presence
|
|
17
|
+
*/
|
|
18
|
+
export declare function collectCapabilities(appState: AppState): Promise<CollectorResult<CapabilitiesData>>;
|
|
19
|
+
//# sourceMappingURL=collector_capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector_capabilities.d.ts","sourceRoot":"","sources":["../../src/collectors/collector_capabilities.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kBAAkB,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;IAC1C,QAAQ,EAAE,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAAC;IAClD,MAAM,EAAE,WAAW,GAAG,YAAY,GAAG,SAAS,CAAC;IAC/C,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,SAAS,CAAC;IAC/C,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;CAC/C,CAAC;AAEF;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC,CAqDxG"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capabilities Collector
|
|
3
|
+
* Phase 3: Report current capability flags based on actual config
|
|
4
|
+
*/
|
|
5
|
+
import { getSystemState } from '../system-state.js';
|
|
6
|
+
/**
|
|
7
|
+
* Collect capability flags
|
|
8
|
+
* Based on actual runtime enforcement, not package presence
|
|
9
|
+
*/
|
|
10
|
+
export async function collectCapabilities(appState) {
|
|
11
|
+
try {
|
|
12
|
+
let systemState;
|
|
13
|
+
try {
|
|
14
|
+
systemState = getSystemState(appState, false);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
systemState = null;
|
|
18
|
+
}
|
|
19
|
+
if (!systemState) {
|
|
20
|
+
return {
|
|
21
|
+
status: 'UNAVAILABLE',
|
|
22
|
+
asOf: Date.now(),
|
|
23
|
+
source: 'collector_capabilities',
|
|
24
|
+
staleAfterMs: 5000,
|
|
25
|
+
reasonCode: 'NO_SYSTEM_STATE',
|
|
26
|
+
message: 'System state not available',
|
|
27
|
+
action: 'system status',
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const flags = systemState.capabilityFlags;
|
|
31
|
+
const data = {
|
|
32
|
+
gateway: flags.gateway,
|
|
33
|
+
database: flags.database,
|
|
34
|
+
memory: flags.memoryLayer,
|
|
35
|
+
security: flags.security,
|
|
36
|
+
rateLimit: flags.rateLimiting,
|
|
37
|
+
};
|
|
38
|
+
// Phase 9: Capabilities are usually LIVE if collected successfully
|
|
39
|
+
const now = Date.now();
|
|
40
|
+
const status = 'LIVE';
|
|
41
|
+
return {
|
|
42
|
+
status,
|
|
43
|
+
asOf: now,
|
|
44
|
+
data,
|
|
45
|
+
source: 'collector_capabilities',
|
|
46
|
+
staleAfterMs: 5000, // Capabilities change rarely
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
return {
|
|
51
|
+
status: 'UNAVAILABLE',
|
|
52
|
+
asOf: Date.now(),
|
|
53
|
+
source: 'collector_capabilities',
|
|
54
|
+
staleAfterMs: 5000,
|
|
55
|
+
reasonCode: 'COLLECTION_ERROR',
|
|
56
|
+
message: error.message || 'Unknown error',
|
|
57
|
+
action: 'system status',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=collector_capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector_capabilities.js","sourceRoot":"","sources":["../../src/collectors/collector_capabilities.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAUpD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,QAAkB;IAC1D,IAAI,CAAC;QACH,IAAI,WAAW,CAAC;QAChB,IAAI,CAAC;YACH,WAAW,GAAG,cAAc,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC;QAED,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO;gBACL,MAAM,EAAE,aAAgC;gBACxC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;gBAChB,MAAM,EAAE,wBAAwB;gBAChC,YAAY,EAAE,IAAI;gBAClB,UAAU,EAAE,iBAAiB;gBAC7B,OAAO,EAAE,4BAA4B;gBACrC,MAAM,EAAE,eAAe;aACxB,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,WAAW,CAAC,eAAe,CAAC;QAE1C,MAAM,IAAI,GAAqB;YAC7B,OAAO,EAAE,KAAK,CAAC,OAA+B;YAC9C,QAAQ,EAAE,KAAK,CAAC,QAAuC;YACvD,MAAM,EAAE,KAAK,CAAC,WAAyC;YACvD,QAAQ,EAAE,KAAK,CAAC,QAAoC;YACpD,SAAS,EAAE,KAAK,CAAC,YAAsC;SACxD,CAAC;QAEF,mEAAmE;QACnE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAoB,MAAM,CAAC;QAEvC,OAAO;YACL,MAAM;YACN,IAAI,EAAE,GAAG;YACT,IAAI;YACJ,MAAM,EAAE,wBAAwB;YAChC,YAAY,EAAE,IAAI,EAAE,6BAA6B;SAClD,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO;YACL,MAAM,EAAE,aAAa;YACrB,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;YAChB,MAAM,EAAE,wBAAwB;YAChC,YAAY,EAAE,IAAI;YAClB,UAAU,EAAE,kBAAkB;YAC9B,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,eAAe;YACzC,MAAM,EAAE,eAAe;SACxB,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feed Collector
|
|
3
|
+
* Phase 3: Own the feed event list (ring buffer)
|
|
4
|
+
*/
|
|
5
|
+
import type { CollectorResult } from '../core/types.js';
|
|
6
|
+
import { type FeedEvent } from '../core/eventBus.js';
|
|
7
|
+
export type FeedData = {
|
|
8
|
+
events: Array<{
|
|
9
|
+
ts: number;
|
|
10
|
+
tag: "RUN" | "NET" | "SEC" | "DB" | "GATEWAY" | "SYSTEM";
|
|
11
|
+
msg: string;
|
|
12
|
+
}>;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Initialize feed collector (subscribe to event bus)
|
|
16
|
+
*/
|
|
17
|
+
export declare function initFeedCollector(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Get events (for collector)
|
|
20
|
+
*/
|
|
21
|
+
export declare function getEvents(limit?: number): FeedEvent[];
|
|
22
|
+
/**
|
|
23
|
+
* Push event (for runtime execution)
|
|
24
|
+
*/
|
|
25
|
+
export declare function pushEvent(tag: FeedEvent['tag'], msg: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Collect feed data
|
|
28
|
+
*/
|
|
29
|
+
export declare function collectFeed(): Promise<CollectorResult<FeedData>>;
|
|
30
|
+
//# sourceMappingURL=collector_feed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector_feed.d.ts","sourceRoot":"","sources":["../../src/collectors/collector_feed.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,MAAM,QAAQ,GAAG;IACrB,MAAM,EAAE,KAAK,CAAC;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,GAAG,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,GAAG,QAAQ,CAAC;QACzD,GAAG,EAAE,MAAM,CAAC;KACb,CAAC,CAAC;CACJ,CAAC;AASF;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAYxC;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,GAAE,MAAW,GAAG,SAAS,EAAE,CAEzD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAMlE;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAkCtE"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feed Collector
|
|
3
|
+
* Phase 3: Own the feed event list (ring buffer)
|
|
4
|
+
*/
|
|
5
|
+
import { eventBus } from '../core/eventBus.js';
|
|
6
|
+
// Ring buffer for feed events (in-memory, stable in-process)
|
|
7
|
+
const MAX_FEED_EVENTS = 50;
|
|
8
|
+
const feedBuffer = [];
|
|
9
|
+
// Subscribe to event bus
|
|
10
|
+
let unsubscribe = null;
|
|
11
|
+
/**
|
|
12
|
+
* Initialize feed collector (subscribe to event bus)
|
|
13
|
+
*/
|
|
14
|
+
export function initFeedCollector() {
|
|
15
|
+
if (unsubscribe) {
|
|
16
|
+
unsubscribe();
|
|
17
|
+
}
|
|
18
|
+
unsubscribe = eventBus.subscribe((event) => {
|
|
19
|
+
feedBuffer.push(event);
|
|
20
|
+
// Keep only last MAX_FEED_EVENTS
|
|
21
|
+
if (feedBuffer.length > MAX_FEED_EVENTS) {
|
|
22
|
+
feedBuffer.shift();
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get events (for collector)
|
|
28
|
+
*/
|
|
29
|
+
export function getEvents(limit = 12) {
|
|
30
|
+
return feedBuffer.slice(-limit).reverse(); // Newest first
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Push event (for runtime execution)
|
|
34
|
+
*/
|
|
35
|
+
export function pushEvent(tag, msg) {
|
|
36
|
+
eventBus.emit({
|
|
37
|
+
tag,
|
|
38
|
+
msg,
|
|
39
|
+
ts: Date.now(),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Collect feed data
|
|
44
|
+
*/
|
|
45
|
+
export async function collectFeed() {
|
|
46
|
+
try {
|
|
47
|
+
const events = getEvents(12).map(e => ({
|
|
48
|
+
ts: e.ts,
|
|
49
|
+
tag: e.tag,
|
|
50
|
+
msg: e.msg,
|
|
51
|
+
}));
|
|
52
|
+
const data = {
|
|
53
|
+
events,
|
|
54
|
+
};
|
|
55
|
+
// Phase 9: Feed is always LIVE if we have events
|
|
56
|
+
const now = Date.now();
|
|
57
|
+
const status = 'LIVE';
|
|
58
|
+
return {
|
|
59
|
+
status,
|
|
60
|
+
asOf: now,
|
|
61
|
+
data,
|
|
62
|
+
source: 'collector_feed',
|
|
63
|
+
staleAfterMs: 0, // Feed updates instantly via event bus
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
return {
|
|
68
|
+
status: 'UNAVAILABLE',
|
|
69
|
+
asOf: Date.now(),
|
|
70
|
+
source: 'collector_feed',
|
|
71
|
+
staleAfterMs: 0,
|
|
72
|
+
reasonCode: 'COLLECTION_ERROR',
|
|
73
|
+
message: error.message || 'Unknown error',
|
|
74
|
+
action: 'system status',
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=collector_feed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector_feed.js","sourceRoot":"","sources":["../../src/collectors/collector_feed.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,QAAQ,EAAkB,MAAM,qBAAqB,CAAC;AAU/D,6DAA6D;AAC7D,MAAM,eAAe,GAAG,EAAE,CAAC;AAC3B,MAAM,UAAU,GAAgB,EAAE,CAAC;AAEnC,yBAAyB;AACzB,IAAI,WAAW,GAAwB,IAAI,CAAC;AAE5C;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,WAAW,EAAE,CAAC;QAChB,WAAW,EAAE,CAAC;IAChB,CAAC;IAED,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,KAAgB,EAAE,EAAE;QACpD,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvB,iCAAiC;QACjC,IAAI,UAAU,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;YACxC,UAAU,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE;IAC1C,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,eAAe;AAC5D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,GAAqB,EAAE,GAAW;IAC1D,QAAQ,CAAC,IAAI,CAAC;QACZ,GAAG;QACH,GAAG;QACH,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;KACf,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACrC,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,GAAG,EAAE,CAAC,CAAC,GAAG;SACX,CAAC,CAAC,CAAC;QAEJ,MAAM,IAAI,GAAa;YACrB,MAAM;SACP,CAAC;QAEF,iDAAiD;QACjD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAoB,MAAM,CAAC;QAEvC,OAAO;YACL,MAAM;YACN,IAAI,EAAE,GAAG;YACT,IAAI;YACJ,MAAM,EAAE,gBAAgB;YACxB,YAAY,EAAE,CAAC,EAAE,uCAAuC;SACzD,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO;YACL,MAAM,EAAE,aAAa;YACrB,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;YAChB,MAAM,EAAE,gBAAgB;YACxB,YAAY,EAAE,CAAC;YACf,UAAU,EAAE,kBAAkB;YAC9B,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,eAAe;YACzC,MAAM,EAAE,eAAe;SACxB,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Geographic Collector
|
|
3
|
+
* Phase 5: Best-effort geographic intelligence
|
|
4
|
+
*/
|
|
5
|
+
import type { CollectorResult } from '../core/types.js';
|
|
6
|
+
import type { AppState } from '../store.js';
|
|
7
|
+
import type { GeoContext } from '../core/types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Collect geographic context
|
|
10
|
+
*/
|
|
11
|
+
export declare function collectGeo(appState: AppState): Promise<CollectorResult<GeoContext>>;
|
|
12
|
+
//# sourceMappingURL=collector_geo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector_geo.d.ts","sourceRoot":"","sources":["../../src/collectors/collector_geo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kBAAkB,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAsKnD;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAuGzF"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Geographic Collector
|
|
3
|
+
* Phase 5: Best-effort geographic intelligence
|
|
4
|
+
*/
|
|
5
|
+
import { getLatencyClass } from '../core/constants.js';
|
|
6
|
+
const ALLOW_GEO_LOOKUP = process.env.ALLOW_GEO_LOOKUP === '1';
|
|
7
|
+
/**
|
|
8
|
+
* Get origin from environment or local IP
|
|
9
|
+
*/
|
|
10
|
+
async function getOrigin() {
|
|
11
|
+
// Priority 1: Manual env override
|
|
12
|
+
const manualLabel = process.env.FOURRUNR_ORIGIN_LABEL;
|
|
13
|
+
const manualLat = process.env.FOURRUNR_ORIGIN_LAT;
|
|
14
|
+
const manualLon = process.env.FOURRUNR_ORIGIN_LON;
|
|
15
|
+
if (manualLabel) {
|
|
16
|
+
return {
|
|
17
|
+
label: manualLabel,
|
|
18
|
+
region: process.env.FOURRUNR_ORIGIN_REGION || "UNKNOWN",
|
|
19
|
+
latLon: (manualLat && manualLon) ? {
|
|
20
|
+
lat: parseFloat(manualLat),
|
|
21
|
+
lon: parseFloat(manualLon),
|
|
22
|
+
} : undefined,
|
|
23
|
+
source: "MANUAL",
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
// Priority 2: Local IP geo lookup (only if enabled)
|
|
27
|
+
if (process.env.ALLOW_GEO_LOOKUP === '1') {
|
|
28
|
+
try {
|
|
29
|
+
// In a real implementation, this would call a geo IP service
|
|
30
|
+
// For v1, we'll return UNKNOWN to be privacy-safe
|
|
31
|
+
// This is a placeholder for future implementation
|
|
32
|
+
return {
|
|
33
|
+
label: "UNKNOWN",
|
|
34
|
+
region: "UNKNOWN",
|
|
35
|
+
source: "NONE",
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return {
|
|
40
|
+
label: "UNKNOWN",
|
|
41
|
+
region: "UNKNOWN",
|
|
42
|
+
source: "NONE",
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Default: UNKNOWN
|
|
47
|
+
return {
|
|
48
|
+
label: "UNKNOWN",
|
|
49
|
+
region: "UNKNOWN",
|
|
50
|
+
source: "NONE",
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get gateway region from AWS metadata or env
|
|
55
|
+
*/
|
|
56
|
+
async function getGatewayRegion(appState) {
|
|
57
|
+
// Priority 1: Env override
|
|
58
|
+
const envRegion = process.env.FOURRUNR_AWS_REGION;
|
|
59
|
+
if (envRegion) {
|
|
60
|
+
return {
|
|
61
|
+
region: envRegion,
|
|
62
|
+
source: "ENV",
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// Priority 2: AWS instance metadata (only if on EC2)
|
|
66
|
+
if (process.env.ALLOW_AWS_META === '1') {
|
|
67
|
+
try {
|
|
68
|
+
// In a real implementation, this would query IMDSv2
|
|
69
|
+
// For v1, we'll return UNKNOWN
|
|
70
|
+
// This is a placeholder for future implementation
|
|
71
|
+
return {
|
|
72
|
+
region: "UNKNOWN",
|
|
73
|
+
source: "NONE",
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return {
|
|
78
|
+
region: "UNKNOWN",
|
|
79
|
+
source: "NONE",
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Try to derive from gateway URL
|
|
84
|
+
if (appState.gatewayUrl) {
|
|
85
|
+
const url = appState.gatewayUrl.toLowerCase();
|
|
86
|
+
// Simple pattern matching for AWS regions in URLs
|
|
87
|
+
const regionMatch = url.match(/(us|eu|ap|sa|ca|cn)-(east|west|central|north|south)-\d/);
|
|
88
|
+
if (regionMatch) {
|
|
89
|
+
return {
|
|
90
|
+
region: regionMatch[0],
|
|
91
|
+
source: "ENV",
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
region: "UNKNOWN",
|
|
97
|
+
source: "NONE",
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get database region
|
|
102
|
+
*/
|
|
103
|
+
async function getDbRegion(appState) {
|
|
104
|
+
// Priority 1: Env override
|
|
105
|
+
const envRegion = process.env.FOURRUNR_DB_REGION;
|
|
106
|
+
if (envRegion) {
|
|
107
|
+
return envRegion;
|
|
108
|
+
}
|
|
109
|
+
// Priority 2: Derive from connection string (if available)
|
|
110
|
+
// This would parse the connection string for region info
|
|
111
|
+
// For v1, return UNKNOWN
|
|
112
|
+
return "UNKNOWN";
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Ping gateway endpoint (if configured)
|
|
116
|
+
* Returns latency in ms or UNKNOWN
|
|
117
|
+
*/
|
|
118
|
+
async function pingGateway(appState) {
|
|
119
|
+
if (!appState.gatewayUrl || !appState.gatewayConnected) {
|
|
120
|
+
return "UNKNOWN";
|
|
121
|
+
}
|
|
122
|
+
// In a real implementation, this would perform an actual ping/HTTP request
|
|
123
|
+
// For v1, we'll use the existing latency from network collector if available
|
|
124
|
+
// This is a placeholder for future implementation
|
|
125
|
+
return "UNKNOWN";
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Convert AWS region to approximate lat/lon
|
|
129
|
+
* This is a best-effort mapping for visualization
|
|
130
|
+
*/
|
|
131
|
+
function regionToLatLon(region) {
|
|
132
|
+
// Approximate region centers (best-effort)
|
|
133
|
+
const regionMap = {
|
|
134
|
+
'us-east-1': { lat: 33.7490, lon: -84.3880 }, // Atlanta
|
|
135
|
+
'us-east-2': { lat: 40.7128, lon: -74.0060 }, // New York
|
|
136
|
+
'us-west-1': { lat: 37.7749, lon: -122.4194 }, // San Francisco
|
|
137
|
+
'us-west-2': { lat: 45.5152, lon: -122.6784 }, // Portland
|
|
138
|
+
'eu-west-1': { lat: 53.3498, lon: -6.2603 }, // Dublin
|
|
139
|
+
'eu-central-1': { lat: 50.1109, lon: 8.6821 }, // Frankfurt
|
|
140
|
+
'ap-southeast-1': { lat: 1.3521, lon: 103.8198 }, // Singapore
|
|
141
|
+
'ap-northeast-1': { lat: 35.6762, lon: 139.6503 }, // Tokyo
|
|
142
|
+
};
|
|
143
|
+
return regionMap[region.toLowerCase()] || "UNKNOWN";
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Collect geographic context
|
|
147
|
+
*/
|
|
148
|
+
export async function collectGeo(appState) {
|
|
149
|
+
try {
|
|
150
|
+
const [origin, gateway, dbRegion, pingMs] = await Promise.all([
|
|
151
|
+
getOrigin(),
|
|
152
|
+
getGatewayRegion(appState),
|
|
153
|
+
getDbRegion(appState),
|
|
154
|
+
pingGateway(appState),
|
|
155
|
+
]);
|
|
156
|
+
// Build route label
|
|
157
|
+
let routeLabel = "UNKNOWN";
|
|
158
|
+
if (origin.label !== "UNKNOWN" && gateway.region !== "UNKNOWN") {
|
|
159
|
+
routeLabel = `${origin.label} → ${gateway.region}`;
|
|
160
|
+
}
|
|
161
|
+
// Get gateway lat/lon if region is known
|
|
162
|
+
let gatewayLatLon = undefined;
|
|
163
|
+
if (gateway.region !== "UNKNOWN") {
|
|
164
|
+
gatewayLatLon = regionToLatLon(gateway.region);
|
|
165
|
+
}
|
|
166
|
+
// Get DB lat/lon if region is known
|
|
167
|
+
let dbLatLon = undefined;
|
|
168
|
+
if (dbRegion !== "UNKNOWN") {
|
|
169
|
+
dbLatLon = regionToLatLon(dbRegion);
|
|
170
|
+
}
|
|
171
|
+
// Determine confidence
|
|
172
|
+
let confidence = "UNKNOWN";
|
|
173
|
+
if (origin.source === "MANUAL" && gateway.region !== "UNKNOWN") {
|
|
174
|
+
confidence = "HIGH";
|
|
175
|
+
}
|
|
176
|
+
else if (origin.label !== "UNKNOWN" || gateway.region !== "UNKNOWN") {
|
|
177
|
+
confidence = "MEDIUM";
|
|
178
|
+
}
|
|
179
|
+
else if (origin.label === "UNKNOWN" && gateway.region === "UNKNOWN") {
|
|
180
|
+
confidence = "UNKNOWN";
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
confidence = "LOW";
|
|
184
|
+
}
|
|
185
|
+
// Determine source
|
|
186
|
+
const source = origin.source === "MANUAL" ? "MANUAL" :
|
|
187
|
+
origin.source === "LOCAL_IP" ? "LOCAL_IP" :
|
|
188
|
+
gateway.source === "AWS_META" ? "AWS_META" :
|
|
189
|
+
"NONE";
|
|
190
|
+
const data = {
|
|
191
|
+
originLabel: origin.label,
|
|
192
|
+
originRegion: origin.region,
|
|
193
|
+
originLatLon: origin.latLon,
|
|
194
|
+
gatewayRegion: gateway.region,
|
|
195
|
+
gatewayLatLon,
|
|
196
|
+
dbRegion,
|
|
197
|
+
dbLatLon,
|
|
198
|
+
routeLabel,
|
|
199
|
+
pingMs,
|
|
200
|
+
pingClass: pingMs !== "UNKNOWN" ? getLatencyClass(pingMs) : "UNKNOWN",
|
|
201
|
+
confidence,
|
|
202
|
+
source,
|
|
203
|
+
};
|
|
204
|
+
// Phase 9: Determine status
|
|
205
|
+
const now = Date.now();
|
|
206
|
+
let status = 'LIVE';
|
|
207
|
+
let reasonCode;
|
|
208
|
+
let message;
|
|
209
|
+
let action;
|
|
210
|
+
if (!ALLOW_GEO_LOOKUP && source === "NONE") {
|
|
211
|
+
status = 'DISABLED';
|
|
212
|
+
reasonCode = 'GEO_LOOKUP_DISABLED';
|
|
213
|
+
message = 'Geo lookup off';
|
|
214
|
+
action = 'system enable-geo';
|
|
215
|
+
}
|
|
216
|
+
else if (confidence === "UNKNOWN" || (source === "NONE" && origin.label === "UNKNOWN" && gateway.region === "UNKNOWN")) {
|
|
217
|
+
status = 'UNAVAILABLE';
|
|
218
|
+
reasonCode = 'NO_GEO_DATA';
|
|
219
|
+
message = 'No geo data available';
|
|
220
|
+
action = 'system enable-geo';
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
status = 'LIVE';
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
status,
|
|
227
|
+
asOf: now,
|
|
228
|
+
data,
|
|
229
|
+
source: 'collector_geo',
|
|
230
|
+
staleAfterMs: 30000, // Geo data changes slowly
|
|
231
|
+
reasonCode,
|
|
232
|
+
message,
|
|
233
|
+
action,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
return {
|
|
238
|
+
status: 'UNAVAILABLE',
|
|
239
|
+
asOf: Date.now(),
|
|
240
|
+
source: 'collector_geo',
|
|
241
|
+
staleAfterMs: 30000,
|
|
242
|
+
reasonCode: 'COLLECTION_ERROR',
|
|
243
|
+
message: error.message || 'Unknown error',
|
|
244
|
+
action: 'system status',
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=collector_geo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector_geo.js","sourceRoot":"","sources":["../../src/collectors/collector_geo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Network Collector
|
|
3
|
+
* Phase 3: Origin class, public IP masked, latency, geo
|
|
4
|
+
* Runs slower (expensive checks)
|
|
5
|
+
*/
|
|
6
|
+
import type { CollectorResult } from '../core/types.js';
|
|
7
|
+
import type { AppState } from '../store.js';
|
|
8
|
+
export type NetworkData = {
|
|
9
|
+
originRegion: string | "UNKNOWN";
|
|
10
|
+
originClass: "LOCAL" | "VPN" | "CLOUD" | "UNKNOWN";
|
|
11
|
+
gatewayRegion: string | "UNKNOWN";
|
|
12
|
+
dbRegion: string | "NONE" | "UNKNOWN";
|
|
13
|
+
latencyMs: number | "UNKNOWN";
|
|
14
|
+
latencyClass: "LOW" | "MEDIUM" | "HIGH" | "UNKNOWN";
|
|
15
|
+
publicIpMasked: string | "HIDDEN" | "UNKNOWN";
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Collect network context
|
|
19
|
+
* Expensive checks - should run slower (10-30s)
|
|
20
|
+
*/
|
|
21
|
+
export declare function collectNetwork(appState: AppState): Promise<CollectorResult<NetworkData>>;
|
|
22
|
+
//# sourceMappingURL=collector_network.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector_network.d.ts","sourceRoot":"","sources":["../../src/collectors/collector_network.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kBAAkB,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,MAAM,WAAW,GAAG;IACxB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,WAAW,EAAE,OAAO,GAAG,KAAK,GAAG,OAAO,GAAG,SAAS,CAAC;IACnD,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACtC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,YAAY,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;IACpD,cAAc,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;CAC/C,CAAC;AAEF;;;GAGG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CA4E9F"}
|