Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,35 @@
[target.x86_64-apple-darwin]
rustflags = [
"-C", "link-arg=-fuse-ld=/usr/bin/ld",
"-C", "codegen-units=16",
"-Z", "threads=16", # Parallel frontend (type check, borrow check, MIR opt)
"-C", "codegen-units=20",
"-Z", "threads=20", # Parallel frontend (type check, borrow check, MIR opt)
]

[target.aarch64-apple-darwin]
rustflags = [
"-C", "link-arg=-fuse-ld=/usr/bin/ld",
"-C", "codegen-units=16",
"-Z", "threads=16", # Parallel frontend (type check, borrow check, MIR opt)
"-C", "codegen-units=20",
"-Z", "threads=20", # Parallel frontend (type check, borrow check, MIR opt)
]

[target.x86_64-unknown-linux-gnu]
rustflags = [
"-C", "link-arg=-fuse-ld=lld",
"-C", "codegen-units=16",
"-Z", "threads=16",
"-C", "codegen-units=20",
"-Z", "threads=20",
]

[target.x86_64-pc-windows-msvc]
rustflags = [
"-C", "link-arg=/DEBUG:NONE",
"-C", "codegen-units=16",
"-Z", "threads=16",
"-C", "codegen-units=20",
"-Z", "threads=20",
]

# Build configuration
[build]
# Parallel compilation jobs (defaults to number of CPU cores)
jobs = 16
jobs = 20

# Incremental compilation for faster rebuilds (enabled by default in dev)
incremental = true
Expand Down
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
nodejs 24.3.0
rust nightly
rust nightly
32 changes: 20 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
# Treq - Coding Agent Orchestrator
# Treq - Coding Agent Orchestrator - test remote clone

Treq transforms AI-generated code into local isolated pull requests.

> **🚀 One-Shot at Speed 🚀**
>
> _Ship quality code to production without the AI slop_

---

## What is Treq?

AI agents can create results fast, but they don’t organize anything. Their outputs stack on top of each other, overwrite previous work, and make it hard to see what changed or what should happen next.
Expand All @@ -18,12 +12,26 @@ It gives each agent result its own space, shows it clearly to the developer for

Now, instead of a messy pile of AI output, you get a clean, organized workflow you can control.

## Key Features
## Features

### Code Reviews

Inspect and iterate on each change for a human-in-the-loop agentic workflow.

<!-- insert gif of a review -->

- Review the code diffs just like a familiar Github PR, annotate and comment on code, and then send it to an agent for changes.
- Spotted an issue when browsing files? Send it to an agent for adjustments in the background.

### Isolated Workspaces

Coding agents work in isolated copies of the codebase, ensuring changes are independent from each other while keeping your current repository clean for planning.

<!-- insert gif of worktree creation -->

- **🌳 Agent Isolation**: Coding agents work in isolation on dedicated Git worktrees, paralleized and isolated.
- **💻 Integrated Terminal**: Use Claude Code in full inteactive mode, with seamless integeration with planning modes and Git worktree management
- **🔍 Code Review**: Inspect and iterate on each change for a human-in-the-loop agentic workflow.
- Workspaces are isolated but interlinked - move changes around workspaces, or split and stack workspaces as needed.
- Got a code conflict? No problem! Let the agent handle it the grunt work.

## License

