@hasna/todos 0.11.85 → 0.11.87
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/cloud-router.d.ts +55 -2
- package/dist/cli/cloud-router.d.ts.map +1 -1
- package/dist/cli/commands/agent-commands.d.ts.map +1 -1
- package/dist/cli/commands/task-commands.d.ts +2 -0
- package/dist/cli/commands/task-commands.d.ts.map +1 -1
- package/dist/cli/index.js +1106 -417
- package/dist/contracts.js +1 -1
- package/dist/db/comments.d.ts.map +1 -1
- package/dist/index.js +180 -5
- package/dist/mcp/index.js +483 -39
- package/dist/registry.js +1 -1
- package/dist/release-provenance.json +3 -3
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +21 -0
- package/dist/sdk/v1.generated.d.ts +54 -0
- package/dist/sdk/v1.generated.d.ts.map +1 -1
- package/dist/server/cloud.d.ts +13 -0
- package/dist/server/cloud.d.ts.map +1 -1
- package/dist/server/index.js +900 -384
- package/dist/server/openapi.d.ts +171 -0
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/v1.d.ts +7 -1
- package/dist/server/v1.d.ts.map +1 -1
- package/dist/storage/comment-redaction-backfill.d.ts +32 -0
- package/dist/storage/comment-redaction-backfill.d.ts.map +1 -0
- package/dist/storage/index.d.ts +4 -2
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/interfaces.d.ts +23 -0
- package/dist/storage/interfaces.d.ts.map +1 -1
- package/dist/storage/local-sqlite.d.ts.map +1 -1
- package/dist/storage/postgres-adapter.d.ts.map +1 -1
- package/dist/storage/postgres-sync.d.ts +6 -0
- package/dist/storage/postgres-sync.d.ts.map +1 -1
- package/dist/storage.d.ts +3 -3
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +184 -5
- package/package.json +2 -1
- package/vendor/hasna-contracts-0.5.1.tgz +0 -0
package/dist/storage.js
CHANGED
|
@@ -9424,7 +9424,7 @@ function getComment(id, db) {
|
|
|
9424
9424
|
}
|
|
9425
9425
|
function listComments(taskId, db) {
|
|
9426
9426
|
const d = db || getDatabase();
|
|
9427
|
-
return d.query("SELECT * FROM task_comments WHERE task_id = ? ORDER BY created_at").all(taskId);
|
|
9427
|
+
return d.query("SELECT * FROM task_comments WHERE task_id = ? ORDER BY created_at, rowid").all(taskId);
|
|
9428
9428
|
}
|
|
9429
9429
|
function deleteComment(id, db) {
|
|
9430
9430
|
const d = db || getDatabase();
|
|
@@ -11552,6 +11552,10 @@ function createLocalSqliteTodosStorageAdapter(options = {}) {
|
|
|
11552
11552
|
list: (filter = {}) => listTasks(filter, database()),
|
|
11553
11553
|
count: (filter = {}) => countTasks(filter, database()),
|
|
11554
11554
|
update: (id, input) => updateTask(id, input, database()),
|
|
11555
|
+
unlock: (id, agentId) => {
|
|
11556
|
+
unlockTask(id, agentId, database());
|
|
11557
|
+
return true;
|
|
11558
|
+
},
|
|
11555
11559
|
delete: (id) => deleteTask(id, database()),
|
|
11556
11560
|
start: (id, agentId) => startTask(id, agentId, database()),
|
|
11557
11561
|
complete: (id, agentId, options2) => completeTask(id, agentId, database(), options2),
|
|
@@ -11603,6 +11607,20 @@ function createLocalSqliteTodosStorageAdapter(options = {}) {
|
|
|
11603
11607
|
logTaskChange: (taskId, action, field, oldValue, newValue, agentId) => logTaskChange(taskId, action, field, oldValue, newValue, agentId, database()),
|
|
11604
11608
|
addComment: (input) => addComment(input, database()),
|
|
11605
11609
|
getComments: (taskId) => listComments(taskId, database()),
|
|
11610
|
+
getCommentsPage: (taskId, options2) => {
|
|
11611
|
+
if (options2?.limit !== undefined && (!Number.isSafeInteger(options2.limit) || options2.limit < 1 || options2.limit > 1001)) {
|
|
11612
|
+
throw new Error("Comment limit must be an integer between 1 and 1001");
|
|
11613
|
+
}
|
|
11614
|
+
let comments = listComments(taskId, database());
|
|
11615
|
+
comments = comments.sort((left, right) => left.created_at.localeCompare(right.created_at) || left.id.localeCompare(right.id));
|
|
11616
|
+
if (options2?.before) {
|
|
11617
|
+
const before = options2.before;
|
|
11618
|
+
comments = comments.filter((comment) => comment.created_at < before.created_at || comment.created_at === before.created_at && comment.id < before.id);
|
|
11619
|
+
}
|
|
11620
|
+
if (options2?.limit !== undefined)
|
|
11621
|
+
comments = comments.slice(-options2.limit);
|
|
11622
|
+
return comments;
|
|
11623
|
+
},
|
|
11606
11624
|
getTaskHistory: (taskId) => getTaskHistory(taskId, database()),
|
|
11607
11625
|
getRecentActivity: (limit) => getRecentActivity(limit, database())
|
|
11608
11626
|
},
|
|
@@ -11650,6 +11668,12 @@ function postgresTodosSyncSchemaSql(tableName = DEFAULT_TODOS_POSTGRES_SYNC_TABL
|
|
|
11650
11668
|
)`
|
|
11651
11669
|
];
|
|
11652
11670
|
}
|
|
11671
|
+
function postgresTodosCommentCursorIndexSql(tableName = DEFAULT_TODOS_POSTGRES_SYNC_TABLE) {
|
|
11672
|
+
assertSafeIdentifier(tableName);
|
|
11673
|
+
return `CREATE INDEX CONCURRENTLY IF NOT EXISTS ${tableName}_comment_task_created_idx
|
|
11674
|
+
ON ${tableName} (service, (payload->>'task_id'), (payload->>'created_at'), object_id)
|
|
11675
|
+
WHERE object_type = 'comments' AND deleted_at IS NULL`;
|
|
11676
|
+
}
|
|
11653
11677
|
|
|
11654
11678
|
class PostgresTodosSyncStore {
|
|
11655
11679
|
client;
|
|
@@ -11882,7 +11906,9 @@ function createHybridTodosStorageAdapter(options) {
|
|
|
11882
11906
|
}
|
|
11883
11907
|
|
|
11884
11908
|
// src/storage/postgres-adapter.ts
|
|
11909
|
+
init_types();
|
|
11885
11910
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
11911
|
+
init_redaction();
|
|
11886
11912
|
function createPostgresTodosStorageAdapter(options) {
|
|
11887
11913
|
const store = new PostgresJsonRecordStore(options);
|
|
11888
11914
|
const adapter = {
|
|
@@ -11909,7 +11935,8 @@ function createPostgresTodosStorageAdapter(options) {
|
|
|
11909
11935
|
getActiveWork: (filters) => getActiveWork2(filters, store),
|
|
11910
11936
|
getChangedSince: (since, filters) => getChangedSince(since, filters, store),
|
|
11911
11937
|
lock: (id, agentId) => lockTask2(id, agentId, store),
|
|
11912
|
-
unlock: (id, agentId) => unlockTask2(id, agentId, store)
|
|
11938
|
+
unlock: (id, agentId) => unlockTask2(id, agentId, store),
|
|
11939
|
+
getByFingerprint: (fingerprint) => store.getTaskByFingerprint(fingerprint)
|
|
11913
11940
|
},
|
|
11914
11941
|
dependencies: {
|
|
11915
11942
|
add: (taskId, dependsOn, context) => addDependency2(taskId, dependsOn, store, context),
|
|
@@ -11977,7 +12004,24 @@ function createPostgresTodosStorageAdapter(options) {
|
|
|
11977
12004
|
audit: {
|
|
11978
12005
|
logTaskChange: (taskId, action, field, oldValue, newValue, agentId, context) => logTaskChange2(taskId, action, field, oldValue, newValue, agentId, store, context),
|
|
11979
12006
|
addComment: (input, context) => addComment2(input, store, context),
|
|
11980
|
-
getComments: async (taskId) =>
|
|
12007
|
+
getComments: async (taskId) => {
|
|
12008
|
+
const pages = [];
|
|
12009
|
+
let before;
|
|
12010
|
+
while (true) {
|
|
12011
|
+
const page = await store.listComments(taskId, { limit: 1000, ...before ? { before } : {} });
|
|
12012
|
+
if (page.length === 0)
|
|
12013
|
+
break;
|
|
12014
|
+
pages.unshift(page);
|
|
12015
|
+
if (page.length < 1000)
|
|
12016
|
+
break;
|
|
12017
|
+
const oldest = page[0];
|
|
12018
|
+
before = { created_at: oldest.created_at, id: oldest.id };
|
|
12019
|
+
}
|
|
12020
|
+
return pages.flat().map(redactComment).sort((a, b) => a.created_at.localeCompare(b.created_at) || a.id.localeCompare(b.id));
|
|
12021
|
+
},
|
|
12022
|
+
getCommentsPage: async (taskId, options2) => {
|
|
12023
|
+
return (await store.listComments(taskId, options2)).map(redactComment).sort((a, b) => a.created_at.localeCompare(b.created_at) || a.id.localeCompare(b.id));
|
|
12024
|
+
},
|
|
11981
12025
|
getTaskHistory: async (taskId) => (await store.list("audit_history")).filter((entry2) => entry2.task_id === taskId).sort((a, b) => a.created_at.localeCompare(b.created_at)),
|
|
11982
12026
|
getRecentActivity: async (limit = 20) => (await store.list("audit_history")).sort((a, b) => b.created_at.localeCompare(a.created_at)).slice(0, limit)
|
|
11983
12027
|
},
|
|
@@ -12027,6 +12071,27 @@ class PostgresJsonRecordStore {
|
|
|
12027
12071
|
async list(type) {
|
|
12028
12072
|
return (await this.listRecords(type)).map((record) => record.payload);
|
|
12029
12073
|
}
|
|
12074
|
+
async listComments(taskId, options = {}) {
|
|
12075
|
+
await this.ensureSchema();
|
|
12076
|
+
const limit = options.limit ?? 100;
|
|
12077
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1001) {
|
|
12078
|
+
throw new Error("Postgres comment limit must be an integer between 1 and 1001");
|
|
12079
|
+
}
|
|
12080
|
+
const params = [this.service, taskId];
|
|
12081
|
+
let cursorPredicate = "";
|
|
12082
|
+
if (options.before) {
|
|
12083
|
+
params.push(options.before.created_at, options.before.id);
|
|
12084
|
+
cursorPredicate = `AND (payload->>'created_at', object_id) < ($3, $4)`;
|
|
12085
|
+
}
|
|
12086
|
+
params.push(limit);
|
|
12087
|
+
const result = await this.options.client.query(`/* todos:list-comments */ SELECT payload FROM ${this.tableName}
|
|
12088
|
+
WHERE service = $1 AND object_type = 'comments' AND deleted_at IS NULL
|
|
12089
|
+
AND payload->>'task_id' = $2
|
|
12090
|
+
${cursorPredicate}
|
|
12091
|
+
ORDER BY payload->>'created_at' DESC, object_id DESC
|
|
12092
|
+
LIMIT $${params.length}`, params);
|
|
12093
|
+
return result.rows.map((row) => payloadRecord2(row.payload)).reverse();
|
|
12094
|
+
}
|
|
12030
12095
|
async listRecords(type) {
|
|
12031
12096
|
await this.ensureSchema();
|
|
12032
12097
|
const result = await this.options.client.query(`SELECT object_type, object_id, payload, updated_at
|
|
@@ -12098,6 +12163,17 @@ class PostgresJsonRecordStore {
|
|
|
12098
12163
|
const result = await this.options.client.query(sql, params);
|
|
12099
12164
|
return result.rows.map((row) => payloadRecord2(row.payload));
|
|
12100
12165
|
}
|
|
12166
|
+
async getTaskByFingerprint(fingerprint) {
|
|
12167
|
+
await this.ensureSchema();
|
|
12168
|
+
const sql = `/* todos:task-by-fingerprint */ SELECT payload FROM ${this.tableName}
|
|
12169
|
+
WHERE service = $1 AND object_type = $2 AND deleted_at IS NULL
|
|
12170
|
+
AND payload->'metadata'->>'fingerprint' = $3
|
|
12171
|
+
ORDER BY payload->>'created_at' ASC
|
|
12172
|
+
LIMIT 1`;
|
|
12173
|
+
const result = await this.options.client.query(sql, [this.service, "tasks", fingerprint]);
|
|
12174
|
+
const row = result.rows[0];
|
|
12175
|
+
return row ? payloadRecord2(row.payload) : null;
|
|
12176
|
+
}
|
|
12101
12177
|
async countTasks(filter) {
|
|
12102
12178
|
await this.ensureSchema();
|
|
12103
12179
|
const { where, params } = this.buildTaskFilterSql(filter);
|
|
@@ -12410,7 +12486,7 @@ async function lockTask2(id, agentId, store) {
|
|
|
12410
12486
|
async function unlockTask2(id, agentId, store) {
|
|
12411
12487
|
const task = await requireRecord("tasks", id, store);
|
|
12412
12488
|
if (agentId && task.locked_by && task.locked_by !== agentId) {
|
|
12413
|
-
throw new
|
|
12489
|
+
throw new LockError(id, task.locked_by);
|
|
12414
12490
|
}
|
|
12415
12491
|
await patchTask(task, { locked_by: null, locked_at: null }, store);
|
|
12416
12492
|
return true;
|
|
@@ -12776,13 +12852,16 @@ async function addComment2(input, store, context) {
|
|
|
12776
12852
|
task_id: input.task_id,
|
|
12777
12853
|
agent_id: input.agent_id ?? context?.agentId ?? null,
|
|
12778
12854
|
session_id: input.session_id ?? context?.sessionId ?? null,
|
|
12779
|
-
content: input.content,
|
|
12855
|
+
content: redactEvidenceText(input.content),
|
|
12780
12856
|
type: input.type ?? "comment",
|
|
12781
12857
|
progress_pct: input.progress_pct ?? null,
|
|
12782
12858
|
created_at: new Date().toISOString()
|
|
12783
12859
|
};
|
|
12784
12860
|
return store.upsert("comments", comment, context);
|
|
12785
12861
|
}
|
|
12862
|
+
function redactComment(comment) {
|
|
12863
|
+
return { ...comment, content: redactEvidenceText(comment.content) };
|
|
12864
|
+
}
|
|
12786
12865
|
async function exportSnapshot(store) {
|
|
12787
12866
|
return {
|
|
12788
12867
|
exportedAt: new Date().toISOString(),
|
|
@@ -13714,6 +13793,102 @@ async function closeRuntimeShadowCloud() {
|
|
|
13714
13793
|
await cloud.close().catch(() => {});
|
|
13715
13794
|
}
|
|
13716
13795
|
}
|
|
13796
|
+
// src/storage/comment-redaction-backfill.ts
|
|
13797
|
+
init_redaction();
|
|
13798
|
+
var COMMENT_REDACTION_BACKFILL_CONFIRMATION = "REDACT_STORED_TODOS_COMMENTS";
|
|
13799
|
+
function assertSafeIdentifier2(value) {
|
|
13800
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value)) {
|
|
13801
|
+
throw new Error(`Unsafe Postgres identifier: ${value}`);
|
|
13802
|
+
}
|
|
13803
|
+
}
|
|
13804
|
+
function payloadObject(value) {
|
|
13805
|
+
if (value && typeof value === "object" && !Array.isArray(value))
|
|
13806
|
+
return value;
|
|
13807
|
+
if (typeof value !== "string")
|
|
13808
|
+
return null;
|
|
13809
|
+
try {
|
|
13810
|
+
const parsed = JSON.parse(value);
|
|
13811
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
13812
|
+
} catch {
|
|
13813
|
+
return null;
|
|
13814
|
+
}
|
|
13815
|
+
}
|
|
13816
|
+
async function backfillPostgresCommentRedaction(client, options = {}) {
|
|
13817
|
+
const apply = options.apply === true;
|
|
13818
|
+
if (apply && options.confirmation !== COMMENT_REDACTION_BACKFILL_CONFIRMATION) {
|
|
13819
|
+
throw new Error(`Applying the comment redaction backfill requires confirmation ${COMMENT_REDACTION_BACKFILL_CONFIRMATION}`);
|
|
13820
|
+
}
|
|
13821
|
+
const tableName = options.tableName ?? DEFAULT_TODOS_POSTGRES_SYNC_TABLE;
|
|
13822
|
+
assertSafeIdentifier2(tableName);
|
|
13823
|
+
const service = options.service ?? "todos";
|
|
13824
|
+
const batchSize = options.batchSize ?? 100;
|
|
13825
|
+
if (!Number.isSafeInteger(batchSize) || batchSize < 1 || batchSize > 500) {
|
|
13826
|
+
throw new Error("Comment redaction backfill batchSize must be an integer between 1 and 500");
|
|
13827
|
+
}
|
|
13828
|
+
const result = {
|
|
13829
|
+
dry_run: !apply,
|
|
13830
|
+
scanned: 0,
|
|
13831
|
+
candidates: 0,
|
|
13832
|
+
updated: 0,
|
|
13833
|
+
conflicts: 0,
|
|
13834
|
+
batches: 0,
|
|
13835
|
+
remaining_candidates: 0
|
|
13836
|
+
};
|
|
13837
|
+
let afterId = "";
|
|
13838
|
+
while (true) {
|
|
13839
|
+
const page = await client.query(`/* todos:comment-redaction-backfill-scan */
|
|
13840
|
+
SELECT object_id, payload
|
|
13841
|
+
FROM ${tableName}
|
|
13842
|
+
WHERE service = $1 AND object_type = 'comments'
|
|
13843
|
+
AND object_id > $2
|
|
13844
|
+
ORDER BY object_id ASC
|
|
13845
|
+
LIMIT $3`, [service, afterId, batchSize]);
|
|
13846
|
+
if (page.rows.length === 0)
|
|
13847
|
+
break;
|
|
13848
|
+
result.batches += 1;
|
|
13849
|
+
for (const row of page.rows) {
|
|
13850
|
+
afterId = row.object_id;
|
|
13851
|
+
result.scanned += 1;
|
|
13852
|
+
const payload = payloadObject(row.payload);
|
|
13853
|
+
const original = payload?.["content"];
|
|
13854
|
+
if (typeof original !== "string")
|
|
13855
|
+
continue;
|
|
13856
|
+
const redacted = redactEvidenceText(original);
|
|
13857
|
+
if (redacted === original)
|
|
13858
|
+
continue;
|
|
13859
|
+
result.candidates += 1;
|
|
13860
|
+
if (!apply)
|
|
13861
|
+
continue;
|
|
13862
|
+
const nextPayload = { ...payload, content: redacted };
|
|
13863
|
+
const update = await client.query(`/* todos:comment-redaction-backfill-apply */
|
|
13864
|
+
UPDATE ${tableName}
|
|
13865
|
+
SET payload = $3::jsonb
|
|
13866
|
+
WHERE service = $1 AND object_type = 'comments' AND object_id = $2
|
|
13867
|
+
AND payload = $4::jsonb
|
|
13868
|
+
RETURNING object_id`, [service, row.object_id, nextPayload, row.payload]);
|
|
13869
|
+
if (update.rows.length === 1)
|
|
13870
|
+
result.updated += 1;
|
|
13871
|
+
else
|
|
13872
|
+
result.conflicts += 1;
|
|
13873
|
+
}
|
|
13874
|
+
if (page.rows.length < batchSize)
|
|
13875
|
+
break;
|
|
13876
|
+
}
|
|
13877
|
+
if (!apply) {
|
|
13878
|
+
result.remaining_candidates = result.candidates;
|
|
13879
|
+
return result;
|
|
13880
|
+
}
|
|
13881
|
+
const verification = await backfillPostgresCommentRedaction(client, {
|
|
13882
|
+
...options,
|
|
13883
|
+
apply: false,
|
|
13884
|
+
confirmation: undefined
|
|
13885
|
+
});
|
|
13886
|
+
result.remaining_candidates = verification.candidates;
|
|
13887
|
+
return result;
|
|
13888
|
+
}
|
|
13889
|
+
function isCommentRedactionBackfillComplete(result) {
|
|
13890
|
+
return !result.dry_run && result.conflicts === 0 && result.remaining_candidates === 0;
|
|
13891
|
+
}
|
|
13717
13892
|
// src/storage/s3-artifacts.ts
|
|
13718
13893
|
import { createHash as createHash3, createHmac as createHmac2 } from "crypto";
|
|
13719
13894
|
function createTodosS3ArtifactStore(options) {
|
|
@@ -14146,6 +14321,7 @@ export {
|
|
|
14146
14321
|
signAwsV4Request,
|
|
14147
14322
|
registerShadowExitFlush,
|
|
14148
14323
|
postgresTodosSyncSchemaSql,
|
|
14324
|
+
postgresTodosCommentCursorIndexSql,
|
|
14149
14325
|
planRunArtifactsS3Sync,
|
|
14150
14326
|
parseStorageMode,
|
|
14151
14327
|
maybeInstallShadowCapture2 as maybeInstallShadowCapture,
|
|
@@ -14153,6 +14329,7 @@ export {
|
|
|
14153
14329
|
loadStorageConfig,
|
|
14154
14330
|
isTodosShadowEnabled,
|
|
14155
14331
|
isTodosRemoteStorageEnabled,
|
|
14332
|
+
isCommentRedactionBackfillComplete,
|
|
14156
14333
|
installShadowOutboxSchema,
|
|
14157
14334
|
importSqliteTodosStorageSnapshot,
|
|
14158
14335
|
getTodosStorageShadowEnvName,
|
|
@@ -14180,6 +14357,7 @@ export {
|
|
|
14180
14357
|
closeRuntimeShadowCloud,
|
|
14181
14358
|
buildS3ObjectUrl,
|
|
14182
14359
|
buildS3ObjectKey,
|
|
14360
|
+
backfillPostgresCommentRedaction,
|
|
14183
14361
|
assertTodosShadowConfig,
|
|
14184
14362
|
assertTodosRemoteStorageConfig,
|
|
14185
14363
|
TodosShadowOutbox,
|
|
@@ -14188,6 +14366,7 @@ export {
|
|
|
14188
14366
|
TODOS_STORAGE_FALLBACK_ENV,
|
|
14189
14367
|
TODOS_STORAGE_ENV,
|
|
14190
14368
|
STORAGE_TABLES,
|
|
14369
|
+
COMMENT_REDACTION_BACKFILL_CONFIRMATION,
|
|
14191
14370
|
CANONICAL_TODOS_RDS_RUNTIME_PATH,
|
|
14192
14371
|
CANONICAL_TODOS_RDS_DATABASE,
|
|
14193
14372
|
CANONICAL_TODOS_RDS_CLUSTER
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/todos",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.87",
|
|
4
4
|
"description": "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"build": "rm -rf dist dashboard/dist && cd dashboard && bun install --frozen-lockfile && bun run build && cd .. && bun build src/cli/index.tsx --outdir dist/cli --target bun --external ink --external react --external chalk --external @modelcontextprotocol/sdk && bun build src/mcp/index.ts --outdir dist/mcp --target bun --external @modelcontextprotocol/sdk && bun build src/server/index.ts --outdir dist/server --target bun && bun build src/sdk/index.ts --outdir dist/sdk --target bun && bun build src/index.ts src/mcp.ts src/registry.ts src/contracts.ts src/storage.ts --outdir dist --target bun && tsc --emitDeclarationOnly --outDir dist",
|
|
51
51
|
"build:server": "rm -rf dist && bun build src/cli/index.tsx --outdir dist/cli --target bun --external ink --external react --external chalk --external @modelcontextprotocol/sdk && bun build src/mcp/index.ts --outdir dist/mcp --target bun --external @modelcontextprotocol/sdk && bun build src/server/index.ts --outdir dist/server --target bun && bun build src/sdk/index.ts --outdir dist/sdk --target bun && bun build src/index.ts src/mcp.ts src/registry.ts src/contracts.ts src/storage.ts --outdir dist --target bun",
|
|
52
52
|
"migrate": "bun run src/server/index.ts migrate",
|
|
53
|
+
"backfill:comment-redaction": "bun run src/server/index.ts redact-comments",
|
|
53
54
|
"generate:sdk": "bun run scripts/generate-sdk.ts",
|
|
54
55
|
"build:dashboard": "cd dashboard && bun install --frozen-lockfile && bun run build",
|
|
55
56
|
"typecheck": "tsc --noEmit",
|
|
Binary file
|