@soleri/forge 5.1.3 → 5.4.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/index.js +0 -0
- package/dist/scaffolder.js +150 -2
- package/dist/scaffolder.js.map +1 -1
- package/dist/templates/brain.d.ts +6 -0
- package/dist/templates/brain.js +478 -0
- package/dist/templates/brain.js.map +1 -0
- package/dist/templates/claude-md-template.js +90 -1
- package/dist/templates/claude-md-template.js.map +1 -1
- package/dist/templates/core-facade.d.ts +6 -0
- package/dist/templates/core-facade.js +564 -0
- package/dist/templates/core-facade.js.map +1 -0
- package/dist/templates/domain-facade.d.ts +4 -0
- package/dist/templates/domain-facade.js +4 -0
- package/dist/templates/domain-facade.js.map +1 -1
- package/dist/templates/entry-point.js +32 -0
- package/dist/templates/entry-point.js.map +1 -1
- package/dist/templates/facade-factory.d.ts +1 -0
- package/dist/templates/facade-factory.js +63 -0
- package/dist/templates/facade-factory.js.map +1 -0
- package/dist/templates/facade-types.d.ts +1 -0
- package/dist/templates/facade-types.js +46 -0
- package/dist/templates/facade-types.js.map +1 -0
- package/dist/templates/intelligence-loader.d.ts +1 -0
- package/dist/templates/intelligence-loader.js +43 -0
- package/dist/templates/intelligence-loader.js.map +1 -0
- package/dist/templates/intelligence-types.d.ts +1 -0
- package/dist/templates/intelligence-types.js +24 -0
- package/dist/templates/intelligence-types.js.map +1 -0
- package/dist/templates/llm-client.d.ts +7 -0
- package/dist/templates/llm-client.js +300 -0
- package/dist/templates/llm-client.js.map +1 -0
- package/dist/templates/llm-key-pool.d.ts +7 -0
- package/dist/templates/llm-key-pool.js +211 -0
- package/dist/templates/llm-key-pool.js.map +1 -0
- package/dist/templates/llm-types.d.ts +5 -0
- package/dist/templates/llm-types.js +161 -0
- package/dist/templates/llm-types.js.map +1 -0
- package/dist/templates/llm-utils.d.ts +5 -0
- package/dist/templates/llm-utils.js +260 -0
- package/dist/templates/llm-utils.js.map +1 -0
- package/dist/templates/planner.d.ts +5 -0
- package/dist/templates/planner.js +150 -0
- package/dist/templates/planner.js.map +1 -0
- package/dist/templates/setup-script.js +26 -1
- package/dist/templates/setup-script.js.map +1 -1
- package/dist/templates/test-brain.d.ts +6 -0
- package/dist/templates/test-brain.js +474 -0
- package/dist/templates/test-brain.js.map +1 -0
- package/dist/templates/test-facades.js +173 -3
- package/dist/templates/test-facades.js.map +1 -1
- package/dist/templates/test-llm.d.ts +7 -0
- package/dist/templates/test-llm.js +574 -0
- package/dist/templates/test-llm.js.map +1 -0
- package/dist/templates/test-loader.d.ts +5 -0
- package/dist/templates/test-loader.js +146 -0
- package/dist/templates/test-loader.js.map +1 -0
- package/dist/templates/test-planner.d.ts +5 -0
- package/dist/templates/test-planner.js +271 -0
- package/dist/templates/test-planner.js.map +1 -0
- package/dist/templates/test-vault.d.ts +5 -0
- package/dist/templates/test-vault.js +380 -0
- package/dist/templates/test-vault.js.map +1 -0
- package/dist/templates/vault.d.ts +5 -0
- package/dist/templates/vault.js +263 -0
- package/dist/templates/vault.js.map +1 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/scaffolder.test.ts +2 -2
- package/src/scaffolder.ts +153 -2
- package/src/templates/claude-md-template.ts +181 -0
- package/src/templates/domain-facade.ts +4 -0
- package/src/templates/entry-point.ts +32 -0
- package/src/templates/setup-script.ts +28 -1
- package/src/templates/test-facades.ts +173 -3
- package/src/types.ts +2 -0
|
@@ -123,6 +123,29 @@ ${domainDescribes}
|
|
|
123
123
|
if (stats.totalEntries === 0) {
|
|
124
124
|
recommendations.push('Vault is empty');
|
|
125
125
|
}
|
|
126
|
+
// Check hook status
|
|
127
|
+
const { readdirSync } = await import('node:fs');
|
|
128
|
+
const agentClaudeDir = joinPath(__dirname, '..', '.claude');
|
|
129
|
+
const globalClaudeDir = joinPath(homedir(), '.claude');
|
|
130
|
+
const hookStatus = { agent: [] as string[], global: [] as string[], missing: [] as string[] };
|
|
131
|
+
if (exists(agentClaudeDir)) {
|
|
132
|
+
try {
|
|
133
|
+
const agentHooks = readdirSync(agentClaudeDir)
|
|
134
|
+
.filter((f: string) => f.startsWith('hookify.') && f.endsWith('.local.md'))
|
|
135
|
+
.map((f: string) => f.replace('hookify.', '').replace('.local.md', ''));
|
|
136
|
+
hookStatus.agent = agentHooks;
|
|
137
|
+
for (const hook of agentHooks) {
|
|
138
|
+
if (exists(joinPath(globalClaudeDir, \`hookify.\${hook}.local.md\`))) {
|
|
139
|
+
hookStatus.global.push(hook);
|
|
140
|
+
} else {
|
|
141
|
+
hookStatus.missing.push(hook);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
} catch { /* ignore */ }
|
|
145
|
+
}
|
|
146
|
+
if (hookStatus.missing.length > 0) {
|
|
147
|
+
recommendations.push(\`\${hookStatus.missing.length} hook(s) not installed globally — run scripts/setup.sh\`);
|
|
148
|
+
}
|
|
126
149
|
if (recommendations.length === 0) {
|
|
127
150
|
recommendations.push('${config.name} is fully set up and ready!');
|
|
128
151
|
}
|
|
@@ -133,6 +156,7 @@ ${domainDescribes}
|
|
|
133
156
|
global: { exists: exists(globalClaudeMd), has_agent_section: hasAgentMarker(globalClaudeMd) },
|
|
134
157
|
},
|
|
135
158
|
vault: { entries: stats.totalEntries, domains: Object.keys(stats.byDomain) },
|
|
159
|
+
hooks: hookStatus,
|
|
136
160
|
recommendations,
|
|
137
161
|
};
|
|
138
162
|
},
|
|
@@ -169,6 +193,10 @@ ${domainDescribes}
|
|
|
169
193
|
expect(opNames).toContain('brain_archive_sessions');
|
|
170
194
|
expect(opNames).toContain('brain_promote_proposals');
|
|
171
195
|
expect(opNames).toContain('brain_lifecycle');
|
|
196
|
+
// Enhanced brain ops (3)
|
|
197
|
+
expect(opNames).toContain('brain_feedback');
|
|
198
|
+
expect(opNames).toContain('brain_feedback_stats');
|
|
199
|
+
expect(opNames).toContain('brain_reset_extracted');
|
|
172
200
|
// Agent-specific ops (5)
|
|
173
201
|
expect(opNames).toContain('health');
|
|
174
202
|
expect(opNames).toContain('identity');
|
|
@@ -184,8 +212,122 @@ ${domainDescribes}
|
|
|
184
212
|
expect(opNames).toContain('route_intent');
|
|
185
213
|
expect(opNames).toContain('morph');
|
|
186
214
|
expect(opNames).toContain('get_behavior_rules');
|
|
187
|
-
//
|
|
188
|
-
expect(
|
|
215
|
+
// Cognee ops (5)
|
|
216
|
+
expect(opNames).toContain('cognee_status');
|
|
217
|
+
expect(opNames).toContain('cognee_search');
|
|
218
|
+
expect(opNames).toContain('cognee_add');
|
|
219
|
+
expect(opNames).toContain('cognee_cognify');
|
|
220
|
+
expect(opNames).toContain('cognee_config');
|
|
221
|
+
// LLM ops (2)
|
|
222
|
+
expect(opNames).toContain('llm_rotate');
|
|
223
|
+
expect(opNames).toContain('llm_call');
|
|
224
|
+
// Governance ops (5)
|
|
225
|
+
expect(opNames).toContain('governance_policy');
|
|
226
|
+
expect(opNames).toContain('governance_proposals');
|
|
227
|
+
expect(opNames).toContain('governance_stats');
|
|
228
|
+
expect(opNames).toContain('governance_expire');
|
|
229
|
+
expect(opNames).toContain('governance_dashboard');
|
|
230
|
+
// Planning Extra ops (9)
|
|
231
|
+
expect(opNames).toContain('plan_iterate');
|
|
232
|
+
expect(opNames).toContain('plan_split');
|
|
233
|
+
expect(opNames).toContain('plan_reconcile');
|
|
234
|
+
expect(opNames).toContain('plan_complete_lifecycle');
|
|
235
|
+
expect(opNames).toContain('plan_dispatch');
|
|
236
|
+
expect(opNames).toContain('plan_review');
|
|
237
|
+
expect(opNames).toContain('plan_archive');
|
|
238
|
+
expect(opNames).toContain('plan_list_tasks');
|
|
239
|
+
expect(opNames).toContain('plan_stats');
|
|
240
|
+
// Memory Extra ops (8)
|
|
241
|
+
expect(opNames).toContain('memory_delete');
|
|
242
|
+
expect(opNames).toContain('memory_stats');
|
|
243
|
+
expect(opNames).toContain('memory_export');
|
|
244
|
+
expect(opNames).toContain('memory_import');
|
|
245
|
+
expect(opNames).toContain('memory_prune');
|
|
246
|
+
expect(opNames).toContain('memory_deduplicate');
|
|
247
|
+
expect(opNames).toContain('memory_topics');
|
|
248
|
+
expect(opNames).toContain('memory_by_project');
|
|
249
|
+
// Vault Extra ops (12)
|
|
250
|
+
expect(opNames).toContain('vault_get');
|
|
251
|
+
expect(opNames).toContain('vault_update');
|
|
252
|
+
expect(opNames).toContain('vault_remove');
|
|
253
|
+
expect(opNames).toContain('vault_bulk_add');
|
|
254
|
+
expect(opNames).toContain('vault_bulk_remove');
|
|
255
|
+
expect(opNames).toContain('vault_tags');
|
|
256
|
+
expect(opNames).toContain('vault_domains');
|
|
257
|
+
expect(opNames).toContain('vault_recent');
|
|
258
|
+
expect(opNames).toContain('vault_import');
|
|
259
|
+
expect(opNames).toContain('vault_seed');
|
|
260
|
+
expect(opNames).toContain('vault_backup');
|
|
261
|
+
expect(opNames).toContain('vault_age_report');
|
|
262
|
+
// Admin ops (8)
|
|
263
|
+
expect(opNames).toContain('admin_health');
|
|
264
|
+
expect(opNames).toContain('admin_tool_list');
|
|
265
|
+
expect(opNames).toContain('admin_config');
|
|
266
|
+
expect(opNames).toContain('admin_vault_size');
|
|
267
|
+
expect(opNames).toContain('admin_uptime');
|
|
268
|
+
expect(opNames).toContain('admin_version');
|
|
269
|
+
expect(opNames).toContain('admin_reset_cache');
|
|
270
|
+
expect(opNames).toContain('admin_diagnostic');
|
|
271
|
+
// Loop ops (7)
|
|
272
|
+
expect(opNames).toContain('loop_start');
|
|
273
|
+
expect(opNames).toContain('loop_iterate');
|
|
274
|
+
expect(opNames).toContain('loop_status');
|
|
275
|
+
expect(opNames).toContain('loop_cancel');
|
|
276
|
+
expect(opNames).toContain('loop_history');
|
|
277
|
+
expect(opNames).toContain('loop_is_active');
|
|
278
|
+
expect(opNames).toContain('loop_complete');
|
|
279
|
+
// Orchestrate ops (5)
|
|
280
|
+
expect(opNames).toContain('orchestrate_plan');
|
|
281
|
+
expect(opNames).toContain('orchestrate_execute');
|
|
282
|
+
expect(opNames).toContain('orchestrate_complete');
|
|
283
|
+
expect(opNames).toContain('orchestrate_status');
|
|
284
|
+
expect(opNames).toContain('orchestrate_quick_capture');
|
|
285
|
+
// Capture ops (4)
|
|
286
|
+
expect(opNames).toContain('capture_knowledge');
|
|
287
|
+
expect(opNames).toContain('capture_quick');
|
|
288
|
+
expect(opNames).toContain('search_intelligent');
|
|
289
|
+
expect(opNames).toContain('search_feedback');
|
|
290
|
+
// Grading ops (5)
|
|
291
|
+
expect(opNames).toContain('plan_grade');
|
|
292
|
+
expect(opNames).toContain('plan_check_history');
|
|
293
|
+
expect(opNames).toContain('plan_latest_check');
|
|
294
|
+
expect(opNames).toContain('plan_meets_grade');
|
|
295
|
+
expect(opNames).toContain('plan_auto_improve');
|
|
296
|
+
// Admin Extra ops (10)
|
|
297
|
+
expect(opNames).toContain('admin_telemetry');
|
|
298
|
+
expect(opNames).toContain('admin_telemetry_recent');
|
|
299
|
+
expect(opNames).toContain('admin_telemetry_reset');
|
|
300
|
+
expect(opNames).toContain('admin_permissions');
|
|
301
|
+
expect(opNames).toContain('admin_vault_analytics');
|
|
302
|
+
expect(opNames).toContain('admin_search_insights');
|
|
303
|
+
expect(opNames).toContain('admin_module_status');
|
|
304
|
+
expect(opNames).toContain('admin_env');
|
|
305
|
+
expect(opNames).toContain('admin_gc');
|
|
306
|
+
expect(opNames).toContain('admin_export_config');
|
|
307
|
+
// Curator Extra ops (4)
|
|
308
|
+
expect(opNames).toContain('curator_entry_history');
|
|
309
|
+
expect(opNames).toContain('curator_record_snapshot');
|
|
310
|
+
expect(opNames).toContain('curator_queue_stats');
|
|
311
|
+
expect(opNames).toContain('curator_enrich');
|
|
312
|
+
// Project ops (12)
|
|
313
|
+
expect(opNames).toContain('project_get');
|
|
314
|
+
expect(opNames).toContain('project_list');
|
|
315
|
+
expect(opNames).toContain('project_unregister');
|
|
316
|
+
expect(opNames).toContain('project_get_rules');
|
|
317
|
+
expect(opNames).toContain('project_list_rules');
|
|
318
|
+
expect(opNames).toContain('project_add_rule');
|
|
319
|
+
expect(opNames).toContain('project_remove_rule');
|
|
320
|
+
expect(opNames).toContain('project_link');
|
|
321
|
+
expect(opNames).toContain('project_unlink');
|
|
322
|
+
expect(opNames).toContain('project_get_links');
|
|
323
|
+
expect(opNames).toContain('project_linked_projects');
|
|
324
|
+
expect(opNames).toContain('project_touch');
|
|
325
|
+
// Cross-project memory ops (3)
|
|
326
|
+
expect(opNames).toContain('memory_promote_to_global');
|
|
327
|
+
expect(opNames).toContain('memory_configure');
|
|
328
|
+
expect(opNames).toContain('memory_cross_project_search');
|
|
329
|
+
// Total: 152 (147 core + 5 agent-specific)
|
|
330
|
+
expect(facade.ops.length).toBe(152);
|
|
189
331
|
});
|
|
190
332
|
|
|
191
333
|
it('search should query across all domains with ranked results', async () => {
|
|
@@ -277,7 +419,9 @@ ${domainDescribes}
|
|
|
277
419
|
const setupOp = facade.ops.find((o) => o.name === 'setup')!;
|
|
278
420
|
const result = (await setupOp.handler({ projectPath: '/tmp/nonexistent-test' })) as {
|
|
279
421
|
agent: { name: string };
|
|
422
|
+
claude_md: { project: { exists: boolean; has_agent_section: boolean }; global: { exists: boolean; has_agent_section: boolean } };
|
|
280
423
|
vault: { entries: number };
|
|
424
|
+
hooks: { agent: string[]; global: string[]; missing: string[] };
|
|
281
425
|
recommendations: string[];
|
|
282
426
|
};
|
|
283
427
|
expect(result.agent.name).toBe('${escapeQuotes(config.name)}');
|
|
@@ -327,6 +471,32 @@ ${domainDescribes}
|
|
|
327
471
|
const result = (await healthOp.handler({})) as { score: number };
|
|
328
472
|
expect(result.score).toBeGreaterThan(0);
|
|
329
473
|
});
|
|
474
|
+
|
|
475
|
+
it('governance_policy get should return default policy', async () => {
|
|
476
|
+
const facade = buildCoreFacade();
|
|
477
|
+
const policyOp = facade.ops.find((o) => o.name === 'governance_policy')!;
|
|
478
|
+
const result = (await policyOp.handler({ action: 'get', projectPath: '/test' })) as {
|
|
479
|
+
projectPath: string;
|
|
480
|
+
quotas: { maxEntriesTotal: number };
|
|
481
|
+
autoCapture: { enabled: boolean };
|
|
482
|
+
};
|
|
483
|
+
expect(result.projectPath).toBe('/test');
|
|
484
|
+
expect(result.quotas.maxEntriesTotal).toBe(500);
|
|
485
|
+
expect(result.autoCapture.enabled).toBe(true);
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
it('governance_dashboard should return combined view', async () => {
|
|
489
|
+
const facade = buildCoreFacade();
|
|
490
|
+
const dashOp = facade.ops.find((o) => o.name === 'governance_dashboard')!;
|
|
491
|
+
const result = (await dashOp.handler({ projectPath: '/test' })) as {
|
|
492
|
+
vaultSize: number;
|
|
493
|
+
quotaPercent: number;
|
|
494
|
+
pendingProposals: number;
|
|
495
|
+
};
|
|
496
|
+
expect(typeof result.vaultSize).toBe('number');
|
|
497
|
+
expect(typeof result.quotaPercent).toBe('number');
|
|
498
|
+
expect(result.pendingProposals).toBe(0);
|
|
499
|
+
});
|
|
330
500
|
});
|
|
331
501
|
});
|
|
332
502
|
`;
|
|
@@ -382,7 +552,7 @@ function generateDomainDescribe(agentId, domain) {
|
|
|
382
552
|
severity: 'warning',
|
|
383
553
|
description: 'A captured pattern.',
|
|
384
554
|
tags: ['captured'],
|
|
385
|
-
})) as { captured: boolean };
|
|
555
|
+
})) as { captured: boolean; governance?: { action: string } };
|
|
386
556
|
expect(result.captured).toBe(true);
|
|
387
557
|
const entry = runtime.vault.get('${domain}-cap1');
|
|
388
558
|
expect(entry).not.toBeNull();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-facades.js","sourceRoot":"","sources":["../../src/templates/test-facades.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAmB;IACrD,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO;SACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;SAChD,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmCS,MAAM,CAAC,EAAE;;;;;;;;;;;EAWzB,eAAe;;cAEH,MAAM,CAAC,EAAE
|
|
1
|
+
{"version":3,"file":"test-facades.js","sourceRoot":"","sources":["../../src/templates/test-facades.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAmB;IACrD,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO;SACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;SAChD,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmCS,MAAM,CAAC,EAAE;;;;;;;;;;;EAWzB,eAAe;;cAEH,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sCA6Fe,MAAM,CAAC,IAAI;;;;;;;;;;;;;;;;iBAgBhC,MAAM,CAAC,EAAE;;;;;;;;kCAQQ,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iDAoKM,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAmCvB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;mCACzB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;0CAWlB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;qCA0B9B,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;wCAgBN,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2EhE,CAAC;AACF,CAAC;AAED,SAAS,sBAAsB,CAAC,OAAe,EAAE,MAAc;IAC7D,MAAM,UAAU,GAAG,GAAG,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;IAE7D,OAAO,eAAe,UAAU;;4CAEU,OAAO,OAAO,MAAM;;;;;kCAK9B,UAAU;;;;;;;;;iDASK,MAAM;;2BAE5B,MAAM,mBAAmB,MAAM;;;;;;kDAMR,MAAM;;;iCAGvB,MAAM;;2BAEZ,MAAM,kBAAkB,MAAM;;;;;;;wDAOD,MAAM;;;wCAGtB,MAAM;;;;eAI/B,MAAM;;;;;;;;yCAQoB,MAAM;;oCAEX,MAAM;;;;6CAIG,MAAM,mBAAmB,MAAM;;;gDAG5B,MAAM;gCACtB,MAAM;;;;6CAIO,MAAM,mBAAmB,MAAM;;;gDAG5B,MAAM;;kCAEpB,MAAM;;MAElC,CAAC;AACP,CAAC;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AgentConfig } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generate the LLM test suite for a new agent.
|
|
4
|
+
* Tests: SecretString, CircuitBreaker, retry, rate-limit parsing,
|
|
5
|
+
* KeyPool rotation, ModelRouter resolution, LLMClient availability.
|
|
6
|
+
*/
|
|
7
|
+
export declare function generateLLMTest(_config: AgentConfig): string;
|