@stackbone/cli 0.1.0-alpha.1 → 0.1.0-alpha.10
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 +228 -0
- package/README.md +2 -2
- package/main.js +23345 -6130
- package/migrations/0005_stackbone_viewer.sql +11 -0
- package/migrations/0009_rename_runs_partial_index.sql +22 -0
- package/migrations/0010_agent_config.sql +32 -0
- package/migrations/0011_secrets_revoke_viewer.sql +26 -0
- package/migrations/0012_queue_jobs.sql +50 -0
- package/migrations/0013_prompts.sql +74 -0
- package/migrations/0014_rag.sql +79 -0
- package/package.json +8 -1
- package/runtime-deps/@stackbone/agent-server/index.js +414 -0
- package/stackbone-cli-0.1.0-alpha.10.tgz +0 -0
- package/stackbone-cli-0.1.0-alpha.1.tgz +0 -0
|
@@ -45,3 +45,14 @@ ALTER DEFAULT PRIVILEGES IN SCHEMA stackbone_platform
|
|
|
45
45
|
GRANT SELECT ON TABLES TO stackbone_viewer;
|
|
46
46
|
ALTER DEFAULT PRIVILEGES IN SCHEMA stackbone_platform
|
|
47
47
|
GRANT SELECT ON SEQUENCES TO stackbone_viewer;
|
|
48
|
+
|
|
49
|
+
-- Membership grant. Postgres requires `SET ROLE <r>` callers to either be
|
|
50
|
+
-- superuser or hold an explicit membership in <r>. On managed Postgres
|
|
51
|
+
-- (Neon, RDS, …) the install's connection URI authenticates as the database
|
|
52
|
+
-- owner — never as superuser — so without this line every `SET LOCAL ROLE
|
|
53
|
+
-- stackbone_viewer` from the DB Explorer fails with `permission denied to
|
|
54
|
+
-- set role "stackbone_viewer"`. Granting to `current_user` ties the
|
|
55
|
+
-- membership to whichever role runs the migration (the project owner on
|
|
56
|
+
-- Neon, `postgres` in local test fixtures) so the same connection that
|
|
57
|
+
-- created the role is automatically allowed to step down to it.
|
|
58
|
+
GRANT stackbone_viewer TO current_user;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-- 0004_rename_runs_partial_index.sql — clarify semantics of the is_playground partial index.
|
|
2
|
+
-- ADR: docs/adr/2026-05-14-playground-runs-bill-like-real-invocations.md.
|
|
3
|
+
--
|
|
4
|
+
-- Migration 0003 created the partial index `runs_billable_workspace_started_idx`
|
|
5
|
+
-- on `stackbone_platform.runs (workspace_id, started_at DESC NULLS LAST)
|
|
6
|
+
-- WHERE is_playground = false`. Its name and accompanying comments framed the
|
|
7
|
+
-- predicate as the "billable" set — that framing is wrong.
|
|
8
|
+
--
|
|
9
|
+
-- Playground runs DO bill: invoking from Studio consumes real LLM tokens, real
|
|
10
|
+
-- DB queries and real compute, and the creator's organization is charged for
|
|
11
|
+
-- it like any other invocation (otherwise a malicious client could mark all
|
|
12
|
+
-- production traffic with `X-Stackbone-Playground: 1` and dodge billing). The
|
|
13
|
+
-- predicate `WHERE is_playground = false` actually identifies the rows that
|
|
14
|
+
-- count toward Trust Layer / public marketplace aggregations (p50 latency,
|
|
15
|
+
-- success rate, median cost) — a slow demo run from Studio must not lower
|
|
16
|
+
-- the public stats of an `agent_template`.
|
|
17
|
+
--
|
|
18
|
+
-- This migration renames the index so the next reader gets the semantics
|
|
19
|
+
-- right. The index definition (table, columns, predicate) is unchanged.
|
|
20
|
+
|
|
21
|
+
ALTER INDEX IF EXISTS stackbone_platform.runs_billable_workspace_started_idx
|
|
22
|
+
RENAME TO runs_public_metrics_workspace_started_idx;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
-- 0010_agent_config.sql — single-row live `AGENT_CONFIG` table the agent
|
|
2
|
+
-- runtime wrapper reads on every invoke. Paired with the existing
|
|
3
|
+
-- `stackbone_platform.agent_config_versions` (migration 0007) which keeps the
|
|
4
|
+
-- audit history; this table holds the *current* payload only and is what the
|
|
5
|
+
-- SDK wrapper (libs/sdk/src/serve/request-handler.ts) issues a
|
|
6
|
+
-- `SELECT payload FROM stackbone_platform.agent_config WHERE id = 1` against
|
|
7
|
+
-- on every `POST /invoke`.
|
|
8
|
+
--
|
|
9
|
+
-- Two tables, one source of truth (`agent_config.payload`):
|
|
10
|
+
-- - agent_config_versions — append-only audit trail + rollback source.
|
|
11
|
+
-- - agent_config — single row, mirrors the latest payload.
|
|
12
|
+
--
|
|
13
|
+
-- AgentConfigService.put() writes both inside the same call so the audit
|
|
14
|
+
-- never lags the live read.
|
|
15
|
+
--
|
|
16
|
+
-- The install saga (apps/api/.../neon.adapter.ts) used to create this table
|
|
17
|
+
-- inline because no migration existed for it; the inline DDL is now a no-op
|
|
18
|
+
-- (CREATE TABLE IF NOT EXISTS) but kept in place so the seed insert that
|
|
19
|
+
-- copies the per-install snapshot config into row id=1 still runs.
|
|
20
|
+
|
|
21
|
+
CREATE TABLE IF NOT EXISTS stackbone_platform.agent_config (
|
|
22
|
+
id int PRIMARY KEY DEFAULT 1 CHECK (id = 1),
|
|
23
|
+
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
24
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
-- Make sure the row exists even on a Neon that pre-dates the saga bootstrap
|
|
28
|
+
-- (e.g. testcontainer integration suites). Idempotent: re-running the
|
|
29
|
+
-- migration leaves the existing payload untouched.
|
|
30
|
+
INSERT INTO stackbone_platform.agent_config (id, payload)
|
|
31
|
+
VALUES (1, '{}'::jsonb)
|
|
32
|
+
ON CONFLICT (id) DO NOTHING;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
-- 0011_secrets_revoke_viewer.sql — promote `stackbone_platform.secrets` to the
|
|
2
|
+
-- single source of truth for ALL agents (cloud + local), and close the
|
|
3
|
+
-- security gap the agent-owned-secrets ADR mandates.
|
|
4
|
+
--
|
|
5
|
+
-- ADR: docs/arquitectura/decisiones — agent-owned secrets / Studio data
|
|
6
|
+
-- decoupling. The secrets table (created by 0006 as a local-emulator-only
|
|
7
|
+
-- mirror of the control-plane `installation_secret`) is now the canonical
|
|
8
|
+
-- cloud + local store: every per-agent application secret lives here,
|
|
9
|
+
-- encrypted with the per-agent key. The 0006 header comment is stale, but
|
|
10
|
+
-- 0006 is checksum-immutable (apply-migrations.ts throws on a changed
|
|
11
|
+
-- applied file) so it cannot be rewritten — this new migration documents
|
|
12
|
+
-- the promotion instead.
|
|
13
|
+
--
|
|
14
|
+
-- WHY a table-level REVOKE and not only an ALTER DEFAULT PRIVILEGES:
|
|
15
|
+
-- 0005_stackbone_viewer.sql ran its `ALTER DEFAULT PRIVILEGES ... GRANT SELECT`
|
|
16
|
+
-- BEFORE 0006 created `secrets`, so the blanket default-privilege grant already
|
|
17
|
+
-- fired when the secrets table came into existence — the read-only DB-Explorer
|
|
18
|
+
-- role (`stackbone_viewer`) can currently SELECT every row. A bare
|
|
19
|
+
-- `ALTER DEFAULT PRIVILEGES ... REVOKE` would only affect tables created in the
|
|
20
|
+
-- future, leaving this already-granted table readable. The explicit table-level
|
|
21
|
+
-- `REVOKE ALL` below is therefore required and sufficient: it strips the
|
|
22
|
+
-- existing grant so the SQL Explorer can never read decrypted secret material.
|
|
23
|
+
-- The table name may still appear in pg_catalog enumeration (readable by every
|
|
24
|
+
-- role); only row SELECT is denied — which is the security requirement.
|
|
25
|
+
|
|
26
|
+
REVOKE ALL ON stackbone_platform.secrets FROM stackbone_viewer;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
-- 0012_queue_jobs.sql — the agent's reduced `_queue_jobs` JOURNAL (ADR
|
|
2
|
+
-- 2026-05-30 "agent jobs dispatcher on BullMQ"). This is NO LONGER a queue:
|
|
3
|
+
-- BullMQ over the core's Redis is the single engine for the in-flight queue +
|
|
4
|
+
-- clock + dispatch failures. This table is the agent's append-only record of
|
|
5
|
+
-- the jobs that actually RAN inside the agent, written by the runtime wrapper
|
|
6
|
+
-- around each dispatched invoke (`libs/runtime-harness/src/queue-journal.ts`).
|
|
7
|
+
-- Studio COMBINES this journal (real executions: `done` / `failed`) with the
|
|
8
|
+
-- BullMQ live state to show one job timeline.
|
|
9
|
+
--
|
|
10
|
+
-- Reduced shape (vs the old pgmq-era table): only the execution facts. The
|
|
11
|
+
-- columns the old design carried as a *queue* — callback_url, visible_at,
|
|
12
|
+
-- max_attempts, signature_key — are GONE; the BullMQ dispatcher owns delivery,
|
|
13
|
+
-- retries, backoff and the per-install HMAC signature.
|
|
14
|
+
--
|
|
15
|
+
-- id — surrogate row id.
|
|
16
|
+
-- dispatch_id — the BullMQ job id; the correlation key Studio joins on and
|
|
17
|
+
-- the UNIQUE key the wrapper upserts by, so a BullMQ
|
|
18
|
+
-- re-delivery of the same job stays one journal row.
|
|
19
|
+
-- name — opaque job name the agent chose at publish time (e.g.
|
|
20
|
+
-- `send-email`); may be empty for anonymous jobs.
|
|
21
|
+
-- status — terminal outcome: `done` on success, `failed` on error /
|
|
22
|
+
-- timeout. NULL while the job is in-flight (started, not yet
|
|
23
|
+
-- finished).
|
|
24
|
+
-- payload — opaque job payload as delivered in the `/invoke` envelope.
|
|
25
|
+
-- attempts — 1-based attempt number from the dispatch envelope.
|
|
26
|
+
-- started_at — set by the wrapper before the handler runs.
|
|
27
|
+
-- finished_at — set when the handler returns (NULL while in-flight).
|
|
28
|
+
-- error — failure reason on `failed`; NULL on `done`.
|
|
29
|
+
--
|
|
30
|
+
-- The wrapper writes it into the install's own Neon (reusing DATABASE_URL), so
|
|
31
|
+
-- it lives in the platform schema alongside `agent_config`. Idempotent
|
|
32
|
+
-- (CREATE TABLE IF NOT EXISTS) because the install saga may re-apply
|
|
33
|
+
-- migrations on a redeploy.
|
|
34
|
+
|
|
35
|
+
CREATE TABLE IF NOT EXISTS stackbone_platform._queue_jobs (
|
|
36
|
+
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
37
|
+
dispatch_id text NOT NULL UNIQUE,
|
|
38
|
+
name text NOT NULL DEFAULT '',
|
|
39
|
+
status text CHECK (status IN ('done', 'failed')),
|
|
40
|
+
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
41
|
+
attempts int NOT NULL DEFAULT 1,
|
|
42
|
+
started_at timestamptz NOT NULL DEFAULT now(),
|
|
43
|
+
finished_at timestamptz,
|
|
44
|
+
error text
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
-- Studio reads the journal newest-first within the agent's install. A descending
|
|
48
|
+
-- index on the surrogate id keeps that page cheap as the journal grows.
|
|
49
|
+
CREATE INDEX IF NOT EXISTS queue_jobs_id_desc_idx
|
|
50
|
+
ON stackbone_platform._queue_jobs (id DESC);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
-- 0013_prompts.sql — the versioned, named-by-key prompt catalog
|
|
2
|
+
-- (feature `sdk_prompts_versioned_catalog`).
|
|
3
|
+
-- ADR: docs/adr/2026-06-01-selfhost-creator-single-box-packaging.md
|
|
4
|
+
-- PRD: .scratch/sdk_prompts_versioned_catalog/PRD.md
|
|
5
|
+
--
|
|
6
|
+
-- Lives in the agent's own database (the same `stackbone_platform.*` schema as
|
|
7
|
+
-- secrets/config/runs), so prompts travel with the agent's data and are read
|
|
8
|
+
-- agent-locally by `client.prompts` (no control-plane round-trip). Studio
|
|
9
|
+
-- (cloud `apps/api` + the local emulator) writes the same wire shape through
|
|
10
|
+
-- the identical tables.
|
|
11
|
+
--
|
|
12
|
+
-- Two tables, append-only history:
|
|
13
|
+
-- - prompts — one row per key; `current_version` points at the live
|
|
14
|
+
-- version. Soft-deleted via `deleted_at` (audit/retention).
|
|
15
|
+
-- - prompt_versions — every `update` appends an immutable version; the
|
|
16
|
+
-- `(prompt_key, version)` pair is unique. `rolled_back_from`
|
|
17
|
+
-- records the source when a version is created by
|
|
18
|
+
-- promoting/rolling back an older one.
|
|
19
|
+
--
|
|
20
|
+
-- Concurrency: the application layer assigns `MAX(version) + 1` under a
|
|
21
|
+
-- per-key `pg_advisory_xact_lock(hashtext('prompts:' || key))` taken inside the
|
|
22
|
+
-- same transaction as the INSERT, so two parallel updates can never produce
|
|
23
|
+
-- duplicate version numbers (the UNIQUE index below is the backstop).
|
|
24
|
+
--
|
|
25
|
+
-- `created_by_email` carries free text on the local emulator (no `user` table
|
|
26
|
+
-- in the agent's Postgres) and the cloud control plane backfills it via
|
|
27
|
+
-- better-auth lookup — mirroring `secrets` / `agent_config_versions`.
|
|
28
|
+
|
|
29
|
+
CREATE TABLE IF NOT EXISTS stackbone_platform.prompts (
|
|
30
|
+
key text PRIMARY KEY,
|
|
31
|
+
name text NOT NULL,
|
|
32
|
+
description text,
|
|
33
|
+
-- The version number considered live. Always points at an existing row in
|
|
34
|
+
-- `prompt_versions` for this key.
|
|
35
|
+
current_version integer NOT NULL CHECK (current_version >= 1),
|
|
36
|
+
metadata jsonb,
|
|
37
|
+
created_by_email text,
|
|
38
|
+
updated_by_email text,
|
|
39
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
40
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
41
|
+
-- Soft delete. Active prompts have `deleted_at IS NULL`; reads filter on it
|
|
42
|
+
-- so the rows survive for the retention window.
|
|
43
|
+
deleted_at timestamptz
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
CREATE TABLE IF NOT EXISTS stackbone_platform.prompt_versions (
|
|
47
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
48
|
+
prompt_key text NOT NULL
|
|
49
|
+
REFERENCES stackbone_platform.prompts (key)
|
|
50
|
+
ON DELETE CASCADE,
|
|
51
|
+
version integer NOT NULL CHECK (version >= 1),
|
|
52
|
+
content text NOT NULL,
|
|
53
|
+
-- Pre-computed list of the `{{vars}}` referenced by `content`, so Studio's
|
|
54
|
+
-- diff view can highlight added/removed variables without re-parsing.
|
|
55
|
+
vars_extracted jsonb NOT NULL DEFAULT '[]'::jsonb,
|
|
56
|
+
-- Source version when this row was created by a rollback/promote; NULL for
|
|
57
|
+
-- a regular edit.
|
|
58
|
+
rolled_back_from integer,
|
|
59
|
+
created_by_email text,
|
|
60
|
+
created_at timestamptz NOT NULL DEFAULT now()
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
-- One version number per key (the race backstop).
|
|
64
|
+
CREATE UNIQUE INDEX IF NOT EXISTS prompt_versions_key_version_idx
|
|
65
|
+
ON stackbone_platform.prompt_versions (prompt_key, version);
|
|
66
|
+
|
|
67
|
+
-- Drives the lateral history list (newest first) per key.
|
|
68
|
+
CREATE INDEX IF NOT EXISTS prompt_versions_key_version_desc_idx
|
|
69
|
+
ON stackbone_platform.prompt_versions (prompt_key, version DESC);
|
|
70
|
+
|
|
71
|
+
-- The list endpoint orders active prompts by key.
|
|
72
|
+
CREATE INDEX IF NOT EXISTS prompts_active_key_idx
|
|
73
|
+
ON stackbone_platform.prompts (key)
|
|
74
|
+
WHERE deleted_at IS NULL;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
-- 0014_rag.sql — the canonical RAG store (collections / documents / chunks /
|
|
2
|
+
-- jobs), moved into the platform schema.
|
|
3
|
+
-- ADR: docs/adr/2026-06-05-rag-tables-in-platform-schema.md
|
|
4
|
+
--
|
|
5
|
+
-- Previously these four tables lived in `public` and were installed by the
|
|
6
|
+
-- creator's own migrator (`stackbone db migrate add-rag`). They are a
|
|
7
|
+
-- platform-owned feature like secrets/prompts/runs, so they now live in
|
|
8
|
+
-- `stackbone_platform.*` and are provisioned by this platform migrator,
|
|
9
|
+
-- present in every install regardless of whether the agent code reads
|
|
10
|
+
-- `client.rag` back (Studio-managed ingest needs the schema up front).
|
|
11
|
+
--
|
|
12
|
+
-- The Drizzle source of truth is `libs/shared/rag-core/src/lib/schema/schema.ts`
|
|
13
|
+
-- (re-exported as `@stackbone/sdk/rag/schema`); the cloud Studio and the
|
|
14
|
+
-- emulator query through those table objects and get the schema-qualified name
|
|
15
|
+
-- for free. The shared ingest pipeline writes the same tables with raw,
|
|
16
|
+
-- schema-qualified SQL. A drift between this file and the Drizzle definitions is
|
|
17
|
+
-- caught by the integration spec that applies this migration to a real Postgres.
|
|
18
|
+
--
|
|
19
|
+
-- Embedding dimension is pinned to vector(1536) (text-embedding-3-small); a
|
|
20
|
+
-- different model requires a new migration with re-ingest.
|
|
21
|
+
|
|
22
|
+
CREATE EXTENSION IF NOT EXISTS vector;
|
|
23
|
+
|
|
24
|
+
CREATE TABLE IF NOT EXISTS stackbone_platform.rag_collections (
|
|
25
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
26
|
+
name text NOT NULL UNIQUE,
|
|
27
|
+
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
28
|
+
created_at timestamptz NOT NULL DEFAULT now()
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
CREATE TABLE IF NOT EXISTS stackbone_platform.rag_documents (
|
|
32
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
33
|
+
collection_id uuid NOT NULL
|
|
34
|
+
REFERENCES stackbone_platform.rag_collections (id)
|
|
35
|
+
ON DELETE CASCADE,
|
|
36
|
+
source text NOT NULL,
|
|
37
|
+
content_hash text NOT NULL,
|
|
38
|
+
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
39
|
+
created_at timestamptz NOT NULL DEFAULT now()
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
CREATE INDEX IF NOT EXISTS rag_documents_collection_idx
|
|
43
|
+
ON stackbone_platform.rag_documents (collection_id);
|
|
44
|
+
CREATE INDEX IF NOT EXISTS rag_documents_hash_idx
|
|
45
|
+
ON stackbone_platform.rag_documents (collection_id, content_hash);
|
|
46
|
+
|
|
47
|
+
CREATE TABLE IF NOT EXISTS stackbone_platform.rag_chunks (
|
|
48
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
49
|
+
document_id uuid NOT NULL
|
|
50
|
+
REFERENCES stackbone_platform.rag_documents (id)
|
|
51
|
+
ON DELETE CASCADE,
|
|
52
|
+
ordinal integer NOT NULL,
|
|
53
|
+
content text NOT NULL,
|
|
54
|
+
embedding vector(1536) NOT NULL,
|
|
55
|
+
metadata jsonb NOT NULL DEFAULT '{}'::jsonb
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
CREATE INDEX IF NOT EXISTS rag_chunks_document_idx
|
|
59
|
+
ON stackbone_platform.rag_chunks (document_id);
|
|
60
|
+
CREATE INDEX IF NOT EXISTS rag_chunks_embedding_hnsw
|
|
61
|
+
ON stackbone_platform.rag_chunks USING hnsw (embedding vector_cosine_ops);
|
|
62
|
+
|
|
63
|
+
CREATE TABLE IF NOT EXISTS stackbone_platform.rag_jobs (
|
|
64
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
65
|
+
collection_id uuid NOT NULL
|
|
66
|
+
REFERENCES stackbone_platform.rag_collections (id)
|
|
67
|
+
ON DELETE CASCADE,
|
|
68
|
+
status text NOT NULL DEFAULT 'queued'
|
|
69
|
+
CHECK (status IN ('queued','running','succeeded','failed','cancelled')),
|
|
70
|
+
progress jsonb NOT NULL DEFAULT '{"totalChunks":0,"processedChunks":0}'::jsonb,
|
|
71
|
+
error text,
|
|
72
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
73
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
CREATE INDEX IF NOT EXISTS rag_jobs_collection_idx
|
|
77
|
+
ON stackbone_platform.rag_jobs (collection_id);
|
|
78
|
+
CREATE INDEX IF NOT EXISTS rag_jobs_status_idx
|
|
79
|
+
ON stackbone_platform.rag_jobs (status);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackbone/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.10",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,16 +18,23 @@
|
|
|
18
18
|
"@clack/prompts": "^1.2.0",
|
|
19
19
|
"@hono/node-server": "^2.0.0",
|
|
20
20
|
"ajv": "^8.20.0",
|
|
21
|
+
"ajv-formats": "^3.0.1",
|
|
22
|
+
"bullmq": "^5.76.6",
|
|
21
23
|
"citty": "^0.2.2",
|
|
24
|
+
"cron-parser": "^4.9.0",
|
|
22
25
|
"drizzle-kit": "^0.31.10",
|
|
23
26
|
"drizzle-orm": "^0.45.2",
|
|
27
|
+
"esbuild": "^0.27.0",
|
|
24
28
|
"hono": "^4.12.15",
|
|
29
|
+
"libsodium-wrappers": "^0.8.4",
|
|
25
30
|
"open": "^11.0.0",
|
|
31
|
+
"openai": "^6.42.0",
|
|
26
32
|
"pg": "^8.20.0",
|
|
27
33
|
"pg-query-emscripten": "^5.1.0",
|
|
28
34
|
"pino": "^10.3.1",
|
|
29
35
|
"pino-pretty": "^13.1.3",
|
|
30
36
|
"postgres": "^3.4.9",
|
|
37
|
+
"unpdf": "^0.12.1",
|
|
31
38
|
"yaml": "^2.8.3",
|
|
32
39
|
"zod": "^4.3.6"
|
|
33
40
|
}
|