@pulsemcp/air-sdk 0.0.39 → 0.0.41
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/auto-discovery.d.ts +54 -0
- package/dist/auto-discovery.d.ts.map +1 -0
- package/dist/auto-discovery.js +99 -0
- package/dist/auto-discovery.js.map +1 -0
- package/dist/discover-indexes.d.ts +72 -0
- package/dist/discover-indexes.d.ts.map +1 -0
- package/dist/discover-indexes.js +309 -0
- package/dist/discover-indexes.js.map +1 -0
- package/dist/edit-air-json.d.ts +62 -0
- package/dist/edit-air-json.d.ts.map +1 -0
- package/dist/edit-air-json.js +227 -0
- package/dist/edit-air-json.js.map +1 -0
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/preferences.d.ts +31 -0
- package/dist/preferences.d.ts.map +1 -0
- package/dist/preferences.js +0 -0
- package/dist/preferences.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type DiscoveryResult, type DiscoveredCatalog, type DiscoveredLooseIndex, type DiscoveredAirJson } from "./discover-indexes.js";
|
|
2
|
+
import { type EditAirJsonResult } from "./edit-air-json.js";
|
|
3
|
+
export interface FindOfferableOptions {
|
|
4
|
+
/** Working directory to anchor discovery. Defaults to process.cwd(). */
|
|
5
|
+
cwd?: string;
|
|
6
|
+
/** Path to air.json. Defaults to AIR_CONFIG env or ~/.air/air.json. */
|
|
7
|
+
configPath?: string;
|
|
8
|
+
/** Override preferences path (for testing). */
|
|
9
|
+
preferencesPath?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface OfferableDiscoveryResult {
|
|
12
|
+
/** The raw result from `discoverIndexes`. */
|
|
13
|
+
raw: DiscoveryResult;
|
|
14
|
+
/** Catalogs not yet in air.json and not dismissed. */
|
|
15
|
+
catalogs: DiscoveredCatalog[];
|
|
16
|
+
/** Loose indexes not yet in air.json and not dismissed. */
|
|
17
|
+
looseIndexes: DiscoveredLooseIndex[];
|
|
18
|
+
/** Nested air.json files not yet in air.json and not dismissed. */
|
|
19
|
+
airJsons: DiscoveredAirJson[];
|
|
20
|
+
/** True if there is anything to offer the user. */
|
|
21
|
+
hasOffers: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Resolved absolute path to the air.json we'll target on accept. Honors
|
|
24
|
+
* `options.configPath`, then `AIR_CONFIG`, then `~/.air/air.json`. Unlike
|
|
25
|
+
* `getAirJsonPath()`, this is populated even when the file does not yet
|
|
26
|
+
* exist so accept-flow scaffolding writes to the right location.
|
|
27
|
+
*/
|
|
28
|
+
resolvedConfigPath: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Run discovery, drop anything already in `~/.air/air.json`, drop anything
|
|
32
|
+
* the user has asked AIR not to offer again. The caller decides what to do
|
|
33
|
+
* with the survivors (prompt, auto-accept, etc.).
|
|
34
|
+
*/
|
|
35
|
+
export declare function findOfferableIndexes(options?: FindOfferableOptions): OfferableDiscoveryResult;
|
|
36
|
+
export interface AcceptDiscoveryOptions {
|
|
37
|
+
/** Override the air.json path. */
|
|
38
|
+
configPath?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Accept all offers by writing them into air.json.
|
|
42
|
+
*/
|
|
43
|
+
export declare function acceptOffers(offers: OfferableDiscoveryResult, options?: AcceptDiscoveryOptions): EditAirJsonResult;
|
|
44
|
+
export interface DismissDiscoveryOptions {
|
|
45
|
+
/** Override the preferences path (for testing). */
|
|
46
|
+
preferencesPath?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Mark every current offer as dismissed so it is never surfaced again.
|
|
50
|
+
* Uses (repoRoot=anchor, indexPath=relative) granularity — new files added
|
|
51
|
+
* later still get offered.
|
|
52
|
+
*/
|
|
53
|
+
export declare function dismissOffers(offers: OfferableDiscoveryResult, options?: DismissDiscoveryOptions): void;
|
|
54
|
+
//# sourceMappingURL=auto-discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-discovery.d.ts","sourceRoot":"","sources":["../src/auto-discovery.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACvB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,oBAAoB;IACnC,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,wBAAwB;IACvC,6CAA6C;IAC7C,GAAG,EAAE,eAAe,CAAC;IACrB,sDAAsD;IACtD,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,2DAA2D;IAC3D,YAAY,EAAE,oBAAoB,EAAE,CAAC;IACrC,mEAAmE;IACnE,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,mDAAmD;IACnD,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAYD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,wBAAwB,CA4C1B;AAED,MAAM,WAAW,sBAAsB;IACrC,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,wBAAwB,EAChC,OAAO,CAAC,EAAE,sBAAsB,GAC/B,iBAAiB,CAanB;AAED,MAAM,WAAW,uBAAuB;IACtC,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,wBAAwB,EAChC,OAAO,CAAC,EAAE,uBAAuB,GAChC,IAAI,CAcN"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { resolve } from "path";
|
|
2
|
+
import { getDefaultAirJsonPath } from "@pulsemcp/air-core";
|
|
3
|
+
import { discoverIndexes, } from "./discover-indexes.js";
|
|
4
|
+
import { loadPreferences, isDismissed, addDismissed, } from "./preferences.js";
|
|
5
|
+
import { addDiscoveredToAirJson, buildRegisteredChecker, } from "./edit-air-json.js";
|
|
6
|
+
/**
|
|
7
|
+
* Resolve the target air.json path consistently across discovery and accept.
|
|
8
|
+
* `getAirJsonPath()` returns null for missing files, which loses the user's
|
|
9
|
+
* `AIR_CONFIG` preference on a first-time scaffold — so we do our own
|
|
10
|
+
* resolution that always returns a real path.
|
|
11
|
+
*/
|
|
12
|
+
function resolveTargetConfigPath(explicit) {
|
|
13
|
+
return explicit ?? process.env.AIR_CONFIG ?? getDefaultAirJsonPath();
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Run discovery, drop anything already in `~/.air/air.json`, drop anything
|
|
17
|
+
* the user has asked AIR not to offer again. The caller decides what to do
|
|
18
|
+
* with the survivors (prompt, auto-accept, etc.).
|
|
19
|
+
*/
|
|
20
|
+
export function findOfferableIndexes(options) {
|
|
21
|
+
const cwd = options?.cwd ?? process.cwd();
|
|
22
|
+
const resolvedConfigPath = resolveTargetConfigPath(options?.configPath);
|
|
23
|
+
const raw = discoverIndexes(cwd);
|
|
24
|
+
// buildRegisteredChecker tolerates a missing file (returns no-op), so we
|
|
25
|
+
// can pass the resolved path even if the air.json doesn't exist yet.
|
|
26
|
+
const registered = buildRegisteredChecker(resolvedConfigPath);
|
|
27
|
+
const prefs = loadPreferences(options?.preferencesPath);
|
|
28
|
+
const asDismissed = (indexPath) => ({
|
|
29
|
+
repoRoot: raw.anchor,
|
|
30
|
+
indexPath,
|
|
31
|
+
});
|
|
32
|
+
const catalogs = raw.catalogs.filter((c) => {
|
|
33
|
+
if (registered.catalog(c.path))
|
|
34
|
+
return false;
|
|
35
|
+
if (isDismissed(prefs, asDismissed(c.relPath)))
|
|
36
|
+
return false;
|
|
37
|
+
return true;
|
|
38
|
+
});
|
|
39
|
+
const looseIndexes = raw.looseIndexes.filter((l) => {
|
|
40
|
+
if (registered.loose(l.type, l.path))
|
|
41
|
+
return false;
|
|
42
|
+
if (isDismissed(prefs, asDismissed(l.relPath)))
|
|
43
|
+
return false;
|
|
44
|
+
return true;
|
|
45
|
+
});
|
|
46
|
+
const airJsons = raw.airJsons.filter((a) => {
|
|
47
|
+
if (registered.airJson(a.path))
|
|
48
|
+
return false;
|
|
49
|
+
if (isDismissed(prefs, asDismissed(a.relPath)))
|
|
50
|
+
return false;
|
|
51
|
+
return true;
|
|
52
|
+
});
|
|
53
|
+
return {
|
|
54
|
+
raw,
|
|
55
|
+
catalogs,
|
|
56
|
+
looseIndexes,
|
|
57
|
+
airJsons,
|
|
58
|
+
hasOffers: catalogs.length > 0 ||
|
|
59
|
+
looseIndexes.length > 0 ||
|
|
60
|
+
airJsons.length > 0,
|
|
61
|
+
resolvedConfigPath,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Accept all offers by writing them into air.json.
|
|
66
|
+
*/
|
|
67
|
+
export function acceptOffers(offers, options) {
|
|
68
|
+
// An explicit override wins; otherwise use the path the discovery already
|
|
69
|
+
// resolved. This preserves AIR_CONFIG even when the file didn't exist at
|
|
70
|
+
// discovery time and is about to be scaffolded.
|
|
71
|
+
const configPath = options?.configPath ?? offers.resolvedConfigPath;
|
|
72
|
+
return addDiscoveredToAirJson({
|
|
73
|
+
catalogs: offers.catalogs,
|
|
74
|
+
looseIndexes: offers.looseIndexes,
|
|
75
|
+
airJsons: offers.airJsons,
|
|
76
|
+
}, { path: configPath });
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Mark every current offer as dismissed so it is never surfaced again.
|
|
80
|
+
* Uses (repoRoot=anchor, indexPath=relative) granularity — new files added
|
|
81
|
+
* later still get offered.
|
|
82
|
+
*/
|
|
83
|
+
export function dismissOffers(offers, options) {
|
|
84
|
+
const { anchor } = offers.raw;
|
|
85
|
+
const entries = [];
|
|
86
|
+
for (const c of offers.catalogs) {
|
|
87
|
+
entries.push({ repoRoot: resolve(anchor), indexPath: c.relPath });
|
|
88
|
+
}
|
|
89
|
+
for (const l of offers.looseIndexes) {
|
|
90
|
+
entries.push({ repoRoot: resolve(anchor), indexPath: l.relPath });
|
|
91
|
+
}
|
|
92
|
+
for (const a of offers.airJsons) {
|
|
93
|
+
entries.push({ repoRoot: resolve(anchor), indexPath: a.relPath });
|
|
94
|
+
}
|
|
95
|
+
if (entries.length === 0)
|
|
96
|
+
return;
|
|
97
|
+
addDismissed(entries, options?.preferencesPath);
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=auto-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-discovery.js","sourceRoot":"","sources":["../src/auto-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** Artifact-index types that map to a catalog layout directory. */
|
|
2
|
+
declare const CATALOG_TYPES: readonly ["skills", "references", "mcp", "plugins", "roots", "hooks"];
|
|
3
|
+
type CatalogType = (typeof CATALOG_TYPES)[number];
|
|
4
|
+
export interface DiscoveredCatalog {
|
|
5
|
+
/** Absolute path to the catalog directory. */
|
|
6
|
+
path: string;
|
|
7
|
+
/** Path relative to the discovery anchor. */
|
|
8
|
+
relPath: string;
|
|
9
|
+
/** Artifact types found under the catalog that match the `<type>/<type>.json` layout. */
|
|
10
|
+
types: CatalogType[];
|
|
11
|
+
/** Count of entries per discovered type, for prompt summaries. */
|
|
12
|
+
entryCounts: Partial<Record<CatalogType, number>>;
|
|
13
|
+
}
|
|
14
|
+
export interface DiscoveredLooseIndex {
|
|
15
|
+
/** Artifact type inferred from the filename and/or `$schema`. */
|
|
16
|
+
type: CatalogType;
|
|
17
|
+
/** Absolute path to the index file. */
|
|
18
|
+
path: string;
|
|
19
|
+
/** Path relative to the discovery anchor. */
|
|
20
|
+
relPath: string;
|
|
21
|
+
/** Count of top-level entries in the index (excluding `$schema`). */
|
|
22
|
+
entryCount: number;
|
|
23
|
+
}
|
|
24
|
+
export interface DiscoveredAirJson {
|
|
25
|
+
/** Absolute path to the air.json file. */
|
|
26
|
+
path: string;
|
|
27
|
+
/** Path relative to the discovery anchor. */
|
|
28
|
+
relPath: string;
|
|
29
|
+
}
|
|
30
|
+
export interface DiscoveryResult {
|
|
31
|
+
/** Absolute path to the directory discovery was anchored at (git root or fallback). */
|
|
32
|
+
anchor: string;
|
|
33
|
+
/** Whether the anchor was determined via `git rev-parse` (true) or a cwd fallback (false). */
|
|
34
|
+
anchorIsGitRoot: boolean;
|
|
35
|
+
/** Catalog directories — `<anchor>/<type>/<type>.json` layouts. */
|
|
36
|
+
catalogs: DiscoveredCatalog[];
|
|
37
|
+
/** Bare artifact index files that are not part of a full catalog layout. */
|
|
38
|
+
looseIndexes: DiscoveredLooseIndex[];
|
|
39
|
+
/** Nested `air.json` files. */
|
|
40
|
+
airJsons: DiscoveredAirJson[];
|
|
41
|
+
}
|
|
42
|
+
export interface DiscoverIndexesOptions {
|
|
43
|
+
/** Maximum walk depth below the anchor. Default: 3. */
|
|
44
|
+
maxDepth?: number;
|
|
45
|
+
/** Override the skiplist. Default: common build/output dirs + node_modules/.git. */
|
|
46
|
+
skipDirs?: Set<string>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Resolve the discovery anchor for a target directory.
|
|
50
|
+
* Returns the git root when inside a repo, otherwise the target itself.
|
|
51
|
+
*/
|
|
52
|
+
export declare function resolveAnchor(targetDir: string): {
|
|
53
|
+
anchor: string;
|
|
54
|
+
isGitRoot: boolean;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Discover AIR index files and `air.json` configs under `targetDir`.
|
|
58
|
+
*
|
|
59
|
+
* Anchor is the enclosing git root (via `git rev-parse --show-toplevel`)
|
|
60
|
+
* if one exists, else `targetDir` itself. Walks up to `maxDepth` levels
|
|
61
|
+
* deep, skipping `node_modules/`, `.git/`, build output dirs, and anything
|
|
62
|
+
* starting with `.`. Every candidate file is validated via filename-based
|
|
63
|
+
* schema detection plus optional `$schema` cross-check; unparseable or
|
|
64
|
+
* non-AIR JSON files are silently skipped.
|
|
65
|
+
*
|
|
66
|
+
* Files found via a catalog layout are excluded from `looseIndexes` — the
|
|
67
|
+
* catalog entry already covers them.
|
|
68
|
+
*/
|
|
69
|
+
export declare function discoverIndexes(targetDir: string, options?: DiscoverIndexesOptions): DiscoveryResult;
|
|
70
|
+
export type { CatalogType };
|
|
71
|
+
export { CATALOG_TYPES };
|
|
72
|
+
//# sourceMappingURL=discover-indexes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover-indexes.d.ts","sourceRoot":"","sources":["../src/discover-indexes.ts"],"names":[],"mappings":"AASA,mEAAmE;AACnE,QAAA,MAAM,aAAa,uEAOuC,CAAC;AAE3D,KAAK,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAkBlD,MAAM,WAAW,iBAAiB;IAChC,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,yFAAyF;IACzF,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,kEAAkE;IAClE,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,oBAAoB;IACnC,iEAAiE;IACjE,IAAI,EAAE,WAAW,CAAC;IAClB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,uFAAuF;IACvF,MAAM,EAAE,MAAM,CAAC;IACf,8FAA8F;IAC9F,eAAe,EAAE,OAAO,CAAC;IACzB,mEAAmE;IACnE,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,4EAA4E;IAC5E,YAAY,EAAE,oBAAoB,EAAE,CAAC;IACrC,+BAA+B;IAC/B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACrC,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;CACpB,CAcA;AAqLD;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,eAAe,CAmEjB;AAED,YAAY,EAAE,WAAW,EAAE,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { execFileSync } from "child_process";
|
|
2
|
+
import { readFileSync, readdirSync, existsSync } from "fs";
|
|
3
|
+
import { resolve, relative, sep, basename } from "path";
|
|
4
|
+
import { detectSchemaType, detectSchemaFromValue, } from "@pulsemcp/air-core";
|
|
5
|
+
/** Artifact-index types that map to a catalog layout directory. */
|
|
6
|
+
const CATALOG_TYPES = [
|
|
7
|
+
"skills",
|
|
8
|
+
"references",
|
|
9
|
+
"mcp",
|
|
10
|
+
"plugins",
|
|
11
|
+
"roots",
|
|
12
|
+
"hooks",
|
|
13
|
+
];
|
|
14
|
+
/** Directories never descended into during discovery. */
|
|
15
|
+
const SKIP_DIRS = new Set([
|
|
16
|
+
"node_modules",
|
|
17
|
+
".git",
|
|
18
|
+
"dist",
|
|
19
|
+
"build",
|
|
20
|
+
"coverage",
|
|
21
|
+
".next",
|
|
22
|
+
".turbo",
|
|
23
|
+
"target",
|
|
24
|
+
"vendor",
|
|
25
|
+
]);
|
|
26
|
+
/** Maximum directory depth walked under the anchor (anchor itself is depth 0). */
|
|
27
|
+
const MAX_DEPTH = 3;
|
|
28
|
+
/**
|
|
29
|
+
* Resolve the discovery anchor for a target directory.
|
|
30
|
+
* Returns the git root when inside a repo, otherwise the target itself.
|
|
31
|
+
*/
|
|
32
|
+
export function resolveAnchor(targetDir) {
|
|
33
|
+
try {
|
|
34
|
+
const root = execFileSync("git", ["rev-parse", "--show-toplevel"], {
|
|
35
|
+
cwd: targetDir,
|
|
36
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
37
|
+
encoding: "utf-8",
|
|
38
|
+
}).trim();
|
|
39
|
+
if (root) {
|
|
40
|
+
return { anchor: resolve(root), isGitRoot: true };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Not a git repo or git not installed — fall through.
|
|
45
|
+
}
|
|
46
|
+
return { anchor: resolve(targetDir), isGitRoot: false };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Read a JSON file and verify it is (a) parseable, (b) an object, and
|
|
50
|
+
* (c) plausibly an AIR artifact index of the expected type.
|
|
51
|
+
*
|
|
52
|
+
* Validation rules:
|
|
53
|
+
* - The file must parse as a JSON object (not array/primitive/null).
|
|
54
|
+
* - A missing `$schema` is allowed — filename-based detection is sufficient.
|
|
55
|
+
* - When `$schema` is present, it must resolve to the expected artifact type;
|
|
56
|
+
* a contradictory or non-AIR schema causes the file to be skipped.
|
|
57
|
+
*
|
|
58
|
+
* Returns the parsed data when valid, or `null` to signal "skip this file".
|
|
59
|
+
*/
|
|
60
|
+
function readAndValidateIndex(filePath, expectedType) {
|
|
61
|
+
let content;
|
|
62
|
+
try {
|
|
63
|
+
content = readFileSync(filePath, "utf-8");
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
let data;
|
|
69
|
+
try {
|
|
70
|
+
data = JSON.parse(content);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
if (typeof data !== "object" ||
|
|
76
|
+
data === null ||
|
|
77
|
+
Array.isArray(data)) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
const obj = data;
|
|
81
|
+
if (typeof obj.$schema === "string") {
|
|
82
|
+
const schemaType = detectSchemaFromValue(obj.$schema);
|
|
83
|
+
if (schemaType === null)
|
|
84
|
+
return null;
|
|
85
|
+
if (schemaType !== expectedType)
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
return obj;
|
|
89
|
+
}
|
|
90
|
+
/** Count top-level artifact entries in a validated index (excludes `$schema`). */
|
|
91
|
+
function countEntries(data) {
|
|
92
|
+
let count = 0;
|
|
93
|
+
for (const key of Object.keys(data)) {
|
|
94
|
+
if (key === "$schema")
|
|
95
|
+
continue;
|
|
96
|
+
count++;
|
|
97
|
+
}
|
|
98
|
+
return count;
|
|
99
|
+
}
|
|
100
|
+
function readAirJson(filePath) {
|
|
101
|
+
let content;
|
|
102
|
+
try {
|
|
103
|
+
content = readFileSync(filePath, "utf-8");
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
let data;
|
|
109
|
+
try {
|
|
110
|
+
data = JSON.parse(content);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
if (typeof data !== "object" || data === null || Array.isArray(data)) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
const obj = data;
|
|
119
|
+
if (typeof obj.name !== "string")
|
|
120
|
+
return false;
|
|
121
|
+
if (typeof obj.$schema === "string") {
|
|
122
|
+
const schemaType = detectSchemaFromValue(obj.$schema);
|
|
123
|
+
if (schemaType !== null && schemaType !== "air")
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Walk `anchor` up to `maxDepth` levels, yielding all files that might be
|
|
130
|
+
* AIR index candidates. Skips hidden directories and the configured skiplist.
|
|
131
|
+
* Hidden files (e.g. `.somefile.json`) are skipped. `.claude/skills/` is
|
|
132
|
+
* intentionally NOT scanned — local `.claude/` skills are adapter-owned and
|
|
133
|
+
* not managed through AIR discovery.
|
|
134
|
+
*/
|
|
135
|
+
function* walkJsonFiles(anchor, maxDepth, skipDirs) {
|
|
136
|
+
function* recurse(dir, depth) {
|
|
137
|
+
let entries;
|
|
138
|
+
try {
|
|
139
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
for (const entry of entries) {
|
|
145
|
+
const name = entry.name;
|
|
146
|
+
if (name.startsWith("."))
|
|
147
|
+
continue;
|
|
148
|
+
const full = resolve(dir, name);
|
|
149
|
+
if (entry.isDirectory()) {
|
|
150
|
+
if (skipDirs.has(name))
|
|
151
|
+
continue;
|
|
152
|
+
if (depth + 1 > maxDepth)
|
|
153
|
+
continue;
|
|
154
|
+
yield* recurse(full, depth + 1);
|
|
155
|
+
}
|
|
156
|
+
else if (entry.isFile()) {
|
|
157
|
+
if (name.endsWith(".json")) {
|
|
158
|
+
yield full;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
yield* recurse(anchor, 0);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Find catalog layouts under the anchor.
|
|
167
|
+
*
|
|
168
|
+
* A catalog is a directory D such that `D/<type>/<type>.json` exists for at
|
|
169
|
+
* least one of the six artifact types. The catalog's position is D itself
|
|
170
|
+
* (so `air.json`'s `catalogs[]` receives a single entry for D, not six
|
|
171
|
+
* per-type paths).
|
|
172
|
+
*
|
|
173
|
+
* Catalog detection is conservative — `D/skills/skills.json` must look like
|
|
174
|
+
* a valid AIR skills index (parseable JSON object with a matching `$schema`
|
|
175
|
+
* if declared) before D is considered a catalog.
|
|
176
|
+
*/
|
|
177
|
+
function findCatalogs(anchor) {
|
|
178
|
+
// Map of catalog absolute path → set of types detected under it.
|
|
179
|
+
const catalogs = new Map();
|
|
180
|
+
function tryCatalogAt(dirPath) {
|
|
181
|
+
if (catalogs.has(dirPath))
|
|
182
|
+
return;
|
|
183
|
+
const entryCounts = {};
|
|
184
|
+
const types = [];
|
|
185
|
+
for (const type of CATALOG_TYPES) {
|
|
186
|
+
const candidate = resolve(dirPath, type, `${type}.json`);
|
|
187
|
+
if (!existsSync(candidate))
|
|
188
|
+
continue;
|
|
189
|
+
const data = readAndValidateIndex(candidate, type);
|
|
190
|
+
if (!data)
|
|
191
|
+
continue;
|
|
192
|
+
types.push(type);
|
|
193
|
+
entryCounts[type] = countEntries(data);
|
|
194
|
+
}
|
|
195
|
+
if (types.length === 0)
|
|
196
|
+
return;
|
|
197
|
+
catalogs.set(dirPath, {
|
|
198
|
+
path: dirPath,
|
|
199
|
+
relPath: relative(anchor, dirPath) || ".",
|
|
200
|
+
types,
|
|
201
|
+
entryCounts,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
// The anchor itself is always a candidate root.
|
|
205
|
+
tryCatalogAt(anchor);
|
|
206
|
+
// Also scan subdirectories one level deep — this catches layouts where the
|
|
207
|
+
// catalog lives under e.g. `config/` or `air/` rather than at the repo root.
|
|
208
|
+
let entries;
|
|
209
|
+
try {
|
|
210
|
+
entries = readdirSync(anchor, { withFileTypes: true });
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
return [...catalogs.values()];
|
|
214
|
+
}
|
|
215
|
+
for (const entry of entries) {
|
|
216
|
+
if (!entry.isDirectory())
|
|
217
|
+
continue;
|
|
218
|
+
const name = entry.name;
|
|
219
|
+
if (name.startsWith("."))
|
|
220
|
+
continue;
|
|
221
|
+
if (SKIP_DIRS.has(name))
|
|
222
|
+
continue;
|
|
223
|
+
// Per-type directories like `skills/` are themselves part of a catalog
|
|
224
|
+
// *rooted at the anchor*, not a catalog on their own. They don't
|
|
225
|
+
// contain `<type>/<type>.json` layouts inside themselves anyway, so
|
|
226
|
+
// `tryCatalogAt` will quietly return. No special-case needed.
|
|
227
|
+
tryCatalogAt(resolve(anchor, name));
|
|
228
|
+
}
|
|
229
|
+
return [...catalogs.values()];
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Discover AIR index files and `air.json` configs under `targetDir`.
|
|
233
|
+
*
|
|
234
|
+
* Anchor is the enclosing git root (via `git rev-parse --show-toplevel`)
|
|
235
|
+
* if one exists, else `targetDir` itself. Walks up to `maxDepth` levels
|
|
236
|
+
* deep, skipping `node_modules/`, `.git/`, build output dirs, and anything
|
|
237
|
+
* starting with `.`. Every candidate file is validated via filename-based
|
|
238
|
+
* schema detection plus optional `$schema` cross-check; unparseable or
|
|
239
|
+
* non-AIR JSON files are silently skipped.
|
|
240
|
+
*
|
|
241
|
+
* Files found via a catalog layout are excluded from `looseIndexes` — the
|
|
242
|
+
* catalog entry already covers them.
|
|
243
|
+
*/
|
|
244
|
+
export function discoverIndexes(targetDir, options) {
|
|
245
|
+
const { anchor, isGitRoot } = resolveAnchor(targetDir);
|
|
246
|
+
const maxDepth = options?.maxDepth ?? MAX_DEPTH;
|
|
247
|
+
const skipDirs = options?.skipDirs ?? SKIP_DIRS;
|
|
248
|
+
const catalogs = findCatalogs(anchor);
|
|
249
|
+
// Build a set of file paths already covered by a catalog so we don't
|
|
250
|
+
// double-count them as loose indexes.
|
|
251
|
+
const catalogCovered = new Set();
|
|
252
|
+
for (const cat of catalogs) {
|
|
253
|
+
for (const type of cat.types) {
|
|
254
|
+
catalogCovered.add(resolve(cat.path, type, `${type}.json`));
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
const looseIndexes = [];
|
|
258
|
+
const airJsons = [];
|
|
259
|
+
for (const file of walkJsonFiles(anchor, maxDepth, skipDirs)) {
|
|
260
|
+
if (catalogCovered.has(file))
|
|
261
|
+
continue;
|
|
262
|
+
const name = basename(file);
|
|
263
|
+
// End-with `.schema.json` is excluded by detectSchemaType.
|
|
264
|
+
const type = detectSchemaType(name);
|
|
265
|
+
if (!type)
|
|
266
|
+
continue;
|
|
267
|
+
if (type === "air") {
|
|
268
|
+
if (readAirJson(file)) {
|
|
269
|
+
airJsons.push({
|
|
270
|
+
path: file,
|
|
271
|
+
relPath: relative(anchor, file),
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
if (!CATALOG_TYPES.includes(type))
|
|
277
|
+
continue;
|
|
278
|
+
const data = readAndValidateIndex(file, type);
|
|
279
|
+
if (!data)
|
|
280
|
+
continue;
|
|
281
|
+
looseIndexes.push({
|
|
282
|
+
type: type,
|
|
283
|
+
path: file,
|
|
284
|
+
relPath: relative(anchor, file),
|
|
285
|
+
entryCount: countEntries(data),
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
// Stable ordering: shallowest first, then alphabetic. Makes test assertions
|
|
289
|
+
// deterministic and produces predictable prompt output.
|
|
290
|
+
const byPath = (a, b) => {
|
|
291
|
+
const da = a.relPath.split(sep).length;
|
|
292
|
+
const db = b.relPath.split(sep).length;
|
|
293
|
+
if (da !== db)
|
|
294
|
+
return da - db;
|
|
295
|
+
return a.relPath.localeCompare(b.relPath);
|
|
296
|
+
};
|
|
297
|
+
catalogs.sort(byPath);
|
|
298
|
+
looseIndexes.sort(byPath);
|
|
299
|
+
airJsons.sort(byPath);
|
|
300
|
+
return {
|
|
301
|
+
anchor,
|
|
302
|
+
anchorIsGitRoot: isGitRoot,
|
|
303
|
+
catalogs,
|
|
304
|
+
looseIndexes,
|
|
305
|
+
airJsons,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
export { CATALOG_TYPES };
|
|
309
|
+
//# sourceMappingURL=discover-indexes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover-indexes.js","sourceRoot":"","sources":["../src/discover-indexes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { DiscoveredCatalog, DiscoveredLooseIndex, DiscoveredAirJson, CatalogType } from "./discover-indexes.js";
|
|
2
|
+
/** Shape of the entries we write — loose indexes get a type, catalogs get the catalogs[] slot. */
|
|
3
|
+
export interface AirJsonAddition {
|
|
4
|
+
kind: "catalog" | "loose" | "airJson";
|
|
5
|
+
/** Path or URI string written to air.json. */
|
|
6
|
+
value: string;
|
|
7
|
+
/** For loose/airJson entries, the artifact type slot the value was written to. */
|
|
8
|
+
type?: CatalogType;
|
|
9
|
+
/** Short human-readable summary used by the acceptance output. */
|
|
10
|
+
label: string;
|
|
11
|
+
}
|
|
12
|
+
export interface EditAirJsonOptions {
|
|
13
|
+
/** Override the default air.json path. */
|
|
14
|
+
path?: string;
|
|
15
|
+
/** Entries already persisted into air.json become no-ops. Default: true. */
|
|
16
|
+
idempotent?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface EditAirJsonResult {
|
|
19
|
+
/** Absolute path to the air.json that was read/written. */
|
|
20
|
+
airJsonPath: string;
|
|
21
|
+
/** Entries that were newly added. */
|
|
22
|
+
added: AirJsonAddition[];
|
|
23
|
+
/** Entries that were already present and therefore skipped. */
|
|
24
|
+
skipped: AirJsonAddition[];
|
|
25
|
+
/** True if the scaffold was created because no air.json existed. */
|
|
26
|
+
createdScaffold: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Check whether `candidate` (an absolute path or URI) is already present in the
|
|
30
|
+
* given list of air.json entries. Performs path normalization so absolute,
|
|
31
|
+
* `./relative`, and `../relative` forms of the same file all collide.
|
|
32
|
+
*/
|
|
33
|
+
export declare function entryAlreadyListed(candidateAbsOrUri: string, list: string[] | undefined, airJsonDir: string): boolean;
|
|
34
|
+
export interface AddDiscoveredEntries {
|
|
35
|
+
catalogs?: DiscoveredCatalog[];
|
|
36
|
+
looseIndexes?: DiscoveredLooseIndex[];
|
|
37
|
+
airJsons?: DiscoveredAirJson[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Add discovered entries to the user's air.json.
|
|
41
|
+
*
|
|
42
|
+
* Catalogs go into `catalogs[]`. Loose indexes go into the matching per-type
|
|
43
|
+
* array (`skills[]`, `mcp[]`, …). Nested `air.json` files land in
|
|
44
|
+
* `catalogs[]` because they describe a full composition at their location —
|
|
45
|
+
* the user can further edit the reference later. All additions are
|
|
46
|
+
* idempotent: an entry already present in air.json is not duplicated.
|
|
47
|
+
*
|
|
48
|
+
* If the target air.json does not exist, a minimal scaffold is written
|
|
49
|
+
* (no local index files — for a full workspace scaffold use `initConfig`).
|
|
50
|
+
*/
|
|
51
|
+
export declare function addDiscoveredToAirJson(entries: AddDiscoveredEntries, options?: EditAirJsonOptions): EditAirJsonResult;
|
|
52
|
+
/**
|
|
53
|
+
* Inspect whether a discovered candidate is already registered in air.json.
|
|
54
|
+
* Used by the discovery filter to drop items that are already composed.
|
|
55
|
+
*/
|
|
56
|
+
export interface RegisteredChecker {
|
|
57
|
+
catalog(absPath: string): boolean;
|
|
58
|
+
loose(type: CatalogType, absPath: string): boolean;
|
|
59
|
+
airJson(absPath: string): boolean;
|
|
60
|
+
}
|
|
61
|
+
export declare function buildRegisteredChecker(airJsonPath: string | null): RegisteredChecker;
|
|
62
|
+
//# sourceMappingURL=edit-air-json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-air-json.d.ts","sourceRoot":"","sources":["../src/edit-air-json.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACZ,MAAM,uBAAuB,CAAC;AAc/B,kGAAkG;AAClG,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IACtC,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,kFAAkF;IAClF,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,+DAA+D;IAC/D,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,oEAAoE;IACpE,eAAe,EAAE,OAAO,CAAC;CAC1B;AA2DD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,iBAAiB,EAAE,MAAM,EACzB,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,EAC1B,UAAU,EAAE,MAAM,GACjB,OAAO,CAYT;AA+CD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC/B,YAAY,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACtC,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAChC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,oBAAoB,EAC7B,OAAO,CAAC,EAAE,kBAAkB,GAC3B,iBAAiB,CAkFnB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,KAAK,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACnD,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;CACnC;AAED,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,GAAG,IAAI,GACzB,iBAAiB,CAiCnB"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
2
|
+
import { resolve, dirname, relative, isAbsolute } from "path";
|
|
3
|
+
import { getDefaultAirJsonPath } from "@pulsemcp/air-core";
|
|
4
|
+
const SCHEMA_BASE_URL = "https://raw.githubusercontent.com/pulsemcp/air/main/schemas";
|
|
5
|
+
const CATALOG_TYPES = [
|
|
6
|
+
"skills",
|
|
7
|
+
"references",
|
|
8
|
+
"mcp",
|
|
9
|
+
"plugins",
|
|
10
|
+
"roots",
|
|
11
|
+
"hooks",
|
|
12
|
+
];
|
|
13
|
+
function loadOrScaffold(airJsonPath) {
|
|
14
|
+
if (!existsSync(airJsonPath)) {
|
|
15
|
+
mkdirSync(dirname(airJsonPath), { recursive: true });
|
|
16
|
+
const scaffold = {
|
|
17
|
+
$schema: `${SCHEMA_BASE_URL}/air.schema.json`,
|
|
18
|
+
name: "my-config",
|
|
19
|
+
description: "Personal AIR configuration",
|
|
20
|
+
};
|
|
21
|
+
return { data: scaffold, created: true };
|
|
22
|
+
}
|
|
23
|
+
const raw = readFileSync(airJsonPath, "utf-8");
|
|
24
|
+
const parsed = JSON.parse(raw);
|
|
25
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
26
|
+
throw new Error(`${airJsonPath} is not a JSON object — refusing to edit.`);
|
|
27
|
+
}
|
|
28
|
+
return { data: parsed, created: false };
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Normalize a path string for comparison against air.json entries. Entries
|
|
32
|
+
* in air.json may be:
|
|
33
|
+
* - absolute (`/abs/path/to/skills.json`)
|
|
34
|
+
* - relative to the air.json directory (`./skills/skills.json`, `../foo/skills.json`)
|
|
35
|
+
* - a URI (`github://…`) — passed through untouched
|
|
36
|
+
*
|
|
37
|
+
* We compare by absolute path when possible so "./skills/skills.json" and its
|
|
38
|
+
* fully-resolved absolute twin are recognized as the same entry.
|
|
39
|
+
*/
|
|
40
|
+
function normalizeToAbsolute(entry, airJsonDir) {
|
|
41
|
+
if (/^[a-zA-Z][a-zA-Z0-9+\-.]*:\/\//.test(entry))
|
|
42
|
+
return entry;
|
|
43
|
+
if (isAbsolute(entry))
|
|
44
|
+
return resolve(entry);
|
|
45
|
+
return resolve(airJsonDir, entry);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check whether `candidate` (an absolute path or URI) is already present in the
|
|
49
|
+
* given list of air.json entries. Performs path normalization so absolute,
|
|
50
|
+
* `./relative`, and `../relative` forms of the same file all collide.
|
|
51
|
+
*/
|
|
52
|
+
export function entryAlreadyListed(candidateAbsOrUri, list, airJsonDir) {
|
|
53
|
+
if (!list || list.length === 0)
|
|
54
|
+
return false;
|
|
55
|
+
const isUri = /^[a-zA-Z][a-zA-Z0-9+\-.]*:\/\//.test(candidateAbsOrUri);
|
|
56
|
+
if (isUri) {
|
|
57
|
+
return list.includes(candidateAbsOrUri);
|
|
58
|
+
}
|
|
59
|
+
const candidateAbs = resolve(candidateAbsOrUri);
|
|
60
|
+
for (const entry of list) {
|
|
61
|
+
const normalized = normalizeToAbsolute(entry, airJsonDir);
|
|
62
|
+
if (normalized === candidateAbs)
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Produce the relative path written to air.json for an absolute target.
|
|
69
|
+
*
|
|
70
|
+
* We emit `./` or `../`-prefixed relative paths for targets that live under
|
|
71
|
+
* or above the air.json directory respectively. Targets on an entirely
|
|
72
|
+
* different volume (uncommon) fall back to the absolute path.
|
|
73
|
+
*/
|
|
74
|
+
function toAirJsonRelPath(absTarget, airJsonDir) {
|
|
75
|
+
const rel = relative(airJsonDir, absTarget);
|
|
76
|
+
if (!rel)
|
|
77
|
+
return "./";
|
|
78
|
+
if (rel.startsWith(".."))
|
|
79
|
+
return rel;
|
|
80
|
+
if (isAbsolute(rel))
|
|
81
|
+
return rel;
|
|
82
|
+
return "./" + rel;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Return all artifact-type entry arrays that are already present in the
|
|
86
|
+
* air.json, defaulting each to `[]` if absent so callers can push without
|
|
87
|
+
* pre-existence checks.
|
|
88
|
+
*/
|
|
89
|
+
function ensureArray(data, key) {
|
|
90
|
+
if (!data[key])
|
|
91
|
+
data[key] = [];
|
|
92
|
+
return data[key];
|
|
93
|
+
}
|
|
94
|
+
function formatLabel(kind, target, type) {
|
|
95
|
+
if (kind === "catalog")
|
|
96
|
+
return `catalog '${target}'`;
|
|
97
|
+
if (kind === "airJson")
|
|
98
|
+
return `air.json '${target}'`;
|
|
99
|
+
return `${type} '${target}'`;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Add discovered entries to the user's air.json.
|
|
103
|
+
*
|
|
104
|
+
* Catalogs go into `catalogs[]`. Loose indexes go into the matching per-type
|
|
105
|
+
* array (`skills[]`, `mcp[]`, …). Nested `air.json` files land in
|
|
106
|
+
* `catalogs[]` because they describe a full composition at their location —
|
|
107
|
+
* the user can further edit the reference later. All additions are
|
|
108
|
+
* idempotent: an entry already present in air.json is not duplicated.
|
|
109
|
+
*
|
|
110
|
+
* If the target air.json does not exist, a minimal scaffold is written
|
|
111
|
+
* (no local index files — for a full workspace scaffold use `initConfig`).
|
|
112
|
+
*/
|
|
113
|
+
export function addDiscoveredToAirJson(entries, options) {
|
|
114
|
+
const airJsonPath = options?.path ?? getDefaultAirJsonPath();
|
|
115
|
+
const airJsonDir = dirname(resolve(airJsonPath));
|
|
116
|
+
const { data, created } = loadOrScaffold(airJsonPath);
|
|
117
|
+
const added = [];
|
|
118
|
+
const skipped = [];
|
|
119
|
+
for (const catalog of entries.catalogs ?? []) {
|
|
120
|
+
const value = toAirJsonRelPath(catalog.path, airJsonDir);
|
|
121
|
+
const list = ensureArray(data, "catalogs");
|
|
122
|
+
if (entryAlreadyListed(catalog.path, list, airJsonDir)) {
|
|
123
|
+
skipped.push({
|
|
124
|
+
kind: "catalog",
|
|
125
|
+
value,
|
|
126
|
+
label: formatLabel("catalog", value),
|
|
127
|
+
});
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
list.push(value);
|
|
131
|
+
added.push({
|
|
132
|
+
kind: "catalog",
|
|
133
|
+
value,
|
|
134
|
+
label: formatLabel("catalog", value),
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
for (const airJson of entries.airJsons ?? []) {
|
|
138
|
+
// A nested air.json is semantically a catalog reference — the directory
|
|
139
|
+
// containing it typically follows the standard layout.
|
|
140
|
+
const catalogDir = dirname(airJson.path);
|
|
141
|
+
const value = toAirJsonRelPath(catalogDir, airJsonDir);
|
|
142
|
+
const list = ensureArray(data, "catalogs");
|
|
143
|
+
if (entryAlreadyListed(catalogDir, list, airJsonDir)) {
|
|
144
|
+
skipped.push({
|
|
145
|
+
kind: "airJson",
|
|
146
|
+
value,
|
|
147
|
+
label: formatLabel("airJson", value),
|
|
148
|
+
});
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
list.push(value);
|
|
152
|
+
added.push({
|
|
153
|
+
kind: "airJson",
|
|
154
|
+
value,
|
|
155
|
+
label: formatLabel("airJson", value),
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
for (const loose of entries.looseIndexes ?? []) {
|
|
159
|
+
if (!CATALOG_TYPES.includes(loose.type))
|
|
160
|
+
continue;
|
|
161
|
+
const value = toAirJsonRelPath(loose.path, airJsonDir);
|
|
162
|
+
const list = ensureArray(data, loose.type);
|
|
163
|
+
if (entryAlreadyListed(loose.path, list, airJsonDir)) {
|
|
164
|
+
skipped.push({
|
|
165
|
+
kind: "loose",
|
|
166
|
+
value,
|
|
167
|
+
type: loose.type,
|
|
168
|
+
label: formatLabel("loose", value, loose.type),
|
|
169
|
+
});
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
list.push(value);
|
|
173
|
+
added.push({
|
|
174
|
+
kind: "loose",
|
|
175
|
+
value,
|
|
176
|
+
type: loose.type,
|
|
177
|
+
label: formatLabel("loose", value, loose.type),
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
if (added.length > 0 || created) {
|
|
181
|
+
mkdirSync(dirname(airJsonPath), { recursive: true });
|
|
182
|
+
writeFileSync(airJsonPath, JSON.stringify(data, null, 2) + "\n");
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
airJsonPath,
|
|
186
|
+
added,
|
|
187
|
+
skipped,
|
|
188
|
+
createdScaffold: created,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
export function buildRegisteredChecker(airJsonPath) {
|
|
192
|
+
if (!airJsonPath || !existsSync(airJsonPath)) {
|
|
193
|
+
return {
|
|
194
|
+
catalog: () => false,
|
|
195
|
+
loose: () => false,
|
|
196
|
+
airJson: () => false,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
let data;
|
|
200
|
+
try {
|
|
201
|
+
data = JSON.parse(readFileSync(airJsonPath, "utf-8"));
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return {
|
|
205
|
+
catalog: () => false,
|
|
206
|
+
loose: () => false,
|
|
207
|
+
airJson: () => false,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
const airJsonDir = dirname(resolve(airJsonPath));
|
|
211
|
+
return {
|
|
212
|
+
catalog(absPath) {
|
|
213
|
+
return entryAlreadyListed(absPath, data.catalogs, airJsonDir);
|
|
214
|
+
},
|
|
215
|
+
loose(type, absPath) {
|
|
216
|
+
const list = data[type];
|
|
217
|
+
if (entryAlreadyListed(absPath, list, airJsonDir))
|
|
218
|
+
return true;
|
|
219
|
+
return entryAlreadyListed(absPath, data.catalogs, airJsonDir);
|
|
220
|
+
},
|
|
221
|
+
airJson(absPath) {
|
|
222
|
+
const catalogDir = dirname(absPath);
|
|
223
|
+
return entryAlreadyListed(catalogDir, data.catalogs, airJsonDir);
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=edit-air-json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-air-json.js","sourceRoot":"","sources":["../src/edit-air-json.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { loadAirConfig, getDefaultAirJsonPath, getAirJsonPath, resolveArtifacts, mergeArtifacts, expandPlugins, emptyArtifacts, validateJson, getSchemasDir, getSchemaPath, loadSchema, detectSchemaType, detectSchemaFromValue, getAllSchemaTypes, isValidSchemaType, } from "@pulsemcp/air-core";
|
|
2
|
-
export type { AirConfig, ResolvedArtifacts, SkillEntry, ReferenceEntry, McpOAuthConfig, McpServerEntry, PluginAuthor, PluginEntry, RootEntry, HookEntry, AgentAdapter, CatalogProvider, CacheFreshnessWarning, CacheRefreshResult, AirExtension, PrepareTransform, PluginEmitter, BuildMarketplaceOptions, BuiltPlugin, BuiltMarketplace, McpConfig, TransformContext, ExtensionCliOption, AgentSessionConfig, StartCommand, PrepareSessionOptions as CorePrepareSessionOptions, PreparedSession, LocalArtifacts, LocalSkillEntry, ValidationResult, ValidationError, ResolveOptions, SchemaType, } from "@pulsemcp/air-core";
|
|
1
|
+
export { loadAirConfig, getDefaultAirJsonPath, getAirJsonPath, resolveArtifacts, mergeArtifacts, expandPlugins, emptyArtifacts, validateJson, getSchemasDir, getSchemaPath, loadSchema, detectSchemaType, detectSchemaFromValue, getAllSchemaTypes, isValidSchemaType, MANIFEST_VERSION, getDefaultAirHome, getManifestPath, loadManifest, writeManifest, buildManifest, diffManifest, } from "@pulsemcp/air-core";
|
|
2
|
+
export type { AirConfig, ResolvedArtifacts, SkillEntry, ReferenceEntry, McpOAuthConfig, McpServerEntry, PluginAuthor, PluginEntry, RootEntry, HookEntry, AgentAdapter, CatalogProvider, CacheFreshnessWarning, CacheRefreshResult, AirExtension, PrepareTransform, PluginEmitter, BuildMarketplaceOptions, BuiltPlugin, BuiltMarketplace, McpConfig, TransformContext, ExtensionCliOption, AgentSessionConfig, StartCommand, PrepareSessionOptions as CorePrepareSessionOptions, PreparedSession, LocalArtifacts, LocalSkillEntry, ValidationResult, ValidationError, ResolveOptions, SchemaType, Manifest, ManifestSelection, ManifestDiff, } from "@pulsemcp/air-core";
|
|
3
3
|
export { findAdapter, listAvailableAdapters, type FindAdapterOptions, } from "./adapter-registry.js";
|
|
4
4
|
export { normalizeGitUrl, detectRoot } from "./root-detection.js";
|
|
5
5
|
export { validateFile } from "./validate.js";
|
|
@@ -28,4 +28,12 @@ export { updateProviderCaches } from "./update.js";
|
|
|
28
28
|
export type { UpdateProviderCachesOptions, UpdateProviderCachesResult, } from "./update.js";
|
|
29
29
|
export { checkProviderFreshness } from "./cache-freshness.js";
|
|
30
30
|
export { findUnresolvedVars, findUnresolvedHookVars, validateNoUnresolvedVars, unresolvedVarsMessage, } from "./validate-config.js";
|
|
31
|
+
export { discoverIndexes, resolveAnchor, CATALOG_TYPES, } from "./discover-indexes.js";
|
|
32
|
+
export type { DiscoveryResult, DiscoveredCatalog, DiscoveredLooseIndex, DiscoveredAirJson, DiscoverIndexesOptions, CatalogType, } from "./discover-indexes.js";
|
|
33
|
+
export { loadPreferences, savePreferences, addDismissed, isDismissed, getDefaultPreferencesPath, } from "./preferences.js";
|
|
34
|
+
export type { AirPreferences, DismissedDiscovery } from "./preferences.js";
|
|
35
|
+
export { addDiscoveredToAirJson, buildRegisteredChecker, entryAlreadyListed, } from "./edit-air-json.js";
|
|
36
|
+
export type { AirJsonAddition, EditAirJsonOptions, EditAirJsonResult, AddDiscoveredEntries, RegisteredChecker, } from "./edit-air-json.js";
|
|
37
|
+
export { findOfferableIndexes, acceptOffers, dismissOffers, } from "./auto-discovery.js";
|
|
38
|
+
export type { FindOfferableOptions, OfferableDiscoveryResult, AcceptDiscoveryOptions, DismissDiscoveryOptions, } from "./auto-discovery.js";
|
|
31
39
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,aAAa,EACb,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,cAAc,EAEd,YAAY,EAEZ,aAAa,EACb,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,9 @@ loadAirConfig, getDefaultAirJsonPath, getAirJsonPath, resolveArtifacts, mergeArt
|
|
|
5
5
|
// Validation
|
|
6
6
|
validateJson,
|
|
7
7
|
// Schemas
|
|
8
|
-
getSchemasDir, getSchemaPath, loadSchema, detectSchemaType, detectSchemaFromValue, getAllSchemaTypes, isValidSchemaType,
|
|
8
|
+
getSchemasDir, getSchemaPath, loadSchema, detectSchemaType, detectSchemaFromValue, getAllSchemaTypes, isValidSchemaType,
|
|
9
|
+
// Manifest
|
|
10
|
+
MANIFEST_VERSION, getDefaultAirHome, getManifestPath, loadManifest, writeManifest, buildManifest, diffManifest, } from "@pulsemcp/air-core";
|
|
9
11
|
// Adapter registry
|
|
10
12
|
export { findAdapter, listAvailableAdapters, } from "./adapter-registry.js";
|
|
11
13
|
// Root detection
|
|
@@ -31,4 +33,12 @@ export { updateProviderCaches } from "./update.js";
|
|
|
31
33
|
export { checkProviderFreshness } from "./cache-freshness.js";
|
|
32
34
|
// Config validation
|
|
33
35
|
export { findUnresolvedVars, findUnresolvedHookVars, validateNoUnresolvedVars, unresolvedVarsMessage, } from "./validate-config.js";
|
|
36
|
+
// Repo-level index discovery (for `air start` / `air prepare` auto-registration)
|
|
37
|
+
export { discoverIndexes, resolveAnchor, CATALOG_TYPES, } from "./discover-indexes.js";
|
|
38
|
+
// User preferences (auto-discovery dismiss-set lives here)
|
|
39
|
+
export { loadPreferences, savePreferences, addDismissed, isDismissed, getDefaultPreferencesPath, } from "./preferences.js";
|
|
40
|
+
// air.json editing (adds discovered entries)
|
|
41
|
+
export { addDiscoveredToAirJson, buildRegisteredChecker, entryAlreadyListed, } from "./edit-air-json.js";
|
|
42
|
+
// Auto-discovery orchestration (used by `air start` / `air prepare`)
|
|
43
|
+
export { findOfferableIndexes, acceptOffers, dismissOffers, } from "./auto-discovery.js";
|
|
34
44
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,OAAO;AACL,oBAAoB;AACpB,aAAa,EACb,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,cAAc;AACd,aAAa;AACb,YAAY;AACZ,UAAU;AACV,aAAa,EACb,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,OAAO;AACL,oBAAoB;AACpB,aAAa,EACb,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,cAAc;AACd,aAAa;AACb,YAAY;AACZ,UAAU;AACV,aAAa,EACb,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB;AACjB,WAAW;AACX,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,aAAa,EACb,aAAa,EACb,YAAY,GACb,MAAM,oBAAoB,CAAC;AAgD5B,mBAAmB;AACnB,OAAO,EACL,WAAW,EACX,qBAAqB,GAEtB,MAAM,uBAAuB,CAAC;AAE/B,iBAAiB;AACjB,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAElE,wBAAwB;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG7C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAOvC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AASjF,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAGhE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AAOtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAM5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGpD,sBAAsB;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAMjD,mBAAmB;AACnB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,mBAAmB;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD,4BAA4B;AAC5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAMnD,2BAA2B;AAC3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,oBAAoB;AACpB,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAE9B,iFAAiF;AACjF,OAAO,EACL,eAAe,EACf,aAAa,EACb,aAAa,GACd,MAAM,uBAAuB,CAAC;AAU/B,2DAA2D;AAC3D,OAAO,EACL,eAAe,EACf,eAAe,EACf,YAAY,EACZ,WAAW,EACX,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAG1B,6CAA6C;AAC7C,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAS5B,qEAAqE;AACrE,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,aAAa,GACd,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface DismissedDiscovery {
|
|
2
|
+
/** Absolute path to the discovery anchor at the time of dismissal. */
|
|
3
|
+
repoRoot: string;
|
|
4
|
+
/** Path relative to `repoRoot` for the specific index file dismissed. */
|
|
5
|
+
indexPath: string;
|
|
6
|
+
}
|
|
7
|
+
export interface AirPreferences {
|
|
8
|
+
$schema?: string;
|
|
9
|
+
autoDiscovery?: {
|
|
10
|
+
dismissed?: DismissedDiscovery[];
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/** Default location: `~/.air/preferences.json`, sibling to `air.json`. */
|
|
14
|
+
export declare function getDefaultPreferencesPath(): string;
|
|
15
|
+
/**
|
|
16
|
+
* Read the preferences file. Returns a structurally complete default when the
|
|
17
|
+
* file is missing or malformed so callers never need to null-check.
|
|
18
|
+
*/
|
|
19
|
+
export declare function loadPreferences(path?: string): AirPreferences;
|
|
20
|
+
/** Write preferences to disk with 2-space indentation and trailing newline. */
|
|
21
|
+
export declare function savePreferences(prefs: AirPreferences, path?: string): void;
|
|
22
|
+
/**
|
|
23
|
+
* Add one or more (repoRoot, indexPath) entries to the dismissed-set.
|
|
24
|
+
* Idempotent — entries already present are not duplicated.
|
|
25
|
+
*/
|
|
26
|
+
export declare function addDismissed(entries: DismissedDiscovery[], path?: string): AirPreferences;
|
|
27
|
+
/**
|
|
28
|
+
* True if the given (repoRoot, indexPath) pair is in the dismissed-set.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isDismissed(prefs: AirPreferences, entry: DismissedDiscovery): boolean;
|
|
31
|
+
//# sourceMappingURL=preferences.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preferences.d.ts","sourceRoot":"","sources":["../src/preferences.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE;QACd,SAAS,CAAC,EAAE,kBAAkB,EAAE,CAAC;KAClC,CAAC;CACH;AAED,0EAA0E;AAC1E,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AASD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,cAAc,CA4B7D;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAI1E;AAMD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,kBAAkB,EAAE,EAC7B,IAAI,CAAC,EAAE,MAAM,GACZ,cAAc,CAYhB;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,cAAc,EACrB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAKT"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preferences.js","sourceRoot":"","sources":["../src/preferences.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pulsemcp/air-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.41",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"lint": "tsc --noEmit"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@pulsemcp/air-core": "0.0.
|
|
32
|
+
"@pulsemcp/air-core": "0.0.41"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/node": "^22.10.0",
|