@wirecat/cli-core 0.499.0 → 0.501.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/CHANGELOG.md +48 -0
- package/dist/calendar/mcp/index.d.ts +12 -12
- package/dist/cli/envelope.d.ts +11 -1
- package/dist/cli/envelope.js +15 -3
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/meeting-preparation-answer.d.ts +8 -0
- package/dist/cli/meeting-preparation-projects.d.ts +8 -0
- package/dist/cli/meeting-preparation-read.d.ts +8 -0
- package/dist/cli/meeting-series-inventory-read.d.ts +8 -0
- package/dist/cli/messenger/messages-search-command.js +4 -1
- package/dist/cli/messenger/search-answers.d.ts +3 -0
- package/dist/cli/messenger/search-answers.js +6 -0
- package/dist/cli/messenger/search-command.js +4 -1
- package/dist/domain/knowledge.d.ts +1 -1
- package/dist/domain/knowledge.js +1 -1
- package/dist/entities/fact.d.ts +15 -1
- package/dist/entities/fact.js +6 -1
- package/dist/entities/fields.d.ts +11 -0
- package/dist/entities/fields.js +11 -0
- package/dist/entities/index.d.ts +49 -1
- package/dist/entities/meeting-preparation.d.ts +8 -0
- package/dist/entities/meeting-series-inventory.d.ts +8 -0
- package/dist/entities/memory.d.ts +14 -0
- package/dist/entities/memory.js +6 -1
- package/dist/mcp/meeting-preparation.d.ts +8 -0
- package/dist/mcp/meeting-series-inventory.d.ts +8 -0
- package/dist/meetings/mcp/index.d.ts +15 -15
- package/dist/meetings/project-evidence-answer.d.ts +8 -0
- package/dist/search/total.d.ts +13 -0
- package/dist/search/total.js +14 -0
- package/dist/services/index.d.ts +2 -1
- package/dist/services/index.js +2 -1
- package/dist/services/messages-archive-search.js +13 -3
- package/dist/services/messages-discovery.d.ts +6 -0
- package/dist/services/messages-discovery.js +14 -11
- package/dist/services/messages-search.d.ts +5 -0
- package/dist/services/messages-search.js +22 -0
- package/dist/services/messages.d.ts +3 -0
- package/dist/services/notes-search.d.ts +14 -2
- package/dist/services/notes-search.js +101 -19
- package/dist/store/index.d.ts +1 -0
- package/dist/store/project-transfer/request.d.ts +1 -1
- package/dist/store/project-transfer/schema.d.ts +2 -2
- package/dist/store/project-transfer/snapshot-model.d.ts +2 -2
- package/dist/store/queries.d.ts +2 -0
- package/dist/store/queries.js +1 -0
- package/dist/store/sqlite/evidence-sources.d.ts +23 -0
- package/dist/store/sqlite/evidence-sources.js +59 -0
- package/dist/store/sqlite/facts.d.ts +16 -0
- package/dist/store/sqlite/facts.js +39 -5
- package/dist/store/sqlite/lucene.d.ts +5 -0
- package/dist/store/sqlite/lucene.js +17 -0
- package/dist/store/sqlite/memories.d.ts +28 -0
- package/dist/store/sqlite/memories.js +62 -3
- package/dist/store/sqlite/note-search.d.ts +18 -0
- package/dist/store/sqlite/note-search.js +40 -4
- package/dist/store/sqlite/project-transfer/snapshot.d.ts +1 -1
- package/package.json +3 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MEMORY_KINDS, MEMORY_SCOPES, type MEMORY_STATUSES } from "../../domain/knowledge.js";
|
|
2
2
|
import { type Actor } from "./actors.js";
|
|
3
|
+
import { type EvidenceSource } from "./evidence-sources.js";
|
|
3
4
|
import { type NoteIndexState } from "./note-index.js";
|
|
4
5
|
import type { StoreContext } from "./open.js";
|
|
5
6
|
/** Who wrote it: the owner, or an agent by its bot handle and the model it ran on. */
|
|
@@ -14,6 +15,10 @@ export interface Memory {
|
|
|
14
15
|
body: string;
|
|
15
16
|
/** What it is about, as a reference; `null` for a general fact. */
|
|
16
17
|
subject: string | null;
|
|
18
|
+
/** What the subject is called; `null` for the owner, who has no name in the store, and for a nameless row. */
|
|
19
|
+
subjectName: string | null;
|
|
20
|
+
/** The subject is the owner. */
|
|
21
|
+
subjectIsOwner: boolean;
|
|
17
22
|
/** `name` is a bot's handle; `null` for a person. */
|
|
18
23
|
author: {
|
|
19
24
|
type: Actor["type"];
|
|
@@ -59,6 +64,17 @@ export interface MemoriesStore {
|
|
|
59
64
|
confirm(reference: string): Promise<Memory>;
|
|
60
65
|
/** Its evidence no longer holds. */
|
|
61
66
|
markStale(reference: string): Promise<Memory>;
|
|
67
|
+
/**
|
|
68
|
+
* Erases the memory: its row, its text in the search and meaning indexes, and every link from or to it. A memory
|
|
69
|
+
* that replaced it no longer names it. A backup made before keeps it.
|
|
70
|
+
*/
|
|
71
|
+
remove(reference: string): Promise<{
|
|
72
|
+
ref: string;
|
|
73
|
+
removed: true;
|
|
74
|
+
links: number;
|
|
75
|
+
}>;
|
|
76
|
+
/** Each reference it rests on, read back; one deleted since is `missing`. */
|
|
77
|
+
sources(reference: string): Promise<EvidenceSource[]>;
|
|
62
78
|
/** Indexes what was written since, then finds memories holding every word or a longer one it starts, best first. */
|
|
63
79
|
search(text: string, options?: {
|
|
64
80
|
subject?: string;
|
|
@@ -82,5 +98,17 @@ export declare const evidenceOf: (context: StoreContext, from: {
|
|
|
82
98
|
type: string;
|
|
83
99
|
id: number;
|
|
84
100
|
}) => string[];
|
|
101
|
+
/** What a memory's or fact's subject is called, for a reader who should not have to look the reference up. */
|
|
102
|
+
export declare const subjectOf: (database: StoreContext["database"], row: Row) => Pick<Memory, "subject" | "subjectName" | "subjectIsOwner">;
|
|
103
|
+
/** Counts every link from or to a row and drops the ones its delete trigger does not: those pointing at it. */
|
|
104
|
+
export declare const dropLinksOf: (database: StoreContext["database"], thing: {
|
|
105
|
+
type: string;
|
|
106
|
+
id: number;
|
|
107
|
+
}) => number;
|
|
108
|
+
/**
|
|
109
|
+
* Runs a delete so the text does not linger in the file: freed pages are zeroed, the words indexes merged so no
|
|
110
|
+
* segment still holds the erased words, and the write-ahead log emptied when no reader holds it.
|
|
111
|
+
*/
|
|
112
|
+
export declare const erase: <T>(database: StoreContext["database"], work: () => T) => T;
|
|
85
113
|
export declare const memoriesStoreOver: (context: StoreContext) => MemoriesStore;
|
|
86
114
|
export {};
|
|
@@ -2,6 +2,7 @@ import { CliError } from "@wirecat/cli-base";
|
|
|
2
2
|
import { MEMORY_KINDS, MEMORY_SCOPES } from "../../domain/knowledge.js";
|
|
3
3
|
import { normalize } from "../normalize.js";
|
|
4
4
|
import { botNamed, ownerPerson } from "./actors.js";
|
|
5
|
+
import { evidenceSourcesOf } from "./evidence-sources.js";
|
|
5
6
|
import { linkKind } from "./link-kinds.js";
|
|
6
7
|
import { CORPORA, corpusIndexState, drainCorpus } from "./note-index.js";
|
|
7
8
|
import { requiredThing } from "./notes.js";
|
|
@@ -42,6 +43,55 @@ export const evidenceOf = (context, from) => context.database
|
|
|
42
43
|
.prepare(`SELECT to_type, to_id FROM links WHERE from_type = ? AND from_id = ? AND kind = ${linkKind("evidence")} AND to_id IS NOT NULL ORDER BY id`)
|
|
43
44
|
.all(from.type, from.id)
|
|
44
45
|
.flatMap((row) => referenceOfThing(context.database, storedThing(row.to_type, row.to_id)) ?? []);
|
|
46
|
+
const SUBJECT_NAMES = {
|
|
47
|
+
person: "SELECT p.owner, coalesce(p.name, (SELECT a.name FROM aliases a WHERE a.aliasable_type = 'person' " +
|
|
48
|
+
"AND a.aliasable_id = p.id ORDER BY a.display DESC, a.id LIMIT 1), (SELECT i.name FROM identity_links l " +
|
|
49
|
+
"JOIN identities i ON i.id = l.identity_id WHERE l.person_id = p.id AND i.name IS NOT NULL ORDER BY i.id LIMIT 1)) " +
|
|
50
|
+
"AS name FROM persons p WHERE p.id = ?",
|
|
51
|
+
project: "SELECT 0 AS owner, name FROM projects WHERE id = ?",
|
|
52
|
+
organization: "SELECT 0 AS owner, name FROM organizations WHERE id = ?",
|
|
53
|
+
};
|
|
54
|
+
/** What a memory's or fact's subject is called, for a reader who should not have to look the reference up. */
|
|
55
|
+
export const subjectOf = (database, row) => {
|
|
56
|
+
if (row.subject_type == null)
|
|
57
|
+
return { subject: null, subjectName: null, subjectIsOwner: false };
|
|
58
|
+
const thing = storedThing(row.subject_type, row.subject_id);
|
|
59
|
+
const read = SUBJECT_NAMES[thing.type];
|
|
60
|
+
const named = read === undefined ? undefined : database.prepare(read).get(thing.id);
|
|
61
|
+
return {
|
|
62
|
+
subject: referenceOfThing(database, thing) ?? null,
|
|
63
|
+
subjectName: named?.name == null ? null : String(named.name),
|
|
64
|
+
subjectIsOwner: Number(named?.owner) === 1,
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
/** Counts every link from or to a row and drops the ones its delete trigger does not: those pointing at it. */
|
|
68
|
+
export const dropLinksOf = (database, thing) => {
|
|
69
|
+
const count = Number(database
|
|
70
|
+
.prepare("SELECT count(*) AS n FROM links WHERE (from_type = ? AND from_id = ?) OR (to_type = ? AND to_id = ?)")
|
|
71
|
+
.get(thing.type, thing.id, thing.type, thing.id)?.n);
|
|
72
|
+
database.prepare("DELETE FROM links WHERE to_type = ? AND to_id = ?").run(thing.type, thing.id);
|
|
73
|
+
return count;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Runs a delete so the text does not linger in the file: freed pages are zeroed, the words indexes merged so no
|
|
77
|
+
* segment still holds the erased words, and the write-ahead log emptied when no reader holds it.
|
|
78
|
+
*/
|
|
79
|
+
export const erase = (database, work) => {
|
|
80
|
+
database.exec("PRAGMA secure_delete = ON");
|
|
81
|
+
try {
|
|
82
|
+
const done = write(database, () => {
|
|
83
|
+
const result = work();
|
|
84
|
+
for (const index of ["memory_words", "memory_stems"])
|
|
85
|
+
database.prepare(`INSERT INTO ${index} (${index}) VALUES ('optimize')`).run();
|
|
86
|
+
return result;
|
|
87
|
+
});
|
|
88
|
+
database.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
89
|
+
return done;
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
database.exec("PRAGMA secure_delete = OFF");
|
|
93
|
+
}
|
|
94
|
+
};
|
|
45
95
|
export const memoriesStoreOver = (context) => {
|
|
46
96
|
const { database, now } = context;
|
|
47
97
|
const stemmerFor = stemmerCache();
|
|
@@ -50,9 +100,7 @@ export const memoriesStoreOver = (context) => {
|
|
|
50
100
|
ref: `memory:${row.id}`,
|
|
51
101
|
kind: row.kind,
|
|
52
102
|
body: String(row.body),
|
|
53
|
-
|
|
54
|
-
? null
|
|
55
|
-
: (referenceOfThing(database, storedThing(row.subject_type, row.subject_id)) ?? null),
|
|
103
|
+
...subjectOf(database, row),
|
|
56
104
|
author: authorOf(row),
|
|
57
105
|
model: row.model == null ? null : String(row.model),
|
|
58
106
|
confidence: row.confidence == null ? null : Number(row.confidence),
|
|
@@ -127,6 +175,17 @@ export const memoriesStoreOver = (context) => {
|
|
|
127
175
|
},
|
|
128
176
|
confirm: async (reference) => setStatus(reference, "confirmed", true),
|
|
129
177
|
markStale: async (reference) => setStatus(reference, "stale", false),
|
|
178
|
+
remove: async (reference) => {
|
|
179
|
+
const id = Number(rowOf(reference).id);
|
|
180
|
+
const links = erase(database, () => {
|
|
181
|
+
database.prepare("UPDATE memories SET supersedes_id = NULL WHERE supersedes_id = ?").run(id);
|
|
182
|
+
const count = dropLinksOf(database, { type: "memory", id });
|
|
183
|
+
database.prepare("DELETE FROM memories WHERE id = ?").run(id);
|
|
184
|
+
return count;
|
|
185
|
+
});
|
|
186
|
+
return { ref: `memory:${id}`, removed: true, links };
|
|
187
|
+
},
|
|
188
|
+
sources: async (reference) => evidenceSourcesOf(database, { type: "memory", id: Number(rowOf(reference).id) }),
|
|
130
189
|
search: async (text, { subject: subjectRef, scope, limit = 20 } = {}) => {
|
|
131
190
|
const subject = subjectRef === undefined ? undefined : requiredThing(database, subjectRef);
|
|
132
191
|
drainCorpus(database, CORPORA.memory, stemmerFor);
|
|
@@ -79,6 +79,11 @@ export declare const searchNotes: (context: StoreContext, query: NoteQuery) => {
|
|
|
79
79
|
items: NoteHit[];
|
|
80
80
|
hasMore: boolean;
|
|
81
81
|
};
|
|
82
|
+
/** The refs of the newest `limit` notes matching a query, without reading the notes themselves. */
|
|
83
|
+
export declare const matchingNoteRefs: (context: StoreContext, query: Omit<NoteQuery, "offset" | "newest">) => {
|
|
84
|
+
refs: string[];
|
|
85
|
+
hasMore: boolean;
|
|
86
|
+
};
|
|
82
87
|
export declare const searchCorpus: (context: StoreContext, query: CorpusQuery, corpus: Corpus) => CorpusRow[];
|
|
83
88
|
export interface NoteChunkToEmbed {
|
|
84
89
|
hash: string;
|
|
@@ -101,6 +106,11 @@ export interface NoteSearch extends DocumentPictureStore {
|
|
|
101
106
|
items: NoteHit[];
|
|
102
107
|
hasMore: boolean;
|
|
103
108
|
}>;
|
|
109
|
+
/** The refs of the newest `limit` notes matching the query; `hasMore` when more match. */
|
|
110
|
+
matchingRefs(query: Omit<NoteQuery, "offset" | "newest">): Promise<{
|
|
111
|
+
refs: string[];
|
|
112
|
+
hasMore: boolean;
|
|
113
|
+
}>;
|
|
104
114
|
indexState(): Promise<NoteIndexState | undefined>;
|
|
105
115
|
/** Live notes' chunks with no vector of `model`, by hash from `after`, each with its text cut again. */
|
|
106
116
|
chunksToEmbed(model: string, options: {
|
|
@@ -120,6 +130,14 @@ export interface NoteSearch extends DocumentPictureStore {
|
|
|
120
130
|
withInternal?: boolean;
|
|
121
131
|
source?: Note["source"];
|
|
122
132
|
}): Promise<NearestNote[]>;
|
|
133
|
+
/**
|
|
134
|
+
* Each of `refs` scored by its best chunk, best first, every chunk compared: a filter's own notes ranked, not the
|
|
135
|
+
* nearest overall. A note with no vector of `model` is left out; the notes themselves are not read.
|
|
136
|
+
*/
|
|
137
|
+
scoreNotes(model: string, query: Float32Array, refs: string[]): Promise<{
|
|
138
|
+
ref: string;
|
|
139
|
+
score: number;
|
|
140
|
+
}[]>;
|
|
123
141
|
}
|
|
124
142
|
export declare const noteSearchOver: (context: StoreContext) => NoteSearch;
|
|
125
143
|
export {};
|
|
@@ -63,9 +63,7 @@ const CORPORA = [
|
|
|
63
63
|
tagged: (tag) => bound("n.id IN (SELECT g.taggable_id FROM taggings g JOIN resolved_tags t ON t.id=g.tag_id WHERE t.name = ? AND g.taggable_type = 'note')", tag),
|
|
64
64
|
},
|
|
65
65
|
];
|
|
66
|
-
|
|
67
|
-
export const searchNotes = (context, query) => {
|
|
68
|
-
const offset = query.offset ?? 0;
|
|
66
|
+
const matchedRows = (context, query) => {
|
|
69
67
|
const chosen = CORPORA.filter(({ type }) => (query.source === undefined || (query.source === "file") === (type === "document")) &&
|
|
70
68
|
(!query.folderIds?.length || query.withInternal === true || type === "document"));
|
|
71
69
|
const idsOf = (type) => query.refs?.flatMap((ref) => (ref.startsWith(`${type}:`) ? [Number(ref.slice(type.length + 1))] : []));
|
|
@@ -83,6 +81,12 @@ export const searchNotes = (context, query) => {
|
|
|
83
81
|
(a.relevance ?? 0) - (b.relevance ?? 0) ||
|
|
84
82
|
(b.at ?? 0) - (a.at ?? 0) ||
|
|
85
83
|
a.id - b.id);
|
|
84
|
+
return rows;
|
|
85
|
+
};
|
|
86
|
+
/** Notes matching a parsed query, by the same language as messages: files and written notes, merged. */
|
|
87
|
+
export const searchNotes = (context, query) => {
|
|
88
|
+
const offset = query.offset ?? 0;
|
|
89
|
+
const rows = matchedRows(context, query);
|
|
86
90
|
const read = {
|
|
87
91
|
document: context.database.prepare("SELECT * FROM documents WHERE id = ?"),
|
|
88
92
|
note: context.database.prepare("SELECT * FROM notes WHERE id = ?"),
|
|
@@ -102,6 +106,11 @@ export const searchNotes = (context, query) => {
|
|
|
102
106
|
hasMore: rows.length > offset + query.limit,
|
|
103
107
|
};
|
|
104
108
|
};
|
|
109
|
+
/** The refs of the newest `limit` notes matching a query, without reading the notes themselves. */
|
|
110
|
+
export const matchingNoteRefs = (context, query) => {
|
|
111
|
+
const rows = matchedRows(context, { ...query, newest: true });
|
|
112
|
+
return { refs: rows.slice(0, query.limit).map(({ type, id }) => `${type}:${id}`), hasMore: rows.length > query.limit };
|
|
113
|
+
};
|
|
105
114
|
export const searchCorpus = (context, query, corpus) => {
|
|
106
115
|
const { database } = context;
|
|
107
116
|
const wordMatch = (match) => ({
|
|
@@ -282,7 +291,7 @@ export const searchCorpus = (context, query, corpus) => {
|
|
|
282
291
|
: "";
|
|
283
292
|
const window = tests.size ? QUERY_LIMITS.candidates + 1 : query.limit + offset + 1;
|
|
284
293
|
const rows = database
|
|
285
|
-
.prepare(`${ctes.length ? `WITH ${ctes.join(", ")} ` : ""}SELECT n
|
|
294
|
+
.prepare(`${ctes.length ? `WITH ${ctes.join(", ")} ` : ""}SELECT ${tests.size ? "n.*" : "n.id, n.at"}, ${ranking ? "f.rank" : "NULL"} AS relevance${exactTier ? ", n.id IN (SELECT id FROM x) AS exact" : ""}${projection}
|
|
286
295
|
FROM ${corpus.view} n${ranking ? " LEFT JOIN f ON f.id = n.id" : ""} WHERE ${where.sql} ORDER BY ${order} LIMIT ?`)
|
|
287
296
|
.all(...cteParams, ...leaves.flatMap(([, fragment]) => (tests.size ? fragment.params : [])), ...where.params, window);
|
|
288
297
|
if (tests.size && rows.length > QUERY_LIMITS.candidates)
|
|
@@ -346,6 +355,10 @@ export const noteSearchOver = (context) => {
|
|
|
346
355
|
drain();
|
|
347
356
|
return searchNotes(context, query);
|
|
348
357
|
},
|
|
358
|
+
matchingRefs: async (query) => {
|
|
359
|
+
drain();
|
|
360
|
+
return matchingNoteRefs(context, query);
|
|
361
|
+
},
|
|
349
362
|
indexState: async () => noteIndexState(database),
|
|
350
363
|
chunksToEmbed: async (model, { after, limit }) => {
|
|
351
364
|
drain();
|
|
@@ -456,5 +469,28 @@ export const noteSearchOver = (context) => {
|
|
|
456
469
|
return note ? [{ ref: note.ref, note, score, range: { start, end } }] : [];
|
|
457
470
|
});
|
|
458
471
|
},
|
|
472
|
+
scoreNotes: async (model, query, refs) => {
|
|
473
|
+
drain();
|
|
474
|
+
const scope = live(undefined, undefined, true);
|
|
475
|
+
const owned = database.prepare(`SELECT k.chunkable_type AS type, k.chunkable_id AS owner, v.vector
|
|
476
|
+
FROM chunks k JOIN embeddings v ON v.model = ? AND v.content_hash = k.content_hash
|
|
477
|
+
WHERE k.chunkable_type = ? AND k.chunkable_id IN (SELECT value FROM json_each(?))${scope.sql}`);
|
|
478
|
+
const best = new Map();
|
|
479
|
+
for (const type of ["document", "note"]) {
|
|
480
|
+
const ids = refs.flatMap((ref) => (ref.startsWith(`${type}:`) ? [Number(ref.slice(type.length + 1))] : []));
|
|
481
|
+
if (!ids.length)
|
|
482
|
+
continue;
|
|
483
|
+
for (const row of owned.all(model, type, JSON.stringify(ids), ...scope.params)) {
|
|
484
|
+
const key = `${row.type}:${row.owner}`;
|
|
485
|
+
const score = dot(query, row.vector);
|
|
486
|
+
if (score > (best.get(key) ?? Number.NEGATIVE_INFINITY))
|
|
487
|
+
best.set(key, score);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
const order = new Map(refs.map((ref, index) => [ref, index]));
|
|
491
|
+
return [...best]
|
|
492
|
+
.map(([ref, score]) => ({ ref, score }))
|
|
493
|
+
.sort((a, b) => b.score - a.score || (order.get(a.ref) ?? 0) - (order.get(b.ref) ?? 0));
|
|
494
|
+
},
|
|
459
495
|
};
|
|
460
496
|
};
|
|
@@ -7,7 +7,7 @@ export declare const projectAnnotationSnapshot: (database: CacheDatabase, projec
|
|
|
7
7
|
ref: string;
|
|
8
8
|
type: "decision" | "fact" | "promise" | "question" | "statement";
|
|
9
9
|
statement: string;
|
|
10
|
-
status: "accepted" | "proposed" | "reversed" | "superseded";
|
|
10
|
+
status: "accepted" | "proposed" | "rejected" | "reversed" | "superseded";
|
|
11
11
|
subject: string | null;
|
|
12
12
|
occurred_at: number | null;
|
|
13
13
|
supersedes: string | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wirecat/cli-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.501.0",
|
|
4
4
|
"description": "The messenger-neutral half of a messaging CLI: domain model, message locators, rendering, name resolution, the SQLite seam, the command skeleton and shared read commands, the send guard, run records and the message store",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Viacheslav Ptsarev",
|
|
@@ -247,7 +247,7 @@
|
|
|
247
247
|
"@types/node": "^22.20.5",
|
|
248
248
|
"@types/pngjs": "6.0.5",
|
|
249
249
|
"@vitest/coverage-v8": "^5.0.5",
|
|
250
|
-
"@wirecat/cli-base": "0.
|
|
250
|
+
"@wirecat/cli-base": "0.67.0",
|
|
251
251
|
"@wirecat/cli-core-legacy-tags": "npm:@wirecat/cli-core@0.414.0",
|
|
252
252
|
"commander": "15.0.0",
|
|
253
253
|
"cspell": "10.4.0",
|
|
@@ -267,7 +267,7 @@
|
|
|
267
267
|
},
|
|
268
268
|
"peerDependencies": {
|
|
269
269
|
"@napi-rs/canvas": ">=0.1.69 <2",
|
|
270
|
-
"@wirecat/cli-base": ">=0.
|
|
270
|
+
"@wirecat/cli-base": ">=0.67.0 <0.68.0",
|
|
271
271
|
"commander": ">=15"
|
|
272
272
|
},
|
|
273
273
|
"bin": {
|