@roll-agent/core 0.15.0 → 0.16.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/dist/cli/chat/ink/live-region.js +1 -1
- package/dist/cli/chat/ink/state.d.ts +1 -0
- package/dist/cli/chat/ink/state.js +1 -1
- package/dist/cli/commands/agent-add.js +1 -1
- package/dist/cli/commands/agent-env-guidance.d.ts +2 -0
- package/dist/cli/commands/agent-env-guidance.js +1 -0
- package/dist/cli/commands/agent-install.d.ts +5 -0
- package/dist/cli/commands/agent-install.js +1 -1
- package/dist/cli/commands/agent-list.d.ts +5 -0
- package/dist/cli/commands/agent-list.js +1 -1
- package/dist/cli/commands/chat.d.ts +3 -0
- package/dist/cli/commands/chat.js +1 -1
- package/dist/cli/commands/config-guidance.d.ts +21 -0
- package/dist/cli/commands/config-guidance.js +1 -1
- package/dist/cli/commands/config-prompts.d.ts +6 -0
- package/dist/cli/commands/config-prompts.js +1 -1
- package/dist/cli/commands/config-setup.d.ts +6 -1
- package/dist/cli/commands/config-setup.js +1 -1
- package/dist/cli/commands/config.d.ts +1 -0
- package/dist/cli/commands/config.js +1 -1
- package/dist/cli/commands/setup.d.ts +38 -0
- package/dist/cli/commands/setup.js +1 -0
- package/dist/cli/commands/skills-install.d.ts +30 -0
- package/dist/cli/commands/skills-install.js +1 -0
- package/dist/cli/commands/skills.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/utils/catalog-status.d.ts +20 -0
- package/dist/cli/utils/catalog-status.js +1 -0
- package/dist/cli/utils/chat-renderer.d.ts +1 -0
- package/dist/cli/utils/chat-renderer.js +1 -1
- package/dist/cli/utils/git-source.d.ts +7 -0
- package/dist/cli/utils/git-source.js +1 -0
- package/dist/cli/utils/tool-format.d.ts +1 -0
- package/dist/cli/utils/tool-format.js +1 -1
- package/dist/config/defaults.js +1 -1
- package/dist/config/helpers.d.ts +17 -0
- package/dist/config/helpers.js +1 -1
- package/dist/config/key-codec.js +1 -1
- package/dist/config/loader.d.ts +2 -0
- package/dist/config/loader.js +1 -1
- package/dist/config/migration.d.ts +5 -1
- package/dist/config/migration.js +1 -1
- package/dist/config/runtime-env.d.ts +30 -30
- package/dist/config/schema.d.ts +250 -0
- package/dist/config/schema.js +1 -1
- package/dist/mcp/client-manager.js +1 -1
- package/dist/registry/catalog-discovery.d.ts +30 -0
- package/dist/registry/catalog-discovery.js +1 -0
- package/dist/registry/catalog.d.ts +42 -0
- package/dist/registry/catalog.js +1 -0
- package/dist/registry/discovery.js +1 -1
- package/dist/registry/index.d.ts +4 -0
- package/dist/registry/index.js +1 -1
- package/dist/registry/install.d.ts +69 -0
- package/dist/registry/install.js +1 -0
- package/dist/skills/install.d.ts +17 -0
- package/dist/skills/install.js +1 -0
- package/dist/skills/orchestrators.d.ts +39 -0
- package/dist/skills/orchestrators.js +1 -0
- package/package.json +2 -2
package/dist/config/schema.d.ts
CHANGED
|
@@ -93,6 +93,72 @@ export declare const runtimeCompactionConfigSchema: z.ZodObject<{
|
|
|
93
93
|
keepRecentTokens?: number | undefined;
|
|
94
94
|
}>;
|
|
95
95
|
export declare const runtimeThinkingLevels: readonly ["off", "low", "medium", "high"];
|
|
96
|
+
export declare const runtimeShellSessionConfigSchema: z.ZodObject<{
|
|
97
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
98
|
+
maxSessions: z.ZodDefault<z.ZodNumber>;
|
|
99
|
+
defaultYieldMs: z.ZodDefault<z.ZodNumber>;
|
|
100
|
+
maxOutputTokens: z.ZodDefault<z.ZodNumber>;
|
|
101
|
+
}, "strip", z.ZodTypeAny, {
|
|
102
|
+
maxOutputTokens: number;
|
|
103
|
+
enabled: boolean;
|
|
104
|
+
maxSessions: number;
|
|
105
|
+
defaultYieldMs: number;
|
|
106
|
+
}, {
|
|
107
|
+
maxOutputTokens?: number | undefined;
|
|
108
|
+
enabled?: boolean | undefined;
|
|
109
|
+
maxSessions?: number | undefined;
|
|
110
|
+
defaultYieldMs?: number | undefined;
|
|
111
|
+
}>;
|
|
112
|
+
export declare const runtimeShellConfigSchema: z.ZodObject<{
|
|
113
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
114
|
+
autoApproveSafe: z.ZodDefault<z.ZodBoolean>;
|
|
115
|
+
defaultTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
116
|
+
maxTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
117
|
+
maxCaptureBytes: z.ZodDefault<z.ZodNumber>;
|
|
118
|
+
maxModelOutputChars: z.ZodDefault<z.ZodNumber>;
|
|
119
|
+
session: z.ZodDefault<z.ZodObject<{
|
|
120
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
121
|
+
maxSessions: z.ZodDefault<z.ZodNumber>;
|
|
122
|
+
defaultYieldMs: z.ZodDefault<z.ZodNumber>;
|
|
123
|
+
maxOutputTokens: z.ZodDefault<z.ZodNumber>;
|
|
124
|
+
}, "strip", z.ZodTypeAny, {
|
|
125
|
+
maxOutputTokens: number;
|
|
126
|
+
enabled: boolean;
|
|
127
|
+
maxSessions: number;
|
|
128
|
+
defaultYieldMs: number;
|
|
129
|
+
}, {
|
|
130
|
+
maxOutputTokens?: number | undefined;
|
|
131
|
+
enabled?: boolean | undefined;
|
|
132
|
+
maxSessions?: number | undefined;
|
|
133
|
+
defaultYieldMs?: number | undefined;
|
|
134
|
+
}>>;
|
|
135
|
+
}, "strip", z.ZodTypeAny, {
|
|
136
|
+
enabled: boolean;
|
|
137
|
+
autoApproveSafe: boolean;
|
|
138
|
+
defaultTimeoutMs: number;
|
|
139
|
+
maxTimeoutMs: number;
|
|
140
|
+
maxCaptureBytes: number;
|
|
141
|
+
maxModelOutputChars: number;
|
|
142
|
+
session: {
|
|
143
|
+
maxOutputTokens: number;
|
|
144
|
+
enabled: boolean;
|
|
145
|
+
maxSessions: number;
|
|
146
|
+
defaultYieldMs: number;
|
|
147
|
+
};
|
|
148
|
+
}, {
|
|
149
|
+
enabled?: boolean | undefined;
|
|
150
|
+
autoApproveSafe?: boolean | undefined;
|
|
151
|
+
defaultTimeoutMs?: number | undefined;
|
|
152
|
+
maxTimeoutMs?: number | undefined;
|
|
153
|
+
maxCaptureBytes?: number | undefined;
|
|
154
|
+
maxModelOutputChars?: number | undefined;
|
|
155
|
+
session?: {
|
|
156
|
+
maxOutputTokens?: number | undefined;
|
|
157
|
+
enabled?: boolean | undefined;
|
|
158
|
+
maxSessions?: number | undefined;
|
|
159
|
+
defaultYieldMs?: number | undefined;
|
|
160
|
+
} | undefined;
|
|
161
|
+
}>;
|
|
96
162
|
export declare const runtimeConfigSchema: z.ZodObject<{
|
|
97
163
|
provider: z.ZodOptional<z.ZodString>;
|
|
98
164
|
model: z.ZodOptional<z.ZodString>;
|
|
@@ -130,7 +196,71 @@ export declare const runtimeConfigSchema: z.ZodObject<{
|
|
|
130
196
|
keepRecentTurns?: number | undefined;
|
|
131
197
|
keepRecentTokens?: number | undefined;
|
|
132
198
|
}>>;
|
|
199
|
+
shell: z.ZodDefault<z.ZodObject<{
|
|
200
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
201
|
+
autoApproveSafe: z.ZodDefault<z.ZodBoolean>;
|
|
202
|
+
defaultTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
203
|
+
maxTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
204
|
+
maxCaptureBytes: z.ZodDefault<z.ZodNumber>;
|
|
205
|
+
maxModelOutputChars: z.ZodDefault<z.ZodNumber>;
|
|
206
|
+
session: z.ZodDefault<z.ZodObject<{
|
|
207
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
208
|
+
maxSessions: z.ZodDefault<z.ZodNumber>;
|
|
209
|
+
defaultYieldMs: z.ZodDefault<z.ZodNumber>;
|
|
210
|
+
maxOutputTokens: z.ZodDefault<z.ZodNumber>;
|
|
211
|
+
}, "strip", z.ZodTypeAny, {
|
|
212
|
+
maxOutputTokens: number;
|
|
213
|
+
enabled: boolean;
|
|
214
|
+
maxSessions: number;
|
|
215
|
+
defaultYieldMs: number;
|
|
216
|
+
}, {
|
|
217
|
+
maxOutputTokens?: number | undefined;
|
|
218
|
+
enabled?: boolean | undefined;
|
|
219
|
+
maxSessions?: number | undefined;
|
|
220
|
+
defaultYieldMs?: number | undefined;
|
|
221
|
+
}>>;
|
|
222
|
+
}, "strip", z.ZodTypeAny, {
|
|
223
|
+
enabled: boolean;
|
|
224
|
+
autoApproveSafe: boolean;
|
|
225
|
+
defaultTimeoutMs: number;
|
|
226
|
+
maxTimeoutMs: number;
|
|
227
|
+
maxCaptureBytes: number;
|
|
228
|
+
maxModelOutputChars: number;
|
|
229
|
+
session: {
|
|
230
|
+
maxOutputTokens: number;
|
|
231
|
+
enabled: boolean;
|
|
232
|
+
maxSessions: number;
|
|
233
|
+
defaultYieldMs: number;
|
|
234
|
+
};
|
|
235
|
+
}, {
|
|
236
|
+
enabled?: boolean | undefined;
|
|
237
|
+
autoApproveSafe?: boolean | undefined;
|
|
238
|
+
defaultTimeoutMs?: number | undefined;
|
|
239
|
+
maxTimeoutMs?: number | undefined;
|
|
240
|
+
maxCaptureBytes?: number | undefined;
|
|
241
|
+
maxModelOutputChars?: number | undefined;
|
|
242
|
+
session?: {
|
|
243
|
+
maxOutputTokens?: number | undefined;
|
|
244
|
+
enabled?: boolean | undefined;
|
|
245
|
+
maxSessions?: number | undefined;
|
|
246
|
+
defaultYieldMs?: number | undefined;
|
|
247
|
+
} | undefined;
|
|
248
|
+
}>>;
|
|
133
249
|
}, "strip", z.ZodTypeAny, {
|
|
250
|
+
shell: {
|
|
251
|
+
enabled: boolean;
|
|
252
|
+
autoApproveSafe: boolean;
|
|
253
|
+
defaultTimeoutMs: number;
|
|
254
|
+
maxTimeoutMs: number;
|
|
255
|
+
maxCaptureBytes: number;
|
|
256
|
+
maxModelOutputChars: number;
|
|
257
|
+
session: {
|
|
258
|
+
maxOutputTokens: number;
|
|
259
|
+
enabled: boolean;
|
|
260
|
+
maxSessions: number;
|
|
261
|
+
defaultYieldMs: number;
|
|
262
|
+
};
|
|
263
|
+
};
|
|
134
264
|
maxSteps: number;
|
|
135
265
|
turnTimeoutMs: number;
|
|
136
266
|
threadsDir: string;
|
|
@@ -150,6 +280,20 @@ export declare const runtimeConfigSchema: z.ZodObject<{
|
|
|
150
280
|
provider?: string | undefined;
|
|
151
281
|
contextWindow?: number | undefined;
|
|
152
282
|
}, {
|
|
283
|
+
shell?: {
|
|
284
|
+
enabled?: boolean | undefined;
|
|
285
|
+
autoApproveSafe?: boolean | undefined;
|
|
286
|
+
defaultTimeoutMs?: number | undefined;
|
|
287
|
+
maxTimeoutMs?: number | undefined;
|
|
288
|
+
maxCaptureBytes?: number | undefined;
|
|
289
|
+
maxModelOutputChars?: number | undefined;
|
|
290
|
+
session?: {
|
|
291
|
+
maxOutputTokens?: number | undefined;
|
|
292
|
+
enabled?: boolean | undefined;
|
|
293
|
+
maxSessions?: number | undefined;
|
|
294
|
+
defaultYieldMs?: number | undefined;
|
|
295
|
+
} | undefined;
|
|
296
|
+
} | undefined;
|
|
153
297
|
model?: string | undefined;
|
|
154
298
|
provider?: string | undefined;
|
|
155
299
|
maxSteps?: number | undefined;
|
|
@@ -621,7 +765,71 @@ export declare const rollConfigSchema: z.ZodObject<{
|
|
|
621
765
|
keepRecentTurns?: number | undefined;
|
|
622
766
|
keepRecentTokens?: number | undefined;
|
|
623
767
|
}>>;
|
|
768
|
+
shell: z.ZodDefault<z.ZodObject<{
|
|
769
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
770
|
+
autoApproveSafe: z.ZodDefault<z.ZodBoolean>;
|
|
771
|
+
defaultTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
772
|
+
maxTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
773
|
+
maxCaptureBytes: z.ZodDefault<z.ZodNumber>;
|
|
774
|
+
maxModelOutputChars: z.ZodDefault<z.ZodNumber>;
|
|
775
|
+
session: z.ZodDefault<z.ZodObject<{
|
|
776
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
777
|
+
maxSessions: z.ZodDefault<z.ZodNumber>;
|
|
778
|
+
defaultYieldMs: z.ZodDefault<z.ZodNumber>;
|
|
779
|
+
maxOutputTokens: z.ZodDefault<z.ZodNumber>;
|
|
780
|
+
}, "strip", z.ZodTypeAny, {
|
|
781
|
+
maxOutputTokens: number;
|
|
782
|
+
enabled: boolean;
|
|
783
|
+
maxSessions: number;
|
|
784
|
+
defaultYieldMs: number;
|
|
785
|
+
}, {
|
|
786
|
+
maxOutputTokens?: number | undefined;
|
|
787
|
+
enabled?: boolean | undefined;
|
|
788
|
+
maxSessions?: number | undefined;
|
|
789
|
+
defaultYieldMs?: number | undefined;
|
|
790
|
+
}>>;
|
|
791
|
+
}, "strip", z.ZodTypeAny, {
|
|
792
|
+
enabled: boolean;
|
|
793
|
+
autoApproveSafe: boolean;
|
|
794
|
+
defaultTimeoutMs: number;
|
|
795
|
+
maxTimeoutMs: number;
|
|
796
|
+
maxCaptureBytes: number;
|
|
797
|
+
maxModelOutputChars: number;
|
|
798
|
+
session: {
|
|
799
|
+
maxOutputTokens: number;
|
|
800
|
+
enabled: boolean;
|
|
801
|
+
maxSessions: number;
|
|
802
|
+
defaultYieldMs: number;
|
|
803
|
+
};
|
|
804
|
+
}, {
|
|
805
|
+
enabled?: boolean | undefined;
|
|
806
|
+
autoApproveSafe?: boolean | undefined;
|
|
807
|
+
defaultTimeoutMs?: number | undefined;
|
|
808
|
+
maxTimeoutMs?: number | undefined;
|
|
809
|
+
maxCaptureBytes?: number | undefined;
|
|
810
|
+
maxModelOutputChars?: number | undefined;
|
|
811
|
+
session?: {
|
|
812
|
+
maxOutputTokens?: number | undefined;
|
|
813
|
+
enabled?: boolean | undefined;
|
|
814
|
+
maxSessions?: number | undefined;
|
|
815
|
+
defaultYieldMs?: number | undefined;
|
|
816
|
+
} | undefined;
|
|
817
|
+
}>>;
|
|
624
818
|
}, "strip", z.ZodTypeAny, {
|
|
819
|
+
shell: {
|
|
820
|
+
enabled: boolean;
|
|
821
|
+
autoApproveSafe: boolean;
|
|
822
|
+
defaultTimeoutMs: number;
|
|
823
|
+
maxTimeoutMs: number;
|
|
824
|
+
maxCaptureBytes: number;
|
|
825
|
+
maxModelOutputChars: number;
|
|
826
|
+
session: {
|
|
827
|
+
maxOutputTokens: number;
|
|
828
|
+
enabled: boolean;
|
|
829
|
+
maxSessions: number;
|
|
830
|
+
defaultYieldMs: number;
|
|
831
|
+
};
|
|
832
|
+
};
|
|
625
833
|
maxSteps: number;
|
|
626
834
|
turnTimeoutMs: number;
|
|
627
835
|
threadsDir: string;
|
|
@@ -641,6 +849,20 @@ export declare const rollConfigSchema: z.ZodObject<{
|
|
|
641
849
|
provider?: string | undefined;
|
|
642
850
|
contextWindow?: number | undefined;
|
|
643
851
|
}, {
|
|
852
|
+
shell?: {
|
|
853
|
+
enabled?: boolean | undefined;
|
|
854
|
+
autoApproveSafe?: boolean | undefined;
|
|
855
|
+
defaultTimeoutMs?: number | undefined;
|
|
856
|
+
maxTimeoutMs?: number | undefined;
|
|
857
|
+
maxCaptureBytes?: number | undefined;
|
|
858
|
+
maxModelOutputChars?: number | undefined;
|
|
859
|
+
session?: {
|
|
860
|
+
maxOutputTokens?: number | undefined;
|
|
861
|
+
enabled?: boolean | undefined;
|
|
862
|
+
maxSessions?: number | undefined;
|
|
863
|
+
defaultYieldMs?: number | undefined;
|
|
864
|
+
} | undefined;
|
|
865
|
+
} | undefined;
|
|
644
866
|
model?: string | undefined;
|
|
645
867
|
provider?: string | undefined;
|
|
646
868
|
maxSteps?: number | undefined;
|
|
@@ -962,6 +1184,20 @@ export declare const rollConfigSchema: z.ZodObject<{
|
|
|
962
1184
|
}>;
|
|
963
1185
|
};
|
|
964
1186
|
runtime: {
|
|
1187
|
+
shell: {
|
|
1188
|
+
enabled: boolean;
|
|
1189
|
+
autoApproveSafe: boolean;
|
|
1190
|
+
defaultTimeoutMs: number;
|
|
1191
|
+
maxTimeoutMs: number;
|
|
1192
|
+
maxCaptureBytes: number;
|
|
1193
|
+
maxModelOutputChars: number;
|
|
1194
|
+
session: {
|
|
1195
|
+
maxOutputTokens: number;
|
|
1196
|
+
enabled: boolean;
|
|
1197
|
+
maxSessions: number;
|
|
1198
|
+
defaultYieldMs: number;
|
|
1199
|
+
};
|
|
1200
|
+
};
|
|
965
1201
|
maxSteps: number;
|
|
966
1202
|
turnTimeoutMs: number;
|
|
967
1203
|
threadsDir: string;
|
|
@@ -1037,6 +1273,20 @@ export declare const rollConfigSchema: z.ZodObject<{
|
|
|
1037
1273
|
}> | undefined;
|
|
1038
1274
|
} | undefined;
|
|
1039
1275
|
runtime?: {
|
|
1276
|
+
shell?: {
|
|
1277
|
+
enabled?: boolean | undefined;
|
|
1278
|
+
autoApproveSafe?: boolean | undefined;
|
|
1279
|
+
defaultTimeoutMs?: number | undefined;
|
|
1280
|
+
maxTimeoutMs?: number | undefined;
|
|
1281
|
+
maxCaptureBytes?: number | undefined;
|
|
1282
|
+
maxModelOutputChars?: number | undefined;
|
|
1283
|
+
session?: {
|
|
1284
|
+
maxOutputTokens?: number | undefined;
|
|
1285
|
+
enabled?: boolean | undefined;
|
|
1286
|
+
maxSessions?: number | undefined;
|
|
1287
|
+
defaultYieldMs?: number | undefined;
|
|
1288
|
+
} | undefined;
|
|
1289
|
+
} | undefined;
|
|
1040
1290
|
model?: string | undefined;
|
|
1041
1291
|
provider?: string | undefined;
|
|
1042
1292
|
maxSteps?: number | undefined;
|
package/dist/config/schema.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z as e}from"zod";const t=["zhipin","yupao"],
|
|
1
|
+
import{z as e}from"zod";const t=["zhipin","yupao"],n=["managed-cdp","remote-cdp","existing-session"],o=["chrome","chromium","msedge"],i=["guarded","auto","deny"],a=["auto","confirm","deny"],r=["summarize","truncate"],s=e.string().trim().regex(/^#[\da-fA-F]{6}$/,"profileColor must be a hex RGB color such as #2563EB").transform(e=>e.toUpperCase());export const browserWindowBoundsSchema=e.object({x:e.number().int().optional(),y:e.number().int().optional(),width:e.number().int().positive().optional(),height:e.number().int().positive().optional()});export const providerConfigSchema=e.object({apiKey:e.string(),baseUrl:e.string().optional()});export const llmConfigSchema=e.object({defaultProvider:e.string(),defaultModel:e.string(),providers:e.record(e.string(),providerConfigSchema)});export const askConfigSchema=e.object({llmModel:e.string().optional(),confirmThreshold:e.number().optional()});export const runtimeApprovalConfigSchema=e.object({default:e.enum(i).default("guarded"),overrides:e.record(e.string(),e.enum(a)).default({})});export const runtimeCompactionConfigSchema=e.object({enabled:e.boolean().default(!0),strategy:e.enum(r).default("summarize"),threshold:e.number().min(.1).max(.95).default(.75),keepRecentTurns:e.number().int().min(1).default(4),keepRecentTokens:e.number().int().min(1).default(32e3)});export const runtimeThinkingLevels=["off","low","medium","high"];export const runtimeShellSessionConfigSchema=e.object({enabled:e.boolean().default(!1),maxSessions:e.number().int().min(1).max(64).default(8),defaultYieldMs:e.number().int().min(250).max(3e4).default(1e4),maxOutputTokens:e.number().int().min(256).default(1e4)});export const runtimeShellConfigSchema=e.object({enabled:e.boolean().default(!1),autoApproveSafe:e.boolean().default(!0),defaultTimeoutMs:e.number().int().min(1e3).max(6e5).default(1e4),maxTimeoutMs:e.number().int().min(1e3).max(6e5).default(6e5),maxCaptureBytes:e.number().int().min(16384).default(1048576),maxModelOutputChars:e.number().int().min(1e3).default(16e3),session:runtimeShellSessionConfigSchema.default({})});export const runtimeConfigSchema=e.object({provider:e.string().optional(),model:e.string().optional(),maxSteps:e.number().int().min(1).default(80),turnTimeoutMs:e.number().int().min(1e4).default(3e5),threadsDir:e.string().default("~/.roll-agent/threads"),contextWindow:e.number().int().min(1).optional(),thinkingLevel:e.enum(runtimeThinkingLevels).default("medium"),approval:runtimeApprovalConfigSchema.default({}),compaction:runtimeCompactionConfigSchema.default({}),shell:runtimeShellConfigSchema.default({})});export const skillsConfigSchema=e.object({dirs:e.array(e.string().trim().min(1)).default([])});export const agentsConfigSchema=e.object({dataDir:e.string(),env:e.record(e.string(),e.record(e.string(),e.string())).optional()});export const installConfigSchema=e.object({registry:e.string().trim().url().optional(),fetchRetries:e.number().int().min(0).max(10).default(3),preferOffline:e.boolean().default(!1),networkTimeoutMs:e.number().int().min(1e4).default(12e4)});export const browserInstanceConfigSchema=e.object({platform:e.enum(t).optional(),mode:e.enum(n).default("managed-cdp"),headless:e.boolean().optional(),cdpUrl:e.string().optional(),cdpHost:e.string().default("127.0.0.1"),cdpPort:e.number().int().min(1).max(65535).optional(),channel:e.enum(o).default("chrome"),executablePath:e.string().optional(),userDataDir:e.string().trim().min(1),sessionsDir:e.string().trim().min(1).optional(),args:e.array(e.string()).optional(),profileName:e.string().trim().min(1).optional(),profileColor:s.optional(),windowBounds:browserWindowBoundsSchema.optional(),trackingAgentId:e.string().trim().min(1).optional()}).superRefine((t,n)=>{"managed-cdp"===t.mode&&void 0===t.cdpPort&&n.addIssue({code:e.ZodIssueCode.custom,path:["cdpPort"],message:"managed-cdp browser instance requires cdpPort"}),"remote-cdp"!==t.mode&&"existing-session"!==t.mode||void 0!==t.cdpUrl||n.addIssue({code:e.ZodIssueCode.custom,path:["cdpUrl"],message:`${t.mode} browser instance requires cdpUrl`})});export const browserConfigSchema=e.object({defaultInstance:e.string().trim().min(1).optional(),instances:e.record(e.string(),browserInstanceConfigSchema).default({})}).superRefine((t,n)=>{const o=Object.entries(t.instances);void 0!==t.defaultInstance&&void 0===t.instances[t.defaultInstance]&&n.addIssue({code:e.ZodIssueCode.custom,path:["defaultInstance"],message:`defaultInstance "${t.defaultInstance}" is not declared in browser.instances`});const i=new Map,a=new Map;for(const[t,r]of o){if(void 0!==r.cdpPort){const o=i.get(r.cdpPort);void 0!==o?n.addIssue({code:e.ZodIssueCode.custom,path:["instances",t,"cdpPort"],message:`cdpPort ${String(r.cdpPort)} is already used by browser instance "${o}"`}):i.set(r.cdpPort,t)}const o=a.get(r.userDataDir);void 0!==o?n.addIssue({code:e.ZodIssueCode.custom,path:["instances",t,"userDataDir"],message:`userDataDir is already used by browser instance "${o}"`}):a.set(r.userDataDir,t)}});export const rollConfigSchema=e.object({llm:llmConfigSchema,ask:askConfigSchema,runtime:runtimeConfigSchema.default({}),skills:skillsConfigSchema.default({}),agents:agentsConfigSchema,install:installConfigSchema.default({}),browser:browserConfigSchema.default({})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Client as n}from"@modelcontextprotocol/sdk/client/index.js";import{StdioClientTransport as t}from"@modelcontextprotocol/sdk/client/stdio.js";import{StreamableHTTPClientTransport as e}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{registerSamplingHandler as o}from"./sampling-handler.js";const s=3e4,i="--disable-warning=ExperimentalWarning";export function buildStdioChildEnv(n){const t=
|
|
1
|
+
import{Client as n}from"@modelcontextprotocol/sdk/client/index.js";import{StdioClientTransport as t}from"@modelcontextprotocol/sdk/client/stdio.js";import{StreamableHTTPClientTransport as e}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{registerSamplingHandler as o}from"./sampling-handler.js";const s=3e4,i="--disable-warning=ExperimentalWarning";export function buildStdioChildEnv(n){const t={...process.env,...n??{}};return{...t,NODE_OPTIONS:r(t.NODE_OPTIONS,i),ROLL_AGENT_LOG_LEVEL:t.ROLL_AGENT_LOG_LEVEL??"warn",PYTHONUTF8:t.PYTHONUTF8??"1",PYTHONIOENCODING:t.PYTHONIOENCODING??"utf-8"}}function r(n,t){const e=n?.trim();if(!e)return t;const o=e.split(/\s+/);return o.includes("--no-warnings")||o.includes(t)?e:`${e} ${t}`}export function shouldSuppressStdioChildStderrLine(n){const t=n.trim();return t.includes("ExperimentalWarning:")||t.startsWith("(Use `node --trace-warnings")||/\[INFO\s*\]\s*\[[^\]]+\]\s*MCP Server running on stdio$/.test(t)}function c(n,e,o){const s=new t({command:n.command,args:[...n.args??[]],cwd:e,env:buildStdioChildEnv(o),stderr:"pipe"});return l(s),s}function l(n){const t=n.stderr;if(!t)return;let e="";const o=n=>{shouldSuppressStdioChildStderrLine(n)||process.stderr.write(`${n}\n`)};t.on("data",n=>{e+=n.toString();const t=e.split(/\r?\n/);e=t.pop()??"";for(const n of t)o(n)}),t.on("end",()=>{e.length>0&&(o(e),e="")})}export class McpClientManager{connections=new Map;async connect(t,i,r,l={}){const a=this.connections.get(t);if(a)return a.client;const d=l.timeoutMs??s,p=l.samplingModel?{sampling:{}}:{},m=new n({name:`roll-client-${t}`,version:"0.0.1"},{capabilities:p});l.samplingModel&&o(m,l.samplingModel);const u="streamable-http"===i.type?new e(new URL(i.endpoint)):c(i,r,l.env),h=m.connect(u);let O;const g=new Promise((n,e)=>{O=setTimeout(()=>e(new Error(`Connection to "${t}" timed out after ${d}ms`)),d)});try{await Promise.race([h,g])}catch(n){throw await m.close().catch(()=>{}),n}finally{clearTimeout(O)}return this.connections.set(t,{client:m,transportType:i.type}),m}async disconnect(n){const t=this.connections.get(n);t&&(await t.client.close(),this.connections.delete(n))}async disconnectAll(){const n=[...this.connections.keys()];await Promise.all(n.map(n=>this.disconnect(n)))}isConnected(n){return this.connections.has(n)}}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { AgentCatalogEntry } from "./catalog.ts";
|
|
2
|
+
import type { RollConfig } from "../config/schema.ts";
|
|
3
|
+
export interface CatalogCacheFile {
|
|
4
|
+
readonly checkedAt: number;
|
|
5
|
+
readonly registry: string;
|
|
6
|
+
readonly entries: readonly AgentCatalogEntry[];
|
|
7
|
+
}
|
|
8
|
+
export interface DiscoveredPackageInfo {
|
|
9
|
+
readonly description?: string;
|
|
10
|
+
readonly hasRollAgentManifest: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface DiscoveryCommandOptions {
|
|
13
|
+
readonly registry?: string;
|
|
14
|
+
readonly timeoutMs: number;
|
|
15
|
+
}
|
|
16
|
+
export interface ResolveCatalogCollaborators {
|
|
17
|
+
readonly searchScopePackages?: (options: DiscoveryCommandOptions) => Promise<readonly string[]>;
|
|
18
|
+
readonly fetchPackageInfo?: (packageName: string, options: DiscoveryCommandOptions) => Promise<DiscoveredPackageInfo | undefined>;
|
|
19
|
+
readonly readCache?: () => CatalogCacheFile | undefined;
|
|
20
|
+
readonly writeCache?: (cache: CatalogCacheFile) => void;
|
|
21
|
+
readonly now?: () => number;
|
|
22
|
+
}
|
|
23
|
+
export interface ResolveCatalogOptions {
|
|
24
|
+
readonly allowNetwork?: boolean;
|
|
25
|
+
readonly forceRefresh?: boolean;
|
|
26
|
+
readonly registry?: string;
|
|
27
|
+
readonly timeoutMs?: number;
|
|
28
|
+
readonly collaborators?: ResolveCatalogCollaborators;
|
|
29
|
+
}
|
|
30
|
+
export declare function resolveAgentCatalog(config?: RollConfig, options?: ResolveCatalogOptions): Promise<readonly AgentCatalogEntry[]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as t,mkdirSync as e,readFileSync as r,writeFileSync as n}from"node:fs";import{homedir as o}from"node:os";import{dirname as i,resolve as s}from"node:path";import{npmViewNetworkArgs as a,runPackageManager as c}from"../cli/utils/package-manager.js";import{getAgentCatalog as u}from"./catalog.js";const f="@roll-agent/",l=864e5,g=1e4,m=100;export async function resolveAgentCatalog(t,e={}){const r=u(t),n=e.collaborators??{},o=n.readCache??j,i=n.writeCache??S,s=n.now??Date.now,a=e.registry??"",c=o(),f=c?.registry===a?c:void 0;if(!e.forceRefresh&&f&&s()-f.checkedAt<l)return d(r,f.entries);if(!(e.allowNetwork??1))return d(r,f?.entries??[]);const g=await p(r,e,n);return void 0===g?d(r,f?.entries??[]):(i({checkedAt:s(),registry:a,entries:g}),d(r,g))}async function p(t,e,r){const n=r.searchScopePackages??N,o=r.fetchPackageInfo??k,i={...e.registry?{registry:e.registry}:{},timeoutMs:e.timeoutMs??g};let s;try{s=await n(i)}catch{return}const a=new Set(t.map(t=>t.packageName)),c=[...new Set(s)].filter(t=>t.startsWith(f)&&!a.has(t)),u=[];for(const t of c){let e;try{e=await o(t,i)}catch{continue}e?.hasRollAgentManifest&&u.push(h(t,e.description))}return u}function y(t){const e=t.slice(12),r=e.endsWith("-agent")?e.slice(0,-6):e;return r.length>0?r:e}function h(t,e){const r=e?.trim()??"";return{shortName:y(t),packageName:t,skillName:t.slice(12),description:r.length>0?r:t,requiredEnv:[]}}function d(t,e){const r=new Set(t.map(t=>t.packageName)),n=new Set(t.map(t=>t.shortName)),o=[...t];for(const t of e){if(r.has(t.packageName))continue;let e=t.shortName;n.has(e)&&(e=t.packageName.slice(12)),n.has(e)||(o.push(e===t.shortName?t:{...t,shortName:e}),r.add(t.packageName),n.add(e))}return o}async function N(t){const e=a({...t.registry?{registry:t.registry}:{}}),{stdout:r}=await c({command:"npm",args:["search",f.slice(0,-1),"--json",`--searchlimit=${String(m)}`,...e]},{timeout:t.timeoutMs}),n=r.trim();if(0===n.length)return[];const o=JSON.parse(n);return Array.isArray(o)?o.flatMap(t=>"object"==typeof t&&null!==t&&"name"in t&&"string"==typeof t.name?[t.name]:[]):[]}async function k(t,e){const r=a({...e.registry?{registry:e.registry}:{}}),{stdout:n}=await c({command:"npm",args:["view",t,"name","description","rollAgent","--json",...r]},{timeout:e.timeoutMs}),o=n.trim();if(0===o.length)return;const i=JSON.parse(o);if("object"!=typeof i||null===i)return;const s=i;return{..."string"==typeof s.description?{description:s.description}:{},hasRollAgentManifest:"object"==typeof s.rollAgent&&null!==s.rollAgent}}function w(){return s(o(),".roll-agent","catalog-cache.json")}function A(t){if("object"!=typeof t||null===t)return!1;const e=t;return"string"==typeof e.shortName&&"string"==typeof e.packageName&&"string"==typeof e.skillName&&"string"==typeof e.description&&Array.isArray(e.requiredEnv)&&e.requiredEnv.every(t=>"string"==typeof t)}function v(t){if("object"!=typeof t||null===t)return!1;const e=t;return"number"==typeof e.checkedAt&&"string"==typeof e.registry&&Array.isArray(e.entries)&&e.entries.every(t=>A(t))}function j(){const e=w();if(t(e))try{const t=JSON.parse(r(e,"utf-8"));return v(t)?t:void 0}catch{return}}function S(r){try{const o=w(),s=i(o);t(s)||e(s,{recursive:!0}),n(o,JSON.stringify(r),"utf-8")}catch{}}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { RollConfig } from "../config/schema.ts";
|
|
2
|
+
export interface AgentCatalogEntry {
|
|
3
|
+
readonly shortName: string;
|
|
4
|
+
readonly packageName: string;
|
|
5
|
+
readonly skillName: string;
|
|
6
|
+
readonly description: string;
|
|
7
|
+
readonly requiredEnv: readonly string[];
|
|
8
|
+
readonly minCoreVersion?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const OFFICIAL_AGENT_CATALOG: readonly [{
|
|
11
|
+
readonly shortName: "browser-use";
|
|
12
|
+
readonly packageName: "@roll-agent/browser-use-agent";
|
|
13
|
+
readonly skillName: "browser-use-agent";
|
|
14
|
+
readonly description: "浏览器操控 Agent。控制浏览器操作招聘平台:读取消息、发送签名回复、筛选候选人,并提供通用 AX snapshot 与元素点击/输入能力。";
|
|
15
|
+
readonly requiredEnv: readonly ["REPLY_AUTHORITY_URL", "REPLY_AUTHORITY_BEARER_TOKEN", "REPLY_AUTHORITY_KEYS_URL", "RECRUITMENT_EVENTS_DEFAULT_AGENT_ID", "RECRUITMENT_EVENTS_API_TOKEN"];
|
|
16
|
+
}, {
|
|
17
|
+
readonly shortName: "smart-reply";
|
|
18
|
+
readonly packageName: "@roll-agent/smart-reply-agent";
|
|
19
|
+
readonly skillName: "smart-reply-agent";
|
|
20
|
+
readonly description: "招聘智能回复 Agent。根据候选人消息和上下文,向 Reply Authority Service 请求已签名回复。";
|
|
21
|
+
readonly requiredEnv: readonly ["REPLY_AUTHORITY_URL", "REPLY_AUTHORITY_BEARER_TOKEN"];
|
|
22
|
+
}, {
|
|
23
|
+
readonly shortName: "reply-policy-tuner";
|
|
24
|
+
readonly packageName: "@roll-agent/reply-policy-tuner-agent";
|
|
25
|
+
readonly skillName: "reply-policy-tuner-agent";
|
|
26
|
+
readonly description: "策略 RSI 编排 Agent(Reply Policy Tuner)。评估、编排与更新招聘回复策略,update 带 evaluate 门禁,与 browser-use 协同使用。";
|
|
27
|
+
readonly requiredEnv: readonly ["REPLY_AUTHORITY_URL", "REPLY_AUTHORITY_BEARER_TOKEN"];
|
|
28
|
+
}, {
|
|
29
|
+
readonly shortName: "octopus";
|
|
30
|
+
readonly packageName: "@roll-agent/octopus-agent";
|
|
31
|
+
readonly skillName: "octopus-agent";
|
|
32
|
+
readonly description: "丸子 Agent(Octopus)。把自然语言问题转换为只读 SQL,并通过 Sponge MCP Server 校验和执行。";
|
|
33
|
+
readonly requiredEnv: readonly ["SPONGE_MCP_BASE_URL", "SPONGE_MCP_ACCESS_TOKEN"];
|
|
34
|
+
}];
|
|
35
|
+
export type OfficialAgentShortName = (typeof OFFICIAL_AGENT_CATALOG)[number]["shortName"];
|
|
36
|
+
export declare function getAgentCatalog(_config?: RollConfig): readonly AgentCatalogEntry[];
|
|
37
|
+
export interface CatalogEntryMatch {
|
|
38
|
+
readonly entry: AgentCatalogEntry;
|
|
39
|
+
readonly versionSpec?: string;
|
|
40
|
+
}
|
|
41
|
+
export declare function findCatalogEntry(catalog: readonly AgentCatalogEntry[], input: string): CatalogEntryMatch | undefined;
|
|
42
|
+
export declare function catalogPackageSpec(entry: AgentCatalogEntry, versionSpec?: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{parsePackageName as e}from"./source.js";export const OFFICIAL_AGENT_CATALOG=[{shortName:"browser-use",packageName:"@roll-agent/browser-use-agent",skillName:"browser-use-agent",description:"浏览器操控 Agent。控制浏览器操作招聘平台:读取消息、发送签名回复、筛选候选人,并提供通用 AX snapshot 与元素点击/输入能力。",requiredEnv:["REPLY_AUTHORITY_URL","REPLY_AUTHORITY_BEARER_TOKEN","REPLY_AUTHORITY_KEYS_URL","RECRUITMENT_EVENTS_DEFAULT_AGENT_ID","RECRUITMENT_EVENTS_API_TOKEN"]},{shortName:"smart-reply",packageName:"@roll-agent/smart-reply-agent",skillName:"smart-reply-agent",description:"招聘智能回复 Agent。根据候选人消息和上下文,向 Reply Authority Service 请求已签名回复。",requiredEnv:["REPLY_AUTHORITY_URL","REPLY_AUTHORITY_BEARER_TOKEN"]},{shortName:"reply-policy-tuner",packageName:"@roll-agent/reply-policy-tuner-agent",skillName:"reply-policy-tuner-agent",description:"策略 RSI 编排 Agent(Reply Policy Tuner)。评估、编排与更新招聘回复策略,update 带 evaluate 门禁,与 browser-use 协同使用。",requiredEnv:["REPLY_AUTHORITY_URL","REPLY_AUTHORITY_BEARER_TOKEN"]},{shortName:"octopus",packageName:"@roll-agent/octopus-agent",skillName:"octopus-agent",description:"丸子 Agent(Octopus)。把自然语言问题转换为只读 SQL,并通过 Sponge MCP Server 校验和执行。",requiredEnv:["SPONGE_MCP_BASE_URL","SPONGE_MCP_ACCESS_TOKEN"]}];export function getAgentCatalog(e){return OFFICIAL_AGENT_CATALOG}export function findCatalogEntry(t,r){const a=r.trim();if(0===a.length)return;const n=e(a),o=a.length>n.length?a.slice(n.length+1):void 0,l=o&&o.length>0?o:void 0,E=t.find(e=>e.shortName===n||e.packageName===n||e.skillName===n);return E?{entry:E,...l?{versionSpec:l}:{}}:void 0}export function catalogPackageSpec(e,t){return t?`${e.packageName}@${t}`:e.packageName}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFileSync as t,existsSync as r,realpathSync as n}from"node:fs";import{readJsonFile as e}from"./json-file.js";import{resolve as o,sep as i}from"node:path";import a from"gray-matter";import{z as s}from"zod";import{parse as p}from"yaml";import{createDefaultRuntimeForTransport as
|
|
1
|
+
import{readFileSync as t,existsSync as r,realpathSync as n}from"node:fs";import{readJsonFile as e}from"./json-file.js";import{resolve as o,sep as i}from"node:path";import a from"gray-matter";import{z as s}from"zod";import{parse as p}from"yaml";import{createDefaultRuntimeForTransport as l}from"../types/agent.js";const d="SKILL.md",m="package.json",c=s.object({name:s.string().min(1),purpose:s.string().optional(),example:s.string().optional(),default:s.string().optional()}),u=s.object({required:s.array(c).optional(),optional:s.array(c).optional()}),f=s.object({required:s.boolean().optional(),purpose:s.string().optional(),example:s.string().optional(),default:s.string().optional()}),h=s.object({env:s.record(f).optional()});export function discoverAgent(n){const e=o(n),i=o(e,d);if(!r(i))throw new Error(`SKILL.md not found in ${e}`);const s=t(i,"utf-8"),{data:p,content:m}=a(s),c=j(e),u=p,f=u.name,h=u.description;if("string"!=typeof f||0===f.length)throw new Error(`SKILL.md missing required field "name" in ${i}`);if("string"!=typeof h||0===h.length)throw new Error(`SKILL.md missing required field "description" in ${i}`);const g=u.metadata??{},w={};for(const[t,r]of Object.entries(g))w[t]=String(r);const v="string"==typeof u.license?u.license:void 0,b="string"==typeof u.compatibility?u.compatibility:void 0,$=y(e,w,i),S={name:f,description:h,...v?{license:v}:{},...b?{compatibility:b}:{},metadata:w,...$?{env:$}:{}},I=c?E(c):void 0;if(I&&q(w)){if(!x(L(w),I.transport))throw new Error(`Conflicting runtime metadata in ${i}: package.json#rollAgent and SKILL.md metadata disagree`)}const K=I?.transport??L(w);return{skill:S,transport:K,runtime:I?.runtime??l(K),skillPath:i,skillBody:m.trim()}}function g(t,r){if(void 0===t)return;if(A(t)&&"env"in t)return w(t,r);const n=u.safeParse(t);if(!n.success){const t=n.error.issues.map(t=>`${t.path.length>0?`env.${t.path.join(".")}`:"env"}: ${t.message}`).join("; ");throw new Error(`SKILL.md has invalid "env" declaration in ${r}: ${t}`)}const e=n.data;return e.required||e.optional?{...e.required?{required:e.required.map(b)}:{},...e.optional?{optional:e.optional.map(b)}:{}}:void 0}function w(t,r){const n=h.safeParse(t);if(!n.success){const t=n.error.issues.map(t=>`${t.path.length>0?t.path.join("."):"env"}: ${t.message}`).join("; ");throw new Error(`SKILL.md has invalid "env" declaration in ${r}: ${t}`)}const e=n.data.env;if(!e)return;const o=[],i=[];for(const[t,n]of Object.entries(e)){if(0===t.length)throw new Error(`SKILL.md has invalid "env" declaration in ${r}: env key is empty`);const e=$(t,n);!0===n.required?o.push(e):i.push(e)}return 0!==o.length||0!==i.length?{...o.length>0?{required:o}:{},...i.length>0?{optional:i}:{}}:void 0}function y(e,i,a){const s=i["roll-env-file"];if(!s)return;const l=o(e,s);if(!v(e,l))throw new Error(`SKILL.md roll-env-file must stay within agent directory: ${a}`);if(!r(l))throw new Error(`SKILL.md roll-env-file not found: ${l}`);const d=n(e),m=n(l);if(!v(d,m))throw new Error(`SKILL.md roll-env-file must stay within agent directory: ${a}`);let c;try{c=p(t(m,"utf-8"))}catch(t){throw new Error(`Failed to parse roll-env-file for ${a}: ${t instanceof Error?t.message:String(t)}`)}return g(c,m)}function v(t,r){return r===t||r.startsWith(`${t}${i}`)}function b(t){return{name:t.name,...t.purpose?{purpose:t.purpose}:{},...t.example?{example:t.example}:{},...t.default?{default:t.default}:{}}}function $(t,r){return{name:t,...r.purpose?{purpose:r.purpose}:{},...r.example?{example:r.example}:{},...r.default?{default:r.default}:{}}}function L(t){if("streamable-http"===("streamable-http"===t["roll-transport"]?"streamable-http":"stdio")){const r=t["roll-endpoint"];if(!r)throw new Error('SKILL.md declares streamable-http transport but missing "roll-endpoint"');return{type:"streamable-http",endpoint:r}}const r=(t["roll-command"]??"node --experimental-strip-types src/index.ts").split(/\s+/),n=r[0],e=r.slice(1);if(!n)throw new Error("Invalid roll-command in SKILL.md");return e.length>0?{type:"stdio",command:n,args:e}:{type:"stdio",command:n}}function j(t){const n=o(t,m);if(!r(n))return;let i;try{i=e(n)}catch{throw new Error(`Invalid package.json in ${t}`)}if(!A(i)||!A(i.rollAgent))return;const a=i.rollAgent,s=A(a.runtime)?a.runtime:void 0;if(!s)throw new Error(`package.json#rollAgent.runtime is required in ${n}`);const p={runtime:{ownership:K(s.ownership)??"",transport:K(s.transport)??""}};if(A(a.start)){const t=K(a.start.command),r=k(a.start.args);(t||r)&&(p.start={...t?{command:t}:{},...r?{args:r}:{}})}if(A(a.endpoint)){const t=K(a.endpoint.url),r=K(a.endpoint.path),n="number"==typeof a.endpoint.port?a.endpoint.port:void 0;(t||r||void 0!==n)&&(p.endpoint={...t?{url:t}:{},...r?{path:r}:{},...void 0!==n?{port:n}:{}})}if(A(a.setup)&&A(a.setup.playwright)){const t=k(a.setup.playwright.browsers);t&&t.length>0&&(p.setup={playwright:{browsers:t}})}return p}function E(t){const{ownership:r,transport:n}=t.runtime;if("on-demand"===r&&"stdio"===n){const r=t.start?.command;if(!r)throw new Error("package.json#rollAgent.start.command is required for stdio runtime");const n=t.start?.args;return{transport:n?{type:"stdio",command:r,args:n}:{type:"stdio",command:r},runtime:{ownership:"on-demand"}}}if("core-managed"===r&&"streamable-http"===n){const r=t.start?.command,n=S(t),e=t.endpoint?.path,o=t.endpoint?.port;if(!r||!e||void 0===o)throw new Error("package.json#rollAgent for core-managed streamable-http requires start.command, endpoint.path and endpoint.port");const i=t.start?.args,a=t.setup?.playwright?.browsers;return{transport:{type:"streamable-http",endpoint:n},runtime:{ownership:"core-managed",start:i?{command:r,args:i}:{command:r},endpoint:{path:e,port:o},...a&&a.length>0?{setup:{playwright:{browsers:a}}}:{}}}}if("external-managed"===r&&"streamable-http"===n)return{transport:{type:"streamable-http",endpoint:S(t)},runtime:{ownership:"external-managed"}};throw new Error(`Unsupported package.json#rollAgent runtime combination: ${r}/${n}`)}function S(t){const r=t.endpoint?.url;if(r)return r;const n=t.endpoint?.path,e=t.endpoint?.port;if(!n||void 0===e)throw new Error("package.json#rollAgent.streamable-http requires endpoint.url or endpoint.path + endpoint.port");return I(n,e)}function I(t,r){const n=t.startsWith("/")?t:`/${t}`;return`http://127.0.0.1:${String(r)}${n}`}function q(t){return"string"==typeof t["roll-transport"]||"string"==typeof t["roll-endpoint"]||"string"==typeof t["roll-command"]}function x(t,r){if(t.type!==r.type)return!1;if("streamable-http"===t.type&&"streamable-http"===r.type)return t.endpoint===r.endpoint;if("stdio"!==t.type||"stdio"!==r.type)return!1;const n=t.args??[],e=r.args??[];return t.command===r.command&&n.join("\0")===e.join("\0")}function K(t){return"string"==typeof t&&t.length>0?t:void 0}function k(t){if(!Array.isArray(t))return;const r=t.filter(t=>"string"==typeof t);return r.length>0?r:void 0}function A(t){return"object"==typeof t&&null!==t}
|
package/dist/registry/index.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export { OFFICIAL_AGENT_CATALOG, catalogPackageSpec, findCatalogEntry, getAgentCatalog, } from "./catalog.ts";
|
|
2
|
+
export type { AgentCatalogEntry, CatalogEntryMatch, OfficialAgentShortName } from "./catalog.ts";
|
|
3
|
+
export { resolveAgentCatalog } from "./catalog-discovery.ts";
|
|
4
|
+
export type { ResolveCatalogOptions } from "./catalog-discovery.ts";
|
|
1
5
|
export { discoverAgent } from "./discovery.ts";
|
|
2
6
|
export type { DiscoveredAgent } from "./discovery.ts";
|
|
3
7
|
export { AgentStore } from "./store.ts";
|
package/dist/registry/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{discoverAgent}from"./discovery.js";export{AgentStore}from"./store.js";export{startAgent,stopAgent,stopAgentGracefully,getAgentPid,getAgentLogPath,probeAgentEndpoint,waitForAgentReady}from"./process-manager.js";export{runAgentSetup}from"./runtime-setup.js";
|
|
1
|
+
export{OFFICIAL_AGENT_CATALOG,catalogPackageSpec,findCatalogEntry,getAgentCatalog}from"./catalog.js";export{resolveAgentCatalog}from"./catalog-discovery.js";export{discoverAgent}from"./discovery.js";export{AgentStore}from"./store.js";export{startAgent,stopAgent,stopAgentGracefully,getAgentPid,getAgentLogPath,probeAgentEndpoint,waitForAgentReady}from"./process-manager.js";export{runAgentSetup}from"./runtime-setup.js";
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { runPackageManagerWithRetry } from "../cli/utils/package-manager.ts";
|
|
2
|
+
import { discoverAgent } from "./discovery.ts";
|
|
3
|
+
import { startAgent, stopAgentGracefully, waitForAgentReady } from "./process-manager.ts";
|
|
4
|
+
import { runAgentSetup } from "./runtime-setup.ts";
|
|
5
|
+
import { readInstalledPackageManifest, resolveInstalledPackageRoot } from "./source.ts";
|
|
6
|
+
import { AgentStore } from "./store.ts";
|
|
7
|
+
import type { AgentEnvCheckReport } from "../config/helpers.ts";
|
|
8
|
+
import type { RollConfig } from "../config/schema.ts";
|
|
9
|
+
import type { RegisteredAgent } from "../types/agent.ts";
|
|
10
|
+
export declare const INSTALL_AGENT_STEPS: readonly ["resolve", "download", "discover", "setup", "register", "start"];
|
|
11
|
+
export type InstallAgentStep = (typeof INSTALL_AGENT_STEPS)[number];
|
|
12
|
+
export type InstallAgentEvent = {
|
|
13
|
+
readonly type: "step";
|
|
14
|
+
readonly step: InstallAgentStep;
|
|
15
|
+
readonly message: string;
|
|
16
|
+
} | {
|
|
17
|
+
readonly type: "info";
|
|
18
|
+
readonly message: string;
|
|
19
|
+
} | {
|
|
20
|
+
readonly type: "warn";
|
|
21
|
+
readonly message: string;
|
|
22
|
+
} | {
|
|
23
|
+
readonly type: "success";
|
|
24
|
+
readonly message: string;
|
|
25
|
+
} | {
|
|
26
|
+
readonly type: "retry";
|
|
27
|
+
readonly attempt: number;
|
|
28
|
+
readonly delayMs: number;
|
|
29
|
+
};
|
|
30
|
+
export type InstallAgentReporter = (event: InstallAgentEvent) => void;
|
|
31
|
+
export interface InstallAgentInput {
|
|
32
|
+
readonly packageSpec: string;
|
|
33
|
+
readonly skipBrowserSetup?: boolean;
|
|
34
|
+
readonly autoStart?: boolean;
|
|
35
|
+
readonly replaceExisting?: boolean;
|
|
36
|
+
readonly expectedSkillName?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface InstallAgentCollaborators {
|
|
39
|
+
readonly runInstall?: typeof runPackageManagerWithRetry;
|
|
40
|
+
readonly discover?: typeof discoverAgent;
|
|
41
|
+
readonly runSetup?: typeof runAgentSetup;
|
|
42
|
+
readonly start?: typeof startAgent;
|
|
43
|
+
readonly waitReady?: typeof waitForAgentReady;
|
|
44
|
+
readonly stopGracefully?: typeof stopAgentGracefully;
|
|
45
|
+
readonly resolvePackageRoot?: typeof resolveInstalledPackageRoot;
|
|
46
|
+
readonly readManifest?: typeof readInstalledPackageManifest;
|
|
47
|
+
}
|
|
48
|
+
export interface InstallAgentDeps {
|
|
49
|
+
readonly agentsConfig: RollConfig["agents"];
|
|
50
|
+
readonly installConfig: RollConfig["install"];
|
|
51
|
+
readonly getStartEnv: (agentName: string) => Readonly<Record<string, string>> | undefined;
|
|
52
|
+
readonly store?: AgentStore;
|
|
53
|
+
readonly report?: InstallAgentReporter;
|
|
54
|
+
readonly collaborators?: InstallAgentCollaborators;
|
|
55
|
+
}
|
|
56
|
+
export interface InstallAgentFailure {
|
|
57
|
+
readonly ok: false;
|
|
58
|
+
readonly step: InstallAgentStep;
|
|
59
|
+
readonly message: string;
|
|
60
|
+
readonly retryCommand?: string;
|
|
61
|
+
}
|
|
62
|
+
export interface InstallAgentSuccess {
|
|
63
|
+
readonly ok: true;
|
|
64
|
+
readonly agent: RegisteredAgent;
|
|
65
|
+
readonly envReport: AgentEnvCheckReport | undefined;
|
|
66
|
+
readonly started: boolean;
|
|
67
|
+
}
|
|
68
|
+
export type InstallAgentResult = InstallAgentSuccess | InstallAgentFailure;
|
|
69
|
+
export declare function installAgent(input: InstallAgentInput, deps: InstallAgentDeps): Promise<InstallAgentResult>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as e,mkdirSync as t,rmSync as s,statSync as r}from"node:fs";import{resolve as a}from"node:path";import{buildNpmRetryPolicy as n,formatPackageManagerError as i,npmInstallNetworkArgs as o,runPackageManagerWithRetry as l}from"../cli/utils/package-manager.js";import{inspectAgentEnvRequirements as g}from"../config/helpers.js";import{discoverAgent as m}from"./discovery.js";import{startAgent as p,stopAgentGracefully as c,waitForAgentReady as u}from"./process-manager.js";import{runAgentSetup as d}from"./runtime-setup.js";import{parsePackageName as f,readInstalledPackageManifest as k,resolveInstalledPackageRoot as y,sanitizeInstallId as h}from"./source.js";import{AgentStore as w}from"./store.js";export const INSTALL_AGENT_STEPS=["resolve","download","discover","setup","register","start"];function v(e){return o({...e.registry?{registry:e.registry}:{},fetchRetries:e.fetchRetries,preferOffline:e.preferOffline})}function S(e){return e.startsWith("git@")||e.startsWith("git+")||e.startsWith("github:")||e.startsWith("gitlab:")||e.startsWith("bitbucket:")||e.endsWith(".git")}function $(t){const s=a(t);return e(s)&&r(s).isDirectory()}function C(e){return e instanceof Error?e.message:String(e)}function A(e){return e.source?.type??"unknown"}function D(e,t,s){return{ok:!1,step:"register",message:`Agent "${e}" 已通过 ${t} 来源注册。为避免覆盖本地/Git Agent,默认不会替换为 npm 安装。请先运行 \`roll agent remove ${e}\`,或确认风险后使用 \`roll agent install ${s} --force\`。`,retryCommand:`roll agent install ${s} --force`}}function j(e,t){return void 0!==e&&"installed-package"!==e.source?.type&&!t}export async function installAgent(r,o){const R=o.report??(()=>{}),B=o.collaborators??{},b=B.runInstall??l,M=B.discover??m,N=B.runSetup??d,T=B.start??p,W=B.waitReady??u,x=B.stopGracefully??c,E=B.resolvePackageRoot??y,L=B.readManifest??k,{packageSpec:G}=r,I=r.autoStart??!0,O=r.replaceExisting??!1;if(S(G))return{ok:!1,step:"resolve",message:`Git URL 请使用 \`roll agent add ${G}\` 注册,不要使用 \`roll agent install\``};if($(G))return{ok:!1,step:"resolve",message:`本地源码目录请使用 \`roll agent add ${G}\` 注册,不要使用 \`roll agent install\``};const P=f(G),_=a(o.agentsConfig.dataDir,"installed",h(P)),q=o.store??new w(o.agentsConfig.dataDir),K=r.expectedSkillName,U=K?q.findByName(K):void 0;if(U&&j(U,O))return D(U.skill.name,A(U),G);const V=e(_);V||t(_,{recursive:!0}),o.installConfig.registry&&R({type:"info",message:`使用 npm registry: ${o.installConfig.registry}(roll.config.yaml install.registry)`}),R({type:"step",step:"download",message:`安装 ${G}...`});const z={command:"npm",args:["install","--prefix",_,G,...v(o.installConfig)]};try{await b(z,{timeout:o.installConfig.networkTimeoutMs},{...n(o.installConfig.fetchRetries),onRetry:({attempt:e,delayMs:t})=>{R({type:"retry",attempt:e,delayMs:t})}})}catch(e){return{ok:!1,step:"download",message:`安装失败: ${i(z,e)}`}}const F=E(_,P);if(!e(F))return{ok:!1,step:"discover",message:`安装完成但未找到包目录: ${F}`};const H=L(F);let J;R({type:"step",step:"discover",message:"解析已安装 Agent 的 SKILL.md..."});try{J=M(F)}catch(e){return{ok:!1,step:"discover",message:C(e)}}const Q={skill:J.skill,transport:J.transport,runtime:J.runtime,installPath:F,registeredAt:(new Date).toISOString(),status:"idle",source:{type:"installed-package",packageName:H?.name??P,packageSpec:G,installDir:_,...H?.version?{installedVersion:H.version}:{}},...J.skillBody.length>0?{skillBody:J.skillBody}:{}},X=q.findByName(J.skill.name);if(X&&j(X,O))return V||s(_,{recursive:!0,force:!0}),D(J.skill.name,A(X),G);"core-managed"===Q.runtime.ownership&&Q.runtime.setup?.playwright&&!r.skipBrowserSetup&&R({type:"info",message:`即将安装浏览器运行时 (${Q.runtime.setup.playwright.browsers.join(", ")}),这可能需要一些时间...`});const Y=await N(Q,{skipBrowserSetup:r.skipBrowserSetup??!1});Y.ok&&!Y.skipped?R({type:"success",message:Y.message}):Y.ok&&R({type:"info",message:Y.message});const Z="core-managed"===X?.runtime.ownership&&"online"===X.status;try{if("installed-package"===X?.source?.type||X&&O){if("installed-package"!==X.source?.type){const e=X.source?.type??"unknown";R({type:"info",message:`Agent "${J.skill.name}" 已通过 ${e} 来源注册,将替换为 npm 安装`})}q.replace(X.skill.name,Q)}else q.add(Q)}catch(e){return{ok:!1,step:"register",message:C(e)}}if(!Y.ok)return Z&&await x(o.agentsConfig.dataDir,Q.skill.name).catch(()=>{}),q.updateStatus(J.skill.name,"error"),{ok:!1,step:"setup",message:Y.message,...Y.retryCommand?{retryCommand:Y.retryCommand}:{}};const ee=g(Q.skill.name,J.skill.env,o.agentsConfig.env),te=ee?.missingRequired??[];let se=!1;const re="core-managed"===Q.runtime.ownership&&I,ae=re&&0===te.length;if(Z&&!ae&&(await x(o.agentsConfig.dataDir,Q.skill.name).catch(()=>{}),q.updateStatus(Q.skill.name,"idle")),re)if(te.length>0)R({type:"warn",message:`Agent "${Q.skill.name}" 缺少必填环境变量(${te.map(e=>e.name).join(", ")}),暂不启动。配置后运行 \`roll agent start ${Q.skill.name}\` 启动`});else{let e=!1;try{Z&&await x(o.agentsConfig.dataDir,Q.skill.name),q.updateStatus(Q.skill.name,"starting"),T(Q,o.agentsConfig.dataDir,o.getStartEnv(Q.skill.name)),e=!0,await W(Q,{startupTimeoutMs:15e3,probeTimeoutMs:2e3}),q.updateStatus(Q.skill.name,"online"),se=!0}catch(t){return e&&await x(o.agentsConfig.dataDir,Q.skill.name).catch(()=>{}),q.updateStatus(Q.skill.name,"error"),{ok:!1,step:"start",message:`Agent "${J.skill.name}" 已安装,但自动启动失败:${C(t)}`}}}return{ok:!0,agent:Q,envReport:ee,started:se}}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface SkillInstallCandidate {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly description: string;
|
|
4
|
+
readonly sourceDir: string;
|
|
5
|
+
}
|
|
6
|
+
export interface CollectInstallableSkillsResult {
|
|
7
|
+
readonly skills: readonly SkillInstallCandidate[];
|
|
8
|
+
readonly issues: readonly string[];
|
|
9
|
+
}
|
|
10
|
+
export interface InstalledSkillRecord {
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly targetPath: string;
|
|
13
|
+
readonly overwritten: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function collectInstallableSkills(sourceDir: string): CollectInstallableSkillsResult;
|
|
16
|
+
export declare function installSkillsToDir(skills: readonly SkillInstallCandidate[], targetSkillsDir: string): readonly InstalledSkillRecord[];
|
|
17
|
+
export declare function findExistingSkillInstalls(skills: readonly SkillInstallCandidate[], targetSkillsDir: string): readonly string[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cpSync as t,existsSync as r,mkdirSync as s,readFileSync as e,readdirSync as n,rmSync as i,statSync as o}from"node:fs";import{join as u,resolve as c}from"node:path";import l from"gray-matter";import{sanitizeInstallId as a}from"../registry/source.js";const m="SKILL.md";function f(t){try{return o(t).isDirectory()}catch{return!1}}function p(t){return t instanceof Error?t.message:String(t)}function h(t){const r=u(t,m);let s,n;try{s=e(r,"utf-8")}catch(t){return{issue:`无法读取 ${r}: ${p(t)}`}}try{n=l(s).data}catch(t){return{issue:`SKILL.md frontmatter 解析失败 ${r}: ${p(t)}`}}const i=n.name;if("string"!=typeof i||0===i.trim().length)return{issue:`${r} 缺少有效的 frontmatter name,已跳过`};const o=n.description;return"string"!=typeof o||0===o.trim().length?{issue:`${r} 缺少有效的 frontmatter description,已跳过`}:{skill:{name:i.trim(),description:o.trim(),sourceDir:t}}}export function collectInstallableSkills(t){const s=c(t);if(!f(s))return{skills:[],issues:[`目录不存在: ${s}`]};if(r(u(s,m))){const{skill:t,issue:r}=h(s);return{skills:t?[t]:[],issues:r?[r]:[]}}const e=[],i=[];let o;try{o=n(s)}catch(t){return{skills:[],issues:[`无法读取目录 ${s}: ${p(t)}`]}}for(const t of o.sort()){const n=u(s,t);if(!f(n)||!r(u(n,m)))continue;const{skill:o,issue:c}=h(n);o&&e.push(o),c&&i.push(c)}return 0===e.length&&0===i.length&&i.push(`未在 ${s} 找到包含 SKILL.md 的 skill 目录`),{skills:e,issues:i}}export function installSkillsToDir(e,n){return s(n,{recursive:!0}),e.map(s=>{const e=u(n,a(s.name)),o=r(e);return o&&i(e,{recursive:!0,force:!0}),t(s.sourceDir,e,{recursive:!0}),{name:s.name,targetPath:e,overwritten:o}})}export function findExistingSkillInstalls(t,s){return t.filter(t=>r(u(s,a(t.name)))).map(t=>t.name)}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface OrchestratorSkillTarget {
|
|
2
|
+
readonly id: string;
|
|
3
|
+
readonly label: string;
|
|
4
|
+
readonly userDir: string;
|
|
5
|
+
readonly projectDir: string;
|
|
6
|
+
readonly detectDir: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const ORCHESTRATOR_SKILL_TARGETS: readonly [{
|
|
9
|
+
readonly id: "claude-code";
|
|
10
|
+
readonly label: "Claude Code";
|
|
11
|
+
readonly userDir: "~/.claude/skills";
|
|
12
|
+
readonly projectDir: ".claude/skills";
|
|
13
|
+
readonly detectDir: "~/.claude";
|
|
14
|
+
}, {
|
|
15
|
+
readonly id: "codex";
|
|
16
|
+
readonly label: "Codex";
|
|
17
|
+
readonly userDir: "~/.codex/skills";
|
|
18
|
+
readonly projectDir: ".codex/skills";
|
|
19
|
+
readonly detectDir: "~/.codex";
|
|
20
|
+
}, {
|
|
21
|
+
readonly id: "agents";
|
|
22
|
+
readonly label: "通用 .agents 目录";
|
|
23
|
+
readonly userDir: "~/.agents/skills";
|
|
24
|
+
readonly projectDir: ".agents/skills";
|
|
25
|
+
readonly detectDir: "~/.agents";
|
|
26
|
+
}];
|
|
27
|
+
export type OrchestratorTargetId = (typeof ORCHESTRATOR_SKILL_TARGETS)[number]["id"];
|
|
28
|
+
export declare function isOrchestratorTargetId(value: string): value is OrchestratorTargetId;
|
|
29
|
+
export interface DetectOrchestratorOptions {
|
|
30
|
+
readonly home?: string;
|
|
31
|
+
readonly cwd?: string;
|
|
32
|
+
readonly project?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface DetectedOrchestratorTarget {
|
|
35
|
+
readonly target: OrchestratorSkillTarget;
|
|
36
|
+
readonly present: boolean;
|
|
37
|
+
readonly skillsDir: string;
|
|
38
|
+
}
|
|
39
|
+
export declare function detectOrchestratorTargets(options?: DetectOrchestratorOptions): readonly DetectedOrchestratorTarget[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as e}from"node:fs";import{homedir as r}from"node:os";import{join as t,resolve as o}from"node:path";export const ORCHESTRATOR_SKILL_TARGETS=[{id:"claude-code",label:"Claude Code",userDir:"~/.claude/skills",projectDir:".claude/skills",detectDir:"~/.claude"},{id:"codex",label:"Codex",userDir:"~/.codex/skills",projectDir:".codex/skills",detectDir:"~/.codex"},{id:"agents",label:"通用 .agents 目录",userDir:"~/.agents/skills",projectDir:".agents/skills",detectDir:"~/.agents"}];const s=Object.fromEntries(ORCHESTRATOR_SKILL_TARGETS.map(e=>[e.id,e]));export function isOrchestratorTargetId(e){return e in s}function i(e,r){return t(e,r.replace(/^~\//,""))}export function detectOrchestratorTargets(t={}){const s=t.home??r(),c=t.cwd??process.cwd();return ORCHESTRATOR_SKILL_TARGETS.map(r=>({target:r,present:e(i(s,r.detectDir)),skillsDir:t.project?o(c,r.projectDir):i(s,r.userDir)}))}
|