@hasna/skills 0.10.11 → 0.10.14
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/bin/index.js +203 -9
- package/bin/maintenance.js +226 -1044
- package/bin/mcp.js +1 -1
- package/bin/migrate.js +1 -1
- package/bin/server.js +9 -7
- package/bin/worker.js +9 -7
- package/dist/index.js +200 -5
- package/dist/lib/agent-codex.d.ts +7 -3
- package/dist/lib/agent-integration.d.ts +1 -0
- package/dist/lib/codex-hook-rpc.d.ts +1 -1
- package/dist/sdk/index.js +208 -11
- package/dist/server/enrollment-inspection.d.ts +26 -0
- package/dist/server/maintenance-entry.d.ts +13 -0
- package/dist/server/store.d.ts +9 -1
- package/package.json +1 -1
package/bin/mcp.js
CHANGED
|
@@ -20019,7 +20019,7 @@ var package_default;
|
|
|
20019
20019
|
var init_package = __esm(() => {
|
|
20020
20020
|
package_default = {
|
|
20021
20021
|
name: "@hasna/skills",
|
|
20022
|
-
version: "0.10.
|
|
20022
|
+
version: "0.10.14",
|
|
20023
20023
|
description: "Skills library for AI coding agents",
|
|
20024
20024
|
type: "module",
|
|
20025
20025
|
bin: {
|
package/bin/migrate.js
CHANGED
package/bin/server.js
CHANGED
|
@@ -24122,7 +24122,7 @@ var init_dist_es9 = __esm(() => {
|
|
|
24122
24122
|
// package.json
|
|
24123
24123
|
var package_default = {
|
|
24124
24124
|
name: "@hasna/skills",
|
|
24125
|
-
version: "0.10.
|
|
24125
|
+
version: "0.10.14",
|
|
24126
24126
|
description: "Skills library for AI coding agents",
|
|
24127
24127
|
type: "module",
|
|
24128
24128
|
bin: {
|
|
@@ -43384,9 +43384,9 @@ class PostgresSkillsStore {
|
|
|
43384
43384
|
}
|
|
43385
43385
|
backend = { kind: "postgres", durable: true, label: "postgres" };
|
|
43386
43386
|
sql;
|
|
43387
|
-
constructor(databaseUrl) {
|
|
43387
|
+
constructor(databaseUrl, connectionOptions = {}) {
|
|
43388
43388
|
const bunWithSql = Bun;
|
|
43389
|
-
this.sql = new bunWithSql.SQL(databaseUrl, { max: resolvePoolMax() });
|
|
43389
|
+
this.sql = new bunWithSql.SQL(databaseUrl, { max: resolvePoolMax(), ...connectionOptions });
|
|
43390
43390
|
}
|
|
43391
43391
|
async verifyConnectivity() {
|
|
43392
43392
|
try {
|
|
@@ -43481,7 +43481,7 @@ class PostgresSkillsStore {
|
|
|
43481
43481
|
}
|
|
43482
43482
|
await tx`
|
|
43483
43483
|
INSERT INTO skills_audit_events (org_id, user_id, api_key_id, action, target_type, target_id, metadata_json)
|
|
43484
|
-
VALUES (${actor.orgId}, ${actor.userId}, ${actor.apiKeyId}, ${"api_key_scopes_added"}, ${"api_key"}, ${keyId}, ${JSON.stringify({ added: addScopes, scopes: parseJsonArray(updated[0].scopes_json) })}::jsonb)
|
|
43484
|
+
VALUES (${actor.orgId}, ${actor.userId}, ${actor.apiKeyId}, ${"api_key_scopes_added"}, ${"api_key"}, ${keyId}, ${JSON.stringify({ added: addScopes, scopes: parseJsonArray(updated[0].scopes_json) })}::text::jsonb)
|
|
43485
43485
|
`;
|
|
43486
43486
|
return { kind: "updated", scopes: parseJsonArray(updated[0].scopes_json) };
|
|
43487
43487
|
});
|
|
@@ -43489,10 +43489,12 @@ class PostgresSkillsStore {
|
|
|
43489
43489
|
async casUpdateApiKeyScopes(tx, keyId, orgId, expectedScopes, addScopes) {
|
|
43490
43490
|
const current = expectedScopes;
|
|
43491
43491
|
const scopes = [...current, ...addScopes.filter((scope2) => !current.includes(scope2))];
|
|
43492
|
+
const expectedScopesJson = JSON.stringify(expectedScopes);
|
|
43492
43493
|
return tx`
|
|
43493
|
-
UPDATE api_keys SET scopes_json = ${JSON.stringify(scopes)}::jsonb
|
|
43494
|
+
UPDATE api_keys SET scopes_json = ${JSON.stringify(scopes)}::text::jsonb
|
|
43494
43495
|
WHERE id = ${keyId} AND org_id = ${orgId} AND revoked_at IS NULL
|
|
43495
|
-
AND scopes_json = ${
|
|
43496
|
+
AND (scopes_json = ${expectedScopesJson}::text::jsonb
|
|
43497
|
+
OR scopes_json = to_jsonb(${expectedScopesJson}::text))
|
|
43496
43498
|
RETURNING scopes_json
|
|
43497
43499
|
`;
|
|
43498
43500
|
}
|
|
@@ -43552,7 +43554,7 @@ class PostgresSkillsStore {
|
|
|
43552
43554
|
operator_task_arn: input.operatorTaskArn,
|
|
43553
43555
|
target_manifest_digest: input.manifestDigest,
|
|
43554
43556
|
station_id: input.stationId
|
|
43555
|
-
})}::jsonb)
|
|
43557
|
+
})}::text::jsonb)
|
|
43556
43558
|
`;
|
|
43557
43559
|
return { kind: "updated", scopes };
|
|
43558
43560
|
});
|
package/bin/worker.js
CHANGED
|
@@ -24125,7 +24125,7 @@ import { randomUUID as randomUUID6 } from "crypto";
|
|
|
24125
24125
|
// package.json
|
|
24126
24126
|
var package_default = {
|
|
24127
24127
|
name: "@hasna/skills",
|
|
24128
|
-
version: "0.10.
|
|
24128
|
+
version: "0.10.14",
|
|
24129
24129
|
description: "Skills library for AI coding agents",
|
|
24130
24130
|
type: "module",
|
|
24131
24131
|
bin: {
|
|
@@ -36913,9 +36913,9 @@ class PostgresSkillsStore {
|
|
|
36913
36913
|
}
|
|
36914
36914
|
backend = { kind: "postgres", durable: true, label: "postgres" };
|
|
36915
36915
|
sql;
|
|
36916
|
-
constructor(databaseUrl) {
|
|
36916
|
+
constructor(databaseUrl, connectionOptions = {}) {
|
|
36917
36917
|
const bunWithSql = Bun;
|
|
36918
|
-
this.sql = new bunWithSql.SQL(databaseUrl, { max: resolvePoolMax() });
|
|
36918
|
+
this.sql = new bunWithSql.SQL(databaseUrl, { max: resolvePoolMax(), ...connectionOptions });
|
|
36919
36919
|
}
|
|
36920
36920
|
async verifyConnectivity() {
|
|
36921
36921
|
try {
|
|
@@ -37010,7 +37010,7 @@ class PostgresSkillsStore {
|
|
|
37010
37010
|
}
|
|
37011
37011
|
await tx`
|
|
37012
37012
|
INSERT INTO skills_audit_events (org_id, user_id, api_key_id, action, target_type, target_id, metadata_json)
|
|
37013
|
-
VALUES (${actor.orgId}, ${actor.userId}, ${actor.apiKeyId}, ${"api_key_scopes_added"}, ${"api_key"}, ${keyId}, ${JSON.stringify({ added: addScopes, scopes: parseJsonArray(updated[0].scopes_json) })}::jsonb)
|
|
37013
|
+
VALUES (${actor.orgId}, ${actor.userId}, ${actor.apiKeyId}, ${"api_key_scopes_added"}, ${"api_key"}, ${keyId}, ${JSON.stringify({ added: addScopes, scopes: parseJsonArray(updated[0].scopes_json) })}::text::jsonb)
|
|
37014
37014
|
`;
|
|
37015
37015
|
return { kind: "updated", scopes: parseJsonArray(updated[0].scopes_json) };
|
|
37016
37016
|
});
|
|
@@ -37018,10 +37018,12 @@ class PostgresSkillsStore {
|
|
|
37018
37018
|
async casUpdateApiKeyScopes(tx, keyId, orgId, expectedScopes, addScopes) {
|
|
37019
37019
|
const current = expectedScopes;
|
|
37020
37020
|
const scopes = [...current, ...addScopes.filter((scope) => !current.includes(scope))];
|
|
37021
|
+
const expectedScopesJson = JSON.stringify(expectedScopes);
|
|
37021
37022
|
return tx`
|
|
37022
|
-
UPDATE api_keys SET scopes_json = ${JSON.stringify(scopes)}::jsonb
|
|
37023
|
+
UPDATE api_keys SET scopes_json = ${JSON.stringify(scopes)}::text::jsonb
|
|
37023
37024
|
WHERE id = ${keyId} AND org_id = ${orgId} AND revoked_at IS NULL
|
|
37024
|
-
AND scopes_json = ${
|
|
37025
|
+
AND (scopes_json = ${expectedScopesJson}::text::jsonb
|
|
37026
|
+
OR scopes_json = to_jsonb(${expectedScopesJson}::text))
|
|
37025
37027
|
RETURNING scopes_json
|
|
37026
37028
|
`;
|
|
37027
37029
|
}
|
|
@@ -37081,7 +37083,7 @@ class PostgresSkillsStore {
|
|
|
37081
37083
|
operator_task_arn: input.operatorTaskArn,
|
|
37082
37084
|
target_manifest_digest: input.manifestDigest,
|
|
37083
37085
|
station_id: input.stationId
|
|
37084
|
-
})}::jsonb)
|
|
37086
|
+
})}::text::jsonb)
|
|
37085
37087
|
`;
|
|
37086
37088
|
return { kind: "updated", scopes };
|
|
37087
37089
|
});
|
package/dist/index.js
CHANGED
|
@@ -9611,7 +9611,7 @@ import { isAbsolute as isAbsolute11, join as join23, resolve as resolve11 } from
|
|
|
9611
9611
|
// package.json
|
|
9612
9612
|
var package_default = {
|
|
9613
9613
|
name: "@hasna/skills",
|
|
9614
|
-
version: "0.10.
|
|
9614
|
+
version: "0.10.14",
|
|
9615
9615
|
description: "Skills library for AI coding agents",
|
|
9616
9616
|
type: "module",
|
|
9617
9617
|
bin: {
|
|
@@ -12812,6 +12812,196 @@ function isOwnedCliBridge(path, expectedPaths) {
|
|
|
12812
12812
|
// src/lib/agent-codex.ts
|
|
12813
12813
|
import { isDeepStrictEqual as isDeepStrictEqual2 } from "util";
|
|
12814
12814
|
var CODEX_SKILL_CONFIG_SECTIONS = /^\[\[skills\.config\]\][^\n]*(?:\n(?!\s*\[)[^\n]*)*/gm;
|
|
12815
|
+
var codexPathConfigRefusal = () => new Error("Codex skill path controls require ordinary [[skills.config]] TOML tables or a native single-line inline array; preserve and review unsupported inline, dotted, or malformed definitions before running skills hook install");
|
|
12816
|
+
function splitTopLevel(value, delimiter) {
|
|
12817
|
+
const result = [];
|
|
12818
|
+
let start = 0, square = 0, curly = 0, quote = null, escaped = false;
|
|
12819
|
+
for (let index = 0;index < value.length; index++) {
|
|
12820
|
+
const char = value[index];
|
|
12821
|
+
if (quote === "double") {
|
|
12822
|
+
if (escaped)
|
|
12823
|
+
escaped = false;
|
|
12824
|
+
else if (char === "\\")
|
|
12825
|
+
escaped = true;
|
|
12826
|
+
else if (char === '"')
|
|
12827
|
+
quote = null;
|
|
12828
|
+
continue;
|
|
12829
|
+
}
|
|
12830
|
+
if (quote === "literal") {
|
|
12831
|
+
if (char === "'")
|
|
12832
|
+
quote = null;
|
|
12833
|
+
continue;
|
|
12834
|
+
}
|
|
12835
|
+
if (char === '"') {
|
|
12836
|
+
quote = "double";
|
|
12837
|
+
continue;
|
|
12838
|
+
}
|
|
12839
|
+
if (char === "'") {
|
|
12840
|
+
quote = "literal";
|
|
12841
|
+
continue;
|
|
12842
|
+
}
|
|
12843
|
+
if (char === "[")
|
|
12844
|
+
square++;
|
|
12845
|
+
else if (char === "]") {
|
|
12846
|
+
if (--square < 0)
|
|
12847
|
+
return null;
|
|
12848
|
+
} else if (char === "{")
|
|
12849
|
+
curly++;
|
|
12850
|
+
else if (char === "}") {
|
|
12851
|
+
if (--curly < 0)
|
|
12852
|
+
return null;
|
|
12853
|
+
} else if (char === delimiter && square === 0 && curly === 0) {
|
|
12854
|
+
result.push(value.slice(start, index));
|
|
12855
|
+
start = index + 1;
|
|
12856
|
+
}
|
|
12857
|
+
}
|
|
12858
|
+
if (quote !== null || square !== 0 || curly !== 0)
|
|
12859
|
+
return null;
|
|
12860
|
+
result.push(value.slice(start));
|
|
12861
|
+
return result;
|
|
12862
|
+
}
|
|
12863
|
+
function inlineArrayEnd(value) {
|
|
12864
|
+
if (!value.startsWith("["))
|
|
12865
|
+
return null;
|
|
12866
|
+
let square = 0, curly = 0, quote = null, escaped = false;
|
|
12867
|
+
for (let index = 0;index < value.length; index++) {
|
|
12868
|
+
const char = value[index];
|
|
12869
|
+
if (quote === "double") {
|
|
12870
|
+
if (escaped)
|
|
12871
|
+
escaped = false;
|
|
12872
|
+
else if (char === "\\")
|
|
12873
|
+
escaped = true;
|
|
12874
|
+
else if (char === '"')
|
|
12875
|
+
quote = null;
|
|
12876
|
+
continue;
|
|
12877
|
+
}
|
|
12878
|
+
if (quote === "literal") {
|
|
12879
|
+
if (char === "'")
|
|
12880
|
+
quote = null;
|
|
12881
|
+
continue;
|
|
12882
|
+
}
|
|
12883
|
+
if (char === '"') {
|
|
12884
|
+
quote = "double";
|
|
12885
|
+
continue;
|
|
12886
|
+
}
|
|
12887
|
+
if (char === "'") {
|
|
12888
|
+
quote = "literal";
|
|
12889
|
+
continue;
|
|
12890
|
+
}
|
|
12891
|
+
if (char === "[")
|
|
12892
|
+
square++;
|
|
12893
|
+
else if (char === "]") {
|
|
12894
|
+
if (--square < 0)
|
|
12895
|
+
return null;
|
|
12896
|
+
if (square === 0 && curly === 0)
|
|
12897
|
+
return index;
|
|
12898
|
+
} else if (char === "{")
|
|
12899
|
+
curly++;
|
|
12900
|
+
else if (char === "}") {
|
|
12901
|
+
if (--curly < 0)
|
|
12902
|
+
return null;
|
|
12903
|
+
}
|
|
12904
|
+
}
|
|
12905
|
+
return null;
|
|
12906
|
+
}
|
|
12907
|
+
function inlineRowsAsTables(value, newline) {
|
|
12908
|
+
const end = inlineArrayEnd(value);
|
|
12909
|
+
if (end === null || value.slice(end + 1).trim() !== "" || value.includes(`
|
|
12910
|
+
`) || value.includes("\r"))
|
|
12911
|
+
return null;
|
|
12912
|
+
const elements = splitTopLevel(value.slice(1, end), ",");
|
|
12913
|
+
if (!elements)
|
|
12914
|
+
return null;
|
|
12915
|
+
const rows = elements.map((element) => element.trim()).filter(Boolean);
|
|
12916
|
+
if (rows.length === 0)
|
|
12917
|
+
return "";
|
|
12918
|
+
const sections = [];
|
|
12919
|
+
for (const row of rows) {
|
|
12920
|
+
if (!row.startsWith("{") || !row.endsWith("}"))
|
|
12921
|
+
return null;
|
|
12922
|
+
const fields = splitTopLevel(row.slice(1, -1), ",");
|
|
12923
|
+
if (!fields)
|
|
12924
|
+
return null;
|
|
12925
|
+
const lines = fields.map((field) => field.trim()).filter(Boolean);
|
|
12926
|
+
if (lines.some((line) => !/^(?:path|name|enabled)\s*=/.test(line)))
|
|
12927
|
+
return null;
|
|
12928
|
+
const keys = lines.map((line) => line.slice(0, line.indexOf("=")).trim());
|
|
12929
|
+
if (new Set(keys).size !== keys.length)
|
|
12930
|
+
return null;
|
|
12931
|
+
sections.push(`[[skills.config]]${newline}${lines.join(newline)}${newline}`);
|
|
12932
|
+
}
|
|
12933
|
+
return sections.join("");
|
|
12934
|
+
}
|
|
12935
|
+
function normalizeCodexInlinePathConfig(text2) {
|
|
12936
|
+
const before = Bun.TOML.parse(text2);
|
|
12937
|
+
if (!Array.isArray(before.skills?.config))
|
|
12938
|
+
return text2;
|
|
12939
|
+
if (before.skills.config.length === 0)
|
|
12940
|
+
throw codexPathConfigRefusal();
|
|
12941
|
+
const expectedWithoutConfig = structuredClone(before);
|
|
12942
|
+
delete expectedWithoutConfig.skills.config;
|
|
12943
|
+
try {
|
|
12944
|
+
if (isDeepStrictEqual2(Bun.TOML.parse(text2.replace(CODEX_SKILL_CONFIG_SECTIONS, "")), expectedWithoutConfig))
|
|
12945
|
+
return text2;
|
|
12946
|
+
} catch {}
|
|
12947
|
+
const matches = [];
|
|
12948
|
+
for (const assignment of text2.matchAll(/^([ \t]*config[ \t]*=[ \t]*)(.*?)(\r?)$/gm)) {
|
|
12949
|
+
const rawValue = assignment[2].trimEnd();
|
|
12950
|
+
let quote = null, escaped = false, comment = "";
|
|
12951
|
+
for (let index = 0;index < rawValue.length; index++) {
|
|
12952
|
+
const char = rawValue[index];
|
|
12953
|
+
if (quote === "double") {
|
|
12954
|
+
if (escaped)
|
|
12955
|
+
escaped = false;
|
|
12956
|
+
else if (char === "\\")
|
|
12957
|
+
escaped = true;
|
|
12958
|
+
else if (char === '"')
|
|
12959
|
+
quote = null;
|
|
12960
|
+
continue;
|
|
12961
|
+
}
|
|
12962
|
+
if (quote === "literal") {
|
|
12963
|
+
if (char === "'")
|
|
12964
|
+
quote = null;
|
|
12965
|
+
continue;
|
|
12966
|
+
}
|
|
12967
|
+
if (char === '"')
|
|
12968
|
+
quote = "double";
|
|
12969
|
+
else if (char === "'")
|
|
12970
|
+
quote = "literal";
|
|
12971
|
+
else if (char === "#") {
|
|
12972
|
+
comment = rawValue.slice(index);
|
|
12973
|
+
break;
|
|
12974
|
+
}
|
|
12975
|
+
}
|
|
12976
|
+
const value = comment ? rawValue.slice(0, rawValue.length - comment.length).trimEnd() : rawValue;
|
|
12977
|
+
const tableSections = inlineRowsAsTables(value, text2.includes(`\r
|
|
12978
|
+
`) ? `\r
|
|
12979
|
+
` : `
|
|
12980
|
+
`);
|
|
12981
|
+
if (tableSections === null)
|
|
12982
|
+
continue;
|
|
12983
|
+
const start = assignment.index;
|
|
12984
|
+
const end = start + assignment[0].length;
|
|
12985
|
+
const withoutAssignment = text2.slice(0, start) + (comment ? comment : "") + assignment[3] + text2.slice(end);
|
|
12986
|
+
const separator = withoutAssignment.endsWith(`
|
|
12987
|
+
`) ? withoutAssignment.endsWith(`
|
|
12988
|
+
|
|
12989
|
+
`) ? "" : `
|
|
12990
|
+
` : `
|
|
12991
|
+
|
|
12992
|
+
`;
|
|
12993
|
+
const candidate = withoutAssignment + (tableSections ? separator + tableSections : "");
|
|
12994
|
+
try {
|
|
12995
|
+
const after = Bun.TOML.parse(candidate);
|
|
12996
|
+
const expected = structuredClone(before);
|
|
12997
|
+
if (isDeepStrictEqual2(after, expected))
|
|
12998
|
+
matches.push(candidate);
|
|
12999
|
+
} catch {}
|
|
13000
|
+
}
|
|
13001
|
+
if (matches.length !== 1)
|
|
13002
|
+
throw codexPathConfigRefusal();
|
|
13003
|
+
return matches[0];
|
|
13004
|
+
}
|
|
12815
13005
|
function assertCodexPathConfigEditable(text2) {
|
|
12816
13006
|
const before = Bun.TOML.parse(text2);
|
|
12817
13007
|
if (before.skills?.config === undefined)
|
|
@@ -12822,8 +13012,12 @@ function assertCodexPathConfigEditable(text2) {
|
|
|
12822
13012
|
const withoutSections = Bun.TOML.parse(text2.replace(CODEX_SKILL_CONFIG_SECTIONS, ""));
|
|
12823
13013
|
if (isDeepStrictEqual2(withoutSections, expected))
|
|
12824
13014
|
return;
|
|
13015
|
+
const normalized = normalizeCodexInlinePathConfig(text2);
|
|
13016
|
+
const withoutNormalizedSections = Bun.TOML.parse(normalized.replace(CODEX_SKILL_CONFIG_SECTIONS, ""));
|
|
13017
|
+
if (isDeepStrictEqual2(withoutNormalizedSections, expected))
|
|
13018
|
+
return;
|
|
12825
13019
|
} catch {}
|
|
12826
|
-
throw
|
|
13020
|
+
throw codexPathConfigRefusal();
|
|
12827
13021
|
}
|
|
12828
13022
|
function disableCodexBundledSkills(text2) {
|
|
12829
13023
|
const before = Bun.TOML.parse(text2);
|
|
@@ -13398,11 +13592,12 @@ function inventoryNativeSkills(home = homedir2(), options = {}) {
|
|
|
13398
13592
|
return false;
|
|
13399
13593
|
if (scan.hasSkills) {
|
|
13400
13594
|
const targetSkills = entries.filter((entry) => entry.agent === agent && entry.vendor && (entry.path === target || entry.path.startsWith(target + sep4)));
|
|
13595
|
+
if (path === options.reviewedCacheAlias && targetSkills.length > 0)
|
|
13596
|
+
reviewedCacheAliasFound = true;
|
|
13401
13597
|
if (agent === "codex" && targetSkills.length > 0 && targetSkills.every((entry) => disabledVendorPaths.has(entry.path)))
|
|
13402
13598
|
return true;
|
|
13403
13599
|
if (path !== options.reviewedCacheAlias)
|
|
13404
13600
|
return false;
|
|
13405
|
-
reviewedCacheAliasFound = true;
|
|
13406
13601
|
}
|
|
13407
13602
|
return true;
|
|
13408
13603
|
}
|
|
@@ -13601,7 +13796,7 @@ function configureHooks(config, agent, command, profileId, nativeReady) {
|
|
|
13601
13796
|
}
|
|
13602
13797
|
function disableCodexSkills(text2, skills, aliases, bridgePath) {
|
|
13603
13798
|
const bundled = disableCodexBundledSkills(text2);
|
|
13604
|
-
let result = bundled;
|
|
13799
|
+
let result = normalizeCodexInlinePathConfig(bundled);
|
|
13605
13800
|
const bridgeSelector = (entry) => typeof entry.name === "string" && entry.name.trim() === CLI_BRIDGE_NAME || typeof entry.path === "string" && [resolve9(bridgePath), resolve9(join16(bridgePath, "SKILL.md"))].includes(canonicalAgentPath(entry.path, aliases));
|
|
13606
13801
|
const previousConfig = Bun.TOML.parse(bundled).skills?.config;
|
|
13607
13802
|
if (previousConfig !== undefined && (!Array.isArray(previousConfig) || previousConfig.some((entry) => !entry || typeof entry !== "object" || entry.path !== undefined && entry.name !== undefined)))
|
|
@@ -13670,7 +13865,7 @@ function planAgentIntegration(options) {
|
|
|
13670
13865
|
return resolveAgentDiscovery({ home, agent, reviewed: options.discoveryInputs, retainedReview, canonical: (path) => canonicalAgentPath(path, aliases) });
|
|
13671
13866
|
});
|
|
13672
13867
|
const codexConfig = options.agents.includes("codex") ? Bun.TOML.parse(readOptional(canonicalAgentPath(join16(home, ".codex", "config.toml"), aliases)) ?? "") : {};
|
|
13673
|
-
const nativeSkills = inventoryNativeSkills(home, { includeVendor: true, guardHermes: options.agents.includes("hermes"), agents: options.agents, projectDir: options.projectDir, agentRoots: discoveries.flatMap((binding) => binding.roots.map((path) => ({ agent: binding.agent, path }))), allowRootAliases: options.allowRootAliases, disabledVendorPaths: disabledCodexSkillPaths(codexConfig, aliases) });
|
|
13868
|
+
const nativeSkills = inventoryNativeSkills(home, { includeVendor: true, guardHermes: options.agents.includes("hermes"), agents: options.agents, projectDir: options.projectDir, agentRoots: discoveries.flatMap((binding) => binding.roots.map((path) => ({ agent: binding.agent, path }))), allowRootAliases: options.allowRootAliases, reviewedCacheAlias: options.reviewedCacheAlias, disabledVendorPaths: disabledCodexSkillPaths(codexConfig, aliases) });
|
|
13674
13869
|
const changes = [];
|
|
13675
13870
|
for (const agent of [...new Set(options.agents)]) {
|
|
13676
13871
|
if (!INTEGRATION_AGENTS.includes(agent))
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
export declare const CODEX_SKILL_CONFIG_SECTIONS: RegExp;
|
|
2
|
-
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
/** Convert only Codex's native, single-line inline array representation into
|
|
3
|
+
* equivalent array-of-table sections. The replacement is accepted only when
|
|
4
|
+
* the complete parsed TOML value is deeply identical before and after. */
|
|
5
|
+
export declare function normalizeCodexInlinePathConfig(text: string): string;
|
|
6
|
+
/** Removing supported path sections must remove exactly the parsed skill path
|
|
7
|
+
* array while preserving every other TOML value. Native app-server inline
|
|
8
|
+
* arrays are first normalized by a targeted, semantically verified edit. */
|
|
5
9
|
export declare function assertCodexPathConfigEditable(text: string): void;
|
|
6
10
|
/** Preserve user TOML verbatim except for the supported bundled-skill control.
|
|
7
11
|
* Bun's parser accepts some illegal table reopenings, so never append a table
|
|
@@ -99,6 +99,7 @@ export declare function planAgentIntegration(options: {
|
|
|
99
99
|
projectDir?: string;
|
|
100
100
|
discoveryInputs?: ReviewedDiscoveryInputs;
|
|
101
101
|
allowRootAliases?: boolean;
|
|
102
|
+
reviewedCacheAlias?: string;
|
|
102
103
|
}): AgentIntegrationPlan;
|
|
103
104
|
/** Plan an explicitly authorized Stop hook replacement without adopting drift.
|
|
104
105
|
* The caller owns authorization of its exact Stop hook delta; Skills refuses
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const SUPPORTED_CODEX_HOOK_VERSIONS: readonly ["codex-cli 0.153.0", "codex-cli 0.154.0", "codex-cli 0.155.0", "codex-cli 0.155.1", "codex-cli 0.156.1", "codex-cli 0.157.0", "codex-cli 0.157.1"];
|
|
1
|
+
export declare const SUPPORTED_CODEX_HOOK_VERSIONS: readonly ["codex-cli 0.153.0", "codex-cli 0.154.0", "codex-cli 0.155.0", "codex-cli 0.155.1", "codex-cli 0.156.1", "codex-cli 0.157.0", "codex-cli 0.157.1", "codex-cli 0.158.0", "codex-cli 0.159.0"];
|
|
2
2
|
export interface CodexHookRpc {
|
|
3
3
|
version: string;
|
|
4
4
|
processId?: number;
|