ai-ops-cli 1.2.0 → 1.3.0
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/README.ko.md +1 -2
- package/README.md +1 -2
- package/data/context-layer/AGENTS.md +1 -1
- package/data/context-layer/docs/agent/checks/impact-checklist.md +8 -6
- package/data/context-layer/docs/agent/workflow.md +21 -7
- package/data/skills/README.ko.md +12 -13
- package/data/skills/README.md +8 -9
- package/data/skills/skill-registry.json +0 -26
- package/data/skills/task-skills/context-promotion-review/SKILL.md +1 -1
- package/data/skills/task-skills/doc-impact-reviewer/SKILL.md +0 -1
- package/dist/bin/index.js +296 -384
- package/dist/bin/index.js.map +1 -1
- package/package.json +1 -1
- package/data/context-layer/docs/agent/checks/review-checklist.md +0 -17
package/dist/bin/index.js
CHANGED
|
@@ -6,42 +6,8 @@ import { Command } from "commander";
|
|
|
6
6
|
// src/commands/init.ts
|
|
7
7
|
import * as p2 from "@clack/prompts";
|
|
8
8
|
|
|
9
|
-
// src/core/schemas/rule.schema.ts
|
|
10
|
-
import { z } from "zod";
|
|
11
|
-
var DecisionTableEntrySchema = z.object({
|
|
12
|
-
when: z.string().min(1),
|
|
13
|
-
then: z.string().min(1),
|
|
14
|
-
/** 조건부 규칙에서 회피해야 할 패턴 */
|
|
15
|
-
avoid: z.string().min(1).optional()
|
|
16
|
-
}).strict();
|
|
17
|
-
var RuleContentSchema = z.object({
|
|
18
|
-
/** Anti-pattern 규칙 ('하지 마라'). guidelines보다 항상 상단 렌더링 */
|
|
19
|
-
constraints: z.array(z.string().min(1)).default([]),
|
|
20
|
-
/** Positive 규칙 ('해라') */
|
|
21
|
-
guidelines: z.array(z.string().min(1)),
|
|
22
|
-
/** 조건부 규칙. when→then→avoid 구조 */
|
|
23
|
-
decision_table: z.array(DecisionTableEntrySchema).optional()
|
|
24
|
-
}).strict();
|
|
25
|
-
var RuleSchema = z.object({
|
|
26
|
-
id: z.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, "id must be kebab-case"),
|
|
27
|
-
category: z.string().min(1),
|
|
28
|
-
tags: z.array(z.string().min(1)),
|
|
29
|
-
/** 0-100. 높을수록 생성 파일 상단 배치 (U-shaped attention 최적화) */
|
|
30
|
-
priority: z.number().int().min(0).max(100),
|
|
31
|
-
supported_tools: z.array(z.string().min(1)).min(1).default(["claude-code", "codex", "gemini"]),
|
|
32
|
-
content: RuleContentSchema
|
|
33
|
-
}).strict();
|
|
34
|
-
|
|
35
|
-
// src/core/schemas/preset.schema.ts
|
|
36
|
-
import { z as z2 } from "zod";
|
|
37
|
-
var PresetSchema = z2.object({
|
|
38
|
-
id: z2.string().regex(/^[a-z][a-z0-9-]*$/).min(1),
|
|
39
|
-
description: z2.string().min(1),
|
|
40
|
-
rules: z2.array(z2.string().min(1)).min(1)
|
|
41
|
-
}).strict();
|
|
42
|
-
|
|
43
9
|
// src/core/schemas/skill.schema.ts
|
|
44
|
-
import { z
|
|
10
|
+
import { z } from "zod";
|
|
45
11
|
var SKILL_KIND = {
|
|
46
12
|
REFERENCE: "reference",
|
|
47
13
|
TASK: "task"
|
|
@@ -51,69 +17,68 @@ var SKILL_TOOL = {
|
|
|
51
17
|
CODEX: "codex",
|
|
52
18
|
GEMINI: "gemini"
|
|
53
19
|
};
|
|
54
|
-
var SkillKindSchema =
|
|
55
|
-
var SkillToolSchema =
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
20
|
+
var SkillKindSchema = z.union([z.literal(SKILL_KIND.REFERENCE), z.literal(SKILL_KIND.TASK)]);
|
|
21
|
+
var SkillToolSchema = z.union([
|
|
22
|
+
z.literal(SKILL_TOOL.CLAUDE_CODE),
|
|
23
|
+
z.literal(SKILL_TOOL.CODEX),
|
|
24
|
+
z.literal(SKILL_TOOL.GEMINI)
|
|
59
25
|
]);
|
|
60
|
-
var SkillFileSchema =
|
|
61
|
-
path:
|
|
62
|
-
content:
|
|
26
|
+
var SkillFileSchema = z.object({
|
|
27
|
+
path: z.string().min(1),
|
|
28
|
+
content: z.string()
|
|
63
29
|
}).strict();
|
|
64
|
-
var SkillFrontmatterSchema =
|
|
65
|
-
name:
|
|
66
|
-
description:
|
|
30
|
+
var SkillFrontmatterSchema = z.object({
|
|
31
|
+
name: z.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, "name must be kebab-case"),
|
|
32
|
+
description: z.string().min(1)
|
|
67
33
|
}).passthrough();
|
|
68
|
-
var InstalledSkillSchema =
|
|
69
|
-
id:
|
|
34
|
+
var InstalledSkillSchema = z.object({
|
|
35
|
+
id: z.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, "id must be kebab-case"),
|
|
70
36
|
kind: SkillKindSchema,
|
|
71
|
-
tools:
|
|
72
|
-
installed_paths:
|
|
73
|
-
sourceHash:
|
|
37
|
+
tools: z.array(SkillToolSchema).min(1),
|
|
38
|
+
installed_paths: z.array(z.string().min(1)).min(1),
|
|
39
|
+
sourceHash: z.string().regex(/^[a-f0-9]{6}$/, "sourceHash must be 6 lowercase hex chars")
|
|
74
40
|
}).strip();
|
|
75
41
|
|
|
76
42
|
// src/core/schemas/skill-catalog.schema.ts
|
|
77
|
-
import { z as
|
|
78
|
-
var SkillIdSchema =
|
|
79
|
-
var SkillCatalogPathSchema =
|
|
80
|
-
var SkillCatalogEntrySchema =
|
|
43
|
+
import { z as z2 } from "zod";
|
|
44
|
+
var SkillIdSchema = z2.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, "id must be kebab-case");
|
|
45
|
+
var SkillCatalogPathSchema = z2.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*(?:\/[a-z0-9]+(?:-[a-z0-9]+)*)+$/, "source_path must be relative kebab-case path");
|
|
46
|
+
var SkillCatalogEntrySchema = z2.object({
|
|
81
47
|
id: SkillIdSchema,
|
|
82
48
|
kind: SkillKindSchema,
|
|
83
|
-
supported_tools:
|
|
84
|
-
groups:
|
|
85
|
-
included_in_presets: z4.array(z4.string().min(1)),
|
|
49
|
+
supported_tools: z2.array(SkillToolSchema).min(1),
|
|
50
|
+
groups: z2.array(z2.string().min(1)),
|
|
86
51
|
source_path: SkillCatalogPathSchema
|
|
87
52
|
}).strict().superRefine((entry, ctx) => {
|
|
88
53
|
const expectedPrefix = entry.kind === "reference" ? "reference-skills/" : "task-skills/";
|
|
89
54
|
if (!entry.source_path.startsWith(expectedPrefix)) {
|
|
90
55
|
ctx.addIssue({
|
|
91
|
-
code:
|
|
56
|
+
code: z2.ZodIssueCode.custom,
|
|
92
57
|
path: ["source_path"],
|
|
93
58
|
message: `source_path must start with ${expectedPrefix}`
|
|
94
59
|
});
|
|
95
60
|
}
|
|
96
61
|
});
|
|
97
|
-
var SkillCatalogSchema =
|
|
98
|
-
skills:
|
|
62
|
+
var SkillCatalogSchema = z2.object({
|
|
63
|
+
skills: z2.array(SkillCatalogEntrySchema)
|
|
99
64
|
}).strict();
|
|
100
65
|
|
|
101
66
|
// src/core/schemas/skill-registry.schema.ts
|
|
102
|
-
import { z as
|
|
103
|
-
var SkillRegistrySchema =
|
|
104
|
-
skills:
|
|
105
|
-
cliVersion:
|
|
106
|
-
generatedAt:
|
|
67
|
+
import { z as z3 } from "zod";
|
|
68
|
+
var SkillRegistrySchema = z3.object({
|
|
69
|
+
skills: z3.array(InstalledSkillSchema),
|
|
70
|
+
cliVersion: z3.string().optional(),
|
|
71
|
+
generatedAt: z3.string().datetime({ offset: true })
|
|
107
72
|
}).strict();
|
|
108
73
|
|
|
109
74
|
// src/core/schemas/subagent.schema.ts
|
|
110
|
-
import { z as
|
|
75
|
+
import { z as z5 } from "zod";
|
|
111
76
|
|
|
112
77
|
// src/core/schemas/project-layer.schema.ts
|
|
113
|
-
import { z as
|
|
114
|
-
var ProjectLayerToolSchema =
|
|
115
|
-
var ProjectLayerDocumentStatusSchema =
|
|
116
|
-
var ShortHashSchema =
|
|
78
|
+
import { z as z4 } from "zod";
|
|
79
|
+
var ProjectLayerToolSchema = z4.enum(["claude-code", "codex", "gemini"]);
|
|
80
|
+
var ProjectLayerDocumentStatusSchema = z4.enum(["Active", "Reserved", "Draft", "Archived"]);
|
|
81
|
+
var ShortHashSchema = z4.string().regex(/^[a-f0-9]{6}$/, "hash must be 6 lowercase hex chars");
|
|
117
82
|
var isSafeProjectLayerPath = (value) => {
|
|
118
83
|
if (value.length === 0) return false;
|
|
119
84
|
if (value.includes("\0")) return false;
|
|
@@ -123,55 +88,55 @@ var isSafeProjectLayerPath = (value) => {
|
|
|
123
88
|
const segments = value.split("/");
|
|
124
89
|
return segments.every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
|
|
125
90
|
};
|
|
126
|
-
var ProjectLayerPathSchema =
|
|
127
|
-
var ProjectLayerFrontmatterSchema =
|
|
91
|
+
var ProjectLayerPathSchema = z4.string().min(1).refine(isSafeProjectLayerPath, "path must be a safe project-relative path");
|
|
92
|
+
var ProjectLayerFrontmatterSchema = z4.object({
|
|
128
93
|
status: ProjectLayerDocumentStatusSchema,
|
|
129
|
-
layer:
|
|
130
|
-
owner:
|
|
131
|
-
read_when:
|
|
132
|
-
update_when:
|
|
94
|
+
layer: z4.string().min(1),
|
|
95
|
+
owner: z4.string().min(1),
|
|
96
|
+
read_when: z4.array(z4.string().min(1)).min(1),
|
|
97
|
+
update_when: z4.array(z4.string().min(1)).min(1)
|
|
133
98
|
}).strict();
|
|
134
|
-
var ProjectLayerManagedFileSchema =
|
|
99
|
+
var ProjectLayerManagedFileSchema = z4.object({
|
|
135
100
|
path: ProjectLayerPathSchema,
|
|
136
101
|
sourceHash: ShortHashSchema
|
|
137
102
|
}).strict();
|
|
138
|
-
var ProjectLayerProjectFileSchema =
|
|
103
|
+
var ProjectLayerProjectFileSchema = z4.object({
|
|
139
104
|
path: ProjectLayerPathSchema,
|
|
140
105
|
templateHash: ShortHashSchema,
|
|
141
|
-
created:
|
|
106
|
+
created: z4.boolean()
|
|
142
107
|
}).strict();
|
|
143
|
-
var ProjectLayerPackFileRecordSchema =
|
|
108
|
+
var ProjectLayerPackFileRecordSchema = z4.object({
|
|
144
109
|
path: ProjectLayerPathSchema,
|
|
145
110
|
sourceHash: ShortHashSchema
|
|
146
111
|
}).strict();
|
|
147
|
-
var ProjectLayerPackRecordSchema =
|
|
148
|
-
id:
|
|
112
|
+
var ProjectLayerPackRecordSchema = z4.object({
|
|
113
|
+
id: z4.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, "id must be kebab-case"),
|
|
149
114
|
sourceHash: ShortHashSchema,
|
|
150
|
-
documents:
|
|
151
|
-
files:
|
|
152
|
-
installedAt:
|
|
115
|
+
documents: z4.array(ProjectLayerPackFileRecordSchema),
|
|
116
|
+
files: z4.array(ProjectLayerPackFileRecordSchema),
|
|
117
|
+
installedAt: z4.string().datetime({ offset: true })
|
|
153
118
|
}).strict();
|
|
154
|
-
var ProjectLayerManifestSchema =
|
|
155
|
-
schemaVersion:
|
|
156
|
-
kind:
|
|
157
|
-
tools:
|
|
158
|
-
managed_files:
|
|
159
|
-
project_files:
|
|
160
|
-
packs:
|
|
161
|
-
settings:
|
|
119
|
+
var ProjectLayerManifestSchema = z4.object({
|
|
120
|
+
schemaVersion: z4.literal(1),
|
|
121
|
+
kind: z4.literal("project-operating-layer"),
|
|
122
|
+
tools: z4.array(ProjectLayerToolSchema).min(1),
|
|
123
|
+
managed_files: z4.array(ProjectLayerManagedFileSchema),
|
|
124
|
+
project_files: z4.array(ProjectLayerProjectFileSchema),
|
|
125
|
+
packs: z4.array(ProjectLayerPackRecordSchema).default([]),
|
|
126
|
+
settings: z4.record(z4.unknown()),
|
|
162
127
|
sourceHash: ShortHashSchema,
|
|
163
|
-
cliVersion:
|
|
164
|
-
generatedAt:
|
|
128
|
+
cliVersion: z4.string().min(1),
|
|
129
|
+
generatedAt: z4.string().datetime({ offset: true })
|
|
165
130
|
}).strict();
|
|
166
131
|
var ProjectLayerContextDocumentSchema = ProjectLayerFrontmatterSchema.extend({
|
|
167
132
|
path: ProjectLayerPathSchema,
|
|
168
133
|
contentHash: ShortHashSchema
|
|
169
134
|
}).strict();
|
|
170
|
-
var ProjectLayerContextIndexSchema =
|
|
171
|
-
schemaVersion:
|
|
172
|
-
kind:
|
|
173
|
-
documents:
|
|
174
|
-
generatedAt:
|
|
135
|
+
var ProjectLayerContextIndexSchema = z4.object({
|
|
136
|
+
schemaVersion: z4.literal(1),
|
|
137
|
+
kind: z4.literal("context-layer-index"),
|
|
138
|
+
documents: z4.array(ProjectLayerContextDocumentSchema),
|
|
139
|
+
generatedAt: z4.string().datetime({ offset: true })
|
|
175
140
|
}).strict();
|
|
176
141
|
|
|
177
142
|
// src/core/subagent-paths.ts
|
|
@@ -196,29 +161,29 @@ var buildSubagentRelativePath = (subagentId, toolId) => {
|
|
|
196
161
|
};
|
|
197
162
|
|
|
198
163
|
// src/core/schemas/subagent.schema.ts
|
|
199
|
-
var SubagentIdSchema =
|
|
200
|
-
var SubagentMarkdownFrontmatterSchema =
|
|
164
|
+
var SubagentIdSchema = z5.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, "id must be kebab-case");
|
|
165
|
+
var SubagentMarkdownFrontmatterSchema = z5.object({
|
|
201
166
|
name: SubagentIdSchema,
|
|
202
|
-
description:
|
|
167
|
+
description: z5.string().min(1)
|
|
203
168
|
}).passthrough();
|
|
204
|
-
var TomlValueSchema =
|
|
205
|
-
var SubagentInstalledPathSchema =
|
|
206
|
-
var CodexSubagentFrontmatterSchema =
|
|
169
|
+
var TomlValueSchema = z5.union([z5.string(), z5.number(), z5.boolean(), z5.array(z5.string())]);
|
|
170
|
+
var SubagentInstalledPathSchema = z5.string().min(1).refine(isSafeProjectLayerPath, "installed path must be safe relative path");
|
|
171
|
+
var CodexSubagentFrontmatterSchema = z5.object({
|
|
207
172
|
name: SubagentIdSchema,
|
|
208
|
-
description:
|
|
209
|
-
skill_names:
|
|
173
|
+
description: z5.string().min(1),
|
|
174
|
+
skill_names: z5.array(SubagentIdSchema).optional()
|
|
210
175
|
}).catchall(TomlValueSchema);
|
|
211
|
-
var InstalledSubagentSchema =
|
|
176
|
+
var InstalledSubagentSchema = z5.object({
|
|
212
177
|
id: SubagentIdSchema,
|
|
213
|
-
tools:
|
|
214
|
-
installed_paths:
|
|
215
|
-
sourceHash:
|
|
178
|
+
tools: z5.array(SkillToolSchema).min(1),
|
|
179
|
+
installed_paths: z5.array(SubagentInstalledPathSchema).min(1),
|
|
180
|
+
sourceHash: z5.string().regex(/^[a-f0-9]{6}$/, "sourceHash must be 6 lowercase hex chars")
|
|
216
181
|
}).strip().superRefine((subagent, ctx) => {
|
|
217
182
|
const expectedPaths = new Set(subagent.tools.map((tool) => buildSubagentRelativePath(subagent.id, tool)));
|
|
218
183
|
const installedPaths = new Set(subagent.installed_paths);
|
|
219
184
|
if (installedPaths.size !== subagent.installed_paths.length) {
|
|
220
185
|
ctx.addIssue({
|
|
221
|
-
code:
|
|
186
|
+
code: z5.ZodIssueCode.custom,
|
|
222
187
|
path: ["installed_paths"],
|
|
223
188
|
message: "installed_paths must not contain duplicates"
|
|
224
189
|
});
|
|
@@ -226,7 +191,7 @@ var InstalledSubagentSchema = z7.object({
|
|
|
226
191
|
}
|
|
227
192
|
if (installedPaths.size !== expectedPaths.size) {
|
|
228
193
|
ctx.addIssue({
|
|
229
|
-
code:
|
|
194
|
+
code: z5.ZodIssueCode.custom,
|
|
230
195
|
path: ["installed_paths"],
|
|
231
196
|
message: "installed_paths must match id and tools"
|
|
232
197
|
});
|
|
@@ -235,7 +200,7 @@ var InstalledSubagentSchema = z7.object({
|
|
|
235
200
|
for (const installedPath of installedPaths) {
|
|
236
201
|
if (!expectedPaths.has(installedPath)) {
|
|
237
202
|
ctx.addIssue({
|
|
238
|
-
code:
|
|
203
|
+
code: z5.ZodIssueCode.custom,
|
|
239
204
|
path: ["installed_paths"],
|
|
240
205
|
message: "installed_paths must match id and tools"
|
|
241
206
|
});
|
|
@@ -245,30 +210,30 @@ var InstalledSubagentSchema = z7.object({
|
|
|
245
210
|
});
|
|
246
211
|
|
|
247
212
|
// src/core/schemas/subagent-catalog.schema.ts
|
|
248
|
-
import { z as
|
|
249
|
-
var SubagentCatalogPathSchema =
|
|
213
|
+
import { z as z6 } from "zod";
|
|
214
|
+
var SubagentCatalogPathSchema = z6.string().regex(
|
|
250
215
|
/^[a-z0-9]+(?:-[a-z0-9]+)*(?:\/[a-z0-9]+(?:-[a-z0-9]+)*)*$/,
|
|
251
216
|
"source_path must be relative kebab-case path"
|
|
252
217
|
);
|
|
253
|
-
var SubagentCatalogEntrySchema =
|
|
218
|
+
var SubagentCatalogEntrySchema = z6.object({
|
|
254
219
|
id: SubagentIdSchema,
|
|
255
|
-
supported_tools:
|
|
220
|
+
supported_tools: z6.array(SkillToolSchema).min(1),
|
|
256
221
|
source_path: SubagentCatalogPathSchema
|
|
257
222
|
}).strict();
|
|
258
|
-
var SubagentCatalogSchema =
|
|
259
|
-
subagents:
|
|
223
|
+
var SubagentCatalogSchema = z6.object({
|
|
224
|
+
subagents: z6.array(SubagentCatalogEntrySchema)
|
|
260
225
|
}).strict();
|
|
261
226
|
|
|
262
227
|
// src/core/schemas/subagent-manifest.schema.ts
|
|
263
|
-
import { z as
|
|
264
|
-
var SubagentManifestSchema =
|
|
265
|
-
subagents:
|
|
266
|
-
cliVersion:
|
|
267
|
-
generatedAt:
|
|
228
|
+
import { z as z7 } from "zod";
|
|
229
|
+
var SubagentManifestSchema = z7.object({
|
|
230
|
+
subagents: z7.array(InstalledSubagentSchema),
|
|
231
|
+
cliVersion: z7.string().optional(),
|
|
232
|
+
generatedAt: z7.string().datetime({ offset: true })
|
|
268
233
|
}).strict();
|
|
269
234
|
|
|
270
235
|
// src/core/schemas/integration.schema.ts
|
|
271
|
-
import { z as
|
|
236
|
+
import { z as z8 } from "zod";
|
|
272
237
|
var INTEGRATION_ID = {
|
|
273
238
|
CONTEXT_PROMOTION: "context-promotion",
|
|
274
239
|
PC: "pc"
|
|
@@ -278,70 +243,70 @@ var INTEGRATION_COMPONENT_TYPE = {
|
|
|
278
243
|
CODEX_HOOK: "codex-hook",
|
|
279
244
|
RECEIPT_CONFIG: "receipt-config"
|
|
280
245
|
};
|
|
281
|
-
var IntegrationIdSchema =
|
|
282
|
-
var IntegrationSkillComponentSchema =
|
|
283
|
-
type:
|
|
284
|
-
id:
|
|
285
|
-
tools:
|
|
286
|
-
owned:
|
|
246
|
+
var IntegrationIdSchema = z8.union([z8.literal(INTEGRATION_ID.CONTEXT_PROMOTION), z8.literal(INTEGRATION_ID.PC)]);
|
|
247
|
+
var IntegrationSkillComponentSchema = z8.object({
|
|
248
|
+
type: z8.literal(INTEGRATION_COMPONENT_TYPE.SKILL),
|
|
249
|
+
id: z8.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/),
|
|
250
|
+
tools: z8.array(SkillToolSchema).min(1),
|
|
251
|
+
owned: z8.boolean()
|
|
287
252
|
}).strict();
|
|
288
|
-
var IntegrationCodexHookComponentSchema =
|
|
289
|
-
type:
|
|
253
|
+
var IntegrationCodexHookComponentSchema = z8.object({
|
|
254
|
+
type: z8.literal(INTEGRATION_COMPONENT_TYPE.CODEX_HOOK),
|
|
290
255
|
id: IntegrationIdSchema,
|
|
291
|
-
command:
|
|
292
|
-
owned:
|
|
256
|
+
command: z8.string().min(1),
|
|
257
|
+
owned: z8.boolean()
|
|
293
258
|
}).strict();
|
|
294
|
-
var IntegrationReceiptConfigComponentSchema =
|
|
295
|
-
type:
|
|
296
|
-
id:
|
|
297
|
-
storagePath:
|
|
298
|
-
owned:
|
|
259
|
+
var IntegrationReceiptConfigComponentSchema = z8.object({
|
|
260
|
+
type: z8.literal(INTEGRATION_COMPONENT_TYPE.RECEIPT_CONFIG),
|
|
261
|
+
id: z8.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/),
|
|
262
|
+
storagePath: z8.string().min(1),
|
|
263
|
+
owned: z8.boolean()
|
|
299
264
|
}).strict();
|
|
300
|
-
var IntegrationComponentSchema =
|
|
265
|
+
var IntegrationComponentSchema = z8.union([
|
|
301
266
|
IntegrationSkillComponentSchema,
|
|
302
267
|
IntegrationCodexHookComponentSchema,
|
|
303
268
|
IntegrationReceiptConfigComponentSchema
|
|
304
269
|
]);
|
|
305
|
-
var InstalledIntegrationSchema =
|
|
270
|
+
var InstalledIntegrationSchema = z8.object({
|
|
306
271
|
id: IntegrationIdSchema,
|
|
307
|
-
components:
|
|
308
|
-
installedAt:
|
|
309
|
-
updatedAt:
|
|
272
|
+
components: z8.array(IntegrationComponentSchema),
|
|
273
|
+
installedAt: z8.string().min(1),
|
|
274
|
+
updatedAt: z8.string().min(1)
|
|
310
275
|
}).strict();
|
|
311
|
-
var IntegrationManifestSchema =
|
|
312
|
-
schemaVersion:
|
|
313
|
-
kind:
|
|
314
|
-
integrations:
|
|
315
|
-
cliVersion:
|
|
316
|
-
generatedAt:
|
|
276
|
+
var IntegrationManifestSchema = z8.object({
|
|
277
|
+
schemaVersion: z8.literal(1),
|
|
278
|
+
kind: z8.literal("ai-ops-integrations-manifest"),
|
|
279
|
+
integrations: z8.array(InstalledIntegrationSchema),
|
|
280
|
+
cliVersion: z8.string().min(1),
|
|
281
|
+
generatedAt: z8.string().min(1)
|
|
317
282
|
}).strict();
|
|
318
283
|
|
|
319
284
|
// src/core/schemas/integration-catalog.schema.ts
|
|
320
|
-
import { z as
|
|
321
|
-
var ComponentIdSchema =
|
|
322
|
-
var IntegrationCatalogSkillComponentSchema =
|
|
323
|
-
type:
|
|
285
|
+
import { z as z9 } from "zod";
|
|
286
|
+
var ComponentIdSchema = z9.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, "component id must be kebab-case");
|
|
287
|
+
var IntegrationCatalogSkillComponentSchema = z9.object({
|
|
288
|
+
type: z9.literal(INTEGRATION_COMPONENT_TYPE.SKILL),
|
|
324
289
|
id: ComponentIdSchema,
|
|
325
|
-
tools:
|
|
290
|
+
tools: z9.array(z9.literal("codex")).min(1)
|
|
326
291
|
}).strict();
|
|
327
|
-
var IntegrationCatalogCodexHookComponentSchema =
|
|
328
|
-
type:
|
|
292
|
+
var IntegrationCatalogCodexHookComponentSchema = z9.object({
|
|
293
|
+
type: z9.literal(INTEGRATION_COMPONENT_TYPE.CODEX_HOOK),
|
|
329
294
|
id: IntegrationIdSchema
|
|
330
295
|
}).strict();
|
|
331
|
-
var IntegrationCatalogReceiptConfigComponentSchema =
|
|
332
|
-
type:
|
|
296
|
+
var IntegrationCatalogReceiptConfigComponentSchema = z9.object({
|
|
297
|
+
type: z9.literal(INTEGRATION_COMPONENT_TYPE.RECEIPT_CONFIG),
|
|
333
298
|
id: ComponentIdSchema,
|
|
334
|
-
storage_path:
|
|
299
|
+
storage_path: z9.string().min(1)
|
|
335
300
|
}).strict();
|
|
336
|
-
var IntegrationCatalogComponentSchema =
|
|
301
|
+
var IntegrationCatalogComponentSchema = z9.union([
|
|
337
302
|
IntegrationCatalogSkillComponentSchema,
|
|
338
303
|
IntegrationCatalogCodexHookComponentSchema,
|
|
339
304
|
IntegrationCatalogReceiptConfigComponentSchema
|
|
340
305
|
]);
|
|
341
|
-
var IntegrationCatalogEntrySchema =
|
|
306
|
+
var IntegrationCatalogEntrySchema = z9.object({
|
|
342
307
|
id: IntegrationIdSchema,
|
|
343
|
-
description:
|
|
344
|
-
components:
|
|
308
|
+
description: z9.string().min(1),
|
|
309
|
+
components: z9.array(IntegrationCatalogComponentSchema).min(1)
|
|
345
310
|
}).strict().superRefine((entry, ctx) => {
|
|
346
311
|
const hasSkill = entry.components.some((component) => component.type === INTEGRATION_COMPONENT_TYPE.SKILL);
|
|
347
312
|
const hasCodexHook = entry.components.some((component) => component.type === INTEGRATION_COMPONENT_TYPE.CODEX_HOOK);
|
|
@@ -350,34 +315,34 @@ var IntegrationCatalogEntrySchema = z11.object({
|
|
|
350
315
|
);
|
|
351
316
|
if (!hasSkill) {
|
|
352
317
|
ctx.addIssue({
|
|
353
|
-
code:
|
|
318
|
+
code: z9.ZodIssueCode.custom,
|
|
354
319
|
path: ["components"],
|
|
355
320
|
message: `integration must declare a skill component: ${entry.id}`
|
|
356
321
|
});
|
|
357
322
|
}
|
|
358
323
|
if (!hasCodexHook) {
|
|
359
324
|
ctx.addIssue({
|
|
360
|
-
code:
|
|
325
|
+
code: z9.ZodIssueCode.custom,
|
|
361
326
|
path: ["components"],
|
|
362
327
|
message: `integration must declare a codex-hook component: ${entry.id}`
|
|
363
328
|
});
|
|
364
329
|
}
|
|
365
330
|
if (!hasReceiptConfig) {
|
|
366
331
|
ctx.addIssue({
|
|
367
|
-
code:
|
|
332
|
+
code: z9.ZodIssueCode.custom,
|
|
368
333
|
path: ["components"],
|
|
369
334
|
message: `integration must declare a receipt-config component: ${entry.id}`
|
|
370
335
|
});
|
|
371
336
|
}
|
|
372
337
|
});
|
|
373
|
-
var IntegrationCatalogSchema =
|
|
374
|
-
integrations:
|
|
338
|
+
var IntegrationCatalogSchema = z9.object({
|
|
339
|
+
integrations: z9.array(IntegrationCatalogEntrySchema)
|
|
375
340
|
}).strict().superRefine((catalog, ctx) => {
|
|
376
341
|
const seen = /* @__PURE__ */ new Set();
|
|
377
342
|
for (const [index, entry] of catalog.integrations.entries()) {
|
|
378
343
|
if (seen.has(entry.id)) {
|
|
379
344
|
ctx.addIssue({
|
|
380
|
-
code:
|
|
345
|
+
code: z9.ZodIssueCode.custom,
|
|
381
346
|
path: ["integrations", index, "id"],
|
|
382
347
|
message: `duplicate integration id: ${entry.id}`
|
|
383
348
|
});
|
|
@@ -387,49 +352,15 @@ var IntegrationCatalogSchema = z11.object({
|
|
|
387
352
|
});
|
|
388
353
|
|
|
389
354
|
// src/core/schemas/pack.schema.ts
|
|
390
|
-
import { z as
|
|
391
|
-
var PackIdSchema =
|
|
392
|
-
var PackSourcePathSchema =
|
|
393
|
-
var PackCatalogEntrySchema =
|
|
355
|
+
import { z as z10 } from "zod";
|
|
356
|
+
var PackIdSchema = z10.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, "id must be kebab-case");
|
|
357
|
+
var PackSourcePathSchema = z10.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*(?:\/[a-z0-9]+(?:-[a-z0-9]+)*)*$/, "source_path must be relative kebab-case path");
|
|
358
|
+
var PackCatalogEntrySchema = z10.object({
|
|
394
359
|
id: PackIdSchema,
|
|
395
360
|
source_path: PackSourcePathSchema
|
|
396
361
|
}).strict();
|
|
397
|
-
var PackCatalogSchema =
|
|
398
|
-
packs:
|
|
399
|
-
}).strict();
|
|
400
|
-
|
|
401
|
-
// src/core/schemas/manifest.schema.ts
|
|
402
|
-
import { z as z13 } from "zod";
|
|
403
|
-
var SettingsConfigSchema = z13.object({
|
|
404
|
-
claude: z13.array(z13.string().min(1)).optional(),
|
|
405
|
-
gemini: z13.array(z13.string().min(1)).optional(),
|
|
406
|
-
prettierignore: z13.boolean().optional()
|
|
407
|
-
}).strict();
|
|
408
|
-
var WorkspaceEntrySchema = z13.object({
|
|
409
|
-
preset: z13.string().min(1),
|
|
410
|
-
rules: z13.array(z13.string().min(1))
|
|
411
|
-
}).strict();
|
|
412
|
-
var ManifestSchema = z13.object({
|
|
413
|
-
tools: z13.array(z13.string().min(1)).min(1),
|
|
414
|
-
scope: z13.literal("project"),
|
|
415
|
-
/** 비모노레포 단일 preset */
|
|
416
|
-
preset: z13.string().min(1).optional(),
|
|
417
|
-
/** 모노레포: workspace path → { preset, rules } */
|
|
418
|
-
workspaces: z13.record(z13.string(), WorkspaceEntrySchema).optional(),
|
|
419
|
-
installed_rules: z13.array(z13.string().min(1)),
|
|
420
|
-
/** 실제 디스크에 쓰여진 파일 상대 경로 목록 (uninstall용). 기존 manifest 호환성 위해 optional */
|
|
421
|
-
installed_files: z13.array(z13.string().min(1)).optional(),
|
|
422
|
-
/** skill 설치 루트 디렉토리 목록 */
|
|
423
|
-
installed_skills: z13.array(InstalledSkillSchema).optional(),
|
|
424
|
-
/** non-managed 파일에 섹션을 append한 경우 추적 (uninstall 시 섹션만 제거) */
|
|
425
|
-
appended_files: z13.array(z13.string().min(1)).optional(),
|
|
426
|
-
/** init 시 선택된 settings 항목 — update 시 재생성에 사용 */
|
|
427
|
-
settings: SettingsConfigSchema.optional(),
|
|
428
|
-
/** init/update 실행 시점의 CLI 패키지 버전 — 버전 변경 감지에 사용 */
|
|
429
|
-
cliVersion: z13.string().optional(),
|
|
430
|
-
/** SSOT 데이터 파일들의 deterministic SHA-256 해시 (6자리 hex). diff/update 판단 기준 */
|
|
431
|
-
sourceHash: z13.string().regex(/^[a-f0-9]{6}$/, "sourceHash must be 6 lowercase hex chars"),
|
|
432
|
-
generatedAt: z13.string().datetime({ offset: true })
|
|
362
|
+
var PackCatalogSchema = z10.object({
|
|
363
|
+
packs: z10.array(PackCatalogEntrySchema)
|
|
433
364
|
}).strict();
|
|
434
365
|
|
|
435
366
|
// src/core/loader.ts
|
|
@@ -543,7 +474,6 @@ var loadAllSkills = (skillsDir) => {
|
|
|
543
474
|
description: parsed.description,
|
|
544
475
|
supported_tools: [...entry.supported_tools],
|
|
545
476
|
groups: [...entry.groups],
|
|
546
|
-
included_in_presets: [...entry.included_in_presets],
|
|
547
477
|
directory,
|
|
548
478
|
files
|
|
549
479
|
};
|
|
@@ -606,16 +536,13 @@ var loadAllSubagents = (subagentsDir) => {
|
|
|
606
536
|
});
|
|
607
537
|
};
|
|
608
538
|
|
|
609
|
-
// src/core/renderer.ts
|
|
610
|
-
import { join as join3 } from "path";
|
|
611
|
-
|
|
612
539
|
// src/core/skill-renderer.ts
|
|
613
|
-
import { join as
|
|
540
|
+
import { join as join4 } from "path";
|
|
614
541
|
|
|
615
542
|
// src/core/source-hash.ts
|
|
616
543
|
import { createHash } from "crypto";
|
|
617
544
|
import { readFileSync as readFileSync2, readdirSync as readdirSync2 } from "fs";
|
|
618
|
-
import { dirname, join as
|
|
545
|
+
import { dirname, join as join3, resolve as resolve2 } from "path";
|
|
619
546
|
import { fileURLToPath } from "url";
|
|
620
547
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
621
548
|
var getCliVersion = () => {
|
|
@@ -637,10 +564,10 @@ var CLAUDE_SKILLS_DIR = ".claude/skills";
|
|
|
637
564
|
var buildRootDirs = (skillId, toolIds) => {
|
|
638
565
|
const dirs = [];
|
|
639
566
|
if (toolIds.some((toolId) => toolId === "codex" || toolId === "gemini")) {
|
|
640
|
-
dirs.push(
|
|
567
|
+
dirs.push(join4(AGENT_SKILLS_DIR, skillId));
|
|
641
568
|
}
|
|
642
569
|
if (toolIds.includes("claude-code")) {
|
|
643
|
-
dirs.push(
|
|
570
|
+
dirs.push(join4(CLAUDE_SKILLS_DIR, skillId));
|
|
644
571
|
}
|
|
645
572
|
return dirs;
|
|
646
573
|
};
|
|
@@ -662,7 +589,7 @@ var buildSkillInstallPlan = (params) => {
|
|
|
662
589
|
});
|
|
663
590
|
const packages = rootDirs.map((rootDir) => {
|
|
664
591
|
const files = params.skill.files.map((file) => ({
|
|
665
|
-
relativePath:
|
|
592
|
+
relativePath: join4(rootDir, file.path),
|
|
666
593
|
content: file.content
|
|
667
594
|
}));
|
|
668
595
|
return {
|
|
@@ -706,11 +633,9 @@ var renderCodexSubagent = (params) => {
|
|
|
706
633
|
path = ${JSON.stringify(skillPath)}
|
|
707
634
|
enabled = true`;
|
|
708
635
|
});
|
|
709
|
-
const sections = [
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
...skills
|
|
713
|
-
].filter((section) => section.length > 0);
|
|
636
|
+
const sections = [metadata, `developer_instructions = ${JSON.stringify(params.prompt.trimEnd())}`, ...skills].filter(
|
|
637
|
+
(section) => section.length > 0
|
|
638
|
+
);
|
|
714
639
|
return sections.join("\n\n") + "\n";
|
|
715
640
|
};
|
|
716
641
|
var renderSubagentForTool = (params) => {
|
|
@@ -855,77 +780,71 @@ var parseAiOpsMeta = (content) => {
|
|
|
855
780
|
return { sourceHash: match[1], generatedAt: match[2] };
|
|
856
781
|
};
|
|
857
782
|
|
|
858
|
-
// src/core/
|
|
783
|
+
// src/core/skill-registry-io.ts
|
|
859
784
|
import { mkdirSync, readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
860
|
-
import { dirname as dirname2, join as
|
|
861
|
-
|
|
862
|
-
// src/core/manifest-resolution.ts
|
|
785
|
+
import { dirname as dirname2, join as join5 } from "path";
|
|
786
|
+
var SKILL_REGISTRY_FILENAME = "skills-manifest.json";
|
|
863
787
|
var LEGACY_SKILL_ID_MAP = {
|
|
864
788
|
"engineering-standards-pack": "backend-service-standards"
|
|
865
789
|
};
|
|
866
790
|
var resolveCanonicalSkillId = (skillId) => LEGACY_SKILL_ID_MAP[skillId] ?? skillId;
|
|
867
|
-
|
|
868
|
-
// src/core/skill-registry-io.ts
|
|
869
|
-
import { mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
870
|
-
import { dirname as dirname3, join as join7 } from "path";
|
|
871
|
-
var SKILL_REGISTRY_FILENAME = "skills-manifest.json";
|
|
872
791
|
var parseSkillRegistry = (json) => SkillRegistrySchema.parse(JSON.parse(json));
|
|
873
792
|
var serializeSkillRegistry = (registry) => JSON.stringify(registry, null, 2) + "\n";
|
|
874
|
-
var resolveSkillRegistryPath = (userBasePath) =>
|
|
793
|
+
var resolveSkillRegistryPath = (userBasePath) => join5(userBasePath, ".ai-ops", SKILL_REGISTRY_FILENAME);
|
|
875
794
|
var readSkillRegistry = (registryPath) => {
|
|
876
795
|
let raw;
|
|
877
796
|
try {
|
|
878
|
-
raw =
|
|
797
|
+
raw = readFileSync3(registryPath, "utf-8");
|
|
879
798
|
} catch {
|
|
880
799
|
return null;
|
|
881
800
|
}
|
|
882
801
|
return parseSkillRegistry(raw);
|
|
883
802
|
};
|
|
884
803
|
var writeSkillRegistry = (registryPath, registry) => {
|
|
885
|
-
|
|
886
|
-
|
|
804
|
+
mkdirSync(dirname2(registryPath), { recursive: true });
|
|
805
|
+
writeFileSync(registryPath, serializeSkillRegistry(registry), "utf-8");
|
|
887
806
|
};
|
|
888
807
|
|
|
889
808
|
// src/core/subagent-manifest-io.ts
|
|
890
|
-
import { mkdirSync as
|
|
891
|
-
import { dirname as
|
|
809
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
810
|
+
import { dirname as dirname3, join as join6 } from "path";
|
|
892
811
|
var SUBAGENT_MANIFEST_FILENAME = "subagents-manifest.json";
|
|
893
812
|
var parseSubagentManifest = (json) => SubagentManifestSchema.parse(JSON.parse(json));
|
|
894
813
|
var serializeSubagentManifest = (manifest) => JSON.stringify(manifest, null, 2) + "\n";
|
|
895
|
-
var resolveSubagentManifestPath = (userBasePath) =>
|
|
814
|
+
var resolveSubagentManifestPath = (userBasePath) => join6(userBasePath, ".ai-ops", SUBAGENT_MANIFEST_FILENAME);
|
|
896
815
|
var readSubagentManifest = (manifestPath) => {
|
|
897
816
|
let raw;
|
|
898
817
|
try {
|
|
899
|
-
raw =
|
|
818
|
+
raw = readFileSync4(manifestPath, "utf-8");
|
|
900
819
|
} catch {
|
|
901
820
|
return null;
|
|
902
821
|
}
|
|
903
822
|
return parseSubagentManifest(raw);
|
|
904
823
|
};
|
|
905
824
|
var writeSubagentManifest = (manifestPath, manifest) => {
|
|
906
|
-
|
|
907
|
-
|
|
825
|
+
mkdirSync2(dirname3(manifestPath), { recursive: true });
|
|
826
|
+
writeFileSync2(manifestPath, serializeSubagentManifest(manifest), "utf-8");
|
|
908
827
|
};
|
|
909
828
|
|
|
910
829
|
// src/core/integration-manifest-io.ts
|
|
911
|
-
import { mkdirSync as
|
|
912
|
-
import { dirname as
|
|
830
|
+
import { mkdirSync as mkdirSync3, readFileSync as readFileSync5, rmSync, writeFileSync as writeFileSync3 } from "fs";
|
|
831
|
+
import { dirname as dirname4, join as join7 } from "path";
|
|
913
832
|
var INTEGRATION_MANIFEST_FILENAME = "integrations-manifest.json";
|
|
914
833
|
var parseIntegrationManifest = (json) => IntegrationManifestSchema.parse(JSON.parse(json));
|
|
915
834
|
var serializeIntegrationManifest = (manifest) => JSON.stringify(manifest, null, 2) + "\n";
|
|
916
|
-
var resolveIntegrationManifestPath = (userBasePath) =>
|
|
835
|
+
var resolveIntegrationManifestPath = (userBasePath) => join7(userBasePath, ".ai-ops", INTEGRATION_MANIFEST_FILENAME);
|
|
917
836
|
var readIntegrationManifest = (manifestPath) => {
|
|
918
837
|
let raw;
|
|
919
838
|
try {
|
|
920
|
-
raw =
|
|
839
|
+
raw = readFileSync5(manifestPath, "utf-8");
|
|
921
840
|
} catch {
|
|
922
841
|
return null;
|
|
923
842
|
}
|
|
924
843
|
return parseIntegrationManifest(raw);
|
|
925
844
|
};
|
|
926
845
|
var writeIntegrationManifest = (manifestPath, manifest) => {
|
|
927
|
-
|
|
928
|
-
|
|
846
|
+
mkdirSync3(dirname4(manifestPath), { recursive: true });
|
|
847
|
+
writeFileSync3(manifestPath, serializeIntegrationManifest(manifest), "utf-8");
|
|
929
848
|
};
|
|
930
849
|
var findInstalledIntegration = (integrations, integrationId) => integrations.find((integration) => integration.id === integrationId);
|
|
931
850
|
var upsertInstalledIntegration = (integrations, nextIntegration) => [
|
|
@@ -949,23 +868,20 @@ var writeUserIntegrationState = (params) => {
|
|
|
949
868
|
});
|
|
950
869
|
};
|
|
951
870
|
|
|
952
|
-
// src/core/install-plan.ts
|
|
953
|
-
import { join as join10 } from "path";
|
|
954
|
-
|
|
955
871
|
// src/core/project-layer.ts
|
|
956
|
-
import { existsSync, mkdirSync as
|
|
957
|
-
import { dirname as
|
|
872
|
+
import { existsSync, mkdirSync as mkdirSync4, readFileSync as readFileSync6, readdirSync as readdirSync3, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
873
|
+
import { dirname as dirname6, isAbsolute, join as join8, relative, resolve as resolve5 } from "path";
|
|
958
874
|
|
|
959
875
|
// src/core/paths.ts
|
|
960
|
-
import { dirname as
|
|
876
|
+
import { dirname as dirname5, resolve as resolve4 } from "path";
|
|
961
877
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
962
|
-
var __dirname2 =
|
|
878
|
+
var __dirname2 = dirname5(fileURLToPath2(import.meta.url));
|
|
963
879
|
var COMPILER_DATA_DIR = resolve4(__dirname2, "..", "..", "data");
|
|
964
880
|
|
|
965
881
|
// src/core/project-layer.ts
|
|
966
882
|
var PROJECT_LAYER_MANIFEST_RELATIVE_PATH = ".ai-ops/manifest.json";
|
|
967
883
|
var PROJECT_LAYER_CONTEXT_INDEX_RELATIVE_PATH = ".ai-ops/context-layer.json";
|
|
968
|
-
var CONTEXT_LAYER_DATA_DIR =
|
|
884
|
+
var CONTEXT_LAYER_DATA_DIR = join8(COMPILER_DATA_DIR, "context-layer");
|
|
969
885
|
var TOOL_ORDER = ["codex", "gemini", "claude-code"];
|
|
970
886
|
var DEFAULT_TOOLS = TOOL_ORDER;
|
|
971
887
|
var TEMPLATE_PATHS = [
|
|
@@ -978,7 +894,6 @@ var TEMPLATE_PATHS = [
|
|
|
978
894
|
"docs/agent/rules/doc-update-rules.md",
|
|
979
895
|
"docs/agent/rules/stop-rules.md",
|
|
980
896
|
"docs/agent/checks/impact-checklist.md",
|
|
981
|
-
"docs/agent/checks/review-checklist.md",
|
|
982
897
|
"docs/agent/maps/codebase-map.md",
|
|
983
898
|
"docs/business/business-rules.md",
|
|
984
899
|
"docs/docs-status.md"
|
|
@@ -992,10 +907,10 @@ var RESERVED_DOCUMENT_WARNINGS = [
|
|
|
992
907
|
"\uD310\uB2E8 \uADFC\uAC70\uB85C \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694",
|
|
993
908
|
"Do not use this document as current decision-making evidence"
|
|
994
909
|
];
|
|
995
|
-
var resolveProjectLayerManifestPath = (basePath) =>
|
|
996
|
-
var resolveProjectLayerContextIndexPath = (basePath) =>
|
|
997
|
-
var resolveTemplatePath = (relativePath) =>
|
|
998
|
-
var toRelativeDir = (relativePath) =>
|
|
910
|
+
var resolveProjectLayerManifestPath = (basePath) => join8(basePath, PROJECT_LAYER_MANIFEST_RELATIVE_PATH);
|
|
911
|
+
var resolveProjectLayerContextIndexPath = (basePath) => join8(basePath, PROJECT_LAYER_CONTEXT_INDEX_RELATIVE_PATH);
|
|
912
|
+
var resolveTemplatePath = (relativePath) => join8(CONTEXT_LAYER_DATA_DIR, relativePath);
|
|
913
|
+
var toRelativeDir = (relativePath) => dirname6(relativePath);
|
|
999
914
|
var resolveProjectLayerFilePath = (basePath, relativePath) => {
|
|
1000
915
|
if (!isSafeProjectLayerPath(relativePath)) {
|
|
1001
916
|
throw new Error(`Unsafe project layer path: ${relativePath}`);
|
|
@@ -1110,8 +1025,8 @@ var loadTemplateSpec = (relativePath, content) => {
|
|
|
1110
1025
|
};
|
|
1111
1026
|
var loadProjectLayerTemplateSpecs = (tools) => {
|
|
1112
1027
|
const selectedPaths = TEMPLATE_PATHS.filter((relativePath) => shouldIncludeTemplate(relativePath, tools));
|
|
1113
|
-
const nonStatusSpecs = selectedPaths.filter((relativePath) => relativePath !== "docs/docs-status.md").map((relativePath) => loadTemplateSpec(relativePath,
|
|
1114
|
-
const statusTemplate =
|
|
1028
|
+
const nonStatusSpecs = selectedPaths.filter((relativePath) => relativePath !== "docs/docs-status.md").map((relativePath) => loadTemplateSpec(relativePath, readFileSync6(resolveTemplatePath(relativePath), "utf-8")));
|
|
1029
|
+
const statusTemplate = readFileSync6(resolveTemplatePath("docs/docs-status.md"), "utf-8");
|
|
1115
1030
|
const statusPlaceholderSpec = loadTemplateSpec("docs/docs-status.md", statusTemplate);
|
|
1116
1031
|
const specsForStatus = [...nonStatusSpecs, statusPlaceholderSpec].sort((a, b) => a.path.localeCompare(b.path));
|
|
1117
1032
|
const statusContent = statusTemplate.replace("{{documents_table}}", buildDocsStatusRows(specsForStatus));
|
|
@@ -1121,7 +1036,7 @@ var loadProjectLayerTemplateSpecs = (tools) => {
|
|
|
1121
1036
|
var computeProjectLayerSourceHash = (specs) => computeHash(specs.map((spec) => `${spec.path}:${spec.content}`));
|
|
1122
1037
|
var readProjectLayerManifest = (basePath) => {
|
|
1123
1038
|
try {
|
|
1124
|
-
return parseProjectLayerManifest(
|
|
1039
|
+
return parseProjectLayerManifest(readFileSync6(resolveProjectLayerManifestPath(basePath), "utf-8"));
|
|
1125
1040
|
} catch (error) {
|
|
1126
1041
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
1127
1042
|
return null;
|
|
@@ -1131,12 +1046,12 @@ var readProjectLayerManifest = (basePath) => {
|
|
|
1131
1046
|
};
|
|
1132
1047
|
var writeProjectLayerManifest = (basePath, manifest) => {
|
|
1133
1048
|
const manifestPath = resolveProjectLayerManifestPath(basePath);
|
|
1134
|
-
|
|
1135
|
-
|
|
1049
|
+
mkdirSync4(dirname6(manifestPath), { recursive: true });
|
|
1050
|
+
writeFileSync4(manifestPath, serializeProjectLayerManifest(manifest), "utf-8");
|
|
1136
1051
|
};
|
|
1137
1052
|
var readProjectLayerContextIndex = (basePath) => {
|
|
1138
1053
|
try {
|
|
1139
|
-
return parseProjectLayerContextIndex(
|
|
1054
|
+
return parseProjectLayerContextIndex(readFileSync6(resolveProjectLayerContextIndexPath(basePath), "utf-8"));
|
|
1140
1055
|
} catch (error) {
|
|
1141
1056
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
1142
1057
|
return null;
|
|
@@ -1146,8 +1061,8 @@ var readProjectLayerContextIndex = (basePath) => {
|
|
|
1146
1061
|
};
|
|
1147
1062
|
var writeProjectLayerContextIndex = (basePath, contextIndex) => {
|
|
1148
1063
|
const contextIndexPath = resolveProjectLayerContextIndexPath(basePath);
|
|
1149
|
-
|
|
1150
|
-
|
|
1064
|
+
mkdirSync4(dirname6(contextIndexPath), { recursive: true });
|
|
1065
|
+
writeFileSync4(contextIndexPath, serializeProjectLayerContextIndex(contextIndex), "utf-8");
|
|
1151
1066
|
};
|
|
1152
1067
|
var installManagedFiles = (basePath, specs, meta) => {
|
|
1153
1068
|
const written = [];
|
|
@@ -1156,24 +1071,24 @@ var installManagedFiles = (basePath, specs, meta) => {
|
|
|
1156
1071
|
const absolutePath = resolveProjectLayerFilePath(basePath, spec.path);
|
|
1157
1072
|
const wrappedContent = wrapWithSection(spec.content, meta);
|
|
1158
1073
|
if (!existsSync(absolutePath)) {
|
|
1159
|
-
|
|
1160
|
-
|
|
1074
|
+
mkdirSync4(dirname6(absolutePath), { recursive: true });
|
|
1075
|
+
writeFileSync4(absolutePath, wrappedContent + "\n", "utf-8");
|
|
1161
1076
|
written.push(spec.path);
|
|
1162
1077
|
continue;
|
|
1163
1078
|
}
|
|
1164
|
-
const existing =
|
|
1079
|
+
const existing = readFileSync6(absolutePath, "utf-8");
|
|
1165
1080
|
if (hasAiOpsSection(existing)) {
|
|
1166
|
-
|
|
1081
|
+
writeFileSync4(absolutePath, replaceAiOpsSection(existing, wrappedContent), "utf-8");
|
|
1167
1082
|
const stripped = stripAiOpsSection(existing);
|
|
1168
1083
|
(stripped.trim().length > 0 ? appended : written).push(spec.path);
|
|
1169
1084
|
continue;
|
|
1170
1085
|
}
|
|
1171
1086
|
if (hasLegacyHeader(existing)) {
|
|
1172
|
-
|
|
1087
|
+
writeFileSync4(absolutePath, wrappedContent + "\n", "utf-8");
|
|
1173
1088
|
written.push(spec.path);
|
|
1174
1089
|
continue;
|
|
1175
1090
|
}
|
|
1176
|
-
|
|
1091
|
+
writeFileSync4(absolutePath, existing.trimEnd() + "\n\n" + wrappedContent + "\n", "utf-8");
|
|
1177
1092
|
appended.push(spec.path);
|
|
1178
1093
|
}
|
|
1179
1094
|
return { written, appended };
|
|
@@ -1188,8 +1103,8 @@ var installProjectFiles = (params) => {
|
|
|
1188
1103
|
const absolutePath = resolveProjectLayerFilePath(params.basePath, spec.path);
|
|
1189
1104
|
const previous = previousByPath.get(spec.path);
|
|
1190
1105
|
if (!existsSync(absolutePath)) {
|
|
1191
|
-
|
|
1192
|
-
|
|
1106
|
+
mkdirSync4(dirname6(absolutePath), { recursive: true });
|
|
1107
|
+
writeFileSync4(absolutePath, spec.content + "\n", "utf-8");
|
|
1193
1108
|
created.push(spec.path);
|
|
1194
1109
|
records.push({
|
|
1195
1110
|
path: spec.path,
|
|
@@ -1198,11 +1113,11 @@ var installProjectFiles = (params) => {
|
|
|
1198
1113
|
});
|
|
1199
1114
|
continue;
|
|
1200
1115
|
}
|
|
1201
|
-
const existingContent =
|
|
1116
|
+
const existingContent = readFileSync6(absolutePath, "utf-8").trimEnd();
|
|
1202
1117
|
const existingHash = computeHash([existingContent]);
|
|
1203
1118
|
if (previous?.created === true && existingHash === previous.templateHash) {
|
|
1204
1119
|
if (existingHash !== spec.contentHash) {
|
|
1205
|
-
|
|
1120
|
+
writeFileSync4(absolutePath, spec.content + "\n", "utf-8");
|
|
1206
1121
|
refreshed.push(spec.path);
|
|
1207
1122
|
} else {
|
|
1208
1123
|
preserved.push(spec.path);
|
|
@@ -1225,7 +1140,7 @@ var installProjectFiles = (params) => {
|
|
|
1225
1140
|
};
|
|
1226
1141
|
var buildContextIndexFromDisk = (params) => {
|
|
1227
1142
|
const documents = params.documentPaths.map(
|
|
1228
|
-
(path) => parseProjectLayerDocument(path,
|
|
1143
|
+
(path) => parseProjectLayerDocument(path, readFileSync6(resolveProjectLayerFilePath(params.basePath, path), "utf-8"))
|
|
1229
1144
|
);
|
|
1230
1145
|
return ProjectLayerContextIndexSchema.parse({
|
|
1231
1146
|
schemaVersion: 1,
|
|
@@ -1234,14 +1149,14 @@ var buildContextIndexFromDisk = (params) => {
|
|
|
1234
1149
|
generatedAt: params.generatedAt
|
|
1235
1150
|
});
|
|
1236
1151
|
};
|
|
1237
|
-
var computeProjectFileHash = (basePath, relativePath) => computeHash([
|
|
1152
|
+
var computeProjectFileHash = (basePath, relativePath) => computeHash([readFileSync6(resolveProjectLayerFilePath(basePath, relativePath), "utf-8").trimEnd()]);
|
|
1238
1153
|
var collectDocumentPathsFromManifest = (manifest) => [
|
|
1239
1154
|
...manifest.managed_files.map((file) => file.path),
|
|
1240
1155
|
...manifest.project_files.map((file) => file.path),
|
|
1241
1156
|
...manifest.packs.flatMap((pack) => pack.documents.map((file) => file.path))
|
|
1242
1157
|
].sort();
|
|
1243
1158
|
var buildDocsStatusRowsFromDisk = (params) => params.documentPaths.map((path) => {
|
|
1244
|
-
const document = parseProjectLayerDocument(path,
|
|
1159
|
+
const document = parseProjectLayerDocument(path, readFileSync6(resolveProjectLayerFilePath(params.basePath, path), "utf-8"));
|
|
1245
1160
|
return `| ${document.path} | ${document.status} | ${document.owner} |`;
|
|
1246
1161
|
});
|
|
1247
1162
|
var replaceDocsStatusRows = (content, rows) => {
|
|
@@ -1257,8 +1172,8 @@ var updateDocsStatusTable = (basePath, documentPaths) => {
|
|
|
1257
1172
|
const absolutePath = resolveProjectLayerFilePath(basePath, docsStatusPath);
|
|
1258
1173
|
const beforeHash = computeProjectFileHash(basePath, docsStatusPath);
|
|
1259
1174
|
const rows = buildDocsStatusRowsFromDisk({ basePath, documentPaths });
|
|
1260
|
-
const nextContent = replaceDocsStatusRows(
|
|
1261
|
-
|
|
1175
|
+
const nextContent = replaceDocsStatusRows(readFileSync6(absolutePath, "utf-8"), rows);
|
|
1176
|
+
writeFileSync4(absolutePath, nextContent, "utf-8");
|
|
1262
1177
|
return {
|
|
1263
1178
|
beforeHash,
|
|
1264
1179
|
afterHash: computeProjectFileHash(basePath, docsStatusPath)
|
|
@@ -1413,7 +1328,7 @@ var readDocumentSafely = (basePath, path) => {
|
|
|
1413
1328
|
if (!existsSync(absolutePath)) {
|
|
1414
1329
|
return issue("error", "missing-file", `\uD30C\uC77C \uC5C6\uC74C: ${path}`);
|
|
1415
1330
|
}
|
|
1416
|
-
return parseProjectLayerDocument(path,
|
|
1331
|
+
return parseProjectLayerDocument(path, readFileSync6(absolutePath, "utf-8"));
|
|
1417
1332
|
} catch (error) {
|
|
1418
1333
|
const reason = error instanceof Error ? error.message : "unknown error";
|
|
1419
1334
|
return issue("error", "invalid-frontmatter", `${path} frontmatter \uD30C\uC2F1 \uC2E4\uD328: ${reason}`);
|
|
@@ -1508,7 +1423,7 @@ var diffProjectLayer = (basePath) => {
|
|
|
1508
1423
|
issues.push(issue("error", "missing-file", `\uD30C\uC77C \uC5C6\uC74C: ${file.path}`));
|
|
1509
1424
|
continue;
|
|
1510
1425
|
}
|
|
1511
|
-
const content =
|
|
1426
|
+
const content = readFileSync6(absolutePath, "utf-8");
|
|
1512
1427
|
const meta = parseAiOpsMeta(content);
|
|
1513
1428
|
if (!meta) {
|
|
1514
1429
|
issues.push(issue("error", "missing-managed-section", `managed section \uBA54\uD0C0 \uC5C6\uC74C: ${file.path}`));
|
|
@@ -1570,7 +1485,7 @@ var auditProjectLayer = (basePath) => {
|
|
|
1570
1485
|
}
|
|
1571
1486
|
let docsStatusEntries = [];
|
|
1572
1487
|
try {
|
|
1573
|
-
docsStatusEntries = parseDocsStatusEntries(
|
|
1488
|
+
docsStatusEntries = parseDocsStatusEntries(readFileSync6(docsStatusPath, "utf-8"));
|
|
1574
1489
|
} catch (error) {
|
|
1575
1490
|
const reason = error instanceof Error ? error.message : "unknown error";
|
|
1576
1491
|
issues.push(issue("error", "invalid-docs-status", `docs/docs-status.md \uD30C\uC2F1 \uC2E4\uD328: ${reason}`));
|
|
@@ -1600,7 +1515,7 @@ function removeManagedProjectFile(basePath, relativePath) {
|
|
|
1600
1515
|
if (!existsSync(absolutePath)) {
|
|
1601
1516
|
return { deleted: [], cleaned: [], preserved: [], notFound: [relativePath] };
|
|
1602
1517
|
}
|
|
1603
|
-
const content =
|
|
1518
|
+
const content = readFileSync6(absolutePath, "utf-8");
|
|
1604
1519
|
if (!hasAiOpsSection(content)) {
|
|
1605
1520
|
return { deleted: [], cleaned: [], preserved: [relativePath], notFound: [] };
|
|
1606
1521
|
}
|
|
@@ -1609,7 +1524,7 @@ function removeManagedProjectFile(basePath, relativePath) {
|
|
|
1609
1524
|
rmSync2(absolutePath);
|
|
1610
1525
|
return { deleted: [relativePath], cleaned: [], preserved: [], notFound: [] };
|
|
1611
1526
|
}
|
|
1612
|
-
|
|
1527
|
+
writeFileSync4(absolutePath, stripped, "utf-8");
|
|
1613
1528
|
return { deleted: [], cleaned: [relativePath], preserved: [], notFound: [] };
|
|
1614
1529
|
}
|
|
1615
1530
|
var removeCreateOnlyProjectFile = (basePath, file) => {
|
|
@@ -1617,7 +1532,7 @@ var removeCreateOnlyProjectFile = (basePath, file) => {
|
|
|
1617
1532
|
if (!existsSync(absolutePath)) {
|
|
1618
1533
|
return { deleted: [], cleaned: [], preserved: [], notFound: [file.path] };
|
|
1619
1534
|
}
|
|
1620
|
-
const content =
|
|
1535
|
+
const content = readFileSync6(absolutePath, "utf-8").trimEnd();
|
|
1621
1536
|
const currentHash = computeHash([content]);
|
|
1622
1537
|
if (file.created && currentHash === file.templateHash) {
|
|
1623
1538
|
rmSync2(absolutePath);
|
|
@@ -1630,7 +1545,7 @@ var removePackOwnedFile = (basePath, file) => {
|
|
|
1630
1545
|
if (!existsSync(absolutePath)) {
|
|
1631
1546
|
return { deleted: [], cleaned: [], preserved: [], notFound: [file.path] };
|
|
1632
1547
|
}
|
|
1633
|
-
const currentHash = computeHash([
|
|
1548
|
+
const currentHash = computeHash([readFileSync6(absolutePath, "utf-8").trimEnd()]);
|
|
1634
1549
|
if (currentHash === file.sourceHash) {
|
|
1635
1550
|
rmSync2(absolutePath);
|
|
1636
1551
|
return { deleted: [file.path], cleaned: [], preserved: [], notFound: [] };
|
|
@@ -1674,8 +1589,8 @@ var uninstallProjectLayer = (basePath, manifest) => {
|
|
|
1674
1589
|
};
|
|
1675
1590
|
|
|
1676
1591
|
// src/core/pack.ts
|
|
1677
|
-
import { existsSync as existsSync2, mkdirSync as
|
|
1678
|
-
import { dirname as
|
|
1592
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync5, readFileSync as readFileSync7, readdirSync as readdirSync4, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "fs";
|
|
1593
|
+
import { dirname as dirname7, isAbsolute as isAbsolute2, join as join9, relative as relative2, resolve as resolve6 } from "path";
|
|
1679
1594
|
var PACK_REGISTRY_FILENAME = "pack-registry.json";
|
|
1680
1595
|
var SPEC_LIFECYCLE_PACK_ID = "spec-lifecycle";
|
|
1681
1596
|
var PACK_INSTALL_ROOT = "docs/specs/";
|
|
@@ -1683,9 +1598,9 @@ var RESERVED_DOCUMENT_WARNINGS2 = [
|
|
|
1683
1598
|
"\uD310\uB2E8 \uADFC\uAC70\uB85C \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694",
|
|
1684
1599
|
"Do not use this document as current decision-making evidence"
|
|
1685
1600
|
];
|
|
1686
|
-
var DEFAULT_PACKS_DIR =
|
|
1601
|
+
var DEFAULT_PACKS_DIR = join9(COMPILER_DATA_DIR, "packs");
|
|
1687
1602
|
var includesReservedDocumentWarning2 = (content) => RESERVED_DOCUMENT_WARNINGS2.some((warning) => content.includes(warning));
|
|
1688
|
-
var readPackCatalog = (packsDir) => PackCatalogSchema.parse(JSON.parse(
|
|
1603
|
+
var readPackCatalog = (packsDir) => PackCatalogSchema.parse(JSON.parse(readFileSync7(join9(packsDir, PACK_REGISTRY_FILENAME), "utf-8")));
|
|
1689
1604
|
var assertPackInstallPath = (path) => {
|
|
1690
1605
|
if (!isSafeProjectLayerPath(path) || !path.startsWith(PACK_INSTALL_ROOT)) {
|
|
1691
1606
|
throw new Error(`Unsafe pack path: ${path}`);
|
|
@@ -1694,16 +1609,16 @@ var assertPackInstallPath = (path) => {
|
|
|
1694
1609
|
var readPackSourceFiles = (packDir) => {
|
|
1695
1610
|
const files = [];
|
|
1696
1611
|
const walk = (relativeDir = "") => {
|
|
1697
|
-
const absoluteDir = relativeDir.length > 0 ?
|
|
1612
|
+
const absoluteDir = relativeDir.length > 0 ? join9(packDir, relativeDir) : packDir;
|
|
1698
1613
|
const entries = readdirSync4(absoluteDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
1699
1614
|
for (const entry of entries) {
|
|
1700
|
-
const nextRelativePath = relativeDir.length > 0 ?
|
|
1615
|
+
const nextRelativePath = relativeDir.length > 0 ? join9(relativeDir, entry.name) : entry.name;
|
|
1701
1616
|
if (entry.isDirectory()) {
|
|
1702
1617
|
walk(nextRelativePath);
|
|
1703
1618
|
continue;
|
|
1704
1619
|
}
|
|
1705
1620
|
assertPackInstallPath(nextRelativePath);
|
|
1706
|
-
const content =
|
|
1621
|
+
const content = readFileSync7(join9(packDir, nextRelativePath), "utf-8");
|
|
1707
1622
|
files.push({
|
|
1708
1623
|
path: nextRelativePath,
|
|
1709
1624
|
content,
|
|
@@ -1761,11 +1676,11 @@ var resolvePackById = (packsDir, packId) => {
|
|
|
1761
1676
|
return pack;
|
|
1762
1677
|
};
|
|
1763
1678
|
var serializePackFileContent = (content) => content.length === 0 ? "" : content.trimEnd() + "\n";
|
|
1764
|
-
var readProjectFileHash = (basePath, relativePath) => computeHash([
|
|
1679
|
+
var readProjectFileHash = (basePath, relativePath) => computeHash([readFileSync7(resolveProjectLayerFilePath(basePath, relativePath), "utf-8").trimEnd()]);
|
|
1765
1680
|
var writePackFile = (basePath, file) => {
|
|
1766
1681
|
const absolutePath = resolveProjectLayerFilePath(basePath, file.path);
|
|
1767
|
-
|
|
1768
|
-
|
|
1682
|
+
mkdirSync5(dirname7(absolutePath), { recursive: true });
|
|
1683
|
+
writeFileSync5(absolutePath, serializePackFileContent(file.content), "utf-8");
|
|
1769
1684
|
};
|
|
1770
1685
|
var buildPackFileRecords = (files) => files.map((file) => ({
|
|
1771
1686
|
path: file.path,
|
|
@@ -1852,7 +1767,7 @@ var removePackFiles = (basePath, record) => {
|
|
|
1852
1767
|
return { written: [], refreshed: [], preserved, deleted, notFound };
|
|
1853
1768
|
};
|
|
1854
1769
|
var removeEmptyDirs2 = (basePath, relativePaths) => {
|
|
1855
|
-
const dirs = [...new Set(relativePaths.map((path) =>
|
|
1770
|
+
const dirs = [...new Set(relativePaths.map((path) => dirname7(path)).filter((dir) => dir !== "."))].sort(
|
|
1856
1771
|
(a, b) => b.length - a.length
|
|
1857
1772
|
);
|
|
1858
1773
|
for (const dir of dirs) {
|
|
@@ -1981,27 +1896,24 @@ var diffProjectLayerPack = (params) => {
|
|
|
1981
1896
|
return { issues };
|
|
1982
1897
|
};
|
|
1983
1898
|
|
|
1984
|
-
// src/core/uninstall-plan.ts
|
|
1985
|
-
import { join as join13 } from "path";
|
|
1986
|
-
|
|
1987
1899
|
// src/core/context-promotion.ts
|
|
1988
1900
|
import { createHash as createHash2 } from "crypto";
|
|
1989
1901
|
import { execFileSync } from "child_process";
|
|
1990
|
-
import { existsSync as existsSync3, mkdirSync as
|
|
1991
|
-
import { dirname as
|
|
1992
|
-
import { z as
|
|
1902
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync6, readFileSync as readFileSync8, statSync, writeFileSync as writeFileSync6 } from "fs";
|
|
1903
|
+
import { dirname as dirname8, join as join10, resolve as resolve7 } from "path";
|
|
1904
|
+
import { z as z12 } from "zod";
|
|
1993
1905
|
|
|
1994
1906
|
// src/core/tool-use-hook.ts
|
|
1995
|
-
import { z as
|
|
1996
|
-
var HookToolInputSchema =
|
|
1997
|
-
command:
|
|
1907
|
+
import { z as z11 } from "zod";
|
|
1908
|
+
var HookToolInputSchema = z11.object({
|
|
1909
|
+
command: z11.string().optional()
|
|
1998
1910
|
}).passthrough();
|
|
1999
|
-
var ToolUseHookInputSchema =
|
|
2000
|
-
hook_event_name:
|
|
2001
|
-
cwd:
|
|
2002
|
-
tool_name:
|
|
2003
|
-
tool_input:
|
|
2004
|
-
tool_response:
|
|
1911
|
+
var ToolUseHookInputSchema = z11.object({
|
|
1912
|
+
hook_event_name: z11.string(),
|
|
1913
|
+
cwd: z11.string(),
|
|
1914
|
+
tool_name: z11.string().optional(),
|
|
1915
|
+
tool_input: z11.unknown().optional(),
|
|
1916
|
+
tool_response: z11.unknown().optional()
|
|
2005
1917
|
}).passthrough();
|
|
2006
1918
|
var SHELL_CONTROL_TOKENS = /* @__PURE__ */ new Set(["&&", "||", ";", "|", "(", ")"]);
|
|
2007
1919
|
var SHELL_SCRIPT_FLAGS = /* @__PURE__ */ new Set(["-c", "-lc"]);
|
|
@@ -2218,30 +2130,30 @@ var CONTEXT_PROMOTION_SCOPE = {
|
|
|
2218
2130
|
PROJECT_LOCAL: "project-local",
|
|
2219
2131
|
GLOBAL: "global"
|
|
2220
2132
|
};
|
|
2221
|
-
var ContextPromotionDecisionSchema =
|
|
2222
|
-
|
|
2223
|
-
|
|
2133
|
+
var ContextPromotionDecisionSchema = z12.union([
|
|
2134
|
+
z12.literal(CONTEXT_PROMOTION_DECISION.PROMOTED),
|
|
2135
|
+
z12.literal(CONTEXT_PROMOTION_DECISION.NO_PROMOTION)
|
|
2224
2136
|
]);
|
|
2225
|
-
var ContextPromotionScopeSchema =
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2137
|
+
var ContextPromotionScopeSchema = z12.union([
|
|
2138
|
+
z12.literal(CONTEXT_PROMOTION_SCOPE.CORE),
|
|
2139
|
+
z12.literal(CONTEXT_PROMOTION_SCOPE.PROJECT_LOCAL),
|
|
2140
|
+
z12.literal(CONTEXT_PROMOTION_SCOPE.GLOBAL)
|
|
2229
2141
|
]);
|
|
2230
|
-
var ContextPromotionReceiptSchema =
|
|
2231
|
-
fingerprint:
|
|
2232
|
-
commitHash:
|
|
2142
|
+
var ContextPromotionReceiptSchema = z12.object({
|
|
2143
|
+
fingerprint: z12.string().regex(/^[a-f0-9]{16}$/),
|
|
2144
|
+
commitHash: z12.string().regex(/^(NO_HEAD|[a-f0-9]{40})$/).optional(),
|
|
2233
2145
|
decision: ContextPromotionDecisionSchema,
|
|
2234
|
-
scopes:
|
|
2235
|
-
targets:
|
|
2236
|
-
summary:
|
|
2237
|
-
resolvedAt:
|
|
2146
|
+
scopes: z12.array(ContextPromotionScopeSchema),
|
|
2147
|
+
targets: z12.array(z12.string().min(1)),
|
|
2148
|
+
summary: z12.string().min(1),
|
|
2149
|
+
resolvedAt: z12.string().min(1)
|
|
2238
2150
|
}).strict();
|
|
2239
|
-
var ContextPromotionReceiptIndexSchema =
|
|
2240
|
-
schemaVersion:
|
|
2241
|
-
kind:
|
|
2242
|
-
projectKey:
|
|
2243
|
-
projectRoot:
|
|
2244
|
-
receipts:
|
|
2151
|
+
var ContextPromotionReceiptIndexSchema = z12.object({
|
|
2152
|
+
schemaVersion: z12.literal(1),
|
|
2153
|
+
kind: z12.literal("context-promotion-receipts"),
|
|
2154
|
+
projectKey: z12.string().regex(/^[a-f0-9]{12}$/),
|
|
2155
|
+
projectRoot: z12.string().min(1),
|
|
2156
|
+
receipts: z12.array(ContextPromotionReceiptSchema)
|
|
2245
2157
|
}).strict();
|
|
2246
2158
|
var RECEIPT_INDEX_FILENAME = "receipts-index.json";
|
|
2247
2159
|
var DEFAULT_PRUNE_MAX = 50;
|
|
@@ -2271,13 +2183,13 @@ var readUntrackedFingerprintParts = (gitRoot) => {
|
|
|
2271
2183
|
const raw = runGit(gitRoot, ["ls-files", "--others", "--exclude-standard", "-z"]);
|
|
2272
2184
|
const paths = raw.split("\0").filter((path) => path.length > 0).sort((a, b) => a.localeCompare(b));
|
|
2273
2185
|
return paths.map((relativePath) => {
|
|
2274
|
-
const absolutePath =
|
|
2186
|
+
const absolutePath = join10(gitRoot, relativePath);
|
|
2275
2187
|
try {
|
|
2276
2188
|
const stat = statSync(absolutePath);
|
|
2277
2189
|
if (!stat.isFile()) {
|
|
2278
2190
|
return `${relativePath}:non-file`;
|
|
2279
2191
|
}
|
|
2280
|
-
const content =
|
|
2192
|
+
const content = readFileSync8(absolutePath);
|
|
2281
2193
|
return `${relativePath}:${createHash2("sha256").update(content).digest("hex")}`;
|
|
2282
2194
|
} catch {
|
|
2283
2195
|
throw new Error(`Unable to read untracked path for context promotion fingerprint: ${relativePath}`);
|
|
@@ -2291,7 +2203,7 @@ var readTrackedWorkingTreeFingerprintParts = (gitRoot) => {
|
|
|
2291
2203
|
return [
|
|
2292
2204
|
`raw:${rawDiff}`,
|
|
2293
2205
|
...paths.map((relativePath) => {
|
|
2294
|
-
const absolutePath =
|
|
2206
|
+
const absolutePath = join10(gitRoot, relativePath);
|
|
2295
2207
|
if (!existsSync3(absolutePath)) {
|
|
2296
2208
|
return `${relativePath}:deleted`;
|
|
2297
2209
|
}
|
|
@@ -2299,7 +2211,7 @@ var readTrackedWorkingTreeFingerprintParts = (gitRoot) => {
|
|
|
2299
2211
|
if (!stat.isFile()) {
|
|
2300
2212
|
return `${relativePath}:non-file`;
|
|
2301
2213
|
}
|
|
2302
|
-
const content =
|
|
2214
|
+
const content = readFileSync8(absolutePath);
|
|
2303
2215
|
return `${relativePath}:${createHash2("sha256").update(content).digest("hex")}`;
|
|
2304
2216
|
})
|
|
2305
2217
|
];
|
|
@@ -2317,19 +2229,19 @@ var computeContextPromotionFingerprint = (gitRoot) => hashHex(
|
|
|
2317
2229
|
],
|
|
2318
2230
|
16
|
|
2319
2231
|
);
|
|
2320
|
-
var resolveContextPromotionReceiptIndexPath = (params) =>
|
|
2232
|
+
var resolveContextPromotionReceiptIndexPath = (params) => join10(params.userBasePath, ".ai-ops", "context-promotion", "projects", params.projectKey, RECEIPT_INDEX_FILENAME);
|
|
2321
2233
|
var parseContextPromotionReceiptIndex = (json) => ContextPromotionReceiptIndexSchema.parse(JSON.parse(json));
|
|
2322
2234
|
var serializeContextPromotionReceiptIndex = (index) => JSON.stringify(index, null, 2) + "\n";
|
|
2323
2235
|
var readContextPromotionReceiptIndex = (indexPath) => {
|
|
2324
2236
|
try {
|
|
2325
|
-
return parseContextPromotionReceiptIndex(
|
|
2237
|
+
return parseContextPromotionReceiptIndex(readFileSync8(indexPath, "utf-8"));
|
|
2326
2238
|
} catch {
|
|
2327
2239
|
return null;
|
|
2328
2240
|
}
|
|
2329
2241
|
};
|
|
2330
2242
|
var writeContextPromotionReceiptIndex = (indexPath, index) => {
|
|
2331
|
-
|
|
2332
|
-
|
|
2243
|
+
mkdirSync6(dirname8(indexPath), { recursive: true });
|
|
2244
|
+
writeFileSync6(indexPath, serializeContextPromotionReceiptIndex(index), "utf-8");
|
|
2333
2245
|
};
|
|
2334
2246
|
var buildEmptyReceiptIndex = (params) => ({
|
|
2335
2247
|
schemaVersion: 1,
|
|
@@ -2377,7 +2289,7 @@ var pruneContextPromotionReceipts = (params) => {
|
|
|
2377
2289
|
writeContextPromotionReceiptIndex(params.indexPath, nextIndex);
|
|
2378
2290
|
return nextIndex;
|
|
2379
2291
|
};
|
|
2380
|
-
var hasContextPromotionLayer = (gitRoot) => existsSync3(
|
|
2292
|
+
var hasContextPromotionLayer = (gitRoot) => existsSync3(join10(gitRoot, PROJECT_LAYER_CONTEXT_INDEX_RELATIVE_PATH));
|
|
2381
2293
|
var getContextPromotionStatus = (params) => {
|
|
2382
2294
|
const cwd = resolve7(params.cwd);
|
|
2383
2295
|
const gitRoot = resolveContextPromotionGitRoot(cwd);
|
|
@@ -2541,8 +2453,8 @@ var evaluateContextPromotionPostToolUseHook = (params) => {
|
|
|
2541
2453
|
|
|
2542
2454
|
// src/core/pc-integration.ts
|
|
2543
2455
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
2544
|
-
import { existsSync as existsSync4, readFileSync as
|
|
2545
|
-
import { join as
|
|
2456
|
+
import { existsSync as existsSync4, readFileSync as readFileSync9, readdirSync as readdirSync5 } from "fs";
|
|
2457
|
+
import { join as join11, resolve as resolve8, sep } from "path";
|
|
2546
2458
|
var normalizePath = (path) => resolve8(path.replace(/^~(?=$|\/)/, process.env.HOME ?? "~"));
|
|
2547
2459
|
var pathContains = (parentPath, childPath) => {
|
|
2548
2460
|
const parent = normalizePath(parentPath);
|
|
@@ -2580,7 +2492,7 @@ var parseListField = (content, labels) => {
|
|
|
2580
2492
|
};
|
|
2581
2493
|
var readTextFileOrNull = (filePath) => {
|
|
2582
2494
|
try {
|
|
2583
|
-
return
|
|
2495
|
+
return readFileSync9(filePath, "utf-8");
|
|
2584
2496
|
} catch {
|
|
2585
2497
|
return null;
|
|
2586
2498
|
}
|
|
@@ -2605,11 +2517,11 @@ var readGitHead2 = (cwd) => {
|
|
|
2605
2517
|
}
|
|
2606
2518
|
};
|
|
2607
2519
|
var listWorkspaceStatePaths = (contextRoot) => {
|
|
2608
|
-
const workspacesDir =
|
|
2520
|
+
const workspacesDir = join11(contextRoot, "workspaces");
|
|
2609
2521
|
if (!existsSync4(workspacesDir)) {
|
|
2610
2522
|
return [];
|
|
2611
2523
|
}
|
|
2612
|
-
return readdirSync5(workspacesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) =>
|
|
2524
|
+
return readdirSync5(workspacesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join11(workspacesDir, entry.name, "workspace-state.md")).filter((statePath) => existsSync4(statePath)).sort((a, b) => a.localeCompare(b));
|
|
2613
2525
|
};
|
|
2614
2526
|
var parseWorkspaceCandidate = (statePath) => {
|
|
2615
2527
|
const content = readTextFileOrNull(statePath);
|
|
@@ -2652,11 +2564,11 @@ var parseRepoEntry = (entryPath) => {
|
|
|
2652
2564
|
};
|
|
2653
2565
|
};
|
|
2654
2566
|
var findCurrentEntry = (params) => {
|
|
2655
|
-
const reposDir =
|
|
2567
|
+
const reposDir = join11(params.workspaceDir, "repos");
|
|
2656
2568
|
if (!existsSync4(reposDir)) {
|
|
2657
2569
|
return null;
|
|
2658
2570
|
}
|
|
2659
|
-
const entries = readdirSync5(reposDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".md")).map((entry) => parseRepoEntry(
|
|
2571
|
+
const entries = readdirSync5(reposDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".md")).map((entry) => parseRepoEntry(join11(reposDir, entry.name))).filter((entry) => entry !== null).filter((entry) => {
|
|
2660
2572
|
const paths = [entry.path, entry.gitRoot].filter((path) => path !== null);
|
|
2661
2573
|
return paths.some((path) => pathContains(path, params.cwd));
|
|
2662
2574
|
}).sort((a, b) => {
|
|
@@ -2751,7 +2663,7 @@ var getPcHandoffStatus = (params) => {
|
|
|
2751
2663
|
skipReason: "active pc workstream not selected"
|
|
2752
2664
|
};
|
|
2753
2665
|
}
|
|
2754
|
-
const activeWorkstreamPath =
|
|
2666
|
+
const activeWorkstreamPath = join11(workspace.workspaceDir, "workstreams", `${workspace.activeWorkstreamId}.md`);
|
|
2755
2667
|
const activeWorkstreamContent = readTextFileOrNull(activeWorkstreamPath);
|
|
2756
2668
|
if (!activeWorkstreamContent) {
|
|
2757
2669
|
return {
|
|
@@ -2869,8 +2781,8 @@ var evaluatePcPostToolUseHook = (params) => {
|
|
|
2869
2781
|
};
|
|
2870
2782
|
|
|
2871
2783
|
// src/core/codex-hook.ts
|
|
2872
|
-
import { existsSync as existsSync5, mkdirSync as
|
|
2873
|
-
import { dirname as
|
|
2784
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync7 } from "fs";
|
|
2785
|
+
import { dirname as dirname9, join as join12 } from "path";
|
|
2874
2786
|
var CONTEXT_PROMOTION_HOOK_ID = "context-promotion";
|
|
2875
2787
|
var CONTEXT_PROMOTION_HOOK_COMMAND_MARKER = "context-promotion hook post-tool-use";
|
|
2876
2788
|
var CONTEXT_PROMOTION_LEGACY_HOOK_COMMAND_MARKER = "context-promotion hook pre-tool-use";
|
|
@@ -2900,15 +2812,15 @@ var readJsonRecord = (filePath) => {
|
|
|
2900
2812
|
if (!existsSync5(filePath)) {
|
|
2901
2813
|
return {};
|
|
2902
2814
|
}
|
|
2903
|
-
const parsed = JSON.parse(
|
|
2815
|
+
const parsed = JSON.parse(readFileSync10(filePath, "utf-8"));
|
|
2904
2816
|
if (!isJsonRecord2(parsed)) {
|
|
2905
2817
|
throw new Error("hooks.json must contain a JSON object");
|
|
2906
2818
|
}
|
|
2907
2819
|
return parsed;
|
|
2908
2820
|
};
|
|
2909
2821
|
var writeJsonRecord = (filePath, value) => {
|
|
2910
|
-
|
|
2911
|
-
|
|
2822
|
+
mkdirSync7(dirname9(filePath), { recursive: true });
|
|
2823
|
+
writeFileSync7(filePath, JSON.stringify(value, null, 2) + "\n", "utf-8");
|
|
2912
2824
|
};
|
|
2913
2825
|
var getOrCreateRecord = (record, key) => {
|
|
2914
2826
|
const existing = record[key];
|
|
@@ -2983,7 +2895,7 @@ var removeDefinitionHooksFromEvent = (hooks, eventName, definition) => {
|
|
|
2983
2895
|
}
|
|
2984
2896
|
return true;
|
|
2985
2897
|
};
|
|
2986
|
-
var resolveCodexHooksPath = (codexHomePath) =>
|
|
2898
|
+
var resolveCodexHooksPath = (codexHomePath) => join12(codexHomePath, "hooks.json");
|
|
2987
2899
|
var buildCodexHookCommand = (params) => {
|
|
2988
2900
|
const command = params.overrideCommand?.trim() ?? params.definition.defaultCommand;
|
|
2989
2901
|
if (!command.includes(params.definition.commandMarker)) {
|
|
@@ -3061,11 +2973,11 @@ var uninstallContextPromotionHook = (hooksPath) => uninstallCodexHook({
|
|
|
3061
2973
|
});
|
|
3062
2974
|
|
|
3063
2975
|
// src/lib/paths.ts
|
|
3064
|
-
import { join as
|
|
3065
|
-
var resolveSkillsDir = () =>
|
|
3066
|
-
var resolveSubagentsDir = () =>
|
|
3067
|
-
var resolvePacksDir = () =>
|
|
3068
|
-
var resolveIntegrationsDir = () =>
|
|
2976
|
+
import { join as join13 } from "path";
|
|
2977
|
+
var resolveSkillsDir = () => join13(COMPILER_DATA_DIR, "skills");
|
|
2978
|
+
var resolveSubagentsDir = () => join13(COMPILER_DATA_DIR, "subagents");
|
|
2979
|
+
var resolvePacksDir = () => join13(COMPILER_DATA_DIR, "packs");
|
|
2980
|
+
var resolveIntegrationsDir = () => join13(COMPILER_DATA_DIR, "integrations");
|
|
3069
2981
|
var resolveBasePath = () => process.cwd();
|
|
3070
2982
|
var resolveUserBasePath = () => {
|
|
3071
2983
|
const userBasePath = process.env.AI_OPS_HOME ?? process.env.HOME;
|
|
@@ -3349,8 +3261,8 @@ var findInstalledSkill = (installedSkills, skillId) => {
|
|
|
3349
3261
|
};
|
|
3350
3262
|
|
|
3351
3263
|
// src/lib/skill-install.ts
|
|
3352
|
-
import { existsSync as existsSync6, mkdirSync as
|
|
3353
|
-
import { dirname as
|
|
3264
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync8, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "fs";
|
|
3265
|
+
import { dirname as dirname10, resolve as resolve9 } from "path";
|
|
3354
3266
|
var installSkillPackages = (basePath, packages) => {
|
|
3355
3267
|
const writtenRoots = [];
|
|
3356
3268
|
for (const skillPackage of packages) {
|
|
@@ -3360,8 +3272,8 @@ var installSkillPackages = (basePath, packages) => {
|
|
|
3360
3272
|
}
|
|
3361
3273
|
for (const file of skillPackage.files) {
|
|
3362
3274
|
const absPath = resolve9(basePath, file.relativePath);
|
|
3363
|
-
|
|
3364
|
-
|
|
3275
|
+
mkdirSync8(dirname10(absPath), { recursive: true });
|
|
3276
|
+
writeFileSync8(absPath, file.content + "\n", "utf-8");
|
|
3365
3277
|
}
|
|
3366
3278
|
writtenRoots.push(skillPackage.rootDir);
|
|
3367
3279
|
}
|
|
@@ -3553,8 +3465,8 @@ import * as p8 from "@clack/prompts";
|
|
|
3553
3465
|
import { existsSync as existsSync8, rmSync as rmSync7 } from "fs";
|
|
3554
3466
|
|
|
3555
3467
|
// src/lib/subagent-install.ts
|
|
3556
|
-
import { existsSync as existsSync7, mkdirSync as
|
|
3557
|
-
import { dirname as
|
|
3468
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync9, rmSync as rmSync6, writeFileSync as writeFileSync9 } from "fs";
|
|
3469
|
+
import { dirname as dirname11, isAbsolute as isAbsolute3, relative as relative3, resolve as resolve10 } from "path";
|
|
3558
3470
|
var resolveInsideBasePath = (basePath, relativePath) => {
|
|
3559
3471
|
const absBasePath = resolve10(basePath);
|
|
3560
3472
|
const absPath = resolve10(absBasePath, relativePath);
|
|
@@ -3572,8 +3484,8 @@ var installSubagentPackages = (basePath, packages) => {
|
|
|
3572
3484
|
if (existsSync7(absPath)) {
|
|
3573
3485
|
rmSync6(absPath, { recursive: true, force: true });
|
|
3574
3486
|
}
|
|
3575
|
-
|
|
3576
|
-
|
|
3487
|
+
mkdirSync9(dirname11(absPath), { recursive: true });
|
|
3488
|
+
writeFileSync9(absPath, file.content.trimEnd() + "\n", "utf-8");
|
|
3577
3489
|
written.push(file.relativePath);
|
|
3578
3490
|
}
|
|
3579
3491
|
}
|
|
@@ -4064,7 +3976,7 @@ var contextPromotionPostToolUseHookCommand = async () => {
|
|
|
4064
3976
|
// src/commands/codex-hook.ts
|
|
4065
3977
|
import * as p11 from "@clack/prompts";
|
|
4066
3978
|
import { existsSync as existsSync9 } from "fs";
|
|
4067
|
-
import { join as
|
|
3979
|
+
import { join as join14 } from "path";
|
|
4068
3980
|
var CONTEXT_PROMOTION_REVIEW_SKILL_ID = "context-promotion-review";
|
|
4069
3981
|
var resolveCodexHomePath = () => {
|
|
4070
3982
|
const codexHome = process.env.CODEX_HOME;
|
|
@@ -4102,7 +4014,7 @@ var resolveContextPromotionReviewSkill = () => {
|
|
|
4102
4014
|
};
|
|
4103
4015
|
var hasInstalledContextPromotionReviewSkill = (basePath) => {
|
|
4104
4016
|
const installedSkill = findInstalledSkill(readInstalledSkills2(basePath), CONTEXT_PROMOTION_REVIEW_SKILL_ID);
|
|
4105
|
-
return installedSkill?.tools.includes(SKILL_TOOL.CODEX) === true && existsSync9(
|
|
4017
|
+
return installedSkill?.tools.includes(SKILL_TOOL.CODEX) === true && existsSync9(join14(basePath, ".agents/skills/context-promotion-review/SKILL.md"));
|
|
4106
4018
|
};
|
|
4107
4019
|
var ensureContextPromotionReviewSkill = (basePath) => {
|
|
4108
4020
|
const skill = resolveContextPromotionReviewSkill();
|
|
@@ -4116,7 +4028,7 @@ var ensureContextPromotionReviewSkill = (basePath) => {
|
|
|
4116
4028
|
skill,
|
|
4117
4029
|
requestedTools
|
|
4118
4030
|
});
|
|
4119
|
-
const alreadyInstalled = existingInstalledSkill?.sourceHash === installedSkill.sourceHash && existingInstalledSkill.tools.includes(SKILL_TOOL.CODEX) && existsSync9(
|
|
4031
|
+
const alreadyInstalled = existingInstalledSkill?.sourceHash === installedSkill.sourceHash && existingInstalledSkill.tools.includes(SKILL_TOOL.CODEX) && existsSync9(join14(basePath, ".agents/skills/context-promotion-review/SKILL.md"));
|
|
4120
4032
|
if (alreadyInstalled) {
|
|
4121
4033
|
return { changed: false, installedSkill };
|
|
4122
4034
|
}
|
|
@@ -4180,7 +4092,7 @@ var codexHookUninstallCommand = async (hookId) => {
|
|
|
4180
4092
|
// src/commands/integration.ts
|
|
4181
4093
|
import * as p12 from "@clack/prompts";
|
|
4182
4094
|
import { existsSync as existsSync10, rmSync as rmSync8 } from "fs";
|
|
4183
|
-
import { join as
|
|
4095
|
+
import { join as join15 } from "path";
|
|
4184
4096
|
var CODEX_HOOK_DEFINITIONS = [CONTEXT_PROMOTION_CODEX_HOOK, PC_CODEX_HOOK];
|
|
4185
4097
|
var resolveCodexHomePath2 = () => {
|
|
4186
4098
|
const codexHome = process.env.CODEX_HOME;
|
|
@@ -4275,7 +4187,7 @@ var resolveSkillById2 = (skillId) => {
|
|
|
4275
4187
|
};
|
|
4276
4188
|
var hasInstalledCodexSkill = (params) => {
|
|
4277
4189
|
const installedSkill = findInstalledSkill(readInstalledSkills3(params.basePath), params.skillId);
|
|
4278
|
-
return installedSkill?.tools.includes(SKILL_TOOL.CODEX) === true && existsSync10(
|
|
4190
|
+
return installedSkill?.tools.includes(SKILL_TOOL.CODEX) === true && existsSync10(join15(params.basePath, ".agents/skills", params.skillId, "SKILL.md"));
|
|
4279
4191
|
};
|
|
4280
4192
|
var writeUserSkillState2 = (params) => {
|
|
4281
4193
|
const registryPath = resolveSkillRegistryPath(params.basePath);
|
|
@@ -4303,7 +4215,7 @@ var ensureSkillComponent = (params) => {
|
|
|
4303
4215
|
skill,
|
|
4304
4216
|
requestedTools
|
|
4305
4217
|
});
|
|
4306
|
-
const alreadyCurrent = existingInstalledSkill?.sourceHash === installedSkill.sourceHash && existingInstalledSkill.tools.includes(SKILL_TOOL.CODEX) && existsSync10(
|
|
4218
|
+
const alreadyCurrent = existingInstalledSkill?.sourceHash === installedSkill.sourceHash && existingInstalledSkill.tools.includes(SKILL_TOOL.CODEX) && existsSync10(join15(params.basePath, ".agents/skills", params.skillId, "SKILL.md"));
|
|
4307
4219
|
if (alreadyCurrent) {
|
|
4308
4220
|
return {
|
|
4309
4221
|
type: INTEGRATION_COMPONENT_TYPE.SKILL,
|