yuangs 3.20.0 ā 3.22.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/README.md +2 -0
- package/dist/agent/AgentRuntime.js +32 -7
- package/dist/agent/AgentRuntime.js.map +1 -1
- package/dist/agent/context.d.ts +5 -0
- package/dist/agent/context.js +24 -4
- package/dist/agent/context.js.map +1 -1
- package/dist/agent/governance.js +10 -0
- package/dist/agent/governance.js.map +1 -1
- package/dist/agent/llm.js +6 -2
- package/dist/agent/llm.js.map +1 -1
- package/dist/agent/prompt.js +6 -6
- package/dist/agent/prompt.js.map +1 -1
- package/dist/cli.js +34 -4
- package/dist/cli.js.map +1 -1
- package/dist/commands/handleAIChat.js +31 -1
- package/dist/commands/handleAIChat.js.map +1 -1
- package/dist/commands/preferencesCommands.d.ts +2 -0
- package/dist/commands/preferencesCommands.js +232 -0
- package/dist/commands/preferencesCommands.js.map +1 -0
- package/package.json +1 -1
- package/dist/Capabilities.js +0 -39
- package/dist/Governance.d.ts +0 -9
- package/dist/Governance.js +0 -25
- package/dist/Kernel.d.ts +0 -13
- package/dist/Kernel.js +0 -53
- package/dist/agent/AgentPipeline.d.ts +0 -5
- package/dist/agent/AgentPipeline.js +0 -105
- package/dist/agent/fsm.d.ts +0 -23
- package/dist/agent/fsm.js +0 -95
- package/dist/agent/intent.d.ts +0 -2
- package/dist/agent/intent.js +0 -28
- package/dist/agent/interpret.d.ts +0 -3
- package/dist/agent/interpret.js +0 -39
- package/dist/agent/loop.d.ts +0 -21
- package/dist/agent/loop.js +0 -214
- package/dist/agent/plan.d.ts +0 -13
- package/dist/agent/plan.js +0 -3
- package/dist/agent/planExecutor.d.ts +0 -10
- package/dist/agent/planExecutor.js +0 -74
- package/dist/agent/record.d.ts +0 -14
- package/dist/agent/record.js +0 -20
- package/dist/agent/replay.d.ts +0 -2
- package/dist/agent/replay.js +0 -25
- package/dist/commands/chatHistoryStorage.d.ts +0 -4
- package/dist/commands/chatHistoryStorage.js +0 -54
- package/dist/governance/GovernanceEngine.d.ts +0 -20
- package/dist/governance/GovernanceEngine.js +0 -95
- package/dist/governance/GovernedAction.d.ts +0 -107
- package/dist/governance/GovernedAction.js +0 -9
- package/dist/governance/actions/CodeChangeAction.d.ts +0 -28
- package/dist/governance/actions/CodeChangeAction.js +0 -139
- package/dist/governance/capability/token.d.ts +0 -45
- package/dist/governance/capability/token.js +0 -103
- package/dist/governance/commands/diffEdit.d.ts +0 -2
- package/dist/governance/commands/diffEdit.js +0 -245
- package/dist/governance/execution/sandbox.d.ts +0 -12
- package/dist/governance/execution/sandbox.js +0 -76
- package/dist/governance/fsm/stateMachine.d.ts +0 -40
- package/dist/governance/fsm/stateMachine.js +0 -93
- package/dist/governance/index.d.ts +0 -9
- package/dist/governance/index.js +0 -26
- package/dist/governance/review/diffParser.d.ts +0 -12
- package/dist/governance/review/diffParser.js +0 -61
- package/dist/governance/review/render.d.ts +0 -5
- package/dist/governance/review/render.js +0 -58
- package/dist/governance/storage/store.d.ts +0 -16
- package/dist/governance/storage/store.js +0 -110
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.createDiffEditCommand = createDiffEditCommand;
|
|
7
|
-
const commander_1 = require("commander");
|
|
8
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
-
const fs_1 = __importDefault(require("fs"));
|
|
10
|
-
const child_process_1 = require("child_process");
|
|
11
|
-
const GovernanceEngine_1 = require("../GovernanceEngine");
|
|
12
|
-
const CodeChangeAction_1 = require("../actions/CodeChangeAction");
|
|
13
|
-
const diffParser_1 = require("../review/diffParser");
|
|
14
|
-
const render_1 = require("../review/render");
|
|
15
|
-
const sandbox_1 = require("../execution/sandbox");
|
|
16
|
-
const store_1 = require("../storage/store");
|
|
17
|
-
const engine = new GovernanceEngine_1.GovernanceEngine();
|
|
18
|
-
(0, store_1.auditActions)((0, store_1.loadActions)());
|
|
19
|
-
function collectGitResult(commitHash) {
|
|
20
|
-
try {
|
|
21
|
-
const output = (0, child_process_1.execSync)(`git show --stat --oneline ${commitHash}`, {
|
|
22
|
-
encoding: "utf-8",
|
|
23
|
-
});
|
|
24
|
-
const files = [];
|
|
25
|
-
let insertions = 0;
|
|
26
|
-
let deletions = 0;
|
|
27
|
-
for (const line of output.split("\n")) {
|
|
28
|
-
const fileMatch = line.match(/^\s*(.+?)\s+\|\s+\d+/);
|
|
29
|
-
if (fileMatch) {
|
|
30
|
-
files.push(fileMatch[1].trim());
|
|
31
|
-
}
|
|
32
|
-
const insMatch = line.match(/(\d+)\s+insertions?\(\+\)/);
|
|
33
|
-
const delMatch = line.match(/(\d+)\s+deletions?\(-\)/);
|
|
34
|
-
if (insMatch)
|
|
35
|
-
insertions = parseInt(insMatch[1], 10);
|
|
36
|
-
if (delMatch)
|
|
37
|
-
deletions = parseInt(delMatch[1], 10);
|
|
38
|
-
}
|
|
39
|
-
return {
|
|
40
|
-
commits: commitHash ? 1 : 0,
|
|
41
|
-
files,
|
|
42
|
-
insertions,
|
|
43
|
-
deletions,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
catch {
|
|
47
|
-
return {
|
|
48
|
-
commits: 1,
|
|
49
|
-
files: [],
|
|
50
|
-
insertions: 0,
|
|
51
|
-
deletions: 0,
|
|
52
|
-
warning: "Unable to derive git stats",
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
class GitExecutor {
|
|
57
|
-
async applyDiff(diff) {
|
|
58
|
-
// execSync is imported at top level
|
|
59
|
-
try {
|
|
60
|
-
(0, child_process_1.execSync)("git apply --index", {
|
|
61
|
-
input: diff,
|
|
62
|
-
stdio: "pipe",
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
catch (error) {
|
|
66
|
-
throw new Error(`Failed to apply diff: ${error}`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
async readFile(path) {
|
|
70
|
-
return fs_1.default.promises.readFile(path, "utf-8");
|
|
71
|
-
}
|
|
72
|
-
async writeFile(path, content) {
|
|
73
|
-
await fs_1.default.promises.writeFile(path, content, "utf-8");
|
|
74
|
-
}
|
|
75
|
-
async deleteFile(path) {
|
|
76
|
-
await fs_1.default.promises.unlink(path);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
function createDiffEditCommand() {
|
|
80
|
-
const program = new commander_1.Command("diff-edit");
|
|
81
|
-
program
|
|
82
|
-
.description("Governed code change CLI - review before executing")
|
|
83
|
-
.version("1.0.0");
|
|
84
|
-
program
|
|
85
|
-
.command("propose <diff-file>")
|
|
86
|
-
.option("-r, --rationale <text>", "Why this change is needed")
|
|
87
|
-
.action(async (diffFile, options) => {
|
|
88
|
-
if (!fs_1.default.existsSync(diffFile)) {
|
|
89
|
-
console.error(chalk_1.default.red(`Diff file not found: ${diffFile}`));
|
|
90
|
-
process.exit(1);
|
|
91
|
-
}
|
|
92
|
-
const diff = fs_1.default.readFileSync(diffFile, "utf-8");
|
|
93
|
-
const rationale = options.rationale || "Manual diff submission";
|
|
94
|
-
const files = (0, diffParser_1.extractFilesFromDiff)(diff);
|
|
95
|
-
const payload = { files, diff };
|
|
96
|
-
const action = CodeChangeAction_1.CodeChangeAction.create(payload, rationale, "cli", "manual-" + Date.now());
|
|
97
|
-
action.propose();
|
|
98
|
-
const actions = (0, store_1.loadActions)();
|
|
99
|
-
actions[action.id] = action;
|
|
100
|
-
(0, store_1.saveActions)(actions);
|
|
101
|
-
console.log(chalk_1.default.green(`[PROPOSED] ${action.id}`));
|
|
102
|
-
console.log(chalk_1.default.cyan("Files:"));
|
|
103
|
-
for (const f of files) {
|
|
104
|
-
console.log(` - ${chalk_1.default.yellow(f)}`);
|
|
105
|
-
}
|
|
106
|
-
console.log(`\n${chalk_1.default.bold("Rationale:")} ${rationale}`);
|
|
107
|
-
});
|
|
108
|
-
program
|
|
109
|
-
.command("list")
|
|
110
|
-
.description("List all proposed actions")
|
|
111
|
-
.action(() => {
|
|
112
|
-
const actions = (0, store_1.loadActions)();
|
|
113
|
-
console.log(chalk_1.default.bold("\n" + "=".repeat(60)));
|
|
114
|
-
console.log(chalk_1.default.bold("Actions"));
|
|
115
|
-
console.log(chalk_1.default.bold("=".repeat(60)) + "\n");
|
|
116
|
-
const table = [];
|
|
117
|
-
for (const [id, a] of Object.entries(actions)) {
|
|
118
|
-
table.push({
|
|
119
|
-
id,
|
|
120
|
-
kind: a.kind,
|
|
121
|
-
state: a.state,
|
|
122
|
-
rationale: a.rationale.substring(0, 50),
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
console.table(table);
|
|
126
|
-
});
|
|
127
|
-
program
|
|
128
|
-
.command("approve <id>")
|
|
129
|
-
.description("Review and approve a proposed action")
|
|
130
|
-
.action(async (id) => {
|
|
131
|
-
const actions = (0, store_1.loadActions)();
|
|
132
|
-
const action = actions[id];
|
|
133
|
-
if (!action) {
|
|
134
|
-
console.error(chalk_1.default.red(`Action not found: ${id}`));
|
|
135
|
-
process.exit(1);
|
|
136
|
-
}
|
|
137
|
-
const files = (0, diffParser_1.parseUnifiedDiff)(action.payload.diff);
|
|
138
|
-
(0, render_1.renderDiffForReview)(files, action.rationale);
|
|
139
|
-
const { level, warnings } = (0, diffParser_1.assessRisk)(files);
|
|
140
|
-
(0, render_1.renderRiskAssessment)(level, warnings);
|
|
141
|
-
const approved = await (0, render_1.promptForApproval)();
|
|
142
|
-
if (!approved) {
|
|
143
|
-
console.log(chalk_1.default.red("\n[REJECTED] Approval aborted"));
|
|
144
|
-
action.state = "REJECTED";
|
|
145
|
-
(0, store_1.saveActions)(actions);
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
action.state = "APPROVED";
|
|
149
|
-
(0, store_1.saveActions)(actions);
|
|
150
|
-
console.log(chalk_1.default.green(`\n[APPROVED] ${id}`));
|
|
151
|
-
});
|
|
152
|
-
program
|
|
153
|
-
.command("exec <id>")
|
|
154
|
-
.description("Execute an approved action")
|
|
155
|
-
.action(async (id) => {
|
|
156
|
-
const actions = (0, store_1.loadActions)();
|
|
157
|
-
const action = actions[id];
|
|
158
|
-
if (!action) {
|
|
159
|
-
console.error(chalk_1.default.red(`Action not found: ${id}`));
|
|
160
|
-
process.exit(1);
|
|
161
|
-
}
|
|
162
|
-
if (action.state !== "APPROVED") {
|
|
163
|
-
console.error(chalk_1.default.red(`Action not approved (state: ${action.state})`));
|
|
164
|
-
process.exit(1);
|
|
165
|
-
}
|
|
166
|
-
console.log(chalk_1.default.cyan(`\n[EXECUTING] ${id}...`));
|
|
167
|
-
const snapshot = (0, sandbox_1.createSnapshot)();
|
|
168
|
-
const executor = new GitExecutor();
|
|
169
|
-
const ctx = { executor, snapshot: snapshot.id };
|
|
170
|
-
try {
|
|
171
|
-
// === PRE-EXEC: Snapshot Validation ===
|
|
172
|
-
await executor.applyDiff(action.payload.diff);
|
|
173
|
-
const changedFiles = (0, sandbox_1.getChangedFiles)();
|
|
174
|
-
(0, sandbox_1.assertNoExtraChanges)(action.payload.files, changedFiles);
|
|
175
|
-
const snapshotResult = {
|
|
176
|
-
changedFiles,
|
|
177
|
-
unexpectedFiles: changedFiles.filter((f) => !action.payload.files.includes(f)),
|
|
178
|
-
matchedBySandbox: changedFiles.length === action.payload.files.length,
|
|
179
|
-
};
|
|
180
|
-
// === EXEC: Commit ===
|
|
181
|
-
(0, sandbox_1.commitChanges)(`EXECUTED action ${id}`, snapshot.id);
|
|
182
|
-
const commitHash = (0, child_process_1.execSync)("git rev-parse HEAD", {
|
|
183
|
-
encoding: "utf-8",
|
|
184
|
-
}).trim();
|
|
185
|
-
action.state = "EXECUTED";
|
|
186
|
-
action.executedAt = Date.now();
|
|
187
|
-
(0, store_1.saveActions)(actions);
|
|
188
|
-
// === POST-EXEC: Reporting ===
|
|
189
|
-
const gitResult = collectGitResult(commitHash);
|
|
190
|
-
console.log(chalk_1.default.green("\n[EXECUTED]"));
|
|
191
|
-
console.log(chalk_1.default.green(`Action ID: ${id}`));
|
|
192
|
-
console.log(chalk_1.default.cyan("\nSnapshot Verification (pre-commit):"));
|
|
193
|
-
console.log(chalk_1.default.cyan(` - Files changed: ${snapshotResult.changedFiles.length}`));
|
|
194
|
-
for (const f of snapshotResult.changedFiles) {
|
|
195
|
-
console.log(chalk_1.default.cyan(` - ${f}`));
|
|
196
|
-
}
|
|
197
|
-
if (snapshotResult.unexpectedFiles.length > 0) {
|
|
198
|
-
console.log(chalk_1.default.yellow(" - Unexpected files:"));
|
|
199
|
-
for (const f of snapshotResult.unexpectedFiles) {
|
|
200
|
-
console.log(chalk_1.default.yellow(` - ${f}`));
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
console.log(chalk_1.default.cyan(` - Status: ${snapshotResult.matchedBySandbox ? "ā
MATCHED" : "ā ļø DEVIATION"}`));
|
|
204
|
-
console.log(chalk_1.default.cyan("\nGit Result:"));
|
|
205
|
-
console.log(chalk_1.default.cyan(` - Commit: ${commitHash.substring(0, 7)}`));
|
|
206
|
-
console.log(chalk_1.default.cyan(` - Files changed: ${gitResult.files.length}`));
|
|
207
|
-
console.log(chalk_1.default.cyan(` - Insertions: ${gitResult.insertions}`));
|
|
208
|
-
console.log(chalk_1.default.cyan(` - Deletions: ${gitResult.deletions}`));
|
|
209
|
-
console.log(chalk_1.default.green("\nStatus:"));
|
|
210
|
-
console.log(chalk_1.default.green(" ā
EXECUTED (validated + committed)"));
|
|
211
|
-
}
|
|
212
|
-
catch (error) {
|
|
213
|
-
console.error(chalk_1.default.red(`\n[FAILED] ${error}`));
|
|
214
|
-
console.log(chalk_1.default.yellow("\nRolling back to snapshot..."));
|
|
215
|
-
(0, sandbox_1.rollbackToSnapshot)(snapshot.id);
|
|
216
|
-
action.state = "REJECTED";
|
|
217
|
-
(0, store_1.saveActions)(actions);
|
|
218
|
-
console.log(chalk_1.default.cyan("\nRolled back successfully"));
|
|
219
|
-
process.exit(1);
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
program
|
|
223
|
-
.command("status <id>")
|
|
224
|
-
.description("Show status of an action")
|
|
225
|
-
.action((id) => {
|
|
226
|
-
const actions = (0, store_1.loadActions)();
|
|
227
|
-
const action = actions[id];
|
|
228
|
-
if (!action) {
|
|
229
|
-
console.error(chalk_1.default.red(`Action not found: ${id}`));
|
|
230
|
-
process.exit(1);
|
|
231
|
-
}
|
|
232
|
-
console.log(chalk_1.default.bold("\n" + "=".repeat(60)));
|
|
233
|
-
console.log(chalk_1.default.bold(`Action: ${id}`));
|
|
234
|
-
console.log(chalk_1.default.bold("=".repeat(60)) + "\n");
|
|
235
|
-
console.log(`${chalk_1.default.bold("Kind:")} ${action.kind}`);
|
|
236
|
-
console.log(`${chalk_1.default.bold("State:")} ${action.state}`);
|
|
237
|
-
console.log(`${chalk_1.default.bold("Rationale:")} ${action.rationale}`);
|
|
238
|
-
console.log(`${chalk_1.default.bold("Updated:")} ${new Date(action.updatedAt).toLocaleString()}`);
|
|
239
|
-
if (action.state === "EXECUTED" && action.executedAt) {
|
|
240
|
-
console.log(`${chalk_1.default.bold("Executed:")} ${new Date(action.executedAt).toLocaleString()}`);
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
return program;
|
|
244
|
-
}
|
|
245
|
-
//# sourceMappingURL=diffEdit.js.map
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export interface ExecutionSnapshot {
|
|
2
|
-
id: string;
|
|
3
|
-
commitHash: string;
|
|
4
|
-
timestamp: number;
|
|
5
|
-
isClean: boolean;
|
|
6
|
-
}
|
|
7
|
-
export declare function createSnapshot(): ExecutionSnapshot;
|
|
8
|
-
export declare function verifySnapshot(snapshotId: string): boolean;
|
|
9
|
-
export declare function rollbackToSnapshot(snapshotId: string): void;
|
|
10
|
-
export declare function commitChanges(message: string, snapshotId: string): void;
|
|
11
|
-
export declare function getChangedFiles(): string[];
|
|
12
|
-
export declare function assertNoExtraChanges(approvedFiles: string[], actualFiles: string[]): void;
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createSnapshot = createSnapshot;
|
|
4
|
-
exports.verifySnapshot = verifySnapshot;
|
|
5
|
-
exports.rollbackToSnapshot = rollbackToSnapshot;
|
|
6
|
-
exports.commitChanges = commitChanges;
|
|
7
|
-
exports.getChangedFiles = getChangedFiles;
|
|
8
|
-
exports.assertNoExtraChanges = assertNoExtraChanges;
|
|
9
|
-
const child_process_1 = require("child_process");
|
|
10
|
-
function createSnapshot() {
|
|
11
|
-
const statusOutput = (0, child_process_1.execSync)("git status --porcelain", {
|
|
12
|
-
encoding: "utf-8",
|
|
13
|
-
}).trim();
|
|
14
|
-
const isClean = statusOutput.length === 0;
|
|
15
|
-
if (!isClean) {
|
|
16
|
-
throw new Error("Cannot create snapshot: working tree is dirty. Commit or stash changes first.");
|
|
17
|
-
}
|
|
18
|
-
const commitHash = (0, child_process_1.execSync)("git rev-parse HEAD", {
|
|
19
|
-
encoding: "utf-8",
|
|
20
|
-
}).trim();
|
|
21
|
-
return {
|
|
22
|
-
id: commitHash,
|
|
23
|
-
commitHash,
|
|
24
|
-
timestamp: Date.now(),
|
|
25
|
-
isClean,
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
function verifySnapshot(snapshotId) {
|
|
29
|
-
try {
|
|
30
|
-
const current = (0, child_process_1.execSync)("git rev-parse HEAD", {
|
|
31
|
-
encoding: "utf-8",
|
|
32
|
-
}).trim();
|
|
33
|
-
return current === snapshotId;
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
function rollbackToSnapshot(snapshotId) {
|
|
40
|
-
try {
|
|
41
|
-
(0, child_process_1.execSync)(`git reset --hard ${snapshotId}`, {
|
|
42
|
-
stdio: "inherit",
|
|
43
|
-
});
|
|
44
|
-
console.log(`Rolled back to snapshot ${snapshotId}`);
|
|
45
|
-
}
|
|
46
|
-
catch (error) {
|
|
47
|
-
throw new Error(`Failed to rollback to snapshot ${snapshotId}: ${error}`);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
function commitChanges(message, snapshotId) {
|
|
51
|
-
try {
|
|
52
|
-
(0, child_process_1.execSync)(`git commit -am "${message}"`, {
|
|
53
|
-
stdio: "inherit",
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
catch (error) {
|
|
57
|
-
throw new Error(`Failed to commit changes: ${error}`);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
function getChangedFiles() {
|
|
61
|
-
const output = (0, child_process_1.execSync)("git diff --name-only HEAD", {
|
|
62
|
-
encoding: "utf-8",
|
|
63
|
-
});
|
|
64
|
-
return output
|
|
65
|
-
.trim()
|
|
66
|
-
.split("\n")
|
|
67
|
-
.filter((f) => f.length > 0);
|
|
68
|
-
}
|
|
69
|
-
function assertNoExtraChanges(approvedFiles, actualFiles) {
|
|
70
|
-
const approvedSet = new Set(approvedFiles);
|
|
71
|
-
const extraFiles = actualFiles.filter((f) => !approvedSet.has(f));
|
|
72
|
-
if (extraFiles.length > 0) {
|
|
73
|
-
throw new Error(`Governance violation: execution modified undeclared files:\n${extraFiles.join("\n")}`);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
//# sourceMappingURL=sandbox.js.map
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { GovernanceState } from "../GovernedAction";
|
|
2
|
-
/**
|
|
3
|
-
* Throw governance violation if transition is not permitted
|
|
4
|
-
*/
|
|
5
|
-
export declare function assertTransition(from: GovernanceState, to: GovernanceState): void;
|
|
6
|
-
/**
|
|
7
|
-
* Check if a transition is valid (without throwing)
|
|
8
|
-
*/
|
|
9
|
-
export declare function canTransition(from: GovernanceState, to: GovernanceState): boolean;
|
|
10
|
-
/**
|
|
11
|
-
* Get all possible next states from current state
|
|
12
|
-
*/
|
|
13
|
-
export declare function getNextStates(from: GovernanceState): GovernanceState[];
|
|
14
|
-
/**
|
|
15
|
-
* Validate that a state is valid
|
|
16
|
-
*/
|
|
17
|
-
export declare function isValidState(state: string): state is GovernanceState;
|
|
18
|
-
/**
|
|
19
|
-
* State machine transition history entry
|
|
20
|
-
*/
|
|
21
|
-
export interface TransitionHistoryEntry {
|
|
22
|
-
from: GovernanceState;
|
|
23
|
-
to: GovernanceState;
|
|
24
|
-
timestamp: number;
|
|
25
|
-
reason?: string;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* State machine for tracking governance state transitions
|
|
29
|
-
* Enforces constitutional invariants
|
|
30
|
-
*/
|
|
31
|
-
export declare class GovernanceStateMachine {
|
|
32
|
-
private currentState;
|
|
33
|
-
private history;
|
|
34
|
-
constructor(initialState: GovernanceState);
|
|
35
|
-
get current(): GovernanceState;
|
|
36
|
-
get transitionHistory(): TransitionHistoryEntry[];
|
|
37
|
-
transition(to: GovernanceState, reason?: string): void;
|
|
38
|
-
isTerminal(): boolean;
|
|
39
|
-
canProceedTo(state: GovernanceState): boolean;
|
|
40
|
-
}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GovernanceStateMachine = void 0;
|
|
4
|
-
exports.assertTransition = assertTransition;
|
|
5
|
-
exports.canTransition = canTransition;
|
|
6
|
-
exports.getNextStates = getNextStates;
|
|
7
|
-
exports.isValidState = isValidState;
|
|
8
|
-
/**
|
|
9
|
-
* Only these state transitions are legally permitted
|
|
10
|
-
* Any other transition is a governance violation
|
|
11
|
-
*/
|
|
12
|
-
const ALLOWED_TRANSITIONS = {
|
|
13
|
-
DRAFT: ["PROPOSED"],
|
|
14
|
-
PROPOSED: ["APPROVED", "REJECTED"],
|
|
15
|
-
APPROVED: ["EXECUTED"],
|
|
16
|
-
EXECUTED: ["OBSERVED"],
|
|
17
|
-
OBSERVED: ["VERIFIED"],
|
|
18
|
-
VERIFIED: [],
|
|
19
|
-
REJECTED: [],
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* Throw governance violation if transition is not permitted
|
|
23
|
-
*/
|
|
24
|
-
function assertTransition(from, to) {
|
|
25
|
-
const allowed = ALLOWED_TRANSITIONS[from].includes(to);
|
|
26
|
-
if (!allowed) {
|
|
27
|
-
throw new Error(`Governance violation: illegal state transition ${from} ā ${to}`);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Check if a transition is valid (without throwing)
|
|
32
|
-
*/
|
|
33
|
-
function canTransition(from, to) {
|
|
34
|
-
return ALLOWED_TRANSITIONS[from].includes(to);
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Get all possible next states from current state
|
|
38
|
-
*/
|
|
39
|
-
function getNextStates(from) {
|
|
40
|
-
return [...ALLOWED_TRANSITIONS[from]];
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Validate that a state is valid
|
|
44
|
-
*/
|
|
45
|
-
function isValidState(state) {
|
|
46
|
-
return [
|
|
47
|
-
"DRAFT",
|
|
48
|
-
"PROPOSED",
|
|
49
|
-
"APPROVED",
|
|
50
|
-
"EXECUTED",
|
|
51
|
-
"OBSERVED",
|
|
52
|
-
"VERIFIED",
|
|
53
|
-
"REJECTED",
|
|
54
|
-
].includes(state);
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* State machine for tracking governance state transitions
|
|
58
|
-
* Enforces constitutional invariants
|
|
59
|
-
*/
|
|
60
|
-
class GovernanceStateMachine {
|
|
61
|
-
currentState;
|
|
62
|
-
history = [];
|
|
63
|
-
constructor(initialState) {
|
|
64
|
-
if (!isValidState(initialState)) {
|
|
65
|
-
throw new Error(`Invalid initial state: ${initialState}`);
|
|
66
|
-
}
|
|
67
|
-
this.currentState = initialState;
|
|
68
|
-
}
|
|
69
|
-
get current() {
|
|
70
|
-
return this.currentState;
|
|
71
|
-
}
|
|
72
|
-
get transitionHistory() {
|
|
73
|
-
return [...this.history];
|
|
74
|
-
}
|
|
75
|
-
transition(to, reason) {
|
|
76
|
-
assertTransition(this.currentState, to);
|
|
77
|
-
this.history.push({
|
|
78
|
-
from: this.currentState,
|
|
79
|
-
to,
|
|
80
|
-
timestamp: Date.now(),
|
|
81
|
-
reason,
|
|
82
|
-
});
|
|
83
|
-
this.currentState = to;
|
|
84
|
-
}
|
|
85
|
-
isTerminal() {
|
|
86
|
-
return this.currentState === "VERIFIED" || this.currentState === "REJECTED";
|
|
87
|
-
}
|
|
88
|
-
canProceedTo(state) {
|
|
89
|
-
return canTransition(this.currentState, state);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
exports.GovernanceStateMachine = GovernanceStateMachine;
|
|
93
|
-
//# sourceMappingURL=stateMachine.js.map
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export * from "./GovernedAction";
|
|
2
|
-
export * from "./GovernanceEngine";
|
|
3
|
-
export * from "./actions/CodeChangeAction";
|
|
4
|
-
export * from "./fsm/stateMachine";
|
|
5
|
-
export * from "./review/diffParser";
|
|
6
|
-
export * from "./review/render";
|
|
7
|
-
export * from "./execution/sandbox";
|
|
8
|
-
export * from "./capability/token";
|
|
9
|
-
export * from "./storage/store";
|
package/dist/governance/index.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./GovernedAction"), exports);
|
|
18
|
-
__exportStar(require("./GovernanceEngine"), exports);
|
|
19
|
-
__exportStar(require("./actions/CodeChangeAction"), exports);
|
|
20
|
-
__exportStar(require("./fsm/stateMachine"), exports);
|
|
21
|
-
__exportStar(require("./review/diffParser"), exports);
|
|
22
|
-
__exportStar(require("./review/render"), exports);
|
|
23
|
-
__exportStar(require("./execution/sandbox"), exports);
|
|
24
|
-
__exportStar(require("./capability/token"), exports);
|
|
25
|
-
__exportStar(require("./storage/store"), exports);
|
|
26
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export interface DiffFile {
|
|
2
|
-
file: string;
|
|
3
|
-
additions: number;
|
|
4
|
-
deletions: number;
|
|
5
|
-
hunks: string[];
|
|
6
|
-
}
|
|
7
|
-
export declare function parseUnifiedDiff(diff: string): DiffFile[];
|
|
8
|
-
export declare function extractFilesFromDiff(diff: string): string[];
|
|
9
|
-
export declare function assessRisk(files: DiffFile[]): {
|
|
10
|
-
level: "low" | "medium" | "high";
|
|
11
|
-
warnings: string[];
|
|
12
|
-
};
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseUnifiedDiff = parseUnifiedDiff;
|
|
4
|
-
exports.extractFilesFromDiff = extractFilesFromDiff;
|
|
5
|
-
exports.assessRisk = assessRisk;
|
|
6
|
-
function parseUnifiedDiff(diff) {
|
|
7
|
-
const files = [];
|
|
8
|
-
let current = null;
|
|
9
|
-
for (const line of diff.split("\n")) {
|
|
10
|
-
if (line.startsWith("diff --git")) {
|
|
11
|
-
if (current) {
|
|
12
|
-
files.push(current);
|
|
13
|
-
}
|
|
14
|
-
const match = line.match(/b\/(.+)$/);
|
|
15
|
-
const file = match ? match[1] : "unknown";
|
|
16
|
-
current = { file, additions: 0, deletions: 0, hunks: [] };
|
|
17
|
-
}
|
|
18
|
-
else if (!current) {
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
else if (line.startsWith("+") && !line.startsWith("+++")) {
|
|
22
|
-
current.additions++;
|
|
23
|
-
}
|
|
24
|
-
else if (line.startsWith("-") && !line.startsWith("---")) {
|
|
25
|
-
current.deletions++;
|
|
26
|
-
}
|
|
27
|
-
else if (line.startsWith("@@")) {
|
|
28
|
-
current.hunks.push(line);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
if (current) {
|
|
32
|
-
files.push(current);
|
|
33
|
-
}
|
|
34
|
-
return files;
|
|
35
|
-
}
|
|
36
|
-
function extractFilesFromDiff(diff) {
|
|
37
|
-
const files = [];
|
|
38
|
-
const filePattern = /^\+\+\+ b\/(.+)$/gm;
|
|
39
|
-
for (const match of diff.matchAll(filePattern)) {
|
|
40
|
-
files.push(match[1]);
|
|
41
|
-
}
|
|
42
|
-
return files;
|
|
43
|
-
}
|
|
44
|
-
function assessRisk(files) {
|
|
45
|
-
const warnings = [];
|
|
46
|
-
const totalLines = files.reduce((sum, f) => sum + f.additions + f.deletions, 0);
|
|
47
|
-
if (totalLines > 300) {
|
|
48
|
-
warnings.push(`Large changeset: ${totalLines} lines`);
|
|
49
|
-
}
|
|
50
|
-
if (files.length > 10) {
|
|
51
|
-
warnings.push(`Many files touched: ${files.length}`);
|
|
52
|
-
}
|
|
53
|
-
if (totalLines > 1000) {
|
|
54
|
-
return { level: "high", warnings };
|
|
55
|
-
}
|
|
56
|
-
if (totalLines > 300 || files.length > 10) {
|
|
57
|
-
return { level: "medium", warnings };
|
|
58
|
-
}
|
|
59
|
-
return { level: "low", warnings };
|
|
60
|
-
}
|
|
61
|
-
//# sourceMappingURL=diffParser.js.map
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { DiffFile } from "./diffParser";
|
|
2
|
-
export declare function renderSummary(files: DiffFile[]): void;
|
|
3
|
-
export declare function renderDiffForReview(files: DiffFile[], rationale: string): void;
|
|
4
|
-
export declare function renderRiskAssessment(level: "low" | "medium" | "high", warnings: string[]): void;
|
|
5
|
-
export declare function promptForApproval(): Promise<boolean>;
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.renderSummary = renderSummary;
|
|
7
|
-
exports.renderDiffForReview = renderDiffForReview;
|
|
8
|
-
exports.renderRiskAssessment = renderRiskAssessment;
|
|
9
|
-
exports.promptForApproval = promptForApproval;
|
|
10
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
-
function renderSummary(files) {
|
|
12
|
-
console.log(chalk_1.default.bold("\nDiff Summary\n"));
|
|
13
|
-
for (const f of files) {
|
|
14
|
-
console.log(`${chalk_1.default.cyan(f.file)} ` +
|
|
15
|
-
chalk_1.default.green(`+${f.additions}`) +
|
|
16
|
-
" " +
|
|
17
|
-
chalk_1.default.red(`-${f.deletions}`));
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
function renderDiffForReview(files, rationale) {
|
|
21
|
-
console.log(chalk_1.default.bold.cyan("=".repeat(60)));
|
|
22
|
-
console.log(chalk_1.default.bold.blue("Proposed Code Change"));
|
|
23
|
-
console.log(chalk_1.default.bold.cyan("=".repeat(60)));
|
|
24
|
-
console.log(`${chalk_1.default.bold("Rationale:")} ${rationale}\n`);
|
|
25
|
-
for (const f of files) {
|
|
26
|
-
console.log(chalk_1.default.yellow(`\nš ${f.file}`));
|
|
27
|
-
console.log(` ${chalk_1.default.green("+")} ${f.additions} lines added`);
|
|
28
|
-
console.log(` ${chalk_1.default.red("-")} ${f.deletions} lines deleted`);
|
|
29
|
-
}
|
|
30
|
-
console.log(chalk_1.default.bold.cyan("\n" + "=".repeat(60)));
|
|
31
|
-
}
|
|
32
|
-
function renderRiskAssessment(level, warnings) {
|
|
33
|
-
const levelColor = {
|
|
34
|
-
low: chalk_1.default.green,
|
|
35
|
-
medium: chalk_1.default.yellow,
|
|
36
|
-
high: chalk_1.default.red,
|
|
37
|
-
};
|
|
38
|
-
console.log(chalk_1.default.bold(`\n${levelColor[level]}(\u26a0\ufe0f Risk Level: ${level.toUpperCase()})`));
|
|
39
|
-
if (warnings.length > 0) {
|
|
40
|
-
for (const w of warnings) {
|
|
41
|
-
console.log(chalk_1.default.yellow(` - ${w}`));
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
function promptForApproval() {
|
|
46
|
-
const readline = require("readline");
|
|
47
|
-
const rl = readline.createInterface({
|
|
48
|
-
input: process.stdin,
|
|
49
|
-
output: process.stdout,
|
|
50
|
-
});
|
|
51
|
-
return new Promise((resolve) => {
|
|
52
|
-
rl.question(chalk_1.default.bold.yellow('\nType "YES" to approve, anything else to reject: '), (answer) => {
|
|
53
|
-
rl.close();
|
|
54
|
-
resolve(answer.trim() === "YES");
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
//# sourceMappingURL=render.js.map
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export interface SerializedAction {
|
|
2
|
-
id: string;
|
|
3
|
-
kind: string;
|
|
4
|
-
state: string;
|
|
5
|
-
payload: any;
|
|
6
|
-
rationale: string;
|
|
7
|
-
provenance: any;
|
|
8
|
-
updatedAt: number;
|
|
9
|
-
executedAt?: number;
|
|
10
|
-
}
|
|
11
|
-
export declare function ensureDataDir(): void;
|
|
12
|
-
export declare function atomicWrite(filePath: string, data: string): void;
|
|
13
|
-
export declare function loadActions(): Record<string, SerializedAction>;
|
|
14
|
-
export declare function saveActions(actions: Record<string, SerializedAction>): void;
|
|
15
|
-
export declare function deserializeActions(data: Record<string, any>): Record<string, SerializedAction>;
|
|
16
|
-
export declare function auditActions(actions: Record<string, SerializedAction>): void;
|