@lamplitisles/codex-for-love 0.5.1 → 0.6.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/package.json +1 -1
- package/vendor/build/_app/immutable/assets/0.CfdLiH0M.css +2 -0
- package/vendor/build/_app/immutable/chunks/B4it5vzu.js +1 -0
- package/vendor/build/_app/immutable/chunks/{BZwtE-rc.js → C4_NpwM1.js} +4 -4
- package/vendor/build/_app/immutable/chunks/CLwTq0ua.js +3 -0
- package/vendor/build/_app/immutable/chunks/{MojBje2g.js → hmUBTeUN.js} +1 -1
- package/vendor/build/_app/immutable/entry/app.DWpdogiL.js +2 -0
- package/vendor/build/_app/immutable/entry/start.ZF-Jvc9b.js +1 -0
- package/vendor/build/_app/immutable/nodes/0.DsknM3BK.js +1 -0
- package/vendor/build/_app/immutable/nodes/1.Be8-HBRE.js +1 -0
- package/vendor/build/_app/immutable/nodes/2.Do9ypv2d.js +330 -0
- package/vendor/build/_app/version.json +1 -1
- package/vendor/build/index.html +10 -10
- package/vendor/runtime/cli.mjs +129 -1
- package/vendor/runtime/companion-mcp.mjs +149 -0
- package/vendor/build/_app/immutable/assets/0.DbZI1-K0.css +0 -2
- package/vendor/build/_app/immutable/chunks/C2DTc7yw.js +0 -3
- package/vendor/build/_app/immutable/chunks/CyqZh0gB.js +0 -1
- package/vendor/build/_app/immutable/entry/app.zliTtOtE.js +0 -2
- package/vendor/build/_app/immutable/entry/start.D7gYhQNp.js +0 -1
- package/vendor/build/_app/immutable/nodes/0.DreEev9t.js +0 -1
- package/vendor/build/_app/immutable/nodes/1.Bd5XGanj.js +0 -1
- package/vendor/build/_app/immutable/nodes/2.GSHICjNc.js +0 -330
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"
|
|
1
|
+
{"version":"1790151901957"}
|
package/vendor/build/index.html
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
2
|
<html lang="en" data-theme="sticker-messenger">
|
|
3
|
-
<head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" /><script>(function(){try{var appearance=localStorage.getItem('her.companion.appearance');var language=localStorage.getItem('her.companion.language');var systemDark=matchMedia('(prefers-color-scheme: dark)').matches;var dark=appearance==='dark'||(appearance!=='light'&&systemDark);document.documentElement.dataset.theme=dark?'night-voyage':'sticker-messenger';document.documentElement.lang=language==='zh'?'zh-Hans':'en'}catch(_){var systemDark=matchMedia('(prefers-color-scheme: dark)').matches;document.documentElement.dataset.theme=systemDark?'night-voyage':'sticker-messenger'}})();</script><link href="/_app/immutable/entry/start.
|
|
4
|
-
<link href="/_app/immutable/chunks/
|
|
5
|
-
<link href="/_app/immutable/chunks/
|
|
6
|
-
<link href="/_app/immutable/chunks/
|
|
7
|
-
<link href="/_app/immutable/entry/app.
|
|
3
|
+
<head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" /><script>(function(){try{var appearance=localStorage.getItem('her.companion.appearance');var language=localStorage.getItem('her.companion.language');var systemDark=matchMedia('(prefers-color-scheme: dark)').matches;var dark=appearance==='dark'||(appearance!=='light'&&systemDark);document.documentElement.dataset.theme=dark?'night-voyage':'sticker-messenger';document.documentElement.lang=language==='zh'?'zh-Hans':'en'}catch(_){var systemDark=matchMedia('(prefers-color-scheme: dark)').matches;document.documentElement.dataset.theme=systemDark?'night-voyage':'sticker-messenger'}})();</script><link href="/_app/immutable/entry/start.ZF-Jvc9b.js" rel="modulepreload">
|
|
4
|
+
<link href="/_app/immutable/chunks/hmUBTeUN.js" rel="modulepreload">
|
|
5
|
+
<link href="/_app/immutable/chunks/CLwTq0ua.js" rel="modulepreload">
|
|
6
|
+
<link href="/_app/immutable/chunks/B4it5vzu.js" rel="modulepreload">
|
|
7
|
+
<link href="/_app/immutable/entry/app.DWpdogiL.js" rel="modulepreload">
|
|
8
8
|
<link href="/_app/immutable/chunks/uBIymjUX.js" rel="modulepreload">
|
|
9
9
|
<link href="/_app/immutable/chunks/xihTtKlq.js" rel="modulepreload">
|
|
10
|
-
<link href="/_app/immutable/nodes/0.
|
|
10
|
+
<link href="/_app/immutable/nodes/0.DsknM3BK.js" rel="modulepreload">
|
|
11
11
|
|
|
12
|
-
<link href="/_app/immutable/assets/0.
|
|
12
|
+
<link href="/_app/immutable/assets/0.CfdLiH0M.css" rel="stylesheet"></head>
|
|
13
13
|
<body data-sveltekit-preload-data="hover"><div style="display: contents">
|
|
14
14
|
<script>
|
|
15
15
|
{
|
|
16
|
-
|
|
16
|
+
__sveltekit_st3em4 = {
|
|
17
17
|
base: ""
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
const element = document.currentScript.parentElement;
|
|
21
21
|
|
|
22
22
|
Promise.all([
|
|
23
|
-
import("/_app/immutable/entry/start.
|
|
24
|
-
import("/_app/immutable/entry/app.
|
|
23
|
+
import("/_app/immutable/entry/start.ZF-Jvc9b.js"),
|
|
24
|
+
import("/_app/immutable/entry/app.DWpdogiL.js")
|
|
25
25
|
]).then(([kit, app]) => {
|
|
26
26
|
kit.start(app, element);
|
|
27
27
|
});
|
package/vendor/runtime/cli.mjs
CHANGED
|
@@ -67983,6 +67983,27 @@ function createWebServer(partner, assets, options = {}) {
|
|
|
67983
67983
|
}).strict().refine((value) => value.before === void 0 || value.after === void 0).parse(params);
|
|
67984
67984
|
return json(response, await partner.snapshot(options));
|
|
67985
67985
|
}
|
|
67986
|
+
if (path === "/api/conversation-search" && request.method === "GET") {
|
|
67987
|
+
const params = Object.fromEntries(new URL(request.url, "http://localhost").searchParams);
|
|
67988
|
+
const parsed = object({ q: string().trim().min(1).max(500) }).strict().safeParse(params);
|
|
67989
|
+
if (!parsed.success) return json(response, { error: "Invalid search query" }, 400);
|
|
67990
|
+
try {
|
|
67991
|
+
if (!options.conversationSearch) throw new Error("Search unavailable");
|
|
67992
|
+
return json(response, await options.conversationSearch.search(parsed.data.q));
|
|
67993
|
+
} catch {
|
|
67994
|
+
return json(response, { error: "Search unavailable" }, 503);
|
|
67995
|
+
}
|
|
67996
|
+
}
|
|
67997
|
+
if (path.startsWith("/api/conversation-search/") && request.method === "GET") {
|
|
67998
|
+
const id = path.slice(25);
|
|
67999
|
+
if (!/^[a-f0-9]{64}$/u.test(id)) return json(response, { error: "Invalid record id" }, 400);
|
|
68000
|
+
try {
|
|
68001
|
+
if (!options.conversationSearch) throw new Error("Search unavailable");
|
|
68002
|
+
return json(response, await options.conversationSearch.read(id));
|
|
68003
|
+
} catch {
|
|
68004
|
+
return json(response, { error: "Record unavailable" }, 404);
|
|
68005
|
+
}
|
|
68006
|
+
}
|
|
67986
68007
|
if (path === "/api/diary" && request.method === "GET") try {
|
|
67987
68008
|
return json(response, { entries: await partner.diary() });
|
|
67988
68009
|
} catch {
|
|
@@ -68133,6 +68154,110 @@ function createWebServer(partner, assets, options = {}) {
|
|
|
68133
68154
|
};
|
|
68134
68155
|
}
|
|
68135
68156
|
//#endregion
|
|
68157
|
+
//#region apps/partner/runtime/conversation-search.ts
|
|
68158
|
+
const executeFile = promisify(execFile);
|
|
68159
|
+
const idSchema = string().regex(/^[a-f0-9]{64}$/u);
|
|
68160
|
+
const querySchema = string().trim().min(1).max(500);
|
|
68161
|
+
const resultSchema = object({
|
|
68162
|
+
query: string(),
|
|
68163
|
+
estimatedTotalHits: number$1().int().nonnegative(),
|
|
68164
|
+
hits: array(object({
|
|
68165
|
+
id: idSchema,
|
|
68166
|
+
kind: _enum(["message", "compaction"]),
|
|
68167
|
+
sessionId: string(),
|
|
68168
|
+
sessionName: string().optional(),
|
|
68169
|
+
cwd: string(),
|
|
68170
|
+
role: _enum(["user", "assistant"]).optional(),
|
|
68171
|
+
phase: _enum(["commentary", "final_answer"]).optional(),
|
|
68172
|
+
createdAt: string().optional(),
|
|
68173
|
+
snippet: string()
|
|
68174
|
+
})).max(20)
|
|
68175
|
+
});
|
|
68176
|
+
const recordSchema = object({
|
|
68177
|
+
id: idSchema,
|
|
68178
|
+
kind: _enum(["message", "compaction"]),
|
|
68179
|
+
sessionId: string(),
|
|
68180
|
+
sessionName: string().optional(),
|
|
68181
|
+
cwd: string(),
|
|
68182
|
+
role: _enum(["user", "assistant"]).optional(),
|
|
68183
|
+
phase: _enum(["commentary", "final_answer"]).optional(),
|
|
68184
|
+
createdAt: string().optional(),
|
|
68185
|
+
content: string()
|
|
68186
|
+
});
|
|
68187
|
+
const contextSchema = object({
|
|
68188
|
+
messageId: idSchema,
|
|
68189
|
+
targetSourceRecordIndex: number$1().int(),
|
|
68190
|
+
truncated: boolean(),
|
|
68191
|
+
items: array(object({
|
|
68192
|
+
sourceRecordIndex: number$1().int(),
|
|
68193
|
+
kind: _enum([
|
|
68194
|
+
"message",
|
|
68195
|
+
"compaction",
|
|
68196
|
+
"tool"
|
|
68197
|
+
]),
|
|
68198
|
+
role: _enum(["user", "assistant"]).optional(),
|
|
68199
|
+
phase: string().optional(),
|
|
68200
|
+
content: string(),
|
|
68201
|
+
truncated: boolean().optional()
|
|
68202
|
+
}))
|
|
68203
|
+
});
|
|
68204
|
+
function createConversationSearch(options) {
|
|
68205
|
+
const workspace = resolve(options.workspace);
|
|
68206
|
+
const env = {
|
|
68207
|
+
...process.env,
|
|
68208
|
+
...options.env,
|
|
68209
|
+
...options.codexHome ? { CODEX_HOME: options.codexHome } : {}
|
|
68210
|
+
};
|
|
68211
|
+
const binary = env.FLICKLOG_BIN ?? "flicklog";
|
|
68212
|
+
let pending = Promise.resolve();
|
|
68213
|
+
function run(args) {
|
|
68214
|
+
const task = pending.then(async () => {
|
|
68215
|
+
if (!env.FLICKLOG_MEILI_KEY && env.CREDENTIALS_DIRECTORY) try {
|
|
68216
|
+
env.FLICKLOG_MEILI_KEY = (await readFile(join(env.CREDENTIALS_DIRECTORY, "flicklog-meili-key"), "utf8")).trim();
|
|
68217
|
+
} catch (error) {
|
|
68218
|
+
if (error.code !== "ENOENT") throw error;
|
|
68219
|
+
}
|
|
68220
|
+
const { stdout } = await executeFile(binary, args, {
|
|
68221
|
+
cwd: workspace,
|
|
68222
|
+
env,
|
|
68223
|
+
timeout: 3e5,
|
|
68224
|
+
maxBuffer: 8388608,
|
|
68225
|
+
windowsHide: true
|
|
68226
|
+
});
|
|
68227
|
+
return JSON.parse(stdout);
|
|
68228
|
+
});
|
|
68229
|
+
pending = task.then(() => void 0, () => void 0);
|
|
68230
|
+
return task;
|
|
68231
|
+
}
|
|
68232
|
+
return {
|
|
68233
|
+
async search(query, limit = 20) {
|
|
68234
|
+
const q = querySchema.parse(query);
|
|
68235
|
+
const count = number$1().int().min(1).max(20).parse(limit);
|
|
68236
|
+
const value = object({ results: resultSchema }).parse(await run([
|
|
68237
|
+
"search",
|
|
68238
|
+
q,
|
|
68239
|
+
"--limit",
|
|
68240
|
+
String(count)
|
|
68241
|
+
]));
|
|
68242
|
+
return {
|
|
68243
|
+
...value.results,
|
|
68244
|
+
hits: value.results.hits.filter((hit) => resolve(hit.cwd) === workspace)
|
|
68245
|
+
};
|
|
68246
|
+
},
|
|
68247
|
+
async read(id) {
|
|
68248
|
+
const selected = idSchema.parse(id);
|
|
68249
|
+
const record = recordSchema.parse(await run(["get", selected]));
|
|
68250
|
+
if (resolve(record.cwd) !== workspace) throw new Error("Conversation record is outside this workspace");
|
|
68251
|
+
const context = contextSchema.parse(await run(["context", selected]));
|
|
68252
|
+
if (context.messageId !== selected) throw new Error("Conversation context does not match the record");
|
|
68253
|
+
return {
|
|
68254
|
+
record,
|
|
68255
|
+
context
|
|
68256
|
+
};
|
|
68257
|
+
}
|
|
68258
|
+
};
|
|
68259
|
+
}
|
|
68260
|
+
//#endregion
|
|
68136
68261
|
//#region apps/partner/runtime/migrate-relationship-journal.ts
|
|
68137
68262
|
/** One-time, explicit conversion of a legacy CFL relationship table. */
|
|
68138
68263
|
async function migrateRelationshipJournal(workspace) {
|
|
@@ -68234,7 +68359,10 @@ if (command === "credential") {
|
|
|
68234
68359
|
const partner = await createPartner(config, credentials);
|
|
68235
68360
|
let app;
|
|
68236
68361
|
try {
|
|
68237
|
-
app = createWebServer(partner, assets
|
|
68362
|
+
app = createWebServer(partner, assets, { conversationSearch: createConversationSearch({
|
|
68363
|
+
workspace: config.workspace,
|
|
68364
|
+
codexHome: config.codex.home
|
|
68365
|
+
}) });
|
|
68238
68366
|
} catch (error) {
|
|
68239
68367
|
await partner.close();
|
|
68240
68368
|
throw error;
|
|
@@ -23011,12 +23011,120 @@ async function withAvailability(images) {
|
|
|
23011
23011
|
}));
|
|
23012
23012
|
}
|
|
23013
23013
|
//#endregion
|
|
23014
|
+
//#region apps/partner/runtime/conversation-search.ts
|
|
23015
|
+
const executeFile = promisify(execFile);
|
|
23016
|
+
const idSchema = string().regex(/^[a-f0-9]{64}$/u);
|
|
23017
|
+
const querySchema = string().trim().min(1).max(500);
|
|
23018
|
+
const resultSchema = object({
|
|
23019
|
+
query: string(),
|
|
23020
|
+
estimatedTotalHits: number().int().nonnegative(),
|
|
23021
|
+
hits: array(object({
|
|
23022
|
+
id: idSchema,
|
|
23023
|
+
kind: _enum(["message", "compaction"]),
|
|
23024
|
+
sessionId: string(),
|
|
23025
|
+
sessionName: string().optional(),
|
|
23026
|
+
cwd: string(),
|
|
23027
|
+
role: _enum(["user", "assistant"]).optional(),
|
|
23028
|
+
phase: _enum(["commentary", "final_answer"]).optional(),
|
|
23029
|
+
createdAt: string().optional(),
|
|
23030
|
+
snippet: string()
|
|
23031
|
+
})).max(20)
|
|
23032
|
+
});
|
|
23033
|
+
const recordSchema = object({
|
|
23034
|
+
id: idSchema,
|
|
23035
|
+
kind: _enum(["message", "compaction"]),
|
|
23036
|
+
sessionId: string(),
|
|
23037
|
+
sessionName: string().optional(),
|
|
23038
|
+
cwd: string(),
|
|
23039
|
+
role: _enum(["user", "assistant"]).optional(),
|
|
23040
|
+
phase: _enum(["commentary", "final_answer"]).optional(),
|
|
23041
|
+
createdAt: string().optional(),
|
|
23042
|
+
content: string()
|
|
23043
|
+
});
|
|
23044
|
+
const contextSchema = object({
|
|
23045
|
+
messageId: idSchema,
|
|
23046
|
+
targetSourceRecordIndex: number().int(),
|
|
23047
|
+
truncated: boolean(),
|
|
23048
|
+
items: array(object({
|
|
23049
|
+
sourceRecordIndex: number().int(),
|
|
23050
|
+
kind: _enum([
|
|
23051
|
+
"message",
|
|
23052
|
+
"compaction",
|
|
23053
|
+
"tool"
|
|
23054
|
+
]),
|
|
23055
|
+
role: _enum(["user", "assistant"]).optional(),
|
|
23056
|
+
phase: string().optional(),
|
|
23057
|
+
content: string(),
|
|
23058
|
+
truncated: boolean().optional()
|
|
23059
|
+
}))
|
|
23060
|
+
});
|
|
23061
|
+
function createConversationSearch(options) {
|
|
23062
|
+
const workspace = resolve(options.workspace);
|
|
23063
|
+
const env = {
|
|
23064
|
+
...process.env,
|
|
23065
|
+
...options.env,
|
|
23066
|
+
...options.codexHome ? { CODEX_HOME: options.codexHome } : {}
|
|
23067
|
+
};
|
|
23068
|
+
const binary = env.FLICKLOG_BIN ?? "flicklog";
|
|
23069
|
+
let pending = Promise.resolve();
|
|
23070
|
+
function run(args) {
|
|
23071
|
+
const task = pending.then(async () => {
|
|
23072
|
+
if (!env.FLICKLOG_MEILI_KEY && env.CREDENTIALS_DIRECTORY) try {
|
|
23073
|
+
env.FLICKLOG_MEILI_KEY = (await readFile(join(env.CREDENTIALS_DIRECTORY, "flicklog-meili-key"), "utf8")).trim();
|
|
23074
|
+
} catch (error) {
|
|
23075
|
+
if (error.code !== "ENOENT") throw error;
|
|
23076
|
+
}
|
|
23077
|
+
const { stdout } = await executeFile(binary, args, {
|
|
23078
|
+
cwd: workspace,
|
|
23079
|
+
env,
|
|
23080
|
+
timeout: 3e5,
|
|
23081
|
+
maxBuffer: 8388608,
|
|
23082
|
+
windowsHide: true
|
|
23083
|
+
});
|
|
23084
|
+
return JSON.parse(stdout);
|
|
23085
|
+
});
|
|
23086
|
+
pending = task.then(() => void 0, () => void 0);
|
|
23087
|
+
return task;
|
|
23088
|
+
}
|
|
23089
|
+
return {
|
|
23090
|
+
async search(query, limit = 20) {
|
|
23091
|
+
const q = querySchema.parse(query);
|
|
23092
|
+
const count = number().int().min(1).max(20).parse(limit);
|
|
23093
|
+
const value = object({ results: resultSchema }).parse(await run([
|
|
23094
|
+
"search",
|
|
23095
|
+
q,
|
|
23096
|
+
"--limit",
|
|
23097
|
+
String(count)
|
|
23098
|
+
]));
|
|
23099
|
+
return {
|
|
23100
|
+
...value.results,
|
|
23101
|
+
hits: value.results.hits.filter((hit) => resolve(hit.cwd) === workspace)
|
|
23102
|
+
};
|
|
23103
|
+
},
|
|
23104
|
+
async read(id) {
|
|
23105
|
+
const selected = idSchema.parse(id);
|
|
23106
|
+
const record = recordSchema.parse(await run(["get", selected]));
|
|
23107
|
+
if (resolve(record.cwd) !== workspace) throw new Error("Conversation record is outside this workspace");
|
|
23108
|
+
const context = contextSchema.parse(await run(["context", selected]));
|
|
23109
|
+
if (context.messageId !== selected) throw new Error("Conversation context does not match the record");
|
|
23110
|
+
return {
|
|
23111
|
+
record,
|
|
23112
|
+
context
|
|
23113
|
+
};
|
|
23114
|
+
}
|
|
23115
|
+
};
|
|
23116
|
+
}
|
|
23117
|
+
//#endregion
|
|
23014
23118
|
//#region apps/partner/runtime/companion-mcp.ts
|
|
23015
23119
|
const workspace = process.argv[2];
|
|
23016
23120
|
if (!workspace) throw new Error("Companion MCP requires a workspace path");
|
|
23017
23121
|
const configPath = process.argv[3];
|
|
23018
23122
|
const journal = partnerPaths(workspace).relationshipJournal;
|
|
23019
23123
|
const conversationImages = partnerPaths(workspace).conversationImages;
|
|
23124
|
+
const conversationSearch = createConversationSearch({
|
|
23125
|
+
workspace,
|
|
23126
|
+
codexHome: configPath ? (await loadConfig(configPath)).codex.home : void 0
|
|
23127
|
+
});
|
|
23020
23128
|
const server = new McpServer({
|
|
23021
23129
|
name: "companion",
|
|
23022
23130
|
version: "0.1.0"
|
|
@@ -23083,6 +23191,47 @@ server.registerTool("list_photos", {
|
|
|
23083
23191
|
})
|
|
23084
23192
|
}] };
|
|
23085
23193
|
});
|
|
23194
|
+
server.registerTool("search_conversation", {
|
|
23195
|
+
description: "Find text in our conversation records. Returns bounded highlighted excerpts; read a selected record for its full text and nearby context.",
|
|
23196
|
+
inputSchema: {
|
|
23197
|
+
query: string().trim().min(1).max(500),
|
|
23198
|
+
limit: number().int().min(1).max(20).optional()
|
|
23199
|
+
}
|
|
23200
|
+
}, async ({ query, limit }) => {
|
|
23201
|
+
try {
|
|
23202
|
+
return { content: [{
|
|
23203
|
+
type: "text",
|
|
23204
|
+
text: JSON.stringify(await conversationSearch.search(query, limit ?? 5))
|
|
23205
|
+
}] };
|
|
23206
|
+
} catch {
|
|
23207
|
+
return {
|
|
23208
|
+
content: [{
|
|
23209
|
+
type: "text",
|
|
23210
|
+
text: "Conversation search is unavailable"
|
|
23211
|
+
}],
|
|
23212
|
+
isError: true
|
|
23213
|
+
};
|
|
23214
|
+
}
|
|
23215
|
+
});
|
|
23216
|
+
server.registerTool("read_conversation_record", {
|
|
23217
|
+
description: "Read one selected conversation search result in full with nearby context.",
|
|
23218
|
+
inputSchema: { id: string().regex(/^[a-f0-9]{64}$/u) }
|
|
23219
|
+
}, async ({ id }) => {
|
|
23220
|
+
try {
|
|
23221
|
+
return { content: [{
|
|
23222
|
+
type: "text",
|
|
23223
|
+
text: JSON.stringify(await conversationSearch.read(id))
|
|
23224
|
+
}] };
|
|
23225
|
+
} catch {
|
|
23226
|
+
return {
|
|
23227
|
+
content: [{
|
|
23228
|
+
type: "text",
|
|
23229
|
+
text: "Conversation record is unavailable"
|
|
23230
|
+
}],
|
|
23231
|
+
isError: true
|
|
23232
|
+
};
|
|
23233
|
+
}
|
|
23234
|
+
});
|
|
23086
23235
|
server.registerTool("roll_dice", {
|
|
23087
23236
|
description: "Roll dice with an optional modifier and label.",
|
|
23088
23237
|
inputSchema: {
|