@iamem/amem 0.1.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/LICENSE +21 -0
- package/README.md +534 -0
- package/dist/activity.d.ts +27 -0
- package/dist/activity.js +202 -0
- package/dist/api/routes.d.ts +31 -0
- package/dist/api/routes.js +1345 -0
- package/dist/attest.d.ts +52 -0
- package/dist/attest.js +192 -0
- package/dist/backup-schedule.d.ts +25 -0
- package/dist/backup-schedule.js +216 -0
- package/dist/capture.d.ts +34 -0
- package/dist/capture.js +257 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +1007 -0
- package/dist/context.d.ts +46 -0
- package/dist/context.js +334 -0
- package/dist/crypto.d.ts +39 -0
- package/dist/crypto.js +166 -0
- package/dist/db.d.ts +192 -0
- package/dist/db.js +666 -0
- package/dist/draft-quality.d.ts +19 -0
- package/dist/draft-quality.js +85 -0
- package/dist/embed.d.ts +76 -0
- package/dist/embed.js +331 -0
- package/dist/estimate.d.ts +32 -0
- package/dist/estimate.js +69 -0
- package/dist/freshness.d.ts +15 -0
- package/dist/freshness.js +93 -0
- package/dist/hook.d.ts +16 -0
- package/dist/hook.js +177 -0
- package/dist/hygiene-schedule.d.ts +28 -0
- package/dist/hygiene-schedule.js +221 -0
- package/dist/hygiene.d.ts +61 -0
- package/dist/hygiene.js +196 -0
- package/dist/install/claude.d.ts +6 -0
- package/dist/install/claude.js +69 -0
- package/dist/install/cursor.d.ts +7 -0
- package/dist/install/cursor.js +80 -0
- package/dist/install/hosts.d.ts +21 -0
- package/dist/install/hosts.js +186 -0
- package/dist/install/skills.d.ts +8 -0
- package/dist/install/skills.js +67 -0
- package/dist/it-pack.d.ts +20 -0
- package/dist/it-pack.js +84 -0
- package/dist/kinds.d.ts +18 -0
- package/dist/kinds.js +106 -0
- package/dist/license.d.ts +48 -0
- package/dist/license.js +172 -0
- package/dist/mcp.d.ts +40 -0
- package/dist/mcp.js +435 -0
- package/dist/paths.d.ts +11 -0
- package/dist/paths.js +55 -0
- package/dist/personal.d.ts +7 -0
- package/dist/personal.js +44 -0
- package/dist/platforms.d.ts +11 -0
- package/dist/platforms.js +32 -0
- package/dist/policy.d.ts +46 -0
- package/dist/policy.js +254 -0
- package/dist/prefs.d.ts +6 -0
- package/dist/prefs.js +11 -0
- package/dist/proposal.d.ts +90 -0
- package/dist/proposal.js +376 -0
- package/dist/publish.d.ts +28 -0
- package/dist/publish.js +57 -0
- package/dist/remember-contract.d.ts +23 -0
- package/dist/remember-contract.js +117 -0
- package/dist/repo-identity.d.ts +15 -0
- package/dist/repo-identity.js +82 -0
- package/dist/rules-sync.d.ts +7 -0
- package/dist/rules-sync.js +47 -0
- package/dist/savings-export.d.ts +49 -0
- package/dist/savings-export.js +141 -0
- package/dist/scan.d.ts +16 -0
- package/dist/scan.js +109 -0
- package/dist/search.d.ts +25 -0
- package/dist/search.js +150 -0
- package/dist/service.d.ts +20 -0
- package/dist/service.js +254 -0
- package/dist/shop.d.ts +9 -0
- package/dist/shop.js +15 -0
- package/dist/ui/server.d.ts +21 -0
- package/dist/ui/server.js +268 -0
- package/dist/vault.d.ts +25 -0
- package/dist/vault.js +42 -0
- package/dist/workspace-setup.d.ts +8 -0
- package/dist/workspace-setup.js +55 -0
- package/docs/agent-install-prompt.md +41 -0
- package/docs/backlog.md +59 -0
- package/docs/enterprise-endpoint.md +98 -0
- package/docs/license.md +54 -0
- package/docs/npm-release.md +38 -0
- package/docs/remember-contract.md +42 -0
- package/package.json +64 -0
- package/scripts/mdm-offboard.sh +14 -0
- package/skills/amem-bootstrap/SKILL.md +83 -0
- package/skills/amem-update-working-memory/SKILL.md +54 -0
- package/templates/cursor-rule.mdc +23 -0
- package/templates/mdm/co.amem.managed.plist +33 -0
- package/templates/policy.deny-default.toml +20 -0
- package/templates/policy.example.toml +22 -0
- package/ui-static/app.js +3966 -0
- package/ui-static/index.html +178 -0
- package/ui-static/orbit.js +389 -0
- package/ui-static/styles.css +2411 -0
package/dist/policy.js
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { platform as osPlatform } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { amemHome } from "./paths.js";
|
|
5
|
+
import { KNOWN_PLATFORMS } from "./platforms.js";
|
|
6
|
+
/** Built-in secret hygiene — always active; policy patterns extend these. */
|
|
7
|
+
export const BUILTIN_DENY_CLAIM_PATTERNS = [
|
|
8
|
+
"api[_-]?key",
|
|
9
|
+
"-----BEGIN",
|
|
10
|
+
"password\\s*=",
|
|
11
|
+
"secret\\s*=",
|
|
12
|
+
"private[_-]?key",
|
|
13
|
+
"aws[_-]?secret",
|
|
14
|
+
"xox[baprs]-",
|
|
15
|
+
];
|
|
16
|
+
export const DEFAULT_POLICY = {
|
|
17
|
+
telemetry: false,
|
|
18
|
+
ui_enabled: true,
|
|
19
|
+
ui_bind: "127.0.0.1",
|
|
20
|
+
allow_export: true,
|
|
21
|
+
allowed_platforms: KNOWN_PLATFORMS.map((p) => p.id),
|
|
22
|
+
allowed_remote_hosts: [],
|
|
23
|
+
deny_claim_patterns: [],
|
|
24
|
+
auto_apply_kinds: [],
|
|
25
|
+
};
|
|
26
|
+
let cached = null;
|
|
27
|
+
export function clearPolicyCache() {
|
|
28
|
+
cached = null;
|
|
29
|
+
}
|
|
30
|
+
export function systemPolicyPath() {
|
|
31
|
+
if (process.env.AMEM_SYSTEM_POLICY)
|
|
32
|
+
return process.env.AMEM_SYSTEM_POLICY;
|
|
33
|
+
if (osPlatform() === "win32") {
|
|
34
|
+
const base = process.env.ProgramData ?? "C:\\ProgramData";
|
|
35
|
+
return join(base, "amem", "policy.toml");
|
|
36
|
+
}
|
|
37
|
+
return "/etc/amem/policy.toml";
|
|
38
|
+
}
|
|
39
|
+
export function userPolicyPath() {
|
|
40
|
+
return join(amemHome(), "policy.toml");
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Minimal TOML subset for amem policy files:
|
|
44
|
+
* booleans, quoted strings, and string arrays. Comments (#) and blank lines ok.
|
|
45
|
+
*/
|
|
46
|
+
export function parsePolicyToml(raw) {
|
|
47
|
+
const out = {};
|
|
48
|
+
const lines = raw.split(/\r?\n/);
|
|
49
|
+
for (let i = 0; i < lines.length; i++) {
|
|
50
|
+
const line = lines[i].replace(/#.*$/, "").trim();
|
|
51
|
+
if (!line)
|
|
52
|
+
continue;
|
|
53
|
+
const eq = line.indexOf("=");
|
|
54
|
+
if (eq <= 0) {
|
|
55
|
+
throw new Error(`Invalid policy line ${i + 1}: ${line}`);
|
|
56
|
+
}
|
|
57
|
+
const key = line.slice(0, eq).trim();
|
|
58
|
+
const valueRaw = line.slice(eq + 1).trim();
|
|
59
|
+
switch (key) {
|
|
60
|
+
case "telemetry":
|
|
61
|
+
case "ui_enabled":
|
|
62
|
+
case "allow_export":
|
|
63
|
+
out[key] = parseBool(valueRaw, key, i + 1);
|
|
64
|
+
break;
|
|
65
|
+
case "ui_bind":
|
|
66
|
+
out.ui_bind = parseString(valueRaw, key, i + 1);
|
|
67
|
+
break;
|
|
68
|
+
case "allowed_platforms":
|
|
69
|
+
case "allowed_remote_hosts":
|
|
70
|
+
case "deny_claim_patterns":
|
|
71
|
+
case "auto_apply_kinds":
|
|
72
|
+
out[key] = parseStringArray(valueRaw, key, i + 1);
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
throw new Error(`Unknown policy key on line ${i + 1}: ${key}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
function parseBool(raw, key, line) {
|
|
81
|
+
if (raw === "true")
|
|
82
|
+
return true;
|
|
83
|
+
if (raw === "false")
|
|
84
|
+
return false;
|
|
85
|
+
throw new Error(`Policy ${key} on line ${line} must be true or false`);
|
|
86
|
+
}
|
|
87
|
+
function parseString(raw, key, line) {
|
|
88
|
+
const m = /^"(.*)"$/.exec(raw);
|
|
89
|
+
if (!m)
|
|
90
|
+
throw new Error(`Policy ${key} on line ${line} must be a quoted string`);
|
|
91
|
+
return m[1].replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
92
|
+
}
|
|
93
|
+
function parseStringArray(raw, key, line) {
|
|
94
|
+
if (raw === "[]")
|
|
95
|
+
return [];
|
|
96
|
+
const m = /^\[(.*)\]$/.exec(raw);
|
|
97
|
+
if (!m)
|
|
98
|
+
throw new Error(`Policy ${key} on line ${line} must be a string array`);
|
|
99
|
+
const inner = m[1].trim();
|
|
100
|
+
if (!inner)
|
|
101
|
+
return [];
|
|
102
|
+
const items = [];
|
|
103
|
+
const re = /"((?:\\.|[^"\\])*)"/g;
|
|
104
|
+
let match;
|
|
105
|
+
while ((match = re.exec(inner))) {
|
|
106
|
+
items.push(match[1].replace(/\\"/g, '"').replace(/\\\\/g, "\\"));
|
|
107
|
+
}
|
|
108
|
+
if (items.length === 0) {
|
|
109
|
+
throw new Error(`Policy ${key} on line ${line} must contain quoted strings`);
|
|
110
|
+
}
|
|
111
|
+
return items;
|
|
112
|
+
}
|
|
113
|
+
function readPartial(path) {
|
|
114
|
+
try {
|
|
115
|
+
if (!existsSync(path) || !statSync(path).isFile())
|
|
116
|
+
return {};
|
|
117
|
+
const partial = parsePolicyToml(readFileSync(path, "utf8"));
|
|
118
|
+
return { partial };
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function mergePolicy(base, overlay) {
|
|
125
|
+
return {
|
|
126
|
+
telemetry: overlay.telemetry ?? base.telemetry,
|
|
127
|
+
ui_enabled: overlay.ui_enabled ?? base.ui_enabled,
|
|
128
|
+
ui_bind: overlay.ui_bind ?? base.ui_bind,
|
|
129
|
+
allow_export: overlay.allow_export ?? base.allow_export,
|
|
130
|
+
allowed_platforms: overlay.allowed_platforms ?? base.allowed_platforms,
|
|
131
|
+
allowed_remote_hosts: overlay.allowed_remote_hosts ?? base.allowed_remote_hosts,
|
|
132
|
+
deny_claim_patterns: overlay.deny_claim_patterns ?? base.deny_claim_patterns,
|
|
133
|
+
auto_apply_kinds: overlay.auto_apply_kinds ?? base.auto_apply_kinds,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Load effective policy.
|
|
138
|
+
* Precedence (later wins): defaults → user (~/.amem) → system (/etc/amem) → AMEM_POLICY_PATH.
|
|
139
|
+
* MDM/system always overrides user for enterprise lock-down.
|
|
140
|
+
*/
|
|
141
|
+
export function loadPolicy(forceReload = false) {
|
|
142
|
+
if (cached && !forceReload)
|
|
143
|
+
return cached;
|
|
144
|
+
let policy = { ...DEFAULT_POLICY, deny_claim_patterns: [...DEFAULT_POLICY.deny_claim_patterns] };
|
|
145
|
+
const sources = [
|
|
146
|
+
{ path: "(defaults)", role: "defaults", applied: true },
|
|
147
|
+
];
|
|
148
|
+
const userPath = userPolicyPath();
|
|
149
|
+
const userRead = readPartial(userPath);
|
|
150
|
+
if (userRead.error) {
|
|
151
|
+
sources.push({ path: userPath, role: "user", applied: false, error: userRead.error });
|
|
152
|
+
}
|
|
153
|
+
else if (userRead.partial) {
|
|
154
|
+
policy = mergePolicy(policy, userRead.partial);
|
|
155
|
+
sources.push({ path: userPath, role: "user", applied: true });
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
sources.push({ path: userPath, role: "user", applied: false });
|
|
159
|
+
}
|
|
160
|
+
const systemPath = systemPolicyPath();
|
|
161
|
+
const systemRead = readPartial(systemPath);
|
|
162
|
+
if (systemRead.error) {
|
|
163
|
+
sources.push({ path: systemPath, role: "system", applied: false, error: systemRead.error });
|
|
164
|
+
}
|
|
165
|
+
else if (systemRead.partial) {
|
|
166
|
+
policy = mergePolicy(policy, systemRead.partial);
|
|
167
|
+
sources.push({ path: systemPath, role: "system", applied: true });
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
sources.push({ path: systemPath, role: "system", applied: false });
|
|
171
|
+
}
|
|
172
|
+
const envPath = process.env.AMEM_POLICY_PATH;
|
|
173
|
+
if (envPath) {
|
|
174
|
+
const envRead = readPartial(envPath);
|
|
175
|
+
if (envRead.error) {
|
|
176
|
+
sources.push({ path: envPath, role: "env", applied: false, error: envRead.error });
|
|
177
|
+
}
|
|
178
|
+
else if (envRead.partial) {
|
|
179
|
+
policy = mergePolicy(policy, envRead.partial);
|
|
180
|
+
sources.push({ path: envPath, role: "env", applied: true });
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
sources.push({
|
|
184
|
+
path: envPath,
|
|
185
|
+
role: "env",
|
|
186
|
+
applied: false,
|
|
187
|
+
error: "AMEM_POLICY_PATH set but file missing",
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// Privacy hard-stops: never allow non-loopback UI or enabling telemetry via policy.
|
|
192
|
+
if (policy.ui_bind !== "127.0.0.1" && policy.ui_bind !== "localhost") {
|
|
193
|
+
policy = { ...policy, ui_bind: "127.0.0.1" };
|
|
194
|
+
}
|
|
195
|
+
policy = { ...policy, telemetry: false };
|
|
196
|
+
// A policy file we could not read must not silently relax into permissive defaults:
|
|
197
|
+
// an admin deploying deny-default would otherwise get allow_export back on a typo.
|
|
198
|
+
// Clamp only the exfiltration-relevant knobs — blanking allowed_platforms here would
|
|
199
|
+
// brick every host instead of protecting anything.
|
|
200
|
+
if (sources.some((s) => s.error)) {
|
|
201
|
+
policy = { ...policy, allow_export: false, auto_apply_kinds: [] };
|
|
202
|
+
}
|
|
203
|
+
cached = { policy, sources };
|
|
204
|
+
return cached;
|
|
205
|
+
}
|
|
206
|
+
export function effectiveDenyPatterns(policy = loadPolicy().policy) {
|
|
207
|
+
return [...BUILTIN_DENY_CLAIM_PATTERNS, ...policy.deny_claim_patterns];
|
|
208
|
+
}
|
|
209
|
+
export function compiledDenyPatterns(policy) {
|
|
210
|
+
return effectiveDenyPatterns(policy).map((p) => {
|
|
211
|
+
try {
|
|
212
|
+
return new RegExp(p, "i");
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
throw new Error(`Invalid deny_claim_patterns regex: ${p}`);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
export function assertPlatformAllowed(platform, policy = loadPolicy().policy) {
|
|
220
|
+
if (policy.allowed_platforms.length === 0)
|
|
221
|
+
return;
|
|
222
|
+
if (!policy.allowed_platforms.includes(platform)) {
|
|
223
|
+
throw new Error(`Platform "${platform}" blocked by policy.allowed_platforms (${policy.allowed_platforms.join(", ")})`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
export function assertRemoteAllowed(remoteUrl, policy = loadPolicy().policy) {
|
|
227
|
+
if (policy.allowed_remote_hosts.length === 0)
|
|
228
|
+
return;
|
|
229
|
+
if (!remoteUrl) {
|
|
230
|
+
throw new Error("Policy requires a git remote matching allowed_remote_hosts (none detected)");
|
|
231
|
+
}
|
|
232
|
+
const normalized = remoteUrl.toLowerCase().replace(/^https?:\/\//, "");
|
|
233
|
+
const ok = policy.allowed_remote_hosts.some((host) => {
|
|
234
|
+
const h = host.toLowerCase().replace(/^https?:\/\//, "").replace(/\/+$/, "");
|
|
235
|
+
return normalized === h || normalized.startsWith(`${h}/`) || normalized.startsWith(`${h}`);
|
|
236
|
+
});
|
|
237
|
+
if (!ok) {
|
|
238
|
+
throw new Error(`Remote "${remoteUrl}" not in policy.allowed_remote_hosts (${policy.allowed_remote_hosts.join(", ")})`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
export function assertExportAllowed(policy = loadPolicy().policy) {
|
|
242
|
+
if (!policy.allow_export) {
|
|
243
|
+
throw new Error("Export blocked by policy (allow_export = false)");
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
export function assertUiAllowed(policy = loadPolicy().policy) {
|
|
247
|
+
if (!policy.ui_enabled) {
|
|
248
|
+
throw new Error("Local UI disabled by policy (ui_enabled = false)");
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/** Unused today — kept so attest / docs can prove the knob exists and is forced off. */
|
|
252
|
+
export function telemetryEnabled(policy = loadPolicy().policy) {
|
|
253
|
+
return policy.telemetry === true;
|
|
254
|
+
}
|
package/dist/prefs.d.ts
ADDED
package/dist/prefs.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getMeta, setMeta } from "./db.js";
|
|
2
|
+
export const META_AUTO_APPLY_ALL = "auto_apply_all";
|
|
3
|
+
export function isAutoApplyAll() {
|
|
4
|
+
return getMeta(META_AUTO_APPLY_ALL) === "1";
|
|
5
|
+
}
|
|
6
|
+
export function setAutoApplyAll(on) {
|
|
7
|
+
setMeta(META_AUTO_APPLY_ALL, on ? "1" : "0");
|
|
8
|
+
}
|
|
9
|
+
export function prefsStatus() {
|
|
10
|
+
return { autoApplyAll: isAutoApplyAll() };
|
|
11
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { type ClaimRow, type ComponentRow, type EdgeRow, type FlowRow } from "./db.js";
|
|
2
|
+
import { type AmemPolicy } from "./policy.js";
|
|
3
|
+
export type ProposalComponent = {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
code_anchor?: string;
|
|
7
|
+
};
|
|
8
|
+
export type ProposalFlow = {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
};
|
|
12
|
+
export type ProposalClaim = {
|
|
13
|
+
id: string;
|
|
14
|
+
kind: string;
|
|
15
|
+
text: string;
|
|
16
|
+
code_anchors?: string[];
|
|
17
|
+
source_ref?: string;
|
|
18
|
+
/** Claim ids this claim replaces; those become status=superseded */
|
|
19
|
+
supersedes?: string[];
|
|
20
|
+
};
|
|
21
|
+
export type ProposalEdge = {
|
|
22
|
+
id?: string;
|
|
23
|
+
from_id: string;
|
|
24
|
+
from_type: "claim" | "flow" | "component";
|
|
25
|
+
to_id: string;
|
|
26
|
+
to_type: "claim" | "flow" | "component";
|
|
27
|
+
kind: string;
|
|
28
|
+
};
|
|
29
|
+
export type Proposal = {
|
|
30
|
+
components?: ProposalComponent[];
|
|
31
|
+
flows?: ProposalFlow[];
|
|
32
|
+
claims?: ProposalClaim[];
|
|
33
|
+
edges?: ProposalEdge[];
|
|
34
|
+
};
|
|
35
|
+
export type ValidationResult = {
|
|
36
|
+
ok: boolean;
|
|
37
|
+
errors: string[];
|
|
38
|
+
warnings: string[];
|
|
39
|
+
proposal: Proposal;
|
|
40
|
+
};
|
|
41
|
+
export declare function parseProposalJson(raw: string): Proposal;
|
|
42
|
+
/** Collect explicit supersede targets from claims + supersedes edges. */
|
|
43
|
+
export declare function collectSupersedeTargets(proposal: Proposal): Map<string, string>;
|
|
44
|
+
export type ClaimConflict = {
|
|
45
|
+
claimId: string;
|
|
46
|
+
otherId: string;
|
|
47
|
+
otherText: string;
|
|
48
|
+
similarity: number;
|
|
49
|
+
sharedAnchors: string[];
|
|
50
|
+
withinProposal: boolean;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Likely conflict: share ≥1 code_anchor and high text overlap, different ids,
|
|
54
|
+
* and the older claim is not explicitly superseded by this proposal.
|
|
55
|
+
*/
|
|
56
|
+
export declare function findClaimConflicts(proposal: Proposal, existingActive: ClaimRow[]): ClaimConflict[];
|
|
57
|
+
export declare function findConflictWarnings(proposal: Proposal, existingActive: ClaimRow[]): string[];
|
|
58
|
+
/** Attach supersede targets to the first claim (Memory “replace older facts”). */
|
|
59
|
+
export declare function applySupersedes(proposal: Proposal, otherIds: string[]): Proposal;
|
|
60
|
+
export declare function validateProposal(proposal: Proposal, policy?: AmemPolicy, opts?: {
|
|
61
|
+
existingClaims?: ClaimRow[];
|
|
62
|
+
}): ValidationResult;
|
|
63
|
+
/** Block claims that look like secrets / credentials (builtin + policy patterns). */
|
|
64
|
+
export declare function checkProposalAgainstPolicy(proposal: Proposal, policy?: AmemPolicy): string[];
|
|
65
|
+
export declare function loadProposalFile(path: string): Proposal;
|
|
66
|
+
export type ProposalDiff = {
|
|
67
|
+
claimsAdded: string[];
|
|
68
|
+
claimsUpdated: string[];
|
|
69
|
+
claimsUnchanged: string[];
|
|
70
|
+
willSupersede: string[];
|
|
71
|
+
componentsAdded: string[];
|
|
72
|
+
flowsAdded: string[];
|
|
73
|
+
};
|
|
74
|
+
/** Preview what apply would change against current active (+ superseded targets). */
|
|
75
|
+
export declare function diffProposal(repoId: string, proposal: Proposal): ProposalDiff;
|
|
76
|
+
export declare function formatProposalDiff(diff: ProposalDiff): string;
|
|
77
|
+
export type ApplyResult = {
|
|
78
|
+
components: number;
|
|
79
|
+
flows: number;
|
|
80
|
+
claims: number;
|
|
81
|
+
edges: number;
|
|
82
|
+
superseded: number;
|
|
83
|
+
};
|
|
84
|
+
export declare function applyProposal(repoId: string, proposal: Proposal, policy?: AmemPolicy): ApplyResult;
|
|
85
|
+
export declare function exportRepoMemory(repoId: string): {
|
|
86
|
+
components: ComponentRow[];
|
|
87
|
+
flows: FlowRow[];
|
|
88
|
+
claims: ClaimRow[];
|
|
89
|
+
edges: EdgeRow[];
|
|
90
|
+
};
|