@voybio/ace-swarm 0.2.5 → 2.4.1
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 +19 -1
- package/README.md +21 -13
- package/assets/.agents/ACE/agent-qa/instructions.md +11 -0
- 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/RUNTIME_TOOL_SPEC_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/agent-state/runtime-tool-specs.json +70 -2
- package/assets/instructions/ACE_Coder.instructions.md +13 -0
- package/assets/instructions/ACE_UI.instructions.md +11 -0
- package/assets/scripts/ace-hook-dispatch.mjs +70 -6
- package/assets/scripts/render-mcp-configs.sh +19 -5
- package/dist/ace-context.js +91 -11
- package/dist/ace-internal-tools.d.ts +3 -1
- package/dist/ace-internal-tools.js +10 -2
- package/dist/ace-server-instructions.js +3 -3
- package/dist/ace-state-resolver.js +5 -3
- package/dist/agent-runtime/role-adapters.d.ts +18 -1
- package/dist/agent-runtime/role-adapters.js +49 -5
- package/dist/astgrep-index.d.ts +57 -1
- package/dist/astgrep-index.js +140 -4
- package/dist/cli.js +232 -35
- package/dist/discovery-runtime-wrappers.d.ts +108 -0
- package/dist/discovery-runtime-wrappers.js +615 -0
- 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 +295 -0
- package/dist/helpers/drift.d.ts +13 -0
- package/dist/helpers/drift.js +45 -0
- package/dist/helpers/path-utils.d.ts +24 -0
- package/dist/helpers/path-utils.js +123 -0
- package/dist/helpers/store-resolution.d.ts +19 -0
- package/dist/helpers/store-resolution.js +305 -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 +33 -7
- package/dist/json-sanitizer.d.ts +16 -0
- package/dist/json-sanitizer.js +26 -0
- package/dist/local-model-policy.d.ts +27 -0
- package/dist/local-model-policy.js +84 -0
- package/dist/local-model-runtime.d.ts +6 -0
- package/dist/local-model-runtime.js +33 -21
- package/dist/model-bridge.d.ts +13 -1
- package/dist/model-bridge.js +410 -23
- package/dist/orchestrator-supervisor.d.ts +56 -0
- package/dist/orchestrator-supervisor.js +179 -1
- package/dist/plan-proposal.d.ts +115 -0
- package/dist/plan-proposal.js +1073 -0
- 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 +20 -1
- package/dist/runtime-executor.js +737 -172
- package/dist/runtime-profile.d.ts +32 -0
- package/dist/runtime-profile.js +89 -13
- package/dist/runtime-tool-specs.d.ts +39 -0
- package/dist/runtime-tool-specs.js +144 -28
- package/dist/safe-edit.d.ts +7 -0
- package/dist/safe-edit.js +163 -37
- package/dist/schemas.js +48 -1
- package/dist/server.js +51 -0
- package/dist/shared.d.ts +3 -2
- package/dist/shared.js +2 -0
- 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 +2 -1
- package/dist/store/bootstrap-store.js +102 -83
- 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/repositories/vericify-repository.d.ts +1 -1
- 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.d.ts +20 -0
- package/dist/tools-agent.js +789 -25
- package/dist/tools-discovery.js +136 -1
- package/dist/tools-files.d.ts +7 -0
- package/dist/tools-files.js +1002 -11
- package/dist/tools-framework.js +105 -66
- 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/index.js +10 -1
- 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/tui/ollama.d.ts +8 -1
- package/dist/tui/ollama.js +53 -12
- package/dist/tui/openai-compatible.d.ts +13 -0
- package/dist/tui/openai-compatible.js +305 -5
- package/dist/tui/provider-discovery.d.ts +1 -0
- package/dist/tui/provider-discovery.js +35 -11
- package/dist/vericify-bridge.d.ts +6 -1
- 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
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, } from "node:fs";
|
|
2
|
+
import { mkdir, rename, writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, isAbsolute } from "node:path";
|
|
4
|
+
import { isInside, normalizeRelPath } from "../shared.js";
|
|
5
|
+
import { getWorkspaceStorePath, listStoreKeysSync, parseVirtualStorePath, readStoreBlobSync, readVirtualStorePathSync, toVirtualStorePath, } from "../store/store-snapshot.js";
|
|
6
|
+
import { isOperationalArtifactPath, operationalArtifactKey, writeOperationalArtifactQueued, writeStoreBlobQueued, writeStoreBlobSync, } from "../store/store-artifacts.js";
|
|
7
|
+
import { withStoreWriteCoordinatorSync } from "../store/write-coordinator.js";
|
|
8
|
+
import { ACE_ROOT_REL, ACE_SCRIPTS_ROOT_REL, ACE_SKILLS_ROOT_REL, ACE_TASKS_ROOT_REL, AGENT_FILES, AGENT_MANIFEST_FILES, DEFAULTS_ROOT, KERNEL_FILES, STORE_AGENT_FILES, STORE_KERNEL_FILES, STORE_TASK_FILES, TASK_FILES, } from "./constants.js";
|
|
9
|
+
import { currentWorkspaceRoot, isProjectedAceWorkspacePath, mapAceWorkspaceRelativePath, resolveWorkspaceReadPath, resolveWorkspaceWritePath, } from "./path-utils.js";
|
|
10
|
+
const STORE_ONLY_AGENT_STATE_FILES = new Set([
|
|
11
|
+
"agent-state/AST_GREP_INDEX.json",
|
|
12
|
+
"agent-state/AST_GREP_INDEX.md",
|
|
13
|
+
"agent-state/EVIDENCE_LOG.md",
|
|
14
|
+
"agent-state/STATUS_EVENTS.ndjson",
|
|
15
|
+
"agent-state/STATUS_EVENTS-archive.ndjson",
|
|
16
|
+
"agent-state/index-fingerprints.json",
|
|
17
|
+
"agent-state/index.json",
|
|
18
|
+
"agent-state/job-locks.json",
|
|
19
|
+
"agent-state/job-queue.json",
|
|
20
|
+
"agent-state/scheduler-lease.json",
|
|
21
|
+
]);
|
|
22
|
+
export function formatStorePath(key) {
|
|
23
|
+
return toVirtualStorePath(getWorkspaceStorePath(currentWorkspaceRoot()), key);
|
|
24
|
+
}
|
|
25
|
+
export function readStoreText(keys) {
|
|
26
|
+
const root = currentWorkspaceRoot();
|
|
27
|
+
for (const key of keys) {
|
|
28
|
+
const text = readStoreBlobSync(root, key);
|
|
29
|
+
if (typeof text === "string") {
|
|
30
|
+
return { key, path: formatStorePath(key), text };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
export function listStoreSkillReferences() {
|
|
36
|
+
const root = currentWorkspaceRoot();
|
|
37
|
+
const names = new Set();
|
|
38
|
+
for (const key of listStoreKeysSync(root, "knowledge/skills/")) {
|
|
39
|
+
const parts = key.split("/");
|
|
40
|
+
if (parts[2])
|
|
41
|
+
names.add(parts[2]);
|
|
42
|
+
}
|
|
43
|
+
return [...names]
|
|
44
|
+
.sort((a, b) => a.localeCompare(b))
|
|
45
|
+
.map((name) => ({
|
|
46
|
+
name,
|
|
47
|
+
path: formatStorePath(`knowledge/skills/${name}/SKILL.md`),
|
|
48
|
+
source: "store",
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
function resolveStoreFallbackKeys(filePath) {
|
|
52
|
+
const normalized = normalizeRelPath(filePath);
|
|
53
|
+
if (!normalized)
|
|
54
|
+
return [];
|
|
55
|
+
const canonical = mapAceWorkspaceRelativePath(normalized);
|
|
56
|
+
const keys = new Set();
|
|
57
|
+
const logicalAgentStatePath = normalized.startsWith("agent-state/")
|
|
58
|
+
? normalized
|
|
59
|
+
: canonical.startsWith(`${ACE_ROOT_REL}/agent-state/`)
|
|
60
|
+
? canonical.slice(`${ACE_ROOT_REL}/`.length)
|
|
61
|
+
: undefined;
|
|
62
|
+
if (logicalAgentStatePath && isOperationalArtifactPath(logicalAgentStatePath)) {
|
|
63
|
+
keys.add(operationalArtifactKey(logicalAgentStatePath));
|
|
64
|
+
}
|
|
65
|
+
if (normalized === "agent-state/ACE_WORKFLOW.md" || canonical === `${ACE_ROOT_REL}/agent-state/ACE_WORKFLOW.md`) {
|
|
66
|
+
keys.add("knowledge/runtime/ACE_WORKFLOW.md");
|
|
67
|
+
}
|
|
68
|
+
const gatePrefix = "agent-state/MODULES/gates/";
|
|
69
|
+
if (logicalAgentStatePath?.startsWith(gatePrefix)) {
|
|
70
|
+
const file = logicalAgentStatePath.slice(gatePrefix.length);
|
|
71
|
+
if (file)
|
|
72
|
+
keys.add(`knowledge/gates/${file}`);
|
|
73
|
+
}
|
|
74
|
+
const rolePrefix = "agent-state/MODULES/roles/";
|
|
75
|
+
if (logicalAgentStatePath?.startsWith(rolePrefix)) {
|
|
76
|
+
const file = logicalAgentStatePath.slice(rolePrefix.length);
|
|
77
|
+
if (file)
|
|
78
|
+
keys.add(`knowledge/roles/${file}`);
|
|
79
|
+
}
|
|
80
|
+
const schemaPrefix = "agent-state/MODULES/schemas/";
|
|
81
|
+
if (logicalAgentStatePath?.startsWith(schemaPrefix)) {
|
|
82
|
+
const file = logicalAgentStatePath.slice(schemaPrefix.length);
|
|
83
|
+
if (file)
|
|
84
|
+
keys.add(`knowledge/schemas/${file}`);
|
|
85
|
+
}
|
|
86
|
+
const staticAgentState = new Set([
|
|
87
|
+
"ACE_WORKFLOW.md",
|
|
88
|
+
"ARTIFACT_MANIFEST.json",
|
|
89
|
+
"AST_GREP_COMMANDS.md",
|
|
90
|
+
"AST_GREP_INDEX.json",
|
|
91
|
+
"AST_GREP_INDEX.md",
|
|
92
|
+
"DECISIONS.md",
|
|
93
|
+
"EVIDENCE_LOG.md",
|
|
94
|
+
"HANDOFF.json",
|
|
95
|
+
"INTERFACE_REGISTRY.md",
|
|
96
|
+
"PROVENANCE_LOG.md",
|
|
97
|
+
"QUALITY_GATES.md",
|
|
98
|
+
"RISKS.md",
|
|
99
|
+
"SCOPE.md",
|
|
100
|
+
"SKILL_CATALOG.md",
|
|
101
|
+
"STATUS.md",
|
|
102
|
+
"STATUS_EVENTS.ndjson",
|
|
103
|
+
"TASK.md",
|
|
104
|
+
"TEAL_CONFIG.md",
|
|
105
|
+
"MODULES/registry.json",
|
|
106
|
+
"handoff-registry.json",
|
|
107
|
+
"index-fingerprints.json",
|
|
108
|
+
"index.json",
|
|
109
|
+
"run-ledger.json",
|
|
110
|
+
"runtime-executor-sessions.json",
|
|
111
|
+
"runtime-tool-specs.json",
|
|
112
|
+
"runtime-workspaces.json",
|
|
113
|
+
"todo-state.json",
|
|
114
|
+
"tracker-snapshot.json",
|
|
115
|
+
"vericify/ace-bridge.json",
|
|
116
|
+
"vericify/process-posts.json",
|
|
117
|
+
]);
|
|
118
|
+
if (logicalAgentStatePath?.startsWith("agent-state/")) {
|
|
119
|
+
const rel = logicalAgentStatePath.slice("agent-state/".length);
|
|
120
|
+
if (!rel.startsWith("context-snapshots/")) {
|
|
121
|
+
keys.add(`state/artifacts/agent-state/${rel}`);
|
|
122
|
+
}
|
|
123
|
+
const runtimeProjectionKey = {
|
|
124
|
+
"job-queue.json": "state/artifacts/agent-state/job-queue.json",
|
|
125
|
+
"job-locks.json": "state/artifacts/agent-state/job-locks.json",
|
|
126
|
+
"scheduler-lease.json": "state/artifacts/agent-state/scheduler-lease.json",
|
|
127
|
+
}[rel];
|
|
128
|
+
if (runtimeProjectionKey)
|
|
129
|
+
keys.add(runtimeProjectionKey);
|
|
130
|
+
if (staticAgentState.has(rel)) {
|
|
131
|
+
keys.add(`knowledge/agent-state/${rel}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const contextSnapshotPrefix = "agent-state/context-snapshots/";
|
|
135
|
+
if (logicalAgentStatePath?.startsWith(contextSnapshotPrefix)) {
|
|
136
|
+
const rel = logicalAgentStatePath.slice(contextSnapshotPrefix.length);
|
|
137
|
+
if (rel)
|
|
138
|
+
keys.add(`state/memory/context_snapshots/${rel}`);
|
|
139
|
+
}
|
|
140
|
+
const skillsPrefix = `${ACE_SKILLS_ROOT_REL}/`;
|
|
141
|
+
if (canonical.startsWith(skillsPrefix)) {
|
|
142
|
+
keys.add(`knowledge/skills/${canonical.slice(skillsPrefix.length)}`);
|
|
143
|
+
}
|
|
144
|
+
const tasksPrefix = `${ACE_TASKS_ROOT_REL}/`;
|
|
145
|
+
if (canonical.startsWith(tasksPrefix)) {
|
|
146
|
+
keys.add(`knowledge/tasks/${canonical.slice(tasksPrefix.length)}`);
|
|
147
|
+
}
|
|
148
|
+
const scriptsPrefix = `${ACE_SCRIPTS_ROOT_REL}/`;
|
|
149
|
+
if (canonical.startsWith(scriptsPrefix)) {
|
|
150
|
+
keys.add(`knowledge/scripts/${canonical.slice(scriptsPrefix.length)}`);
|
|
151
|
+
}
|
|
152
|
+
for (const [key, candidates] of Object.entries(TASK_FILES)) {
|
|
153
|
+
if (candidates.includes(canonical)) {
|
|
154
|
+
keys.add(STORE_TASK_FILES[key]);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
for (const [key, candidates] of Object.entries(KERNEL_FILES)) {
|
|
158
|
+
if (candidates.includes(canonical)) {
|
|
159
|
+
for (const storeKey of STORE_KERNEL_FILES[key])
|
|
160
|
+
keys.add(storeKey);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
for (const [role, candidates] of Object.entries(AGENT_FILES)) {
|
|
164
|
+
if (candidates.includes(canonical)) {
|
|
165
|
+
for (const file of STORE_AGENT_FILES[role].instructions) {
|
|
166
|
+
keys.add(`knowledge/agents/${STORE_AGENT_FILES[role].agent}/${file}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
for (const [role, candidates] of Object.entries(AGENT_MANIFEST_FILES)) {
|
|
171
|
+
if (candidates.includes(canonical)) {
|
|
172
|
+
for (const file of STORE_AGENT_FILES[role].manifests) {
|
|
173
|
+
keys.add(`knowledge/agents/${STORE_AGENT_FILES[role].agent}/${file}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return [...keys];
|
|
178
|
+
}
|
|
179
|
+
export function resolveStoreFallbackKeysForPath(filePath) {
|
|
180
|
+
return resolveStoreFallbackKeys(filePath);
|
|
181
|
+
}
|
|
182
|
+
export function classifyPathSource(path) {
|
|
183
|
+
if (!path)
|
|
184
|
+
return "missing";
|
|
185
|
+
const root = currentWorkspaceRoot();
|
|
186
|
+
if (path.includes(".ace#"))
|
|
187
|
+
return "store";
|
|
188
|
+
if (isInside(root, path))
|
|
189
|
+
return "workspace";
|
|
190
|
+
if (isInside(DEFAULTS_ROOT, path))
|
|
191
|
+
return "package-defaults";
|
|
192
|
+
return "missing";
|
|
193
|
+
}
|
|
194
|
+
export function safeRead(filePath) {
|
|
195
|
+
try {
|
|
196
|
+
if (parseVirtualStorePath(filePath)) {
|
|
197
|
+
const direct = readVirtualStorePathSync(filePath);
|
|
198
|
+
return typeof direct === "string" ? direct : `[FILE NOT FOUND] ${filePath}`;
|
|
199
|
+
}
|
|
200
|
+
const abs = resolveWorkspaceReadPath(filePath);
|
|
201
|
+
if (!existsSync(abs)) {
|
|
202
|
+
const store = readStoreText(resolveStoreFallbackKeys(filePath));
|
|
203
|
+
if (store)
|
|
204
|
+
return store.text;
|
|
205
|
+
return `[FILE NOT FOUND] ${abs}`;
|
|
206
|
+
}
|
|
207
|
+
return readFileSyncUtf8(abs);
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
return `[ACCESS DENIED] ${String(err)}`;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
export function safeWrite(filePath, content) {
|
|
214
|
+
const normalized = normalizeRelPath(filePath);
|
|
215
|
+
const canonical = mapAceWorkspaceRelativePath(normalized);
|
|
216
|
+
const logicalAgentStatePath = normalized.startsWith("agent-state/")
|
|
217
|
+
? normalized
|
|
218
|
+
: canonical.startsWith(`${ACE_ROOT_REL}/agent-state/`)
|
|
219
|
+
? canonical.slice(`${ACE_ROOT_REL}/`.length)
|
|
220
|
+
: undefined;
|
|
221
|
+
const root = currentWorkspaceRoot();
|
|
222
|
+
let storeVirtualPath;
|
|
223
|
+
const storeKeys = resolveStoreFallbackKeys(filePath);
|
|
224
|
+
if (storeKeys.length > 0 && existsSync(getWorkspaceStorePath(root))) {
|
|
225
|
+
storeVirtualPath = withStoreWriteCoordinatorSync(getWorkspaceStorePath(root), () => writeStoreBlobSync(root, storeKeys[0], content), { operation_label: "safeWrite" });
|
|
226
|
+
const isAcePath = canonical === ACE_ROOT_REL || canonical.startsWith(`${ACE_ROOT_REL}/`);
|
|
227
|
+
const isStoreOnlyProjection = canonical === `${ACE_ROOT_REL}/ace-hook-context.json` ||
|
|
228
|
+
logicalAgentStatePath?.startsWith("agent-state/context-snapshots/") ||
|
|
229
|
+
STORE_ONLY_AGENT_STATE_FILES.has(logicalAgentStatePath ?? "");
|
|
230
|
+
if (isAcePath && !isProjectedAceWorkspacePath(canonical)) {
|
|
231
|
+
return storeVirtualPath;
|
|
232
|
+
}
|
|
233
|
+
if (isStoreOnlyProjection) {
|
|
234
|
+
return storeVirtualPath;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
const abs = isAbsolute(filePath) && isInside(root, filePath)
|
|
238
|
+
? filePath
|
|
239
|
+
: resolveWorkspaceWritePath(filePath, root);
|
|
240
|
+
mkdirSync(dirname(abs), { recursive: true });
|
|
241
|
+
const tmpPath = `${abs}.${process.pid}.${Date.now()}.tmp`;
|
|
242
|
+
writeFileSync(tmpPath, content, "utf-8");
|
|
243
|
+
renameSync(tmpPath, abs);
|
|
244
|
+
return abs;
|
|
245
|
+
}
|
|
246
|
+
export async function safeWriteAsync(filePath, content) {
|
|
247
|
+
const normalized = normalizeRelPath(filePath);
|
|
248
|
+
const canonical = mapAceWorkspaceRelativePath(normalized);
|
|
249
|
+
const logicalAgentStatePath = normalized.startsWith("agent-state/")
|
|
250
|
+
? normalized
|
|
251
|
+
: canonical.startsWith(`${ACE_ROOT_REL}/agent-state/`)
|
|
252
|
+
? canonical.slice(`${ACE_ROOT_REL}/`.length)
|
|
253
|
+
: undefined;
|
|
254
|
+
const root = currentWorkspaceRoot();
|
|
255
|
+
let storeVirtualPath;
|
|
256
|
+
const storeKeys = resolveStoreFallbackKeys(filePath);
|
|
257
|
+
if (storeKeys.length > 0 && existsSync(getWorkspaceStorePath(root))) {
|
|
258
|
+
const storeKey = storeKeys[0];
|
|
259
|
+
if (logicalAgentStatePath && isOperationalArtifactPath(logicalAgentStatePath)) {
|
|
260
|
+
storeVirtualPath = await writeOperationalArtifactQueued(root, logicalAgentStatePath, content, { operation_label: "safeWriteAsync" });
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
storeVirtualPath = await writeStoreBlobQueued(root, storeKey, content, { operation_label: "safeWriteAsync" });
|
|
264
|
+
}
|
|
265
|
+
const isAcePath = canonical === ACE_ROOT_REL || canonical.startsWith(`${ACE_ROOT_REL}/`);
|
|
266
|
+
const isStoreOnlyProjection = canonical === `${ACE_ROOT_REL}/ace-hook-context.json` ||
|
|
267
|
+
logicalAgentStatePath?.startsWith("agent-state/context-snapshots/") ||
|
|
268
|
+
STORE_ONLY_AGENT_STATE_FILES.has(logicalAgentStatePath ?? "");
|
|
269
|
+
if (isAcePath && !isProjectedAceWorkspacePath(canonical)) {
|
|
270
|
+
return storeVirtualPath;
|
|
271
|
+
}
|
|
272
|
+
if (isStoreOnlyProjection) {
|
|
273
|
+
return storeVirtualPath;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const abs = isAbsolute(filePath) && isInside(root, filePath)
|
|
277
|
+
? filePath
|
|
278
|
+
: resolveWorkspaceWritePath(filePath, root);
|
|
279
|
+
await mkdir(dirname(abs), { recursive: true });
|
|
280
|
+
const tmpPath = `${abs}.${process.pid}.${Date.now()}.tmp`;
|
|
281
|
+
await writeFile(tmpPath, content, "utf-8");
|
|
282
|
+
await rename(tmpPath, abs);
|
|
283
|
+
return abs;
|
|
284
|
+
}
|
|
285
|
+
const _fileLocks = new Map();
|
|
286
|
+
export async function withFileLock(path, fn) {
|
|
287
|
+
const key = resolveWorkspaceWritePath(path);
|
|
288
|
+
const prev = _fileLocks.get(key) ?? Promise.resolve();
|
|
289
|
+
let releaseLock;
|
|
290
|
+
const next = new Promise((r) => { releaseLock = r; });
|
|
291
|
+
_fileLocks.set(key, next);
|
|
292
|
+
await prev;
|
|
293
|
+
try {
|
|
294
|
+
return await fn();
|
|
295
|
+
}
|
|
296
|
+
finally {
|
|
297
|
+
releaseLock();
|
|
298
|
+
if (_fileLocks.get(key) === next)
|
|
299
|
+
_fileLocks.delete(key);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
function readFileSyncUtf8(path) {
|
|
303
|
+
return readFileSync(path, "utf-8");
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=store-resolution.js.map
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
function normalizeWorkspaceRootCandidate(candidate) {
|
|
4
|
+
const trimmed = candidate?.trim();
|
|
5
|
+
if (!trimmed)
|
|
6
|
+
return undefined;
|
|
7
|
+
return resolve(trimmed);
|
|
8
|
+
}
|
|
9
|
+
function isFilesystemRoot(path) {
|
|
10
|
+
return dirname(path) === path;
|
|
11
|
+
}
|
|
12
|
+
function normalizeWorkspaceRootLikePath(candidate) {
|
|
13
|
+
const resolvedCandidate = resolve(candidate);
|
|
14
|
+
if (resolvedCandidate.endsWith(join("agent-state", "ace-state.ace"))) {
|
|
15
|
+
return dirname(dirname(resolvedCandidate));
|
|
16
|
+
}
|
|
17
|
+
if (resolvedCandidate.endsWith(join(".agents", "ACE", "ace-state.ace"))) {
|
|
18
|
+
return dirname(dirname(dirname(resolvedCandidate)));
|
|
19
|
+
}
|
|
20
|
+
if (resolvedCandidate.endsWith(join(".agents", "ACE"))) {
|
|
21
|
+
return dirname(dirname(resolvedCandidate));
|
|
22
|
+
}
|
|
23
|
+
if (resolvedCandidate.endsWith(join(".agents"))) {
|
|
24
|
+
return dirname(resolvedCandidate);
|
|
25
|
+
}
|
|
26
|
+
return resolvedCandidate;
|
|
27
|
+
}
|
|
28
|
+
function hasInitiatedAceWorkspace(root) {
|
|
29
|
+
return (existsSync(resolve(root, "agent-state", "ace-state.ace")) ||
|
|
30
|
+
existsSync(resolve(root, ".agents", "ACE", "ace-state.ace")) ||
|
|
31
|
+
existsSync(resolve(root, ".agents", "ACE")) ||
|
|
32
|
+
existsSync(resolve(root, "agent-state", "TASK.md")) ||
|
|
33
|
+
existsSync(resolve(root, "agent-state", "STATUS.md")));
|
|
34
|
+
}
|
|
35
|
+
function findNearestInitiatedWorkspaceRoot(candidate) {
|
|
36
|
+
let cursor = normalizeWorkspaceRootLikePath(candidate);
|
|
37
|
+
while (true) {
|
|
38
|
+
if (existsSync(cursor) && hasInitiatedAceWorkspace(cursor)) {
|
|
39
|
+
return cursor;
|
|
40
|
+
}
|
|
41
|
+
const parent = dirname(cursor);
|
|
42
|
+
if (parent === cursor)
|
|
43
|
+
break;
|
|
44
|
+
cursor = parent;
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
function pinWorkspaceRoot(root) {
|
|
49
|
+
const normalized = normalizeWorkspaceRootLikePath(root);
|
|
50
|
+
process.env.ACE_WORKSPACE_ROOT = normalized;
|
|
51
|
+
return normalized;
|
|
52
|
+
}
|
|
53
|
+
export function resolveWorkspaceRoot() {
|
|
54
|
+
const explicit = normalizeWorkspaceRootCandidate(process.env.ACE_WORKSPACE_ROOT);
|
|
55
|
+
if (explicit)
|
|
56
|
+
return pinWorkspaceRoot(findNearestInitiatedWorkspaceRoot(explicit) ?? explicit);
|
|
57
|
+
const ordered = [
|
|
58
|
+
process.env.ACE_TUI_WORKSPACE_ROOT,
|
|
59
|
+
process.env.INIT_CWD,
|
|
60
|
+
process.env.PWD,
|
|
61
|
+
process.cwd(),
|
|
62
|
+
]
|
|
63
|
+
.map(normalizeWorkspaceRootCandidate)
|
|
64
|
+
.filter((candidate) => Boolean(candidate));
|
|
65
|
+
const candidates = [...new Set(ordered)];
|
|
66
|
+
for (const candidate of candidates) {
|
|
67
|
+
const initiated = findNearestInitiatedWorkspaceRoot(candidate);
|
|
68
|
+
if (initiated)
|
|
69
|
+
return pinWorkspaceRoot(initiated);
|
|
70
|
+
}
|
|
71
|
+
const firstExistingNonRoot = candidates.find((candidate) => existsSync(candidate) && !isFilesystemRoot(candidate));
|
|
72
|
+
if (firstExistingNonRoot)
|
|
73
|
+
return pinWorkspaceRoot(firstExistingNonRoot);
|
|
74
|
+
const firstExisting = candidates.find((candidate) => existsSync(candidate));
|
|
75
|
+
if (firstExisting)
|
|
76
|
+
return pinWorkspaceRoot(firstExisting);
|
|
77
|
+
return pinWorkspaceRoot(candidates[0] ?? resolve(process.cwd()));
|
|
78
|
+
}
|
|
79
|
+
export const WORKSPACE_ROOT = resolveWorkspaceRoot();
|
|
80
|
+
//# sourceMappingURL=workspace-root.js.map
|
package/dist/helpers.d.ts
CHANGED
|
@@ -1,128 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
* Shared helpers – path resolution, file I/O, artifact discovery, bootstrap.
|
|
3
|
-
*/
|
|
1
|
+
import { resolveWorkspaceRoot } from "./helpers/workspace-root.js";
|
|
4
2
|
export { isInside, isReadError, normalizeRelPath, looksLikeSwarmHandoffPath } from "./shared.js";
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export declare function resolveWorkspaceRoot(): string;
|
|
3
|
+
export * from "./helpers/constants.js";
|
|
4
|
+
export { resolveWorkspaceRoot };
|
|
8
5
|
export declare const WORKSPACE_ROOT: string;
|
|
9
|
-
export
|
|
10
|
-
export
|
|
11
|
-
export
|
|
12
|
-
export
|
|
13
|
-
export
|
|
14
|
-
export declare const ACE_BUNDLE_ROOT_REL = ".mcp-config";
|
|
15
|
-
export declare const ACE_LLM_ROOT_REL = ".agents/ACE/.ace";
|
|
16
|
-
export declare const ACE_VSCODE_ROOT_REL = ".vscode";
|
|
17
|
-
export declare const ACE_CURSOR_ROOT_REL = ".cursor";
|
|
18
|
-
export declare const ACE_CLAUDE_ROOT_REL = ".claude";
|
|
19
|
-
export declare const ACE_GITHUB_ROOT_REL = ".github";
|
|
20
|
-
export declare const ACE_HOST_AGENTS_REL = "AGENTS.md";
|
|
21
|
-
export declare const ACE_HOST_CLAUDE_REL = "CLAUDE.md";
|
|
22
|
-
export declare const ACE_HOST_CURSOR_RULES_REL = ".cursorrules";
|
|
23
|
-
export declare const ALL_MCP_CLIENTS: readonly ["codex", "vscode", "claude", "cursor", "antigravity"];
|
|
24
|
-
export type McpClient = (typeof ALL_MCP_CLIENTS)[number];
|
|
25
|
-
export declare const ALL_LLM_PROVIDERS: readonly ["ollama", "llama.cpp", "codex", "claude", "gemini", "copilot"];
|
|
26
|
-
export type LlmProvider = (typeof ALL_LLM_PROVIDERS)[number];
|
|
27
|
-
export declare const ALL_AGENTS: readonly ["orchestrator", "vos", "ui", "coders", "astgrep", "skeptic", "ops", "research", "spec", "builder", "qa", "docs", "memory", "security", "observability", "eval", "release"];
|
|
28
|
-
export type AgentRole = (typeof ALL_AGENTS)[number];
|
|
29
|
-
export declare const SWARM_AGENTS: readonly ["orchestrator", "vos", "ui", "coders"];
|
|
30
|
-
export type SwarmAgentRole = (typeof SWARM_AGENTS)[number];
|
|
31
|
-
export declare const COMPOSABLE_AGENTS: readonly ["astgrep", "skeptic", "ops", "research", "spec", "builder", "qa", "docs", "memory", "security", "observability", "eval", "release"];
|
|
32
|
-
export type ComposableAgentRole = (typeof COMPOSABLE_AGENTS)[number];
|
|
33
|
-
export declare const SWARM_SUBAGENT_MAP: Record<SwarmAgentRole, readonly ComposableAgentRole[]>;
|
|
34
|
-
export type TaskKey = "todo" | "role_tasks" | "cli_work_split" | "lessons" | "readme" | "handoff_template" | "handoff_example" | "handoff_example_vos_ui" | "handoff_example_ui_coders";
|
|
35
|
-
export type KernelKey = "directive_kernel" | "agent_registry";
|
|
36
|
-
export declare const AGENT_FILES: Record<AgentRole, string[]>;
|
|
37
|
-
export declare const AGENT_MANIFEST_FILES: Record<AgentRole, string[]>;
|
|
38
|
-
export declare const TASK_FILES: Record<TaskKey, string[]>;
|
|
39
|
-
export declare const KERNEL_FILES: Record<KernelKey, string[]>;
|
|
40
|
-
export type ArtifactSource = "workspace" | "package-defaults" | "store" | "missing";
|
|
41
|
-
export interface SkillReference {
|
|
42
|
-
name: string;
|
|
43
|
-
path: string;
|
|
44
|
-
source: "workspace" | "package-defaults" | "store";
|
|
45
|
-
}
|
|
46
|
-
export interface BootstrapOptions {
|
|
47
|
-
projectName?: string;
|
|
48
|
-
force?: boolean;
|
|
49
|
-
includeMcpConfig?: boolean;
|
|
50
|
-
includeClientConfigBundle?: boolean;
|
|
51
|
-
llmProvider?: LlmProvider;
|
|
52
|
-
llmModel?: string;
|
|
53
|
-
llmBaseUrl?: string;
|
|
54
|
-
ollamaModel?: string;
|
|
55
|
-
ollamaBaseUrl?: string;
|
|
56
|
-
/**
|
|
57
|
-
* When true, skip copying store-managed trees (tasks, agent-state, skills,
|
|
58
|
-
* and the .agents/ACE defaults tree). Pass this when bootstrapStoreWorkspace()
|
|
59
|
-
* has already run so the store is authoritative for those paths.
|
|
60
|
-
*/
|
|
61
|
-
skipStoreManaged?: boolean;
|
|
62
|
-
}
|
|
63
|
-
export interface BootstrapResult {
|
|
64
|
-
created: string[];
|
|
65
|
-
updated: string[];
|
|
66
|
-
skipped: string[];
|
|
67
|
-
}
|
|
68
|
-
export declare function mapAceWorkspaceRelativePath(path: string): string;
|
|
69
|
-
export declare function isProjectedAceWorkspacePath(filePath: string): boolean;
|
|
70
|
-
export declare function acePath(...segments: string[]): string;
|
|
71
|
-
export declare function wsPath(...segments: string[]): string;
|
|
72
|
-
/** Normalize a path for validation: workspace-relative, forward slashes. */
|
|
73
|
-
export declare function normalizePathForValidation(path: string): string;
|
|
74
|
-
/** Check if a role is a swarm agent (vs composable). */
|
|
75
|
-
export declare function isSwarmRole(role: string): role is (typeof SWARM_AGENTS)[number];
|
|
76
|
-
/** Atomically write a file via tmp + rename to prevent partial writes. */
|
|
77
|
-
export declare function atomicWrite(filePath: string, content: string): string;
|
|
78
|
-
/** Check if a file exists. Relative paths are workspace-relative. */
|
|
79
|
-
export declare function fileExists(filePath: string): boolean;
|
|
80
|
-
export declare function resolveWorkspaceWritePath(filePath: string): string;
|
|
81
|
-
export declare function resolveWorkspaceReadPath(filePath: string): string;
|
|
82
|
-
export declare function resolveWorkspaceArtifactPath(filePath: string, mode?: "read" | "write"): string;
|
|
83
|
-
export declare function resolveStoreFallbackKeysForPath(filePath: string): string[];
|
|
84
|
-
export declare function classifyPathSource(path?: string): ArtifactSource;
|
|
85
|
-
/** Safely read a workspace file, returning either text or a not-found/access message. */
|
|
86
|
-
export declare function safeRead(filePath: string): string;
|
|
87
|
-
/** Safely write a workspace file atomically (tmp + rename), creating directories if needed. */
|
|
88
|
-
export declare function safeWrite(filePath: string, content: string): string;
|
|
89
|
-
/**
|
|
90
|
-
* Execute `fn` while holding a per-path serialization lock.
|
|
91
|
-
* Prevents concurrent read-modify-write cycles on the same file
|
|
92
|
-
* within a single process. Cross-process safety relies on atomic rename.
|
|
93
|
-
*/
|
|
94
|
-
export declare function withFileLock<T>(path: string, fn: () => T | Promise<T>): Promise<T>;
|
|
95
|
-
export declare function getAgentInstructionPath(role: AgentRole): string | undefined;
|
|
96
|
-
export declare function getAgentManifestPath(role: AgentRole): string | undefined;
|
|
97
|
-
export declare function readAgentInstructions(role: AgentRole): string;
|
|
98
|
-
export declare function readAgentManifest(role: AgentRole): string;
|
|
99
|
-
export declare function getTaskArtifactPath(key: TaskKey): string | undefined;
|
|
100
|
-
export declare function readTaskArtifact(key: TaskKey): string;
|
|
101
|
-
export declare function getKernelArtifactPath(key: KernelKey): string | undefined;
|
|
102
|
-
export declare function readKernelArtifact(key: KernelKey): string;
|
|
103
|
-
export declare function resolveWritableTaskPath(key: TaskKey): string;
|
|
104
|
-
export declare function listAvailableSkills(): SkillReference[];
|
|
105
|
-
export declare function getSkillPath(name: string): string | undefined;
|
|
106
|
-
export declare function readSkillInstructions(name: string): string;
|
|
107
|
-
export declare function getMcpClientBundlePath(client: McpClient): string;
|
|
108
|
-
export declare function getMcpClientInstallHint(client: McpClient): string;
|
|
109
|
-
export declare function getMcpServerConfigSnippet(client?: McpClient): string;
|
|
110
|
-
export declare function getAllMcpServerConfigSnippets(): Record<McpClient, string>;
|
|
111
|
-
export declare function bootstrapAceWorkspace(options?: BootstrapOptions): BootstrapResult;
|
|
112
|
-
export interface DriftEntry {
|
|
113
|
-
asset_path: string;
|
|
114
|
-
runtime_path: string;
|
|
115
|
-
status: "match" | "drift" | "missing-runtime" | "missing-asset";
|
|
116
|
-
}
|
|
117
|
-
export interface DriftReport {
|
|
118
|
-
checked: number;
|
|
119
|
-
drifted: number;
|
|
120
|
-
missing_runtime: number;
|
|
121
|
-
entries: DriftEntry[];
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Compare packaged assets against runtime workspace copies.
|
|
125
|
-
* Detects silent divergence between authoritative defaults and live state.
|
|
126
|
-
*/
|
|
127
|
-
export declare function detectAssetDrift(): DriftReport;
|
|
6
|
+
export * from "./helpers/path-utils.js";
|
|
7
|
+
export * from "./helpers/store-resolution.js";
|
|
8
|
+
export * from "./helpers/artifacts.js";
|
|
9
|
+
export * from "./helpers/bootstrap.js";
|
|
10
|
+
export * from "./helpers/drift.js";
|
|
128
11
|
//# sourceMappingURL=helpers.d.ts.map
|