Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

307 lines
9.1 KiB
Go

package workspace
import (
"context"
"fmt"
"time"
)
func (s *SQLiteStore) applyWorkspaceAppsV1(ctx context.Context) error {
applied, err := s.hasMigration(ctx, schemaMigrationWorkspaceAppsV1)
if err != nil {
return err
}
if applied {
return nil
}
now := unixMs(time.Now().UTC())
_, err = s.writeDB.ExecContext(ctx, `
CREATE TABLE IF NOT EXISTS app_packages (
app_id TEXT PRIMARY KEY,
version TEXT NOT NULL,
package_dir TEXT NOT NULL,
manifest_json TEXT NOT NULL DEFAULT '',
created_at_unix_ms INTEGER NOT NULL,
updated_at_unix_ms INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS workspace_app_installations (
workspace_id TEXT NOT NULL,
app_id TEXT NOT NULL,
enabled INTEGER NOT NULL DEFAULT 1,
created_at_unix_ms INTEGER NOT NULL,
updated_at_unix_ms INTEGER NOT NULL,
PRIMARY KEY (workspace_id, app_id),
FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE,
FOREIGN KEY (app_id) REFERENCES app_packages(app_id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_workspace_app_installations_workspace
ON workspace_app_installations(workspace_id, app_id ASC);
INSERT INTO tuttid_schema_migrations (id, applied_at_unix_ms)
VALUES (?, ?);
`, schemaMigrationWorkspaceAppsV1, now)
if err != nil {
return fmt.Errorf("migrate workspace database apps v1: %w", err)
}
return nil
}
func (s *SQLiteStore) applyWorkspaceAppsV2(ctx context.Context) error {
applied, err := s.hasMigration(ctx, schemaMigrationWorkspaceAppsV2)
if err != nil {
return err
}
if applied {
return nil
}
hasManifestJSON, err := s.hasColumn(ctx, "app_packages", "manifest_json")
if err != nil {
return err
}
now := unixMs(time.Now().UTC())
if !hasManifestJSON {
if _, err := s.writeDB.ExecContext(ctx, `
ALTER TABLE app_packages ADD COLUMN manifest_json TEXT NOT NULL DEFAULT '';
`); err != nil {
return fmt.Errorf("migrate workspace database apps v2: %w", err)
}
}
_, err = s.writeDB.ExecContext(ctx, `
INSERT INTO tuttid_schema_migrations (id, applied_at_unix_ms)
VALUES (?, ?);
`, schemaMigrationWorkspaceAppsV2, now)
if err != nil {
return fmt.Errorf("record workspace database apps v2 migration: %w", err)
}
return nil
}
func (s *SQLiteStore) applyWorkspaceAppsV3(ctx context.Context) error {
applied, err := s.hasMigration(ctx, schemaMigrationWorkspaceAppsV3)
if err != nil {
return err
}
if applied {
return nil
}
now := unixMs(time.Now().UTC())
if _, err := s.writeDB.ExecContext(ctx, `PRAGMA foreign_keys = OFF`); err != nil {
return fmt.Errorf("disable sqlite foreign keys for workspace apps v3 migration: %w", err)
}
defer func() {
_, _ = s.writeDB.ExecContext(context.Background(), `PRAGMA foreign_keys = ON`)
}()
tx, err := s.writeDB.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("begin workspace apps v3 migration: %w", err)
}
defer func() {
_ = tx.Rollback()
}()
_, err = tx.ExecContext(ctx, `
DROP INDEX IF EXISTS idx_workspace_app_installations_workspace;
CREATE TABLE app_packages_v3 (
app_id TEXT NOT NULL,
version TEXT NOT NULL,
package_dir TEXT NOT NULL,
manifest_json TEXT NOT NULL DEFAULT '',
source TEXT NOT NULL DEFAULT 'builtin',
factory_job_id TEXT NOT NULL DEFAULT '',
created_in_workspace_id TEXT NOT NULL DEFAULT '',
created_at_unix_ms INTEGER NOT NULL,
updated_at_unix_ms INTEGER NOT NULL,
PRIMARY KEY (app_id, version)
);
INSERT INTO app_packages_v3 (
app_id, version, package_dir, manifest_json, source, created_at_unix_ms, updated_at_unix_ms
)
SELECT app_id, version, package_dir, manifest_json, 'builtin', created_at_unix_ms, updated_at_unix_ms
FROM app_packages;
CREATE TABLE app_catalog_entries (
app_id TEXT PRIMARY KEY,
active_version TEXT NOT NULL,
source TEXT NOT NULL DEFAULT 'builtin',
created_in_workspace_id TEXT NOT NULL DEFAULT '',
created_at_unix_ms INTEGER NOT NULL,
updated_at_unix_ms INTEGER NOT NULL
);
INSERT INTO app_catalog_entries (
app_id, active_version, source, created_at_unix_ms, updated_at_unix_ms
)
SELECT app_id, version, 'builtin', created_at_unix_ms, updated_at_unix_ms
FROM app_packages;
CREATE TABLE workspace_app_installations_v3 (
workspace_id TEXT NOT NULL,
app_id TEXT NOT NULL,
enabled INTEGER NOT NULL DEFAULT 1,
created_at_unix_ms INTEGER NOT NULL,
updated_at_unix_ms INTEGER NOT NULL,
PRIMARY KEY (workspace_id, app_id),
FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE,
FOREIGN KEY (app_id) REFERENCES app_catalog_entries(app_id) ON DELETE CASCADE
);
INSERT INTO workspace_app_installations_v3 (
workspace_id, app_id, enabled, created_at_unix_ms, updated_at_unix_ms
)
SELECT workspace_id, app_id, enabled, created_at_unix_ms, updated_at_unix_ms
FROM workspace_app_installations;
DROP TABLE workspace_app_installations;
DROP TABLE app_packages;
ALTER TABLE app_packages_v3 RENAME TO app_packages;
ALTER TABLE workspace_app_installations_v3 RENAME TO workspace_app_installations;
CREATE INDEX IF NOT EXISTS idx_workspace_app_installations_workspace
ON workspace_app_installations(workspace_id, app_id ASC);
CREATE INDEX IF NOT EXISTS idx_app_packages_app_updated
ON app_packages(app_id, updated_at_unix_ms DESC);
INSERT INTO tuttid_schema_migrations (id, applied_at_unix_ms)
VALUES (?, ?);
`, schemaMigrationWorkspaceAppsV3, now)
if err != nil {
return fmt.Errorf("migrate workspace database apps v3: %w", err)
}
if err := tx.Commit(); err != nil {
return fmt.Errorf("commit workspace apps v3 migration: %w", err)
}
if _, err := s.writeDB.ExecContext(ctx, `PRAGMA foreign_keys = ON`); err != nil {
return fmt.Errorf("re-enable sqlite foreign keys for workspace apps v3 migration: %w", err)
}
return nil
}
func (s *SQLiteStore) applyAppFactoryJobsV1(ctx context.Context) error {
applied, err := s.hasMigration(ctx, schemaMigrationAppFactoryJobsV1)
if err != nil {
return err
}
if applied {
return nil
}
now := unixMs(time.Now().UTC())
_, err = s.writeDB.ExecContext(ctx, `
CREATE TABLE IF NOT EXISTS app_factory_jobs (
workspace_id TEXT NOT NULL,
job_id TEXT NOT NULL,
status TEXT NOT NULL,
prompt TEXT NOT NULL,
app_id TEXT NOT NULL DEFAULT '',
display_name TEXT NOT NULL DEFAULT '',
description TEXT NOT NULL DEFAULT '',
agent_target_id TEXT NOT NULL DEFAULT '',
provider TEXT NOT NULL DEFAULT '',
model TEXT NOT NULL DEFAULT '',
agent_session_id TEXT NOT NULL DEFAULT '',
draft_dir TEXT NOT NULL DEFAULT '',
runtime_dir TEXT NOT NULL DEFAULT '',
data_dir TEXT NOT NULL DEFAULT '',
log_dir TEXT NOT NULL DEFAULT '',
package_dir TEXT NOT NULL DEFAULT '',
validation_result_json TEXT NOT NULL DEFAULT '',
failure_reason TEXT NOT NULL DEFAULT '',
published_version TEXT NOT NULL DEFAULT '',
created_at_unix_ms INTEGER NOT NULL,
updated_at_unix_ms INTEGER NOT NULL,
PRIMARY KEY (workspace_id, job_id),
FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_app_factory_jobs_workspace_updated
ON app_factory_jobs(workspace_id, updated_at_unix_ms DESC, job_id ASC);
INSERT INTO tuttid_schema_migrations (id, applied_at_unix_ms)
VALUES (?, ?);
`, schemaMigrationAppFactoryJobsV1, now)
if err != nil {
return fmt.Errorf("migrate workspace database app factory jobs v1: %w", err)
}
return nil
}
func (s *SQLiteStore) applyAppFactoryJobsV2(ctx context.Context) error {
applied, err := s.hasMigration(ctx, schemaMigrationAppFactoryJobsV2)
if err != nil {
return err
}
if applied {
return nil
}
now := unixMs(time.Now().UTC())
_, err = s.writeDB.ExecContext(ctx, `
ALTER TABLE app_factory_jobs
ADD COLUMN reasoning_effort TEXT NOT NULL DEFAULT '';
INSERT INTO tuttid_schema_migrations (id, applied_at_unix_ms)
VALUES (?, ?);
`, schemaMigrationAppFactoryJobsV2, now)
if err != nil {
return fmt.Errorf("migrate workspace database app factory jobs v2: %w", err)
}
return nil
}
func (s *SQLiteStore) applyAppFactoryJobsV3(ctx context.Context) error {
applied, err := s.hasMigration(ctx, schemaMigrationAppFactoryJobsV3)
if err != nil {
return err
}
if applied {
return nil
}
hasAgentTargetID, err := s.hasColumn(ctx, "app_factory_jobs", "agent_target_id")
if err != nil {
return err
}
if !hasAgentTargetID {
if _, err := s.writeDB.ExecContext(ctx, `
ALTER TABLE app_factory_jobs ADD COLUMN agent_target_id TEXT NOT NULL DEFAULT '';
`); err != nil {
return fmt.Errorf("migrate workspace app factory jobs agent target id: %w", err)
}
}
now := unixMs(time.Now().UTC())
targetIDs := defaultTargetIDBackfillByProvider()
codexTargetID := targetIDs["codex"]
if codexTargetID == "" {
return fmt.Errorf("migrate workspace app factory jobs agent target id: codex target descriptor is missing")
}
if _, err := s.writeDB.ExecContext(ctx, `
UPDATE app_factory_jobs
SET agent_target_id = CASE provider
WHEN ? THEN ?
WHEN 'claude-code' THEN 'local:claude-code'
ELSE agent_target_id
END
WHERE agent_target_id = '';
`, "codex", codexTargetID); err != nil {
return fmt.Errorf("backfill workspace app factory job agent target ids: %w", err)
}
_, err = s.writeDB.ExecContext(ctx, `
INSERT INTO tuttid_schema_migrations (id, applied_at_unix_ms)
VALUES (?, ?);
`, schemaMigrationAppFactoryJobsV3, now)
if err != nil {
return fmt.Errorf("record workspace app factory jobs v3 migration: %w", err)
}
return nil
}