@hasna/prompts 0.2.1 → 0.3.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/dist/cli/index.js +1090 -92
- package/dist/db/database.d.ts +1 -0
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/projects.d.ts +10 -0
- package/dist/db/projects.d.ts.map +1 -0
- package/dist/db/prompts.d.ts +8 -0
- package/dist/db/prompts.d.ts.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +141 -3
- package/dist/lib/audit.d.ts +16 -0
- package/dist/lib/audit.d.ts.map +1 -0
- package/dist/lib/completion.d.ts +3 -0
- package/dist/lib/completion.d.ts.map +1 -0
- package/dist/lib/diff.d.ts +8 -0
- package/dist/lib/diff.d.ts.map +1 -0
- package/dist/lib/importer.d.ts +8 -0
- package/dist/lib/importer.d.ts.map +1 -1
- package/dist/lib/search.d.ts.map +1 -1
- package/dist/mcp/index.js +553 -15
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +175 -4
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/db/database.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export declare function getDbPath(): string;
|
|
|
3
3
|
export declare function getDatabase(): Database;
|
|
4
4
|
export declare function closeDatabase(): void;
|
|
5
5
|
export declare function resetDatabase(): void;
|
|
6
|
+
export declare function resolveProject(db: Database, idOrSlug: string): string | null;
|
|
6
7
|
export declare function hasFts(db: Database): boolean;
|
|
7
8
|
export declare function resolvePrompt(db: Database, idOrSlug: string): string | null;
|
|
8
9
|
//# sourceMappingURL=database.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAMrC,wBAAgB,SAAS,IAAI,MAAM,CAsBlC;AAED,wBAAgB,WAAW,IAAI,QAAQ,CAmBtC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAKpC;AAGD,wBAAgB,aAAa,IAAI,IAAI,CAEpC;
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAMrC,wBAAgB,SAAS,IAAI,MAAM,CAsBlC;AAED,wBAAgB,WAAW,IAAI,QAAQ,CAmBtC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAKpC;AAGD,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAyJD,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA0B5E;AAED,wBAAgB,MAAM,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAM5C;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkC3E"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Project } from "../types/index.js";
|
|
2
|
+
export declare function createProject(input: {
|
|
3
|
+
name: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
path?: string;
|
|
6
|
+
}): Project;
|
|
7
|
+
export declare function getProject(idOrSlug: string): Project | null;
|
|
8
|
+
export declare function listProjects(): Project[];
|
|
9
|
+
export declare function deleteProject(idOrSlug: string): void;
|
|
10
|
+
//# sourceMappingURL=projects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/db/projects.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAehD,wBAAgB,aAAa,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAWnG;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAU3D;AAED,wBAAgB,YAAY,IAAI,OAAO,EAAE,CAOxC;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAKpD"}
|
package/dist/db/prompts.d.ts
CHANGED
|
@@ -6,6 +6,14 @@ export declare function listPrompts(filter?: ListPromptsFilter): Prompt[];
|
|
|
6
6
|
export declare function updatePrompt(idOrSlug: string, input: UpdatePromptInput): Prompt;
|
|
7
7
|
export declare function deletePrompt(idOrSlug: string): void;
|
|
8
8
|
export declare function usePrompt(idOrSlug: string): Prompt;
|
|
9
|
+
export declare function getTrending(days?: number, limit?: number): Array<{
|
|
10
|
+
id: string;
|
|
11
|
+
slug: string;
|
|
12
|
+
title: string;
|
|
13
|
+
uses: number;
|
|
14
|
+
}>;
|
|
15
|
+
export declare function setExpiry(idOrSlug: string, expiresAt: string | null): Prompt;
|
|
16
|
+
export declare function setNextPrompt(idOrSlug: string, nextSlug: string | null): Prompt;
|
|
9
17
|
export declare function pinPrompt(idOrSlug: string, pinned: boolean): Prompt;
|
|
10
18
|
export declare function upsertPrompt(input: CreatePromptInput, force?: boolean): {
|
|
11
19
|
prompt: Prompt;
|
package/dist/db/prompts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/db/prompts.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,MAAM,EACN,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EAGlB,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/db/prompts.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,MAAM,EACN,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EAGlB,MAAM,mBAAmB,CAAA;AA6B1B,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CA0C7D;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOzD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAItD;AAED,wBAAgB,WAAW,CAAC,MAAM,GAAE,iBAAsB,GAAG,MAAM,EAAE,CA4CpE;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAiD/E;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAInD;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CASlD;AAED,wBAAgB,WAAW,CAAC,IAAI,SAAI,EAAE,KAAK,SAAK,GAAG,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAYlH;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAK5E;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAK/E;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAKnE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,UAAQ,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAE,CA6BtI;AAED,wBAAgB,cAAc;;;;;YAOJ,MAAM;cAAQ,MAAM;cAAQ,MAAM;eAAS,MAAM;mBAAa,MAAM;;;YAGpE,MAAM;cAAQ,MAAM;cAAQ,MAAM;eAAS,MAAM;sBAAgB,MAAM;;;oBAG/D,MAAM;eAAS,MAAM;;;gBAGzB,MAAM;eAAS,MAAM;;EAGlD"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export { createPrompt, getPrompt, requirePrompt, listPrompts, updatePrompt, deletePrompt, usePrompt, upsertPrompt, getPromptStats, pinPrompt } from "./db/prompts.js";
|
|
1
|
+
export { createPrompt, getPrompt, requirePrompt, listPrompts, updatePrompt, deletePrompt, usePrompt, upsertPrompt, getPromptStats, pinPrompt, setNextPrompt } from "./db/prompts.js";
|
|
2
2
|
export { listVersions, getVersion, restoreVersion } from "./db/versions.js";
|
|
3
3
|
export { listCollections, getCollection, ensureCollection, movePrompt } from "./db/collections.js";
|
|
4
4
|
export { registerAgent, listAgents } from "./db/agents.js";
|
|
5
5
|
export { getDatabase, getDbPath } from "./db/database.js";
|
|
6
|
+
export { createProject, getProject, listProjects, deleteProject } from "./db/projects.js";
|
|
6
7
|
export { searchPrompts, findSimilar } from "./lib/search.js";
|
|
7
8
|
export { extractVariables, extractVariableInfo, renderTemplate, validateVars } from "./lib/template.js";
|
|
8
9
|
export type { VariableInfo } from "./lib/template.js";
|
|
@@ -10,6 +11,6 @@ export { importFromJson, exportToJson } from "./lib/importer.js";
|
|
|
10
11
|
export { findDuplicates } from "./lib/duplicates.js";
|
|
11
12
|
export type { DuplicateMatch } from "./lib/duplicates.js";
|
|
12
13
|
export { generateSlug, uniqueSlug, generatePromptId } from "./lib/ids.js";
|
|
13
|
-
export type { Prompt, PromptVersion, Collection, Agent, TemplateVariable, PromptSource, CreatePromptInput, UpdatePromptInput, ListPromptsFilter, SearchResult, RenderResult, PromptStats, } from "./types/index.js";
|
|
14
|
-
export { PromptNotFoundError, VersionConflictError, DuplicateSlugError, TemplateRenderError, } from "./types/index.js";
|
|
14
|
+
export type { Prompt, PromptVersion, Collection, Agent, Project, TemplateVariable, PromptSource, CreatePromptInput, UpdatePromptInput, ListPromptsFilter, SearchResult, RenderResult, PromptStats, } from "./types/index.js";
|
|
15
|
+
export { PromptNotFoundError, VersionConflictError, DuplicateSlugError, TemplateRenderError, ProjectNotFoundError, } from "./types/index.js";
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AACpL,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC3E,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAClG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAGzF,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAG5D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACvG,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGrD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAGzD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAGzE,YAAY,EACV,MAAM,EACN,aAAa,EACb,UAAU,EACV,KAAK,EACL,OAAO,EACP,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,WAAW,GACZ,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,kBAAkB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -113,6 +113,41 @@ function runMigrations(db) {
|
|
|
113
113
|
name: "003_pinned",
|
|
114
114
|
sql: `ALTER TABLE prompts ADD COLUMN pinned INTEGER NOT NULL DEFAULT 0;`
|
|
115
115
|
},
|
|
116
|
+
{
|
|
117
|
+
name: "004_projects",
|
|
118
|
+
sql: `
|
|
119
|
+
CREATE TABLE IF NOT EXISTS projects (
|
|
120
|
+
id TEXT PRIMARY KEY,
|
|
121
|
+
name TEXT NOT NULL UNIQUE,
|
|
122
|
+
slug TEXT NOT NULL UNIQUE,
|
|
123
|
+
description TEXT,
|
|
124
|
+
path TEXT,
|
|
125
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
126
|
+
);
|
|
127
|
+
ALTER TABLE prompts ADD COLUMN project_id TEXT REFERENCES projects(id) ON DELETE SET NULL;
|
|
128
|
+
CREATE INDEX IF NOT EXISTS idx_prompts_project_id ON prompts(project_id);
|
|
129
|
+
`
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: "005_chaining",
|
|
133
|
+
sql: `ALTER TABLE prompts ADD COLUMN next_prompt TEXT;`
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: "006_expiry",
|
|
137
|
+
sql: `ALTER TABLE prompts ADD COLUMN expires_at TEXT;`
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: "007_usage_log",
|
|
141
|
+
sql: `
|
|
142
|
+
CREATE TABLE IF NOT EXISTS usage_log (
|
|
143
|
+
id TEXT PRIMARY KEY,
|
|
144
|
+
prompt_id TEXT NOT NULL REFERENCES prompts(id) ON DELETE CASCADE,
|
|
145
|
+
used_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
146
|
+
);
|
|
147
|
+
CREATE INDEX IF NOT EXISTS idx_usage_log_prompt_id ON usage_log(prompt_id);
|
|
148
|
+
CREATE INDEX IF NOT EXISTS idx_usage_log_used_at ON usage_log(used_at);
|
|
149
|
+
`
|
|
150
|
+
},
|
|
116
151
|
{
|
|
117
152
|
name: "002_fts5",
|
|
118
153
|
sql: `
|
|
@@ -153,6 +188,24 @@ function runMigrations(db) {
|
|
|
153
188
|
db.run("INSERT INTO _migrations (name) VALUES (?)", [migration.name]);
|
|
154
189
|
}
|
|
155
190
|
}
|
|
191
|
+
function resolveProject(db, idOrSlug) {
|
|
192
|
+
const byId = db.query("SELECT id FROM projects WHERE id = ?").get(idOrSlug);
|
|
193
|
+
if (byId)
|
|
194
|
+
return byId.id;
|
|
195
|
+
const bySlug = db.query("SELECT id FROM projects WHERE slug = ?").get(idOrSlug);
|
|
196
|
+
if (bySlug)
|
|
197
|
+
return bySlug.id;
|
|
198
|
+
const byName = db.query("SELECT id FROM projects WHERE lower(name) = ?").get(idOrSlug.toLowerCase());
|
|
199
|
+
if (byName)
|
|
200
|
+
return byName.id;
|
|
201
|
+
const byPrefix = db.query("SELECT id FROM projects WHERE id LIKE ? LIMIT 2").all(`${idOrSlug}%`);
|
|
202
|
+
if (byPrefix.length === 1 && byPrefix[0])
|
|
203
|
+
return byPrefix[0].id;
|
|
204
|
+
const bySlugPrefix = db.query("SELECT id FROM projects WHERE slug LIKE ? LIMIT 2").all(`${idOrSlug}%`);
|
|
205
|
+
if (bySlugPrefix.length === 1 && bySlugPrefix[0])
|
|
206
|
+
return bySlugPrefix[0].id;
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
156
209
|
function hasFts(db) {
|
|
157
210
|
return db.query("SELECT 1 FROM sqlite_master WHERE type='table' AND name='prompts_fts'").get() !== null;
|
|
158
211
|
}
|
|
@@ -378,6 +431,13 @@ class TemplateRenderError extends Error {
|
|
|
378
431
|
}
|
|
379
432
|
}
|
|
380
433
|
|
|
434
|
+
class ProjectNotFoundError extends Error {
|
|
435
|
+
constructor(id) {
|
|
436
|
+
super(`Project not found: ${id}`);
|
|
437
|
+
this.name = "ProjectNotFoundError";
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
381
441
|
// src/db/prompts.ts
|
|
382
442
|
function rowToPrompt(row) {
|
|
383
443
|
return {
|
|
@@ -391,6 +451,9 @@ function rowToPrompt(row) {
|
|
|
391
451
|
tags: JSON.parse(row["tags"] || "[]"),
|
|
392
452
|
variables: JSON.parse(row["variables"] || "[]"),
|
|
393
453
|
pinned: Boolean(row["pinned"]),
|
|
454
|
+
next_prompt: row["next_prompt"] ?? null,
|
|
455
|
+
expires_at: row["expires_at"] ?? null,
|
|
456
|
+
project_id: row["project_id"] ?? null,
|
|
394
457
|
is_template: Boolean(row["is_template"]),
|
|
395
458
|
source: row["source"],
|
|
396
459
|
version: row["version"],
|
|
@@ -414,11 +477,12 @@ function createPrompt(input) {
|
|
|
414
477
|
ensureCollection(collection);
|
|
415
478
|
const tags = JSON.stringify(input.tags || []);
|
|
416
479
|
const source = input.source || "manual";
|
|
480
|
+
const project_id = input.project_id ?? null;
|
|
417
481
|
const vars = extractVariables(input.body);
|
|
418
482
|
const variables = JSON.stringify(vars.map((v) => ({ name: v, required: true })));
|
|
419
483
|
const is_template = vars.length > 0 ? 1 : 0;
|
|
420
|
-
db.run(`INSERT INTO prompts (id, name, slug, title, body, description, collection, tags, variables, is_template, source)
|
|
421
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [id, name, slug, input.title, input.body, input.description ?? null, collection, tags, variables, is_template, source]);
|
|
484
|
+
db.run(`INSERT INTO prompts (id, name, slug, title, body, description, collection, tags, variables, is_template, source, project_id)
|
|
485
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [id, name, slug, input.title, input.body, input.description ?? null, collection, tags, variables, is_template, source, project_id]);
|
|
422
486
|
db.run(`INSERT INTO prompt_versions (id, prompt_id, body, version, changed_by)
|
|
423
487
|
VALUES (?, ?, ?, 1, ?)`, [generateId("VER"), id, input.body, input.changed_by ?? null]);
|
|
424
488
|
return getPrompt(id);
|
|
@@ -462,10 +526,16 @@ function listPrompts(filter = {}) {
|
|
|
462
526
|
params.push(`%"${tag}"%`);
|
|
463
527
|
}
|
|
464
528
|
}
|
|
529
|
+
let orderBy = "pinned DESC, use_count DESC, updated_at DESC";
|
|
530
|
+
if (filter.project_id !== undefined && filter.project_id !== null) {
|
|
531
|
+
conditions.push("(project_id = ? OR project_id IS NULL)");
|
|
532
|
+
params.push(filter.project_id);
|
|
533
|
+
orderBy = `(CASE WHEN project_id = '${filter.project_id}' THEN 0 ELSE 1 END), pinned DESC, use_count DESC, updated_at DESC`;
|
|
534
|
+
}
|
|
465
535
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
466
536
|
const limit = filter.limit ?? 100;
|
|
467
537
|
const offset = filter.offset ?? 0;
|
|
468
|
-
const rows = db.query(`SELECT * FROM prompts ${where} ORDER BY
|
|
538
|
+
const rows = db.query(`SELECT * FROM prompts ${where} ORDER BY ${orderBy} LIMIT ? OFFSET ?`).all(...params, limit, offset);
|
|
469
539
|
return rows.map(rowToPrompt);
|
|
470
540
|
}
|
|
471
541
|
function updatePrompt(idOrSlug, input) {
|
|
@@ -481,6 +551,7 @@ function updatePrompt(idOrSlug, input) {
|
|
|
481
551
|
description = COALESCE(?, description),
|
|
482
552
|
collection = COALESCE(?, collection),
|
|
483
553
|
tags = COALESCE(?, tags),
|
|
554
|
+
next_prompt = CASE WHEN ? IS NOT NULL THEN ? ELSE next_prompt END,
|
|
484
555
|
variables = ?,
|
|
485
556
|
is_template = ?,
|
|
486
557
|
version = version + 1,
|
|
@@ -491,6 +562,8 @@ function updatePrompt(idOrSlug, input) {
|
|
|
491
562
|
input.description ?? null,
|
|
492
563
|
input.collection ?? null,
|
|
493
564
|
input.tags ? JSON.stringify(input.tags) : null,
|
|
565
|
+
"next_prompt" in input ? input.next_prompt ?? "" : null,
|
|
566
|
+
"next_prompt" in input ? input.next_prompt ?? null : null,
|
|
494
567
|
variables,
|
|
495
568
|
is_template,
|
|
496
569
|
prompt.id,
|
|
@@ -513,6 +586,13 @@ function usePrompt(idOrSlug) {
|
|
|
513
586
|
const db = getDatabase();
|
|
514
587
|
const prompt = requirePrompt(idOrSlug);
|
|
515
588
|
db.run("UPDATE prompts SET use_count = use_count + 1, last_used_at = datetime('now') WHERE id = ?", [prompt.id]);
|
|
589
|
+
db.run("INSERT INTO usage_log (id, prompt_id) VALUES (?, ?)", [generateId("UL"), prompt.id]);
|
|
590
|
+
return requirePrompt(prompt.id);
|
|
591
|
+
}
|
|
592
|
+
function setNextPrompt(idOrSlug, nextSlug) {
|
|
593
|
+
const db = getDatabase();
|
|
594
|
+
const prompt = requirePrompt(idOrSlug);
|
|
595
|
+
db.run("UPDATE prompts SET next_prompt = ?, updated_at = datetime('now') WHERE id = ?", [nextSlug, prompt.id]);
|
|
516
596
|
return requirePrompt(prompt.id);
|
|
517
597
|
}
|
|
518
598
|
function pinPrompt(idOrSlug, pinned) {
|
|
@@ -625,6 +705,51 @@ function listAgents() {
|
|
|
625
705
|
const rows = db.query("SELECT * FROM agents ORDER BY last_seen_at DESC").all();
|
|
626
706
|
return rows.map(rowToAgent);
|
|
627
707
|
}
|
|
708
|
+
// src/db/projects.ts
|
|
709
|
+
function rowToProject(row, promptCount) {
|
|
710
|
+
return {
|
|
711
|
+
id: row["id"],
|
|
712
|
+
name: row["name"],
|
|
713
|
+
slug: row["slug"],
|
|
714
|
+
description: row["description"] ?? null,
|
|
715
|
+
path: row["path"] ?? null,
|
|
716
|
+
prompt_count: promptCount,
|
|
717
|
+
created_at: row["created_at"]
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
function createProject(input) {
|
|
721
|
+
const db = getDatabase();
|
|
722
|
+
const id = generateId("proj");
|
|
723
|
+
const slug = generateSlug(input.name);
|
|
724
|
+
db.run(`INSERT INTO projects (id, name, slug, description, path) VALUES (?, ?, ?, ?, ?)`, [id, input.name, slug, input.description ?? null, input.path ?? null]);
|
|
725
|
+
return getProject(id);
|
|
726
|
+
}
|
|
727
|
+
function getProject(idOrSlug) {
|
|
728
|
+
const db = getDatabase();
|
|
729
|
+
const id = resolveProject(db, idOrSlug);
|
|
730
|
+
if (!id)
|
|
731
|
+
return null;
|
|
732
|
+
const row = db.query("SELECT * FROM projects WHERE id = ?").get(id);
|
|
733
|
+
if (!row)
|
|
734
|
+
return null;
|
|
735
|
+
const countRow = db.query("SELECT COUNT(*) as n FROM prompts WHERE project_id = ?").get(id);
|
|
736
|
+
return rowToProject(row, countRow.n);
|
|
737
|
+
}
|
|
738
|
+
function listProjects() {
|
|
739
|
+
const db = getDatabase();
|
|
740
|
+
const rows = db.query("SELECT * FROM projects ORDER BY name ASC").all();
|
|
741
|
+
return rows.map((row) => {
|
|
742
|
+
const countRow = db.query("SELECT COUNT(*) as n FROM prompts WHERE project_id = ?").get(row["id"]);
|
|
743
|
+
return rowToProject(row, countRow.n);
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
function deleteProject(idOrSlug) {
|
|
747
|
+
const db = getDatabase();
|
|
748
|
+
const id = resolveProject(db, idOrSlug);
|
|
749
|
+
if (!id)
|
|
750
|
+
throw new ProjectNotFoundError(idOrSlug);
|
|
751
|
+
db.run("DELETE FROM projects WHERE id = ?", [id]);
|
|
752
|
+
}
|
|
628
753
|
// src/lib/search.ts
|
|
629
754
|
function rowToSearchResult(row, snippet) {
|
|
630
755
|
return {
|
|
@@ -639,6 +764,9 @@ function rowToSearchResult(row, snippet) {
|
|
|
639
764
|
tags: JSON.parse(row["tags"] || "[]"),
|
|
640
765
|
variables: JSON.parse(row["variables"] || "[]"),
|
|
641
766
|
pinned: Boolean(row["pinned"]),
|
|
767
|
+
next_prompt: row["next_prompt"] ?? null,
|
|
768
|
+
expires_at: row["expires_at"] ?? null,
|
|
769
|
+
project_id: row["project_id"] ?? null,
|
|
642
770
|
is_template: Boolean(row["is_template"]),
|
|
643
771
|
source: row["source"],
|
|
644
772
|
version: row["version"],
|
|
@@ -682,6 +810,10 @@ function searchPrompts(query, filter = {}) {
|
|
|
682
810
|
for (const tag of filter.tags)
|
|
683
811
|
params.push(`%"${tag}"%`);
|
|
684
812
|
}
|
|
813
|
+
if (filter.project_id !== undefined && filter.project_id !== null) {
|
|
814
|
+
conditions.push("(p.project_id = ? OR p.project_id IS NULL)");
|
|
815
|
+
params.push(filter.project_id);
|
|
816
|
+
}
|
|
685
817
|
const where = conditions.length > 0 ? `AND ${conditions.join(" AND ")}` : "";
|
|
686
818
|
const limit = filter.limit ?? 50;
|
|
687
819
|
const offset = filter.offset ?? 0;
|
|
@@ -762,6 +894,7 @@ export {
|
|
|
762
894
|
upsertPrompt,
|
|
763
895
|
updatePrompt,
|
|
764
896
|
uniqueSlug,
|
|
897
|
+
setNextPrompt,
|
|
765
898
|
searchPrompts,
|
|
766
899
|
restoreVersion,
|
|
767
900
|
requirePrompt,
|
|
@@ -771,12 +904,14 @@ export {
|
|
|
771
904
|
movePrompt,
|
|
772
905
|
listVersions,
|
|
773
906
|
listPrompts,
|
|
907
|
+
listProjects,
|
|
774
908
|
listCollections,
|
|
775
909
|
listAgents,
|
|
776
910
|
importFromJson,
|
|
777
911
|
getVersion,
|
|
778
912
|
getPromptStats,
|
|
779
913
|
getPrompt,
|
|
914
|
+
getProject,
|
|
780
915
|
getDbPath,
|
|
781
916
|
getDatabase,
|
|
782
917
|
getCollection,
|
|
@@ -789,9 +924,12 @@ export {
|
|
|
789
924
|
exportToJson,
|
|
790
925
|
ensureCollection,
|
|
791
926
|
deletePrompt,
|
|
927
|
+
deleteProject,
|
|
792
928
|
createPrompt,
|
|
929
|
+
createProject,
|
|
793
930
|
VersionConflictError,
|
|
794
931
|
TemplateRenderError,
|
|
795
932
|
PromptNotFoundError,
|
|
933
|
+
ProjectNotFoundError,
|
|
796
934
|
DuplicateSlugError
|
|
797
935
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface AuditIssue {
|
|
2
|
+
type: "orphaned-project" | "empty-collection" | "missing-version-history" | "near-duplicate-slug" | "expired";
|
|
3
|
+
severity: "error" | "warn" | "info";
|
|
4
|
+
prompt_id?: string;
|
|
5
|
+
slug?: string;
|
|
6
|
+
message: string;
|
|
7
|
+
}
|
|
8
|
+
export interface AuditReport {
|
|
9
|
+
issues: AuditIssue[];
|
|
10
|
+
errors: number;
|
|
11
|
+
warnings: number;
|
|
12
|
+
info: number;
|
|
13
|
+
checked_at: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function runAudit(): AuditReport;
|
|
16
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/lib/audit.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,kBAAkB,GAAG,kBAAkB,GAAG,yBAAyB,GAAG,qBAAqB,GAAG,SAAS,CAAA;IAC7G,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;IACnC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,QAAQ,IAAI,WAAW,CAuFtC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../src/lib/completion.ts"],"names":[],"mappings":"AAYA,wBAAgB,qBAAqB,IAAI,MAAM,CAkE9C;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAgD/C"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface DiffLine {
|
|
2
|
+
type: "added" | "removed" | "unchanged";
|
|
3
|
+
content: string;
|
|
4
|
+
lineNum?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function diffTexts(a: string, b: string): DiffLine[];
|
|
7
|
+
export declare function formatDiff(lines: DiffLine[]): string;
|
|
8
|
+
//# sourceMappingURL=diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/lib/diff.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,WAAW,CAAA;IACvC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE,CAmC1D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAMpD"}
|
package/dist/lib/importer.d.ts
CHANGED
|
@@ -31,6 +31,14 @@ export declare function importFromMarkdown(files: Array<{
|
|
|
31
31
|
filename: string;
|
|
32
32
|
content: string;
|
|
33
33
|
}>, changedBy?: string): ImportResult;
|
|
34
|
+
export interface SlashCommandScanResult {
|
|
35
|
+
scanned: Array<{
|
|
36
|
+
source: string;
|
|
37
|
+
file: string;
|
|
38
|
+
}>;
|
|
39
|
+
imported: ImportResult;
|
|
40
|
+
}
|
|
41
|
+
export declare function scanAndImportSlashCommands(rootDir: string, changedBy?: string): SlashCommandScanResult;
|
|
34
42
|
export declare function importFromClaudeCommands(files: Array<{
|
|
35
43
|
filename: string;
|
|
36
44
|
content: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../../src/lib/importer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAqB,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAElE,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC/C;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,CA0BpF;AAED,wBAAgB,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG;IACjD,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAGA;AAaD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAYvD;AAED,wBAAgB,qBAAqB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAMvG;AAGD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CA8B1F;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,CAKxH;AAKD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,EACnD,SAAS,CAAC,EAAE,MAAM,GACjB,YAAY,CAad"}
|
|
1
|
+
{"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../../src/lib/importer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAqB,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAElE,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC/C;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,CA0BpF;AAED,wBAAgB,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG;IACjD,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAGA;AAaD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAYvD;AAED,wBAAgB,qBAAqB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAMvG;AAGD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CA8B1F;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,CAKxH;AAGD,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAChD,QAAQ,EAAE,YAAY,CAAA;CACvB;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,sBAAsB,CAgDxB;AAKD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,EACnD,SAAS,CAAC,EAAE,MAAM,GACjB,YAAY,CAad"}
|
package/dist/lib/search.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/lib/search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/lib/search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AA0CxE,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,IAAI,CAAC,iBAAiB,EAAE,GAAG,CAAM,GACxC,YAAY,EAAE,CAwEhB;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,YAAY,EAAE,CAmCvE"}
|