@aaac/contracts 0.1.13 → 0.1.15
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/{chunk-MWZFJ2VL.js → chunk-F57V745S.js} +605 -5
- package/dist/chunk-F57V745S.js.map +1 -0
- package/dist/cli/index.js +43 -379
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +93 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/chunk-MWZFJ2VL.js.map +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -3,18 +3,26 @@ import {
|
|
|
3
3
|
ComponentCompileError,
|
|
4
4
|
ComponentParseError,
|
|
5
5
|
ComponentValidationError,
|
|
6
|
+
GOVERNANCE_LOCK_PATH,
|
|
6
7
|
RefResolutionError,
|
|
8
|
+
SCAFFOLD_PROJECT_YAML,
|
|
7
9
|
compileComponent,
|
|
8
10
|
compileComponentFile,
|
|
11
|
+
copyCLIBinary,
|
|
9
12
|
generateAll,
|
|
13
|
+
loadHookBindings,
|
|
14
|
+
loadInitConfig,
|
|
15
|
+
materializeHooks,
|
|
10
16
|
parseComponentFile,
|
|
17
|
+
readGovernanceLock,
|
|
18
|
+
unmaterializeHooks,
|
|
11
19
|
validateComponent,
|
|
12
20
|
writeGeneratedFiles
|
|
13
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-F57V745S.js";
|
|
14
22
|
|
|
15
23
|
// src/cli/index.ts
|
|
16
24
|
import { readFileSync } from "fs";
|
|
17
|
-
import { dirname as
|
|
25
|
+
import { dirname as dirname2, resolve as resolve2 } from "path";
|
|
18
26
|
import { fileURLToPath } from "url";
|
|
19
27
|
|
|
20
28
|
// ../../node_modules/commander/lib/error.js
|
|
@@ -3800,356 +3808,10 @@ function createProgram(handlers2, version) {
|
|
|
3800
3808
|
}
|
|
3801
3809
|
|
|
3802
3810
|
// src/cli/handlers.ts
|
|
3803
|
-
import { existsSync as existsSync2 } from "fs";
|
|
3804
|
-
import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
3805
|
-
import { dirname as dirname2, join as join2, resolve as resolve2 } from "path";
|
|
3806
|
-
import { stringify as stringifyYaml } from "yaml";
|
|
3807
|
-
|
|
3808
|
-
// src/cli/governance.ts
|
|
3809
|
-
import { createHash } from "crypto";
|
|
3810
3811
|
import { existsSync } from "fs";
|
|
3811
|
-
import {
|
|
3812
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
3812
3813
|
import { dirname, join, resolve } from "path";
|
|
3813
|
-
import {
|
|
3814
|
-
import { z } from "zod";
|
|
3815
|
-
var MANAGED_BLOCK_START = "# >>> aaac-governance:managed (do not edit) >>>";
|
|
3816
|
-
var MANAGED_BLOCK_END = "# <<< aaac-governance:managed <<<";
|
|
3817
|
-
var GOVERNANCE_LOCK_PATH = ".agent-logs/governance-manifest.lock";
|
|
3818
|
-
var DEFAULT_RECORDER = ".cursor/hooks/observ-record.sh";
|
|
3819
|
-
var DEFAULT_CURSOR_HOOKS_JSON = ".cursor/hooks.json";
|
|
3820
|
-
var DEFAULT_BINARY_DEST = "bin/aaac.js";
|
|
3821
|
-
var CURSOR_HOOKS_VERSION = 1;
|
|
3822
|
-
var EnvironmentsSchema = z.object({
|
|
3823
|
-
git: z.object({ hooks: z.array(z.string()).optional() }).optional(),
|
|
3824
|
-
cursor: z.object({ hooks_json: z.string().optional() }).optional()
|
|
3825
|
-
}).optional();
|
|
3826
|
-
var BindingsObservabilitySchema = z.object({
|
|
3827
|
-
event_mapping: z.string().optional(),
|
|
3828
|
-
recorder: z.string().optional()
|
|
3829
|
-
}).optional();
|
|
3830
|
-
var BindingsSchema = z.object({
|
|
3831
|
-
observability: BindingsObservabilitySchema,
|
|
3832
|
-
hooks: z.array(z.string()).optional()
|
|
3833
|
-
}).optional();
|
|
3834
|
-
var InitProjectConfigSchema = z.object({
|
|
3835
|
-
environments: EnvironmentsSchema,
|
|
3836
|
-
bindings: BindingsSchema
|
|
3837
|
-
});
|
|
3838
|
-
async function loadInitConfig(configPath) {
|
|
3839
|
-
const absPath = resolve(configPath);
|
|
3840
|
-
const raw = await readFile(absPath, "utf8");
|
|
3841
|
-
const parsed = parseYaml(raw);
|
|
3842
|
-
return InitProjectConfigSchema.parse(parsed ?? {});
|
|
3843
|
-
}
|
|
3844
|
-
var HookCommandSchema = z.object({
|
|
3845
|
-
command: z.string(),
|
|
3846
|
-
description: z.string().optional()
|
|
3847
|
-
});
|
|
3848
|
-
var HookBindingSchema = z.object({
|
|
3849
|
-
hooks: z.record(z.string(), z.array(HookCommandSchema)).optional()
|
|
3850
|
-
});
|
|
3851
|
-
async function loadHookBindings(projectRoot, bindingPaths) {
|
|
3852
|
-
const result = {};
|
|
3853
|
-
if (!bindingPaths?.length) return result;
|
|
3854
|
-
const root = resolve(projectRoot);
|
|
3855
|
-
for (const bindingPath of bindingPaths) {
|
|
3856
|
-
const absPath = resolve(root, bindingPath);
|
|
3857
|
-
if (!existsSync(absPath)) continue;
|
|
3858
|
-
const raw = await readFile(absPath, "utf8");
|
|
3859
|
-
const parsed = HookBindingSchema.parse(parseYaml(raw) ?? {});
|
|
3860
|
-
if (!parsed.hooks) continue;
|
|
3861
|
-
for (const [hookName, commands] of Object.entries(parsed.hooks)) {
|
|
3862
|
-
const list = result[hookName] ?? [];
|
|
3863
|
-
for (const { command } of commands) {
|
|
3864
|
-
if (!list.includes(command)) list.push(command);
|
|
3865
|
-
}
|
|
3866
|
-
result[hookName] = list;
|
|
3867
|
-
}
|
|
3868
|
-
}
|
|
3869
|
-
return result;
|
|
3870
|
-
}
|
|
3871
|
-
function escapeRegex(value) {
|
|
3872
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3873
|
-
}
|
|
3874
|
-
function createManagedBlockRegex() {
|
|
3875
|
-
return new RegExp(
|
|
3876
|
-
`${escapeRegex(MANAGED_BLOCK_START)}[\\s\\S]*?${escapeRegex(MANAGED_BLOCK_END)}\\n?`,
|
|
3877
|
-
"g"
|
|
3878
|
-
);
|
|
3879
|
-
}
|
|
3880
|
-
function buildManagedBlock(blockContent) {
|
|
3881
|
-
return `${MANAGED_BLOCK_START}
|
|
3882
|
-
${blockContent.trimEnd()}
|
|
3883
|
-
${MANAGED_BLOCK_END}
|
|
3884
|
-
`;
|
|
3885
|
-
}
|
|
3886
|
-
function injectManagedBlock(existingContent, blockContent) {
|
|
3887
|
-
const managedBlock = buildManagedBlock(blockContent);
|
|
3888
|
-
const re = createManagedBlockRegex();
|
|
3889
|
-
if (re.test(existingContent)) {
|
|
3890
|
-
return existingContent.replace(createManagedBlockRegex(), managedBlock);
|
|
3891
|
-
}
|
|
3892
|
-
const trimmed = existingContent.replace(/\s+$/, "");
|
|
3893
|
-
if (trimmed.length === 0) {
|
|
3894
|
-
return `#!/bin/sh
|
|
3895
|
-
${managedBlock}`;
|
|
3896
|
-
}
|
|
3897
|
-
const separator = trimmed.endsWith("\n") ? "" : "\n";
|
|
3898
|
-
return `${trimmed}${separator}${managedBlock}`;
|
|
3899
|
-
}
|
|
3900
|
-
function removeManagedBlock(existingContent) {
|
|
3901
|
-
if (!existingContent.includes(MANAGED_BLOCK_START)) {
|
|
3902
|
-
return existingContent;
|
|
3903
|
-
}
|
|
3904
|
-
const withoutBlock = existingContent.replace(createManagedBlockRegex(), "");
|
|
3905
|
-
const meaningful = withoutBlock.split("\n").filter((line) => {
|
|
3906
|
-
const t = line.trim();
|
|
3907
|
-
return t.length > 0 && t !== "#!/bin/sh" && t !== "#!/bin/bash";
|
|
3908
|
-
});
|
|
3909
|
-
if (meaningful.length === 0) {
|
|
3910
|
-
return "";
|
|
3911
|
-
}
|
|
3912
|
-
return withoutBlock.replace(/\n{3,}/g, "\n\n").replace(/\s+$/, "\n");
|
|
3913
|
-
}
|
|
3914
|
-
function parseCursorHooksFile(raw) {
|
|
3915
|
-
if (!raw || !raw.trim()) {
|
|
3916
|
-
return { version: CURSOR_HOOKS_VERSION, hooks: {} };
|
|
3917
|
-
}
|
|
3918
|
-
const parsed = JSON.parse(raw);
|
|
3919
|
-
if (Array.isArray(parsed)) {
|
|
3920
|
-
return flatEntriesToFile(
|
|
3921
|
-
parsed.filter(
|
|
3922
|
-
(entry) => entry !== null && typeof entry === "object" && typeof entry.event === "string" && typeof entry.command === "string"
|
|
3923
|
-
)
|
|
3924
|
-
);
|
|
3925
|
-
}
|
|
3926
|
-
if (parsed && typeof parsed === "object") {
|
|
3927
|
-
const obj = parsed;
|
|
3928
|
-
const version = typeof obj.version === "number" ? obj.version : CURSOR_HOOKS_VERSION;
|
|
3929
|
-
const hooks = {};
|
|
3930
|
-
const rawHooks = obj.hooks;
|
|
3931
|
-
if (rawHooks && typeof rawHooks === "object" && !Array.isArray(rawHooks)) {
|
|
3932
|
-
for (const [event, commands] of Object.entries(rawHooks)) {
|
|
3933
|
-
if (Array.isArray(commands)) {
|
|
3934
|
-
hooks[event] = commands.filter(
|
|
3935
|
-
(c) => c !== null && typeof c === "object" && typeof c.command === "string"
|
|
3936
|
-
);
|
|
3937
|
-
}
|
|
3938
|
-
}
|
|
3939
|
-
}
|
|
3940
|
-
return { version, hooks };
|
|
3941
|
-
}
|
|
3942
|
-
return { version: CURSOR_HOOKS_VERSION, hooks: {} };
|
|
3943
|
-
}
|
|
3944
|
-
function serializeCursorHooksFile(file) {
|
|
3945
|
-
return JSON.stringify(file, null, 2) + "\n";
|
|
3946
|
-
}
|
|
3947
|
-
function flatEntriesToFile(entries) {
|
|
3948
|
-
return mergeCursorHooks({ version: CURSOR_HOOKS_VERSION, hooks: {} }, entries);
|
|
3949
|
-
}
|
|
3950
|
-
function mergeCursorHooks(existing, newEntries) {
|
|
3951
|
-
const hooks = {};
|
|
3952
|
-
for (const [event, commands] of Object.entries(existing.hooks)) {
|
|
3953
|
-
hooks[event] = commands.map((c) => ({ ...c }));
|
|
3954
|
-
}
|
|
3955
|
-
for (const entry of newEntries) {
|
|
3956
|
-
const { event, ...command } = entry;
|
|
3957
|
-
const list = hooks[event] ?? [];
|
|
3958
|
-
const idx = list.findIndex((c) => c.command === command.command);
|
|
3959
|
-
if (idx >= 0) {
|
|
3960
|
-
list[idx] = command;
|
|
3961
|
-
} else {
|
|
3962
|
-
list.push(command);
|
|
3963
|
-
}
|
|
3964
|
-
hooks[event] = list;
|
|
3965
|
-
}
|
|
3966
|
-
return { version: existing.version ?? CURSOR_HOOKS_VERSION, hooks };
|
|
3967
|
-
}
|
|
3968
|
-
function removeCursorHooks(existing, commands) {
|
|
3969
|
-
const removeSet = new Set(commands);
|
|
3970
|
-
const hooks = {};
|
|
3971
|
-
for (const [event, list] of Object.entries(existing.hooks)) {
|
|
3972
|
-
const filtered = list.filter((c) => !removeSet.has(c.command));
|
|
3973
|
-
if (filtered.length > 0) {
|
|
3974
|
-
hooks[event] = filtered;
|
|
3975
|
-
}
|
|
3976
|
-
}
|
|
3977
|
-
return { version: existing.version ?? CURSOR_HOOKS_VERSION, hooks };
|
|
3978
|
-
}
|
|
3979
|
-
function buildGitHookBlock(hookName, recorder, gateCommands = []) {
|
|
3980
|
-
const lines = [`${recorder} ${hookName} "$@" || true`];
|
|
3981
|
-
for (const command of gateCommands) {
|
|
3982
|
-
lines.push(`${command} || exit 1`);
|
|
3983
|
-
}
|
|
3984
|
-
return lines.join("\n");
|
|
3985
|
-
}
|
|
3986
|
-
function buildDefaultCursorHooks(recorder) {
|
|
3987
|
-
return [
|
|
3988
|
-
{ event: "beforeSubmitPrompt", command: `${recorder} beforeSubmitPrompt` },
|
|
3989
|
-
{ event: "afterShellExecution", command: `${recorder} afterShellExecution` }
|
|
3990
|
-
];
|
|
3991
|
-
}
|
|
3992
|
-
async function ensureParentDir(filePath) {
|
|
3993
|
-
await mkdir(dirname(filePath), { recursive: true });
|
|
3994
|
-
}
|
|
3995
|
-
async function readTextFileIfExists(filePath) {
|
|
3996
|
-
if (!existsSync(filePath)) return void 0;
|
|
3997
|
-
return readFile(filePath, "utf8");
|
|
3998
|
-
}
|
|
3999
|
-
async function writeGovernanceLock(projectRoot, entries) {
|
|
4000
|
-
const lockPath = join(projectRoot, GOVERNANCE_LOCK_PATH);
|
|
4001
|
-
const lock = {
|
|
4002
|
-
materialized_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4003
|
-
entries
|
|
4004
|
-
};
|
|
4005
|
-
await ensureParentDir(lockPath);
|
|
4006
|
-
await writeFile(lockPath, JSON.stringify(lock, null, 2) + "\n", "utf8");
|
|
4007
|
-
return GOVERNANCE_LOCK_PATH;
|
|
4008
|
-
}
|
|
4009
|
-
async function readGovernanceLock(projectRoot) {
|
|
4010
|
-
const lockPath = join(projectRoot, GOVERNANCE_LOCK_PATH);
|
|
4011
|
-
if (!existsSync(lockPath)) return void 0;
|
|
4012
|
-
const raw = await readFile(lockPath, "utf8");
|
|
4013
|
-
if (!raw.trim()) return void 0;
|
|
4014
|
-
return JSON.parse(raw);
|
|
4015
|
-
}
|
|
4016
|
-
async function materializeHooks(options) {
|
|
4017
|
-
const projectRoot = resolve(options.projectRoot);
|
|
4018
|
-
const result = { materialized: [], lockEntries: [] };
|
|
4019
|
-
const recorder = options.observabilityBinding?.recorder ?? DEFAULT_RECORDER;
|
|
4020
|
-
if (options.environments.git?.hooks?.length) {
|
|
4021
|
-
for (const hookName of options.environments.git.hooks) {
|
|
4022
|
-
const relPath = join(".git/hooks", hookName);
|
|
4023
|
-
const absPath = join(projectRoot, relPath);
|
|
4024
|
-
const blockContent = buildGitHookBlock(
|
|
4025
|
-
hookName,
|
|
4026
|
-
recorder,
|
|
4027
|
-
options.hookCommands?.[hookName]
|
|
4028
|
-
);
|
|
4029
|
-
const existing = await readTextFileIfExists(absPath) ?? "";
|
|
4030
|
-
const updated = injectManagedBlock(existing, blockContent);
|
|
4031
|
-
let action = "unchanged";
|
|
4032
|
-
if (!existsSync(absPath)) {
|
|
4033
|
-
action = "created";
|
|
4034
|
-
} else if (updated !== existing) {
|
|
4035
|
-
action = "updated";
|
|
4036
|
-
}
|
|
4037
|
-
if (action !== "unchanged") {
|
|
4038
|
-
await ensureParentDir(absPath);
|
|
4039
|
-
await writeFile(absPath, updated, "utf8");
|
|
4040
|
-
await chmod(absPath, 493);
|
|
4041
|
-
}
|
|
4042
|
-
result.materialized.push({ path: relPath, action });
|
|
4043
|
-
result.lockEntries.push({ path: relPath, type: "git-hook" });
|
|
4044
|
-
}
|
|
4045
|
-
}
|
|
4046
|
-
if (options.environments.cursor) {
|
|
4047
|
-
const rawHooksJsonValue = options.environments.cursor.hooks_json;
|
|
4048
|
-
const hooksJsonPath = rawHooksJsonValue ? resolve(projectRoot, rawHooksJsonValue) : join(projectRoot, DEFAULT_CURSOR_HOOKS_JSON);
|
|
4049
|
-
const relPath = hooksJsonPath.startsWith(projectRoot + "/") ? hooksJsonPath.slice(projectRoot.length + 1) : DEFAULT_CURSOR_HOOKS_JSON;
|
|
4050
|
-
const newEntries = buildDefaultCursorHooks(recorder);
|
|
4051
|
-
const existingRaw = await readTextFileIfExists(hooksJsonPath);
|
|
4052
|
-
const existing = parseCursorHooksFile(existingRaw);
|
|
4053
|
-
const merged = mergeCursorHooks(existing, newEntries);
|
|
4054
|
-
const serialized = serializeCursorHooksFile(merged);
|
|
4055
|
-
let action = "unchanged";
|
|
4056
|
-
if (!existsSync(hooksJsonPath)) {
|
|
4057
|
-
action = "created";
|
|
4058
|
-
} else if (serialized !== existingRaw) {
|
|
4059
|
-
action = "updated";
|
|
4060
|
-
}
|
|
4061
|
-
if (action !== "unchanged") {
|
|
4062
|
-
await ensureParentDir(hooksJsonPath);
|
|
4063
|
-
await writeFile(hooksJsonPath, serialized, "utf8");
|
|
4064
|
-
}
|
|
4065
|
-
result.materialized.push({ path: relPath, action });
|
|
4066
|
-
result.lockEntries.push({ path: relPath, type: "cursor-hook" });
|
|
4067
|
-
}
|
|
4068
|
-
if (result.lockEntries.length > 0) {
|
|
4069
|
-
const lockExisted = existsSync(join(projectRoot, GOVERNANCE_LOCK_PATH));
|
|
4070
|
-
await writeGovernanceLock(projectRoot, result.lockEntries);
|
|
4071
|
-
result.materialized.push({
|
|
4072
|
-
path: GOVERNANCE_LOCK_PATH,
|
|
4073
|
-
action: lockExisted ? "updated" : "created"
|
|
4074
|
-
});
|
|
4075
|
-
result.lockEntries.push({ path: GOVERNANCE_LOCK_PATH, type: "generated" });
|
|
4076
|
-
}
|
|
4077
|
-
return result;
|
|
4078
|
-
}
|
|
4079
|
-
async function unmaterializeHooks(projectRoot, lockEntries) {
|
|
4080
|
-
const root = resolve(projectRoot);
|
|
4081
|
-
for (const entry of lockEntries) {
|
|
4082
|
-
if (entry.type === "generated") {
|
|
4083
|
-
const absPath = join(root, entry.path);
|
|
4084
|
-
if (existsSync(absPath)) {
|
|
4085
|
-
await writeFile(absPath, "", "utf8");
|
|
4086
|
-
}
|
|
4087
|
-
continue;
|
|
4088
|
-
}
|
|
4089
|
-
if (entry.type === "git-hook") {
|
|
4090
|
-
const absPath = join(root, entry.path);
|
|
4091
|
-
const existing = await readTextFileIfExists(absPath);
|
|
4092
|
-
if (existing === void 0) continue;
|
|
4093
|
-
const updated = removeManagedBlock(existing);
|
|
4094
|
-
await writeFile(absPath, updated, "utf8");
|
|
4095
|
-
continue;
|
|
4096
|
-
}
|
|
4097
|
-
if (entry.type === "cursor-hook") {
|
|
4098
|
-
const absPath = join(root, entry.path);
|
|
4099
|
-
const existingRaw = await readTextFileIfExists(absPath);
|
|
4100
|
-
if (existingRaw === void 0) continue;
|
|
4101
|
-
const existing = parseCursorHooksFile(existingRaw);
|
|
4102
|
-
const commandsToRemove = buildDefaultCursorHooks(DEFAULT_RECORDER).map((h) => h.command);
|
|
4103
|
-
const updated = removeCursorHooks(existing, commandsToRemove);
|
|
4104
|
-
await writeFile(absPath, serializeCursorHooksFile(updated), "utf8");
|
|
4105
|
-
}
|
|
4106
|
-
}
|
|
4107
|
-
const lockPath = join(root, GOVERNANCE_LOCK_PATH);
|
|
4108
|
-
if (existsSync(lockPath)) {
|
|
4109
|
-
await writeFile(lockPath, "", "utf8");
|
|
4110
|
-
}
|
|
4111
|
-
}
|
|
4112
|
-
async function copyCLIBinary(srcPath, projectRoot, destRelPath = DEFAULT_BINARY_DEST) {
|
|
4113
|
-
const dstPath = join(projectRoot, destRelPath);
|
|
4114
|
-
const srcContent = await readFile(srcPath);
|
|
4115
|
-
const srcHash = createHash("sha256").update(srcContent).digest("hex");
|
|
4116
|
-
if (existsSync(dstPath)) {
|
|
4117
|
-
const dstContent = await readFile(dstPath);
|
|
4118
|
-
const dstHash = createHash("sha256").update(dstContent).digest("hex");
|
|
4119
|
-
if (srcHash === dstHash) {
|
|
4120
|
-
return { path: destRelPath, action: "unchanged" };
|
|
4121
|
-
}
|
|
4122
|
-
await writeFile(dstPath, srcContent);
|
|
4123
|
-
await chmod(dstPath, 493);
|
|
4124
|
-
return { path: destRelPath, action: "updated" };
|
|
4125
|
-
}
|
|
4126
|
-
await ensureParentDir(dstPath);
|
|
4127
|
-
await writeFile(dstPath, srcContent);
|
|
4128
|
-
await chmod(dstPath, 493);
|
|
4129
|
-
return { path: destRelPath, action: "created" };
|
|
4130
|
-
}
|
|
4131
|
-
var SCAFFOLD_PROJECT_YAML = `schema: aaac/project/0.1
|
|
4132
|
-
|
|
4133
|
-
# Uncomment and configure to enable git hook governance:
|
|
4134
|
-
#
|
|
4135
|
-
# environments:
|
|
4136
|
-
# git:
|
|
4137
|
-
# hooks: [pre-commit, pre-push, post-commit]
|
|
4138
|
-
# cursor:
|
|
4139
|
-
# hooks_json: .cursor/hooks.json
|
|
4140
|
-
#
|
|
4141
|
-
# bindings:
|
|
4142
|
-
# observability:
|
|
4143
|
-
# event_mapping: ./bindings/observability.yaml
|
|
4144
|
-
# recorder: aaac-observ
|
|
4145
|
-
# hooks:
|
|
4146
|
-
# # Each file declares gate commands per git hook; a non-zero exit
|
|
4147
|
-
# # blocks the commit/push. Only hooks listed in environments.git.hooks
|
|
4148
|
-
# # are materialized.
|
|
4149
|
-
# - ./bindings/git.yaml
|
|
4150
|
-
`;
|
|
4151
|
-
|
|
4152
|
-
// src/cli/handlers.ts
|
|
3814
|
+
import { stringify as stringifyYaml } from "yaml";
|
|
4153
3815
|
function formatError(err, file) {
|
|
4154
3816
|
if (err instanceof ComponentParseError) {
|
|
4155
3817
|
return err.message;
|
|
@@ -4177,10 +3839,10 @@ function resolveComponentPath(file) {
|
|
|
4177
3839
|
if (!file) {
|
|
4178
3840
|
fail("Error: component file path is required");
|
|
4179
3841
|
}
|
|
4180
|
-
return
|
|
3842
|
+
return resolve(file);
|
|
4181
3843
|
}
|
|
4182
3844
|
function defaultOutputDir(componentPath) {
|
|
4183
|
-
return
|
|
3845
|
+
return join(dirname(componentPath), "generated");
|
|
4184
3846
|
}
|
|
4185
3847
|
function buildIntrospectionDump(ir) {
|
|
4186
3848
|
const operations = {};
|
|
@@ -4215,10 +3877,10 @@ var handleCompile = async (file, options, parentOpts) => {
|
|
|
4215
3877
|
const ir = await compileComponentFile(componentPath);
|
|
4216
3878
|
const json = JSON.stringify(ir, null, 2);
|
|
4217
3879
|
if (options.output) {
|
|
4218
|
-
await
|
|
3880
|
+
await writeFile(resolve(options.output), `${json}
|
|
4219
3881
|
`, "utf-8");
|
|
4220
3882
|
if (!parentOpts.quiet) {
|
|
4221
|
-
process.stdout.write(`Wrote IR to ${
|
|
3883
|
+
process.stdout.write(`Wrote IR to ${resolve(options.output)}
|
|
4222
3884
|
`);
|
|
4223
3885
|
}
|
|
4224
3886
|
return;
|
|
@@ -4233,7 +3895,7 @@ async function resolveEmbeddedDslData(ir, componentPath) {
|
|
|
4233
3895
|
if (!ir.embeddedDslDir || !ir.implementation) {
|
|
4234
3896
|
return void 0;
|
|
4235
3897
|
}
|
|
4236
|
-
const implPath =
|
|
3898
|
+
const implPath = resolve(dirname(componentPath), ir.implementation);
|
|
4237
3899
|
const { resolve: resolveDsl } = await import("agent-contracts");
|
|
4238
3900
|
const dslResult = await resolveDsl(implPath);
|
|
4239
3901
|
return dslResult.data;
|
|
@@ -4252,7 +3914,7 @@ function splitGeneratedFiles(files) {
|
|
|
4252
3914
|
}
|
|
4253
3915
|
var handleGenerate = async (file, options, parentOpts) => {
|
|
4254
3916
|
const componentPath = resolveComponentPath(file);
|
|
4255
|
-
const outputDir =
|
|
3917
|
+
const outputDir = resolve(options.outputDir ?? defaultOutputDir(componentPath));
|
|
4256
3918
|
const dryRun = Boolean(options.dryRun);
|
|
4257
3919
|
try {
|
|
4258
3920
|
const ir = await compileComponentFile(componentPath);
|
|
@@ -4277,10 +3939,10 @@ var handleGenerate = async (file, options, parentOpts) => {
|
|
|
4277
3939
|
}
|
|
4278
3940
|
}
|
|
4279
3941
|
for (const generated of embedded) {
|
|
4280
|
-
const embeddedDir =
|
|
3942
|
+
const embeddedDir = resolve(dirname(componentPath), generated.targetDir);
|
|
4281
3943
|
const action = generated.overwrite ? "write" : "create";
|
|
4282
3944
|
process.stdout.write(
|
|
4283
|
-
` ${action}: ${
|
|
3945
|
+
` ${action}: ${join(embeddedDir, generated.path)} (embedded DSL)
|
|
4284
3946
|
`
|
|
4285
3947
|
);
|
|
4286
3948
|
}
|
|
@@ -4289,10 +3951,10 @@ var handleGenerate = async (file, options, parentOpts) => {
|
|
|
4289
3951
|
}
|
|
4290
3952
|
const result = await writeGeneratedFiles(main, outputDir);
|
|
4291
3953
|
for (const generated of embedded) {
|
|
4292
|
-
const embeddedDir =
|
|
4293
|
-
await
|
|
4294
|
-
await
|
|
4295
|
-
result.written.push(
|
|
3954
|
+
const embeddedDir = resolve(dirname(componentPath), generated.targetDir);
|
|
3955
|
+
await mkdir(embeddedDir, { recursive: true });
|
|
3956
|
+
await writeFile(join(embeddedDir, generated.path), generated.content, "utf-8");
|
|
3957
|
+
result.written.push(join(generated.targetDir, generated.path));
|
|
4296
3958
|
}
|
|
4297
3959
|
if (!parentOpts.quiet) {
|
|
4298
3960
|
if (result.written.length > 0) {
|
|
@@ -4322,7 +3984,7 @@ var handleGenerate = async (file, options, parentOpts) => {
|
|
|
4322
3984
|
};
|
|
4323
3985
|
var handleValidate = async (file, options, parentOpts) => {
|
|
4324
3986
|
const componentPath = resolveComponentPath(file);
|
|
4325
|
-
const basePath =
|
|
3987
|
+
const basePath = dirname(componentPath);
|
|
4326
3988
|
try {
|
|
4327
3989
|
const dsl = await parseComponentFile(componentPath);
|
|
4328
3990
|
const ir = compileComponent(dsl, { basePath });
|
|
@@ -4356,24 +4018,24 @@ var handleIntrospect = async (file, options, _parentOpts) => {
|
|
|
4356
4018
|
};
|
|
4357
4019
|
var DEFAULT_PROJECT_YAML = "project.yaml";
|
|
4358
4020
|
var handleInit = async (projectRoot, options, parentOpts) => {
|
|
4359
|
-
const root =
|
|
4021
|
+
const root = resolve(projectRoot ?? ".");
|
|
4360
4022
|
const quiet = Boolean(parentOpts.quiet);
|
|
4361
|
-
const projectYamlPath =
|
|
4362
|
-
const srcBinary =
|
|
4023
|
+
const projectYamlPath = join(root, options.projectYaml ?? DEFAULT_PROJECT_YAML);
|
|
4024
|
+
const srcBinary = resolve(options.binaryPath ?? process.argv[1]);
|
|
4363
4025
|
const binaryResult = await copyCLIBinary(srcBinary, root);
|
|
4364
4026
|
if (!quiet && binaryResult.action !== "unchanged") {
|
|
4365
4027
|
process.stdout.write(` ${binaryResult.action}: ${binaryResult.path}
|
|
4366
4028
|
`);
|
|
4367
4029
|
}
|
|
4368
|
-
if (!
|
|
4369
|
-
await
|
|
4030
|
+
if (!existsSync(projectYamlPath)) {
|
|
4031
|
+
await writeFile(projectYamlPath, SCAFFOLD_PROJECT_YAML, "utf8");
|
|
4370
4032
|
if (!quiet) {
|
|
4371
4033
|
process.stdout.write(` created: ${DEFAULT_PROJECT_YAML}
|
|
4372
4034
|
`);
|
|
4373
4035
|
}
|
|
4374
4036
|
}
|
|
4375
|
-
const gitDir =
|
|
4376
|
-
if (!
|
|
4037
|
+
const gitDir = join(root, ".git");
|
|
4038
|
+
if (!existsSync(gitDir)) {
|
|
4377
4039
|
process.stderr.write(
|
|
4378
4040
|
`Warning: .git/ not found in ${root}; skipping hook materialization
|
|
4379
4041
|
`
|
|
@@ -4414,6 +4076,7 @@ var handleInit = async (projectRoot, options, parentOpts) => {
|
|
|
4414
4076
|
projectRoot: root,
|
|
4415
4077
|
environments: config.environments,
|
|
4416
4078
|
observabilityBinding: config.bindings?.observability,
|
|
4079
|
+
artifactContracts: config.artifacts,
|
|
4417
4080
|
hookCommands
|
|
4418
4081
|
});
|
|
4419
4082
|
if (!quiet) {
|
|
@@ -4428,16 +4091,16 @@ var handleInit = async (projectRoot, options, parentOpts) => {
|
|
|
4428
4091
|
}
|
|
4429
4092
|
};
|
|
4430
4093
|
var handleUpdate = async (projectRoot, options, parentOpts) => {
|
|
4431
|
-
const root =
|
|
4094
|
+
const root = resolve(projectRoot ?? ".");
|
|
4432
4095
|
const quiet = Boolean(parentOpts.quiet);
|
|
4433
|
-
const projectYamlPath =
|
|
4434
|
-
if (!
|
|
4096
|
+
const projectYamlPath = join(root, options.projectYaml ?? DEFAULT_PROJECT_YAML);
|
|
4097
|
+
if (!existsSync(projectYamlPath)) {
|
|
4435
4098
|
fail(
|
|
4436
4099
|
`Error: ${DEFAULT_PROJECT_YAML} not found at ${root}. Run 'aaac init' first.`
|
|
4437
4100
|
);
|
|
4438
4101
|
}
|
|
4439
|
-
const gitDir =
|
|
4440
|
-
if (!
|
|
4102
|
+
const gitDir = join(root, ".git");
|
|
4103
|
+
if (!existsSync(gitDir)) {
|
|
4441
4104
|
process.stderr.write(
|
|
4442
4105
|
`Warning: .git/ not found in ${root}; skipping hook materialization
|
|
4443
4106
|
`
|
|
@@ -4464,6 +4127,7 @@ var handleUpdate = async (projectRoot, options, parentOpts) => {
|
|
|
4464
4127
|
projectRoot: root,
|
|
4465
4128
|
environments: config.environments,
|
|
4466
4129
|
observabilityBinding: config.bindings?.observability,
|
|
4130
|
+
artifactContracts: config.artifacts,
|
|
4467
4131
|
hookCommands
|
|
4468
4132
|
});
|
|
4469
4133
|
if (!quiet) {
|
|
@@ -4476,13 +4140,13 @@ var handleUpdate = async (projectRoot, options, parentOpts) => {
|
|
|
4476
4140
|
}
|
|
4477
4141
|
};
|
|
4478
4142
|
var handleUninstall = async (projectRoot, _options, parentOpts) => {
|
|
4479
|
-
const root =
|
|
4143
|
+
const root = resolve(projectRoot ?? ".");
|
|
4480
4144
|
const quiet = Boolean(parentOpts.quiet);
|
|
4481
4145
|
const lock = await readGovernanceLock(root);
|
|
4482
4146
|
if (!lock || lock.entries.length === 0) {
|
|
4483
4147
|
if (!quiet) {
|
|
4484
4148
|
process.stdout.write(
|
|
4485
|
-
`Nothing to uninstall (no governance lock found at ${
|
|
4149
|
+
`Nothing to uninstall (no governance lock found at ${join(root, GOVERNANCE_LOCK_PATH)})
|
|
4486
4150
|
`
|
|
4487
4151
|
);
|
|
4488
4152
|
}
|
|
@@ -4505,9 +4169,9 @@ var handlers = {
|
|
|
4505
4169
|
};
|
|
4506
4170
|
|
|
4507
4171
|
// src/cli/index.ts
|
|
4508
|
-
var __dirname =
|
|
4172
|
+
var __dirname = dirname2(fileURLToPath(import.meta.url));
|
|
4509
4173
|
var pkg = JSON.parse(
|
|
4510
|
-
readFileSync(
|
|
4174
|
+
readFileSync(resolve2(__dirname, "../../package.json"), "utf8")
|
|
4511
4175
|
);
|
|
4512
4176
|
var program2 = createProgram(handlers, pkg.version);
|
|
4513
4177
|
await program2.parseAsync();
|