c0de-agent 1.11.0 → 1.13.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/README.md +63 -16
- package/dist/cli/commands/acp.js +26 -8
- package/dist/cli/commands/chat.js +151 -1
- package/dist/cli/commands/config.d.ts +2 -0
- package/dist/cli/commands/config.js +63 -3
- package/dist/cli/commands/serve.js +11 -2
- package/dist/cli/commands/sessions.js +109 -3
- package/dist/cli/commands/trust.d.ts +11 -0
- package/dist/cli/commands/trust.js +31 -0
- package/dist/cli/commands/update.js +4 -0
- package/dist/cli/deps.d.ts +9 -6
- package/dist/cli/deps.js +66 -19
- package/dist/cli/index.d.ts +4 -1
- package/dist/cli/index.js +110 -11
- package/dist/cli/modes/acp.js +39 -8
- package/dist/cli/modes/print.d.ts +3 -0
- package/dist/cli/modes/print.js +78 -8
- package/dist/core/agent.d.ts +1 -1
- package/dist/core/agent.js +9 -4
- package/dist/core/agents/builtin.js +2 -2
- package/dist/core/agents/index.d.ts +0 -1
- package/dist/core/agents/index.js +0 -1
- package/dist/core/compact.d.ts +2 -0
- package/dist/core/compact.js +1 -0
- package/dist/core/config.d.ts +53 -2
- package/dist/core/config.js +235 -19
- package/dist/core/loop/compaction.d.ts +2 -1
- package/dist/core/loop/compaction.js +19 -6
- package/dist/core/loop/segment.d.ts +3 -1
- package/dist/core/loop/segment.js +24 -1
- package/dist/core/loop/stream-collect.js +9 -1
- package/dist/core/loop/subagent.js +88 -37
- package/dist/core/loop.d.ts +7 -0
- package/dist/core/loop.js +90 -6
- package/dist/core/redact.d.ts +11 -0
- package/dist/core/redact.js +49 -0
- package/dist/core/slash.d.ts +10 -0
- package/dist/core/slash.js +237 -65
- package/dist/core/title.js +7 -1
- package/dist/core/types.d.ts +22 -1
- package/dist/core/workflows/context.js +44 -4
- package/dist/core/workflows/discovery.d.ts +2 -2
- package/dist/core/workflows/discovery.js +5 -7
- package/dist/core/workflows/index.d.ts +2 -1
- package/dist/core/workflows/index.js +2 -1
- package/dist/core/workflows/registry.d.ts +13 -3
- package/dist/core/workflows/registry.js +14 -9
- package/dist/core/workflows/resolve.d.ts +22 -0
- package/dist/core/workflows/resolve.js +23 -0
- package/dist/core/workflows/runtime.d.ts +6 -1
- package/dist/core/workflows/runtime.js +19 -2
- package/dist/db/schema.d.ts +373 -1
- package/dist/db/schema.js +60 -4
- package/dist/kanban/index.d.ts +2 -1
- package/dist/kanban/index.js +1 -1
- package/dist/kanban/store.d.ts +87 -1
- package/dist/kanban/store.js +429 -22
- package/dist/llm/index.d.ts +1 -1
- package/dist/llm/index.js +1 -1
- package/dist/llm/provider.js +1 -1
- package/dist/llm/registry.d.ts +7 -1
- package/dist/llm/registry.js +7 -1
- package/dist/llm/retry.d.ts +5 -2
- package/dist/llm/retry.js +6 -5
- package/dist/llm/routing.d.ts +24 -1
- package/dist/llm/routing.js +29 -1
- package/dist/plugins/init.d.ts +7 -0
- package/dist/plugins/init.js +22 -1
- package/dist/plugins/loader.d.ts +7 -1
- package/dist/plugins/loader.js +12 -4
- package/dist/project/index.d.ts +1 -1
- package/dist/project/index.js +1 -1
- package/dist/project/project.d.ts +37 -0
- package/dist/project/project.js +142 -1
- package/dist/project/trust.d.ts +65 -0
- package/dist/project/trust.js +328 -0
- package/dist/server/agent-manager.d.ts +15 -2
- package/dist/server/agent-manager.js +18 -3
- package/dist/server/app.js +45 -30
- package/dist/server/auth-manager.d.ts +26 -9
- package/dist/server/auth-manager.js +78 -42
- package/dist/server/context.js +14 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/middleware/auth.d.ts +11 -1
- package/dist/server/middleware/auth.js +25 -3
- package/dist/server/permission/interactive.d.ts +11 -3
- package/dist/server/permission/interactive.js +23 -4
- package/dist/server/permission/store.d.ts +14 -2
- package/dist/server/permission/store.js +39 -3
- package/dist/server/registry-config.d.ts +14 -0
- package/dist/server/registry-config.js +44 -0
- package/dist/server/routes/auth.js +66 -10
- package/dist/server/routes/chat.d.ts +21 -0
- package/dist/server/routes/chat.js +685 -52
- package/dist/server/routes/commands.d.ts +4 -2
- package/dist/server/routes/commands.js +9 -4
- package/dist/server/routes/config.js +180 -23
- package/dist/server/routes/files.js +142 -28
- package/dist/server/routes/kanban.js +218 -26
- package/dist/server/routes/permissions.d.ts +0 -4
- package/dist/server/routes/permissions.js +140 -7
- package/dist/server/routes/project.js +132 -29
- package/dist/server/routes/provider.js +54 -3
- package/dist/server/routes/session.js +463 -23
- package/dist/server/routes/tool.js +24 -5
- package/dist/server/routes/update.d.ts +11 -5
- package/dist/server/routes/update.js +145 -29
- package/dist/server/routes/usage.d.ts +4 -0
- package/dist/server/routes/usage.js +133 -0
- package/dist/server/routes/workflows.js +476 -87
- package/dist/server/server.d.ts +16 -13
- package/dist/server/server.js +364 -107
- package/dist/server/terminal/pty-manager.d.ts +12 -0
- package/dist/server/terminal/pty-manager.js +63 -7
- package/dist/server/types.d.ts +16 -0
- package/dist/session/archive.d.ts +3 -1
- package/dist/session/archive.js +13 -1
- package/dist/session/branch.d.ts +2 -1
- package/dist/session/branch.js +92 -9
- package/dist/session/context.js +28 -2
- package/dist/session/import.d.ts +44 -0
- package/dist/session/import.js +83 -0
- package/dist/session/index.d.ts +1 -1
- package/dist/session/index.js +1 -1
- package/dist/session/jobs.d.ts +12 -0
- package/dist/session/jobs.js +53 -0
- package/dist/session/message.d.ts +7 -1
- package/dist/session/message.js +21 -1
- package/dist/session/session.d.ts +186 -12
- package/dist/session/session.js +577 -33
- package/dist/session/snapshot.d.ts +5 -2
- package/dist/session/snapshot.js +10 -2
- package/dist/session/types.d.ts +13 -1
- package/dist/session/usage.d.ts +62 -0
- package/dist/session/usage.js +194 -0
- package/dist/shared/types/agent.d.ts +29 -2
- package/dist/shared/types/config.d.ts +64 -5
- package/dist/shared/types/kanban.d.ts +17 -2
- package/dist/shared/types/message.d.ts +23 -0
- package/dist/tools/builtin/kanban.js +13 -2
- package/dist/tools/index.d.ts +14 -3
- package/dist/tools/index.js +23 -5
- package/dist/tools/websearch/index.d.ts +5 -1
- package/dist/tools/websearch/index.js +46 -7
- package/dist/tools/websearch/providers/brave.js +2 -2
- package/dist/tools/websearch/providers/duckduckgo.js +2 -1
- package/dist/tools/websearch/providers/tavily.js +2 -2
- package/dist/tools/websearch/types.d.ts +5 -1
- package/dist/tools/websearch/types.js +7 -1
- package/dist/update/index.d.ts +3 -3
- package/dist/update/index.js +2 -2
- package/dist/update/ipc.d.ts +13 -2
- package/dist/update/ipc.js +36 -2
- package/dist/update/scheduler.js +5 -2
- package/dist/update/snapshot.d.ts +18 -3
- package/dist/update/snapshot.js +5 -2
- package/dist/update/updater.d.ts +17 -1
- package/dist/update/updater.js +47 -18
- package/dist/update/version.d.ts +3 -0
- package/dist/update/version.js +9 -3
- package/drizzle/0008_tranquil_lily_hollister.sql +1 -0
- package/drizzle/0010_usage_events_ledger.sql +17 -0
- package/drizzle/0011_slow_slapstick.sql +12 -0
- package/drizzle/0012_chief_timeslip.sql +1 -0
- package/drizzle/0013_swift_zeigeist.sql +1 -0
- package/drizzle/0014_flimsy_legion.sql +1 -0
- package/drizzle/meta/0008_snapshot.json +875 -0
- package/drizzle/meta/0010_snapshot.json +1010 -0
- package/drizzle/meta/0011_snapshot.json +1055 -0
- package/drizzle/meta/0012_snapshot.json +1062 -0
- package/drizzle/meta/0013_snapshot.json +1068 -0
- package/drizzle/meta/0014_snapshot.json +1075 -0
- package/drizzle/meta/_journal.json +42 -0
- package/package.json +42 -42
- package/dist/core/agents/discovery.d.ts +0 -6
- package/dist/core/agents/discovery.js +0 -96
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { mkdir, readdir, readFile, unlink, writeFile } from 'node:fs/promises';
|
|
2
|
-
import { homedir } from 'node:os';
|
|
3
2
|
import { basename, join } from 'node:path';
|
|
4
3
|
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import { resolveGlobalConfigDir } from '../config.js';
|
|
5
5
|
/** 项目级工作流目录相对路径。 */
|
|
6
6
|
const PROJECT_WORKFLOWS_DIR = '.c0de/workflows';
|
|
7
|
-
/** 用户级(全局)工作流目录:~/.c0de/workflows。 */
|
|
8
|
-
const GLOBAL_WORKFLOWS_DIR = join('.c0de', 'workflows');
|
|
9
7
|
/**
|
|
10
8
|
* 扫描指定目录下的 `*.js` 工作流文件,dynamic import 后转为 WorkflowEntry。
|
|
11
9
|
* import 失败的文件跳过(warn),不阻塞其他工作流加载。
|
|
@@ -60,11 +58,11 @@ async function discoverWorkflows(projectDir) {
|
|
|
60
58
|
return discoverFromDir(join(projectDir, PROJECT_WORKFLOWS_DIR), 'project');
|
|
61
59
|
}
|
|
62
60
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
61
|
+
* 扫描全局工作流目录(默认 `~/.c0de/workflows/*.js`,C0DE_CONFIG_DIR 可重定向),
|
|
62
|
+
* source 标记为 'user'。目录不存在时返回空数组(与项目级一致)。
|
|
65
63
|
*/
|
|
66
64
|
async function discoverGlobalWorkflows() {
|
|
67
|
-
return discoverFromDir(join(
|
|
65
|
+
return discoverFromDir(join(resolveGlobalConfigDir(), 'workflows'), 'user');
|
|
68
66
|
}
|
|
69
67
|
/** 合法工作流名称:仅小写字母、数字、连字符。 */
|
|
70
68
|
const WORKFLOW_NAME_RE = /^[a-z0-9-]+$/;
|
|
@@ -82,7 +80,7 @@ async function saveWorkflow(name, source, target = 'project', projectDir) {
|
|
|
82
80
|
}
|
|
83
81
|
const dir = target === 'project'
|
|
84
82
|
? join(projectDir ?? '.', PROJECT_WORKFLOWS_DIR)
|
|
85
|
-
: join(
|
|
83
|
+
: join(resolveGlobalConfigDir(), 'workflows');
|
|
86
84
|
await mkdir(dir, { recursive: true });
|
|
87
85
|
const filePath = join(dir, `${name}.js`);
|
|
88
86
|
await writeFile(filePath, source, 'utf-8');
|
|
@@ -4,5 +4,6 @@ export type { SaveResult, SaveTarget } from './discovery.js';
|
|
|
4
4
|
export { discoverGlobalWorkflows, discoverWorkflows, saveWorkflow } from './discovery.js';
|
|
5
5
|
export type { WorkflowRegistry } from './registry.js';
|
|
6
6
|
export { createAndPopulateRegistry, createWorkflowRegistry, reloadRegistry } from './registry.js';
|
|
7
|
-
export {
|
|
7
|
+
export { resolveWorkflow } from './resolve.js';
|
|
8
|
+
export { executeWorkflow, workflowSessionTitle } from './runtime.js';
|
|
8
9
|
export type { WorkflowAgentResult, WorkflowContext, WorkflowEntry, WorkflowMeta, WorkflowModule, WorkflowResult, WorkflowSource, WorkflowUtils, } from './types.js';
|
|
@@ -2,4 +2,5 @@ export { BUILTIN_WORKFLOWS, createBuiltinWorkflows } from './builtins.js';
|
|
|
2
2
|
export { buildWorkflowContext } from './context.js';
|
|
3
3
|
export { discoverGlobalWorkflows, discoverWorkflows, saveWorkflow } from './discovery.js';
|
|
4
4
|
export { createAndPopulateRegistry, createWorkflowRegistry, reloadRegistry } from './registry.js';
|
|
5
|
-
export {
|
|
5
|
+
export { resolveWorkflow } from './resolve.js';
|
|
6
|
+
export { executeWorkflow, workflowSessionTitle } from './runtime.js';
|
|
@@ -10,18 +10,28 @@ declare function createWorkflowRegistry(): {
|
|
|
10
10
|
clear(): void;
|
|
11
11
|
};
|
|
12
12
|
type WorkflowRegistry = ReturnType<typeof createWorkflowRegistry>;
|
|
13
|
+
type RegistryPopulateOptions = {
|
|
14
|
+
/**
|
|
15
|
+
* 项目是否当前可信任(P0 信任边界):false 时跳过项目级
|
|
16
|
+
* `.c0de/workflows/*.js` 发现(不 dynamic import 仓库代码)。
|
|
17
|
+
* 缺省为 false——调用方必须显式确认信任后才放行(fail-closed)。
|
|
18
|
+
* 内置与全局 `~/.c0de/workflows` 是用户本机显式安装,始终加载。
|
|
19
|
+
*/
|
|
20
|
+
projectTrusted?: boolean;
|
|
21
|
+
};
|
|
13
22
|
/**
|
|
14
23
|
* 创建并填充工作流注册表(三级发现,后注册覆盖同名):
|
|
15
24
|
* 1. 注册内置工作流(builtin)
|
|
16
25
|
* 2. 发现并注册全局 `~/.c0de/workflows/*.js`(user)
|
|
17
|
-
* 3. 发现并注册项目 `.c0de/workflows/*.js`(project
|
|
26
|
+
* 3. 发现并注册项目 `.c0de/workflows/*.js`(project;仅 projectTrusted 时)
|
|
18
27
|
* 覆盖优先级:project > user > builtin。
|
|
19
28
|
*/
|
|
20
|
-
declare function createAndPopulateRegistry(projectDir: string): Promise<WorkflowRegistry>;
|
|
29
|
+
declare function createAndPopulateRegistry(projectDir: string, opts?: RegistryPopulateOptions): Promise<WorkflowRegistry>;
|
|
21
30
|
/**
|
|
22
31
|
* 重新填充已有注册表:清空 → 三级发现 → 注册。
|
|
23
32
|
* 用于 create/save 后热重载,保留同一 registry 引用。
|
|
33
|
+
* 项目级发现同样受 projectTrusted 门禁(fail-closed)。
|
|
24
34
|
*/
|
|
25
|
-
declare function reloadRegistry(registry: WorkflowRegistry, projectDir: string): Promise<void>;
|
|
35
|
+
declare function reloadRegistry(registry: WorkflowRegistry, projectDir: string, opts?: RegistryPopulateOptions): Promise<void>;
|
|
26
36
|
export type { WorkflowRegistry };
|
|
27
37
|
export { createAndPopulateRegistry, createWorkflowRegistry, reloadRegistry };
|
|
@@ -29,10 +29,10 @@ function createWorkflowRegistry() {
|
|
|
29
29
|
* 创建并填充工作流注册表(三级发现,后注册覆盖同名):
|
|
30
30
|
* 1. 注册内置工作流(builtin)
|
|
31
31
|
* 2. 发现并注册全局 `~/.c0de/workflows/*.js`(user)
|
|
32
|
-
* 3. 发现并注册项目 `.c0de/workflows/*.js`(project
|
|
32
|
+
* 3. 发现并注册项目 `.c0de/workflows/*.js`(project;仅 projectTrusted 时)
|
|
33
33
|
* 覆盖优先级:project > user > builtin。
|
|
34
34
|
*/
|
|
35
|
-
async function createAndPopulateRegistry(projectDir) {
|
|
35
|
+
async function createAndPopulateRegistry(projectDir, opts = {}) {
|
|
36
36
|
const registry = createWorkflowRegistry();
|
|
37
37
|
// 1. 内置(由源码字符串动态导入生成,show === run)
|
|
38
38
|
for (const wf of await createBuiltinWorkflows()) {
|
|
@@ -43,18 +43,21 @@ async function createAndPopulateRegistry(projectDir) {
|
|
|
43
43
|
for (const wf of globalWorkflows) {
|
|
44
44
|
registry.register(wf);
|
|
45
45
|
}
|
|
46
|
-
// 3. 项目级(.c0de/workflows
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
// 3. 项目级(.c0de/workflows)——未信任项目绝不 import(任意代码执行面)
|
|
47
|
+
if (opts.projectTrusted) {
|
|
48
|
+
const projectWorkflows = await discoverWorkflows(projectDir);
|
|
49
|
+
for (const wf of projectWorkflows) {
|
|
50
|
+
registry.register(wf);
|
|
51
|
+
}
|
|
50
52
|
}
|
|
51
53
|
return registry;
|
|
52
54
|
}
|
|
53
55
|
/**
|
|
54
56
|
* 重新填充已有注册表:清空 → 三级发现 → 注册。
|
|
55
57
|
* 用于 create/save 后热重载,保留同一 registry 引用。
|
|
58
|
+
* 项目级发现同样受 projectTrusted 门禁(fail-closed)。
|
|
56
59
|
*/
|
|
57
|
-
async function reloadRegistry(registry, projectDir) {
|
|
60
|
+
async function reloadRegistry(registry, projectDir, opts = {}) {
|
|
58
61
|
registry.clear();
|
|
59
62
|
for (const wf of await createBuiltinWorkflows()) {
|
|
60
63
|
registry.register(wf);
|
|
@@ -62,8 +65,10 @@ async function reloadRegistry(registry, projectDir) {
|
|
|
62
65
|
for (const wf of await discoverGlobalWorkflows()) {
|
|
63
66
|
registry.register(wf);
|
|
64
67
|
}
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
if (opts.projectTrusted) {
|
|
69
|
+
for (const wf of await discoverWorkflows(projectDir)) {
|
|
70
|
+
registry.register(wf);
|
|
71
|
+
}
|
|
67
72
|
}
|
|
68
73
|
}
|
|
69
74
|
export { createAndPopulateRegistry, createWorkflowRegistry, reloadRegistry };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { WorkflowRegistry } from './registry.js';
|
|
2
|
+
import type { WorkflowEntry } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* 统一工作流解析:按「项目(已信任)> 用户 > 内置」优先级查找同名工作流。
|
|
5
|
+
*
|
|
6
|
+
* 此前各消费方口径分裂:列表(GET /、/workflow list)项目级覆盖注册表,
|
|
7
|
+
* 而运行/查看(REST GET /:name、POST /:name/run、chat 斜杠、slash resolveEntry)
|
|
8
|
+
* 是注册表优先——项目级同名工作流被用户级/内置条目遮蔽,UI 显示项目版、
|
|
9
|
+
* 实际执行另一份。全部调用点必须经此函数收敛。
|
|
10
|
+
*
|
|
11
|
+
* 项目级发现受信任门禁:discoverWorkflows 会 dynamic import 仓库代码
|
|
12
|
+
* (模块顶层即刻执行),未信任/漂移的项目绝不发现(fail-closed,回退注册表)。
|
|
13
|
+
*/
|
|
14
|
+
declare function resolveWorkflow(opts: {
|
|
15
|
+
name: string;
|
|
16
|
+
registry?: WorkflowRegistry | null;
|
|
17
|
+
/** 项目目录(agent cwd / 项目 worktree);缺省不发现项目级工作流。 */
|
|
18
|
+
projectDir?: string;
|
|
19
|
+
/** 项目当前是否可信(trustedAt + 指纹一致)。false/缺省 → 跳过项目级发现。 */
|
|
20
|
+
projectTrusted?: boolean;
|
|
21
|
+
}): Promise<WorkflowEntry | undefined>;
|
|
22
|
+
export { resolveWorkflow };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { discoverWorkflows } from './discovery.js';
|
|
2
|
+
/**
|
|
3
|
+
* 统一工作流解析:按「项目(已信任)> 用户 > 内置」优先级查找同名工作流。
|
|
4
|
+
*
|
|
5
|
+
* 此前各消费方口径分裂:列表(GET /、/workflow list)项目级覆盖注册表,
|
|
6
|
+
* 而运行/查看(REST GET /:name、POST /:name/run、chat 斜杠、slash resolveEntry)
|
|
7
|
+
* 是注册表优先——项目级同名工作流被用户级/内置条目遮蔽,UI 显示项目版、
|
|
8
|
+
* 实际执行另一份。全部调用点必须经此函数收敛。
|
|
9
|
+
*
|
|
10
|
+
* 项目级发现受信任门禁:discoverWorkflows 会 dynamic import 仓库代码
|
|
11
|
+
* (模块顶层即刻执行),未信任/漂移的项目绝不发现(fail-closed,回退注册表)。
|
|
12
|
+
*/
|
|
13
|
+
async function resolveWorkflow(opts) {
|
|
14
|
+
const { name, registry, projectDir, projectTrusted } = opts;
|
|
15
|
+
if (projectDir && projectTrusted) {
|
|
16
|
+
const discovered = await discoverWorkflows(projectDir);
|
|
17
|
+
const projectEntry = discovered.find((w) => w.meta.name === name);
|
|
18
|
+
if (projectEntry)
|
|
19
|
+
return projectEntry;
|
|
20
|
+
}
|
|
21
|
+
return registry?.get(name);
|
|
22
|
+
}
|
|
23
|
+
export { resolveWorkflow };
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { AgentDependencies, AgentState, CommandResult } from '../types.js';
|
|
2
2
|
import type { WorkflowRegistry } from './registry.js';
|
|
3
3
|
import type { WorkflowEntry } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* 工作流运行会话标题:`workflow:<name> MM-DD HH:mm`。
|
|
6
|
+
* 同名工作流多次运行在会话树里可区分,不再是无时间戳的同名行。
|
|
7
|
+
*/
|
|
8
|
+
declare function workflowSessionTitle(name: string, now?: Date): string;
|
|
4
9
|
/** executeWorkflow 的参数。 */
|
|
5
10
|
type ExecuteWorkflowOpts = {
|
|
6
11
|
registry: WorkflowRegistry;
|
|
@@ -18,4 +23,4 @@ type ExecuteWorkflowOpts = {
|
|
|
18
23
|
* 工作流 return 的 output 作为 text 返回;异常捕获为 error。
|
|
19
24
|
*/
|
|
20
25
|
declare function executeWorkflow(opts: ExecuteWorkflowOpts): Promise<CommandResult>;
|
|
21
|
-
export { executeWorkflow };
|
|
26
|
+
export { executeWorkflow, workflowSessionTitle };
|
|
@@ -14,6 +14,14 @@ function createTimeoutPromise(timeoutMs, timeoutSeconds) {
|
|
|
14
14
|
timer.unref();
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* 工作流运行会话标题:`workflow:<name> MM-DD HH:mm`。
|
|
19
|
+
* 同名工作流多次运行在会话树里可区分,不再是无时间戳的同名行。
|
|
20
|
+
*/
|
|
21
|
+
function workflowSessionTitle(name, now = new Date()) {
|
|
22
|
+
const pad = (n) => String(n).padStart(2, '0');
|
|
23
|
+
return `workflow:${name} ${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}`;
|
|
24
|
+
}
|
|
17
25
|
/**
|
|
18
26
|
* 执行工作流:查注册表 → 构建 ctx → 调用 entry.execute → 返回 CommandResult。
|
|
19
27
|
*
|
|
@@ -56,9 +64,18 @@ async function executeWorkflow(opts) {
|
|
|
56
64
|
}
|
|
57
65
|
catch (e) {
|
|
58
66
|
if (e instanceof WorkflowTimeoutError) {
|
|
67
|
+
// 超时必须真正终止执行,而不是只对用户报错——此前仅 race reject,
|
|
68
|
+
// 工作流的子 agent 仍在后台继续调 LLM/改文件(继续计费且无中止手柄)。
|
|
69
|
+
// 与 abortAgent 同语义;内联实现避免 import 循环
|
|
70
|
+
// (agent.ts → loop.ts → prompt-registry.ts → slash.ts → workflows/index.ts → 本文件)。
|
|
71
|
+
// 父 abort 经 runSubAgent 的 abort 级联传递给全部子 agent。
|
|
72
|
+
parent.abortController.abort();
|
|
73
|
+
if (parent.status._tag === 'running' || parent.status._tag === 'paused') {
|
|
74
|
+
parent.status = { _tag: 'stopped', reason: 'aborted' };
|
|
75
|
+
}
|
|
59
76
|
return {
|
|
60
77
|
_tag: 'error',
|
|
61
|
-
message: `Workflow "${name}" timed out after ${timeoutSeconds}s
|
|
78
|
+
message: `Workflow "${name}" timed out after ${timeoutSeconds}s(执行已中止)`,
|
|
62
79
|
};
|
|
63
80
|
}
|
|
64
81
|
return {
|
|
@@ -67,4 +84,4 @@ async function executeWorkflow(opts) {
|
|
|
67
84
|
};
|
|
68
85
|
}
|
|
69
86
|
}
|
|
70
|
-
export { executeWorkflow };
|
|
87
|
+
export { executeWorkflow, workflowSessionTitle };
|
package/dist/db/schema.d.ts
CHANGED
|
@@ -126,6 +126,40 @@ export declare const projects: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
126
126
|
identity: undefined;
|
|
127
127
|
generated: undefined;
|
|
128
128
|
}, {}, {}>;
|
|
129
|
+
trustedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
130
|
+
name: "trusted_at";
|
|
131
|
+
tableName: "projects";
|
|
132
|
+
dataType: "date";
|
|
133
|
+
columnType: "PgTimestamp";
|
|
134
|
+
data: Date;
|
|
135
|
+
driverParam: string;
|
|
136
|
+
notNull: false;
|
|
137
|
+
hasDefault: true;
|
|
138
|
+
isPrimaryKey: false;
|
|
139
|
+
isAutoincrement: false;
|
|
140
|
+
hasRuntimeDefault: false;
|
|
141
|
+
enumValues: undefined;
|
|
142
|
+
baseColumn: never;
|
|
143
|
+
identity: undefined;
|
|
144
|
+
generated: undefined;
|
|
145
|
+
}, {}, {}>;
|
|
146
|
+
riskFingerprint: import("drizzle-orm/pg-core").PgColumn<{
|
|
147
|
+
name: "risk_fingerprint";
|
|
148
|
+
tableName: "projects";
|
|
149
|
+
dataType: "string";
|
|
150
|
+
columnType: "PgText";
|
|
151
|
+
data: string;
|
|
152
|
+
driverParam: string;
|
|
153
|
+
notNull: false;
|
|
154
|
+
hasDefault: true;
|
|
155
|
+
isPrimaryKey: false;
|
|
156
|
+
isAutoincrement: false;
|
|
157
|
+
hasRuntimeDefault: false;
|
|
158
|
+
enumValues: [string, ...string[]];
|
|
159
|
+
baseColumn: never;
|
|
160
|
+
identity: undefined;
|
|
161
|
+
generated: undefined;
|
|
162
|
+
}, {}, {}>;
|
|
129
163
|
};
|
|
130
164
|
dialect: "pg";
|
|
131
165
|
}>;
|
|
@@ -307,6 +341,23 @@ export declare const sessions: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
307
341
|
identity: undefined;
|
|
308
342
|
generated: undefined;
|
|
309
343
|
}, {}, {}>;
|
|
344
|
+
deletedBatchId: import("drizzle-orm/pg-core").PgColumn<{
|
|
345
|
+
name: "deleted_batch_id";
|
|
346
|
+
tableName: "sessions";
|
|
347
|
+
dataType: "string";
|
|
348
|
+
columnType: "PgUUID";
|
|
349
|
+
data: string;
|
|
350
|
+
driverParam: string;
|
|
351
|
+
notNull: false;
|
|
352
|
+
hasDefault: false;
|
|
353
|
+
isPrimaryKey: false;
|
|
354
|
+
isAutoincrement: false;
|
|
355
|
+
hasRuntimeDefault: false;
|
|
356
|
+
enumValues: undefined;
|
|
357
|
+
baseColumn: never;
|
|
358
|
+
identity: undefined;
|
|
359
|
+
generated: undefined;
|
|
360
|
+
}, {}, {}>;
|
|
310
361
|
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
311
362
|
name: "created_at";
|
|
312
363
|
tableName: "sessions";
|
|
@@ -1004,6 +1055,8 @@ export declare const toolMetrics: import("drizzle-orm/pg-core").PgTableWithColum
|
|
|
1004
1055
|
/**
|
|
1005
1056
|
* Kanban boards — one per project (unique projectId). Stores column/label
|
|
1006
1057
|
* configuration as JSON; cards live in kanban_cards.
|
|
1058
|
+
* P2-5:项目删除不再级联销毁看板——projectId 置 null + deletedAt 标记,
|
|
1059
|
+
* 进入回收站「未归属看板」分组,60 天后随清理任务物理清除;恢复时可重新归属。
|
|
1007
1060
|
*/
|
|
1008
1061
|
export declare const kanbanBoards: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
1009
1062
|
name: "kanban_boards";
|
|
@@ -1033,7 +1086,7 @@ export declare const kanbanBoards: import("drizzle-orm/pg-core").PgTableWithColu
|
|
|
1033
1086
|
columnType: "PgText";
|
|
1034
1087
|
data: string;
|
|
1035
1088
|
driverParam: string;
|
|
1036
|
-
notNull:
|
|
1089
|
+
notNull: false;
|
|
1037
1090
|
hasDefault: false;
|
|
1038
1091
|
isPrimaryKey: false;
|
|
1039
1092
|
isAutoincrement: false;
|
|
@@ -1077,6 +1130,74 @@ export declare const kanbanBoards: import("drizzle-orm/pg-core").PgTableWithColu
|
|
|
1077
1130
|
identity: undefined;
|
|
1078
1131
|
generated: undefined;
|
|
1079
1132
|
}, {}, {}>;
|
|
1133
|
+
deletedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
1134
|
+
name: "deleted_at";
|
|
1135
|
+
tableName: "kanban_boards";
|
|
1136
|
+
dataType: "date";
|
|
1137
|
+
columnType: "PgTimestamp";
|
|
1138
|
+
data: Date;
|
|
1139
|
+
driverParam: string;
|
|
1140
|
+
notNull: false;
|
|
1141
|
+
hasDefault: true;
|
|
1142
|
+
isPrimaryKey: false;
|
|
1143
|
+
isAutoincrement: false;
|
|
1144
|
+
hasRuntimeDefault: false;
|
|
1145
|
+
enumValues: undefined;
|
|
1146
|
+
baseColumn: never;
|
|
1147
|
+
identity: undefined;
|
|
1148
|
+
generated: undefined;
|
|
1149
|
+
}, {}, {}>;
|
|
1150
|
+
deletedProjectName: import("drizzle-orm/pg-core").PgColumn<{
|
|
1151
|
+
name: "deleted_project_name";
|
|
1152
|
+
tableName: "kanban_boards";
|
|
1153
|
+
dataType: "string";
|
|
1154
|
+
columnType: "PgText";
|
|
1155
|
+
data: string;
|
|
1156
|
+
driverParam: string;
|
|
1157
|
+
notNull: false;
|
|
1158
|
+
hasDefault: false;
|
|
1159
|
+
isPrimaryKey: false;
|
|
1160
|
+
isAutoincrement: false;
|
|
1161
|
+
hasRuntimeDefault: false;
|
|
1162
|
+
enumValues: [string, ...string[]];
|
|
1163
|
+
baseColumn: never;
|
|
1164
|
+
identity: undefined;
|
|
1165
|
+
generated: undefined;
|
|
1166
|
+
}, {}, {}>;
|
|
1167
|
+
deletedProjectWorktree: import("drizzle-orm/pg-core").PgColumn<{
|
|
1168
|
+
name: "deleted_project_worktree";
|
|
1169
|
+
tableName: "kanban_boards";
|
|
1170
|
+
dataType: "string";
|
|
1171
|
+
columnType: "PgText";
|
|
1172
|
+
data: string;
|
|
1173
|
+
driverParam: string;
|
|
1174
|
+
notNull: false;
|
|
1175
|
+
hasDefault: false;
|
|
1176
|
+
isPrimaryKey: false;
|
|
1177
|
+
isAutoincrement: false;
|
|
1178
|
+
hasRuntimeDefault: false;
|
|
1179
|
+
enumValues: [string, ...string[]];
|
|
1180
|
+
baseColumn: never;
|
|
1181
|
+
identity: undefined;
|
|
1182
|
+
generated: undefined;
|
|
1183
|
+
}, {}, {}>;
|
|
1184
|
+
purgePendingAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
1185
|
+
name: "purge_pending_at";
|
|
1186
|
+
tableName: "kanban_boards";
|
|
1187
|
+
dataType: "date";
|
|
1188
|
+
columnType: "PgTimestamp";
|
|
1189
|
+
data: Date;
|
|
1190
|
+
driverParam: string;
|
|
1191
|
+
notNull: false;
|
|
1192
|
+
hasDefault: true;
|
|
1193
|
+
isPrimaryKey: false;
|
|
1194
|
+
isAutoincrement: false;
|
|
1195
|
+
hasRuntimeDefault: false;
|
|
1196
|
+
enumValues: undefined;
|
|
1197
|
+
baseColumn: never;
|
|
1198
|
+
identity: undefined;
|
|
1199
|
+
generated: undefined;
|
|
1200
|
+
}, {}, {}>;
|
|
1080
1201
|
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
1081
1202
|
name: "created_at";
|
|
1082
1203
|
tableName: "kanban_boards";
|
|
@@ -1296,6 +1417,253 @@ export declare const kanbanCards: import("drizzle-orm/pg-core").PgTableWithColum
|
|
|
1296
1417
|
};
|
|
1297
1418
|
dialect: "pg";
|
|
1298
1419
|
}>;
|
|
1420
|
+
/**
|
|
1421
|
+
* Usage events — append-only LLM cost ledger (P2 cost accounting decoupled from
|
|
1422
|
+
* session lifecycle). One row per LLM call, written by loop manageSegment.
|
|
1423
|
+
* No FK to sessions/projects: physical purge of sessions (recycle-bin expiry,
|
|
1424
|
+
* manual forever-delete, temp CLI cleanup) must NOT erase spent-cost records —
|
|
1425
|
+
* 成本是账本. sessionId/projectId are denormalized provenance only.
|
|
1426
|
+
*/
|
|
1427
|
+
export declare const usageEvents: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
1428
|
+
name: "usage_events";
|
|
1429
|
+
schema: undefined;
|
|
1430
|
+
columns: {
|
|
1431
|
+
id: import("drizzle-orm/pg-core").PgColumn<{
|
|
1432
|
+
name: "id";
|
|
1433
|
+
tableName: "usage_events";
|
|
1434
|
+
dataType: "string";
|
|
1435
|
+
columnType: "PgUUID";
|
|
1436
|
+
data: string;
|
|
1437
|
+
driverParam: string;
|
|
1438
|
+
notNull: true;
|
|
1439
|
+
hasDefault: true;
|
|
1440
|
+
isPrimaryKey: true;
|
|
1441
|
+
isAutoincrement: false;
|
|
1442
|
+
hasRuntimeDefault: false;
|
|
1443
|
+
enumValues: undefined;
|
|
1444
|
+
baseColumn: never;
|
|
1445
|
+
identity: undefined;
|
|
1446
|
+
generated: undefined;
|
|
1447
|
+
}, {}, {}>;
|
|
1448
|
+
callId: import("drizzle-orm/pg-core").PgColumn<{
|
|
1449
|
+
name: "call_id";
|
|
1450
|
+
tableName: "usage_events";
|
|
1451
|
+
dataType: "string";
|
|
1452
|
+
columnType: "PgUUID";
|
|
1453
|
+
data: string;
|
|
1454
|
+
driverParam: string;
|
|
1455
|
+
notNull: true;
|
|
1456
|
+
hasDefault: false;
|
|
1457
|
+
isPrimaryKey: false;
|
|
1458
|
+
isAutoincrement: false;
|
|
1459
|
+
hasRuntimeDefault: false;
|
|
1460
|
+
enumValues: undefined;
|
|
1461
|
+
baseColumn: never;
|
|
1462
|
+
identity: undefined;
|
|
1463
|
+
generated: undefined;
|
|
1464
|
+
}, {}, {}>;
|
|
1465
|
+
sessionId: import("drizzle-orm/pg-core").PgColumn<{
|
|
1466
|
+
name: "session_id";
|
|
1467
|
+
tableName: "usage_events";
|
|
1468
|
+
dataType: "string";
|
|
1469
|
+
columnType: "PgUUID";
|
|
1470
|
+
data: string;
|
|
1471
|
+
driverParam: string;
|
|
1472
|
+
notNull: false;
|
|
1473
|
+
hasDefault: false;
|
|
1474
|
+
isPrimaryKey: false;
|
|
1475
|
+
isAutoincrement: false;
|
|
1476
|
+
hasRuntimeDefault: false;
|
|
1477
|
+
enumValues: undefined;
|
|
1478
|
+
baseColumn: never;
|
|
1479
|
+
identity: undefined;
|
|
1480
|
+
generated: undefined;
|
|
1481
|
+
}, {}, {}>;
|
|
1482
|
+
projectId: import("drizzle-orm/pg-core").PgColumn<{
|
|
1483
|
+
name: "project_id";
|
|
1484
|
+
tableName: "usage_events";
|
|
1485
|
+
dataType: "string";
|
|
1486
|
+
columnType: "PgText";
|
|
1487
|
+
data: string;
|
|
1488
|
+
driverParam: string;
|
|
1489
|
+
notNull: false;
|
|
1490
|
+
hasDefault: false;
|
|
1491
|
+
isPrimaryKey: false;
|
|
1492
|
+
isAutoincrement: false;
|
|
1493
|
+
hasRuntimeDefault: false;
|
|
1494
|
+
enumValues: [string, ...string[]];
|
|
1495
|
+
baseColumn: never;
|
|
1496
|
+
identity: undefined;
|
|
1497
|
+
generated: undefined;
|
|
1498
|
+
}, {}, {}>;
|
|
1499
|
+
provider: import("drizzle-orm/pg-core").PgColumn<{
|
|
1500
|
+
name: "provider";
|
|
1501
|
+
tableName: "usage_events";
|
|
1502
|
+
dataType: "string";
|
|
1503
|
+
columnType: "PgText";
|
|
1504
|
+
data: string;
|
|
1505
|
+
driverParam: string;
|
|
1506
|
+
notNull: true;
|
|
1507
|
+
hasDefault: false;
|
|
1508
|
+
isPrimaryKey: false;
|
|
1509
|
+
isAutoincrement: false;
|
|
1510
|
+
hasRuntimeDefault: false;
|
|
1511
|
+
enumValues: [string, ...string[]];
|
|
1512
|
+
baseColumn: never;
|
|
1513
|
+
identity: undefined;
|
|
1514
|
+
generated: undefined;
|
|
1515
|
+
}, {}, {}>;
|
|
1516
|
+
model: import("drizzle-orm/pg-core").PgColumn<{
|
|
1517
|
+
name: "model";
|
|
1518
|
+
tableName: "usage_events";
|
|
1519
|
+
dataType: "string";
|
|
1520
|
+
columnType: "PgText";
|
|
1521
|
+
data: string;
|
|
1522
|
+
driverParam: string;
|
|
1523
|
+
notNull: true;
|
|
1524
|
+
hasDefault: false;
|
|
1525
|
+
isPrimaryKey: false;
|
|
1526
|
+
isAutoincrement: false;
|
|
1527
|
+
hasRuntimeDefault: false;
|
|
1528
|
+
enumValues: [string, ...string[]];
|
|
1529
|
+
baseColumn: never;
|
|
1530
|
+
identity: undefined;
|
|
1531
|
+
generated: undefined;
|
|
1532
|
+
}, {}, {}>;
|
|
1533
|
+
inputTokens: import("drizzle-orm/pg-core").PgColumn<{
|
|
1534
|
+
name: "input_tokens";
|
|
1535
|
+
tableName: "usage_events";
|
|
1536
|
+
dataType: "number";
|
|
1537
|
+
columnType: "PgBigInt53";
|
|
1538
|
+
data: number;
|
|
1539
|
+
driverParam: string | number;
|
|
1540
|
+
notNull: true;
|
|
1541
|
+
hasDefault: true;
|
|
1542
|
+
isPrimaryKey: false;
|
|
1543
|
+
isAutoincrement: false;
|
|
1544
|
+
hasRuntimeDefault: false;
|
|
1545
|
+
enumValues: undefined;
|
|
1546
|
+
baseColumn: never;
|
|
1547
|
+
identity: undefined;
|
|
1548
|
+
generated: undefined;
|
|
1549
|
+
}, {}, {}>;
|
|
1550
|
+
outputTokens: import("drizzle-orm/pg-core").PgColumn<{
|
|
1551
|
+
name: "output_tokens";
|
|
1552
|
+
tableName: "usage_events";
|
|
1553
|
+
dataType: "number";
|
|
1554
|
+
columnType: "PgBigInt53";
|
|
1555
|
+
data: number;
|
|
1556
|
+
driverParam: string | number;
|
|
1557
|
+
notNull: true;
|
|
1558
|
+
hasDefault: true;
|
|
1559
|
+
isPrimaryKey: false;
|
|
1560
|
+
isAutoincrement: false;
|
|
1561
|
+
hasRuntimeDefault: false;
|
|
1562
|
+
enumValues: undefined;
|
|
1563
|
+
baseColumn: never;
|
|
1564
|
+
identity: undefined;
|
|
1565
|
+
generated: undefined;
|
|
1566
|
+
}, {}, {}>;
|
|
1567
|
+
cacheRead: import("drizzle-orm/pg-core").PgColumn<{
|
|
1568
|
+
name: "cache_read";
|
|
1569
|
+
tableName: "usage_events";
|
|
1570
|
+
dataType: "number";
|
|
1571
|
+
columnType: "PgBigInt53";
|
|
1572
|
+
data: number;
|
|
1573
|
+
driverParam: string | number;
|
|
1574
|
+
notNull: false;
|
|
1575
|
+
hasDefault: true;
|
|
1576
|
+
isPrimaryKey: false;
|
|
1577
|
+
isAutoincrement: false;
|
|
1578
|
+
hasRuntimeDefault: false;
|
|
1579
|
+
enumValues: undefined;
|
|
1580
|
+
baseColumn: never;
|
|
1581
|
+
identity: undefined;
|
|
1582
|
+
generated: undefined;
|
|
1583
|
+
}, {}, {}>;
|
|
1584
|
+
cost: import("drizzle-orm/pg-core").PgColumn<{
|
|
1585
|
+
name: "cost";
|
|
1586
|
+
tableName: "usage_events";
|
|
1587
|
+
dataType: "number";
|
|
1588
|
+
columnType: "PgReal";
|
|
1589
|
+
data: number;
|
|
1590
|
+
driverParam: string | number;
|
|
1591
|
+
notNull: false;
|
|
1592
|
+
hasDefault: false;
|
|
1593
|
+
isPrimaryKey: false;
|
|
1594
|
+
isAutoincrement: false;
|
|
1595
|
+
hasRuntimeDefault: false;
|
|
1596
|
+
enumValues: undefined;
|
|
1597
|
+
baseColumn: never;
|
|
1598
|
+
identity: undefined;
|
|
1599
|
+
generated: undefined;
|
|
1600
|
+
}, {}, {}>;
|
|
1601
|
+
timestamp: import("drizzle-orm/pg-core").PgColumn<{
|
|
1602
|
+
name: "timestamp";
|
|
1603
|
+
tableName: "usage_events";
|
|
1604
|
+
dataType: "number";
|
|
1605
|
+
columnType: "PgBigInt53";
|
|
1606
|
+
data: number;
|
|
1607
|
+
driverParam: string | number;
|
|
1608
|
+
notNull: true;
|
|
1609
|
+
hasDefault: false;
|
|
1610
|
+
isPrimaryKey: false;
|
|
1611
|
+
isAutoincrement: false;
|
|
1612
|
+
hasRuntimeDefault: false;
|
|
1613
|
+
enumValues: undefined;
|
|
1614
|
+
baseColumn: never;
|
|
1615
|
+
identity: undefined;
|
|
1616
|
+
generated: undefined;
|
|
1617
|
+
}, {}, {}>;
|
|
1618
|
+
};
|
|
1619
|
+
dialect: "pg";
|
|
1620
|
+
}>;
|
|
1621
|
+
/**
|
|
1622
|
+
* App metadata — 一次性迁移/初始化标记(key-value)。
|
|
1623
|
+
* P3-8:usage backfill 迁移完成后写 'usage_backfill_v1' 标记,
|
|
1624
|
+
* 后续启动跳过全表扫描(导入/备份路径不依赖 backfill 的会话不再产生账本行)。
|
|
1625
|
+
*/
|
|
1626
|
+
export declare const appMeta: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
1627
|
+
name: "app_meta";
|
|
1628
|
+
schema: undefined;
|
|
1629
|
+
columns: {
|
|
1630
|
+
key: import("drizzle-orm/pg-core").PgColumn<{
|
|
1631
|
+
name: "key";
|
|
1632
|
+
tableName: "app_meta";
|
|
1633
|
+
dataType: "string";
|
|
1634
|
+
columnType: "PgText";
|
|
1635
|
+
data: string;
|
|
1636
|
+
driverParam: string;
|
|
1637
|
+
notNull: true;
|
|
1638
|
+
hasDefault: false;
|
|
1639
|
+
isPrimaryKey: true;
|
|
1640
|
+
isAutoincrement: false;
|
|
1641
|
+
hasRuntimeDefault: false;
|
|
1642
|
+
enumValues: [string, ...string[]];
|
|
1643
|
+
baseColumn: never;
|
|
1644
|
+
identity: undefined;
|
|
1645
|
+
generated: undefined;
|
|
1646
|
+
}, {}, {}>;
|
|
1647
|
+
value: import("drizzle-orm/pg-core").PgColumn<{
|
|
1648
|
+
name: "value";
|
|
1649
|
+
tableName: "app_meta";
|
|
1650
|
+
dataType: "string";
|
|
1651
|
+
columnType: "PgText";
|
|
1652
|
+
data: string;
|
|
1653
|
+
driverParam: string;
|
|
1654
|
+
notNull: true;
|
|
1655
|
+
hasDefault: false;
|
|
1656
|
+
isPrimaryKey: false;
|
|
1657
|
+
isAutoincrement: false;
|
|
1658
|
+
hasRuntimeDefault: false;
|
|
1659
|
+
enumValues: [string, ...string[]];
|
|
1660
|
+
baseColumn: never;
|
|
1661
|
+
identity: undefined;
|
|
1662
|
+
generated: undefined;
|
|
1663
|
+
}, {}, {}>;
|
|
1664
|
+
};
|
|
1665
|
+
dialect: "pg";
|
|
1666
|
+
}>;
|
|
1299
1667
|
/** Type exports for insert/select operations. */
|
|
1300
1668
|
export type ProjectRow = typeof projects.$inferSelect;
|
|
1301
1669
|
export type ProjectInsert = typeof projects.$inferInsert;
|
|
@@ -1313,3 +1681,7 @@ export type KanbanBoardRow = typeof kanbanBoards.$inferSelect;
|
|
|
1313
1681
|
export type KanbanBoardInsert = typeof kanbanBoards.$inferInsert;
|
|
1314
1682
|
export type KanbanCardRow = typeof kanbanCards.$inferSelect;
|
|
1315
1683
|
export type KanbanCardInsert = typeof kanbanCards.$inferInsert;
|
|
1684
|
+
export type UsageEventRow = typeof usageEvents.$inferSelect;
|
|
1685
|
+
export type UsageEventInsert = typeof usageEvents.$inferInsert;
|
|
1686
|
+
export type AppMetaRow = typeof appMeta.$inferSelect;
|
|
1687
|
+
export type AppMetaInsert = typeof appMeta.$inferInsert;
|