forkit-ai-footprints 0.2.0
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/LICENSE +21 -0
- package/PRIVACY.md +150 -0
- package/README.md +313 -0
- package/STATUS.md +136 -0
- package/dist/agents.d.ts +22 -0
- package/dist/agents.js +281 -0
- package/dist/aggregate.d.ts +28 -0
- package/dist/aggregate.js +151 -0
- package/dist/assets/forkit-icon-dark.png +0 -0
- package/dist/assets/forkit-icon-light.png +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Info.plist +5 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/MacOS/Forkit AI Footprint +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/ForkitAIFootprint.icns +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/ForkitStatusTemplate.png +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/agents.d.ts +22 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/agents.js +281 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/aggregate.d.ts +28 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/aggregate.js +151 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/assets/forkit-icon-dark.png +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/assets/forkit-icon-light.png +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/census.d.ts +3 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/census.js +196 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/cli.d.ts +32 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/cli.js +404 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/doctor.d.ts +14 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/doctor.js +71 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/endpoints.d.ts +8 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/endpoints.js +45 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/evaluate.d.ts +44 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/evaluate.js +102 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/filesystem.d.ts +11 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/filesystem.js +226 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/format.d.ts +7 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/format.js +78 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/hash.d.ts +4 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/hash.js +16 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/index.d.ts +22 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/index.js +58 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/insights.d.ts +13 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/insights.js +76 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/local-device.d.ts +19 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/local-device.js +81 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/locales.json +272 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/localization.d.ts +277 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/localization.js +55 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/mcp.d.ts +9 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/mcp.js +93 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/monitor.d.ts +99 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/monitor.js +285 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/base.d.ts +34 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/base.js +88 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/index.d.ts +6 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/index.js +24 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/lmstudio.d.ts +9 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/lmstudio.js +71 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/ollama.d.ts +12 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/ollama.js +171 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/openai-compatible.d.ts +10 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/openai-compatible.js +68 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/resource-evidence.d.ts +17 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/resource-evidence.js +52 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/runtime-activity.d.ts +5 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/runtime-activity.js +66 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/runtime-identity.d.ts +7 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/runtime-identity.js +66 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/server.d.ts +21 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/server.js +308 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/share-page.d.ts +75 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/share-page.js +167 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/sharing.d.ts +35 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/sharing.js +67 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/tools.d.ts +9 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/tools.js +106 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/types.d.ts +166 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/types.js +3 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/version.d.ts +4 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/version.js +13 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/node_modules/ps-list/index.d.ts +76 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/node_modules/ps-list/index.js +366 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/node_modules/ps-list/license +9 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/node_modules/ps-list/package.json +44 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/node_modules/ps-list/readme.md +56 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/node_modules/ps-list/vendor/fastlist-0.3.0-x64.exe +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/node_modules/ps-list/vendor/fastlist-0.3.0-x86.exe +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/package.json +6 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/runtime/node +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/_CodeSignature/CodeResources +931 -0
- package/dist/census.d.ts +3 -0
- package/dist/census.js +196 -0
- package/dist/cli.d.ts +32 -0
- package/dist/cli.js +404 -0
- package/dist/doctor.d.ts +14 -0
- package/dist/doctor.js +71 -0
- package/dist/endpoints.d.ts +8 -0
- package/dist/endpoints.js +45 -0
- package/dist/evaluate.d.ts +44 -0
- package/dist/evaluate.js +102 -0
- package/dist/filesystem.d.ts +11 -0
- package/dist/filesystem.js +226 -0
- package/dist/format.d.ts +7 -0
- package/dist/format.js +78 -0
- package/dist/hash.d.ts +4 -0
- package/dist/hash.js +16 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +58 -0
- package/dist/insights.d.ts +13 -0
- package/dist/insights.js +76 -0
- package/dist/local-device.d.ts +19 -0
- package/dist/local-device.js +81 -0
- package/dist/locales.json +272 -0
- package/dist/localization.d.ts +277 -0
- package/dist/localization.js +55 -0
- package/dist/mcp.d.ts +9 -0
- package/dist/mcp.js +93 -0
- package/dist/monitor.d.ts +99 -0
- package/dist/monitor.js +285 -0
- package/dist/providers/base.d.ts +34 -0
- package/dist/providers/base.js +88 -0
- package/dist/providers/index.d.ts +6 -0
- package/dist/providers/index.js +24 -0
- package/dist/providers/lmstudio.d.ts +9 -0
- package/dist/providers/lmstudio.js +71 -0
- package/dist/providers/ollama.d.ts +12 -0
- package/dist/providers/ollama.js +171 -0
- package/dist/providers/openai-compatible.d.ts +10 -0
- package/dist/providers/openai-compatible.js +68 -0
- package/dist/resource-evidence.d.ts +17 -0
- package/dist/resource-evidence.js +52 -0
- package/dist/runtime-activity.d.ts +5 -0
- package/dist/runtime-activity.js +66 -0
- package/dist/runtime-identity.d.ts +7 -0
- package/dist/runtime-identity.js +66 -0
- package/dist/server.d.ts +21 -0
- package/dist/server.js +308 -0
- package/dist/share-page.d.ts +75 -0
- package/dist/share-page.js +167 -0
- package/dist/sharing.d.ts +35 -0
- package/dist/sharing.js +67 -0
- package/dist/tools.d.ts +9 -0
- package/dist/tools.js +106 -0
- package/dist/types.d.ts +166 -0
- package/dist/types.js +3 -0
- package/dist/version.d.ts +4 -0
- package/dist/version.js +13 -0
- package/docs/GLOBAL_DISTRIBUTION.md +79 -0
- package/docs/MACOS_ACCURACY_GATE.md +140 -0
- package/docs/MACOS_TESTER_GUIDE.md +88 -0
- package/examples/macos-truth.template.json +10 -0
- package/package.json +75 -0
- package/release/channels.json +41 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchJson = fetchJson;
|
|
4
|
+
exports.createRuntime = createRuntime;
|
|
5
|
+
exports.createModel = createModel;
|
|
6
|
+
exports.readRecord = readRecord;
|
|
7
|
+
exports.readArray = readArray;
|
|
8
|
+
exports.readString = readString;
|
|
9
|
+
exports.readNumber = readNumber;
|
|
10
|
+
const hash_1 = require("../hash");
|
|
11
|
+
async function fetchJson(url, init, fetchImpl, timeoutMs = 3000) {
|
|
12
|
+
const controller = new AbortController();
|
|
13
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
14
|
+
try {
|
|
15
|
+
const response = await fetchImpl(url, { ...init, signal: controller.signal });
|
|
16
|
+
let body = null;
|
|
17
|
+
try {
|
|
18
|
+
body = await response.json();
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
body = null;
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
ok: response.ok,
|
|
25
|
+
status: response.status,
|
|
26
|
+
body,
|
|
27
|
+
error: response.ok ? null : `http_${response.status}`,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
const code = error instanceof Error && error.name === 'AbortError'
|
|
32
|
+
? 'timeout'
|
|
33
|
+
: 'connection_unavailable';
|
|
34
|
+
return { ok: false, status: 0, body: null, error: code };
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
clearTimeout(timer);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function createRuntime(input) {
|
|
41
|
+
return {
|
|
42
|
+
runtime_id: (0, hash_1.stableId)('runtime', `${input.name}:${input.endpoint ?? 'local-inventory'}`),
|
|
43
|
+
name: input.name,
|
|
44
|
+
status: input.status,
|
|
45
|
+
endpoint: input.endpoint,
|
|
46
|
+
model_count: input.modelCount,
|
|
47
|
+
observed_at: input.observedAt,
|
|
48
|
+
error_code: input.errorCode ?? null,
|
|
49
|
+
evidence_status: input.status === 'available'
|
|
50
|
+
? 'online'
|
|
51
|
+
: input.status === 'inventory-only'
|
|
52
|
+
? 'configured'
|
|
53
|
+
: 'unavailable',
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function createModel(input) {
|
|
57
|
+
return {
|
|
58
|
+
model_id: (0, hash_1.stableId)('model', `${input.runtime}:${input.name}:${input.identity}`),
|
|
59
|
+
name: input.name,
|
|
60
|
+
runtime: input.runtime,
|
|
61
|
+
identity_kind: input.identityKind,
|
|
62
|
+
identity: input.identity,
|
|
63
|
+
size_bytes: input.sizeBytes ?? null,
|
|
64
|
+
modified_at: input.modifiedAt ?? null,
|
|
65
|
+
quantization: input.quantization ?? null,
|
|
66
|
+
architecture: input.architecture ?? null,
|
|
67
|
+
parameter_size: input.parameterSize ?? null,
|
|
68
|
+
source: input.source,
|
|
69
|
+
location_hint: input.locationHint ?? null,
|
|
70
|
+
confidence: input.confidence,
|
|
71
|
+
evidence_status: 'discovered',
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function readRecord(value) {
|
|
75
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
76
|
+
? value
|
|
77
|
+
: null;
|
|
78
|
+
}
|
|
79
|
+
function readArray(value) {
|
|
80
|
+
return Array.isArray(value) ? value : [];
|
|
81
|
+
}
|
|
82
|
+
function readString(value) {
|
|
83
|
+
return typeof value === 'string' && value.trim() ? value.trim() : null;
|
|
84
|
+
}
|
|
85
|
+
function readNumber(value) {
|
|
86
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : null;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=base.js.map
|
package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RuntimeProvider } from '../types';
|
|
2
|
+
export { LMStudioProvider } from './lmstudio';
|
|
3
|
+
export { OllamaProvider } from './ollama';
|
|
4
|
+
export { OpenAICompatibleProvider, configuredOpenAICompatibleProviders } from './openai-compatible';
|
|
5
|
+
export declare function createDefaultProviders(fetchImpl?: typeof fetch): RuntimeProvider[];
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configuredOpenAICompatibleProviders = exports.OpenAICompatibleProvider = exports.OllamaProvider = exports.LMStudioProvider = void 0;
|
|
4
|
+
exports.createDefaultProviders = createDefaultProviders;
|
|
5
|
+
const lmstudio_1 = require("./lmstudio");
|
|
6
|
+
const ollama_1 = require("./ollama");
|
|
7
|
+
const openai_compatible_1 = require("./openai-compatible");
|
|
8
|
+
var lmstudio_2 = require("./lmstudio");
|
|
9
|
+
Object.defineProperty(exports, "LMStudioProvider", { enumerable: true, get: function () { return lmstudio_2.LMStudioProvider; } });
|
|
10
|
+
var ollama_2 = require("./ollama");
|
|
11
|
+
Object.defineProperty(exports, "OllamaProvider", { enumerable: true, get: function () { return ollama_2.OllamaProvider; } });
|
|
12
|
+
var openai_compatible_2 = require("./openai-compatible");
|
|
13
|
+
Object.defineProperty(exports, "OpenAICompatibleProvider", { enumerable: true, get: function () { return openai_compatible_2.OpenAICompatibleProvider; } });
|
|
14
|
+
Object.defineProperty(exports, "configuredOpenAICompatibleProviders", { enumerable: true, get: function () { return openai_compatible_2.configuredOpenAICompatibleProviders; } });
|
|
15
|
+
function createDefaultProviders(fetchImpl = fetch) {
|
|
16
|
+
if (process.env.FORKIT_CENSUS_DISABLE_DEFAULT_RUNTIMES === '1')
|
|
17
|
+
return [];
|
|
18
|
+
return [
|
|
19
|
+
new ollama_1.OllamaProvider('http://localhost:11434', fetchImpl),
|
|
20
|
+
new lmstudio_1.LMStudioProvider('http://localhost:1234', fetchImpl),
|
|
21
|
+
...(0, openai_compatible_1.configuredOpenAICompatibleProviders)(process.env.FORKIT_CENSUS_OPENAI_ENDPOINTS ?? 'http://localhost:8000', fetchImpl),
|
|
22
|
+
];
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/lmstudio.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RuntimeProvider, RuntimeScanResult } from '../types';
|
|
2
|
+
export declare class LMStudioProvider implements RuntimeProvider {
|
|
3
|
+
private readonly fetchImpl;
|
|
4
|
+
readonly name: "lmstudio";
|
|
5
|
+
private readonly endpoint;
|
|
6
|
+
constructor(endpoint?: string, fetchImpl?: typeof fetch);
|
|
7
|
+
scan(observedAt: string): Promise<RuntimeScanResult>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=lmstudio.d.ts.map
|
package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/lmstudio.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LMStudioProvider = void 0;
|
|
4
|
+
const endpoints_1 = require("../endpoints");
|
|
5
|
+
const hash_1 = require("../hash");
|
|
6
|
+
const base_1 = require("./base");
|
|
7
|
+
class LMStudioProvider {
|
|
8
|
+
fetchImpl;
|
|
9
|
+
name = 'lmstudio';
|
|
10
|
+
endpoint;
|
|
11
|
+
constructor(endpoint = 'http://localhost:1234', fetchImpl = fetch) {
|
|
12
|
+
this.fetchImpl = fetchImpl;
|
|
13
|
+
const safeEndpoint = (0, endpoints_1.parseLoopbackEndpoint)(endpoint);
|
|
14
|
+
if (!safeEndpoint)
|
|
15
|
+
throw new Error('LM Studio endpoint must be loopback HTTP(S).');
|
|
16
|
+
this.endpoint = safeEndpoint;
|
|
17
|
+
}
|
|
18
|
+
async scan(observedAt) {
|
|
19
|
+
const v0 = await (0, base_1.fetchJson)(`${this.endpoint.url}/api/v0/models`, { method: 'GET' }, this.fetchImpl);
|
|
20
|
+
const result = v0.ok
|
|
21
|
+
? v0
|
|
22
|
+
: await (0, base_1.fetchJson)(`${this.endpoint.url}/v1/models`, { method: 'GET' }, this.fetchImpl);
|
|
23
|
+
if (!result.ok) {
|
|
24
|
+
return {
|
|
25
|
+
runtime: (0, base_1.createRuntime)({
|
|
26
|
+
name: this.name,
|
|
27
|
+
endpoint: this.endpoint.display,
|
|
28
|
+
status: 'unavailable',
|
|
29
|
+
modelCount: 0,
|
|
30
|
+
observedAt,
|
|
31
|
+
errorCode: result.error,
|
|
32
|
+
}),
|
|
33
|
+
models: [],
|
|
34
|
+
warnings: [],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const body = (0, base_1.readRecord)(result.body);
|
|
38
|
+
const models = (0, base_1.readArray)(body?.data).flatMap((value) => {
|
|
39
|
+
const entry = (0, base_1.readRecord)(value);
|
|
40
|
+
const name = (0, base_1.readString)(entry?.id);
|
|
41
|
+
if (!name)
|
|
42
|
+
return [];
|
|
43
|
+
return [(0, base_1.createModel)({
|
|
44
|
+
name,
|
|
45
|
+
runtime: this.name,
|
|
46
|
+
identityKind: 'provider-id',
|
|
47
|
+
identity: (0, hash_1.sha256)(`lmstudio:${name}`),
|
|
48
|
+
source: 'runtime-api',
|
|
49
|
+
confidence: 'medium',
|
|
50
|
+
quantization: (0, base_1.readString)(entry?.quantization),
|
|
51
|
+
architecture: (0, base_1.readString)(entry?.arch),
|
|
52
|
+
parameterSize: (0, base_1.readNumber)(entry?.parameter_size) === null
|
|
53
|
+
? (0, base_1.readString)(entry?.parameter_size)
|
|
54
|
+
: String((0, base_1.readNumber)(entry?.parameter_size)),
|
|
55
|
+
})];
|
|
56
|
+
});
|
|
57
|
+
return {
|
|
58
|
+
runtime: (0, base_1.createRuntime)({
|
|
59
|
+
name: this.name,
|
|
60
|
+
endpoint: this.endpoint.display,
|
|
61
|
+
status: 'available',
|
|
62
|
+
modelCount: models.length,
|
|
63
|
+
observedAt,
|
|
64
|
+
}),
|
|
65
|
+
models,
|
|
66
|
+
warnings: [],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.LMStudioProvider = LMStudioProvider;
|
|
71
|
+
//# sourceMappingURL=lmstudio.js.map
|
package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/ollama.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type RuntimeIdentityVerifier } from '../runtime-identity';
|
|
2
|
+
import type { RuntimeProvider, RuntimeScanResult } from '../types';
|
|
3
|
+
export declare class OllamaProvider implements RuntimeProvider {
|
|
4
|
+
private readonly fetchImpl;
|
|
5
|
+
private readonly verifyIdentity;
|
|
6
|
+
readonly name: "ollama";
|
|
7
|
+
private readonly endpoint;
|
|
8
|
+
private readonly detailsCache;
|
|
9
|
+
constructor(endpoint?: string, fetchImpl?: typeof fetch, verifyIdentity?: RuntimeIdentityVerifier);
|
|
10
|
+
scan(observedAt: string): Promise<RuntimeScanResult>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=ollama.d.ts.map
|
package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/ollama.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OllamaProvider = void 0;
|
|
4
|
+
const endpoints_1 = require("../endpoints");
|
|
5
|
+
const hash_1 = require("../hash");
|
|
6
|
+
const runtime_identity_1 = require("../runtime-identity");
|
|
7
|
+
const base_1 = require("./base");
|
|
8
|
+
function parseSha256(value) {
|
|
9
|
+
if (!value)
|
|
10
|
+
return null;
|
|
11
|
+
const match = /^(?:sha256:)?([0-9a-f]{64})$/i.exec(value);
|
|
12
|
+
return match?.[1]?.toLowerCase() ?? null;
|
|
13
|
+
}
|
|
14
|
+
function validOllamaVersion(value) {
|
|
15
|
+
const body = (0, base_1.readRecord)(value);
|
|
16
|
+
const version = (0, base_1.readString)(body?.version);
|
|
17
|
+
return version !== null && /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(version);
|
|
18
|
+
}
|
|
19
|
+
function validModelArray(value) {
|
|
20
|
+
const body = (0, base_1.readRecord)(value);
|
|
21
|
+
return body !== null && Array.isArray(body.models) ? body.models : null;
|
|
22
|
+
}
|
|
23
|
+
class OllamaProvider {
|
|
24
|
+
fetchImpl;
|
|
25
|
+
verifyIdentity;
|
|
26
|
+
name = 'ollama';
|
|
27
|
+
endpoint;
|
|
28
|
+
detailsCache = new Map();
|
|
29
|
+
constructor(endpoint = 'http://localhost:11434', fetchImpl = fetch, verifyIdentity = runtime_identity_1.verifyMacosLoopbackRuntimeIdentity) {
|
|
30
|
+
this.fetchImpl = fetchImpl;
|
|
31
|
+
this.verifyIdentity = verifyIdentity;
|
|
32
|
+
const safeEndpoint = (0, endpoints_1.parseLoopbackEndpoint)(endpoint);
|
|
33
|
+
if (!safeEndpoint)
|
|
34
|
+
throw new Error('Ollama endpoint must be loopback HTTP(S).');
|
|
35
|
+
this.endpoint = safeEndpoint;
|
|
36
|
+
}
|
|
37
|
+
async scan(observedAt) {
|
|
38
|
+
if (!await this.verifyIdentity(this.endpoint.url, 'ollama')) {
|
|
39
|
+
return {
|
|
40
|
+
runtime: (0, base_1.createRuntime)({
|
|
41
|
+
name: this.name,
|
|
42
|
+
endpoint: this.endpoint.display,
|
|
43
|
+
status: 'unavailable',
|
|
44
|
+
modelCount: 0,
|
|
45
|
+
observedAt,
|
|
46
|
+
errorCode: 'runtime_identity_unverified',
|
|
47
|
+
}),
|
|
48
|
+
models: [],
|
|
49
|
+
warnings: [{
|
|
50
|
+
code: 'runtime_identity_unverified',
|
|
51
|
+
message: 'A loopback response could not be tied to the supported Ollama executable.',
|
|
52
|
+
scope: 'runtime',
|
|
53
|
+
}],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const [version, tags, running] = await Promise.all([
|
|
57
|
+
(0, base_1.fetchJson)(`${this.endpoint.url}/api/version`, { method: 'GET' }, this.fetchImpl),
|
|
58
|
+
(0, base_1.fetchJson)(`${this.endpoint.url}/api/tags`, { method: 'GET' }, this.fetchImpl),
|
|
59
|
+
(0, base_1.fetchJson)(`${this.endpoint.url}/api/ps`, { method: 'GET' }, this.fetchImpl),
|
|
60
|
+
]);
|
|
61
|
+
const tagEntries = tags.ok ? validModelArray(tags.body) : null;
|
|
62
|
+
if (!version.ok || !validOllamaVersion(version.body) || tagEntries === null) {
|
|
63
|
+
return {
|
|
64
|
+
runtime: (0, base_1.createRuntime)({
|
|
65
|
+
name: this.name,
|
|
66
|
+
endpoint: this.endpoint.display,
|
|
67
|
+
status: 'unavailable',
|
|
68
|
+
modelCount: 0,
|
|
69
|
+
observedAt,
|
|
70
|
+
errorCode: !version.ok ? version.error : !tags.ok ? tags.error : 'invalid_ollama_api_shape',
|
|
71
|
+
}),
|
|
72
|
+
models: [],
|
|
73
|
+
warnings: [{
|
|
74
|
+
code: 'ollama_api_unverified',
|
|
75
|
+
message: 'The listener owner matched Ollama, but its version or inventory response was not valid.',
|
|
76
|
+
scope: 'runtime',
|
|
77
|
+
}],
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const validatedRunning = running.ok ? validModelArray(running.body) : null;
|
|
81
|
+
const runningEntries = validatedRunning ?? [];
|
|
82
|
+
const runningNames = new Set(runningEntries.flatMap((value) => {
|
|
83
|
+
const entry = (0, base_1.readRecord)(value);
|
|
84
|
+
const name = (0, base_1.readString)(entry?.name) ?? (0, base_1.readString)(entry?.model);
|
|
85
|
+
return name ? [name.toLowerCase()] : [];
|
|
86
|
+
}));
|
|
87
|
+
const entries = tagEntries;
|
|
88
|
+
const models = await Promise.all(entries.map(async (entryValue) => {
|
|
89
|
+
const entry = (0, base_1.readRecord)(entryValue);
|
|
90
|
+
const name = (0, base_1.readString)(entry?.name) ?? (0, base_1.readString)(entry?.model);
|
|
91
|
+
if (!name)
|
|
92
|
+
return null;
|
|
93
|
+
const manifestDigest = parseSha256((0, base_1.readString)(entry?.digest));
|
|
94
|
+
const cacheKey = manifestDigest ?? name.toLowerCase();
|
|
95
|
+
let detailsValue = this.detailsCache.get(cacheKey);
|
|
96
|
+
if (detailsValue === undefined) {
|
|
97
|
+
const detailsResult = await (0, base_1.fetchJson)(`${this.endpoint.url}/api/show`, {
|
|
98
|
+
method: 'POST',
|
|
99
|
+
headers: { 'Content-Type': 'application/json' },
|
|
100
|
+
body: JSON.stringify({ model: name, verbose: false }),
|
|
101
|
+
}, this.fetchImpl, 4000);
|
|
102
|
+
if (detailsResult.ok) {
|
|
103
|
+
detailsValue = detailsResult.body;
|
|
104
|
+
this.detailsCache.set(cacheKey, detailsValue);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const detailsBody = (0, base_1.readRecord)(detailsValue);
|
|
108
|
+
const layers = (0, base_1.readArray)(detailsBody?.layers);
|
|
109
|
+
const modelLayer = layers
|
|
110
|
+
.map((layer) => (0, base_1.readRecord)(layer))
|
|
111
|
+
.find((layer) => (0, base_1.readString)(layer?.mediaType) === 'application/vnd.ollama.image.model');
|
|
112
|
+
const weightsDigest = parseSha256((0, base_1.readString)(modelLayer?.digest));
|
|
113
|
+
const details = (0, base_1.readRecord)(detailsBody?.details);
|
|
114
|
+
const contentIdentity = weightsDigest ?? manifestDigest;
|
|
115
|
+
const identity = contentIdentity ?? (0, hash_1.sha256)(`ollama:${name}`);
|
|
116
|
+
const model = (0, base_1.createModel)({
|
|
117
|
+
name,
|
|
118
|
+
runtime: this.name,
|
|
119
|
+
identityKind: contentIdentity ? 'content-sha256' : 'provider-id',
|
|
120
|
+
identity,
|
|
121
|
+
source: 'runtime-api',
|
|
122
|
+
confidence: contentIdentity ? 'high' : 'medium',
|
|
123
|
+
sizeBytes: (0, base_1.readNumber)(entry?.size),
|
|
124
|
+
modifiedAt: (0, base_1.readString)(entry?.modified_at),
|
|
125
|
+
quantization: (0, base_1.readString)(details?.quantization_level),
|
|
126
|
+
architecture: (0, base_1.readString)(details?.family),
|
|
127
|
+
parameterSize: (0, base_1.readString)(details?.parameter_size),
|
|
128
|
+
});
|
|
129
|
+
return {
|
|
130
|
+
...model,
|
|
131
|
+
evidence_status: runningNames.has(name.toLowerCase()) ? 'confirmed-running' : 'discovered',
|
|
132
|
+
};
|
|
133
|
+
}));
|
|
134
|
+
const detectedModels = models.filter((model) => model !== null);
|
|
135
|
+
const detectedNames = new Set(detectedModels.map((model) => model.name.toLowerCase()));
|
|
136
|
+
for (const value of runningEntries) {
|
|
137
|
+
const entry = (0, base_1.readRecord)(value);
|
|
138
|
+
const name = (0, base_1.readString)(entry?.name) ?? (0, base_1.readString)(entry?.model);
|
|
139
|
+
if (!name || detectedNames.has(name.toLowerCase()))
|
|
140
|
+
continue;
|
|
141
|
+
const digest = parseSha256((0, base_1.readString)(entry?.digest));
|
|
142
|
+
const model = (0, base_1.createModel)({
|
|
143
|
+
name,
|
|
144
|
+
runtime: this.name,
|
|
145
|
+
identityKind: digest ? 'content-sha256' : 'provider-id',
|
|
146
|
+
identity: digest ?? (0, hash_1.sha256)(`ollama:${name}`),
|
|
147
|
+
source: 'runtime-api',
|
|
148
|
+
confidence: digest ? 'high' : 'medium',
|
|
149
|
+
sizeBytes: (0, base_1.readNumber)(entry?.size),
|
|
150
|
+
});
|
|
151
|
+
detectedModels.push({ ...model, evidence_status: 'confirmed-running' });
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
runtime: (0, base_1.createRuntime)({
|
|
155
|
+
name: this.name,
|
|
156
|
+
endpoint: this.endpoint.display,
|
|
157
|
+
status: 'available',
|
|
158
|
+
modelCount: detectedModels.length,
|
|
159
|
+
observedAt,
|
|
160
|
+
}),
|
|
161
|
+
models: detectedModels,
|
|
162
|
+
warnings: validatedRunning !== null ? [] : [{
|
|
163
|
+
code: 'ollama_running_state_unavailable',
|
|
164
|
+
message: 'Ollama inventory was available, but confirmed loaded-model state could not be read.',
|
|
165
|
+
scope: 'runtime',
|
|
166
|
+
}],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
exports.OllamaProvider = OllamaProvider;
|
|
171
|
+
//# sourceMappingURL=ollama.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RuntimeProvider, RuntimeScanResult } from '../types';
|
|
2
|
+
export declare class OpenAICompatibleProvider implements RuntimeProvider {
|
|
3
|
+
private readonly fetchImpl;
|
|
4
|
+
readonly name: "openai-compatible";
|
|
5
|
+
private readonly endpoint;
|
|
6
|
+
constructor(endpoint?: string, fetchImpl?: typeof fetch);
|
|
7
|
+
scan(observedAt: string): Promise<RuntimeScanResult>;
|
|
8
|
+
}
|
|
9
|
+
export declare function configuredOpenAICompatibleProviders(raw?: string, fetchImpl?: typeof fetch): OpenAICompatibleProvider[];
|
|
10
|
+
//# sourceMappingURL=openai-compatible.d.ts.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OpenAICompatibleProvider = void 0;
|
|
4
|
+
exports.configuredOpenAICompatibleProviders = configuredOpenAICompatibleProviders;
|
|
5
|
+
const endpoints_1 = require("../endpoints");
|
|
6
|
+
const hash_1 = require("../hash");
|
|
7
|
+
const base_1 = require("./base");
|
|
8
|
+
class OpenAICompatibleProvider {
|
|
9
|
+
fetchImpl;
|
|
10
|
+
name = 'openai-compatible';
|
|
11
|
+
endpoint;
|
|
12
|
+
constructor(endpoint = 'http://localhost:8000', fetchImpl = fetch) {
|
|
13
|
+
this.fetchImpl = fetchImpl;
|
|
14
|
+
const safeEndpoint = (0, endpoints_1.parseLoopbackEndpoint)(endpoint);
|
|
15
|
+
if (!safeEndpoint)
|
|
16
|
+
throw new Error('OpenAI-compatible endpoint must be loopback HTTP(S).');
|
|
17
|
+
this.endpoint = safeEndpoint;
|
|
18
|
+
}
|
|
19
|
+
async scan(observedAt) {
|
|
20
|
+
const result = await (0, base_1.fetchJson)(`${this.endpoint.url}/v1/models`, { method: 'GET' }, this.fetchImpl);
|
|
21
|
+
if (!result.ok) {
|
|
22
|
+
return {
|
|
23
|
+
runtime: (0, base_1.createRuntime)({
|
|
24
|
+
name: this.name,
|
|
25
|
+
endpoint: this.endpoint.display,
|
|
26
|
+
status: 'unavailable',
|
|
27
|
+
modelCount: 0,
|
|
28
|
+
observedAt,
|
|
29
|
+
errorCode: result.error,
|
|
30
|
+
}),
|
|
31
|
+
models: [],
|
|
32
|
+
warnings: [],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const body = (0, base_1.readRecord)(result.body);
|
|
36
|
+
const models = (0, base_1.readArray)(body?.data).flatMap((value) => {
|
|
37
|
+
const entry = (0, base_1.readRecord)(value);
|
|
38
|
+
const name = (0, base_1.readString)(entry?.id);
|
|
39
|
+
if (!name)
|
|
40
|
+
return [];
|
|
41
|
+
return [(0, base_1.createModel)({
|
|
42
|
+
name,
|
|
43
|
+
runtime: this.name,
|
|
44
|
+
identityKind: 'provider-id',
|
|
45
|
+
identity: (0, hash_1.sha256)(`openai-compatible:${this.endpoint.id}:${name}`),
|
|
46
|
+
source: 'runtime-api',
|
|
47
|
+
confidence: 'medium',
|
|
48
|
+
})];
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
runtime: (0, base_1.createRuntime)({
|
|
52
|
+
name: this.name,
|
|
53
|
+
endpoint: this.endpoint.display,
|
|
54
|
+
status: 'available',
|
|
55
|
+
modelCount: models.length,
|
|
56
|
+
observedAt,
|
|
57
|
+
}),
|
|
58
|
+
models,
|
|
59
|
+
warnings: [],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.OpenAICompatibleProvider = OpenAICompatibleProvider;
|
|
64
|
+
function configuredOpenAICompatibleProviders(raw = process.env.FORKIT_CENSUS_OPENAI_ENDPOINTS ?? 'http://localhost:8000', fetchImpl = fetch) {
|
|
65
|
+
return (0, endpoints_1.parseLoopbackEndpointList)(raw)
|
|
66
|
+
.map((endpoint) => new OpenAICompatibleProvider(endpoint.url, fetchImpl));
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=openai-compatible.js.map
|
package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/resource-evidence.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type ResourceEvidenceState = 'measured' | 'hardware-fact' | 'not-available';
|
|
2
|
+
export type AttributionStrength = 'detected-process-window' | 'device' | 'none';
|
|
3
|
+
export interface ResourceEvidenceCapability {
|
|
4
|
+
metric: 'cpu' | 'memory' | 'gpu' | 'hardware' | 'network_traffic';
|
|
5
|
+
state: ResourceEvidenceState;
|
|
6
|
+
attribution: AttributionStrength;
|
|
7
|
+
source: string;
|
|
8
|
+
exclusive_task_proof: false;
|
|
9
|
+
limitation: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ResourceEvidenceManifest {
|
|
12
|
+
schema_version: '1.0';
|
|
13
|
+
platform: 'macos';
|
|
14
|
+
capabilities: ResourceEvidenceCapability[];
|
|
15
|
+
}
|
|
16
|
+
export declare function macosResourceEvidenceManifest(): ResourceEvidenceManifest;
|
|
17
|
+
//# sourceMappingURL=resource-evidence.d.ts.map
|
package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/resource-evidence.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.macosResourceEvidenceManifest = macosResourceEvidenceManifest;
|
|
4
|
+
function macosResourceEvidenceManifest() {
|
|
5
|
+
return {
|
|
6
|
+
schema_version: '1.0',
|
|
7
|
+
platform: 'macos',
|
|
8
|
+
capabilities: [
|
|
9
|
+
{
|
|
10
|
+
metric: 'cpu',
|
|
11
|
+
state: 'measured',
|
|
12
|
+
attribution: 'detected-process-window',
|
|
13
|
+
source: 'operating-system-process-sample',
|
|
14
|
+
exclusive_task_proof: false,
|
|
15
|
+
limitation: 'Detected process work is measured; concurrent background work inside the same process can be included.',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
metric: 'memory',
|
|
19
|
+
state: 'measured',
|
|
20
|
+
attribution: 'detected-process-window',
|
|
21
|
+
source: 'operating-system-process-sample',
|
|
22
|
+
exclusive_task_proof: false,
|
|
23
|
+
limitation: 'Memory is shared and may persist across tasks; the window cannot prove which task owns every byte.',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
metric: 'gpu',
|
|
27
|
+
state: 'not-available',
|
|
28
|
+
attribution: 'none',
|
|
29
|
+
source: 'no-supported-cross-process-proof-source',
|
|
30
|
+
exclusive_task_proof: false,
|
|
31
|
+
limitation: 'Metal counters can measure work submitted by an instrumented app, not arbitrary third-party AI process work as exclusive task proof.',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
metric: 'hardware',
|
|
35
|
+
state: 'hardware-fact',
|
|
36
|
+
attribution: 'device',
|
|
37
|
+
source: 'operating-system-hardware-metadata',
|
|
38
|
+
exclusive_task_proof: false,
|
|
39
|
+
limitation: 'Hardware inventory identifies device capability; it does not prove task-specific utilization.',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
metric: 'network_traffic',
|
|
43
|
+
state: 'not-available',
|
|
44
|
+
attribution: 'none',
|
|
45
|
+
source: 'no-supported-per-process-proof-source-integrated',
|
|
46
|
+
exclusive_task_proof: false,
|
|
47
|
+
limitation: 'The current release does not use privileged packet inspection or unsupported per-process network APIs.',
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=resource-evidence.js.map
|
package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/runtime-activity.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ClassifiedAgentProcess } from './agents';
|
|
2
|
+
import type { ProcessEntry, RuntimeProvider } from './types';
|
|
3
|
+
export declare function loadedRuntimeSignatures(providers: RuntimeProvider[], observedAt: string): Promise<Set<string>>;
|
|
4
|
+
export declare function classifyLoadedRuntimeProcesses(processes: ProcessEntry[], loaded: Set<string>, excludedRootPid?: number | null): ClassifiedAgentProcess[];
|
|
5
|
+
//# sourceMappingURL=runtime-activity.d.ts.map
|
package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/runtime-activity.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loadedRuntimeSignatures = loadedRuntimeSignatures;
|
|
7
|
+
exports.classifyLoadedRuntimeProcesses = classifyLoadedRuntimeProcesses;
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
function basename(value) {
|
|
10
|
+
return node_path_1.default.basename(String(value || '').replaceAll('\\', '/')).toLowerCase().replace(/\.exe$/i, '');
|
|
11
|
+
}
|
|
12
|
+
async function loadedRuntimeSignatures(providers, observedAt) {
|
|
13
|
+
const loaded = new Set();
|
|
14
|
+
const results = await Promise.all(providers.map(async (provider) => {
|
|
15
|
+
try {
|
|
16
|
+
return await provider.scan(observedAt);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}));
|
|
22
|
+
for (const result of results) {
|
|
23
|
+
if (!result)
|
|
24
|
+
continue;
|
|
25
|
+
if (result.models.some((model) => model.evidence_status === 'confirmed-running'))
|
|
26
|
+
loaded.add(result.runtime.name);
|
|
27
|
+
}
|
|
28
|
+
return loaded;
|
|
29
|
+
}
|
|
30
|
+
function classifyLoadedRuntimeProcesses(processes, loaded, excludedRootPid = process.pid) {
|
|
31
|
+
const definitions = [
|
|
32
|
+
{ signature: 'runtime:ollama', runtime: 'ollama', name: 'Ollama', executables: ['ollama'] },
|
|
33
|
+
{ signature: 'runtime:lmstudio', runtime: 'lmstudio', name: 'LM Studio', executables: ['lm studio', 'lmstudio'] },
|
|
34
|
+
];
|
|
35
|
+
const excluded = new Set();
|
|
36
|
+
if (excludedRootPid !== null) {
|
|
37
|
+
excluded.add(excludedRootPid);
|
|
38
|
+
let changed = true;
|
|
39
|
+
while (changed) {
|
|
40
|
+
changed = false;
|
|
41
|
+
for (const entry of processes)
|
|
42
|
+
if (!excluded.has(entry.pid) && entry.ppid !== undefined && excluded.has(entry.ppid)) {
|
|
43
|
+
excluded.add(entry.pid);
|
|
44
|
+
changed = true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const result = [];
|
|
49
|
+
for (const entry of processes) {
|
|
50
|
+
if (excluded.has(entry.pid))
|
|
51
|
+
continue;
|
|
52
|
+
const executable = basename(entry.name || String(entry.cmd || '').split(/\s+/)[0] || '');
|
|
53
|
+
const definition = definitions.find((candidate) => loaded.has(candidate.runtime) && candidate.executables.includes(executable));
|
|
54
|
+
if (!definition)
|
|
55
|
+
continue;
|
|
56
|
+
result.push({
|
|
57
|
+
pid: entry.pid, ppid: entry.ppid ?? null, signature: definition.signature, name: definition.name,
|
|
58
|
+
kind: 'local-model-runtime', confidence: 'high', relationship: 'direct',
|
|
59
|
+
cpu_percent: Number.isFinite(entry.cpu_percent) ? Number(entry.cpu_percent) : null,
|
|
60
|
+
memory_percent: Number.isFinite(entry.memory_percent) ? Number(entry.memory_percent) : null,
|
|
61
|
+
cpu_time_ms: Number.isFinite(entry.cpu_time_ms) ? Number(entry.cpu_time_ms) : null,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=runtime-activity.js.map
|
package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/runtime-identity.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type RuntimeIdentityVerifier = (endpoint: string, expectedExecutable: string) => Promise<boolean>;
|
|
2
|
+
/**
|
|
3
|
+
* Correlates a loopback listener with an exact executable name. Only the
|
|
4
|
+
* boolean result leaves this adapter; PID and executable path stay ephemeral.
|
|
5
|
+
*/
|
|
6
|
+
export declare const verifyMacosLoopbackRuntimeIdentity: RuntimeIdentityVerifier;
|
|
7
|
+
//# sourceMappingURL=runtime-identity.d.ts.map
|