This commit is contained in:
-Puter
2026-08-03 18:13:45 +05:30
parent 289c16f11e
commit 48205a5e19
13 changed files with 5362 additions and 7318 deletions

View File

@@ -1,102 +0,0 @@
# Slice 1 Handoff Notes
Date: 2026-07-27 Branch: `master` at `cfdb2efc7` PR: #19 (merged)
## What was built
### Core product loop
- Conversation to Signal to proposed Work with exact source provenance.
- Convex owns durable data: `conversationMessages`, `signals`, `works`, `workEvents`.
- Effect validation in `@code/work-os` package.
- Flue agent (`packages/agents/src/agents/zopu.ts`) routes actionable messages through Signal/Work tools.
- Slice-one tools at `packages/agents/src/tools/slice-one.ts`.
- Mobile-first UI at `apps/web/src/components/slice-one/slice-one-page.tsx`.
### Model
- MiMo V2.5 (`xiaomi/mimo-v2.5`) via Cheaptricks AI gateway.
- Provider identity `xiaomi` gives Flue correct multimodal metadata (text + image).
- `AGENT_MODEL_BASE_URL` points at Cheaptricks; API key in `.env`.
- Context window 1,048,576; max output tokens 131,076.
- `thinkingLevel: "medium"`.
### Reasoning traces
- Native Flue `reasoning` parts render as live "Thinking trace" (open while streaming, collapsed after).
- Inline `<think>...</think>` extraction for models that embed thinking in text.
- No fallback that hides model output.
### Image attachments
- Picker button + hidden file input, up to 4 images at 10 MB each.
- Base64 conversion into Flue `AgentPromptImage`.
- Authenticated blob-URL rendering for historical image replay.
- Verified live: MiMo read exact text and background color from generated test images.
### Mobile keyboard fix
- Visual viewport hook (`use-visual-viewport.ts`).
- Fixed full-screen shell; `interactive-widget=resizes-content` in viewport meta.
- Header stays pinned; chat shrinks; composer follows keyboard.
- Regression tests in `frontend-regressions.test.ts` and `use-visual-viewport.test.ts`.
### Rendering
- Streamdown markdown streaming with Mermaid chart support.
- Tool turns hidden; reasoning-containing tool turns remain visible.
- Work cards render inline in the conversation timeline with source navigation.
### Deployment
- Cheaptricks staging live at `https://zopu.cheaptricks.puter.wtf`.
- Caddy reverse proxy: `/api/*` to Flue (port 3585), root to web (port 5173).
- `server.allowedHosts: true` in `apps/web/vite.config.ts` for Caddy domain.
- Convex `SITE_URL` set to `https://zopu.cheaptricks.puter.wtf`.
- Both processes running via `nohup` on Cheaptricks (PIDs 416955 and 418726).
- Deployment notes at `docs/deployment.md`.
### Repository cleanup
- 17 stale worktrees removed (Codex, Paseo, T3).
- 23 stale local branches deleted.
- 18 stale remote branches deleted.
- 6 stale PRs closed (#1, #10, #11, #12, #13, #15).
- 8 stale issues closed (#4, #5, #6, #7, #8, #9, #14, #17).
- 0 open PRs, 0 open issues.
## Current state
### Running
- Cheaptricks: web on `:5173`, Flue on `:3585`, both persistent via `nohup`.
- Local Mac: servers stopped. Run `bun run dev:tailscale:agents -- --port 3585` and `bun run dev:tailscale:web` to start.
### Git
- `master` at `cfdb2efc7` on local, Cheaptricks, and remote.
- Only `master` branch locally. Two remote branches remain: `origin/sai/changes`, `origin/t3code/explore-primitives-package` (not cleaned because they may be owned by other contributors/tools).
## Known issues and next steps
1. **Convex SITE_URL is single-valued.** Switch it when moving between local and staging:
```bash
cd packages/backend
npx convex env set SITE_URL 'http://100.101.157.28:5173' # local
npx convex env set SITE_URL 'https://zopu.cheaptricks.puter.wtf' # staging
```
2. **MiMo latency is ~14-20 seconds per turn.** This is model-side thinking time, not transport. Streaming works correctly; first reasoning token arrives live. Consider a faster model or lower `thinkingLevel` if latency becomes a product problem.
3. **Audio/video input not wired.** MiMo supports audio and video per its spec, but the composer only accepts images. Adding audio/video would require extending `use-chat-images.ts`, the file input `accept` attribute, and the Flue `AgentPromptImage` type if it does not already cover those media types.
4. **Two remote branches remain.** `origin/sai/changes` and `origin/t3code/explore-primitives-package` were left because they may be owned by other tools. Delete with `git push origin --delete sai/changes t3code/explore-primitives-package` if safe.
5. **Convex schema and functions are deployed** to the dev deployment `befitting-dalmatian-161`. No pending migrations.
6. **`.env` is gitignored** on both machines. See `docs/deployment.md` for the exact templates.
## Slice 2 preview
Per `docs/slices.md`, Slice 2 is "Work Definition and approval" - turning proposed Work into approved Work with structured definitions, acceptance criteria, and the approval flow. The Convex `works.ts` schema and `@code/work-os` primitives are already in place to build on.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,6 @@
"workspaces": {
"packages": [
"apps/web",
"packages/agents",
"packages/auth",
"packages/backend",
"packages/config",
@@ -13,9 +12,6 @@
"packages/ui"
],
"catalog": {
"@rivet-dev/agentos": "0.2.14",
"@rivet-dev/agentos-core": "0.2.14",
"rivetkit": "2.3.10",
"@effect/platform-bun": "4.0.0-beta.99",
"dotenv": "17.4.2",
"zod": "4.4.3",
@@ -42,17 +38,14 @@
"react-native": "0.86.0",
"@types/react": "19.2.17",
"@types/node": "22.20.1",
"hono": "4.12.32",
"valibot": "1.4.2",
"streamdown": "2.5.0",
"@tailwindcss/postcss": "4.3.3",
"@tailwindcss/vite": "4.3.3"
}
},
"type": "module",
"scripts": {
"dev": "concurrently --names engine,runner,server,agents,web --prefix-colors yellow,blue,magenta,green,cyan --handle-input --kill-others-on-fail \"pnpm run dev:engine\" \"pnpm run dev:runner\" \"pnpm run dev:server\" \"pnpm run dev:agents\" \"pnpm run dev:web\"",
"dev:tailscale": "concurrently --names engine,runner,server,agents,web --prefix-colors yellow,blue,magenta,green,cyan --handle-input --kill-others-on-fail \"pnpm run dev:engine\" \"pnpm run dev:runner\" \"pnpm run dev:server\" \"pnpm run dev:agents\" \"pnpm run dev:tailscale:web\"",
"dev": "concurrently --names server,web --prefix-colors magenta,cyan --handle-input --kill-others-on-fail \"pnpm run dev:server\" \"pnpm run dev:web\"",
"dev:tailscale": "concurrently --names server,web --prefix-colors magenta,cyan --handle-input --kill-others-on-fail \"pnpm run dev:server\" \"pnpm run dev:tailscale:web\"",
"build": "vp run -r build",
"check-types": "vp run -r check-types",
"lint": "oxlint --disable-nested-config",
@@ -60,14 +53,9 @@
"staged": "vp staged",
"hooks:setup": "vp config",
"dev:web": "vp --filter web run dev",
"dev:agents": "vp --filter @code/agents run dev",
"dev:tailscale:web": "vp --filter web run dev:tailscale",
"dev:tailscale:agents": "vp --filter @code/agents run dev:tailscale",
"dev:server": "vp --filter @code/backend run dev",
"dev:setup": "vp --filter @code/backend run dev:setup",
"dev:engine": "vp --filter @code/agents run dev:engine",
"dev:runner": "node scripts/wait-for-port.mjs 127.0.0.1 6420 && vp --filter @code/agents run runner",
"build:agents": "vp run --filter @code/agents build",
"docs:update": "node scripts/update-docs.ts",
"subtree": "node scripts/subtree.ts",
"vercel-build": "node scripts/vercel-build.ts",
@@ -79,7 +67,6 @@
"@code/config": "workspace:*",
"@code/env": "workspace:*",
"@code/primitives": "workspace:*",
"@flue/sdk": "npm:@rivet-dev/labs-flue-sdk@1.0.0-beta.9-rivet.2",
"@types/bun": "catalog:",
"@types/node": "catalog:",
"@vercel/config": "^0.5.5",
@@ -99,7 +86,6 @@
"overrides": {
"react": "19.2.8",
"react-dom": "19.2.8",
"rivetkit": "2.3.10",
"vite": "npm:@voidzero-dev/vite-plus-core@0.2.2"
},
"packageManager": "pnpm@11.17.0"

View File

@@ -4,7 +4,6 @@
"private": true,
"type": "module",
"exports": {
"./agent": "./src/agent.ts",
"./convex": "./src/convex.ts",
"./native": "./src/native.ts",
"./server": "./src/server.ts",

View File

@@ -5,10 +5,7 @@ export const env = createEnv({
emptyStringAsUndefined: true,
runtimeEnv: process.env,
server: {
AGENT_BACKEND_URL: z.url().optional(),
CONVEX_SITE_URL: z.url().optional(),
FLUE_DB_TOKEN: z.string().min(1),
FLUE_URL: z.url().optional(),
GITEA_TOKEN: z.string().min(1).optional(),
GITEA_URL: z.url().default("https://git.openputer.com"),
GITEA_WEBHOOK_SECRET: z.string().min(1).optional(),

View File

@@ -16,8 +16,6 @@ export const env = createEnv({
DAEMON_ID: z.string().min(1),
DAEMON_NAME: z.string().min(1).optional(),
DAEMON_VERSION: z.string().default("0.0.0"),
FLUE_DB_TOKEN: z.string().min(1),
RIVET_ENDPOINT: z.url().optional(),
},
skipValidation: process.env.SKIP_ENV_VALIDATION === "true",
});

View File

@@ -5,28 +5,13 @@
"type": "module",
"exports": {
".": "./src/index.ts",
"./agent-os": "./src/agent-os.ts",
"./execution-runtime": "./src/execution-runtime.ts",
"./git": "./src/git.ts",
"./git-provider": "./src/git-provider.ts",
"./git-provisioning": "./src/git-provisioning.ts",
"./git-webhook": "./src/git-webhook.ts",
"./git-local-runtime": "./src/git-local-runtime.ts",
"./git-remote-runtime": "./src/git-remote-runtime.ts",
"./project": "./src/project.ts",
"./project-issue": "./src/project-issue.ts",
"./project-work": "./src/project-work.ts",
"./project-workspace": "./src/project-workspace.ts",
"./signal": "./src/signal.ts",
"./smoke": "./src/smoke.ts",
"./work": "./src/work.ts",
"./work-artifact": "./src/work-artifact.ts",
"./work-definition": "./src/work-definition.ts",
"./work-design": "./src/work-design.ts",
"./work-lifecycle": "./src/work-lifecycle.ts",
"./resolver": "./src/resolver.ts",
"./harness-runtime": "./src/harness-runtime.ts",
"./host-repository": "./src/host-repository.ts"
"./signal": "./src/signal.ts"
},
"scripts": {
"check-types": "tsc --noEmit",
@@ -34,9 +19,6 @@
"test:watch": "vitest"
},
"dependencies": {
"@agentos-software/git": "0.3.3",
"@agentos-software/pi": "0.2.7",
"@rivet-dev/agentos": "0.2.14",
"effect": "catalog:"
},
"devDependencies": {

View File

@@ -0,0 +1,81 @@
/* eslint-disable max-classes-per-file -- Git credential schemas share one error type. */
import { Effect, Schema } from "effect";
import { GitProvider } from "./git-provider";
export type { GitProvider } from "./git-provider";
const Text = Schema.String.check(
Schema.makeFilter((value) => value.trim().length > 0, {
expected: "a non-empty string",
})
);
const HttpUrl = Schema.String.check(
Schema.makeFilter(
(value) => {
try {
const url = new URL(value);
return url.protocol === "http:" || url.protocol === "https:";
} catch {
return false;
}
},
{ expected: "an HTTP URL" }
)
);
export const GitCredentialKind = Schema.Literals(["oauth", "token"]);
export type GitCredentialKind = typeof GitCredentialKind.Type;
export const GitConnectionInput = Schema.Struct({
credential: Text,
credentialKind: GitCredentialKind,
provider: GitProvider,
serverUrl: HttpUrl,
username: Schema.optional(Text),
});
export type GitConnectionInput = typeof GitConnectionInput.Type;
export const GitConnectionView = Schema.Struct({
connectedAt: Schema.Number,
credentialKind: GitCredentialKind,
id: Text,
provider: GitProvider,
serverUrl: HttpUrl,
username: Schema.optional(Text),
});
export type GitConnectionView = typeof GitConnectionView.Type;
export const RepositoryExecutionAuth = Schema.Struct({
credential: Text,
provider: GitProvider,
serverUrl: HttpUrl,
username: Schema.optional(Text),
});
export type RepositoryExecutionAuth = typeof RepositoryExecutionAuth.Type;
export const GitConnectionInputErrorReason = Schema.Literals(["InvalidInput"]);
export type GitConnectionInputErrorReason =
typeof GitConnectionInputErrorReason.Type;
export class GitConnectionInputError extends Schema.TaggedErrorClass<GitConnectionInputError>()(
"GitConnectionInputError",
{
message: Schema.String,
reason: GitConnectionInputErrorReason,
retryable: Schema.Boolean,
}
) {}
const invalidInput = (message: string) =>
new GitConnectionInputError({
message,
reason: "InvalidInput",
retryable: false,
});
export const decodeGitConnectionInput = (input: unknown) =>
Schema.decodeUnknownEffect(GitConnectionInput)(input).pipe(
Effect.mapError((cause) => invalidInput(cause.message))
);

View File

@@ -1,23 +1,8 @@
// oxlint-disable-next-line no-barrel-file -- The package root intentionally exposes its public modules.
export * from "./agent-os";
export * from "./execution-runtime";
export * from "./git";
export * from "./git-provider";
export * from "./git-provisioning";
export * from "./git-webhook";
export * from "./git-local-runtime";
export * from "./git-remote-runtime";
export * from "./project";
export * from "./project-issue";
export * from "./project-workspace";
export * from "./project-work";
export * from "./signal";
export * from "./smoke";
export * from "./work";
export * from "./work-artifact";
export * from "./work-definition";
export * from "./work-design";
export * from "./work-lifecycle";
export * from "./resolver";
export * from "./harness-runtime";
export * from "./host-repository";

View File

@@ -16,11 +16,6 @@
"dependencies": {
"@base-ui/react": "^1.6.0",
"@shadcn/react": "^0.2.0",
"@streamdown/cjk": "^1.0.3",
"@streamdown/code": "^1.1.1",
"@streamdown/math": "^1.0.2",
"@streamdown/mermaid": "^1.0.2",
"ai": "^7.0.35",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "catalog:",
@@ -28,12 +23,9 @@
"react": "catalog:",
"react-dom": "catalog:",
"shadcn": "^4.12.0",
"shiki": "^4.3.1",
"sonner": "catalog:",
"streamdown": "catalog:",
"tailwind-merge": "catalog:",
"tw-animate-css": "^1.4.0",
"use-stick-to-bottom": "^1.1.6"
"tw-animate-css": "^1.4.0"
},
"devDependencies": {
"@code/config": "workspace:*",

7218
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,5 @@
packages:
- apps/web
- packages/agents
- packages/auth
- packages/backend
- packages/config
@@ -22,9 +21,6 @@ allowBuilds:
workerd: true
catalog:
"@rivet-dev/agentos": "0.2.14"
"@rivet-dev/agentos-core": "0.2.14"
rivetkit: "2.3.10"
"@effect/platform-bun": "4.0.0-beta.99"
dotenv: "17.4.2"
zod: "4.4.3"
@@ -51,14 +47,10 @@ catalog:
react-native: "0.86.0"
"@types/react": "19.2.17"
"@types/node": "22.20.1"
hono: "4.12.32"
valibot: "1.4.2"
streamdown: "2.5.0"
"@tailwindcss/postcss": "4.3.3"
"@tailwindcss/vite": "4.3.3"
overrides:
react: "19.2.8"
react-dom: "19.2.8"
rivetkit: "2.3.10"
vite: "npm:@voidzero-dev/vite-plus-core@0.2.2"