Licensed under the Apache License, Version 2.0
Licensed under the Apache License, Version 2.0
2 changes: 1 addition & 1 deletion agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ npm run tauri dev # Run in dev mode (Rust + frontend dev server)
**Core Components:**
- **App.tsx** - Root with QueryClient provider, routing, and global state
- **components/Dashboard.tsx** - Main UI controller (repository dashboard)
- **components/SessionTerminal.tsx** - PTY terminal with ghostty-web integration
- **components/ShowWorkspace.tsx** - Workspace viewer with overview, changes, and files tabs
- **components/StagingDiffViewer.tsx** - Git staging area with file tree and diff view
- **components/AnnotatableDiffViewer.tsx** - Diff viewer with annotation support
- **components/ui/** - Shadcn-based UI primitives
Expand Down
9 changes: 6 additions & 3 deletions docs/src/components/HomepageFeatures/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import type {ReactNode} from 'react';
import clsx from 'clsx';
import Heading from '@theme/Heading';
import styles from './styles.module.css';
import MountainSvg from '@site/static/img/undraw_docusaurus_mountain.svg';
import TreeSvg from '@site/static/img/undraw_docusaurus_tree.svg';
import ReactSvg from '@site/static/img/undraw_docusaurus_react.svg';

type FeatureItem = {
title: string;
Expand All @@ -12,7 +15,7 @@ type FeatureItem = {
const FeatureList: FeatureItem[] = [
{
title: 'Easy to Use',
Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
Svg: MountainSvg,
description: (
<>
Docusaurus was designed from the ground up to be easily installed and
Expand All @@ -22,7 +25,7 @@ const FeatureList: FeatureItem[] = [
},
{
title: 'Focus on What Matters',
Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
Svg: TreeSvg,
description: (
<>
Docusaurus lets you focus on your docs, and we&apos;ll do the chores. Go
Expand All @@ -32,7 +35,7 @@ const FeatureList: FeatureItem[] = [
},
{
title: 'Powered by React',
Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
Svg: ReactSvg,
description: (
<>
Extend or customize your website layout by reusing React. Docusaurus can
Expand Down
15 changes: 7 additions & 8 deletions docs/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import Heading from '@theme/Heading';
import styles from './index.module.css';

function HomepageHeader() {
const {siteConfig} = useDocusaurusContext();
return (
<header className={styles.heroBanner}>
<div className={styles.heroGlow}></div>
Expand Down Expand Up @@ -162,9 +161,9 @@ function ProblemSection(): ReactNode {
</p>

<div className={styles.problemList}>
<div className={styles.problemListTitle}>
Today's AI development workflow is basically:
</div>
<div className={styles.problemListTitle}>
Today&rsquo;s AI development workflow is basically:
</div>
<div className={styles.problemItem}>
copy/paste patches into editors
</div>
Expand All @@ -180,7 +179,7 @@ function ProblemSection(): ReactNode {
</div>

<p className={styles.problemConclusion}>
It's chaos disguised as productivity.
It&rsquo;s chaos disguised as productivity.
</p>
</div>
</section>
Expand Down Expand Up @@ -265,9 +264,9 @@ function FeaturesSection(): ReactNode {
<div className={styles.solutionItem}>
Claude Code–ready terminal per branch
</div>
<div className={styles.solutionItem}>
Iterate patches safely until they're right
</div>
<div className={styles.solutionItem}>
Iterate patches safely until they&rsquo;re right
</div>
<div className={styles.solutionItem}>
Merge only when approved
</div>
Expand Down
152 changes: 152 additions & 0 deletions eslint-rules/no-banned-tailwind-classes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/**
* ESLint rule to ban specific Tailwind CSS classes
*
* @example
* // In eslint.config.js:
* rules: {
* "local/no-banned-tailwind-classes": ["error", {
* bannedClasses: ["text-xs", "text-2xs"]
* }]
* }
*/

module.exports = {
meta: {
type: "problem",
docs: {
description: "Disallow specific Tailwind CSS classes",
category: "Stylistic Issues",
recommended: false,
},
schema: [
{
type: "object",
properties: {
bannedClasses: {
type: "array",
items: { type: "string" },
uniqueItems: true,
},
},
additionalProperties: false,
},
],
messages: {
bannedClass: 'Tailwind class "{{className}}" is banned. Consider using a different size class.',
},
},

create(context) {
const options = context.options[0] || {};
const bannedClasses = new Set(options.bannedClasses || []);

if (bannedClasses.size === 0) {
// No banned classes configured, skip processing
return {};
}

/**
* Extract class names from a string
*/
function extractClassNames(str) {
return str.split(/\s+/).filter(Boolean);
}

/**
* Check if any class in the string is banned and report
*/
function checkClasses(node, classString) {
const classes = extractClassNames(classString);
for (const className of classes) {
if (bannedClasses.has(className)) {
context.report({
node,
messageId: "bannedClass",
data: { className },
});
}
}
}

/**
* Recursively extract class strings from various node types
*/
function extractFromNode(node) {
if (!node) return;

// String literal: "text-xs"
if (node.type === "Literal" && typeof node.value === "string") {
checkClasses(node, node.value);
}

// Template literal: `text-xs ${var}`
else if (node.type === "TemplateLiteral") {
for (const quasi of node.quasis) {
checkClasses(quasi, quasi.value.raw);
}
}

// JSX expression: className={"text-xs"}
else if (node.type === "JSXExpressionContainer") {
extractFromNode(node.expression);
}

// Call expression: cn("text-xs", ...) or clsx("text-xs", ...)
else if (node.type === "CallExpression") {
const calleeName =
node.callee.type === "Identifier" ? node.callee.name : null;

// Only process cn() and clsx() calls
if (calleeName === "cn" || calleeName === "clsx") {
for (const arg of node.arguments) {
extractFromNode(arg);
}
}
}

// Ternary expression: condition ? "text-xs" : "text-sm"
else if (node.type === "ConditionalExpression") {
extractFromNode(node.consequent);
extractFromNode(node.alternate);
}

// Logical expression: condition && "text-xs"
else if (node.type === "LogicalExpression") {
extractFromNode(node.left);
extractFromNode(node.right);
}

// Array expression: ["text-xs", condition && "other"]
else if (node.type === "ArrayExpression") {
for (const element of node.elements) {
if (element) {
extractFromNode(element);
}
}
}

// Object expression (for conditional classes): { "text-xs": true }
else if (node.type === "ObjectExpression") {
for (const prop of node.properties) {
if (prop.type === "Property" && prop.key.type === "Literal") {
const keyValue = prop.key.value;
if (typeof keyValue === "string") {
checkClasses(prop.key, keyValue);
}
}
}
}
}

return {
JSXAttribute(node) {
// Only check className attributes
if (node.name.name !== "className") {
return;
}

extractFromNode(node.value);
},
};
},
};
Loading