@hasna/instructions 0.4.20 → 0.4.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +275 -93
- package/dist/cli/profile-reads.test.d.ts +2 -0
- package/dist/cli/profile-reads.test.d.ts.map +1 -0
- package/dist/data/config-store.d.ts +10 -1
- package/dist/data/config-store.d.ts.map +1 -1
- package/dist/db/profiles.d.ts +4 -1
- package/dist/db/profiles.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +217 -26
- package/dist/lib/bounded-read.d.ts +7 -0
- package/dist/lib/bounded-read.d.ts.map +1 -0
- package/dist/mcp/index.js +299 -126
- package/dist/server/index.js +246 -36
- package/dist/server/openapi.d.ts +246 -20
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/profile-contract.test.d.ts +2 -0
- package/dist/server/profile-contract.test.d.ts.map +1 -0
- package/dist/server/v1.d.ts.map +1 -1
- package/dist/storage/cloud-store.d.ts +8 -1
- package/dist/storage/cloud-store.d.ts.map +1 -1
- package/dist/types/index.d.ts +24 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -2649,6 +2649,84 @@ var init_machine = __esm(() => {
|
|
|
2649
2649
|
init_template();
|
|
2650
2650
|
});
|
|
2651
2651
|
|
|
2652
|
+
// src/lib/compact-output.ts
|
|
2653
|
+
function parseLimit(value, fallback = DEFAULT_LIST_LIMIT, max = MAX_LIST_LIMIT) {
|
|
2654
|
+
const parsed = typeof value === "number" ? value : Number.parseInt(String(value ?? ""), 10);
|
|
2655
|
+
if (!Number.isFinite(parsed) || parsed <= 0)
|
|
2656
|
+
return fallback;
|
|
2657
|
+
return Math.min(Math.floor(parsed), max);
|
|
2658
|
+
}
|
|
2659
|
+
function parseCursor(value) {
|
|
2660
|
+
const parsed = typeof value === "number" ? value : Number.parseInt(String(value ?? ""), 10);
|
|
2661
|
+
if (!Number.isFinite(parsed) || parsed < 0)
|
|
2662
|
+
return 0;
|
|
2663
|
+
return Math.floor(parsed);
|
|
2664
|
+
}
|
|
2665
|
+
function paginate(items, opts = {}) {
|
|
2666
|
+
const limit = parseLimit(opts.limit, opts.defaultLimit ?? DEFAULT_LIST_LIMIT, opts.maxLimit ?? MAX_LIST_LIMIT);
|
|
2667
|
+
const cursor = parseCursor(opts.cursor);
|
|
2668
|
+
const pageItems = items.slice(cursor, cursor + limit);
|
|
2669
|
+
const nextCursor = cursor + pageItems.length < items.length ? cursor + pageItems.length : null;
|
|
2670
|
+
return {
|
|
2671
|
+
items: pageItems,
|
|
2672
|
+
total: items.length,
|
|
2673
|
+
limit,
|
|
2674
|
+
cursor,
|
|
2675
|
+
next_cursor: nextCursor,
|
|
2676
|
+
has_more: nextCursor !== null
|
|
2677
|
+
};
|
|
2678
|
+
}
|
|
2679
|
+
function truncateText(value, max = 80) {
|
|
2680
|
+
const text = (value ?? "").replace(/\s+/g, " ").trim();
|
|
2681
|
+
if (text.length <= max)
|
|
2682
|
+
return text;
|
|
2683
|
+
if (max <= 3)
|
|
2684
|
+
return text.slice(0, max);
|
|
2685
|
+
return `${text.slice(0, max - 3)}...`;
|
|
2686
|
+
}
|
|
2687
|
+
function truncateMiddle(value, max = 80) {
|
|
2688
|
+
const text = (value ?? "").replace(/\s+/g, " ").trim();
|
|
2689
|
+
if (text.length <= max)
|
|
2690
|
+
return text;
|
|
2691
|
+
if (max <= 3)
|
|
2692
|
+
return text.slice(0, max);
|
|
2693
|
+
const head = Math.ceil((max - 3) * 0.55);
|
|
2694
|
+
const tail = Math.floor((max - 3) * 0.45);
|
|
2695
|
+
return `${text.slice(0, head)}...${text.slice(text.length - tail)}`;
|
|
2696
|
+
}
|
|
2697
|
+
var DEFAULT_LIST_LIMIT = 20, MAX_LIST_LIMIT = 100;
|
|
2698
|
+
|
|
2699
|
+
// src/lib/bounded-read.ts
|
|
2700
|
+
function normalizeBoundedReadOptions(options = {}) {
|
|
2701
|
+
return {
|
|
2702
|
+
limit: parseLimit(options.limit, DEFAULT_LIST_LIMIT, MAX_LIST_LIMIT),
|
|
2703
|
+
cursor: parseCursor(options.cursor)
|
|
2704
|
+
};
|
|
2705
|
+
}
|
|
2706
|
+
function boundedReadPage(items, total, options = {}) {
|
|
2707
|
+
const { limit, cursor } = normalizeBoundedReadOptions(options);
|
|
2708
|
+
if (items.length > limit) {
|
|
2709
|
+
throw new Error(`bounded read returned ${items.length} rows for limit ${limit}`);
|
|
2710
|
+
}
|
|
2711
|
+
const consumed = cursor + items.length;
|
|
2712
|
+
const complete = consumed >= total;
|
|
2713
|
+
if (!complete && items.length === 0) {
|
|
2714
|
+
throw new Error(`bounded read did not advance at cursor ${cursor} of ${total}`);
|
|
2715
|
+
}
|
|
2716
|
+
return {
|
|
2717
|
+
items,
|
|
2718
|
+
total,
|
|
2719
|
+
limit,
|
|
2720
|
+
cursor,
|
|
2721
|
+
next_cursor: complete ? null : consumed,
|
|
2722
|
+
has_more: !complete,
|
|
2723
|
+
complete,
|
|
2724
|
+
truncated: false,
|
|
2725
|
+
source_bounded: true
|
|
2726
|
+
};
|
|
2727
|
+
}
|
|
2728
|
+
var init_bounded_read = () => {};
|
|
2729
|
+
|
|
2652
2730
|
// src/db/profiles.ts
|
|
2653
2731
|
function rowToProfile(row) {
|
|
2654
2732
|
return {
|
|
@@ -2692,9 +2770,12 @@ function getProfile(idOrSlug, db) {
|
|
|
2692
2770
|
throw new ProfileNotFoundError(idOrSlug);
|
|
2693
2771
|
return rowToProfile(row);
|
|
2694
2772
|
}
|
|
2695
|
-
function
|
|
2773
|
+
function listProfilesPage(options = {}, db) {
|
|
2696
2774
|
const d = db || getDatabase();
|
|
2697
|
-
|
|
2775
|
+
const normalized = normalizeBoundedReadOptions(options);
|
|
2776
|
+
const total = d.query("SELECT COUNT(*) AS total FROM profiles").get()?.total ?? 0;
|
|
2777
|
+
const rows = d.query("SELECT * FROM profiles ORDER BY name LIMIT ? OFFSET ?").all(normalized.limit, normalized.cursor).map(rowToProfile);
|
|
2778
|
+
return boundedReadPage(rows, total, normalized);
|
|
2698
2779
|
}
|
|
2699
2780
|
function updateProfile(idOrSlug, input, db) {
|
|
2700
2781
|
const d = db || getDatabase();
|
|
@@ -2739,14 +2820,13 @@ function removeConfigFromProfile(profileIdOrSlug, configId, db) {
|
|
|
2739
2820
|
const profile = getProfile(profileIdOrSlug, d);
|
|
2740
2821
|
d.run("DELETE FROM profile_configs WHERE profile_id = ? AND config_id = ?", [profile.id, configId]);
|
|
2741
2822
|
}
|
|
2742
|
-
function
|
|
2823
|
+
function getProfileConfigsPage(profileIdOrSlug, options = {}, db) {
|
|
2743
2824
|
const d = db || getDatabase();
|
|
2744
2825
|
const profile = getProfile(profileIdOrSlug, d);
|
|
2745
|
-
const
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
return listConfigs(undefined, d).filter((c) => ids.includes(c.id));
|
|
2826
|
+
const normalized = normalizeBoundedReadOptions(options);
|
|
2827
|
+
const total = d.query("SELECT COUNT(*) AS total FROM profile_configs WHERE profile_id = ?").get(profile.id)?.total ?? 0;
|
|
2828
|
+
const rows = d.query("SELECT config_id FROM profile_configs WHERE profile_id = ? ORDER BY sort_order LIMIT ? OFFSET ?").all(profile.id, normalized.limit, normalized.cursor);
|
|
2829
|
+
return boundedReadPage(rows.map((row) => getConfigById(row.config_id, d)), total, normalized);
|
|
2750
2830
|
}
|
|
2751
2831
|
function profileHasSelectors(profile) {
|
|
2752
2832
|
const selectors = profile.selectors ?? {};
|
|
@@ -2762,20 +2842,46 @@ function profileMatchesMachine(profile, machine) {
|
|
|
2762
2842
|
const hostnameMatches = !selectors.hostnames?.length || selectors.hostnames.some((candidate) => candidate.trim().toLowerCase() === machine.hostname.trim().toLowerCase());
|
|
2763
2843
|
return osMatches && archMatches && hostnameMatches;
|
|
2764
2844
|
}
|
|
2765
|
-
function
|
|
2766
|
-
const
|
|
2767
|
-
const
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2845
|
+
function resolveProfileForMachineRead(machine = detectMachineContext(), options = {}, db) {
|
|
2846
|
+
const d = db || getDatabase();
|
|
2847
|
+
const { limit } = normalizeBoundedReadOptions(options);
|
|
2848
|
+
let cursor = 0;
|
|
2849
|
+
let scanned = 0;
|
|
2850
|
+
let total = 0;
|
|
2851
|
+
let selected = null;
|
|
2852
|
+
while (true) {
|
|
2853
|
+
const page = listProfilesPage({ limit, cursor }, d);
|
|
2854
|
+
total = page.total;
|
|
2855
|
+
scanned += page.items.length;
|
|
2856
|
+
for (const profile of page.items) {
|
|
2857
|
+
if (!profileHasSelectors(profile) || !profileMatchesMachine(profile, machine))
|
|
2858
|
+
continue;
|
|
2859
|
+
const selectors = profile.selectors;
|
|
2860
|
+
const score = (selectors.hostnames?.length ? 100 : 0) + (selectors.os?.length ? 10 : 0) + (selectors.arch?.length ? 10 : 0);
|
|
2861
|
+
if (!selected || score > selected.score || score === selected.score && profile.name.localeCompare(selected.profile.name) < 0) {
|
|
2862
|
+
selected = { profile, score };
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2865
|
+
if (page.complete)
|
|
2866
|
+
break;
|
|
2867
|
+
cursor = page.next_cursor;
|
|
2868
|
+
}
|
|
2869
|
+
return {
|
|
2870
|
+
profile: selected?.profile ?? null,
|
|
2871
|
+
scanned,
|
|
2872
|
+
total,
|
|
2873
|
+
batch_limit: limit,
|
|
2874
|
+
source_bounded: true,
|
|
2875
|
+
complete: true,
|
|
2876
|
+
truncated: false
|
|
2877
|
+
};
|
|
2773
2878
|
}
|
|
2774
2879
|
var init_profiles = __esm(() => {
|
|
2775
2880
|
init_types();
|
|
2776
2881
|
init_database();
|
|
2777
2882
|
init_configs();
|
|
2778
2883
|
init_machine();
|
|
2884
|
+
init_bounded_read();
|
|
2779
2885
|
});
|
|
2780
2886
|
|
|
2781
2887
|
// src/db/snapshots.ts
|
|
@@ -2853,6 +2959,32 @@ var init_machines = __esm(() => {
|
|
|
2853
2959
|
|
|
2854
2960
|
// src/data/config-store.ts
|
|
2855
2961
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
2962
|
+
function parseBoundedPagePayload(value, label) {
|
|
2963
|
+
const page = value;
|
|
2964
|
+
const consumed = Number(page?.cursor) + (page?.items?.length ?? 0);
|
|
2965
|
+
const complete = Boolean(page && Number.isSafeInteger(page.total) && consumed >= Number(page.total));
|
|
2966
|
+
if (!page || !Array.isArray(page.items) || !Number.isSafeInteger(page.total) || Number(page.total) < 0 || !Number.isSafeInteger(page.limit) || Number(page.limit) < 1 || !Number.isSafeInteger(page.cursor) || Number(page.cursor) < 0 || page.items.length > Number(page.limit) || typeof page.has_more !== "boolean" || typeof page.complete !== "boolean" || page.truncated !== false || page.next_cursor !== null && !Number.isSafeInteger(page.next_cursor) || page.complete !== complete || page.has_more !== !complete || page.next_cursor !== (complete ? null : consumed)) {
|
|
2967
|
+
throw new CloudHttpError(502, `${label} returned an invalid or truncated bounded-read envelope`, value);
|
|
2968
|
+
}
|
|
2969
|
+
return {
|
|
2970
|
+
...page,
|
|
2971
|
+
source_bounded: page.source_bounded ?? true
|
|
2972
|
+
};
|
|
2973
|
+
}
|
|
2974
|
+
function parseBoundedOrLegacyPage(value, legacyItems, options, label) {
|
|
2975
|
+
if (value && typeof value === "object") {
|
|
2976
|
+
const candidate = value;
|
|
2977
|
+
if ("items" in candidate || "total" in candidate || "complete" in candidate || "truncated" in candidate || "next_cursor" in candidate) {
|
|
2978
|
+
return parseBoundedPagePayload(value, label);
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
if (!Array.isArray(legacyItems)) {
|
|
2982
|
+
throw new CloudHttpError(502, `${label} returned neither a bounded envelope nor a complete legacy array`, value);
|
|
2983
|
+
}
|
|
2984
|
+
const normalized = normalizeBoundedReadOptions(options);
|
|
2985
|
+
const page = boundedReadPage(legacyItems.slice(normalized.cursor, normalized.cursor + normalized.limit), legacyItems.length, normalized);
|
|
2986
|
+
return { ...page, source_bounded: false };
|
|
2987
|
+
}
|
|
2856
2988
|
function isCloudAuthError(err) {
|
|
2857
2989
|
return err instanceof CloudHttpError && (err.status === 401 || err.status === 403);
|
|
2858
2990
|
}
|
|
@@ -2930,13 +3062,35 @@ class LocalConfigStore {
|
|
|
2930
3062
|
return pruneSnapshots(configId, keep, this.db);
|
|
2931
3063
|
}
|
|
2932
3064
|
async listProfiles() {
|
|
2933
|
-
|
|
3065
|
+
const profiles = [];
|
|
3066
|
+
let cursor = 0;
|
|
3067
|
+
while (true) {
|
|
3068
|
+
const page = await this.listProfilesPage({ limit: 100, cursor });
|
|
3069
|
+
profiles.push(...page.items);
|
|
3070
|
+
if (page.complete)
|
|
3071
|
+
return profiles;
|
|
3072
|
+
cursor = page.next_cursor;
|
|
3073
|
+
}
|
|
3074
|
+
}
|
|
3075
|
+
async listProfilesPage(options = {}) {
|
|
3076
|
+
return listProfilesPage(options, this.db);
|
|
2934
3077
|
}
|
|
2935
3078
|
async getProfile(idOrSlug) {
|
|
2936
3079
|
return getProfile(idOrSlug, this.db);
|
|
2937
3080
|
}
|
|
2938
3081
|
async getProfileConfigs(idOrSlug) {
|
|
2939
|
-
|
|
3082
|
+
const configs = [];
|
|
3083
|
+
let cursor = 0;
|
|
3084
|
+
while (true) {
|
|
3085
|
+
const page = await this.getProfileConfigsPage(idOrSlug, { limit: 100, cursor });
|
|
3086
|
+
configs.push(...page.items);
|
|
3087
|
+
if (page.complete)
|
|
3088
|
+
return configs;
|
|
3089
|
+
cursor = page.next_cursor;
|
|
3090
|
+
}
|
|
3091
|
+
}
|
|
3092
|
+
async getProfileConfigsPage(idOrSlug, options = {}) {
|
|
3093
|
+
return getProfileConfigsPage(idOrSlug, options, this.db);
|
|
2940
3094
|
}
|
|
2941
3095
|
async createProfile(input) {
|
|
2942
3096
|
return createProfile(input, this.db);
|
|
@@ -2954,7 +3108,10 @@ class LocalConfigStore {
|
|
|
2954
3108
|
removeConfigFromProfile(profileIdOrSlug, configId, this.db);
|
|
2955
3109
|
}
|
|
2956
3110
|
async resolveProfileForMachine(machine) {
|
|
2957
|
-
return
|
|
3111
|
+
return (await this.resolveProfileForMachineRead(machine)).profile;
|
|
3112
|
+
}
|
|
3113
|
+
async resolveProfileForMachineRead(machine, options = {}) {
|
|
3114
|
+
return machine ? resolveProfileForMachineRead(machine, options, this.db) : resolveProfileForMachineRead(undefined, options, this.db);
|
|
2958
3115
|
}
|
|
2959
3116
|
async registerMachine(hostname2, os, arch2) {
|
|
2960
3117
|
return registerMachine(hostname2, os, arch2, this.db);
|
|
@@ -3095,8 +3252,24 @@ class CloudConfigStore {
|
|
|
3095
3252
|
return data?.pruned ?? 0;
|
|
3096
3253
|
}
|
|
3097
3254
|
async listProfiles() {
|
|
3098
|
-
const
|
|
3099
|
-
|
|
3255
|
+
const profiles = [];
|
|
3256
|
+
let cursor = 0;
|
|
3257
|
+
while (true) {
|
|
3258
|
+
const page = await this.listProfilesPage({ limit: 100, cursor });
|
|
3259
|
+
profiles.push(...page.items);
|
|
3260
|
+
if (page.complete)
|
|
3261
|
+
return profiles;
|
|
3262
|
+
cursor = page.next_cursor;
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
async listProfilesPage(options = {}) {
|
|
3266
|
+
const normalized = normalizeBoundedReadOptions(options);
|
|
3267
|
+
const params = new URLSearchParams;
|
|
3268
|
+
params.set("limit", String(normalized.limit));
|
|
3269
|
+
params.set("cursor", String(normalized.cursor));
|
|
3270
|
+
const qs = params.toString();
|
|
3271
|
+
const { data } = await this.request("GET", `/profiles${qs ? `?${qs}` : ""}`);
|
|
3272
|
+
return parseBoundedOrLegacyPage(data, data?.profiles, normalized, "profile list");
|
|
3100
3273
|
}
|
|
3101
3274
|
async getProfile(idOrSlug) {
|
|
3102
3275
|
const { status, data } = await this.request("GET", `/profiles/${encodeURIComponent(idOrSlug)}`, undefined, { allow404: true });
|
|
@@ -3106,10 +3279,26 @@ class CloudConfigStore {
|
|
|
3106
3279
|
return profile;
|
|
3107
3280
|
}
|
|
3108
3281
|
async getProfileConfigs(idOrSlug) {
|
|
3109
|
-
const
|
|
3282
|
+
const configs = [];
|
|
3283
|
+
let cursor = 0;
|
|
3284
|
+
while (true) {
|
|
3285
|
+
const page = await this.getProfileConfigsPage(idOrSlug, { limit: 100, cursor });
|
|
3286
|
+
configs.push(...page.items);
|
|
3287
|
+
if (page.complete)
|
|
3288
|
+
return configs;
|
|
3289
|
+
cursor = page.next_cursor;
|
|
3290
|
+
}
|
|
3291
|
+
}
|
|
3292
|
+
async getProfileConfigsPage(idOrSlug, options = {}) {
|
|
3293
|
+
const normalized = normalizeBoundedReadOptions(options);
|
|
3294
|
+
const params = new URLSearchParams;
|
|
3295
|
+
params.set("limit", String(normalized.limit));
|
|
3296
|
+
params.set("cursor", String(normalized.cursor));
|
|
3297
|
+
const qs = params.toString();
|
|
3298
|
+
const { status, data } = await this.request("GET", `/profiles/${encodeURIComponent(idOrSlug)}${qs ? `?${qs}` : ""}`, undefined, { allow404: true });
|
|
3110
3299
|
if (status === 404 || !data?.profile)
|
|
3111
3300
|
throw new ProfileNotFoundError(idOrSlug);
|
|
3112
|
-
return data.profile.configs
|
|
3301
|
+
return parseBoundedOrLegacyPage(data.configs, data.profile.configs, normalized, "profile membership");
|
|
3113
3302
|
}
|
|
3114
3303
|
async createProfile(input) {
|
|
3115
3304
|
const { data } = await this.request("POST", "/profiles", input, {
|
|
@@ -3133,6 +3322,10 @@ class CloudConfigStore {
|
|
|
3133
3322
|
await this.request("DELETE", `/profiles/${encodeURIComponent(profileIdOrSlug)}/configs/${encodeURIComponent(configId)}`, undefined, { allow404: true });
|
|
3134
3323
|
}
|
|
3135
3324
|
async resolveProfileForMachine(machine) {
|
|
3325
|
+
return (await this.resolveProfileForMachineRead(machine)).profile;
|
|
3326
|
+
}
|
|
3327
|
+
async resolveProfileForMachineRead(machine, options = {}) {
|
|
3328
|
+
const normalized = normalizeBoundedReadOptions(options);
|
|
3136
3329
|
const params = new URLSearchParams;
|
|
3137
3330
|
if (machine?.hostname)
|
|
3138
3331
|
params.set("hostname", machine.hostname);
|
|
@@ -3140,11 +3333,40 @@ class CloudConfigStore {
|
|
|
3140
3333
|
params.set("os", machine.os);
|
|
3141
3334
|
if (machine?.arch)
|
|
3142
3335
|
params.set("arch", machine.arch);
|
|
3336
|
+
params.set("limit", String(normalized.limit));
|
|
3143
3337
|
const qs = params.toString();
|
|
3144
3338
|
const { status, data } = await this.request("GET", `/profiles/resolve${qs ? `?${qs}` : ""}`, undefined, { allow404: true });
|
|
3145
|
-
if (status === 404
|
|
3146
|
-
return
|
|
3147
|
-
|
|
3339
|
+
if (status === 404) {
|
|
3340
|
+
return {
|
|
3341
|
+
profile: null,
|
|
3342
|
+
scanned: null,
|
|
3343
|
+
total: null,
|
|
3344
|
+
batch_limit: null,
|
|
3345
|
+
source_bounded: false,
|
|
3346
|
+
complete: true,
|
|
3347
|
+
truncated: false
|
|
3348
|
+
};
|
|
3349
|
+
}
|
|
3350
|
+
if (data && "complete" in data) {
|
|
3351
|
+
if (data.complete !== true || data.truncated !== false) {
|
|
3352
|
+
throw new CloudHttpError(502, "profile resolve returned an incomplete or truncated read", data);
|
|
3353
|
+
}
|
|
3354
|
+
return { ...data, source_bounded: data.source_bounded ?? true };
|
|
3355
|
+
}
|
|
3356
|
+
if (data && "profile" in data) {
|
|
3357
|
+
return {
|
|
3358
|
+
profile: data.profile,
|
|
3359
|
+
scanned: null,
|
|
3360
|
+
total: null,
|
|
3361
|
+
batch_limit: null,
|
|
3362
|
+
source_bounded: false,
|
|
3363
|
+
complete: true,
|
|
3364
|
+
truncated: false
|
|
3365
|
+
};
|
|
3366
|
+
}
|
|
3367
|
+
{
|
|
3368
|
+
throw new CloudHttpError(502, "profile resolve returned an incomplete or truncated read", data);
|
|
3369
|
+
}
|
|
3148
3370
|
}
|
|
3149
3371
|
async registerMachine(hostname2, os, arch2) {
|
|
3150
3372
|
const { data } = await this.request("POST", "/machines", { hostname: hostname2, os, arch: arch2 }, { idempotent: true });
|
|
@@ -3181,6 +3403,7 @@ var init_config_store = __esm(() => {
|
|
|
3181
3403
|
init_machines();
|
|
3182
3404
|
init_database();
|
|
3183
3405
|
init_types();
|
|
3406
|
+
init_bounded_read();
|
|
3184
3407
|
CloudHttpError = class CloudHttpError extends Error {
|
|
3185
3408
|
status;
|
|
3186
3409
|
body;
|
|
@@ -15408,56 +15631,6 @@ async function getConfigsStatus(store = resolveConfigStore()) {
|
|
|
15408
15631
|
|
|
15409
15632
|
// src/cli/index.tsx
|
|
15410
15633
|
init_config_store();
|
|
15411
|
-
|
|
15412
|
-
// src/lib/compact-output.ts
|
|
15413
|
-
var DEFAULT_LIST_LIMIT = 20;
|
|
15414
|
-
var MAX_LIST_LIMIT = 100;
|
|
15415
|
-
function parseLimit(value, fallback = DEFAULT_LIST_LIMIT, max = MAX_LIST_LIMIT) {
|
|
15416
|
-
const parsed = typeof value === "number" ? value : Number.parseInt(String(value ?? ""), 10);
|
|
15417
|
-
if (!Number.isFinite(parsed) || parsed <= 0)
|
|
15418
|
-
return fallback;
|
|
15419
|
-
return Math.min(Math.floor(parsed), max);
|
|
15420
|
-
}
|
|
15421
|
-
function parseCursor(value) {
|
|
15422
|
-
const parsed = typeof value === "number" ? value : Number.parseInt(String(value ?? ""), 10);
|
|
15423
|
-
if (!Number.isFinite(parsed) || parsed < 0)
|
|
15424
|
-
return 0;
|
|
15425
|
-
return Math.floor(parsed);
|
|
15426
|
-
}
|
|
15427
|
-
function paginate(items, opts = {}) {
|
|
15428
|
-
const limit = parseLimit(opts.limit, opts.defaultLimit ?? DEFAULT_LIST_LIMIT, opts.maxLimit ?? MAX_LIST_LIMIT);
|
|
15429
|
-
const cursor = parseCursor(opts.cursor);
|
|
15430
|
-
const pageItems = items.slice(cursor, cursor + limit);
|
|
15431
|
-
const nextCursor = cursor + pageItems.length < items.length ? cursor + pageItems.length : null;
|
|
15432
|
-
return {
|
|
15433
|
-
items: pageItems,
|
|
15434
|
-
total: items.length,
|
|
15435
|
-
limit,
|
|
15436
|
-
cursor,
|
|
15437
|
-
next_cursor: nextCursor,
|
|
15438
|
-
has_more: nextCursor !== null
|
|
15439
|
-
};
|
|
15440
|
-
}
|
|
15441
|
-
function truncateText(value, max = 80) {
|
|
15442
|
-
const text = (value ?? "").replace(/\s+/g, " ").trim();
|
|
15443
|
-
if (text.length <= max)
|
|
15444
|
-
return text;
|
|
15445
|
-
if (max <= 3)
|
|
15446
|
-
return text.slice(0, max);
|
|
15447
|
-
return `${text.slice(0, max - 3)}...`;
|
|
15448
|
-
}
|
|
15449
|
-
function truncateMiddle(value, max = 80) {
|
|
15450
|
-
const text = (value ?? "").replace(/\s+/g, " ").trim();
|
|
15451
|
-
if (text.length <= max)
|
|
15452
|
-
return text;
|
|
15453
|
-
if (max <= 3)
|
|
15454
|
-
return text.slice(0, max);
|
|
15455
|
-
const head = Math.ceil((max - 3) * 0.55);
|
|
15456
|
-
const tail = Math.floor((max - 3) * 0.45);
|
|
15457
|
-
return `${text.slice(0, head)}...${text.slice(text.length - tail)}`;
|
|
15458
|
-
}
|
|
15459
|
-
|
|
15460
|
-
// src/cli/index.tsx
|
|
15461
15634
|
import { createRequire } from "module";
|
|
15462
15635
|
var pkg = createRequire(import.meta.url)("../../package.json");
|
|
15463
15636
|
var EAGAIN_SLEEP = new Int32Array(new SharedArrayBuffer(4));
|
|
@@ -15720,10 +15893,11 @@ function formatProfileSelectorSummary(profile) {
|
|
|
15720
15893
|
function formatProfileVariables(profile) {
|
|
15721
15894
|
return Object.entries(profile.variables).map(([key, value]) => `${key}=${value}`).join(", ");
|
|
15722
15895
|
}
|
|
15723
|
-
async function getMachineProfileContext(opts, store) {
|
|
15896
|
+
async function getMachineProfileContext(opts, store, readOptions = {}) {
|
|
15724
15897
|
const machine = detectMachineContext({ hostname: opts.hostname, os: opts.os, arch: opts.arch });
|
|
15725
|
-
const
|
|
15726
|
-
|
|
15898
|
+
const resolution = await store.resolveProfileForMachineRead(machine, readOptions);
|
|
15899
|
+
const profile = resolution.profile;
|
|
15900
|
+
return { machine, profile, resolution, vars: resolveProfileVariables(profile, machine) };
|
|
15727
15901
|
}
|
|
15728
15902
|
program.command("list").alias("ls").description("List stored configs").option("-c, --category <cat>", "filter by category").option("-a, --agent <agent>", "filter by agent").option("-k, --kind <kind>", "filter by kind (file|reference)").option("-t, --tag <tag>", "filter by tag").option("-s, --search <query>", "search name/description/content").option("-f, --format <fmt>", "output format: compact|table|json", "compact").option("--brief", "shorthand for --format compact").option("--verbose", "show expanded metadata for each listed config").option("--json", "output full matching records as JSON").option("--limit <n>", `max rows for human output (default ${DEFAULT_LIST_LIMIT})`).option("--cursor <n>", "zero-based pagination cursor for human output").action(async (opts) => {
|
|
15729
15903
|
const fmt = opts.json ? "json" : opts.verbose ? "table" : opts.brief ? "compact" : opts.format;
|
|
@@ -16066,29 +16240,28 @@ program.command("whoami").description("Show setup summary").action(async () => {
|
|
|
16066
16240
|
}
|
|
16067
16241
|
});
|
|
16068
16242
|
var profileCmd = program.command("profile").description("Manage config profiles (named bundles)");
|
|
16069
|
-
profileCmd.command("list").description("List all profiles").option("--brief", "compact one-line output").option("-f, --format <fmt>", "compact|table|json", "compact").option("--verbose", "show expanded profile metadata").option("--json", "output full profiles as JSON").option("--limit <n>", `max rows
|
|
16243
|
+
profileCmd.command("list").description("List all profiles").option("--brief", "compact one-line output").option("-f, --format <fmt>", "compact|table|json", "compact").option("--verbose", "show expanded profile metadata").option("--json", "output full profiles as JSON").option("--limit <n>", `max rows requested from the source (default ${DEFAULT_LIST_LIMIT})`).option("--cursor <n>", "zero-based source pagination cursor").action(async (opts) => {
|
|
16070
16244
|
const fmt = opts.json ? "json" : opts.verbose ? "table" : opts.brief ? "compact" : opts.format;
|
|
16071
16245
|
const store = resolveConfigStore();
|
|
16072
|
-
const
|
|
16246
|
+
const page = await store.listProfilesPage({ limit: opts.limit, cursor: opts.cursor });
|
|
16073
16247
|
if (fmt === "json") {
|
|
16074
|
-
printJson(
|
|
16248
|
+
printJson(page);
|
|
16075
16249
|
return;
|
|
16076
16250
|
}
|
|
16077
|
-
if (
|
|
16251
|
+
if (page.total === 0) {
|
|
16078
16252
|
console.log(chalk.dim("No profiles."));
|
|
16079
16253
|
return;
|
|
16080
16254
|
}
|
|
16081
|
-
const page = paginate(profiles, { limit: opts.limit, cursor: opts.cursor });
|
|
16082
16255
|
if (fmt === "compact")
|
|
16083
16256
|
console.log(`${pad("slug", 28)} ${pad("configs", 8)} ${pad("match", 36)} vars`);
|
|
16084
16257
|
for (const p of page.items) {
|
|
16258
|
+
const configCount = (await store.getProfileConfigsPage(p.id, { limit: 1 })).total;
|
|
16085
16259
|
if (fmt === "compact") {
|
|
16086
16260
|
const selectorSummary2 = formatProfileSelectorSummary(p);
|
|
16087
|
-
console.log(`${pad(p.slug, 28)} ${pad(String(
|
|
16261
|
+
console.log(`${pad(p.slug, 28)} ${pad(String(configCount), 8)} ${pad(selectorSummary2 || "-", 36)} ${Object.keys(p.variables).length}`);
|
|
16088
16262
|
continue;
|
|
16089
16263
|
}
|
|
16090
|
-
|
|
16091
|
-
console.log(`${chalk.bold(p.name)} ${chalk.dim(`(${p.slug})`)} \u2014 ${configs.length} config(s)`);
|
|
16264
|
+
console.log(`${chalk.bold(p.name)} ${chalk.dim(`(${p.slug})`)} \u2014 ${configCount} config(s)`);
|
|
16092
16265
|
if (p.description)
|
|
16093
16266
|
console.log(` ${chalk.dim(p.description)}`);
|
|
16094
16267
|
const selectorSummary = formatProfileSelectorSummary(p);
|
|
@@ -16134,11 +16307,15 @@ profileCmd.command("update <id>").description("Update an existing profile's vari
|
|
|
16134
16307
|
process.exit(1);
|
|
16135
16308
|
}
|
|
16136
16309
|
});
|
|
16137
|
-
profileCmd.command("show <id>").description("Show profile and its configs").option("--limit <n>", `max config rows (default ${DEFAULT_LIST_LIMIT})`).option("--cursor <n>", "zero-based pagination cursor").action(async (id, opts) => {
|
|
16310
|
+
profileCmd.command("show <id>").description("Show profile and its configs").option("--limit <n>", `max config rows (default ${DEFAULT_LIST_LIMIT})`).option("--cursor <n>", "zero-based pagination cursor").option("--json", "output the profile and bounded membership page as JSON").action(async (id, opts) => {
|
|
16138
16311
|
try {
|
|
16139
16312
|
const store = resolveConfigStore();
|
|
16140
16313
|
const p = await store.getProfile(id);
|
|
16141
|
-
const
|
|
16314
|
+
const page = await store.getProfileConfigsPage(id, { limit: opts.limit, cursor: opts.cursor });
|
|
16315
|
+
if (opts.json) {
|
|
16316
|
+
printJson({ profile: p, configs: page });
|
|
16317
|
+
return;
|
|
16318
|
+
}
|
|
16142
16319
|
console.log(chalk.bold(p.name) + chalk.dim(` (${p.slug})`));
|
|
16143
16320
|
if (p.description)
|
|
16144
16321
|
console.log(chalk.dim(p.description));
|
|
@@ -16148,8 +16325,7 @@ profileCmd.command("show <id>").description("Show profile and its configs").opti
|
|
|
16148
16325
|
const varSummary = formatProfileVariables(p);
|
|
16149
16326
|
if (varSummary)
|
|
16150
16327
|
console.log(chalk.dim(`vars: ${varSummary}`));
|
|
16151
|
-
console.log(chalk.cyan(`${
|
|
16152
|
-
const page = paginate(configs, { limit: opts.limit, cursor: opts.cursor });
|
|
16328
|
+
console.log(chalk.cyan(`${page.total} config(s):`));
|
|
16153
16329
|
for (const c of page.items)
|
|
16154
16330
|
console.log(` ${c.slug} ${chalk.dim(`[${c.category}/${c.agent}]`)}`);
|
|
16155
16331
|
if (page.has_more) {
|
|
@@ -16226,9 +16402,15 @@ ${changed}/${results.length} changed (${selected.slug} on ${machine.hostname} ${
|
|
|
16226
16402
|
process.exit(1);
|
|
16227
16403
|
}
|
|
16228
16404
|
});
|
|
16229
|
-
profileCmd.command("resolve").description("Resolve the matching machine-aware profile").option("--hostname <hostname>", "override detected hostname").option("--os <os>", "override detected OS").option("--arch <arch>", "override detected arch").action(async (opts) => {
|
|
16405
|
+
profileCmd.command("resolve").description("Resolve the matching machine-aware profile").option("--hostname <hostname>", "override detected hostname").option("--os <os>", "override detected OS").option("--arch <arch>", "override detected arch").option("--limit <n>", `maximum profiles per source scan batch (default ${DEFAULT_LIST_LIMIT})`).option("--json", "output the complete bounded resolution read as JSON").action(async (opts) => {
|
|
16230
16406
|
const store = resolveConfigStore();
|
|
16231
|
-
const { machine, profile, vars } = await getMachineProfileContext(opts, store);
|
|
16407
|
+
const { machine, profile, resolution, vars } = await getMachineProfileContext(opts, store, { limit: opts.limit });
|
|
16408
|
+
if (opts.json) {
|
|
16409
|
+
printJson({ ...resolution, machine, vars });
|
|
16410
|
+
if (!profile)
|
|
16411
|
+
process.exitCode = 1;
|
|
16412
|
+
return;
|
|
16413
|
+
}
|
|
16232
16414
|
if (!profile) {
|
|
16233
16415
|
console.log(chalk.yellow(`No matching profile for ${machine.hostname} ${machine.os_family}/${machine.arch}`));
|
|
16234
16416
|
process.exit(1);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-reads.test.d.ts","sourceRoot":"","sources":["../../src/cli/profile-reads.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Database } from "bun:sqlite";
|
|
2
2
|
import { type FeedbackInput } from "../db/database.js";
|
|
3
|
-
import type { Config, ConfigFilter, ConfigSnapshot, CreateConfigInput, CreateProfileInput, Machine, MachineContext, Profile, UpdateConfigInput, UpdateProfileInput } from "../types/index.js";
|
|
3
|
+
import type { Config, ConfigFilter, ConfigSnapshot, CreateConfigInput, CreateProfileInput, Machine, MachineContext, Profile, BoundedReadOptions, BoundedReadPage, ProfileResolutionRead, UpdateConfigInput, UpdateProfileInput } from "../types/index.js";
|
|
4
4
|
export interface CloudConfig {
|
|
5
5
|
apiUrl: string;
|
|
6
6
|
apiKey: string;
|
|
@@ -52,14 +52,17 @@ export interface ConfigStore {
|
|
|
52
52
|
createSnapshot(configId: string, content: string, version: number): Promise<ConfigSnapshot>;
|
|
53
53
|
pruneSnapshots(configId: string, keep?: number): Promise<number>;
|
|
54
54
|
listProfiles(): Promise<Profile[]>;
|
|
55
|
+
listProfilesPage(options?: BoundedReadOptions): Promise<BoundedReadPage<Profile>>;
|
|
55
56
|
getProfile(idOrSlug: string): Promise<Profile>;
|
|
56
57
|
getProfileConfigs(idOrSlug: string): Promise<Config[]>;
|
|
58
|
+
getProfileConfigsPage(idOrSlug: string, options?: BoundedReadOptions): Promise<BoundedReadPage<Config>>;
|
|
57
59
|
createProfile(input: CreateProfileInput): Promise<Profile>;
|
|
58
60
|
updateProfile(idOrSlug: string, input: UpdateProfileInput): Promise<Profile>;
|
|
59
61
|
deleteProfile(idOrSlug: string): Promise<void>;
|
|
60
62
|
addConfigToProfile(profileIdOrSlug: string, configId: string): Promise<void>;
|
|
61
63
|
removeConfigFromProfile(profileIdOrSlug: string, configId: string): Promise<void>;
|
|
62
64
|
resolveProfileForMachine(machine?: MachineContext): Promise<Profile | null>;
|
|
65
|
+
resolveProfileForMachineRead(machine?: MachineContext, options?: BoundedReadOptions): Promise<ProfileResolutionRead>;
|
|
63
66
|
registerMachine(hostname?: string, os?: string, arch?: string): Promise<Machine>;
|
|
64
67
|
updateMachineApplied(hostname?: string): Promise<void>;
|
|
65
68
|
listMachines(): Promise<Machine[]>;
|
|
@@ -93,14 +96,17 @@ export declare class LocalConfigStore implements ConfigStore {
|
|
|
93
96
|
createSnapshot(configId: string, content: string, version: number): Promise<ConfigSnapshot>;
|
|
94
97
|
pruneSnapshots(configId: string, keep?: number): Promise<number>;
|
|
95
98
|
listProfiles(): Promise<Profile[]>;
|
|
99
|
+
listProfilesPage(options?: BoundedReadOptions): Promise<BoundedReadPage<Profile>>;
|
|
96
100
|
getProfile(idOrSlug: string): Promise<Profile>;
|
|
97
101
|
getProfileConfigs(idOrSlug: string): Promise<Config[]>;
|
|
102
|
+
getProfileConfigsPage(idOrSlug: string, options?: BoundedReadOptions): Promise<BoundedReadPage<Config>>;
|
|
98
103
|
createProfile(input: CreateProfileInput): Promise<Profile>;
|
|
99
104
|
updateProfile(idOrSlug: string, input: UpdateProfileInput): Promise<Profile>;
|
|
100
105
|
deleteProfile(idOrSlug: string): Promise<void>;
|
|
101
106
|
addConfigToProfile(profileIdOrSlug: string, configId: string): Promise<void>;
|
|
102
107
|
removeConfigFromProfile(profileIdOrSlug: string, configId: string): Promise<void>;
|
|
103
108
|
resolveProfileForMachine(machine?: MachineContext): Promise<Profile | null>;
|
|
109
|
+
resolveProfileForMachineRead(machine?: MachineContext, options?: BoundedReadOptions): Promise<ProfileResolutionRead>;
|
|
104
110
|
registerMachine(hostname?: string, os?: string, arch?: string): Promise<Machine>;
|
|
105
111
|
updateMachineApplied(hostname?: string): Promise<void>;
|
|
106
112
|
listMachines(): Promise<Machine[]>;
|
|
@@ -128,14 +134,17 @@ export declare class CloudConfigStore implements ConfigStore {
|
|
|
128
134
|
createSnapshot(configId: string, content: string, version: number): Promise<ConfigSnapshot>;
|
|
129
135
|
pruneSnapshots(configId: string, keep?: number): Promise<number>;
|
|
130
136
|
listProfiles(): Promise<Profile[]>;
|
|
137
|
+
listProfilesPage(options?: BoundedReadOptions): Promise<BoundedReadPage<Profile>>;
|
|
131
138
|
getProfile(idOrSlug: string): Promise<Profile>;
|
|
132
139
|
getProfileConfigs(idOrSlug: string): Promise<Config[]>;
|
|
140
|
+
getProfileConfigsPage(idOrSlug: string, options?: BoundedReadOptions): Promise<BoundedReadPage<Config>>;
|
|
133
141
|
createProfile(input: CreateProfileInput): Promise<Profile>;
|
|
134
142
|
updateProfile(idOrSlug: string, input: UpdateProfileInput): Promise<Profile>;
|
|
135
143
|
deleteProfile(idOrSlug: string): Promise<void>;
|
|
136
144
|
addConfigToProfile(profileIdOrSlug: string, configId: string): Promise<void>;
|
|
137
145
|
removeConfigFromProfile(profileIdOrSlug: string, configId: string): Promise<void>;
|
|
138
146
|
resolveProfileForMachine(machine?: MachineContext): Promise<Profile | null>;
|
|
147
|
+
resolveProfileForMachineRead(machine?: MachineContext, options?: BoundedReadOptions): Promise<ProfileResolutionRead>;
|
|
139
148
|
registerMachine(hostname?: string, os?: string, arch?: string): Promise<Machine>;
|
|
140
149
|
updateMachineApplied(hostname?: string): Promise<void>;
|
|
141
150
|
listMachines(): Promise<Machine[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-store.d.ts","sourceRoot":"","sources":["../../src/data/config-store.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAiC3C,OAAO,EAAkF,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvI,OAAO,KAAK,EACV,MAAM,EACN,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,OAAO,EACP,cAAc,EACd,OAAO,EACP,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"config-store.d.ts","sourceRoot":"","sources":["../../src/data/config-store.ts"],"names":[],"mappings":"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"}
|
package/dist/db/profiles.d.ts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import type { Database } from "bun:sqlite";
|
|
2
|
-
import type { Config, CreateProfileInput, Profile, UpdateProfileInput, MachineContext } from "../types/index.js";
|
|
2
|
+
import type { Config, CreateProfileInput, Profile, UpdateProfileInput, MachineContext, BoundedReadOptions, BoundedReadPage, ProfileResolutionRead } from "../types/index.js";
|
|
3
3
|
export declare function createProfile(input: CreateProfileInput, db?: Database): Profile;
|
|
4
4
|
export declare function getProfile(idOrSlug: string, db?: Database): Profile;
|
|
5
5
|
export declare function listProfiles(db?: Database): Profile[];
|
|
6
|
+
export declare function listProfilesPage(options?: BoundedReadOptions, db?: Database): BoundedReadPage<Profile>;
|
|
6
7
|
export declare function updateProfile(idOrSlug: string, input: UpdateProfileInput, db?: Database): Profile;
|
|
7
8
|
export declare function deleteProfile(idOrSlug: string, db?: Database): void;
|
|
8
9
|
export declare function addConfigToProfile(profileIdOrSlug: string, configId: string, db?: Database): void;
|
|
9
10
|
export declare function removeConfigFromProfile(profileIdOrSlug: string, configId: string, db?: Database): void;
|
|
10
11
|
export declare function getProfileConfigs(profileIdOrSlug: string, db?: Database): Config[];
|
|
12
|
+
export declare function getProfileConfigsPage(profileIdOrSlug: string, options?: BoundedReadOptions, db?: Database): BoundedReadPage<Config>;
|
|
11
13
|
export declare function profileHasSelectors(profile: Pick<Profile, "selectors">): boolean;
|
|
12
14
|
export declare function profileMatchesMachine(profile: Pick<Profile, "selectors">, machine: Pick<MachineContext, "hostname" | "os" | "arch" | "os_family">): boolean;
|
|
13
15
|
export declare function resolveProfileForMachine(machine?: MachineContext, db?: Database): Profile | null;
|
|
16
|
+
export declare function resolveProfileForMachineRead(machine?: MachineContext, options?: BoundedReadOptions, db?: Database): ProfileResolutionRead;
|
|
14
17
|
//# sourceMappingURL=profiles.d.ts.map
|