claude-launchpad 0.10.1-dev.3 → 0.10.1-dev.5
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 +10 -8
- package/dist/{chunk-7YDBTED2.js → chunk-HVWGJSU5.js} +88 -21
- package/dist/chunk-HVWGJSU5.js.map +1 -0
- package/dist/cli.js +6 -6
- package/dist/cli.js.map +1 -1
- package/dist/commands/memory/server.js +12 -6
- package/dist/commands/memory/server.js.map +1 -1
- package/dist/pull-6WBOOER2.js +109 -0
- package/dist/pull-6WBOOER2.js.map +1 -0
- package/dist/push-XLL3FQ32.js +141 -0
- package/dist/push-XLL3FQ32.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-7YDBTED2.js.map +0 -1
- package/dist/pull-MPBJHZIP.js +0 -71
- package/dist/pull-MPBJHZIP.js.map +0 -1
- package/dist/push-GRCPUMV6.js +0 -114
- package/dist/push-GRCPUMV6.js.map +0 -1
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
assertGhAvailable,
|
|
4
|
+
createGist,
|
|
5
|
+
loadSyncConfig,
|
|
6
|
+
memoryToSyncRow,
|
|
7
|
+
mergeFromRemote,
|
|
8
|
+
parsePayload,
|
|
9
|
+
projectToFilename,
|
|
10
|
+
readGistFile,
|
|
11
|
+
updateGistFiles
|
|
12
|
+
} from "./chunk-HVWGJSU5.js";
|
|
13
|
+
import "./chunk-J5NT4JGE.js";
|
|
14
|
+
import {
|
|
15
|
+
detectProject
|
|
16
|
+
} from "./chunk-NAW47BYA.js";
|
|
17
|
+
import {
|
|
18
|
+
initStorage
|
|
19
|
+
} from "./chunk-YEGOHLE7.js";
|
|
20
|
+
import "./chunk-JXFTVFPC.js";
|
|
21
|
+
import "./chunk-ZMSHFAZQ.js";
|
|
22
|
+
import "./chunk-Z6FBT44W.js";
|
|
23
|
+
import {
|
|
24
|
+
log
|
|
25
|
+
} from "./chunk-RJGXPH7P.js";
|
|
26
|
+
|
|
27
|
+
// src/commands/memory/subcommands/push.ts
|
|
28
|
+
import { hostname } from "os";
|
|
29
|
+
import { confirm } from "@inquirer/prompts";
|
|
30
|
+
function buildPayload(memories, relations) {
|
|
31
|
+
return {
|
|
32
|
+
version: 1,
|
|
33
|
+
machine_id: hostname(),
|
|
34
|
+
pushed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35
|
+
memories,
|
|
36
|
+
relations
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function filterRelations(allRelations, memoryIds) {
|
|
40
|
+
return allRelations.filter((r) => memoryIds.has(r.sourceId) && memoryIds.has(r.targetId)).map((r) => ({
|
|
41
|
+
source_id: r.sourceId,
|
|
42
|
+
target_id: r.targetId,
|
|
43
|
+
relation_type: r.relationType,
|
|
44
|
+
created_at: r.createdAt
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
async function runPush(opts) {
|
|
48
|
+
assertGhAvailable();
|
|
49
|
+
const { requireMemoryDeps } = await import("./require-deps-NKRCPVAO.js");
|
|
50
|
+
await requireMemoryDeps();
|
|
51
|
+
const ctx = initStorage();
|
|
52
|
+
try {
|
|
53
|
+
const syncConfig = loadSyncConfig();
|
|
54
|
+
const allRelations = ctx.relationRepo.getAll();
|
|
55
|
+
if (opts.all) {
|
|
56
|
+
await pushAll(ctx, allRelations, syncConfig, opts);
|
|
57
|
+
} else {
|
|
58
|
+
await pushProject(ctx, allRelations, syncConfig, opts);
|
|
59
|
+
}
|
|
60
|
+
} finally {
|
|
61
|
+
ctx.close();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async function pushProject(ctx, allRelations, syncConfig, opts) {
|
|
65
|
+
const project = detectProject(process.cwd());
|
|
66
|
+
if (!project) {
|
|
67
|
+
log.error("Could not detect project. Run from a project directory or use --all.");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const filename = projectToFilename(project);
|
|
71
|
+
if (syncConfig) {
|
|
72
|
+
const remote = parsePayload(readGistFile(syncConfig.gistId, filename));
|
|
73
|
+
if (remote) mergeFromRemote(ctx.memoryRepo, ctx.relationRepo, remote);
|
|
74
|
+
}
|
|
75
|
+
const memories = ctx.memoryRepo.getAllForSync(project);
|
|
76
|
+
const memoryIds = new Set(memories.map((m) => m.id));
|
|
77
|
+
const relations = filterRelations(allRelations, memoryIds);
|
|
78
|
+
const json = JSON.stringify(buildPayload(memories.map(memoryToSyncRow), relations), null, 2);
|
|
79
|
+
if (!syncConfig) {
|
|
80
|
+
if (!opts.yes && !await confirmCreate()) return;
|
|
81
|
+
createGist(filename, json);
|
|
82
|
+
} else {
|
|
83
|
+
updateGistFiles(syncConfig.gistId, { [filename]: json });
|
|
84
|
+
}
|
|
85
|
+
log.blank();
|
|
86
|
+
log.step("Push complete");
|
|
87
|
+
log.info(`Project: ${project} (${memories.length} memories)`);
|
|
88
|
+
log.info(`Relations: ${relations.length}`);
|
|
89
|
+
log.blank();
|
|
90
|
+
}
|
|
91
|
+
async function pushAll(ctx, allRelations, syncConfig, opts) {
|
|
92
|
+
const allMemories = ctx.memoryRepo.getAllForSync();
|
|
93
|
+
const byProject = groupByProject(allMemories);
|
|
94
|
+
const files = {};
|
|
95
|
+
for (const [project, memories] of byProject) {
|
|
96
|
+
const memoryIds = new Set(memories.map((m) => m.id));
|
|
97
|
+
const relations = filterRelations(allRelations, memoryIds);
|
|
98
|
+
files[projectToFilename(project)] = JSON.stringify(
|
|
99
|
+
buildPayload(memories.map(memoryToSyncRow), relations),
|
|
100
|
+
null,
|
|
101
|
+
2
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
if (!syncConfig) {
|
|
105
|
+
if (!opts.yes && !await confirmCreate()) return;
|
|
106
|
+
const entries = Object.entries(files);
|
|
107
|
+
const gistId = createGist(entries[0][0], entries[0][1]);
|
|
108
|
+
if (entries.length > 1) {
|
|
109
|
+
updateGistFiles(gistId, Object.fromEntries(entries.slice(1)));
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
updateGistFiles(syncConfig.gistId, files);
|
|
113
|
+
}
|
|
114
|
+
log.blank();
|
|
115
|
+
log.step("Push complete");
|
|
116
|
+
log.info(`Projects: ${byProject.size}`);
|
|
117
|
+
log.info(`Memories: ${allMemories.length}`);
|
|
118
|
+
log.blank();
|
|
119
|
+
}
|
|
120
|
+
function groupByProject(memories) {
|
|
121
|
+
const byProject = /* @__PURE__ */ new Map();
|
|
122
|
+
for (const m of memories) {
|
|
123
|
+
const key = m.project ?? "_global";
|
|
124
|
+
const list = byProject.get(key) ?? [];
|
|
125
|
+
list.push(m);
|
|
126
|
+
byProject.set(key, list);
|
|
127
|
+
}
|
|
128
|
+
return byProject;
|
|
129
|
+
}
|
|
130
|
+
async function confirmCreate() {
|
|
131
|
+
const proceed = await confirm({
|
|
132
|
+
message: "Create a private GitHub Gist for memory sync?",
|
|
133
|
+
default: true
|
|
134
|
+
});
|
|
135
|
+
if (!proceed) log.info("Skipped.");
|
|
136
|
+
return proceed;
|
|
137
|
+
}
|
|
138
|
+
export {
|
|
139
|
+
runPush
|
|
140
|
+
};
|
|
141
|
+
//# sourceMappingURL=push-XLL3FQ32.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/memory/subcommands/push.ts"],"sourcesContent":["import { hostname } from 'node:os';\nimport { confirm } from '@inquirer/prompts';\nimport { log } from '../../../lib/output.js';\nimport { initStorage } from './init-storage.js';\nimport type { StorageContext } from './init-storage.js';\nimport {\n assertGhAvailable,\n loadSyncConfig,\n createGist,\n readGistFile,\n updateGistFiles,\n projectToFilename,\n parsePayload,\n} from '../utils/gist-transport.js';\nimport { mergeFromRemote, memoryToSyncRow } from '../utils/sync-merge.js';\nimport type { Memory, SyncPayload, SyncRelationRow } from '../types.js';\nimport { detectProject } from '../utils/project.js';\n\ninterface PushOpts {\n readonly all?: boolean;\n readonly yes?: boolean;\n}\n\nfunction buildPayload(\n memories: readonly ReturnType<typeof memoryToSyncRow>[],\n relations: readonly SyncRelationRow[],\n): SyncPayload {\n return {\n version: 1,\n machine_id: hostname(),\n pushed_at: new Date().toISOString(),\n memories,\n relations,\n };\n}\n\nfunction filterRelations(\n allRelations: readonly { sourceId: string; targetId: string; relationType: string; createdAt: string }[],\n memoryIds: ReadonlySet<string>,\n): readonly SyncRelationRow[] {\n return allRelations\n .filter((r) => memoryIds.has(r.sourceId) && memoryIds.has(r.targetId))\n .map((r) => ({\n source_id: r.sourceId,\n target_id: r.targetId,\n relation_type: r.relationType as SyncRelationRow['relation_type'],\n created_at: r.createdAt,\n }));\n}\n\nexport async function runPush(opts: PushOpts): Promise<void> {\n assertGhAvailable();\n\n const { requireMemoryDeps } = await import('../utils/require-deps.js');\n await requireMemoryDeps();\n const ctx = initStorage();\n\n try {\n const syncConfig = loadSyncConfig();\n const allRelations = ctx.relationRepo.getAll();\n\n if (opts.all) {\n await pushAll(ctx, allRelations, syncConfig, opts);\n } else {\n await pushProject(ctx, allRelations, syncConfig, opts);\n }\n } finally {\n ctx.close();\n }\n}\n\nasync function pushProject(\n ctx: StorageContext,\n allRelations: readonly { sourceId: string; targetId: string; relationType: string; createdAt: string }[],\n syncConfig: { gistId: string } | null,\n opts: PushOpts,\n): Promise<void> {\n const project = detectProject(process.cwd());\n if (!project) {\n log.error('Could not detect project. Run from a project directory or use --all.');\n return;\n }\n\n const filename = projectToFilename(project);\n\n // Pull-before-push for this project\n if (syncConfig) {\n const remote = parsePayload(readGistFile(syncConfig.gistId, filename));\n if (remote) mergeFromRemote(ctx.memoryRepo, ctx.relationRepo, remote);\n }\n\n const memories = ctx.memoryRepo.getAllForSync(project);\n const memoryIds = new Set(memories.map((m) => m.id));\n const relations = filterRelations(allRelations, memoryIds);\n const json = JSON.stringify(buildPayload(memories.map(memoryToSyncRow), relations), null, 2);\n\n if (!syncConfig) {\n if (!opts.yes && !(await confirmCreate())) return;\n createGist(filename, json);\n } else {\n updateGistFiles(syncConfig.gistId, { [filename]: json });\n }\n\n log.blank();\n log.step('Push complete');\n log.info(`Project: ${project} (${memories.length} memories)`);\n log.info(`Relations: ${relations.length}`);\n log.blank();\n}\n\nasync function pushAll(\n ctx: StorageContext,\n allRelations: readonly { sourceId: string; targetId: string; relationType: string; createdAt: string }[],\n syncConfig: { gistId: string } | null,\n opts: PushOpts,\n): Promise<void> {\n const allMemories = ctx.memoryRepo.getAllForSync();\n const byProject = groupByProject(allMemories);\n\n const files: Record<string, string> = {};\n for (const [project, memories] of byProject) {\n const memoryIds = new Set(memories.map((m) => m.id));\n const relations = filterRelations(allRelations, memoryIds);\n files[projectToFilename(project)] = JSON.stringify(\n buildPayload(memories.map(memoryToSyncRow), relations), null, 2,\n );\n }\n\n if (!syncConfig) {\n if (!opts.yes && !(await confirmCreate())) return;\n const entries = Object.entries(files);\n const gistId = createGist(entries[0]![0], entries[0]![1]);\n if (entries.length > 1) {\n updateGistFiles(gistId, Object.fromEntries(entries.slice(1)));\n }\n } else {\n updateGistFiles(syncConfig.gistId, files);\n }\n\n log.blank();\n log.step('Push complete');\n log.info(`Projects: ${byProject.size}`);\n log.info(`Memories: ${allMemories.length}`);\n log.blank();\n}\n\nfunction groupByProject(memories: readonly Memory[]): Map<string, Memory[]> {\n const byProject = new Map<string, Memory[]>();\n for (const m of memories) {\n const key = m.project ?? '_global';\n const list = byProject.get(key) ?? [];\n list.push(m);\n byProject.set(key, list);\n }\n return byProject;\n}\n\nasync function confirmCreate(): Promise<boolean> {\n const proceed = await confirm({\n message: 'Create a private GitHub Gist for memory sync?',\n default: true,\n });\n if (!proceed) log.info('Skipped.');\n return proceed;\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/memory/utils/gist-transport.ts","../src/commands/memory/utils/sync-merge.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { readFileSync, writeFileSync, unlinkSync, mkdirSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport { randomUUID } from 'node:crypto';\nimport { resolveDataDir, DEFAULT_CONFIG } from '../config.js';\nimport type { SyncConfig } from '../types.js';\n\nconst EXEC_OPTS = { encoding: 'utf-8' as const, timeout: 30_000 };\nconst GIST_FILENAME = 'agentic-memory-sync.json';\nconst SYNC_CONFIG_FILE = 'sync-config.json';\n\nfunction syncConfigPath(): string {\n return join(resolveDataDir(DEFAULT_CONFIG.dataDir), SYNC_CONFIG_FILE);\n}\n\nexport function assertGhAvailable(): void {\n try {\n execSync('gh --version', { ...EXEC_OPTS, stdio: 'pipe' });\n } catch {\n throw new Error(\n 'Memory sync requires the GitHub CLI.\\n' +\n 'Install: https://cli.github.com/\\n' +\n 'Then run: gh auth login'\n );\n }\n try {\n execSync('gh auth status', { ...EXEC_OPTS, stdio: 'pipe' });\n } catch {\n throw new Error(\n 'gh is installed but not authenticated.\\n' +\n 'Run: gh auth login'\n );\n }\n}\n\nexport function loadSyncConfig(): SyncConfig | null {\n try {\n const raw = readFileSync(syncConfigPath(), 'utf-8');\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n if (typeof parsed.gistId === 'string' && parsed.gistId.length > 0) {\n return { gistId: parsed.gistId };\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport function saveSyncConfig(config: SyncConfig): void {\n const filePath = syncConfigPath();\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n}\n\nexport function createGist(payload: string): string {\n const tmpFile = join(tmpdir(), GIST_FILENAME);\n try {\n writeFileSync(tmpFile, payload, 'utf-8');\n const result = execSync(\n `gh gist create \"${tmpFile}\" --desc \"agentic-memory sync\" --public=false`,\n { ...EXEC_OPTS, stdio: ['pipe', 'pipe', 'pipe'] },\n ).trim();\n const gistId = result.split('/').pop() ?? '';\n if (!gistId) throw new Error(`Failed to parse gist ID from: ${result}`);\n saveSyncConfig({ gistId });\n return gistId;\n } finally {\n try { unlinkSync(tmpFile); } catch { /* ignore */ }\n }\n}\n\nexport function readGist(gistId: string): string | null {\n try {\n return execSync(\n `gh gist view \"${gistId}\" --filename \"${GIST_FILENAME}\" --raw`,\n { ...EXEC_OPTS, stdio: ['pipe', 'pipe', 'pipe'] },\n );\n } catch {\n return null;\n }\n}\n\nexport function updateGist(gistId: string, payload: string): void {\n const tmpFile = join(tmpdir(), GIST_FILENAME);\n try {\n writeFileSync(tmpFile, payload, 'utf-8');\n execSync(\n `gh gist edit \"${gistId}\" --filename \"${GIST_FILENAME}\" \"${tmpFile}\"`,\n { ...EXEC_OPTS, stdio: ['pipe', 'pipe', 'pipe'] },\n );\n } finally {\n try { unlinkSync(tmpFile); } catch { /* ignore */ }\n }\n}\n","import type { Memory, SyncPayload, SyncMemoryRow, MergeResult, RelationType } from '../types.js';\nimport type { MemoryRepo } from '../storage/memory-repo.js';\nimport type { RelationRepo } from '../storage/relation-repo.js';\n\nfunction memoryToSyncRow(m: Memory): SyncMemoryRow {\n return {\n id: m.id,\n type: m.type,\n title: m.title,\n content: m.content,\n context: m.context,\n source: m.source,\n project: m.project,\n tags: [...m.tags],\n importance: m.importance,\n access_count: m.accessCount,\n injection_count: m.injectionCount,\n created_at: m.createdAt,\n updated_at: m.updatedAt,\n last_accessed: m.lastAccessed,\n };\n}\n\nexport { memoryToSyncRow };\n\nexport function mergeFromRemote(\n memoryRepo: MemoryRepo,\n relationRepo: RelationRepo,\n payload: SyncPayload,\n project?: string,\n): MergeResult {\n let inserted = 0;\n let updated = 0;\n let relationsAdded = 0;\n\n const memories = project\n ? payload.memories.filter((m) => m.project === project)\n : payload.memories;\n\n for (const remote of memories) {\n const local = memoryRepo.getById(remote.id);\n if (!local) {\n memoryRepo.upsertFromSync(remote);\n inserted++;\n } else if (remote.updated_at > local.updatedAt) {\n memoryRepo.upsertFromSync(remote);\n updated++;\n }\n }\n\n const localIds = new Set(memoryRepo.getAll().map((m) => m.id));\n const relations = payload.relations.filter(\n (r) => localIds.has(r.source_id) && localIds.has(r.target_id),\n );\n\n for (const rel of relations) {\n const added = relationRepo.create(\n rel.source_id,\n rel.target_id,\n rel.relation_type as RelationType,\n );\n if (added) relationsAdded++;\n }\n\n return { inserted, updated, relationsAdded };\n}\n"],"mappings":";;;;;;;AAAA,SAAS,gBAAgB;AACzB,SAAS,cAAc,eAAe,YAAY,iBAAiB;AACnE,SAAS,MAAM,eAAe;AAC9B,SAAS,cAAc;AAKvB,IAAM,YAAY,EAAE,UAAU,SAAkB,SAAS,IAAO;AAChE,IAAM,gBAAgB;AACtB,IAAM,mBAAmB;AAEzB,SAAS,iBAAyB;AAChC,SAAO,KAAK,eAAe,eAAe,OAAO,GAAG,gBAAgB;AACtE;AAEO,SAAS,oBAA0B;AACxC,MAAI;AACF,aAAS,gBAAgB,EAAE,GAAG,WAAW,OAAO,OAAO,CAAC;AAAA,EAC1D,QAAQ;AACN,UAAM,IAAI;AAAA,MACR;AAAA,IAGF;AAAA,EACF;AACA,MAAI;AACF,aAAS,kBAAkB,EAAE,GAAG,WAAW,OAAO,OAAO,CAAC;AAAA,EAC5D,QAAQ;AACN,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACF;AAEO,SAAS,iBAAoC;AAClD,MAAI;AACF,UAAM,MAAM,aAAa,eAAe,GAAG,OAAO;AAClD,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,OAAO,OAAO,WAAW,YAAY,OAAO,OAAO,SAAS,GAAG;AACjE,aAAO,EAAE,QAAQ,OAAO,OAAO;AAAA,IACjC;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eAAe,QAA0B;AACvD,QAAM,WAAW,eAAe;AAChC,YAAU,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAChD,gBAAc,UAAU,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,MAAM,OAAO;AACzE;AAEO,SAAS,WAAW,SAAyB;AAClD,QAAM,UAAU,KAAK,OAAO,GAAG,aAAa;AAC5C,MAAI;AACF,kBAAc,SAAS,SAAS,OAAO;AACvC,UAAM,SAAS;AAAA,MACb,mBAAmB,OAAO;AAAA,MAC1B,EAAE,GAAG,WAAW,OAAO,CAAC,QAAQ,QAAQ,MAAM,EAAE;AAAA,IAClD,EAAE,KAAK;AACP,UAAM,SAAS,OAAO,MAAM,GAAG,EAAE,IAAI,KAAK;AAC1C,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,iCAAiC,MAAM,EAAE;AACtE,mBAAe,EAAE,OAAO,CAAC;AACzB,WAAO;AAAA,EACT,UAAE;AACA,QAAI;AAAE,iBAAW,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAe;AAAA,EACpD;AACF;AAEO,SAAS,SAAS,QAA+B;AACtD,MAAI;AACF,WAAO;AAAA,MACL,iBAAiB,MAAM,iBAAiB,aAAa;AAAA,MACrD,EAAE,GAAG,WAAW,OAAO,CAAC,QAAQ,QAAQ,MAAM,EAAE;AAAA,IAClD;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,WAAW,QAAgB,SAAuB;AAChE,QAAM,UAAU,KAAK,OAAO,GAAG,aAAa;AAC5C,MAAI;AACF,kBAAc,SAAS,SAAS,OAAO;AACvC;AAAA,MACE,iBAAiB,MAAM,iBAAiB,aAAa,MAAM,OAAO;AAAA,MAClE,EAAE,GAAG,WAAW,OAAO,CAAC,QAAQ,QAAQ,MAAM,EAAE;AAAA,IAClD;AAAA,EACF,UAAE;AACA,QAAI;AAAE,iBAAW,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAe;AAAA,EACpD;AACF;;;AC1FA,SAAS,gBAAgB,GAA0B;AACjD,SAAO;AAAA,IACL,IAAI,EAAE;AAAA,IACN,MAAM,EAAE;AAAA,IACR,OAAO,EAAE;AAAA,IACT,SAAS,EAAE;AAAA,IACX,SAAS,EAAE;AAAA,IACX,QAAQ,EAAE;AAAA,IACV,SAAS,EAAE;AAAA,IACX,MAAM,CAAC,GAAG,EAAE,IAAI;AAAA,IAChB,YAAY,EAAE;AAAA,IACd,cAAc,EAAE;AAAA,IAChB,iBAAiB,EAAE;AAAA,IACnB,YAAY,EAAE;AAAA,IACd,YAAY,EAAE;AAAA,IACd,eAAe,EAAE;AAAA,EACnB;AACF;AAIO,SAAS,gBACd,YACA,cACA,SACA,SACa;AACb,MAAI,WAAW;AACf,MAAI,UAAU;AACd,MAAI,iBAAiB;AAErB,QAAM,WAAW,UACb,QAAQ,SAAS,OAAO,CAAC,MAAM,EAAE,YAAY,OAAO,IACpD,QAAQ;AAEZ,aAAW,UAAU,UAAU;AAC7B,UAAM,QAAQ,WAAW,QAAQ,OAAO,EAAE;AAC1C,QAAI,CAAC,OAAO;AACV,iBAAW,eAAe,MAAM;AAChC;AAAA,IACF,WAAW,OAAO,aAAa,MAAM,WAAW;AAC9C,iBAAW,eAAe,MAAM;AAChC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAAW,IAAI,IAAI,WAAW,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC7D,QAAM,YAAY,QAAQ,UAAU;AAAA,IAClC,CAAC,MAAM,SAAS,IAAI,EAAE,SAAS,KAAK,SAAS,IAAI,EAAE,SAAS;AAAA,EAC9D;AAEA,aAAW,OAAO,WAAW;AAC3B,UAAM,QAAQ,aAAa;AAAA,MACzB,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,IACN;AACA,QAAI,MAAO;AAAA,EACb;AAEA,SAAO,EAAE,UAAU,SAAS,eAAe;AAC7C;","names":[]}
|
package/dist/pull-MPBJHZIP.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
assertGhAvailable,
|
|
4
|
-
loadSyncConfig,
|
|
5
|
-
mergeFromRemote,
|
|
6
|
-
readGist
|
|
7
|
-
} from "./chunk-7YDBTED2.js";
|
|
8
|
-
import {
|
|
9
|
-
SyncPayloadSchema
|
|
10
|
-
} from "./chunk-J5NT4JGE.js";
|
|
11
|
-
import {
|
|
12
|
-
initStorage
|
|
13
|
-
} from "./chunk-YEGOHLE7.js";
|
|
14
|
-
import "./chunk-JXFTVFPC.js";
|
|
15
|
-
import "./chunk-ZMSHFAZQ.js";
|
|
16
|
-
import "./chunk-Z6FBT44W.js";
|
|
17
|
-
import {
|
|
18
|
-
log
|
|
19
|
-
} from "./chunk-RJGXPH7P.js";
|
|
20
|
-
|
|
21
|
-
// src/commands/memory/subcommands/pull.ts
|
|
22
|
-
function parsePayload(raw) {
|
|
23
|
-
try {
|
|
24
|
-
const parsed = JSON.parse(raw);
|
|
25
|
-
return SyncPayloadSchema.parse(parsed);
|
|
26
|
-
} catch {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
async function runPull(opts) {
|
|
31
|
-
assertGhAvailable();
|
|
32
|
-
const syncConfig = loadSyncConfig();
|
|
33
|
-
if (!syncConfig) {
|
|
34
|
-
log.error("No sync configured. Run `memory push` first to create a gist.");
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
const raw = readGist(syncConfig.gistId);
|
|
38
|
-
if (!raw) {
|
|
39
|
-
log.error("Gist is empty or not found. It may have been deleted.");
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
const payload = parsePayload(raw);
|
|
43
|
-
if (!payload) {
|
|
44
|
-
log.error("Corrupted or incompatible sync data. Could not parse gist.");
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
const { requireMemoryDeps } = await import("./require-deps-NKRCPVAO.js");
|
|
48
|
-
await requireMemoryDeps();
|
|
49
|
-
const ctx = initStorage();
|
|
50
|
-
try {
|
|
51
|
-
const result = mergeFromRemote(ctx.memoryRepo, ctx.relationRepo, payload, opts.project);
|
|
52
|
-
log.blank();
|
|
53
|
-
if (result.inserted === 0 && result.updated === 0 && result.relationsAdded === 0) {
|
|
54
|
-
log.step("Already in sync");
|
|
55
|
-
log.info(`From: ${payload.machine_id} (${payload.pushed_at})`);
|
|
56
|
-
} else {
|
|
57
|
-
log.step("Pull complete");
|
|
58
|
-
log.info(`From: ${payload.machine_id} (${payload.pushed_at})`);
|
|
59
|
-
if (result.inserted > 0) log.info(`Inserted: ${result.inserted}`);
|
|
60
|
-
if (result.updated > 0) log.info(`Updated: ${result.updated}`);
|
|
61
|
-
if (result.relationsAdded > 0) log.info(`Relations: ${result.relationsAdded} added`);
|
|
62
|
-
}
|
|
63
|
-
log.blank();
|
|
64
|
-
} finally {
|
|
65
|
-
ctx.close();
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
export {
|
|
69
|
-
runPull
|
|
70
|
-
};
|
|
71
|
-
//# sourceMappingURL=pull-MPBJHZIP.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/memory/subcommands/pull.ts"],"sourcesContent":["import { log } from '../../../lib/output.js';\nimport { initStorage } from './init-storage.js';\nimport { assertGhAvailable, loadSyncConfig, readGist } from '../utils/gist-transport.js';\nimport { mergeFromRemote } from '../utils/sync-merge.js';\nimport { SyncPayloadSchema } from '../types.js';\nimport type { SyncPayload } from '../types.js';\n\ninterface PullOpts {\n readonly project?: string;\n}\n\nfunction parsePayload(raw: string): SyncPayload | null {\n try {\n const parsed = JSON.parse(raw);\n return SyncPayloadSchema.parse(parsed);\n } catch {\n return null;\n }\n}\n\nexport async function runPull(opts: PullOpts): Promise<void> {\n assertGhAvailable();\n\n const syncConfig = loadSyncConfig();\n if (!syncConfig) {\n log.error('No sync configured. Run `memory push` first to create a gist.');\n return;\n }\n\n const raw = readGist(syncConfig.gistId);\n if (!raw) {\n log.error('Gist is empty or not found. It may have been deleted.');\n return;\n }\n\n const payload = parsePayload(raw);\n if (!payload) {\n log.error('Corrupted or incompatible sync data. Could not parse gist.');\n return;\n }\n\n const { requireMemoryDeps } = await import('../utils/require-deps.js');\n await requireMemoryDeps();\n const ctx = initStorage();\n\n try {\n const result = mergeFromRemote(ctx.memoryRepo, ctx.relationRepo, payload, opts.project);\n log.blank();\n if (result.inserted === 0 && result.updated === 0 && result.relationsAdded === 0) {\n log.step('Already in sync');\n log.info(`From: ${payload.machine_id} (${payload.pushed_at})`);\n } else {\n log.step('Pull complete');\n log.info(`From: ${payload.machine_id} (${payload.pushed_at})`);\n if (result.inserted > 0) log.info(`Inserted: ${result.inserted}`);\n if (result.updated > 0) log.info(`Updated: ${result.updated}`);\n if (result.relationsAdded > 0) log.info(`Relations: ${result.relationsAdded} added`);\n }\n log.blank();\n } finally {\n ctx.close();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAWA,SAAS,aAAa,KAAiC;AACrD,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,WAAO,kBAAkB,MAAM,MAAM;AAAA,EACvC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,QAAQ,MAA+B;AAC3D,oBAAkB;AAElB,QAAM,aAAa,eAAe;AAClC,MAAI,CAAC,YAAY;AACf,QAAI,MAAM,+DAA+D;AACzE;AAAA,EACF;AAEA,QAAM,MAAM,SAAS,WAAW,MAAM;AACtC,MAAI,CAAC,KAAK;AACR,QAAI,MAAM,uDAAuD;AACjE;AAAA,EACF;AAEA,QAAM,UAAU,aAAa,GAAG;AAChC,MAAI,CAAC,SAAS;AACZ,QAAI,MAAM,4DAA4D;AACtE;AAAA,EACF;AAEA,QAAM,EAAE,kBAAkB,IAAI,MAAM,OAAO,4BAA0B;AACrE,QAAM,kBAAkB;AACxB,QAAM,MAAM,YAAY;AAExB,MAAI;AACF,UAAM,SAAS,gBAAgB,IAAI,YAAY,IAAI,cAAc,SAAS,KAAK,OAAO;AACtF,QAAI,MAAM;AACV,QAAI,OAAO,aAAa,KAAK,OAAO,YAAY,KAAK,OAAO,mBAAmB,GAAG;AAChF,UAAI,KAAK,iBAAiB;AAC1B,UAAI,KAAK,SAAS,QAAQ,UAAU,KAAK,QAAQ,SAAS,GAAG;AAAA,IAC/D,OAAO;AACL,UAAI,KAAK,eAAe;AACxB,UAAI,KAAK,cAAc,QAAQ,UAAU,KAAK,QAAQ,SAAS,GAAG;AAClE,UAAI,OAAO,WAAW,EAAG,KAAI,KAAK,cAAc,OAAO,QAAQ,EAAE;AACjE,UAAI,OAAO,UAAU,EAAG,KAAI,KAAK,cAAc,OAAO,OAAO,EAAE;AAC/D,UAAI,OAAO,iBAAiB,EAAG,KAAI,KAAK,cAAc,OAAO,cAAc,QAAQ;AAAA,IACrF;AACA,QAAI,MAAM;AAAA,EACZ,UAAE;AACA,QAAI,MAAM;AAAA,EACZ;AACF;","names":[]}
|
package/dist/push-GRCPUMV6.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
assertGhAvailable,
|
|
4
|
-
createGist,
|
|
5
|
-
loadSyncConfig,
|
|
6
|
-
memoryToSyncRow,
|
|
7
|
-
mergeFromRemote,
|
|
8
|
-
readGist,
|
|
9
|
-
updateGist
|
|
10
|
-
} from "./chunk-7YDBTED2.js";
|
|
11
|
-
import {
|
|
12
|
-
SyncPayloadSchema
|
|
13
|
-
} from "./chunk-J5NT4JGE.js";
|
|
14
|
-
import {
|
|
15
|
-
initStorage
|
|
16
|
-
} from "./chunk-YEGOHLE7.js";
|
|
17
|
-
import "./chunk-JXFTVFPC.js";
|
|
18
|
-
import "./chunk-ZMSHFAZQ.js";
|
|
19
|
-
import "./chunk-Z6FBT44W.js";
|
|
20
|
-
import {
|
|
21
|
-
log
|
|
22
|
-
} from "./chunk-RJGXPH7P.js";
|
|
23
|
-
|
|
24
|
-
// src/commands/memory/subcommands/push.ts
|
|
25
|
-
import { hostname } from "os";
|
|
26
|
-
import { confirm } from "@inquirer/prompts";
|
|
27
|
-
async function runPush(opts) {
|
|
28
|
-
assertGhAvailable();
|
|
29
|
-
const { requireMemoryDeps } = await import("./require-deps-NKRCPVAO.js");
|
|
30
|
-
await requireMemoryDeps();
|
|
31
|
-
const ctx = initStorage();
|
|
32
|
-
try {
|
|
33
|
-
const syncConfig = loadSyncConfig();
|
|
34
|
-
if (syncConfig) {
|
|
35
|
-
const raw = readGist(syncConfig.gistId);
|
|
36
|
-
if (raw) {
|
|
37
|
-
try {
|
|
38
|
-
const remote = SyncPayloadSchema.parse(JSON.parse(raw));
|
|
39
|
-
mergeFromRemote(ctx.memoryRepo, ctx.relationRepo, remote, opts.project);
|
|
40
|
-
} catch {
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
const localMemories = ctx.memoryRepo.getAllForSync(opts.project);
|
|
45
|
-
const allRelations = ctx.relationRepo.getAll();
|
|
46
|
-
let finalMemories = localMemories.map(memoryToSyncRow);
|
|
47
|
-
let finalRelations = [];
|
|
48
|
-
if (opts.project && syncConfig) {
|
|
49
|
-
const raw = readGist(syncConfig.gistId);
|
|
50
|
-
if (raw) {
|
|
51
|
-
try {
|
|
52
|
-
const existing = SyncPayloadSchema.parse(JSON.parse(raw));
|
|
53
|
-
const otherMemories = existing.memories.filter((m) => m.project !== opts.project);
|
|
54
|
-
finalMemories = [...otherMemories, ...finalMemories];
|
|
55
|
-
const otherRelations = existing.relations.filter((r) => {
|
|
56
|
-
const localIds = new Set(localMemories.map((m) => m.id));
|
|
57
|
-
return !localIds.has(r.source_id) && !localIds.has(r.target_id);
|
|
58
|
-
});
|
|
59
|
-
finalRelations = [...otherRelations];
|
|
60
|
-
} catch {
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
const memoryIds = new Set(finalMemories.map((m) => m.id));
|
|
65
|
-
const localRelations = allRelations.filter((r) => memoryIds.has(r.sourceId) && memoryIds.has(r.targetId)).map((r) => ({
|
|
66
|
-
source_id: r.sourceId,
|
|
67
|
-
target_id: r.targetId,
|
|
68
|
-
relation_type: r.relationType,
|
|
69
|
-
created_at: r.createdAt
|
|
70
|
-
}));
|
|
71
|
-
const mergedRelations = [...new Map(
|
|
72
|
-
[...finalRelations, ...localRelations].map((r) => [`${r.source_id}:${r.target_id}:${r.relation_type}`, r])
|
|
73
|
-
).values()];
|
|
74
|
-
const payload = {
|
|
75
|
-
version: 1,
|
|
76
|
-
machine_id: hostname(),
|
|
77
|
-
pushed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
78
|
-
memories: finalMemories,
|
|
79
|
-
relations: mergedRelations
|
|
80
|
-
};
|
|
81
|
-
const json = JSON.stringify(payload, null, 2);
|
|
82
|
-
if (!syncConfig) {
|
|
83
|
-
if (!opts.yes) {
|
|
84
|
-
const proceed = await confirm({
|
|
85
|
-
message: "Create a private GitHub Gist for memory sync?",
|
|
86
|
-
default: true
|
|
87
|
-
});
|
|
88
|
-
if (!proceed) {
|
|
89
|
-
log.info("Skipped.");
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
createGist(json);
|
|
94
|
-
} else {
|
|
95
|
-
updateGist(syncConfig.gistId, json);
|
|
96
|
-
}
|
|
97
|
-
log.blank();
|
|
98
|
-
log.step("Push complete");
|
|
99
|
-
if (opts.project) {
|
|
100
|
-
log.info(`Project: ${opts.project} (${localMemories.length} memories)`);
|
|
101
|
-
log.info(`Total: ${finalMemories.length} memories in gist`);
|
|
102
|
-
} else {
|
|
103
|
-
log.info(`Memories: ${finalMemories.length}`);
|
|
104
|
-
}
|
|
105
|
-
log.info(`Relations: ${mergedRelations.length}`);
|
|
106
|
-
log.blank();
|
|
107
|
-
} finally {
|
|
108
|
-
ctx.close();
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
export {
|
|
112
|
-
runPush
|
|
113
|
-
};
|
|
114
|
-
//# sourceMappingURL=push-GRCPUMV6.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/memory/subcommands/push.ts"],"sourcesContent":["import { hostname } from 'node:os';\nimport { confirm } from '@inquirer/prompts';\nimport { log } from '../../../lib/output.js';\nimport { initStorage } from './init-storage.js';\nimport {\n assertGhAvailable,\n loadSyncConfig,\n readGist,\n createGist,\n updateGist,\n} from '../utils/gist-transport.js';\nimport { mergeFromRemote, memoryToSyncRow } from '../utils/sync-merge.js';\nimport { SyncPayloadSchema } from '../types.js';\nimport type { SyncPayload, SyncRelationRow } from '../types.js';\n\ninterface PushOpts {\n readonly project?: string;\n readonly yes?: boolean;\n}\n\nexport async function runPush(opts: PushOpts): Promise<void> {\n assertGhAvailable();\n\n const { requireMemoryDeps } = await import('../utils/require-deps.js');\n await requireMemoryDeps();\n const ctx = initStorage();\n\n try {\n const syncConfig = loadSyncConfig();\n\n // Pull-before-push: merge remote changes first\n if (syncConfig) {\n const raw = readGist(syncConfig.gistId);\n if (raw) {\n try {\n const remote = SyncPayloadSchema.parse(JSON.parse(raw));\n mergeFromRemote(ctx.memoryRepo, ctx.relationRepo, remote, opts.project);\n } catch { /* ignore corrupt remote — overwrite with fresh data */ }\n }\n }\n\n // Serialize local memories\n const localMemories = ctx.memoryRepo.getAllForSync(opts.project);\n const allRelations = ctx.relationRepo.getAll();\n\n // For project-scoped push: merge local project memories into existing gist\n // so other projects' memories aren't nuked\n let finalMemories = localMemories.map(memoryToSyncRow);\n let finalRelations: readonly SyncRelationRow[] = [];\n\n if (opts.project && syncConfig) {\n const raw = readGist(syncConfig.gistId);\n if (raw) {\n try {\n const existing = SyncPayloadSchema.parse(JSON.parse(raw));\n const otherMemories = existing.memories.filter((m) => m.project !== opts.project);\n finalMemories = [...otherMemories, ...finalMemories];\n const otherRelations = existing.relations.filter((r) => {\n const localIds = new Set(localMemories.map((m) => m.id));\n return !localIds.has(r.source_id) && !localIds.has(r.target_id);\n });\n finalRelations = [...otherRelations];\n } catch { /* corrupt gist — overwrite */ }\n }\n }\n\n const memoryIds = new Set(finalMemories.map((m) => m.id));\n const localRelations: readonly SyncRelationRow[] = allRelations\n .filter((r) => memoryIds.has(r.sourceId) && memoryIds.has(r.targetId))\n .map((r) => ({\n source_id: r.sourceId,\n target_id: r.targetId,\n relation_type: r.relationType,\n created_at: r.createdAt,\n }));\n\n const mergedRelations = [...new Map(\n [...finalRelations, ...localRelations].map((r) => [`${r.source_id}:${r.target_id}:${r.relation_type}`, r]),\n ).values()];\n\n const payload: SyncPayload = {\n version: 1,\n machine_id: hostname(),\n pushed_at: new Date().toISOString(),\n memories: finalMemories,\n relations: mergedRelations,\n };\n\n const json = JSON.stringify(payload, null, 2);\n\n if (!syncConfig) {\n if (!opts.yes) {\n const proceed = await confirm({\n message: 'Create a private GitHub Gist for memory sync?',\n default: true,\n });\n if (!proceed) {\n log.info('Skipped.');\n return;\n }\n }\n createGist(json);\n } else {\n updateGist(syncConfig.gistId, json);\n }\n\n log.blank();\n log.step('Push complete');\n if (opts.project) {\n log.info(`Project: ${opts.project} (${localMemories.length} memories)`);\n log.info(`Total: ${finalMemories.length} memories in gist`);\n } else {\n log.info(`Memories: ${finalMemories.length}`);\n }\n log.info(`Relations: ${mergedRelations.length}`);\n log.blank();\n } finally {\n ctx.close();\n }\n}\n"],"mappings":"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","names":[]}
|