@tiangong-ai/cli 0.0.19 → 0.0.20
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/AGENTS.md +8 -2
- package/README.md +72 -4
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/research/commands.js +6 -0
- package/dist/research/commands.js.map +1 -1
- package/dist/research/orchestration.d.ts +3 -0
- package/dist/research/orchestration.js +236 -0
- package/dist/research/orchestration.js.map +1 -0
- package/dist/research/workspace/broker.d.ts +5 -0
- package/dist/research/workspace/broker.js +353 -0
- package/dist/research/workspace/broker.js.map +1 -0
- package/dist/research/workspace/capabilities.d.ts +10 -0
- package/dist/research/workspace/capabilities.js +291 -0
- package/dist/research/workspace/capabilities.js.map +1 -0
- package/dist/research/workspace/constants.d.ts +8 -0
- package/dist/research/workspace/constants.js +37 -0
- package/dist/research/workspace/constants.js.map +1 -0
- package/dist/research/workspace/context.d.ts +3 -0
- package/dist/research/workspace/context.js +77 -0
- package/dist/research/workspace/context.js.map +1 -0
- package/dist/research/workspace/executor.d.ts +12 -0
- package/dist/research/workspace/executor.js +353 -0
- package/dist/research/workspace/executor.js.map +1 -0
- package/dist/research/workspace/journal.d.ts +7 -0
- package/dist/research/workspace/journal.js +104 -0
- package/dist/research/workspace/journal.js.map +1 -0
- package/dist/research/workspace/projects.d.ts +9 -0
- package/dist/research/workspace/projects.js +230 -0
- package/dist/research/workspace/projects.js.map +1 -0
- package/dist/research/workspace/runtime.d.ts +27 -0
- package/dist/research/workspace/runtime.js +519 -0
- package/dist/research/workspace/runtime.js.map +1 -0
- package/dist/research/workspace/storage.d.ts +25 -0
- package/dist/research/workspace/storage.js +218 -0
- package/dist/research/workspace/storage.js.map +1 -0
- package/dist/research/workspace/types.d.ts +181 -0
- package/dist/research/workspace/types.js +2 -0
- package/dist/research/workspace/types.js.map +1 -0
- package/dist/research/workspace/workspace.d.ts +12 -0
- package/dist/research/workspace/workspace.js +340 -0
- package/dist/research/workspace/workspace.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
4
|
+
import { CliError } from "../../errors.js";
|
|
5
|
+
import { ALLOWED_CAPABILITY_PERMISSIONS } from "./constants.js";
|
|
6
|
+
import { canonicalJson, ensureDirectory, hashRegularTree, isObject, pathExists, readJsonFile, regularTreeFiles, workspacePaths, writeJsonAtomic, } from "./storage.js";
|
|
7
|
+
export async function loadCapabilityDeclarations(root) {
|
|
8
|
+
const value = await readJsonFile(workspacePaths(root).capabilityDeclarations, "Research capability declarations");
|
|
9
|
+
if (!isObject(value) || value.schemaVersion !== 1 || !Array.isArray(value.capabilities)) {
|
|
10
|
+
throw new CliError("Research capability declarations have an unsupported shape.", {
|
|
11
|
+
code: "RESEARCH_CAPABILITY_INVALID",
|
|
12
|
+
exitCode: 2,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
const capabilities = value.capabilities.map((item, index) => parseCapability(item, index));
|
|
16
|
+
assertUnique(capabilities.map((item) => item.id), "capability ID");
|
|
17
|
+
assertUnique(capabilities.flatMap((item) => item.credentials.map((credential) => credential.id)), "credential ID");
|
|
18
|
+
return { schemaVersion: 1, capabilities };
|
|
19
|
+
}
|
|
20
|
+
export async function lockCapabilities(root) {
|
|
21
|
+
const declarations = await loadCapabilityDeclarations(root);
|
|
22
|
+
const records = await Promise.all(declarations.capabilities.map(async (declaration) => lockCapability(declaration)));
|
|
23
|
+
records.sort((left, right) => left.id.localeCompare(right.id));
|
|
24
|
+
assertUnique(records.map((record) => record.skillName), "capability skill name");
|
|
25
|
+
const lock = {
|
|
26
|
+
schemaVersion: 1,
|
|
27
|
+
generatedAt: new Date().toISOString(),
|
|
28
|
+
capabilities: records,
|
|
29
|
+
};
|
|
30
|
+
await writeJsonAtomic(workspacePaths(root).capabilityLock, lock, 0o444);
|
|
31
|
+
return lock;
|
|
32
|
+
}
|
|
33
|
+
export async function verifyCapabilities(root) {
|
|
34
|
+
const declarations = await loadCapabilityDeclarations(root);
|
|
35
|
+
const lockPath = workspacePaths(root).capabilityLock;
|
|
36
|
+
if (!(await pathExists(lockPath))) {
|
|
37
|
+
if (declarations.capabilities.length === 0) {
|
|
38
|
+
return { status: "verified", checked: 0, errors: [] };
|
|
39
|
+
}
|
|
40
|
+
return { status: "drifted", checked: 0, errors: ["capability lock is missing"] };
|
|
41
|
+
}
|
|
42
|
+
const lock = await readJsonFile(lockPath, "Research capability lock");
|
|
43
|
+
if (!isCapabilityLock(lock)) {
|
|
44
|
+
return { status: "drifted", checked: 0, errors: ["capability lock shape is invalid"] };
|
|
45
|
+
}
|
|
46
|
+
const lockedById = new Map(lock.capabilities.map((record) => [record.id, record]));
|
|
47
|
+
const errors = [];
|
|
48
|
+
for (const declaration of declarations.capabilities) {
|
|
49
|
+
const record = lockedById.get(declaration.id);
|
|
50
|
+
if (!record) {
|
|
51
|
+
errors.push(`${declaration.id}: missing lock record`);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const current = await lockCapability(declaration);
|
|
56
|
+
if (JSON.stringify(current) !== JSON.stringify(record)) {
|
|
57
|
+
errors.push(`${declaration.id}: installed skill differs from its lock`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
errors.push(`${declaration.id}: ${error instanceof Error ? error.message : String(error)}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
for (const record of lock.capabilities) {
|
|
65
|
+
if (!declarations.capabilities.some((item) => item.id === record.id)) {
|
|
66
|
+
errors.push(`${record.id}: lock record has no declaration`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
status: errors.length ? "drifted" : "verified",
|
|
71
|
+
checked: declarations.capabilities.length,
|
|
72
|
+
errors,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export async function stageLockedCapabilities(root, destination) {
|
|
76
|
+
const declarations = await loadCapabilityDeclarations(root);
|
|
77
|
+
if (declarations.capabilities.length === 0)
|
|
78
|
+
return [];
|
|
79
|
+
const verification = await verifyCapabilities(root);
|
|
80
|
+
if (verification.status !== "verified") {
|
|
81
|
+
throw new CliError("Research capabilities must be locked and verified before execution.", {
|
|
82
|
+
code: "RESEARCH_CAPABILITY_DRIFT",
|
|
83
|
+
exitCode: 3,
|
|
84
|
+
details: verification,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
const lock = await readJsonFile(workspacePaths(root).capabilityLock, "Research capability lock");
|
|
88
|
+
const staged = [];
|
|
89
|
+
for (const record of lock.capabilities) {
|
|
90
|
+
const target = join(destination, record.skillName);
|
|
91
|
+
await copyRegularTree(record.skillPath, target);
|
|
92
|
+
staged.push(target);
|
|
93
|
+
}
|
|
94
|
+
return staged;
|
|
95
|
+
}
|
|
96
|
+
export async function declaredCredentialIds(root) {
|
|
97
|
+
const declarations = await loadCapabilityDeclarations(root);
|
|
98
|
+
return new Set(declarations.capabilities.flatMap((capability) => capability.credentials.map((credential) => credential.id)));
|
|
99
|
+
}
|
|
100
|
+
async function lockCapability(declaration) {
|
|
101
|
+
const skillPath = resolve(declaration.skillPath);
|
|
102
|
+
if (skillPath !== declaration.skillPath) {
|
|
103
|
+
throw new CliError(`Capability skill path must be absolute: ${declaration.skillPath}`, {
|
|
104
|
+
code: "RESEARCH_CAPABILITY_INVALID",
|
|
105
|
+
exitCode: 2,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
const skillEntry = join(skillPath, "SKILL.md");
|
|
109
|
+
const skillText = await readFile(skillEntry, "utf8").catch(() => {
|
|
110
|
+
throw new CliError(`Capability is missing SKILL.md: ${skillPath}`, {
|
|
111
|
+
code: "RESEARCH_CAPABILITY_INVALID",
|
|
112
|
+
exitCode: 2,
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
const skillName = skillFrontmatterName(skillText);
|
|
116
|
+
if (basename(skillPath) !== skillName) {
|
|
117
|
+
throw new CliError(`Capability directory and skill name differ: ${skillPath}`, {
|
|
118
|
+
code: "RESEARCH_CAPABILITY_INVALID",
|
|
119
|
+
exitCode: 2,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
id: declaration.id,
|
|
124
|
+
skillName,
|
|
125
|
+
skillPath,
|
|
126
|
+
treeSha256: await hashRegularTree(skillPath),
|
|
127
|
+
policySha256: policyHash(declaration),
|
|
128
|
+
permissions: [...declaration.permissions].sort(),
|
|
129
|
+
credentialIds: declaration.credentials.map((item) => item.id).sort(),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function parseCapability(value, index) {
|
|
133
|
+
if (!isObject(value))
|
|
134
|
+
invalid(index, "must be an object");
|
|
135
|
+
const id = value.id;
|
|
136
|
+
const skillPath = value.skillPath;
|
|
137
|
+
const permissions = value.permissions;
|
|
138
|
+
const allowedHosts = value.allowedHosts ?? [];
|
|
139
|
+
const credentials = value.credentials ?? [];
|
|
140
|
+
if (typeof id !== "string" || !/^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)+$/.test(id)) {
|
|
141
|
+
invalid(index, "id must be a namespaced logical identifier");
|
|
142
|
+
}
|
|
143
|
+
if (typeof skillPath !== "string" || !isAbsolute(skillPath)) {
|
|
144
|
+
invalid(index, "skillPath must be absolute");
|
|
145
|
+
}
|
|
146
|
+
if (!Array.isArray(permissions) ||
|
|
147
|
+
permissions.some((permission) => typeof permission !== "string" || !ALLOWED_CAPABILITY_PERMISSIONS.has(permission))) {
|
|
148
|
+
invalid(index, "permissions contain an unsupported value");
|
|
149
|
+
}
|
|
150
|
+
if (!Array.isArray(credentials))
|
|
151
|
+
invalid(index, "credentials must be an array");
|
|
152
|
+
if (!Array.isArray(allowedHosts) || allowedHosts.some((host) => typeof host !== "string")) {
|
|
153
|
+
invalid(index, "allowedHosts must be an array of exact host names");
|
|
154
|
+
}
|
|
155
|
+
const parsedAllowedHosts = [
|
|
156
|
+
...new Set(allowedHosts.map((host) => normalizeAllowedHost(host, index))),
|
|
157
|
+
].sort();
|
|
158
|
+
const brokeredNetwork = permissions.includes("brokered-network");
|
|
159
|
+
if (brokeredNetwork && parsedAllowedHosts.length === 0) {
|
|
160
|
+
invalid(index, "must declare allowedHosts for brokered-network");
|
|
161
|
+
}
|
|
162
|
+
if (!brokeredNetwork && parsedAllowedHosts.length > 0) {
|
|
163
|
+
invalid(index, "cannot declare allowedHosts without brokered-network");
|
|
164
|
+
}
|
|
165
|
+
const parsedCredentials = credentials.map((credential, credentialIndex) => {
|
|
166
|
+
if (!isObject(credential))
|
|
167
|
+
invalid(index, `credential ${credentialIndex} must be an object`);
|
|
168
|
+
if (typeof credential.id !== "string" ||
|
|
169
|
+
!/^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)+$/.test(credential.id) ||
|
|
170
|
+
!Array.isArray(credential.allowedHosts) ||
|
|
171
|
+
credential.allowedHosts.length === 0 ||
|
|
172
|
+
credential.allowedHosts.some((host) => typeof host !== "string") ||
|
|
173
|
+
typeof credential.headerName !== "string" ||
|
|
174
|
+
!/^[A-Za-z][A-Za-z0-9-]*$/.test(credential.headerName) ||
|
|
175
|
+
typeof credential.prefix !== "string") {
|
|
176
|
+
invalid(index, `credential ${credentialIndex} is malformed`);
|
|
177
|
+
}
|
|
178
|
+
const credentialHosts = [
|
|
179
|
+
...new Set(credential.allowedHosts.map((host) => normalizeAllowedHost(host, index, credentialIndex))),
|
|
180
|
+
].sort();
|
|
181
|
+
if (!brokeredNetwork || credentialHosts.some((host) => !parsedAllowedHosts.includes(host))) {
|
|
182
|
+
invalid(index, `credential ${credentialIndex} hosts must be within capability allowedHosts`);
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
id: credential.id,
|
|
186
|
+
allowedHosts: credentialHosts,
|
|
187
|
+
headerName: credential.headerName,
|
|
188
|
+
prefix: credential.prefix,
|
|
189
|
+
};
|
|
190
|
+
});
|
|
191
|
+
assertUnique(parsedCredentials.map((item) => item.id), `credential ID in ${id}`);
|
|
192
|
+
return {
|
|
193
|
+
id,
|
|
194
|
+
skillPath,
|
|
195
|
+
permissions: [...new Set(permissions)],
|
|
196
|
+
allowedHosts: parsedAllowedHosts,
|
|
197
|
+
credentials: parsedCredentials,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
function isCapabilityLock(value) {
|
|
201
|
+
return (isObject(value) &&
|
|
202
|
+
value.schemaVersion === 1 &&
|
|
203
|
+
typeof value.generatedAt === "string" &&
|
|
204
|
+
Array.isArray(value.capabilities) &&
|
|
205
|
+
value.capabilities.every((record) => isObject(record) &&
|
|
206
|
+
typeof record.id === "string" &&
|
|
207
|
+
typeof record.skillName === "string" &&
|
|
208
|
+
typeof record.skillPath === "string" &&
|
|
209
|
+
typeof record.treeSha256 === "string" &&
|
|
210
|
+
typeof record.policySha256 === "string" &&
|
|
211
|
+
Array.isArray(record.permissions) &&
|
|
212
|
+
Array.isArray(record.credentialIds)));
|
|
213
|
+
}
|
|
214
|
+
function policyHash(declaration) {
|
|
215
|
+
return hashText(canonicalJson({
|
|
216
|
+
permissions: [...declaration.permissions].sort(),
|
|
217
|
+
allowedHosts: [...declaration.allowedHosts].sort(),
|
|
218
|
+
credentials: declaration.credentials
|
|
219
|
+
.map((credential) => ({
|
|
220
|
+
id: credential.id,
|
|
221
|
+
allowedHosts: [...credential.allowedHosts].sort(),
|
|
222
|
+
headerName: credential.headerName.toLowerCase(),
|
|
223
|
+
prefix: credential.prefix,
|
|
224
|
+
}))
|
|
225
|
+
.sort((left, right) => left.id.localeCompare(right.id)),
|
|
226
|
+
}));
|
|
227
|
+
}
|
|
228
|
+
function hashText(value) {
|
|
229
|
+
return createHash("sha256").update(value, "utf8").digest("hex");
|
|
230
|
+
}
|
|
231
|
+
function normalizeAllowedHost(value, index, credentialIndex) {
|
|
232
|
+
const label = credentialIndex === undefined ? "allowedHosts" : `credential ${credentialIndex} host`;
|
|
233
|
+
const candidate = value.trim().toLowerCase();
|
|
234
|
+
let parsed;
|
|
235
|
+
try {
|
|
236
|
+
parsed = new URL(`https://${candidate}`);
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
invalid(index, `${label} contains an invalid host`);
|
|
240
|
+
}
|
|
241
|
+
if (!candidate ||
|
|
242
|
+
candidate.includes("*") ||
|
|
243
|
+
parsed.username ||
|
|
244
|
+
parsed.password ||
|
|
245
|
+
parsed.hostname.endsWith(".") ||
|
|
246
|
+
parsed.pathname !== "/" ||
|
|
247
|
+
parsed.search ||
|
|
248
|
+
parsed.hash) {
|
|
249
|
+
invalid(index, `${label} must contain exact HTTPS host names without paths or wildcards`);
|
|
250
|
+
}
|
|
251
|
+
return parsed.host;
|
|
252
|
+
}
|
|
253
|
+
function skillFrontmatterName(content) {
|
|
254
|
+
const match = content.match(/^---\s*\n([\s\S]*?)\n---(?:\s*\n|$)/);
|
|
255
|
+
const name = match?.[1]?.match(/^name:\s*["']?([a-z0-9-]+)["']?\s*$/m)?.[1];
|
|
256
|
+
if (!name) {
|
|
257
|
+
throw new CliError("Capability SKILL.md has no valid name frontmatter.", {
|
|
258
|
+
code: "RESEARCH_CAPABILITY_INVALID",
|
|
259
|
+
exitCode: 2,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
return name;
|
|
263
|
+
}
|
|
264
|
+
async function copyRegularTree(source, target) {
|
|
265
|
+
const files = await regularTreeFiles(source);
|
|
266
|
+
for (const path of files) {
|
|
267
|
+
const logical = relative(source, path);
|
|
268
|
+
const destination = join(target, logical);
|
|
269
|
+
await ensureDirectory(dirname(destination));
|
|
270
|
+
await writeFile(destination, await readFile(path), { mode: 0o600 });
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
function assertUnique(values, label) {
|
|
274
|
+
const seen = new Set();
|
|
275
|
+
for (const value of values) {
|
|
276
|
+
if (seen.has(value)) {
|
|
277
|
+
throw new CliError(`Duplicate ${label}: ${value}`, {
|
|
278
|
+
code: "RESEARCH_CAPABILITY_INVALID",
|
|
279
|
+
exitCode: 2,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
seen.add(value);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function invalid(index, detail) {
|
|
286
|
+
throw new CliError(`Capability declaration ${index} ${detail}.`, {
|
|
287
|
+
code: "RESEARCH_CAPABILITY_INVALID",
|
|
288
|
+
exitCode: 2,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../../src/research/workspace/capabilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const RESEARCH_CONTROL_DIRECTORY = ".tiangong-research";
|
|
2
|
+
export declare const RESEARCH_PROTOCOL_VERSION: 1;
|
|
3
|
+
export declare const RESEARCH_PACKAGE_NAME: "@tiangong-ai/cli";
|
|
4
|
+
export declare const ALLOWED_CAPABILITY_PERMISSIONS: Set<string>;
|
|
5
|
+
export declare const WORKSPACE_OPERATIONS: readonly ["research.context.inspect", "research.workspace.doctor", "research.capability.lock", "research.capability.verify", "research.project.init", "research.project.input.add", "research.status", "research.run"];
|
|
6
|
+
export declare const UNMANAGED_OPERATIONS: readonly ["research.context.inspect", "research.workspace.init"];
|
|
7
|
+
export declare const INVALID_OPERATIONS: readonly ["research.context.inspect"];
|
|
8
|
+
export declare function packageVersion(): string;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
export const RESEARCH_CONTROL_DIRECTORY = ".tiangong-research";
|
|
5
|
+
export const RESEARCH_PROTOCOL_VERSION = 1;
|
|
6
|
+
export const RESEARCH_PACKAGE_NAME = "@tiangong-ai/cli";
|
|
7
|
+
export const ALLOWED_CAPABILITY_PERMISSIONS = new Set([
|
|
8
|
+
"project-read",
|
|
9
|
+
"candidate-write",
|
|
10
|
+
"brokered-network",
|
|
11
|
+
"controlled-command",
|
|
12
|
+
]);
|
|
13
|
+
export const WORKSPACE_OPERATIONS = [
|
|
14
|
+
"research.context.inspect",
|
|
15
|
+
"research.workspace.doctor",
|
|
16
|
+
"research.capability.lock",
|
|
17
|
+
"research.capability.verify",
|
|
18
|
+
"research.project.init",
|
|
19
|
+
"research.project.input.add",
|
|
20
|
+
"research.status",
|
|
21
|
+
"research.run",
|
|
22
|
+
];
|
|
23
|
+
export const UNMANAGED_OPERATIONS = [
|
|
24
|
+
"research.context.inspect",
|
|
25
|
+
"research.workspace.init",
|
|
26
|
+
];
|
|
27
|
+
export const INVALID_OPERATIONS = ["research.context.inspect"];
|
|
28
|
+
export function packageVersion() {
|
|
29
|
+
const moduleDirectory = dirname(fileURLToPath(import.meta.url));
|
|
30
|
+
const packagePath = resolve(moduleDirectory, "../../../package.json");
|
|
31
|
+
const value = JSON.parse(readFileSync(packagePath, "utf8"));
|
|
32
|
+
if (typeof value.version !== "string" || !value.version.trim()) {
|
|
33
|
+
throw new Error("Package version is unavailable.");
|
|
34
|
+
}
|
|
35
|
+
return value.version;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/research/workspace/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,CAAC,MAAM,0BAA0B,GAAG,oBAAoB,CAAC;AAC/D,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAU,CAAC;AACpD,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAA2B,CAAC;AAEjE,MAAM,CAAC,MAAM,8BAA8B,GAAG,IAAI,GAAG,CAAC;IACpD,cAAc;IACd,iBAAiB;IACjB,kBAAkB;IAClB,oBAAoB;CACrB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,0BAA0B;IAC1B,2BAA2B;IAC3B,0BAA0B;IAC1B,4BAA4B;IAC5B,uBAAuB;IACvB,4BAA4B;IAC5B,iBAAiB;IACjB,cAAc;CACN,CAAC;AAEX,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,0BAA0B;IAC1B,yBAAyB;CACjB,CAAC;AAEX,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,0BAA0B,CAAU,CAAC;AAExE,MAAM,UAAU,cAAc;IAC5B,MAAM,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,MAAM,WAAW,GAAG,OAAO,CAAC,eAAe,EAAE,uBAAuB,CAAC,CAAC;IACtE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAA0B,CAAC;IACrF,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,KAAK,CAAC,OAAO,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { lstat } from "node:fs/promises";
|
|
2
|
+
import { dirname, join, parse, resolve } from "node:path";
|
|
3
|
+
import { INVALID_OPERATIONS, RESEARCH_CONTROL_DIRECTORY, UNMANAGED_OPERATIONS, WORKSPACE_OPERATIONS, } from "./constants.js";
|
|
4
|
+
import { isObject, pathExists, readJsonFile } from "./storage.js";
|
|
5
|
+
export async function inspectResearchContext(selectedPath) {
|
|
6
|
+
const canonical = resolve(selectedPath);
|
|
7
|
+
const info = await lstat(canonical).catch(() => undefined);
|
|
8
|
+
let cursor = info?.isFile() ? dirname(canonical) : canonical;
|
|
9
|
+
while (true) {
|
|
10
|
+
const control = join(cursor, RESEARCH_CONTROL_DIRECTORY);
|
|
11
|
+
if (await pathExists(control)) {
|
|
12
|
+
const markerPath = join(control, "workspace.json");
|
|
13
|
+
if (!(await pathExists(markerPath))) {
|
|
14
|
+
return {
|
|
15
|
+
role: "invalid",
|
|
16
|
+
selectedPath: canonical,
|
|
17
|
+
root: cursor,
|
|
18
|
+
allowedOperations: [...INVALID_OPERATIONS],
|
|
19
|
+
violations: [
|
|
20
|
+
{
|
|
21
|
+
code: "WORKSPACE_MARKER_MISSING",
|
|
22
|
+
message: `${RESEARCH_CONTROL_DIRECTORY} exists without workspace.json.`,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const marker = await readJsonFile(markerPath, "Research workspace marker");
|
|
29
|
+
if (!isWorkspaceMarker(marker)) {
|
|
30
|
+
return invalidMarker(canonical, cursor, "workspace.json has an unsupported shape.");
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
role: "workspace",
|
|
34
|
+
selectedPath: canonical,
|
|
35
|
+
root: cursor,
|
|
36
|
+
allowedOperations: [...WORKSPACE_OPERATIONS],
|
|
37
|
+
violations: [],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
return invalidMarker(canonical, cursor, String(error));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const parent = dirname(cursor);
|
|
45
|
+
if (cursor === parent || cursor === parse(cursor).root)
|
|
46
|
+
break;
|
|
47
|
+
cursor = parent;
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
role: "unmanaged",
|
|
51
|
+
selectedPath: canonical,
|
|
52
|
+
root: null,
|
|
53
|
+
allowedOperations: [...UNMANAGED_OPERATIONS],
|
|
54
|
+
violations: [],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export function isWorkspaceMarker(value) {
|
|
58
|
+
return (isObject(value) &&
|
|
59
|
+
value.schemaVersion === 1 &&
|
|
60
|
+
value.kind === "tiangong-research-workspace" &&
|
|
61
|
+
typeof value.workspaceId === "string" &&
|
|
62
|
+
value.workspaceId.length > 0 &&
|
|
63
|
+
typeof value.name === "string" &&
|
|
64
|
+
value.name.length > 0 &&
|
|
65
|
+
typeof value.createdAt === "string" &&
|
|
66
|
+
value.createdAt.length > 0);
|
|
67
|
+
}
|
|
68
|
+
function invalidMarker(selectedPath, root, message) {
|
|
69
|
+
return {
|
|
70
|
+
role: "invalid",
|
|
71
|
+
selectedPath,
|
|
72
|
+
root,
|
|
73
|
+
allowedOperations: [...INVALID_OPERATIONS],
|
|
74
|
+
violations: [{ code: "WORKSPACE_MARKER_INVALID", message }],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/research/workspace/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AgentRoute, ExecutionResult } from "./types.js";
|
|
2
|
+
export interface AgentExecutionRequest {
|
|
3
|
+
route: AgentRoute;
|
|
4
|
+
prompt: string;
|
|
5
|
+
capsuleRoot: string;
|
|
6
|
+
projectRoot: string;
|
|
7
|
+
workspaceRoot: string;
|
|
8
|
+
timeoutSeconds: number;
|
|
9
|
+
environment: NodeJS.ProcessEnv;
|
|
10
|
+
brokerUrl: string | null;
|
|
11
|
+
}
|
|
12
|
+
export declare function executeAgent(request: AgentExecutionRequest): Promise<ExecutionResult>;
|