faf-cli 4.5.0 → 5.0.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 +25 -24
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +90 -4
- package/dist/cli.js.map +1 -1
- package/dist/commands/bi-sync.d.ts +1 -0
- package/dist/commands/bi-sync.d.ts.map +1 -1
- package/dist/commands/bi-sync.js +14 -1
- package/dist/commands/bi-sync.js.map +1 -1
- package/dist/commands/memory.d.ts +14 -0
- package/dist/commands/memory.d.ts.map +1 -0
- package/dist/commands/memory.js +293 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/pro.d.ts +10 -0
- package/dist/commands/pro.d.ts.map +1 -0
- package/dist/commands/pro.js +113 -0
- package/dist/commands/pro.js.map +1 -0
- package/dist/commands/ram.d.ts +17 -0
- package/dist/commands/ram.d.ts.map +1 -0
- package/dist/commands/ram.js +303 -0
- package/dist/commands/ram.js.map +1 -0
- package/dist/commands/readme.js +8 -8
- package/dist/commands/readme.js.map +1 -1
- package/dist/commands/sixws.js +1 -1
- package/dist/engines/v252-hybrid-engine.d.ts +1 -1
- package/dist/engines/v252-hybrid-engine.d.ts.map +1 -1
- package/dist/engines/v252-hybrid-engine.js +1 -1
- package/dist/engines/v252-hybrid-engine.js.map +1 -1
- package/dist/licensing/license-messages.d.ts +20 -0
- package/dist/licensing/license-messages.d.ts.map +1 -0
- package/dist/licensing/license-messages.js +77 -0
- package/dist/licensing/license-messages.js.map +1 -0
- package/dist/licensing/pro-gate.d.ts +54 -0
- package/dist/licensing/pro-gate.d.ts.map +1 -0
- package/dist/licensing/pro-gate.js +243 -0
- package/dist/licensing/pro-gate.js.map +1 -0
- package/dist/utils/memory-parser.d.ts +95 -0
- package/dist/utils/memory-parser.d.ts.map +1 -0
- package/dist/utils/memory-parser.js +408 -0
- package/dist/utils/memory-parser.js.map +1 -0
- package/package.json +1 -1
- package/project.faf +9 -17
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FAF Pro Gate — Zero-Friction License System for tri-sync
|
|
3
|
+
*
|
|
4
|
+
* Gates: faf ram, faf tri-sync, faf bi-sync --ram/--all
|
|
5
|
+
* Model: PHPStan Pro — 14-day free trial, no signup, no credit card.
|
|
6
|
+
*
|
|
7
|
+
* Flow:
|
|
8
|
+
* User runs gated command
|
|
9
|
+
* → checkProAccess()
|
|
10
|
+
* → isLegacyDev()? → ALLOW
|
|
11
|
+
* → hasLicense()? → verify sig → ALLOW
|
|
12
|
+
* → hasTrial()? → verify sig → check expiry
|
|
13
|
+
* → within 14 days? → ALLOW (hint days left)
|
|
14
|
+
* → expired? → BLOCK (upgrade prompt)
|
|
15
|
+
* → no trial? → startTrial() → ALLOW
|
|
16
|
+
*/
|
|
17
|
+
export interface TrialState {
|
|
18
|
+
startedAt: string;
|
|
19
|
+
expiresAt: string;
|
|
20
|
+
signature: string;
|
|
21
|
+
}
|
|
22
|
+
export interface LicenseState {
|
|
23
|
+
key: string;
|
|
24
|
+
activatedAt: string;
|
|
25
|
+
email?: string;
|
|
26
|
+
tier: string;
|
|
27
|
+
signature: string;
|
|
28
|
+
}
|
|
29
|
+
export type ProReason = 'licensed' | 'trial' | 'trial_expired' | 'no_trial' | 'legacy_dev';
|
|
30
|
+
export interface ProStatus {
|
|
31
|
+
allowed: boolean;
|
|
32
|
+
reason: ProReason;
|
|
33
|
+
daysLeft?: number;
|
|
34
|
+
justStarted?: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface ActivationResult {
|
|
37
|
+
success: boolean;
|
|
38
|
+
message: string;
|
|
39
|
+
}
|
|
40
|
+
export declare function isLegacyDev(): boolean;
|
|
41
|
+
export declare function startTrial(): TrialState;
|
|
42
|
+
export declare function activateLicense(key: string): ActivationResult;
|
|
43
|
+
export declare function checkProAccess(): ProStatus;
|
|
44
|
+
export declare function gateProFeature(): boolean;
|
|
45
|
+
export declare function getProStatus(): {
|
|
46
|
+
state: 'licensed' | 'trial' | 'trial_expired' | 'none' | 'legacy_dev';
|
|
47
|
+
daysLeft?: number;
|
|
48
|
+
key?: string;
|
|
49
|
+
tier?: string;
|
|
50
|
+
trialStarted?: string;
|
|
51
|
+
trialExpires?: string;
|
|
52
|
+
activatedAt?: string;
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=pro-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pro-gate.d.ts","sourceRoot":"","sources":["../../src/licensing/pro-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AA2BH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,eAAe,GAAG,UAAU,GAAG,YAAY,CAAC;AAE3F,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AA6CD,wBAAgB,WAAW,IAAI,OAAO,CAIrC;AAiBD,wBAAgB,UAAU,IAAI,UAAU,CAiBvC;AA0BD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAyB7D;AAMD,wBAAgB,cAAc,IAAI,SAAS,CAyB1C;AAMD,wBAAgB,cAAc,IAAI,OAAO,CAqBxC;AAMD,wBAAgB,YAAY,IAAI;IAC9B,KAAK,EAAE,UAAU,GAAG,OAAO,GAAG,eAAe,GAAG,MAAM,GAAG,YAAY,CAAC;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAmCA"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* FAF Pro Gate — Zero-Friction License System for tri-sync
|
|
4
|
+
*
|
|
5
|
+
* Gates: faf ram, faf tri-sync, faf bi-sync --ram/--all
|
|
6
|
+
* Model: PHPStan Pro — 14-day free trial, no signup, no credit card.
|
|
7
|
+
*
|
|
8
|
+
* Flow:
|
|
9
|
+
* User runs gated command
|
|
10
|
+
* → checkProAccess()
|
|
11
|
+
* → isLegacyDev()? → ALLOW
|
|
12
|
+
* → hasLicense()? → verify sig → ALLOW
|
|
13
|
+
* → hasTrial()? → verify sig → check expiry
|
|
14
|
+
* → within 14 days? → ALLOW (hint days left)
|
|
15
|
+
* → expired? → BLOCK (upgrade prompt)
|
|
16
|
+
* → no trial? → startTrial() → ALLOW
|
|
17
|
+
*/
|
|
18
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
19
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.isLegacyDev = isLegacyDev;
|
|
23
|
+
exports.startTrial = startTrial;
|
|
24
|
+
exports.activateLicense = activateLicense;
|
|
25
|
+
exports.checkProAccess = checkProAccess;
|
|
26
|
+
exports.gateProFeature = gateProFeature;
|
|
27
|
+
exports.getProStatus = getProStatus;
|
|
28
|
+
const fs_1 = __importDefault(require("fs"));
|
|
29
|
+
const path_1 = __importDefault(require("path"));
|
|
30
|
+
const os_1 = __importDefault(require("os"));
|
|
31
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
32
|
+
const license_messages_1 = require("./license-messages");
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Paths
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
const FAF_DIR = path_1.default.join(os_1.default.homedir(), '.faf');
|
|
37
|
+
const TRIAL_PATH = path_1.default.join(FAF_DIR, 'trial.json');
|
|
38
|
+
const LICENSE_PATH = path_1.default.join(FAF_DIR, 'license.json');
|
|
39
|
+
const LEGACY_LICENSE_PATH = path_1.default.join(FAF_DIR, 'turbo-license.json');
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// HMAC Signing (v1 — honest-user guard, not DRM)
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
const HMAC_SECRET = 'faf-pro-v1-honest-user';
|
|
44
|
+
function sign(payload) {
|
|
45
|
+
return crypto_1.default.createHmac('sha256', HMAC_SECRET).update(payload).digest('hex');
|
|
46
|
+
}
|
|
47
|
+
function verify(payload, signature) {
|
|
48
|
+
return sign(payload) === signature;
|
|
49
|
+
}
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// File helpers (sync for <10ms)
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
function ensureFafDir() {
|
|
54
|
+
if (!fs_1.default.existsSync(FAF_DIR)) {
|
|
55
|
+
fs_1.default.mkdirSync(FAF_DIR, { recursive: true });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function readJSON(filePath) {
|
|
59
|
+
try {
|
|
60
|
+
if (!fs_1.default.existsSync(filePath)) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const raw = fs_1.default.readFileSync(filePath, 'utf-8');
|
|
64
|
+
return JSON.parse(raw);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function writeJSON(filePath, data) {
|
|
71
|
+
ensureFafDir();
|
|
72
|
+
fs_1.default.writeFileSync(filePath, JSON.stringify(data, null, 2));
|
|
73
|
+
}
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// Legacy dev check
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
function isLegacyDev() {
|
|
78
|
+
const legacy = readJSON(LEGACY_LICENSE_PATH);
|
|
79
|
+
if (!legacy || !legacy.key) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
return legacy.key.startsWith('FAF-DEV0-');
|
|
83
|
+
}
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
// Trial management
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
function readTrial() {
|
|
88
|
+
const trial = readJSON(TRIAL_PATH);
|
|
89
|
+
if (!trial) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
// Verify integrity
|
|
93
|
+
const payload = `${trial.startedAt}:${trial.expiresAt}`;
|
|
94
|
+
if (!verify(payload, trial.signature)) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
return trial;
|
|
98
|
+
}
|
|
99
|
+
function startTrial() {
|
|
100
|
+
const now = new Date();
|
|
101
|
+
const expires = new Date(now);
|
|
102
|
+
expires.setDate(expires.getDate() + 14);
|
|
103
|
+
const startedAt = now.toISOString();
|
|
104
|
+
const expiresAt = expires.toISOString();
|
|
105
|
+
const payload = `${startedAt}:${expiresAt}`;
|
|
106
|
+
const trial = {
|
|
107
|
+
startedAt,
|
|
108
|
+
expiresAt,
|
|
109
|
+
signature: sign(payload),
|
|
110
|
+
};
|
|
111
|
+
writeJSON(TRIAL_PATH, trial);
|
|
112
|
+
return trial;
|
|
113
|
+
}
|
|
114
|
+
function trialDaysLeft(trial) {
|
|
115
|
+
const now = Date.now();
|
|
116
|
+
const expires = new Date(trial.expiresAt).getTime();
|
|
117
|
+
const msLeft = expires - now;
|
|
118
|
+
return Math.max(0, Math.ceil(msLeft / (1000 * 60 * 60 * 24)));
|
|
119
|
+
}
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// License management
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
const LICENSE_KEY_REGEX = /^FAF-PRO-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/;
|
|
124
|
+
function readLicense() {
|
|
125
|
+
const license = readJSON(LICENSE_PATH);
|
|
126
|
+
if (!license) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
// Verify integrity
|
|
130
|
+
const payload = `${license.key}:${license.activatedAt}`;
|
|
131
|
+
if (!verify(payload, license.signature)) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
return license;
|
|
135
|
+
}
|
|
136
|
+
function activateLicense(key) {
|
|
137
|
+
const trimmed = key.trim().toUpperCase();
|
|
138
|
+
if (!LICENSE_KEY_REGEX.test(trimmed)) {
|
|
139
|
+
return { success: false, message: license_messages_1.MESSAGES.invalidKey };
|
|
140
|
+
}
|
|
141
|
+
// Check if already licensed
|
|
142
|
+
const existing = readLicense();
|
|
143
|
+
if (existing) {
|
|
144
|
+
return { success: false, message: license_messages_1.MESSAGES.alreadyLicensed };
|
|
145
|
+
}
|
|
146
|
+
const activatedAt = new Date().toISOString();
|
|
147
|
+
const payload = `${trimmed}:${activatedAt}`;
|
|
148
|
+
const license = {
|
|
149
|
+
key: trimmed,
|
|
150
|
+
activatedAt,
|
|
151
|
+
tier: 'pro',
|
|
152
|
+
signature: sign(payload),
|
|
153
|
+
};
|
|
154
|
+
writeJSON(LICENSE_PATH, license);
|
|
155
|
+
return { success: true, message: license_messages_1.MESSAGES.licenseActivated };
|
|
156
|
+
}
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
// Core gate check
|
|
159
|
+
// ---------------------------------------------------------------------------
|
|
160
|
+
function checkProAccess() {
|
|
161
|
+
// 1. Legacy dev — always allowed
|
|
162
|
+
if (isLegacyDev()) {
|
|
163
|
+
return { allowed: true, reason: 'legacy_dev' };
|
|
164
|
+
}
|
|
165
|
+
// 2. Active license
|
|
166
|
+
const license = readLicense();
|
|
167
|
+
if (license) {
|
|
168
|
+
return { allowed: true, reason: 'licensed' };
|
|
169
|
+
}
|
|
170
|
+
// 3. Active trial
|
|
171
|
+
const trial = readTrial();
|
|
172
|
+
if (trial) {
|
|
173
|
+
const days = trialDaysLeft(trial);
|
|
174
|
+
if (days > 0) {
|
|
175
|
+
return { allowed: true, reason: 'trial', daysLeft: days };
|
|
176
|
+
}
|
|
177
|
+
return { allowed: false, reason: 'trial_expired', daysLeft: 0 };
|
|
178
|
+
}
|
|
179
|
+
// 4. No trial yet — start one automatically
|
|
180
|
+
startTrial();
|
|
181
|
+
return { allowed: true, reason: 'trial', daysLeft: 14, justStarted: true };
|
|
182
|
+
}
|
|
183
|
+
// ---------------------------------------------------------------------------
|
|
184
|
+
// Gate wrapper — call before any Pro feature
|
|
185
|
+
// ---------------------------------------------------------------------------
|
|
186
|
+
function gateProFeature() {
|
|
187
|
+
const status = checkProAccess();
|
|
188
|
+
if (!status.allowed) {
|
|
189
|
+
if (status.reason === 'trial_expired') {
|
|
190
|
+
(0, license_messages_1.showTrialExpired)();
|
|
191
|
+
}
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
// Show contextual messages
|
|
195
|
+
if (status.reason === 'trial' && status.justStarted) {
|
|
196
|
+
(0, license_messages_1.showTrialStarted)();
|
|
197
|
+
}
|
|
198
|
+
else if (status.reason === 'trial') {
|
|
199
|
+
(0, license_messages_1.showTrialReminder)(status.daysLeft);
|
|
200
|
+
}
|
|
201
|
+
else if (status.reason === 'licensed') {
|
|
202
|
+
(0, license_messages_1.showLicenseActive)();
|
|
203
|
+
}
|
|
204
|
+
// legacy_dev — silent pass
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
208
|
+
// Status helpers (for `faf pro` command)
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
function getProStatus() {
|
|
211
|
+
if (isLegacyDev()) {
|
|
212
|
+
return { state: 'legacy_dev' };
|
|
213
|
+
}
|
|
214
|
+
const license = readLicense();
|
|
215
|
+
if (license) {
|
|
216
|
+
return {
|
|
217
|
+
state: 'licensed',
|
|
218
|
+
key: license.key,
|
|
219
|
+
tier: license.tier,
|
|
220
|
+
activatedAt: license.activatedAt,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
const trial = readTrial();
|
|
224
|
+
if (trial) {
|
|
225
|
+
const days = trialDaysLeft(trial);
|
|
226
|
+
if (days > 0) {
|
|
227
|
+
return {
|
|
228
|
+
state: 'trial',
|
|
229
|
+
daysLeft: days,
|
|
230
|
+
trialStarted: trial.startedAt,
|
|
231
|
+
trialExpires: trial.expiresAt,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
return {
|
|
235
|
+
state: 'trial_expired',
|
|
236
|
+
daysLeft: 0,
|
|
237
|
+
trialStarted: trial.startedAt,
|
|
238
|
+
trialExpires: trial.expiresAt,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
return { state: 'none' };
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=pro-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pro-gate.js","sourceRoot":"","sources":["../../src/licensing/pro-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MEMORY.md Parser — Claude Code Auto-Memory Interop
|
|
3
|
+
*
|
|
4
|
+
* Bidirectional interoperability between FAF and Claude Code's
|
|
5
|
+
* auto-memory system (~/.claude/projects/<id>/memory/MEMORY.md).
|
|
6
|
+
*
|
|
7
|
+
* Key difference from other targets: MEMORY.md lives OUTSIDE the
|
|
8
|
+
* project root, has a 200-line auto-load ceiling, and must MERGE
|
|
9
|
+
* (not overwrite) to preserve Claude's own notes.
|
|
10
|
+
*
|
|
11
|
+
* Path convention:
|
|
12
|
+
* ~/.claude/projects/<project-id>/memory/MEMORY.md
|
|
13
|
+
* project-id = absolute path with / replaced by -
|
|
14
|
+
* e.g. /Users/wolfejam/FAF/cli → -Users-wolfejam-FAF-cli
|
|
15
|
+
*/
|
|
16
|
+
export interface MemoryMdSection {
|
|
17
|
+
title: string;
|
|
18
|
+
content: string;
|
|
19
|
+
}
|
|
20
|
+
export interface MemoryMdFile {
|
|
21
|
+
fafSection: string | null;
|
|
22
|
+
claudeNotes: string;
|
|
23
|
+
totalLines: number;
|
|
24
|
+
}
|
|
25
|
+
export interface MemoryImportResult {
|
|
26
|
+
success: boolean;
|
|
27
|
+
warnings: string[];
|
|
28
|
+
harvested: {
|
|
29
|
+
patterns: string[];
|
|
30
|
+
conventions: string[];
|
|
31
|
+
keyFiles: string[];
|
|
32
|
+
notes: string[];
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export interface MemoryExportResult {
|
|
36
|
+
success: boolean;
|
|
37
|
+
filePath: string;
|
|
38
|
+
linesWritten: number;
|
|
39
|
+
warnings: string[];
|
|
40
|
+
merged: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Compute Claude Code project ID from an absolute path.
|
|
44
|
+
* Convention: /Users/wolfejam/FAF/cli → -Users-wolfejam-FAF-cli
|
|
45
|
+
*/
|
|
46
|
+
export declare function computeProjectId(projectPath: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Get the git repository root for a directory.
|
|
49
|
+
* Returns null if not in a git repo.
|
|
50
|
+
*/
|
|
51
|
+
export declare function getGitRoot(cwd?: string): string | null;
|
|
52
|
+
/**
|
|
53
|
+
* Resolve the memory directory for a project.
|
|
54
|
+
* → ~/.claude/projects/-Users-wolfejam-FAF-cli/memory/
|
|
55
|
+
*/
|
|
56
|
+
export declare function resolveMemoryDir(projectPath: string): string;
|
|
57
|
+
/**
|
|
58
|
+
* Resolve the full MEMORY.md path for a project.
|
|
59
|
+
* → ~/.claude/projects/-Users-wolfejam-FAF-cli/memory/MEMORY.md
|
|
60
|
+
*/
|
|
61
|
+
export declare function resolveMemoryPath(projectPath: string): string;
|
|
62
|
+
/**
|
|
63
|
+
* Parse MEMORY.md into our section and Claude's notes.
|
|
64
|
+
*/
|
|
65
|
+
export declare function parseMemoryMd(content: string): MemoryMdFile;
|
|
66
|
+
/**
|
|
67
|
+
* Export .faf data to MEMORY.md.
|
|
68
|
+
* Merge mode (default): replace only our section, preserve Claude's notes.
|
|
69
|
+
* Force mode: overwrite entire file.
|
|
70
|
+
*/
|
|
71
|
+
export declare function memoryExport(fafContent: any, outputPath: string, options?: {
|
|
72
|
+
merge?: boolean;
|
|
73
|
+
}): Promise<MemoryExportResult>;
|
|
74
|
+
/**
|
|
75
|
+
* Import/harvest Claude's notes from MEMORY.md into structured data.
|
|
76
|
+
* Conservative: only extracts clearly structured entries.
|
|
77
|
+
*/
|
|
78
|
+
export declare function memoryImport(memoryPath: string): Promise<MemoryImportResult>;
|
|
79
|
+
/**
|
|
80
|
+
* Detect MEMORY.md at Claude's expected path for this project.
|
|
81
|
+
* Returns the path if found, null otherwise.
|
|
82
|
+
*/
|
|
83
|
+
export declare function detectMemoryMd(projectPath: string): Promise<string | null>;
|
|
84
|
+
/**
|
|
85
|
+
* Get memory status for display.
|
|
86
|
+
*/
|
|
87
|
+
export declare function getMemoryStatus(projectPath: string): Promise<{
|
|
88
|
+
exists: boolean;
|
|
89
|
+
path: string;
|
|
90
|
+
totalLines: number;
|
|
91
|
+
fafSectionLines: number;
|
|
92
|
+
claudeNotesLines: number;
|
|
93
|
+
hasFafSection: boolean;
|
|
94
|
+
}>;
|
|
95
|
+
//# sourceMappingURL=memory-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-parser.d.ts","sourceRoot":"","sources":["../../src/utils/memory-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAUH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE;QACT,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,KAAK,EAAE,MAAM,EAAE,CAAC;KACjB,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;CACjB;AAMD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAK5D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWtD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAK5D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE7D;AAaD;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CA6B3D;AA4GD;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,GAAG,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5B,OAAO,CAAC,kBAAkB,CAAC,CAsD7B;AAMD;;;GAGG;AACH,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAmElF;AAMD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQhF;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;IAClE,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC,CAwBD"}
|