@enactprotocol/cli 2.3.5 → 2.3.7
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/commands/index.d.ts +1 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +2 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/org/index.d.ts +16 -0
- package/dist/commands/org/index.d.ts.map +1 -0
- package/dist/commands/org/index.js +203 -0
- package/dist/commands/org/index.js.map +1 -0
- package/dist/commands/publish/index.d.ts.map +1 -1
- package/dist/commands/publish/index.js +5 -1
- package/dist/commands/publish/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/utils/errors.js +2 -2
- package/dist/utils/errors.js.map +1 -1
- package/package.json +6 -6
- package/src/commands/env/README.md +1 -1
- package/src/commands/index.ts +3 -0
- package/src/commands/install/README.md +1 -1
- package/src/commands/org/index.ts +263 -0
- package/src/commands/publish/index.ts +4 -1
- package/src/commands/run/README.md +1 -1
- package/src/index.ts +5 -1
- package/src/utils/errors.ts +2 -2
- package/tests/commands/install-integration.test.ts +5 -5
- package/tests/commands/publish.test.ts +5 -3
- package/tests/commands/sign.test.ts +1 -1
- package/tests/e2e.test.ts +3 -1
- package/tests/utils/ignore.test.ts +2 -1
- package/tsconfig.tsbuildinfo +1 -1
- /package/tests/fixtures/calculator/{skill.yaml → skill.package.yaml} +0 -0
- /package/tests/fixtures/env-tool/{skill.yaml → skill.package.yaml} +0 -0
- /package/tests/fixtures/greeter/{skill.yaml → skill.package.yaml} +0 -0
- /package/tests/fixtures/invalid-tool/{skill.yaml → skill.package.yaml} +0 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* enact org command
|
|
3
|
+
*
|
|
4
|
+
* Manage organizations for @org scoped tool namespaces.
|
|
5
|
+
*
|
|
6
|
+
* Subcommands:
|
|
7
|
+
* - create: Create a new organization
|
|
8
|
+
* - info: Show organization details
|
|
9
|
+
* - list: List your organizations (TODO: requires user orgs endpoint)
|
|
10
|
+
* - add-member: Add a member to an organization
|
|
11
|
+
* - remove-member: Remove a member from an organization
|
|
12
|
+
* - set-role: Change a member's role
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
addOrgMember,
|
|
17
|
+
createApiClient,
|
|
18
|
+
createOrg,
|
|
19
|
+
getOrg,
|
|
20
|
+
listOrgMembers,
|
|
21
|
+
removeOrgMember,
|
|
22
|
+
updateOrgMemberRole,
|
|
23
|
+
} from "@enactprotocol/api";
|
|
24
|
+
import { getSecret } from "@enactprotocol/secrets";
|
|
25
|
+
import { loadConfig } from "@enactprotocol/shared";
|
|
26
|
+
import type { OrgRole } from "@enactprotocol/shared";
|
|
27
|
+
import type { Command } from "commander";
|
|
28
|
+
import type { GlobalOptions } from "../../types";
|
|
29
|
+
import {
|
|
30
|
+
type TableColumn,
|
|
31
|
+
dim,
|
|
32
|
+
error,
|
|
33
|
+
formatError,
|
|
34
|
+
header,
|
|
35
|
+
json,
|
|
36
|
+
keyValue,
|
|
37
|
+
newline,
|
|
38
|
+
success,
|
|
39
|
+
table,
|
|
40
|
+
} from "../../utils";
|
|
41
|
+
|
|
42
|
+
const AUTH_NAMESPACE = "enact:auth";
|
|
43
|
+
const ACCESS_TOKEN_KEY = "access_token";
|
|
44
|
+
|
|
45
|
+
const VALID_ROLES = ["owner", "admin", "member"] as const;
|
|
46
|
+
|
|
47
|
+
async function getClient() {
|
|
48
|
+
const config = loadConfig();
|
|
49
|
+
const token = await getSecret(AUTH_NAMESPACE, ACCESS_TOKEN_KEY);
|
|
50
|
+
return createApiClient({
|
|
51
|
+
baseUrl: config.registry?.url,
|
|
52
|
+
authToken: token ?? undefined,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
// Handlers
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
|
|
60
|
+
async function createHandler(
|
|
61
|
+
name: string,
|
|
62
|
+
options: { displayName?: string; description?: string } & GlobalOptions
|
|
63
|
+
) {
|
|
64
|
+
try {
|
|
65
|
+
const client = await getClient();
|
|
66
|
+
const org = await createOrg(client, {
|
|
67
|
+
name,
|
|
68
|
+
displayName: options.displayName,
|
|
69
|
+
description: options.description,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (options.json) {
|
|
73
|
+
json(org);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
success(`Organization "@${org.name}" created`);
|
|
78
|
+
newline();
|
|
79
|
+
keyValue("Name", `@${org.name}`);
|
|
80
|
+
if (org.display_name) keyValue("Display Name", org.display_name);
|
|
81
|
+
if (org.description) keyValue("Description", org.description);
|
|
82
|
+
newline();
|
|
83
|
+
dim("You are the owner. Publish tools with:");
|
|
84
|
+
dim(` enact publish (with name: "@${org.name}/your-tool" in SKILL.md)`);
|
|
85
|
+
} catch (err) {
|
|
86
|
+
error(formatError(err));
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function infoHandler(name: string, options: GlobalOptions) {
|
|
92
|
+
try {
|
|
93
|
+
// Strip @ prefix if provided
|
|
94
|
+
const orgName = name.startsWith("@") ? name.substring(1) : name;
|
|
95
|
+
const client = await getClient();
|
|
96
|
+
|
|
97
|
+
const org = await getOrg(client, orgName);
|
|
98
|
+
const members = await listOrgMembers(client, orgName);
|
|
99
|
+
|
|
100
|
+
if (options.json) {
|
|
101
|
+
json({ ...org, members });
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
header(`@${org.name}`);
|
|
106
|
+
if (org.display_name) keyValue("Display Name", org.display_name);
|
|
107
|
+
if (org.description) keyValue("Description", org.description);
|
|
108
|
+
keyValue("Tools", String(org.tool_count));
|
|
109
|
+
keyValue("Members", String(org.member_count));
|
|
110
|
+
keyValue("Created", org.created_at);
|
|
111
|
+
|
|
112
|
+
newline();
|
|
113
|
+
header("Members");
|
|
114
|
+
const columns: TableColumn[] = [
|
|
115
|
+
{ header: "Username", key: "username", width: 20 },
|
|
116
|
+
{ header: "Role", key: "role", width: 10 },
|
|
117
|
+
{ header: "Added", key: "added_at", width: 20 },
|
|
118
|
+
];
|
|
119
|
+
table(
|
|
120
|
+
members.map((m) => ({
|
|
121
|
+
username: m.username,
|
|
122
|
+
role: m.role,
|
|
123
|
+
added_at: m.added_at,
|
|
124
|
+
})),
|
|
125
|
+
columns
|
|
126
|
+
);
|
|
127
|
+
} catch (err) {
|
|
128
|
+
error(formatError(err));
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async function addMemberHandler(
|
|
134
|
+
orgName: string,
|
|
135
|
+
username: string,
|
|
136
|
+
options: { role?: string } & GlobalOptions
|
|
137
|
+
) {
|
|
138
|
+
try {
|
|
139
|
+
const org = orgName.startsWith("@") ? orgName.substring(1) : orgName;
|
|
140
|
+
const role = (options.role ?? "member") as OrgRole;
|
|
141
|
+
|
|
142
|
+
if (!VALID_ROLES.includes(role as (typeof VALID_ROLES)[number])) {
|
|
143
|
+
error(`Invalid role: ${role}. Must be one of: ${VALID_ROLES.join(", ")}`);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const client = await getClient();
|
|
148
|
+
await addOrgMember(client, org, { username, role });
|
|
149
|
+
|
|
150
|
+
if (options.json) {
|
|
151
|
+
json({ username, role, org });
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
success(`Added "${username}" to @${org} as ${role}`);
|
|
156
|
+
} catch (err) {
|
|
157
|
+
error(formatError(err));
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async function removeMemberHandler(orgName: string, username: string, options: GlobalOptions) {
|
|
163
|
+
try {
|
|
164
|
+
const org = orgName.startsWith("@") ? orgName.substring(1) : orgName;
|
|
165
|
+
const client = await getClient();
|
|
166
|
+
await removeOrgMember(client, org, username);
|
|
167
|
+
|
|
168
|
+
if (options.json) {
|
|
169
|
+
json({ removed: username, org });
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
success(`Removed "${username}" from @${org}`);
|
|
174
|
+
} catch (err) {
|
|
175
|
+
error(formatError(err));
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function setRoleHandler(
|
|
181
|
+
orgName: string,
|
|
182
|
+
username: string,
|
|
183
|
+
role: string,
|
|
184
|
+
options: GlobalOptions
|
|
185
|
+
) {
|
|
186
|
+
try {
|
|
187
|
+
const org = orgName.startsWith("@") ? orgName.substring(1) : orgName;
|
|
188
|
+
|
|
189
|
+
if (!VALID_ROLES.includes(role as (typeof VALID_ROLES)[number])) {
|
|
190
|
+
error(`Invalid role: ${role}. Must be one of: ${VALID_ROLES.join(", ")}`);
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const client = await getClient();
|
|
195
|
+
await updateOrgMemberRole(client, org, username, role as OrgRole);
|
|
196
|
+
|
|
197
|
+
if (options.json) {
|
|
198
|
+
json({ username, role, org });
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
success(`Set "${username}" role to ${role} in @${org}`);
|
|
203
|
+
} catch (err) {
|
|
204
|
+
error(formatError(err));
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
// Command Configuration
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
|
|
213
|
+
export function configureOrgCommand(program: Command): void {
|
|
214
|
+
const org = program.command("org").description("Manage organizations (@org scoped namespaces)");
|
|
215
|
+
|
|
216
|
+
// enact org create <name>
|
|
217
|
+
org
|
|
218
|
+
.command("create <name>")
|
|
219
|
+
.description("Create a new organization")
|
|
220
|
+
.option("--display-name <name>", "Display name for the organization")
|
|
221
|
+
.option("--description <desc>", "Organization description")
|
|
222
|
+
.option("--json", "Output as JSON")
|
|
223
|
+
.action(async (name: string, options) => {
|
|
224
|
+
await createHandler(name, options);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// enact org info <name>
|
|
228
|
+
org
|
|
229
|
+
.command("info <name>")
|
|
230
|
+
.description("Show organization details and members")
|
|
231
|
+
.option("--json", "Output as JSON")
|
|
232
|
+
.action(async (name: string, options) => {
|
|
233
|
+
await infoHandler(name, options);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// enact org add-member <org> <username>
|
|
237
|
+
org
|
|
238
|
+
.command("add-member <org> <username>")
|
|
239
|
+
.description("Add a member to an organization")
|
|
240
|
+
.option("--role <role>", "Member role (owner, admin, member)", "member")
|
|
241
|
+
.option("--json", "Output as JSON")
|
|
242
|
+
.action(async (orgName: string, username: string, options) => {
|
|
243
|
+
await addMemberHandler(orgName, username, options);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// enact org remove-member <org> <username>
|
|
247
|
+
org
|
|
248
|
+
.command("remove-member <org> <username>")
|
|
249
|
+
.description("Remove a member from an organization")
|
|
250
|
+
.option("--json", "Output as JSON")
|
|
251
|
+
.action(async (orgName: string, username: string, options) => {
|
|
252
|
+
await removeMemberHandler(orgName, username, options);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// enact org set-role <org> <username> <role>
|
|
256
|
+
org
|
|
257
|
+
.command("set-role <org> <username> <role>")
|
|
258
|
+
.description("Change a member's role (owner, admin, member)")
|
|
259
|
+
.option("--json", "Output as JSON")
|
|
260
|
+
.action(async (orgName: string, username: string, role: string, options) => {
|
|
261
|
+
await setRoleHandler(orgName, username, role, options);
|
|
262
|
+
});
|
|
263
|
+
}
|
|
@@ -320,7 +320,10 @@ async function publishHandler(
|
|
|
320
320
|
const currentUsername = await getCurrentUsername();
|
|
321
321
|
if (currentUsername) {
|
|
322
322
|
const toolNamespace = extractNamespace(toolName);
|
|
323
|
-
if (toolNamespace
|
|
323
|
+
if (toolNamespace.startsWith("@")) {
|
|
324
|
+
// Org-scoped tool — server will enforce org membership
|
|
325
|
+
dim(`Publishing to organization namespace "${toolNamespace}"...`);
|
|
326
|
+
} else if (toolNamespace !== currentUsername) {
|
|
324
327
|
error(
|
|
325
328
|
`Namespace mismatch: Tool namespace "${toolNamespace}" does not match your username "${currentUsername}".`
|
|
326
329
|
);
|
|
@@ -10,7 +10,7 @@ enact run <tool> [options]
|
|
|
10
10
|
|
|
11
11
|
## Description
|
|
12
12
|
|
|
13
|
-
The `run` command executes a tool using the command defined in its manifest (`skill.
|
|
13
|
+
The `run` command executes a tool using the command defined in its manifest (`skill.package.yml` or `SKILL.md`). The tool runs in an isolated container environment with:
|
|
14
14
|
|
|
15
15
|
- Input validation against the tool's JSON Schema
|
|
16
16
|
- Automatic secret resolution from the OS keyring
|
package/src/index.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
configureLearnCommand,
|
|
23
23
|
configureListCommand,
|
|
24
24
|
configureMcpCommand,
|
|
25
|
+
configureOrgCommand,
|
|
25
26
|
configurePublishCommand,
|
|
26
27
|
configureReportCommand,
|
|
27
28
|
configureRunCommand,
|
|
@@ -37,7 +38,7 @@ import {
|
|
|
37
38
|
} from "./commands";
|
|
38
39
|
import { error, formatError } from "./utils";
|
|
39
40
|
|
|
40
|
-
export const version = "2.3.
|
|
41
|
+
export const version = "2.3.7";
|
|
41
42
|
|
|
42
43
|
// Export types for external use
|
|
43
44
|
export type { GlobalOptions, CommandContext } from "./types";
|
|
@@ -93,6 +94,9 @@ async function main() {
|
|
|
93
94
|
// Self-hosted registry
|
|
94
95
|
configureServeCommand(program);
|
|
95
96
|
|
|
97
|
+
// Organizations
|
|
98
|
+
configureOrgCommand(program);
|
|
99
|
+
|
|
96
100
|
// Global error handler - handle Commander's help/version exits gracefully
|
|
97
101
|
program.exitOverride((err) => {
|
|
98
102
|
// Commander throws errors for help, version, and other "exit" scenarios
|
package/src/utils/errors.ts
CHANGED
|
@@ -84,7 +84,7 @@ export class ManifestError extends CliError {
|
|
|
84
84
|
super(
|
|
85
85
|
fullMessage,
|
|
86
86
|
EXIT_MANIFEST_ERROR,
|
|
87
|
-
"Ensure the directory contains a valid skill.yaml or SKILL.md file."
|
|
87
|
+
"Ensure the directory contains a valid skill.package.yaml, skill.package.yml, or SKILL.md file."
|
|
88
88
|
);
|
|
89
89
|
this.name = "ManifestError";
|
|
90
90
|
}
|
|
@@ -377,7 +377,7 @@ export const ErrorMessages = {
|
|
|
377
377
|
message: `No manifest found in ${dir}`,
|
|
378
378
|
suggestions: [
|
|
379
379
|
`Create a manifest: ${colors.command("enact init")}`,
|
|
380
|
-
"Ensure the directory contains skill.yaml or SKILL.md",
|
|
380
|
+
"Ensure the directory contains skill.package.yaml, skill.package.yml, or SKILL.md",
|
|
381
381
|
],
|
|
382
382
|
}),
|
|
383
383
|
|
|
@@ -46,7 +46,7 @@ describe("install integration", () => {
|
|
|
46
46
|
mkdirSync(join(TEST_GLOBAL_HOME, ".enact", "cache"), { recursive: true });
|
|
47
47
|
|
|
48
48
|
// Create sample tool source
|
|
49
|
-
writeFileSync(join(TEST_TOOL_SRC, "skill.
|
|
49
|
+
writeFileSync(join(TEST_TOOL_SRC, "skill.package.yml"), SAMPLE_MANIFEST);
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
beforeEach(() => {
|
|
@@ -92,7 +92,7 @@ describe("install integration", () => {
|
|
|
92
92
|
|
|
93
93
|
// Verify installation
|
|
94
94
|
expect(existsSync(destPath)).toBe(true);
|
|
95
|
-
expect(existsSync(join(destPath, "skill.
|
|
95
|
+
expect(existsSync(join(destPath, "skill.package.yml"))).toBe(true);
|
|
96
96
|
|
|
97
97
|
// Verify manifest can be loaded from destination
|
|
98
98
|
const installedManifest = loadManifestFromDir(destPath);
|
|
@@ -118,7 +118,7 @@ describe("install integration", () => {
|
|
|
118
118
|
// Create v2 source
|
|
119
119
|
const v2Source = join(TEST_BASE, "source-tool-v2");
|
|
120
120
|
mkdirSync(v2Source, { recursive: true });
|
|
121
|
-
writeFileSync(join(v2Source, "skill.
|
|
121
|
+
writeFileSync(join(v2Source, "skill.package.yml"), SAMPLE_MANIFEST_V2);
|
|
122
122
|
|
|
123
123
|
// Simulate force overwrite
|
|
124
124
|
rmSync(destPath, { recursive: true, force: true });
|
|
@@ -240,7 +240,7 @@ describe("install integration", () => {
|
|
|
240
240
|
const cachePath = join(TEST_GLOBAL_HOME, ".enact", "cache", "test", "cached-tool", "v1.0.0");
|
|
241
241
|
mkdirSync(cachePath, { recursive: true });
|
|
242
242
|
writeFileSync(
|
|
243
|
-
join(cachePath, "skill.
|
|
243
|
+
join(cachePath, "skill.package.yml"),
|
|
244
244
|
`
|
|
245
245
|
name: test/cached-tool
|
|
246
246
|
version: 1.0.0
|
|
@@ -251,7 +251,7 @@ command: echo "cached"
|
|
|
251
251
|
|
|
252
252
|
// The resolver should be able to find this tool once it's registered
|
|
253
253
|
// Note: Full resolver testing is in resolver.test.ts
|
|
254
|
-
expect(existsSync(join(cachePath, "skill.
|
|
254
|
+
expect(existsSync(join(cachePath, "skill.package.yml"))).toBe(true);
|
|
255
255
|
});
|
|
256
256
|
});
|
|
257
257
|
});
|
|
@@ -110,7 +110,8 @@ describe("publish command", () => {
|
|
|
110
110
|
test("identifies manifest files", () => {
|
|
111
111
|
const isManifest = (filename: string): boolean => {
|
|
112
112
|
return (
|
|
113
|
-
filename === "skill.yaml" ||
|
|
113
|
+
filename === "skill.package.yaml" ||
|
|
114
|
+
filename === "skill.package.yml" ||
|
|
114
115
|
filename === "skill.yml" ||
|
|
115
116
|
filename === "enact.yaml" ||
|
|
116
117
|
filename === "enact.yml" ||
|
|
@@ -118,7 +119,8 @@ describe("publish command", () => {
|
|
|
118
119
|
);
|
|
119
120
|
};
|
|
120
121
|
|
|
121
|
-
expect(isManifest("skill.yaml")).toBe(true);
|
|
122
|
+
expect(isManifest("skill.package.yaml")).toBe(true);
|
|
123
|
+
expect(isManifest("skill.package.yml")).toBe(true);
|
|
122
124
|
expect(isManifest("skill.yml")).toBe(true);
|
|
123
125
|
expect(isManifest("enact.yaml")).toBe(true);
|
|
124
126
|
expect(isManifest("enact.yml")).toBe(true);
|
|
@@ -132,7 +134,7 @@ describe("publish command", () => {
|
|
|
132
134
|
return lastDot === -1 ? "" : filename.slice(lastDot + 1);
|
|
133
135
|
};
|
|
134
136
|
|
|
135
|
-
expect(getExtension("skill.yaml")).toBe("yaml");
|
|
137
|
+
expect(getExtension("skill.package.yaml")).toBe("yaml");
|
|
136
138
|
expect(getExtension("skill.yml")).toBe("yml");
|
|
137
139
|
expect(getExtension("enact.yaml")).toBe("yaml");
|
|
138
140
|
expect(getExtension("enact.yml")).toBe("yml");
|
package/tests/e2e.test.ts
CHANGED
|
@@ -126,7 +126,9 @@ describe("E2E: Tool Installation Flow", () => {
|
|
|
126
126
|
expect(manifest.name).toBe("test/greeter");
|
|
127
127
|
expect(existsSync(destPath)).toBe(true);
|
|
128
128
|
expect(
|
|
129
|
-
existsSync(join(destPath, "enact.yaml")) ||
|
|
129
|
+
existsSync(join(destPath, "enact.yaml")) ||
|
|
130
|
+
existsSync(join(destPath, "skill.package.yaml")) ||
|
|
131
|
+
existsSync(join(destPath, "skill.package.yml"))
|
|
130
132
|
).toBe(true);
|
|
131
133
|
|
|
132
134
|
// Verify installed manifest can be loaded
|
|
@@ -281,7 +281,8 @@ dist `;
|
|
|
281
281
|
});
|
|
282
282
|
|
|
283
283
|
test("allows manifest files", () => {
|
|
284
|
-
expect(shouldIgnore("skill.yaml", "skill.yaml")).toBe(false);
|
|
284
|
+
expect(shouldIgnore("skill.package.yaml", "skill.package.yaml")).toBe(false);
|
|
285
|
+
expect(shouldIgnore("skill.package.yml", "skill.package.yml")).toBe(false);
|
|
285
286
|
expect(shouldIgnore("skill.yml", "skill.yml")).toBe(false);
|
|
286
287
|
expect(shouldIgnore("enact.md", "enact.md")).toBe(false);
|
|
287
288
|
expect(shouldIgnore("enact.yaml", "enact.yaml")).toBe(false);
|