@getripple/core 1.0.9 → 1.0.11

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.
@@ -0,0 +1,41 @@
1
+ import { RippleAuditSummary } from "./audit";
2
+ import { RippleApprovalRecord } from "./approval";
3
+ import { ChangeIntent } from "./change-intent";
4
+ export declare class RippleCloudClient {
5
+ private apiUrl;
6
+ private apiKey;
7
+ constructor();
8
+ get isConfigured(): boolean;
9
+ private getGitMetadata;
10
+ syncIntent(intent: ChangeIntent): Promise<void>;
11
+ syncApproval(approval: RippleApprovalRecord): Promise<void>;
12
+ syncVerification(verification: any): Promise<void>;
13
+ syncAudit(audit: RippleAuditSummary, commitSha: string): Promise<{
14
+ sent: boolean;
15
+ error?: string;
16
+ }>;
17
+ }
18
+ export declare function getCurrentCommitSha(execSync: any): string;
19
+ export declare function getCurrentBranch(execSync: any): string;
20
+ export declare function getCurrentActor(execSync: any): string;
21
+ export interface CloudAuditPayload {
22
+ protocol?: string;
23
+ intentId: string;
24
+ decision: string;
25
+ commitSha: string;
26
+ branch: string;
27
+ actor: string;
28
+ source: string;
29
+ payload: any;
30
+ }
31
+ export declare function syncAuditToCloud(data: CloudAuditPayload): Promise<{
32
+ sent: boolean;
33
+ error?: string;
34
+ }>;
35
+ /** Pushes a validated change intent to Ripple Cloud, making it the active boundary. */
36
+ export declare function pushIntentToCloud(intent: ChangeIntent): Promise<{
37
+ sent: boolean;
38
+ error?: string;
39
+ }>;
40
+ /** Fetches the active intent for a project from Ripple Cloud using a commit SHA. */
41
+ export declare function fetchActiveIntentForCommit(commitSha: string): Promise<ChangeIntent | null>;
package/dist/cloud.js ADDED
@@ -0,0 +1,304 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.fetchActiveIntentForCommit = exports.pushIntentToCloud = exports.syncAuditToCloud = exports.getCurrentActor = exports.getCurrentBranch = exports.getCurrentCommitSha = exports.RippleCloudClient = void 0;
27
+ const crypto = __importStar(require("crypto"));
28
+ const child_process_1 = require("child_process");
29
+ // FOUNDER FIX: Inline dotenv loader from process.cwd()
30
+ const fs_1 = require("fs");
31
+ const path_1 = require("path");
32
+ function loadDotEnv() {
33
+ const envPath = (0, path_1.join)(process.cwd(), ".env");
34
+ if (!(0, fs_1.existsSync)(envPath))
35
+ return;
36
+ try {
37
+ const lines = (0, fs_1.readFileSync)(envPath, "utf8").split("\n");
38
+ for (const line of lines) {
39
+ const trimmed = line.trim();
40
+ if (!trimmed || trimmed.startsWith("#"))
41
+ continue;
42
+ const eqIndex = trimmed.indexOf("=");
43
+ if (eqIndex < 1)
44
+ continue;
45
+ const key = trimmed.slice(0, eqIndex).trim();
46
+ const value = trimmed.slice(eqIndex + 1).trim()
47
+ .replace(/^["']/, "").replace(/["']$/, "");
48
+ if (key && !(key in process.env)) {
49
+ process.env[key] = value;
50
+ }
51
+ }
52
+ }
53
+ catch { /* silent — never block for dotenv failures */ }
54
+ }
55
+ loadDotEnv(); // Must run before constants are evaluated
56
+ const RIPPLE_CLOUD_URL = process.env.RIPPLE_CLOUD_URL ?? "https://ripple-cloud.vercel.app";
57
+ class RippleCloudClient {
58
+ apiUrl;
59
+ apiKey;
60
+ constructor() {
61
+ this.apiUrl = RIPPLE_CLOUD_URL;
62
+ this.apiKey = process.env.RIPPLE_API_KEY;
63
+ }
64
+ get isConfigured() {
65
+ return typeof this.apiKey === "string" && this.apiKey.trim().length > 0;
66
+ }
67
+ getGitMetadata(commitSha) {
68
+ try {
69
+ const branch = (0, child_process_1.execSync)("git rev-parse --abbrev-ref HEAD", { encoding: "utf8", stdio: "pipe" }).trim();
70
+ let actor = "unknown_actor";
71
+ try {
72
+ actor = commitSha
73
+ ? (0, child_process_1.execSync)(`git log -1 --pretty=format:'%ae' ${commitSha}`, { encoding: "utf8", stdio: "pipe" }).trim()
74
+ : (0, child_process_1.execSync)("git config user.email", { encoding: "utf8", stdio: "pipe" }).trim();
75
+ }
76
+ catch {
77
+ actor = (0, child_process_1.execSync)("git config user.email", { encoding: "utf8", stdio: "pipe" }).trim();
78
+ }
79
+ return { branch, actor };
80
+ }
81
+ catch {
82
+ return { branch: "unknown", actor: "unknown" };
83
+ }
84
+ }
85
+ async syncIntent(intent) {
86
+ if (!this.isConfigured)
87
+ return;
88
+ try {
89
+ await fetch(`${this.apiUrl}/api/intents`, {
90
+ method: "POST",
91
+ headers: { "Content-Type": "application/json", "Authorization": `Bearer ${this.apiKey}` },
92
+ body: JSON.stringify(intent)
93
+ });
94
+ }
95
+ catch (error) { }
96
+ }
97
+ async syncApproval(approval) {
98
+ if (!this.isConfigured)
99
+ return;
100
+ try {
101
+ const { branch, actor } = this.getGitMetadata();
102
+ const rawPayload = JSON.stringify(approval);
103
+ const payloadHash = crypto.createHash("sha256").update(rawPayload).digest("hex");
104
+ const requestBody = {
105
+ protocol: "ripple-approval",
106
+ intentId: approval.intentId,
107
+ branch, actor, source: "cli", payloadHash,
108
+ gate: approval.gate, payload: approval
109
+ };
110
+ await fetch(`${this.apiUrl}/api/approvals`, {
111
+ method: "POST",
112
+ headers: { "Content-Type": "application/json", "Authorization": `Bearer ${this.apiKey}` },
113
+ body: JSON.stringify(requestBody)
114
+ });
115
+ }
116
+ catch (error) { }
117
+ }
118
+ async syncVerification(verification) {
119
+ if (!this.isConfigured)
120
+ return;
121
+ try {
122
+ const { branch, actor } = this.getGitMetadata();
123
+ const rawPayload = JSON.stringify(verification);
124
+ const payloadHash = crypto.createHash("sha256").update(rawPayload).digest("hex");
125
+ const requestBody = {
126
+ protocol: "ripple-verification",
127
+ intentId: verification.intentId,
128
+ branch, actor, source: "cli", payloadHash,
129
+ status: verification.status, payload: verification
130
+ };
131
+ await fetch(`${this.apiUrl}/api/verification`, {
132
+ method: "POST",
133
+ headers: { "Content-Type": "application/json", "Authorization": `Bearer ${this.apiKey}` },
134
+ body: JSON.stringify(requestBody)
135
+ });
136
+ }
137
+ catch (error) { }
138
+ }
139
+ async syncAudit(audit, commitSha) {
140
+ // FOUNDER FIX: Re-check environment variable dynamically
141
+ const apiKey = process.env.RIPPLE_API_KEY;
142
+ if (!apiKey) {
143
+ if (process.env.RIPPLE_CLOUD_URL) {
144
+ console.warn("\n[Ripple Cloud] ⚠ RIPPLE_API_KEY not found. Set it in .env or environment.");
145
+ }
146
+ return { sent: false };
147
+ }
148
+ try {
149
+ const { branch, actor } = this.getGitMetadata(commitSha);
150
+ const rawPayload = JSON.stringify(audit);
151
+ const payloadHash = crypto.createHash("sha256").update(rawPayload).digest("hex");
152
+ const requestBody = {
153
+ protocol: "ripple-audit",
154
+ intentId: audit.intent.id,
155
+ commitSha: commitSha,
156
+ branch, actor, source: "cli", payloadHash,
157
+ decision: audit.decision, payload: audit
158
+ };
159
+ const response = await fetch(`${this.apiUrl}/api/audit`, {
160
+ method: "POST",
161
+ headers: { "Content-Type": "application/json", "Authorization": `Bearer ${apiKey}` },
162
+ body: JSON.stringify(requestBody),
163
+ signal: AbortSignal.timeout(10000)
164
+ });
165
+ if (!response.ok) {
166
+ const body = await response.text().catch(() => "");
167
+ return { sent: false, error: `HTTP ${response.status}: ${body}` };
168
+ }
169
+ return { sent: true };
170
+ }
171
+ catch (err) {
172
+ const message = err instanceof Error ? err.message : String(err);
173
+ return { sent: false, error: message };
174
+ }
175
+ }
176
+ }
177
+ exports.RippleCloudClient = RippleCloudClient;
178
+ function getCurrentCommitSha(execSync) {
179
+ if (process.env.GITHUB_SHA)
180
+ return process.env.GITHUB_SHA;
181
+ try {
182
+ return execSync("git rev-parse HEAD").toString().trim();
183
+ }
184
+ catch {
185
+ return "unknown";
186
+ }
187
+ }
188
+ exports.getCurrentCommitSha = getCurrentCommitSha;
189
+ function getCurrentBranch(execSync) {
190
+ if (process.env.GITHUB_REF_NAME)
191
+ return process.env.GITHUB_REF_NAME;
192
+ if (process.env.GITHUB_HEAD_REF)
193
+ return process.env.GITHUB_HEAD_REF;
194
+ try {
195
+ return execSync("git branch --show-current").toString().trim() || "unknown";
196
+ }
197
+ catch {
198
+ return "unknown";
199
+ }
200
+ }
201
+ exports.getCurrentBranch = getCurrentBranch;
202
+ function getCurrentActor(execSync) {
203
+ if (process.env.GITHUB_ACTOR)
204
+ return process.env.GITHUB_ACTOR;
205
+ try {
206
+ return execSync("git config user.name").toString().trim() || execSync("git config user.email").toString().trim() || "unknown";
207
+ }
208
+ catch {
209
+ return "unknown";
210
+ }
211
+ }
212
+ exports.getCurrentActor = getCurrentActor;
213
+ async function syncAuditToCloud(data) {
214
+ const apiKey = process.env.RIPPLE_API_KEY;
215
+ const apiUrl = process.env.RIPPLE_CLOUD_URL ?? "https://ripple-cloud.vercel.app";
216
+ if (!apiKey) {
217
+ if (process.env.RIPPLE_CLOUD_URL) {
218
+ console.warn("\n[Ripple Cloud] ⚠ RIPPLE_API_KEY not found. Set it in .env or environment.");
219
+ }
220
+ return { sent: false };
221
+ }
222
+ try {
223
+ const requestBody = {
224
+ protocol: data.protocol || "ripple-audit",
225
+ intentId: data.intentId,
226
+ commitSha: data.commitSha,
227
+ branch: data.branch,
228
+ actor: data.actor,
229
+ source: data.source,
230
+ payloadHash: crypto.createHash("sha256").update(JSON.stringify(data.payload)).digest("hex"),
231
+ decision: data.decision,
232
+ payload: data.payload,
233
+ };
234
+ const response = await fetch(`${apiUrl}/api/audit`, {
235
+ method: "POST",
236
+ headers: {
237
+ "Content-Type": "application/json",
238
+ Authorization: `Bearer ${apiKey}`,
239
+ },
240
+ body: JSON.stringify(requestBody),
241
+ signal: AbortSignal.timeout(10000),
242
+ });
243
+ if (!response.ok) {
244
+ const body = await response.text().catch(() => "");
245
+ return { sent: false, error: `HTTP ${response.status}: ${body}` };
246
+ }
247
+ return { sent: true };
248
+ }
249
+ catch (err) {
250
+ const message = err instanceof Error ? err.message : String(err);
251
+ return { sent: false, error: message };
252
+ }
253
+ }
254
+ exports.syncAuditToCloud = syncAuditToCloud;
255
+ /** Pushes a validated change intent to Ripple Cloud, making it the active boundary. */
256
+ async function pushIntentToCloud(intent) {
257
+ const apiKey = process.env.RIPPLE_API_KEY;
258
+ if (!apiKey) {
259
+ return { sent: false, error: "RIPPLE_API_KEY is not set." };
260
+ }
261
+ const apiUrl = process.env.RIPPLE_CLOUD_URL ?? "https://ripple-cloud.vercel.app";
262
+ try {
263
+ const response = await fetch(`${apiUrl}/api/intents`, {
264
+ method: 'POST',
265
+ headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` },
266
+ body: JSON.stringify(intent),
267
+ signal: AbortSignal.timeout(10000),
268
+ });
269
+ if (!response.ok) {
270
+ const body = await response.text().catch(() => "");
271
+ return { sent: false, error: `HTTP ${response.status}: ${body}` };
272
+ }
273
+ return { sent: true };
274
+ }
275
+ catch (err) {
276
+ const message = err instanceof Error ? err.message : String(err);
277
+ return { sent: false, error: message };
278
+ }
279
+ }
280
+ exports.pushIntentToCloud = pushIntentToCloud;
281
+ /** Fetches the active intent for a project from Ripple Cloud using a commit SHA. */
282
+ async function fetchActiveIntentForCommit(commitSha) {
283
+ const apiKey = process.env.RIPPLE_API_KEY;
284
+ if (!apiKey)
285
+ return null;
286
+ const apiUrl = process.env.RIPPLE_CLOUD_URL ?? "https://ripple-cloud.vercel.app";
287
+ try {
288
+ const response = await fetch(`${apiUrl}/api/intents/active?commit_sha=${commitSha}`, {
289
+ method: 'GET',
290
+ headers: { Authorization: `Bearer ${apiKey}` },
291
+ signal: AbortSignal.timeout(10000),
292
+ });
293
+ if (!response.ok) {
294
+ return null;
295
+ }
296
+ // The response body is the raw intent payload
297
+ return await response.json();
298
+ }
299
+ catch {
300
+ return null;
301
+ }
302
+ }
303
+ exports.fetchActiveIntentForCommit = fetchActiveIntentForCommit;
304
+ //# sourceMappingURL=cloud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud.js","sourceRoot":"","sources":["../src/cloud.ts"],"names":[],"mappings":"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"}
package/dist/graph.js CHANGED
@@ -65,6 +65,11 @@ const adapters_1 = require("./adapters");
65
65
  * - optional .ripple/WORKFLOW.md for agent operating rules
66
66
  */
67
67
  class GraphPersistence {
68
+ persistPath;
69
+ cachePath;
70
+ workspaceRoot;
71
+ contextGenerationMode = "full";
72
+ patternCache = null;
68
73
  /**
69
74
  * Pattern hints are derived from source files and cached between context
70
75
  * generations. File changes and project-config rebuilds invalidate them.
@@ -73,8 +78,6 @@ class GraphPersistence {
73
78
  this.patternCache = null;
74
79
  }
75
80
  constructor(workspaceRoot) {
76
- this.contextGenerationMode = "full";
77
- this.patternCache = null;
78
81
  this.workspaceRoot = workspaceRoot;
79
82
  const rippleDir = path.join(workspaceRoot, ".ripple");
80
83
  if (!fs.existsSync(rippleDir)) {
@@ -1611,6 +1614,23 @@ function isPythonIdentifier(value) {
1611
1614
  // GRAPH ENGINE
1612
1615
  // ────────────────────────────────────────────────────────────────────────────
1613
1616
  class GraphEngine {
1617
+ graph;
1618
+ history;
1619
+ persistence;
1620
+ project;
1621
+ workspaceRoot;
1622
+ // Scans rebuild a large part of the graph. File-system events that arrive
1623
+ // during a scan are queued and replayed afterward instead of mutating midway.
1624
+ isScanning = false;
1625
+ pendingUpdates = new Set();
1626
+ pendingAdds = new Set();
1627
+ pendingDeletes = new Set();
1628
+ pendingFullRescan = false;
1629
+ sessionNewFiles = new Set();
1630
+ cacheWriteTimer;
1631
+ adapterSupportCache;
1632
+ focusKeyCache = new Map();
1633
+ focusBaseKeyCounts;
1614
1634
  /**
1615
1635
  * Chooses how much file-based context Ripple writes for the active interface.
1616
1636
  *
@@ -1628,15 +1648,6 @@ class GraphEngine {
1628
1648
  this.setContextGenerationMode(enabled ? "full" : "lean");
1629
1649
  }
1630
1650
  constructor(workspaceRoot) {
1631
- // Scans rebuild a large part of the graph. File-system events that arrive
1632
- // during a scan are queued and replayed afterward instead of mutating midway.
1633
- this.isScanning = false;
1634
- this.pendingUpdates = new Set();
1635
- this.pendingAdds = new Set();
1636
- this.pendingDeletes = new Set();
1637
- this.pendingFullRescan = false;
1638
- this.sessionNewFiles = new Set();
1639
- this.focusKeyCache = new Map();
1640
1651
  this.workspaceRoot = workspaceRoot;
1641
1652
  this.graph = new types_1.SystemGraph();
1642
1653
  this.history = new types_1.HistoryLog();