@voybio/ace-swarm 0.2.5 → 2.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/CHANGELOG.md +11 -1
- package/README.md +20 -13
- package/assets/agent-state/EVIDENCE_LOG.md +1 -1
- package/assets/agent-state/MODULES/roles/capability-framework.json +41 -0
- package/assets/agent-state/MODULES/roles/capability-git.json +33 -0
- package/assets/agent-state/MODULES/roles/capability-safety.json +37 -0
- package/assets/agent-state/MODULES/schemas/ACE_RUNTIME_PROFILE.schema.json +21 -0
- package/assets/agent-state/MODULES/schemas/RUNTIME_EXECUTOR_SESSION_REGISTRY.schema.json +43 -0
- package/assets/agent-state/MODULES/schemas/WORKSPACE_SESSION_REGISTRY.schema.json +11 -0
- package/assets/agent-state/STATUS.md +2 -2
- package/assets/scripts/ace-hook-dispatch.mjs +70 -6
- package/assets/scripts/render-mcp-configs.sh +19 -5
- package/dist/ace-context.js +22 -1
- package/dist/ace-server-instructions.js +3 -3
- package/dist/ace-state-resolver.js +5 -3
- package/dist/astgrep-index.d.ts +9 -1
- package/dist/astgrep-index.js +14 -3
- package/dist/cli.js +27 -20
- package/dist/handoff-registry.js +5 -5
- package/dist/helpers/artifacts.d.ts +19 -0
- package/dist/helpers/artifacts.js +152 -0
- package/dist/helpers/bootstrap.d.ts +24 -0
- package/dist/helpers/bootstrap.js +894 -0
- package/dist/helpers/constants.d.ts +53 -0
- package/dist/helpers/constants.js +288 -0
- package/dist/helpers/drift.d.ts +13 -0
- package/dist/helpers/drift.js +45 -0
- package/dist/helpers/path-utils.d.ts +17 -0
- package/dist/helpers/path-utils.js +104 -0
- package/dist/helpers/store-resolution.d.ts +19 -0
- package/dist/helpers/store-resolution.js +301 -0
- package/dist/helpers/workspace-root.d.ts +3 -0
- package/dist/helpers/workspace-root.js +80 -0
- package/dist/helpers.d.ts +8 -125
- package/dist/helpers.js +8 -1768
- package/dist/job-scheduler.js +3 -3
- package/dist/local-model-runtime.js +12 -1
- package/dist/model-bridge.d.ts +7 -0
- package/dist/model-bridge.js +75 -5
- package/dist/orchestrator-supervisor.d.ts +14 -0
- package/dist/orchestrator-supervisor.js +72 -1
- package/dist/run-ledger.js +3 -3
- package/dist/runtime-command.d.ts +8 -0
- package/dist/runtime-command.js +38 -6
- package/dist/runtime-executor.d.ts +14 -0
- package/dist/runtime-executor.js +669 -171
- package/dist/runtime-profile.d.ts +32 -0
- package/dist/runtime-profile.js +89 -13
- package/dist/runtime-tool-specs.d.ts +21 -0
- package/dist/runtime-tool-specs.js +78 -3
- package/dist/safe-edit.d.ts +7 -0
- package/dist/safe-edit.js +163 -37
- package/dist/schemas.js +19 -0
- package/dist/shared.d.ts +2 -2
- package/dist/status-events.js +9 -6
- package/dist/store/ace-packed-store.d.ts +3 -2
- package/dist/store/ace-packed-store.js +188 -110
- package/dist/store/bootstrap-store.d.ts +1 -1
- package/dist/store/bootstrap-store.js +94 -81
- package/dist/store/cache-workspace.js +11 -5
- package/dist/store/materializers/context-snapshot-materializer.js +6 -2
- package/dist/store/materializers/hook-context-materializer.d.ts +6 -9
- package/dist/store/materializers/hook-context-materializer.js +11 -21
- package/dist/store/materializers/host-file-materializer.js +6 -0
- package/dist/store/materializers/projection-manager.d.ts +0 -1
- package/dist/store/materializers/projection-manager.js +5 -13
- package/dist/store/materializers/scheduler-projection-materializer.js +1 -1
- package/dist/store/materializers/vericify-projector.d.ts +7 -7
- package/dist/store/materializers/vericify-projector.js +11 -11
- package/dist/store/repositories/local-model-runtime-repository.d.ts +120 -3
- package/dist/store/repositories/local-model-runtime-repository.js +242 -6
- package/dist/store/skills-install.d.ts +4 -0
- package/dist/store/skills-install.js +21 -12
- package/dist/store/state-reader.d.ts +2 -0
- package/dist/store/state-reader.js +20 -0
- package/dist/store/store-artifacts.d.ts +7 -0
- package/dist/store/store-artifacts.js +27 -1
- package/dist/store/store-authority-audit.d.ts +18 -1
- package/dist/store/store-authority-audit.js +115 -5
- package/dist/store/store-snapshot.d.ts +3 -0
- package/dist/store/store-snapshot.js +22 -2
- package/dist/store/workspace-store-paths.d.ts +39 -0
- package/dist/store/workspace-store-paths.js +94 -0
- package/dist/store/write-coordinator.d.ts +65 -0
- package/dist/store/write-coordinator.js +386 -0
- package/dist/todo-state.js +5 -5
- package/dist/tools-agent.js +268 -14
- package/dist/tools-discovery.js +1 -1
- package/dist/tools-files.d.ts +7 -0
- package/dist/tools-files.js +299 -10
- package/dist/tools-framework.js +25 -5
- package/dist/tools-handoff.js +2 -2
- package/dist/tools-lifecycle.js +4 -4
- package/dist/tools-memory.js +6 -6
- package/dist/tools-todo.js +2 -2
- package/dist/tracker-adapters.d.ts +1 -1
- package/dist/tracker-adapters.js +13 -18
- package/dist/tracker-sync.js +5 -3
- package/dist/tui/agent-runner.js +3 -1
- package/dist/tui/chat.js +103 -7
- package/dist/tui/dashboard.d.ts +1 -0
- package/dist/tui/dashboard.js +43 -0
- package/dist/tui/layout.d.ts +20 -0
- package/dist/tui/layout.js +31 -1
- package/dist/tui/local-model-contract.d.ts +6 -2
- package/dist/tui/local-model-contract.js +16 -3
- package/dist/vericify-bridge.d.ts +5 -0
- package/dist/vericify-bridge.js +27 -3
- package/dist/workspace-manager.d.ts +30 -3
- package/dist/workspace-manager.js +257 -27
- package/package.json +1 -2
- package/dist/internal-tool-runtime.d.ts +0 -21
- package/dist/internal-tool-runtime.js +0 -136
- package/dist/store/workspace-snapshot.d.ts +0 -26
- package/dist/store/workspace-snapshot.js +0 -107
package/dist/astgrep-index.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
export interface AstgrepMatch {
|
|
2
|
+
file: string;
|
|
3
|
+
line: number;
|
|
4
|
+
column: number;
|
|
5
|
+
text: string;
|
|
6
|
+
context_lines?: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function runAstgrepQuery(pattern: string, lang: string, roots: string[], _contextLines?: number): AstgrepMatch[];
|
|
1
9
|
export interface RefreshAstgrepIndexInput {
|
|
2
10
|
scope?: string;
|
|
3
11
|
append_evidence?: boolean;
|
|
@@ -20,5 +28,5 @@ export interface RefreshAstgrepIndexResult {
|
|
|
20
28
|
todo_signals: number;
|
|
21
29
|
};
|
|
22
30
|
}
|
|
23
|
-
export declare function refreshAstgrepIndex(input?: RefreshAstgrepIndexInput): RefreshAstgrepIndexResult
|
|
31
|
+
export declare function refreshAstgrepIndex(input?: RefreshAstgrepIndexInput): Promise<RefreshAstgrepIndexResult>;
|
|
24
32
|
//# sourceMappingURL=astgrep-index.d.ts.map
|
package/dist/astgrep-index.js
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
2
2
|
import { isAbsolute, relative, resolve } from "node:path";
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
|
-
import {
|
|
4
|
+
import { appendStatusEventSafe } from "./status-events.js";
|
|
5
5
|
import { safeRead, safeWrite, WORKSPACE_ROOT, wsPath } from "./helpers.js";
|
|
6
|
+
export function runAstgrepQuery(pattern, lang, roots, _contextLines) {
|
|
7
|
+
const cmd = detectAstgrepCommand();
|
|
8
|
+
const raw = runAstgrep(cmd, pattern, lang, roots);
|
|
9
|
+
return raw.slice(0, 200).map((m) => ({
|
|
10
|
+
file: m.file ?? "",
|
|
11
|
+
line: m.range?.start?.line ?? 0,
|
|
12
|
+
column: m.range?.start?.column ?? 0,
|
|
13
|
+
text: m.text ?? "",
|
|
14
|
+
context_lines: [],
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
6
17
|
const CODE_EXTENSIONS = new Set(["ts", "tsx", "js", "mjs", "cjs", "py", "rs", "go"]);
|
|
7
18
|
const EXCLUDE_DIRS = new Set([
|
|
8
19
|
".git",
|
|
@@ -180,7 +191,7 @@ function appendEvidenceLine(timestamp, astgrepCmd, stats) {
|
|
|
180
191
|
].join("\n");
|
|
181
192
|
safeWrite("agent-state/EVIDENCE_LOG.md", `${seed}${entry}\n`);
|
|
182
193
|
}
|
|
183
|
-
export function refreshAstgrepIndex(input = {}) {
|
|
194
|
+
export async function refreshAstgrepIndex(input = {}) {
|
|
184
195
|
const generatedAt = new Date().toISOString();
|
|
185
196
|
const scope = resolveScope(input.scope);
|
|
186
197
|
const appendEvidence = input.append_evidence ?? true;
|
|
@@ -440,7 +451,7 @@ export function refreshAstgrepIndex(input = {}) {
|
|
|
440
451
|
if (emitEvent) {
|
|
441
452
|
const status = astgrepCmd ? "pass" : "blocked";
|
|
442
453
|
const eventType = astgrepCmd ? "DISCOVERY_INDEX_READY" : "DISCOVERY_SCOPE_BLOCKED";
|
|
443
|
-
const event =
|
|
454
|
+
const event = await appendStatusEventSafe({
|
|
444
455
|
source_module: "capability-astgrep",
|
|
445
456
|
event_type: eventType,
|
|
446
457
|
status,
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { ACE_TASKS_ROOT_REL, ALL_MCP_CLIENTS, ALL_LLM_PROVIDERS, DEFAULTS_ROOT, PACKAGE_ROOT, WORKSPACE_ROOT, fileExists, getAllMcpServerConfigSnippets, getMcpClientInstallHint, getMcpServerConfigSnippet, wsPath, } from "./helpers.js";
|
|
3
3
|
import { refreshAstgrepIndex } from "./astgrep-index.js";
|
|
4
4
|
import { scanWorkspaceDelta } from "./index-store.js";
|
|
5
5
|
import { startStdioServer } from "./server.js";
|
|
@@ -8,9 +8,10 @@ import { waitForPendingStatusEventMirrors } from "./status-events.js";
|
|
|
8
8
|
import { bootstrapStoreWorkspace } from "./store/bootstrap-store.js";
|
|
9
9
|
import { HostFileMaterializer } from "./store/materializers/host-file-materializer.js";
|
|
10
10
|
import { openStore } from "./store/ace-packed-store.js";
|
|
11
|
-
import { withStoreWriteQueue } from "./store/write-queue.js";
|
|
12
11
|
import { DiscoveryRepository } from "./store/repositories/discovery-repository.js";
|
|
12
|
+
import { withStoreWriteCoordinator } from "./store/write-coordinator.js";
|
|
13
13
|
import { getWorkspaceStorePath, readStoreBlobSync, readStoreJsonSync, } from "./store/store-snapshot.js";
|
|
14
|
+
import { ensureCanonicalWorkspaceStore } from "./store/workspace-store-paths.js";
|
|
14
15
|
import { readFileSync } from "node:fs";
|
|
15
16
|
import { runTui } from "./tui/index.js";
|
|
16
17
|
import { buildOpenAiCompatibleBaseUrl, buildProviderDoctorCommands, defaultModelForProvider, discoverProviderContext, isLocalLlmProvider, normalizeLocalBaseUrl, normalizeProvider, scanLocalModelRuntimes, } from "./tui/provider-discovery.js";
|
|
@@ -38,7 +39,7 @@ Options for tui:
|
|
|
38
39
|
--ollama-url <url> Legacy alias for --base-url
|
|
39
40
|
|
|
40
41
|
Options for init:
|
|
41
|
-
--project <name> Project name stored in
|
|
42
|
+
--project <name> Project name stored in agent-state/ace-state.ace metadata
|
|
42
43
|
--force Overwrite scaffolded files if they already exist
|
|
43
44
|
--mcp-config Also write .vscode/mcp.json workspace bridge
|
|
44
45
|
--client-config-bundle Also write minimal workspace host stubs (AGENTS.md, CLAUDE.md, .cursorrules, .github/copilot-instructions.md)
|
|
@@ -48,7 +49,7 @@ Options for init:
|
|
|
48
49
|
--ollama-url <url> Legacy alias for --base-url
|
|
49
50
|
|
|
50
51
|
Options for doctor:
|
|
51
|
-
--llm <provider> ollama|llama.cpp|codex|claude|gemini|copilot|... (default: auto from
|
|
52
|
+
--llm <provider> ollama|llama.cpp|codex|claude|gemini|copilot|... (default: auto from agent-state/ace-state.ace)
|
|
52
53
|
--model <name> Model name override
|
|
53
54
|
--base-url <url> Runtime base URL override
|
|
54
55
|
--ollama-url <url> Legacy alias for --base-url
|
|
@@ -59,11 +60,12 @@ Options for cache:
|
|
|
59
60
|
--no-clean Keep workspace ACE artifacts after caching them into ace-state.ace
|
|
60
61
|
|
|
61
62
|
Options for mcp-config:
|
|
62
|
-
--client <name> codex|vscode|claude|cursor|antigravity
|
|
63
|
+
--client <name> codex|vscode|copilot|claude|cursor|antigravity
|
|
63
64
|
--all Print all client snippets for optional global install
|
|
64
65
|
|
|
65
66
|
preconfig writes .mcp-config/ at the workspace root with ready-to-use config files for every
|
|
66
|
-
supported MCP client
|
|
67
|
+
supported MCP client plus a root .mcp.json for GitHub Copilot CLI. Run once after ace init.
|
|
68
|
+
Each file includes the install hint for its client.
|
|
67
69
|
`);
|
|
68
70
|
}
|
|
69
71
|
function readFlagValue(args, flag) {
|
|
@@ -116,7 +118,7 @@ function parseLlmOptions(args) {
|
|
|
116
118
|
}
|
|
117
119
|
async function writeLlmProfile(profile) {
|
|
118
120
|
const storePath = getWorkspaceStorePath(WORKSPACE_ROOT);
|
|
119
|
-
await
|
|
121
|
+
await withStoreWriteCoordinator(storePath, async () => {
|
|
120
122
|
const payload = {
|
|
121
123
|
provider: profile.provider,
|
|
122
124
|
model: profile.model,
|
|
@@ -148,12 +150,12 @@ async function writeLlmProfile(profile) {
|
|
|
148
150
|
finally {
|
|
149
151
|
await store.close();
|
|
150
152
|
}
|
|
151
|
-
});
|
|
153
|
+
}, { operation_label: "writeLlmProfile" });
|
|
152
154
|
return `${storePath}#state/runtime/llm_profile`;
|
|
153
155
|
}
|
|
154
156
|
async function recordDiscoveryProfile(input) {
|
|
155
157
|
const storePath = getWorkspaceStorePath(WORKSPACE_ROOT);
|
|
156
|
-
await
|
|
158
|
+
await withStoreWriteCoordinator(storePath, async () => {
|
|
157
159
|
const store = await openStore(storePath);
|
|
158
160
|
try {
|
|
159
161
|
const discovery = new DiscoveryRepository(store);
|
|
@@ -176,7 +178,7 @@ async function recordDiscoveryProfile(input) {
|
|
|
176
178
|
finally {
|
|
177
179
|
await store.close();
|
|
178
180
|
}
|
|
179
|
-
});
|
|
181
|
+
}, { operation_label: "recordDiscoveryProfile" });
|
|
180
182
|
}
|
|
181
183
|
async function runInit(args, mode = "init") {
|
|
182
184
|
const projectName = readFlagValue(args, "--project");
|
|
@@ -197,7 +199,7 @@ async function runInit(args, mode = "init") {
|
|
|
197
199
|
model: llm.llmModel ?? undefined,
|
|
198
200
|
baseUrl: llm.llmBaseUrl ?? undefined,
|
|
199
201
|
});
|
|
200
|
-
const astIndex = refreshAstgrepIndex({
|
|
202
|
+
const astIndex = await refreshAstgrepIndex({
|
|
201
203
|
scope: ".",
|
|
202
204
|
append_evidence: true,
|
|
203
205
|
emit_event: true,
|
|
@@ -253,7 +255,7 @@ async function runInit(args, mode = "init") {
|
|
|
253
255
|
message: `ace ${mode} completed: ${storeResult.materialized.length} bootstrap files materialized`,
|
|
254
256
|
artifacts: [
|
|
255
257
|
`${ACE_TASKS_ROOT_REL}/`,
|
|
256
|
-
|
|
258
|
+
storeResult.storePath,
|
|
257
259
|
delta.index_path,
|
|
258
260
|
astIndex.output_json_path,
|
|
259
261
|
],
|
|
@@ -340,7 +342,7 @@ async function runDoctor(args) {
|
|
|
340
342
|
ok: hasProfile,
|
|
341
343
|
detail: hasProfile
|
|
342
344
|
? profilePath
|
|
343
|
-
: `Missing
|
|
345
|
+
: `Missing agent-state/ace-state.ace#state/runtime/llm_profile. Run \`ace init --llm <provider>\` or \`ace doctor --scan\` for a local runtime.`,
|
|
344
346
|
});
|
|
345
347
|
let provider = llm.llmProvider;
|
|
346
348
|
let model = llm.llmModel;
|
|
@@ -383,7 +385,7 @@ async function runDoctor(args) {
|
|
|
383
385
|
}
|
|
384
386
|
}
|
|
385
387
|
if (!provider) {
|
|
386
|
-
throw new Error(`No runtime provider configured. Use --llm <provider>, bootstrap one into
|
|
388
|
+
throw new Error(`No runtime provider configured. Use --llm <provider>, bootstrap one into agent-state/ace-state.ace#state/runtime/llm_profile, or run \`ace doctor --scan\` for a local runtime.`);
|
|
387
389
|
}
|
|
388
390
|
if (!model) {
|
|
389
391
|
model = defaultModelForProvider(provider);
|
|
@@ -520,16 +522,21 @@ function parseClientFlag(args) {
|
|
|
520
522
|
return match;
|
|
521
523
|
}
|
|
522
524
|
async function runPreconfig() {
|
|
523
|
-
const
|
|
524
|
-
|
|
525
|
-
|
|
525
|
+
const resolved = await ensureCanonicalWorkspaceStore(WORKSPACE_ROOT, {
|
|
526
|
+
operationLabel: "runPreconfig",
|
|
527
|
+
});
|
|
528
|
+
if (resolved.mode === "missing") {
|
|
529
|
+
console.error(`No ACE store found. Expected canonical ${resolved.canonicalPath}; legacy fallback ${resolved.legacyPath} was also not found. Run 'ace init' first.`);
|
|
526
530
|
process.exit(1);
|
|
527
531
|
}
|
|
528
|
-
const
|
|
532
|
+
for (const w of resolved.warnings) {
|
|
533
|
+
console.warn(`[preconfig] ${w}`);
|
|
534
|
+
}
|
|
535
|
+
const store = await openStore(resolved.storePath);
|
|
529
536
|
try {
|
|
530
537
|
const mat = new HostFileMaterializer(store, WORKSPACE_ROOT);
|
|
531
538
|
const written = await mat.materializeMcpBundle();
|
|
532
|
-
console.log(`ACE preconfig complete — wrote ${written.length} files to .mcp-config
|
|
539
|
+
console.log(`ACE preconfig complete — wrote ${written.length} files to .mcp-config/ and root .mcp.json\n`);
|
|
533
540
|
for (const p of written) {
|
|
534
541
|
console.log(` ${p}`);
|
|
535
542
|
}
|
|
@@ -649,7 +656,7 @@ async function main() {
|
|
|
649
656
|
}
|
|
650
657
|
if (command === "migrate") {
|
|
651
658
|
const { importFromFileWorkspace } = await import("./store/importer.js");
|
|
652
|
-
const storePath = args[1] ??
|
|
659
|
+
const storePath = args[1] ?? getWorkspaceStorePath(WORKSPACE_ROOT);
|
|
653
660
|
console.log(`Migrating file workspace at ${WORKSPACE_ROOT} to store at ${storePath}...`);
|
|
654
661
|
const result = await importFromFileWorkspace(WORKSPACE_ROOT, storePath);
|
|
655
662
|
console.log(`Migration complete:`);
|
package/dist/handoff-registry.js
CHANGED
|
@@ -4,7 +4,7 @@ import { openStore } from "./store/ace-packed-store.js";
|
|
|
4
4
|
import { ProjectionManager } from "./store/materializers/projection-manager.js";
|
|
5
5
|
import { HandoffRepository } from "./store/repositories/handoff-repository.js";
|
|
6
6
|
import { getWorkspaceStorePath, listStoreKeysSync, readStoreJsonSync, storeExistsSync, } from "./store/store-snapshot.js";
|
|
7
|
-
import {
|
|
7
|
+
import { withStoreWriteCoordinator } from "./store/write-coordinator.js";
|
|
8
8
|
import { waitForPendingStatusEventMirrors } from "./status-events.js";
|
|
9
9
|
import { waitForTodoStoreMirror } from "./todo-state.js";
|
|
10
10
|
const HANDOFF_REGISTRY_REL = "agent-state/handoff-registry.json";
|
|
@@ -299,7 +299,7 @@ export async function registerHandoffSafe(input) {
|
|
|
299
299
|
return withFileLock(HANDOFF_REGISTRY_REL, () => registerHandoff(input));
|
|
300
300
|
}
|
|
301
301
|
return withFileLock(HANDOFF_REGISTRY_REL, async () => {
|
|
302
|
-
return
|
|
302
|
+
return withStoreWriteCoordinator(storePath, async () => {
|
|
303
303
|
const store = await openStore(storePath);
|
|
304
304
|
try {
|
|
305
305
|
const repo = new HandoffRepository(store);
|
|
@@ -346,7 +346,7 @@ export async function registerHandoffSafe(input) {
|
|
|
346
346
|
finally {
|
|
347
347
|
await store.close();
|
|
348
348
|
}
|
|
349
|
-
});
|
|
349
|
+
}, { operation_label: "registerHandoffSafe" });
|
|
350
350
|
});
|
|
351
351
|
}
|
|
352
352
|
/**
|
|
@@ -361,7 +361,7 @@ export async function acknowledgeHandoffSafe(input) {
|
|
|
361
361
|
return withFileLock(HANDOFF_REGISTRY_REL, () => acknowledgeHandoff(input));
|
|
362
362
|
}
|
|
363
363
|
return withFileLock(HANDOFF_REGISTRY_REL, async () => {
|
|
364
|
-
return
|
|
364
|
+
return withStoreWriteCoordinator(storePath, async () => {
|
|
365
365
|
const store = await openStore(storePath);
|
|
366
366
|
try {
|
|
367
367
|
const repo = new HandoffRepository(store);
|
|
@@ -420,7 +420,7 @@ export async function acknowledgeHandoffSafe(input) {
|
|
|
420
420
|
finally {
|
|
421
421
|
await store.close();
|
|
422
422
|
}
|
|
423
|
-
});
|
|
423
|
+
}, { operation_label: "acknowledgeHandoffSafe" });
|
|
424
424
|
});
|
|
425
425
|
}
|
|
426
426
|
//# sourceMappingURL=handoff-registry.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type AgentRole, type KernelKey, type TaskKey } from "./constants.js";
|
|
2
|
+
export interface SkillReference {
|
|
3
|
+
name: string;
|
|
4
|
+
path: string;
|
|
5
|
+
source: "workspace" | "package-defaults" | "store";
|
|
6
|
+
}
|
|
7
|
+
export declare function getAgentInstructionPath(role: AgentRole): string | undefined;
|
|
8
|
+
export declare function getAgentManifestPath(role: AgentRole): string | undefined;
|
|
9
|
+
export declare function readAgentInstructions(role: AgentRole): string;
|
|
10
|
+
export declare function readAgentManifest(role: AgentRole): string;
|
|
11
|
+
export declare function getTaskArtifactPath(key: TaskKey): string | undefined;
|
|
12
|
+
export declare function readTaskArtifact(key: TaskKey): string;
|
|
13
|
+
export declare function getKernelArtifactPath(key: KernelKey): string | undefined;
|
|
14
|
+
export declare function readKernelArtifact(key: KernelKey): string;
|
|
15
|
+
export declare function resolveWritableTaskPath(key: TaskKey): string;
|
|
16
|
+
export declare function listAvailableSkills(): SkillReference[];
|
|
17
|
+
export declare function getSkillPath(name: string): string | undefined;
|
|
18
|
+
export declare function readSkillInstructions(name: string): string;
|
|
19
|
+
//# sourceMappingURL=artifacts.d.ts.map
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { AGENT_FILES, AGENT_MANIFEST_FILES, DEFAULT_AGENT_INSTRUCTION_FILES, DEFAULT_AGENT_MANIFEST_FILES, DEFAULT_KERNEL_FILES, DEFAULTS_SKILLS_ROOT, DEFAULT_TASK_FILES, KERNEL_FILES, STORE_AGENT_FILES, STORE_KERNEL_FILES, STORE_TASK_FILES, TASK_FILES, } from "./constants.js";
|
|
4
|
+
import { acePath, currentWorkspaceRoot, firstExistingPath, readText, resolveWorkspaceWritePath, toAbsoluteWorkspaceCandidates, } from "./path-utils.js";
|
|
5
|
+
import { listStoreSkillReferences, readStoreText } from "./store-resolution.js";
|
|
6
|
+
function shouldPreferWorkspaceTaskFile(key) {
|
|
7
|
+
return key === "todo" || key === "lessons";
|
|
8
|
+
}
|
|
9
|
+
function readFirstAvailable(paths) {
|
|
10
|
+
const found = firstExistingPath(paths);
|
|
11
|
+
if (!found) {
|
|
12
|
+
return {
|
|
13
|
+
text: `[FILE NOT FOUND]\nTried:\n${paths.map((p) => `- ${p}`).join("\n")}`,
|
|
14
|
+
path: undefined,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
return { text: readText(found), path: found };
|
|
18
|
+
}
|
|
19
|
+
export function getAgentInstructionPath(role) {
|
|
20
|
+
const store = readStoreText(STORE_AGENT_FILES[role].instructions.map((file) => `knowledge/agents/${STORE_AGENT_FILES[role].agent}/${file}`));
|
|
21
|
+
if (store)
|
|
22
|
+
return store.path;
|
|
23
|
+
const workspaceCandidates = toAbsoluteWorkspaceCandidates(AGENT_FILES[role]);
|
|
24
|
+
return firstExistingPath([...workspaceCandidates, DEFAULT_AGENT_INSTRUCTION_FILES[role]]);
|
|
25
|
+
}
|
|
26
|
+
export function getAgentManifestPath(role) {
|
|
27
|
+
const store = readStoreText(STORE_AGENT_FILES[role].manifests.map((file) => `knowledge/agents/${STORE_AGENT_FILES[role].agent}/${file}`));
|
|
28
|
+
if (store)
|
|
29
|
+
return store.path;
|
|
30
|
+
const workspaceCandidates = toAbsoluteWorkspaceCandidates(AGENT_MANIFEST_FILES[role]);
|
|
31
|
+
return firstExistingPath([...workspaceCandidates, DEFAULT_AGENT_MANIFEST_FILES[role]]);
|
|
32
|
+
}
|
|
33
|
+
export function readAgentInstructions(role) {
|
|
34
|
+
const store = readStoreText(STORE_AGENT_FILES[role].instructions.map((file) => `knowledge/agents/${STORE_AGENT_FILES[role].agent}/${file}`));
|
|
35
|
+
if (store)
|
|
36
|
+
return store.text;
|
|
37
|
+
const workspaceCandidates = toAbsoluteWorkspaceCandidates(AGENT_FILES[role]);
|
|
38
|
+
return readFirstAvailable([...workspaceCandidates, DEFAULT_AGENT_INSTRUCTION_FILES[role]]).text;
|
|
39
|
+
}
|
|
40
|
+
export function readAgentManifest(role) {
|
|
41
|
+
const store = readStoreText(STORE_AGENT_FILES[role].manifests.map((file) => `knowledge/agents/${STORE_AGENT_FILES[role].agent}/${file}`));
|
|
42
|
+
if (store)
|
|
43
|
+
return store.text;
|
|
44
|
+
const workspaceCandidates = toAbsoluteWorkspaceCandidates(AGENT_MANIFEST_FILES[role]);
|
|
45
|
+
return readFirstAvailable([...workspaceCandidates, DEFAULT_AGENT_MANIFEST_FILES[role]]).text;
|
|
46
|
+
}
|
|
47
|
+
export function getTaskArtifactPath(key) {
|
|
48
|
+
const workspaceCandidates = toAbsoluteWorkspaceCandidates(TASK_FILES[key]);
|
|
49
|
+
const workspaceFirst = shouldPreferWorkspaceTaskFile(key);
|
|
50
|
+
if (workspaceFirst) {
|
|
51
|
+
const workspace = firstExistingPath(workspaceCandidates);
|
|
52
|
+
if (workspace)
|
|
53
|
+
return workspace;
|
|
54
|
+
}
|
|
55
|
+
const store = readStoreText([STORE_TASK_FILES[key]]);
|
|
56
|
+
if (store)
|
|
57
|
+
return store.path;
|
|
58
|
+
return firstExistingPath([
|
|
59
|
+
...workspaceCandidates,
|
|
60
|
+
DEFAULT_TASK_FILES[key],
|
|
61
|
+
]);
|
|
62
|
+
}
|
|
63
|
+
export function readTaskArtifact(key) {
|
|
64
|
+
if (shouldPreferWorkspaceTaskFile(key)) {
|
|
65
|
+
const workspaceCandidates = toAbsoluteWorkspaceCandidates(TASK_FILES[key]);
|
|
66
|
+
const workspacePath = firstExistingPath(workspaceCandidates);
|
|
67
|
+
if (workspacePath)
|
|
68
|
+
return readText(workspacePath);
|
|
69
|
+
}
|
|
70
|
+
const store = readStoreText([STORE_TASK_FILES[key]]);
|
|
71
|
+
if (store)
|
|
72
|
+
return store.text;
|
|
73
|
+
const workspaceCandidates = toAbsoluteWorkspaceCandidates(TASK_FILES[key]);
|
|
74
|
+
return readFirstAvailable([...workspaceCandidates, DEFAULT_TASK_FILES[key]]).text;
|
|
75
|
+
}
|
|
76
|
+
export function getKernelArtifactPath(key) {
|
|
77
|
+
const store = readStoreText(STORE_KERNEL_FILES[key]);
|
|
78
|
+
if (store)
|
|
79
|
+
return store.path;
|
|
80
|
+
const workspaceCandidates = toAbsoluteWorkspaceCandidates(KERNEL_FILES[key]);
|
|
81
|
+
return firstExistingPath([...workspaceCandidates, DEFAULT_KERNEL_FILES[key]]);
|
|
82
|
+
}
|
|
83
|
+
export function readKernelArtifact(key) {
|
|
84
|
+
const store = readStoreText(STORE_KERNEL_FILES[key]);
|
|
85
|
+
if (store)
|
|
86
|
+
return store.text;
|
|
87
|
+
const workspaceCandidates = toAbsoluteWorkspaceCandidates(KERNEL_FILES[key]);
|
|
88
|
+
return readFirstAvailable([...workspaceCandidates, DEFAULT_KERNEL_FILES[key]]).text;
|
|
89
|
+
}
|
|
90
|
+
export function resolveWritableTaskPath(key) {
|
|
91
|
+
const workspaceCandidates = toAbsoluteWorkspaceCandidates(TASK_FILES[key]);
|
|
92
|
+
const existingWorkspacePath = workspaceCandidates.find((candidate) => existsSync(candidate));
|
|
93
|
+
if (existingWorkspacePath)
|
|
94
|
+
return existingWorkspacePath;
|
|
95
|
+
return resolveWorkspaceWritePath(TASK_FILES[key][0]);
|
|
96
|
+
}
|
|
97
|
+
function listSkillDirs() {
|
|
98
|
+
const root = currentWorkspaceRoot();
|
|
99
|
+
return [
|
|
100
|
+
{ root: acePath("skills"), source: "workspace" },
|
|
101
|
+
{ root: resolve(root, ".agents", "skills"), source: "workspace" },
|
|
102
|
+
{ root: DEFAULTS_SKILLS_ROOT, source: "package-defaults" },
|
|
103
|
+
];
|
|
104
|
+
}
|
|
105
|
+
export function listAvailableSkills() {
|
|
106
|
+
const dedup = new Map();
|
|
107
|
+
for (const skill of listStoreSkillReferences()) {
|
|
108
|
+
dedup.set(skill.name, skill);
|
|
109
|
+
}
|
|
110
|
+
for (const { root, source } of listSkillDirs()) {
|
|
111
|
+
if (!existsSync(root))
|
|
112
|
+
continue;
|
|
113
|
+
const entries = readdirSync(root, { withFileTypes: true });
|
|
114
|
+
for (const entry of entries) {
|
|
115
|
+
if (!entry.isDirectory())
|
|
116
|
+
continue;
|
|
117
|
+
const skillName = entry.name;
|
|
118
|
+
const skillPath = resolve(root, skillName, "SKILL.md");
|
|
119
|
+
if (!existsSync(skillPath))
|
|
120
|
+
continue;
|
|
121
|
+
if (source === "package-defaults" && dedup.has(skillName)) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
dedup.set(skillName, {
|
|
125
|
+
name: skillName,
|
|
126
|
+
path: skillPath,
|
|
127
|
+
source,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return [...dedup.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
132
|
+
}
|
|
133
|
+
export function getSkillPath(name) {
|
|
134
|
+
const target = name.trim().toLowerCase();
|
|
135
|
+
const skills = listAvailableSkills();
|
|
136
|
+
const exact = skills.find((skill) => skill.name.toLowerCase() === target);
|
|
137
|
+
return exact?.path;
|
|
138
|
+
}
|
|
139
|
+
export function readSkillInstructions(name) {
|
|
140
|
+
const target = name.trim().toLowerCase();
|
|
141
|
+
const match = listAvailableSkills().find((skill) => skill.name.toLowerCase() === target);
|
|
142
|
+
if (!match) {
|
|
143
|
+
return `Skill not found: ${name}\nAvailable: ${listAvailableSkills()
|
|
144
|
+
.map((s) => s.name)
|
|
145
|
+
.join(", ")}`;
|
|
146
|
+
}
|
|
147
|
+
if (match.source === "store") {
|
|
148
|
+
return readStoreText([`knowledge/skills/${match.name}/SKILL.md`])?.text ?? "";
|
|
149
|
+
}
|
|
150
|
+
return readText(match.path);
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type LlmProvider, type McpClient } from "./constants.js";
|
|
2
|
+
export interface BootstrapOptions {
|
|
3
|
+
projectName?: string;
|
|
4
|
+
force?: boolean;
|
|
5
|
+
includeMcpConfig?: boolean;
|
|
6
|
+
includeClientConfigBundle?: boolean;
|
|
7
|
+
llmProvider?: LlmProvider;
|
|
8
|
+
llmModel?: string;
|
|
9
|
+
llmBaseUrl?: string;
|
|
10
|
+
ollamaModel?: string;
|
|
11
|
+
ollamaBaseUrl?: string;
|
|
12
|
+
skipStoreManaged?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface BootstrapResult {
|
|
15
|
+
created: string[];
|
|
16
|
+
updated: string[];
|
|
17
|
+
skipped: string[];
|
|
18
|
+
}
|
|
19
|
+
export declare function getMcpClientBundlePath(client: McpClient): string;
|
|
20
|
+
export declare function getMcpClientInstallHint(client: McpClient): string;
|
|
21
|
+
export declare function getMcpServerConfigSnippet(client?: McpClient): string;
|
|
22
|
+
export declare function getAllMcpServerConfigSnippets(): Record<McpClient, string>;
|
|
23
|
+
export declare function bootstrapAceWorkspace(options?: BootstrapOptions): BootstrapResult;
|
|
24
|
+
//# sourceMappingURL=bootstrap.d.ts.map
|