@hasna/instructions 0.4.32 → 0.4.34
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 +58 -14
- package/dist/data/config-store.d.ts.map +1 -1
- package/dist/index.js +51 -13
- package/dist/lib/apply.d.ts.map +1 -1
- package/dist/lib/cursor-authority.d.ts +26 -3
- package/dist/lib/cursor-authority.d.ts.map +1 -1
- package/dist/mcp/index.js +88 -38
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -10718,18 +10718,34 @@ function observeCursorGlobalAuthorityPath(authorityPath, readFile2) {
|
|
|
10718
10718
|
return {
|
|
10719
10719
|
...base,
|
|
10720
10720
|
fileType,
|
|
10721
|
-
status: "
|
|
10721
|
+
status: "managed",
|
|
10722
10722
|
sha256: contentSha256,
|
|
10723
10723
|
markers,
|
|
10724
10724
|
markerSha256,
|
|
10725
10725
|
provenance: {
|
|
10726
10726
|
source: "filesystem",
|
|
10727
|
-
authority: "
|
|
10727
|
+
authority: "managed",
|
|
10728
10728
|
observedPath: authorityPath,
|
|
10729
|
-
detection: "
|
|
10729
|
+
detection: "managed-marker"
|
|
10730
10730
|
}
|
|
10731
10731
|
};
|
|
10732
10732
|
}
|
|
10733
|
+
function isCursorGlobalAuthorityPath(path) {
|
|
10734
|
+
return resolve3(path) === resolve3(join5(homeDir(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
|
|
10735
|
+
}
|
|
10736
|
+
function stampCursorGlobalAuthorityMarker(content) {
|
|
10737
|
+
if (CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN.test(content))
|
|
10738
|
+
return content;
|
|
10739
|
+
const digest = sha2564(content);
|
|
10740
|
+
const markerLine = `<!-- ${CURSOR_GLOBAL_AUTHORITY_MANAGED_MARKER} hash=sha256:${digest} -->`;
|
|
10741
|
+
const frontmatter = content.match(CURSOR_GLOBAL_AUTHORITY_FRONTMATTER_PATTERN)?.[0];
|
|
10742
|
+
if (frontmatter) {
|
|
10743
|
+
return `${frontmatter}${markerLine}
|
|
10744
|
+
${content.slice(frontmatter.length)}`;
|
|
10745
|
+
}
|
|
10746
|
+
return `${markerLine}
|
|
10747
|
+
${content}`;
|
|
10748
|
+
}
|
|
10733
10749
|
function detectCursorAuthorityConflicts(observation = observeCursorGlobalAuthority()) {
|
|
10734
10750
|
if (observation.status === "absent" || observation.status === "managed")
|
|
10735
10751
|
return [];
|
|
@@ -10751,10 +10767,11 @@ function detectCursorAuthorityConflicts(observation = observeCursorGlobalAuthori
|
|
|
10751
10767
|
reason: invalid ? `Cursor fixed global authority ${CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH} is not a verifiable regular managed file; refusing to render project rules.` : `Cursor fixed global authority ${CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH} is unmanaged; refusing to guess whether it conflicts with the managed project render.`
|
|
10752
10768
|
}];
|
|
10753
10769
|
}
|
|
10754
|
-
var CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH = ".cursor/rules/hasna-global.mdc", CURSOR_GLOBAL_AUTHORITY_MAX_BYTES, CURSOR_GLOBAL_AUTHORITY_MANAGED_MARKER = "Managed by @hasna/configs cursor global authority", CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN;
|
|
10770
|
+
var CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH = ".cursor/rules/hasna-global.mdc", CURSOR_GLOBAL_AUTHORITY_MAX_BYTES, CURSOR_GLOBAL_AUTHORITY_MANAGED_MARKER = "Managed by @hasna/configs cursor global authority", CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN, CURSOR_GLOBAL_AUTHORITY_FRONTMATTER_PATTERN;
|
|
10755
10771
|
var init_cursor_authority = __esm(() => {
|
|
10756
10772
|
CURSOR_GLOBAL_AUTHORITY_MAX_BYTES = 256 * 1024;
|
|
10757
10773
|
CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN = /^<!-- Managed by @hasna\/configs cursor global authority hash=(sha256:[a-f0-9]{64}) -->$/m;
|
|
10774
|
+
CURSOR_GLOBAL_AUTHORITY_FRONTMATTER_PATTERN = /^---\n[\s\S]*?\n---(?:\n|$)/;
|
|
10758
10775
|
});
|
|
10759
10776
|
|
|
10760
10777
|
// src/lib/session-render.ts
|
|
@@ -13655,7 +13672,17 @@ class CloudConfigStore {
|
|
|
13655
13672
|
return parseBoundedOrLegacyPage(data.configs, data.profile.configs, normalized, "profile membership");
|
|
13656
13673
|
}
|
|
13657
13674
|
async getProfileConfigBindings(idOrSlug) {
|
|
13658
|
-
const { data } = await this.requestProfileRoute(idOrSlug, (profileId) => `/profiles/${encodeURIComponent(profileId)}/bindings`, (value) => Array.isArray(value?.bindings));
|
|
13675
|
+
const { status, data } = await this.requestProfileRoute(idOrSlug, (profileId) => `/profiles/${encodeURIComponent(profileId)}/bindings`, (value) => Array.isArray(value?.bindings));
|
|
13676
|
+
if (status === 404) {
|
|
13677
|
+
const profile = await this.getProfile(idOrSlug);
|
|
13678
|
+
const configs = await this.getProfileConfigs(idOrSlug);
|
|
13679
|
+
return configs.map((config, sort_order) => ({
|
|
13680
|
+
profile_id: profile.id,
|
|
13681
|
+
config_id: config.id,
|
|
13682
|
+
sort_order,
|
|
13683
|
+
binding: legacyProfileConfigBinding()
|
|
13684
|
+
}));
|
|
13685
|
+
}
|
|
13659
13686
|
if (!data || !Array.isArray(data.bindings))
|
|
13660
13687
|
throw new ProfileNotFoundError(idOrSlug);
|
|
13661
13688
|
return data.bindings;
|
|
@@ -13667,8 +13694,11 @@ class CloudConfigStore {
|
|
|
13667
13694
|
return this.request("GET", pathForId(profileId), undefined, { allow404: true });
|
|
13668
13695
|
};
|
|
13669
13696
|
const first = await request(idOrSlug);
|
|
13670
|
-
if (first.status !== 404
|
|
13671
|
-
|
|
13697
|
+
if (first.status !== 404) {
|
|
13698
|
+
if (isUsable(first.data))
|
|
13699
|
+
return first;
|
|
13700
|
+
throw new CloudHttpError(502, "profile follow-up returned an invalid response", first.data);
|
|
13701
|
+
}
|
|
13672
13702
|
const profiles = await this.listProfiles();
|
|
13673
13703
|
const profile = profiles.find((candidate) => candidate.id === idOrSlug || candidate.slug === idOrSlug);
|
|
13674
13704
|
if (!profile)
|
|
@@ -13677,10 +13707,13 @@ class CloudConfigStore {
|
|
|
13677
13707
|
if (attempted.has(candidate))
|
|
13678
13708
|
continue;
|
|
13679
13709
|
const response = await request(candidate);
|
|
13680
|
-
if (response.status !== 404
|
|
13681
|
-
|
|
13710
|
+
if (response.status !== 404) {
|
|
13711
|
+
if (isUsable(response.data))
|
|
13712
|
+
return response;
|
|
13713
|
+
throw new CloudHttpError(502, "profile follow-up returned an invalid response", response.data);
|
|
13714
|
+
}
|
|
13682
13715
|
}
|
|
13683
|
-
|
|
13716
|
+
return { status: 404, data: null };
|
|
13684
13717
|
}
|
|
13685
13718
|
async createProfile(input) {
|
|
13686
13719
|
const { data } = await this.request("POST", "/profiles", input, {
|
|
@@ -13710,7 +13743,11 @@ class CloudConfigStore {
|
|
|
13710
13743
|
await this.request("DELETE", `/profiles/${encodeURIComponent(profileIdOrSlug)}/configs/${encodeURIComponent(configId)}`, undefined, { allow404: true });
|
|
13711
13744
|
}
|
|
13712
13745
|
async getProfileAssetBindings(profileIdOrSlug) {
|
|
13713
|
-
const { data } = await this.requestProfileRoute(profileIdOrSlug, (profileId) => `/profiles/${encodeURIComponent(profileId)}/assets`, (value) => Array.isArray(value?.assets));
|
|
13746
|
+
const { status, data } = await this.requestProfileRoute(profileIdOrSlug, (profileId) => `/profiles/${encodeURIComponent(profileId)}/assets`, (value) => Array.isArray(value?.assets));
|
|
13747
|
+
if (status === 404) {
|
|
13748
|
+
await this.getProfile(profileIdOrSlug);
|
|
13749
|
+
return [];
|
|
13750
|
+
}
|
|
13714
13751
|
if (!data || !Array.isArray(data.assets))
|
|
13715
13752
|
throw new ProfileNotFoundError(profileIdOrSlug);
|
|
13716
13753
|
return data.assets;
|
|
@@ -13811,6 +13848,7 @@ var init_config_store = __esm(() => {
|
|
|
13811
13848
|
init_database();
|
|
13812
13849
|
init_types();
|
|
13813
13850
|
init_bounded_read();
|
|
13851
|
+
init_instruction_graph();
|
|
13814
13852
|
CloudHttpError = class CloudHttpError extends Error {
|
|
13815
13853
|
status;
|
|
13816
13854
|
body;
|
|
@@ -13958,8 +13996,9 @@ async function writeConfigResult(config, targetPath, content, opts, meta = {}) {
|
|
|
13958
13996
|
throw new ConfigApplyError(`Antigravity rule file ${renderedTargetPath} is ${renderedContent.length} characters; split it before applying because Antigravity limits rule files to ${ANTIGRAVITY_RULE_FILE_CHAR_LIMIT} characters.`);
|
|
13959
13997
|
}
|
|
13960
13998
|
const path = expandPath(renderedTargetPath);
|
|
13999
|
+
const renderedForTarget = isCursorGlobalAuthorityPath(path) ? stampCursorGlobalAuthorityMarker(renderedContent) : renderedContent;
|
|
13961
14000
|
const previousContent = existsSync7(path) ? readFileSync5(path, "utf-8") : null;
|
|
13962
|
-
const changed = previousContent !==
|
|
14001
|
+
const changed = previousContent !== renderedForTarget;
|
|
13963
14002
|
if (!opts.dryRun) {
|
|
13964
14003
|
const dir = dirname4(path);
|
|
13965
14004
|
if (!existsSync7(dir)) {
|
|
@@ -13969,13 +14008,13 @@ async function writeConfigResult(config, targetPath, content, opts, meta = {}) {
|
|
|
13969
14008
|
const store = opts.store ?? resolveConfigStore();
|
|
13970
14009
|
await store.createSnapshot(config.id, previousContent, config.version);
|
|
13971
14010
|
}
|
|
13972
|
-
writeFileSync2(path,
|
|
14011
|
+
writeFileSync2(path, renderedForTarget, "utf-8");
|
|
13973
14012
|
}
|
|
13974
14013
|
return {
|
|
13975
14014
|
config_id: config.id,
|
|
13976
14015
|
path,
|
|
13977
14016
|
previous_content: previousContent,
|
|
13978
|
-
new_content:
|
|
14017
|
+
new_content: renderedForTarget,
|
|
13979
14018
|
dry_run: opts.dryRun ?? false,
|
|
13980
14019
|
changed,
|
|
13981
14020
|
primary_changed: changed,
|
|
@@ -14336,6 +14375,7 @@ var init_apply = __esm(() => {
|
|
|
14336
14375
|
init_redact();
|
|
14337
14376
|
init_template();
|
|
14338
14377
|
init_transforms();
|
|
14378
|
+
init_cursor_authority();
|
|
14339
14379
|
});
|
|
14340
14380
|
|
|
14341
14381
|
// src/lib/sync-dir.ts
|
|
@@ -18754,6 +18794,8 @@ sessionCmd.command("plan").description("Produce a dry-run render plan for profil
|
|
|
18754
18794
|
...planJsonForOutput(plan),
|
|
18755
18795
|
...globalCoverage ? { globalSourceCoverage: globalCoverage } : {}
|
|
18756
18796
|
});
|
|
18797
|
+
if (plan.blocked)
|
|
18798
|
+
process.exitCode = 1;
|
|
18757
18799
|
return;
|
|
18758
18800
|
}
|
|
18759
18801
|
console.log(chalk.bold(`${plan.tool} session render plan`) + chalk.dim(` (${plan.adapter.mode})`));
|
|
@@ -18780,6 +18822,8 @@ sessionCmd.command("plan").description("Produce a dry-run render plan for profil
|
|
|
18780
18822
|
if (globalCoverage.complete)
|
|
18781
18823
|
console.log(chalk.dim(`global source coverage: ${globalCoverage.expectedSlugs.length}/${globalCoverage.expectedSlugs.length} complete`));
|
|
18782
18824
|
}
|
|
18825
|
+
if (plan.blocked)
|
|
18826
|
+
process.exitCode = 1;
|
|
18783
18827
|
console.log(chalk.dim("Dry run only. No files were written."));
|
|
18784
18828
|
} catch (e) {
|
|
18785
18829
|
console.error(chalk.red(formatCliError(e)));
|
|
@@ -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;AAuC3C,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,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,uBAAuB,EACxB,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/index.js
CHANGED
|
@@ -8513,6 +8513,7 @@ var CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH = ".cursor/rules/hasna-global.mdc";
|
|
|
8513
8513
|
var CURSOR_GLOBAL_AUTHORITY_MAX_BYTES = 256 * 1024;
|
|
8514
8514
|
var CURSOR_GLOBAL_AUTHORITY_MANAGED_MARKER = "Managed by @hasna/configs cursor global authority";
|
|
8515
8515
|
var CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN = /^<!-- Managed by @hasna\/configs cursor global authority hash=(sha256:[a-f0-9]{64}) -->$/m;
|
|
8516
|
+
var CURSOR_GLOBAL_AUTHORITY_FRONTMATTER_PATTERN = /^---\n[\s\S]*?\n---(?:\n|$)/;
|
|
8516
8517
|
function sha2564(content) {
|
|
8517
8518
|
return createHash4("sha256").update(content).digest("hex");
|
|
8518
8519
|
}
|
|
@@ -8674,18 +8675,34 @@ function observeCursorGlobalAuthorityPath(authorityPath, readFile) {
|
|
|
8674
8675
|
return {
|
|
8675
8676
|
...base,
|
|
8676
8677
|
fileType,
|
|
8677
|
-
status: "
|
|
8678
|
+
status: "managed",
|
|
8678
8679
|
sha256: contentSha256,
|
|
8679
8680
|
markers,
|
|
8680
8681
|
markerSha256,
|
|
8681
8682
|
provenance: {
|
|
8682
8683
|
source: "filesystem",
|
|
8683
|
-
authority: "
|
|
8684
|
+
authority: "managed",
|
|
8684
8685
|
observedPath: authorityPath,
|
|
8685
|
-
detection: "
|
|
8686
|
+
detection: "managed-marker"
|
|
8686
8687
|
}
|
|
8687
8688
|
};
|
|
8688
8689
|
}
|
|
8690
|
+
function isCursorGlobalAuthorityPath(path) {
|
|
8691
|
+
return resolve3(path) === resolve3(join4(homeDir(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
|
|
8692
|
+
}
|
|
8693
|
+
function stampCursorGlobalAuthorityMarker(content) {
|
|
8694
|
+
if (CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN.test(content))
|
|
8695
|
+
return content;
|
|
8696
|
+
const digest = sha2564(content);
|
|
8697
|
+
const markerLine = `<!-- ${CURSOR_GLOBAL_AUTHORITY_MANAGED_MARKER} hash=sha256:${digest} -->`;
|
|
8698
|
+
const frontmatter = content.match(CURSOR_GLOBAL_AUTHORITY_FRONTMATTER_PATTERN)?.[0];
|
|
8699
|
+
if (frontmatter) {
|
|
8700
|
+
return `${frontmatter}${markerLine}
|
|
8701
|
+
${content.slice(frontmatter.length)}`;
|
|
8702
|
+
}
|
|
8703
|
+
return `${markerLine}
|
|
8704
|
+
${content}`;
|
|
8705
|
+
}
|
|
8689
8706
|
function detectCursorAuthorityConflicts(observation = observeCursorGlobalAuthority()) {
|
|
8690
8707
|
if (observation.status === "absent" || observation.status === "managed")
|
|
8691
8708
|
return [];
|
|
@@ -11663,7 +11680,17 @@ class CloudConfigStore {
|
|
|
11663
11680
|
return parseBoundedOrLegacyPage(data.configs, data.profile.configs, normalized, "profile membership");
|
|
11664
11681
|
}
|
|
11665
11682
|
async getProfileConfigBindings(idOrSlug) {
|
|
11666
|
-
const { data } = await this.requestProfileRoute(idOrSlug, (profileId) => `/profiles/${encodeURIComponent(profileId)}/bindings`, (value) => Array.isArray(value?.bindings));
|
|
11683
|
+
const { status, data } = await this.requestProfileRoute(idOrSlug, (profileId) => `/profiles/${encodeURIComponent(profileId)}/bindings`, (value) => Array.isArray(value?.bindings));
|
|
11684
|
+
if (status === 404) {
|
|
11685
|
+
const profile = await this.getProfile(idOrSlug);
|
|
11686
|
+
const configs = await this.getProfileConfigs(idOrSlug);
|
|
11687
|
+
return configs.map((config, sort_order) => ({
|
|
11688
|
+
profile_id: profile.id,
|
|
11689
|
+
config_id: config.id,
|
|
11690
|
+
sort_order,
|
|
11691
|
+
binding: legacyProfileConfigBinding()
|
|
11692
|
+
}));
|
|
11693
|
+
}
|
|
11667
11694
|
if (!data || !Array.isArray(data.bindings))
|
|
11668
11695
|
throw new ProfileNotFoundError(idOrSlug);
|
|
11669
11696
|
return data.bindings;
|
|
@@ -11675,8 +11702,11 @@ class CloudConfigStore {
|
|
|
11675
11702
|
return this.request("GET", pathForId(profileId), undefined, { allow404: true });
|
|
11676
11703
|
};
|
|
11677
11704
|
const first = await request(idOrSlug);
|
|
11678
|
-
if (first.status !== 404
|
|
11679
|
-
|
|
11705
|
+
if (first.status !== 404) {
|
|
11706
|
+
if (isUsable(first.data))
|
|
11707
|
+
return first;
|
|
11708
|
+
throw new CloudHttpError(502, "profile follow-up returned an invalid response", first.data);
|
|
11709
|
+
}
|
|
11680
11710
|
const profiles = await this.listProfiles();
|
|
11681
11711
|
const profile = profiles.find((candidate) => candidate.id === idOrSlug || candidate.slug === idOrSlug);
|
|
11682
11712
|
if (!profile)
|
|
@@ -11685,10 +11715,13 @@ class CloudConfigStore {
|
|
|
11685
11715
|
if (attempted.has(candidate))
|
|
11686
11716
|
continue;
|
|
11687
11717
|
const response = await request(candidate);
|
|
11688
|
-
if (response.status !== 404
|
|
11689
|
-
|
|
11718
|
+
if (response.status !== 404) {
|
|
11719
|
+
if (isUsable(response.data))
|
|
11720
|
+
return response;
|
|
11721
|
+
throw new CloudHttpError(502, "profile follow-up returned an invalid response", response.data);
|
|
11722
|
+
}
|
|
11690
11723
|
}
|
|
11691
|
-
|
|
11724
|
+
return { status: 404, data: null };
|
|
11692
11725
|
}
|
|
11693
11726
|
async createProfile(input) {
|
|
11694
11727
|
const { data } = await this.request("POST", "/profiles", input, {
|
|
@@ -11718,7 +11751,11 @@ class CloudConfigStore {
|
|
|
11718
11751
|
await this.request("DELETE", `/profiles/${encodeURIComponent(profileIdOrSlug)}/configs/${encodeURIComponent(configId)}`, undefined, { allow404: true });
|
|
11719
11752
|
}
|
|
11720
11753
|
async getProfileAssetBindings(profileIdOrSlug) {
|
|
11721
|
-
const { data } = await this.requestProfileRoute(profileIdOrSlug, (profileId) => `/profiles/${encodeURIComponent(profileId)}/assets`, (value) => Array.isArray(value?.assets));
|
|
11754
|
+
const { status, data } = await this.requestProfileRoute(profileIdOrSlug, (profileId) => `/profiles/${encodeURIComponent(profileId)}/assets`, (value) => Array.isArray(value?.assets));
|
|
11755
|
+
if (status === 404) {
|
|
11756
|
+
await this.getProfile(profileIdOrSlug);
|
|
11757
|
+
return [];
|
|
11758
|
+
}
|
|
11722
11759
|
if (!data || !Array.isArray(data.assets))
|
|
11723
11760
|
throw new ProfileNotFoundError(profileIdOrSlug);
|
|
11724
11761
|
return data.assets;
|
|
@@ -11937,8 +11974,9 @@ async function writeConfigResult(config, targetPath, content, opts, meta = {}) {
|
|
|
11937
11974
|
throw new ConfigApplyError(`Antigravity rule file ${renderedTargetPath} is ${renderedContent.length} characters; split it before applying because Antigravity limits rule files to ${ANTIGRAVITY_RULE_FILE_CHAR_LIMIT} characters.`);
|
|
11938
11975
|
}
|
|
11939
11976
|
const path = expandPath(renderedTargetPath);
|
|
11977
|
+
const renderedForTarget = isCursorGlobalAuthorityPath(path) ? stampCursorGlobalAuthorityMarker(renderedContent) : renderedContent;
|
|
11940
11978
|
const previousContent = existsSync6(path) ? readFileSync5(path, "utf-8") : null;
|
|
11941
|
-
const changed = previousContent !==
|
|
11979
|
+
const changed = previousContent !== renderedForTarget;
|
|
11942
11980
|
if (!opts.dryRun) {
|
|
11943
11981
|
const dir = dirname4(path);
|
|
11944
11982
|
if (!existsSync6(dir)) {
|
|
@@ -11948,13 +11986,13 @@ async function writeConfigResult(config, targetPath, content, opts, meta = {}) {
|
|
|
11948
11986
|
const store = opts.store ?? resolveConfigStore();
|
|
11949
11987
|
await store.createSnapshot(config.id, previousContent, config.version);
|
|
11950
11988
|
}
|
|
11951
|
-
writeFileSync2(path,
|
|
11989
|
+
writeFileSync2(path, renderedForTarget, "utf-8");
|
|
11952
11990
|
}
|
|
11953
11991
|
return {
|
|
11954
11992
|
config_id: config.id,
|
|
11955
11993
|
path,
|
|
11956
11994
|
previous_content: previousContent,
|
|
11957
|
-
new_content:
|
|
11995
|
+
new_content: renderedForTarget,
|
|
11958
11996
|
dry_run: opts.dryRun ?? false,
|
|
11959
11997
|
changed,
|
|
11960
11998
|
primary_changed: changed,
|
package/dist/lib/apply.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/lib/apply.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAA8B,MAAM,mBAAmB,CAAC;AAEzF,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAQ1D,OAAO,EAGL,yBAAyB,EAC1B,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/lib/apply.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAA8B,MAAM,mBAAmB,CAAC;AAEzF,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAQ1D,OAAO,EAGL,yBAAyB,EAC1B,MAAM,qBAAqB,CAAC;AAO7B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK5C;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAsBrD;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9B;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,yBAAyB,GAAG,2BAA2B,GAAG,yBAAyB,GAAG,+BAA+B,CAAC;IACpI,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,OAAO,EAAE,wBAAwB,EAAE,CAAC;IACpC,QAAQ,EAAE,yBAAyB,EAAE,CAAC;CACvC;AAyRD,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,WAAW,CAAC,CA+BtB;AA2ED,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,WAAW,EAAE,CAAC,CAMxB;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAiC7B;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,GAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAM,GACtC,OAAO,CAAC,kBAAkB,CAAC,CAE7B"}
|
|
@@ -44,11 +44,34 @@ export interface CursorAuthorityObservationOptions {
|
|
|
44
44
|
* Cursor reads this fixed global rule before project-scoped `.cursor/rules`
|
|
45
45
|
* files. The session renderer owns only the project-scoped files, so an
|
|
46
46
|
* unmanaged global rule is a second authority. A missing file is the clean
|
|
47
|
-
* case.
|
|
48
|
-
*
|
|
49
|
-
*
|
|
47
|
+
* case. The package's own apply path stamps every write to this path with
|
|
48
|
+
* {@link stampCursorGlobalAuthorityMarker}; a regular file carrying that
|
|
49
|
+
* marker with a matching payload hash is the package's own output and is
|
|
50
|
+
* accepted as managed. Everything else — foreign content, a tampered marker,
|
|
51
|
+
* a non-regular file — remains blocked, because the renderer cannot guess
|
|
52
|
+
* whether it conflicts with the managed project render.
|
|
50
53
|
*/
|
|
51
54
|
export declare function observeCursorGlobalAuthority(options?: CursorAuthorityObservationOptions): CursorAuthorityObservation;
|
|
52
55
|
export declare function observeCursorGlobalAuthorityAtPath(authorityPath: string): CursorAuthorityObservation;
|
|
56
|
+
/**
|
|
57
|
+
* Whether an expanded target path is the Cursor fixed global authority path
|
|
58
|
+
* under the current home. Used by the apply path to decide when to stamp the
|
|
59
|
+
* managed marker; the comparison mirrors {@link observeCursorGlobalAuthority}'s
|
|
60
|
+
* resolution so the writer and the observer always agree.
|
|
61
|
+
*/
|
|
62
|
+
export declare function isCursorGlobalAuthorityPath(path: string): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Stamp the managed marker onto content destined for the Cursor fixed global
|
|
65
|
+
* authority path. The marker carries the sha256 of the payload AFTER the
|
|
66
|
+
* marker line, which is exactly the payload the observer recomputes in
|
|
67
|
+
* {@link observeCursorGlobalAuthorityPath} — so a stamped file round-trips as
|
|
68
|
+
* managed. Cursor requires YAML frontmatter to start the file, so content that
|
|
69
|
+
* opens with a `---` frontmatter block is stamped AFTER the closing `---`,
|
|
70
|
+
* matching how the package's own session-render cursor files place their
|
|
71
|
+
* managed marker; plain content without frontmatter is stamped at the top.
|
|
72
|
+
* Content that already carries a valid marker anywhere is returned unchanged
|
|
73
|
+
* (idempotent re-apply).
|
|
74
|
+
*/
|
|
75
|
+
export declare function stampCursorGlobalAuthorityMarker(content: string): string;
|
|
53
76
|
export declare function detectCursorAuthorityConflicts(observation?: CursorAuthorityObservation): CursorAuthorityConflict[];
|
|
54
77
|
//# sourceMappingURL=cursor-authority.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor-authority.d.ts","sourceRoot":"","sources":["../../src/lib/cursor-authority.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,qCAAqC,mCAAmC,CAAC;AACtF,eAAO,MAAM,iCAAiC,QAAa,CAAC;AAC5D,eAAO,MAAM,sCAAsC,sDAAsD,CAAC;
|
|
1
|
+
{"version":3,"file":"cursor-authority.d.ts","sourceRoot":"","sources":["../../src/lib/cursor-authority.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,qCAAqC,mCAAmC,CAAC;AACtF,eAAO,MAAM,iCAAiC,QAAa,CAAC;AAC5D,eAAO,MAAM,sCAAsC,sDAAsD,CAAC;AAQ1G,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,CAAC;AAChG,MAAM,MAAM,gCAAgC,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAC9F,MAAM,MAAM,wBAAwB,GAChC,SAAS,GACT,gBAAgB,GAChB,iBAAiB,GACjB,2BAA2B,GAC3B,kBAAkB,GAClB,gBAAgB,GAChB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,QAAQ,CAAC;IACf,YAAY,EAAE,OAAO,qCAAqC,CAAC;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,uBAAuB,CAAC;IAClC,MAAM,EAAE,gCAAgC,CAAC;IACzC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE;QACV,MAAM,EAAE,YAAY,CAAC;QACrB,SAAS,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;QAC9C,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,wBAAwB,CAAC;KACrC,CAAC;CACH;AAED,MAAM,MAAM,2BAA2B,GACnC,6BAA6B,GAC7B,6BAA6B,CAAC;AAElC,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,QAAQ,CAAC;IACf,YAAY,EAAE,OAAO,qCAAqC,CAAC;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,2BAA2B,CAAC;IAClC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE;QACV,MAAM,EAAE,YAAY,CAAC;QACrB,SAAS,EAAE,WAAW,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,OAAO,CAAC,wBAAwB,EAAE,SAAS,GAAG,gBAAgB,CAAC,CAAC;KAC5E,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iCAAiC;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACrC;AAyBD;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,GAAE,iCAAsC,GAC9C,0BAA0B,CAI5B;AAED,wBAAgB,kCAAkC,CAChD,aAAa,EAAE,MAAM,GACpB,0BAA0B,CAK5B;AAoKD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CASxE;AAED,wBAAgB,8BAA8B,CAC5C,WAAW,6BAAiC,GAC3C,uBAAuB,EAAE,CAsB3B"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -5602,9 +5602,36 @@ var init_asset_plan = __esm(() => {
|
|
|
5602
5602
|
});
|
|
5603
5603
|
|
|
5604
5604
|
// src/lib/cursor-authority.ts
|
|
5605
|
-
|
|
5605
|
+
import { createHash } from "crypto";
|
|
5606
|
+
import { homedir as homedir2 } from "os";
|
|
5607
|
+
import { join as join4, resolve as resolve2 } from "path";
|
|
5608
|
+
function sha256(content) {
|
|
5609
|
+
return createHash("sha256").update(content).digest("hex");
|
|
5610
|
+
}
|
|
5611
|
+
function homeDir() {
|
|
5612
|
+
return process.env["HOME"] || homedir2();
|
|
5613
|
+
}
|
|
5614
|
+
function isCursorGlobalAuthorityPath(path) {
|
|
5615
|
+
return resolve2(path) === resolve2(join4(homeDir(), CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH));
|
|
5616
|
+
}
|
|
5617
|
+
function stampCursorGlobalAuthorityMarker(content) {
|
|
5618
|
+
if (CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN.test(content))
|
|
5619
|
+
return content;
|
|
5620
|
+
const digest = sha256(content);
|
|
5621
|
+
const markerLine = `<!-- ${CURSOR_GLOBAL_AUTHORITY_MANAGED_MARKER} hash=sha256:${digest} -->`;
|
|
5622
|
+
const frontmatter = content.match(CURSOR_GLOBAL_AUTHORITY_FRONTMATTER_PATTERN)?.[0];
|
|
5623
|
+
if (frontmatter) {
|
|
5624
|
+
return `${frontmatter}${markerLine}
|
|
5625
|
+
${content.slice(frontmatter.length)}`;
|
|
5626
|
+
}
|
|
5627
|
+
return `${markerLine}
|
|
5628
|
+
${content}`;
|
|
5629
|
+
}
|
|
5630
|
+
var CURSOR_GLOBAL_AUTHORITY_RELATIVE_PATH = ".cursor/rules/hasna-global.mdc", CURSOR_GLOBAL_AUTHORITY_MAX_BYTES, CURSOR_GLOBAL_AUTHORITY_MANAGED_MARKER = "Managed by @hasna/configs cursor global authority", CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN, CURSOR_GLOBAL_AUTHORITY_FRONTMATTER_PATTERN;
|
|
5606
5631
|
var init_cursor_authority = __esm(() => {
|
|
5607
5632
|
CURSOR_GLOBAL_AUTHORITY_MAX_BYTES = 256 * 1024;
|
|
5633
|
+
CURSOR_GLOBAL_AUTHORITY_MARKER_PATTERN = /^<!-- Managed by @hasna\/configs cursor global authority hash=(sha256:[a-f0-9]{64}) -->$/m;
|
|
5634
|
+
CURSOR_GLOBAL_AUTHORITY_FRONTMATTER_PATTERN = /^---\n[\s\S]*?\n---(?:\n|$)/;
|
|
5608
5635
|
});
|
|
5609
5636
|
|
|
5610
5637
|
// src/lib/session-render.ts
|
|
@@ -6608,7 +6635,17 @@ class CloudConfigStore {
|
|
|
6608
6635
|
return parseBoundedOrLegacyPage(data.configs, data.profile.configs, normalized, "profile membership");
|
|
6609
6636
|
}
|
|
6610
6637
|
async getProfileConfigBindings(idOrSlug) {
|
|
6611
|
-
const { data } = await this.requestProfileRoute(idOrSlug, (profileId) => `/profiles/${encodeURIComponent(profileId)}/bindings`, (value) => Array.isArray(value?.bindings));
|
|
6638
|
+
const { status, data } = await this.requestProfileRoute(idOrSlug, (profileId) => `/profiles/${encodeURIComponent(profileId)}/bindings`, (value) => Array.isArray(value?.bindings));
|
|
6639
|
+
if (status === 404) {
|
|
6640
|
+
const profile = await this.getProfile(idOrSlug);
|
|
6641
|
+
const configs = await this.getProfileConfigs(idOrSlug);
|
|
6642
|
+
return configs.map((config, sort_order) => ({
|
|
6643
|
+
profile_id: profile.id,
|
|
6644
|
+
config_id: config.id,
|
|
6645
|
+
sort_order,
|
|
6646
|
+
binding: legacyProfileConfigBinding()
|
|
6647
|
+
}));
|
|
6648
|
+
}
|
|
6612
6649
|
if (!data || !Array.isArray(data.bindings))
|
|
6613
6650
|
throw new ProfileNotFoundError(idOrSlug);
|
|
6614
6651
|
return data.bindings;
|
|
@@ -6620,8 +6657,11 @@ class CloudConfigStore {
|
|
|
6620
6657
|
return this.request("GET", pathForId(profileId), undefined, { allow404: true });
|
|
6621
6658
|
};
|
|
6622
6659
|
const first = await request(idOrSlug);
|
|
6623
|
-
if (first.status !== 404
|
|
6624
|
-
|
|
6660
|
+
if (first.status !== 404) {
|
|
6661
|
+
if (isUsable(first.data))
|
|
6662
|
+
return first;
|
|
6663
|
+
throw new CloudHttpError(502, "profile follow-up returned an invalid response", first.data);
|
|
6664
|
+
}
|
|
6625
6665
|
const profiles = await this.listProfiles();
|
|
6626
6666
|
const profile = profiles.find((candidate) => candidate.id === idOrSlug || candidate.slug === idOrSlug);
|
|
6627
6667
|
if (!profile)
|
|
@@ -6630,10 +6670,13 @@ class CloudConfigStore {
|
|
|
6630
6670
|
if (attempted.has(candidate))
|
|
6631
6671
|
continue;
|
|
6632
6672
|
const response = await request(candidate);
|
|
6633
|
-
if (response.status !== 404
|
|
6634
|
-
|
|
6673
|
+
if (response.status !== 404) {
|
|
6674
|
+
if (isUsable(response.data))
|
|
6675
|
+
return response;
|
|
6676
|
+
throw new CloudHttpError(502, "profile follow-up returned an invalid response", response.data);
|
|
6677
|
+
}
|
|
6635
6678
|
}
|
|
6636
|
-
|
|
6679
|
+
return { status: 404, data: null };
|
|
6637
6680
|
}
|
|
6638
6681
|
async createProfile(input) {
|
|
6639
6682
|
const { data } = await this.request("POST", "/profiles", input, {
|
|
@@ -6663,7 +6706,11 @@ class CloudConfigStore {
|
|
|
6663
6706
|
await this.request("DELETE", `/profiles/${encodeURIComponent(profileIdOrSlug)}/configs/${encodeURIComponent(configId)}`, undefined, { allow404: true });
|
|
6664
6707
|
}
|
|
6665
6708
|
async getProfileAssetBindings(profileIdOrSlug) {
|
|
6666
|
-
const { data } = await this.requestProfileRoute(profileIdOrSlug, (profileId) => `/profiles/${encodeURIComponent(profileId)}/assets`, (value) => Array.isArray(value?.assets));
|
|
6709
|
+
const { status, data } = await this.requestProfileRoute(profileIdOrSlug, (profileId) => `/profiles/${encodeURIComponent(profileId)}/assets`, (value) => Array.isArray(value?.assets));
|
|
6710
|
+
if (status === 404) {
|
|
6711
|
+
await this.getProfile(profileIdOrSlug);
|
|
6712
|
+
return [];
|
|
6713
|
+
}
|
|
6667
6714
|
if (!data || !Array.isArray(data.assets))
|
|
6668
6715
|
throw new ProfileNotFoundError(profileIdOrSlug);
|
|
6669
6716
|
return data.assets;
|
|
@@ -6764,6 +6811,7 @@ var init_config_store = __esm(() => {
|
|
|
6764
6811
|
init_database();
|
|
6765
6812
|
init_types();
|
|
6766
6813
|
init_bounded_read();
|
|
6814
|
+
init_instruction_graph();
|
|
6767
6815
|
CloudHttpError = class CloudHttpError extends Error {
|
|
6768
6816
|
status;
|
|
6769
6817
|
body;
|
|
@@ -6778,7 +6826,7 @@ var init_config_store = __esm(() => {
|
|
|
6778
6826
|
|
|
6779
6827
|
// src/lib/session-render-ownership.ts
|
|
6780
6828
|
import { existsSync as existsSync3, readFileSync, statSync } from "fs";
|
|
6781
|
-
import { dirname as dirname2, join as
|
|
6829
|
+
import { dirname as dirname2, join as join5, parse as parse2, relative as relative2, sep } from "path";
|
|
6782
6830
|
function toSegments(absolutePath2) {
|
|
6783
6831
|
return absolutePath2.replaceAll("\\", "/").split("/").filter(Boolean);
|
|
6784
6832
|
}
|
|
@@ -6826,7 +6874,7 @@ function sessionRenderManifestClaimsPath(absolutePath2) {
|
|
|
6826
6874
|
const root = parse2(absolutePath2).root;
|
|
6827
6875
|
let home = dirname2(absolutePath2);
|
|
6828
6876
|
for (let depth = 0;depth < MANIFEST_ANCESTOR_LIMIT; depth += 1) {
|
|
6829
|
-
const manifestPath =
|
|
6877
|
+
const manifestPath = join5(home, ...SESSION_RENDER_MANIFEST_RELATIVE_PATH.split("/"));
|
|
6830
6878
|
const relativePaths = readManifestRelativePaths(manifestPath);
|
|
6831
6879
|
if (relativePaths) {
|
|
6832
6880
|
const claimed = relative2(home, absolutePath2).split(sep).join("/");
|
|
@@ -6862,16 +6910,16 @@ __export(exports_apply, {
|
|
|
6862
6910
|
applyConfig: () => applyConfig
|
|
6863
6911
|
});
|
|
6864
6912
|
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync2, realpathSync, writeFileSync } from "fs";
|
|
6865
|
-
import { basename as basename3, dirname as dirname3, join as
|
|
6866
|
-
import { homedir as
|
|
6913
|
+
import { basename as basename3, dirname as dirname3, join as join6, resolve as resolve3 } from "path";
|
|
6914
|
+
import { homedir as homedir3 } from "os";
|
|
6867
6915
|
function getConfigHome() {
|
|
6868
|
-
return process.env["CONFIGS_HOME"] || process.env["HOME"] ||
|
|
6916
|
+
return process.env["CONFIGS_HOME"] || process.env["HOME"] || homedir3();
|
|
6869
6917
|
}
|
|
6870
6918
|
function expandPath(p) {
|
|
6871
6919
|
if (p.startsWith("~/")) {
|
|
6872
|
-
return
|
|
6920
|
+
return resolve3(getConfigHome(), p.slice(2));
|
|
6873
6921
|
}
|
|
6874
|
-
return
|
|
6922
|
+
return resolve3(p);
|
|
6875
6923
|
}
|
|
6876
6924
|
function normalizeTargetPath(p) {
|
|
6877
6925
|
const expanded = expandPath(p);
|
|
@@ -6883,7 +6931,7 @@ function normalizeTargetPath(p) {
|
|
|
6883
6931
|
while (true) {
|
|
6884
6932
|
if (existsSync4(current)) {
|
|
6885
6933
|
try {
|
|
6886
|
-
return
|
|
6934
|
+
return resolve3(realpathSync(current), ...missingSegments);
|
|
6887
6935
|
} catch {
|
|
6888
6936
|
return expanded;
|
|
6889
6937
|
}
|
|
@@ -6911,8 +6959,9 @@ async function writeConfigResult(config, targetPath, content, opts, meta = {}) {
|
|
|
6911
6959
|
throw new ConfigApplyError(`Antigravity rule file ${renderedTargetPath} is ${renderedContent.length} characters; split it before applying because Antigravity limits rule files to ${ANTIGRAVITY_RULE_FILE_CHAR_LIMIT} characters.`);
|
|
6912
6960
|
}
|
|
6913
6961
|
const path = expandPath(renderedTargetPath);
|
|
6962
|
+
const renderedForTarget = isCursorGlobalAuthorityPath(path) ? stampCursorGlobalAuthorityMarker(renderedContent) : renderedContent;
|
|
6914
6963
|
const previousContent = existsSync4(path) ? readFileSync2(path, "utf-8") : null;
|
|
6915
|
-
const changed = previousContent !==
|
|
6964
|
+
const changed = previousContent !== renderedForTarget;
|
|
6916
6965
|
if (!opts.dryRun) {
|
|
6917
6966
|
const dir = dirname3(path);
|
|
6918
6967
|
if (!existsSync4(dir)) {
|
|
@@ -6922,13 +6971,13 @@ async function writeConfigResult(config, targetPath, content, opts, meta = {}) {
|
|
|
6922
6971
|
const store = opts.store ?? resolveConfigStore();
|
|
6923
6972
|
await store.createSnapshot(config.id, previousContent, config.version);
|
|
6924
6973
|
}
|
|
6925
|
-
writeFileSync(path,
|
|
6974
|
+
writeFileSync(path, renderedForTarget, "utf-8");
|
|
6926
6975
|
}
|
|
6927
6976
|
return {
|
|
6928
6977
|
config_id: config.id,
|
|
6929
6978
|
path,
|
|
6930
6979
|
previous_content: previousContent,
|
|
6931
|
-
new_content:
|
|
6980
|
+
new_content: renderedForTarget,
|
|
6932
6981
|
dry_run: opts.dryRun ?? false,
|
|
6933
6982
|
changed,
|
|
6934
6983
|
primary_changed: changed,
|
|
@@ -7275,7 +7324,7 @@ function sessionRendererOwnsCanonicalTarget(normalized, opts) {
|
|
|
7275
7324
|
getConfigHome(),
|
|
7276
7325
|
opts.vars?.["HOME_DIR"]
|
|
7277
7326
|
].filter((home) => typeof home === "string" && home.length > 0));
|
|
7278
|
-
if ([...homes].some((home) => SESSION_RENDER_OWNED_CONFIG_TARGETS.some((relativePath) => normalized === normalizeTargetPath(
|
|
7327
|
+
if ([...homes].some((home) => SESSION_RENDER_OWNED_CONFIG_TARGETS.some((relativePath) => normalized === normalizeTargetPath(join6(home, ...relativePath.split("/"))))))
|
|
7279
7328
|
return true;
|
|
7280
7329
|
return sessionRenderOwnsPath(normalized);
|
|
7281
7330
|
}
|
|
@@ -7289,6 +7338,7 @@ var init_apply = __esm(() => {
|
|
|
7289
7338
|
init_redact();
|
|
7290
7339
|
init_template();
|
|
7291
7340
|
init_transforms();
|
|
7341
|
+
init_cursor_authority();
|
|
7292
7342
|
});
|
|
7293
7343
|
|
|
7294
7344
|
// src/lib/sync.ts
|
|
@@ -7308,7 +7358,7 @@ __export(exports_sync, {
|
|
|
7308
7358
|
CLAUDE_PROMPT_OUTPUTS: () => CLAUDE_PROMPT_OUTPUTS
|
|
7309
7359
|
});
|
|
7310
7360
|
import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync3 } from "fs";
|
|
7311
|
-
import { basename as basename4, extname as extname2, join as
|
|
7361
|
+
import { basename as basename4, extname as extname2, join as join7 } from "path";
|
|
7312
7362
|
function claudeRuleOutputs(fileName) {
|
|
7313
7363
|
const stem = basename4(fileName, extname2(fileName));
|
|
7314
7364
|
return [
|
|
@@ -7372,7 +7422,7 @@ async function syncProject(opts) {
|
|
|
7372
7422
|
const allConfigs = await store.listConfigs();
|
|
7373
7423
|
const machine = detectMachineContext();
|
|
7374
7424
|
for (const pf of PROJECT_CONFIG_FILES) {
|
|
7375
|
-
const abs =
|
|
7425
|
+
const abs = join7(absDir, pf.file);
|
|
7376
7426
|
if (!existsSync5(abs))
|
|
7377
7427
|
continue;
|
|
7378
7428
|
try {
|
|
@@ -7405,19 +7455,19 @@ async function syncProject(opts) {
|
|
|
7405
7455
|
}
|
|
7406
7456
|
}
|
|
7407
7457
|
for (const ruleDir of [
|
|
7408
|
-
{ dir:
|
|
7409
|
-
{ dir:
|
|
7410
|
-
{ dir:
|
|
7411
|
-
{ dir:
|
|
7412
|
-
{ dir:
|
|
7413
|
-
{ dir:
|
|
7414
|
-
{ dir:
|
|
7458
|
+
{ dir: join7(absDir, ".claude", "rules"), agent: "claude", namePrefix: "rules" },
|
|
7459
|
+
{ dir: join7(absDir, ".agents", "rules"), agent: "antigravity", namePrefix: "antigravity-rules" },
|
|
7460
|
+
{ dir: join7(absDir, ".cursor", "rules"), agent: "cursor", namePrefix: "cursor-rules" },
|
|
7461
|
+
{ dir: join7(absDir, ".github", "instructions"), agent: "copilot", namePrefix: "copilot-instructions" },
|
|
7462
|
+
{ dir: join7(absDir, ".devin", "rules"), agent: "devin", namePrefix: "devin-rules" },
|
|
7463
|
+
{ dir: join7(absDir, ".windsurf", "rules"), agent: "windsurf-legacy", namePrefix: "windsurf-rules" },
|
|
7464
|
+
{ dir: join7(absDir, ".clinerules"), agent: "cline", namePrefix: "cline-rules" }
|
|
7415
7465
|
]) {
|
|
7416
7466
|
if (!existsSync5(ruleDir.dir))
|
|
7417
7467
|
continue;
|
|
7418
7468
|
const mdFiles = readdirSync(ruleDir.dir).filter((f) => f.endsWith(".md") || f.endsWith(".mdc"));
|
|
7419
7469
|
for (const f of mdFiles) {
|
|
7420
|
-
const abs =
|
|
7470
|
+
const abs = join7(ruleDir.dir, f);
|
|
7421
7471
|
const raw = readFileSync3(abs, "utf-8");
|
|
7422
7472
|
const redacted = redactContent(raw, "markdown");
|
|
7423
7473
|
const machineAware = templateizeMachineContent(redacted.content, machine);
|
|
@@ -7464,7 +7514,7 @@ async function syncKnown(opts = {}) {
|
|
|
7464
7514
|
const extensions = known.rulesExtensions ?? [".md", ".mdc"];
|
|
7465
7515
|
const ruleFiles = readdirSync(absDir).filter((f) => extensions.some((ext) => f.endsWith(ext)));
|
|
7466
7516
|
for (const f of ruleFiles) {
|
|
7467
|
-
const abs2 =
|
|
7517
|
+
const abs2 = join7(absDir, f);
|
|
7468
7518
|
const targetPath = abs2.replace(home, "~");
|
|
7469
7519
|
if (existingOutputOwners.has(normalizeTargetPath(targetPath)) || isKnownGeneratedTargetPath(targetPath)) {
|
|
7470
7520
|
result.skipped.push(`${targetPath} (generated output)`);
|
|
@@ -7835,8 +7885,8 @@ var init_sync = __esm(() => {
|
|
|
7835
7885
|
|
|
7836
7886
|
// src/lib/sync-dir.ts
|
|
7837
7887
|
import { existsSync as existsSync6, readdirSync as readdirSync2, readFileSync as readFileSync4, statSync as statSync2 } from "fs";
|
|
7838
|
-
import { join as
|
|
7839
|
-
import { homedir as
|
|
7888
|
+
import { join as join8, relative as relative3 } from "path";
|
|
7889
|
+
import { homedir as homedir4 } from "os";
|
|
7840
7890
|
function shouldSkip(p) {
|
|
7841
7891
|
return SKIP.some((s) => p.includes(s));
|
|
7842
7892
|
}
|
|
@@ -7845,9 +7895,9 @@ async function syncFromDir(dir, opts = {}) {
|
|
|
7845
7895
|
const absDir = expandPath(dir);
|
|
7846
7896
|
if (!existsSync6(absDir))
|
|
7847
7897
|
return { added: 0, updated: 0, unchanged: 0, skipped: [`Not found: ${absDir}`] };
|
|
7848
|
-
const files = opts.recursive !== false ? walkDir(absDir) : readdirSync2(absDir).map((f) =>
|
|
7898
|
+
const files = opts.recursive !== false ? walkDir(absDir) : readdirSync2(absDir).map((f) => join8(absDir, f)).filter((f) => statSync2(f).isFile());
|
|
7849
7899
|
const result = { added: 0, updated: 0, unchanged: 0, skipped: [] };
|
|
7850
|
-
const home =
|
|
7900
|
+
const home = homedir4();
|
|
7851
7901
|
const allConfigs = await store.listConfigs();
|
|
7852
7902
|
for (const file of files) {
|
|
7853
7903
|
if (shouldSkip(file)) {
|
|
@@ -7881,7 +7931,7 @@ async function syncFromDir(dir, opts = {}) {
|
|
|
7881
7931
|
}
|
|
7882
7932
|
async function syncToDir(dir, opts = {}) {
|
|
7883
7933
|
const store = opts.store ?? resolveConfigStore();
|
|
7884
|
-
const home =
|
|
7934
|
+
const home = homedir4();
|
|
7885
7935
|
const absDir = expandPath(dir);
|
|
7886
7936
|
const normalized = dir.startsWith("~/") ? dir : absDir.replace(home, "~");
|
|
7887
7937
|
const configs = (await store.listConfigs()).filter((c) => c.target_path && (c.target_path.startsWith(normalized) || c.target_path.startsWith(absDir)));
|
|
@@ -7905,7 +7955,7 @@ async function syncToDir(dir, opts = {}) {
|
|
|
7905
7955
|
}
|
|
7906
7956
|
function walkDir(dir, files = []) {
|
|
7907
7957
|
for (const entry of readdirSync2(dir, { withFileTypes: true })) {
|
|
7908
|
-
const full =
|
|
7958
|
+
const full = join8(dir, entry.name);
|
|
7909
7959
|
if (shouldSkip(full))
|
|
7910
7960
|
continue;
|
|
7911
7961
|
if (entry.isDirectory())
|
|
@@ -7927,7 +7977,7 @@ var init_sync_dir = __esm(() => {
|
|
|
7927
7977
|
var require_package = __commonJS((exports, module) => {
|
|
7928
7978
|
module.exports = {
|
|
7929
7979
|
name: "@hasna/instructions",
|
|
7930
|
-
version: "0.4.
|
|
7980
|
+
version: "0.4.34",
|
|
7931
7981
|
description: "AI coding agent instruction & configuration manager \u2014 store, version, apply, and share all your AI coding configs. CLI + MCP + HTTP API (instructions-serve) + generated SDK + Dashboard.",
|
|
7932
7982
|
type: "module",
|
|
7933
7983
|
main: "dist/index.js",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/instructions",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.34",
|
|
4
4
|
"description": "AI coding agent instruction & configuration manager \u2014 store, version, apply, and share all your AI coding configs. CLI + MCP + HTTP API (instructions-serve) + generated SDK + Dashboard.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|