diff --git a/packages/console/app/.opencode/agent/css.md b/packages/console/app/.opencode/agent/css.md deleted file mode 100644 index d5e68c7bf6a..00000000000 --- a/packages/console/app/.opencode/agent/css.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -description: use whenever you are styling a ui with css ---- - -you are very good at writing clean maintainable css using modern techniques - -css is structured like this - -```css -[data-page="home"] { - [data-component="header"] { - [data-slot="logo"] { - } - } -} -``` - -top level pages are scoped using `data-page` - -pages can break down into components using `data-component` - -components can break down into slots using `data-slot` - -structure things so that this hierarchy is followed IN YOUR CSS - you should rarely need to -nest components inside other components. you should NEVER nest components inside -slots. you should NEVER nest slots inside other slots. - -**IMPORTANT: This hierarchy rule applies to CSS structure, NOT JSX/DOM structure.** - -The hierarchy in css file does NOT have to match the hierarchy in the dom - you -can put components or slots at the same level in CSS even if one goes inside another in the DOM. - -Your JSX can nest however makes semantic sense - components can be inside slots, -slots can contain components, etc. The DOM structure should be whatever makes the most -semantic and functional sense. - -It is more important to follow the pages -> components -> slots structure IN YOUR CSS, -while keeping your JSX/DOM structure logical and semantic. - -use data attributes to represent different states of the component - -```css -[data-component="modal"] { - opacity: 0; - - &[data-state="open"] { - opacity: 1; - } -} -``` - -this will allow jsx to control the styling - -avoid selectors that just target an element type like `> span` you should assign -it a slot name. it's ok to do this sometimes where it makes sense semantically -like targeting `li` elements in a list - -in terms of file structure `./src/style/` contains all universal styling rules. -these should not contain anything specific to a page - -`./src/style/token` contains all the tokens used in the project - -`./src/style/component` is for reusable components like buttons or inputs - -page specific styles should go next to the page they are styling so -`./src/routes/about.tsx` should have its styles in `./src/routes/about.css` - -`about.css` should be scoped using `data-page="about"` - -## Example of correct implementation - -JSX can nest however makes sense semantically: - -```jsx -
-
Section Title
-
Content here
-
-``` - -CSS maintains clean hierarchy regardless of DOM nesting: - -```css -[data-page="home"] { - [data-component="screenshots"] { - [data-slot="left"] { - /* styles */ - } - [data-slot="content"] { - /* styles */ - } - } - - [data-component="title"] { - /* can be at same level even though nested in DOM */ - } -} -``` - -## Reusable Components - -If a component is reused across multiple sections of the same page, define it at the page level: - -```jsx - -
-
-

npm

-
-
-

bun

-
-
- -
-
-
Screenshot Title
-
-
-``` - -```css -[data-page="home"] { - /* Reusable title component defined at page level since it's used in multiple components */ - [data-component="title"] { - text-transform: uppercase; - font-weight: 400; - } - - [data-component="install"] { - /* install-specific styles */ - } - - [data-component="screenshots"] { - /* screenshots-specific styles */ - } -} -``` - -This is correct because the `title` component has consistent styling and behavior across the page. - -## Key Clarifications - -1. **JSX Nesting is Flexible**: Components can be nested inside slots, slots can contain components - whatever makes semantic sense -2. **CSS Hierarchy is Strict**: Follow pages → components → slots structure in CSS -3. **Reusable Components**: Define at the appropriate level where they're shared (page level if used across the page, component level if only used within that component) -4. **DOM vs CSS Structure**: These don't need to match - optimize each for its purpose - -See ./src/routes/index.css and ./src/routes/index.tsx for a complete example. diff --git a/packages/opencode/src/cli/cmd/session.ts b/packages/opencode/src/cli/cmd/session.ts index c6a1fd4138f..042a8cb4aaa 100644 --- a/packages/opencode/src/cli/cmd/session.ts +++ b/packages/opencode/src/cli/cmd/session.ts @@ -52,6 +52,12 @@ export const SessionListCommand = cmd({ describe: "limit to N most recent sessions", type: "number", }) + .option("all", { + alias: "a", + describe: "show sessions from all directories in the project", + type: "boolean", + default: false, + }) .option("format", { describe: "output format", type: "string", @@ -62,7 +68,7 @@ export const SessionListCommand = cmd({ handler: async (args) => { await bootstrap(process.cwd(), async () => { const sessions = [] - for await (const session of Session.list()) { + for await (const session of Session.list({ all: args.all })) { if (!session.parentID) { sessions.push(session) } diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 077a9dd1135..5997736d1b0 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -419,13 +419,15 @@ export namespace Config { }) export type Permission = z.infer - export const Command = z.object({ - template: z.string(), - description: z.string().optional(), - agent: z.string().optional(), - model: z.string().optional(), - subtask: z.boolean().optional(), - }) + export const Command = z + .object({ + template: z.string(), + description: z.string().optional(), + agent: z.string().optional(), + model: z.string().optional(), + subtask: z.boolean().optional(), + }) + .passthrough() export type Command = z.infer export const Agent = z diff --git a/packages/opencode/src/server/server.ts b/packages/opencode/src/server/server.ts index bc727b02857..e2d9f047c17 100644 --- a/packages/opencode/src/server/server.ts +++ b/packages/opencode/src/server/server.ts @@ -688,7 +688,8 @@ export namespace Server { "/session", describeRoute({ summary: "List sessions", - description: "Get a list of all OpenCode sessions, sorted by most recently updated.", + description: + "Get a list of OpenCode sessions. By default, returns sessions from the current directory. Use ?all=true to get all sessions in the project.", operationId: "session.list", responses: { 200: { @@ -702,9 +703,10 @@ export namespace Server { }, }), async (c) => { - const sessions = await Array.fromAsync(Session.list()) + const all = c.req.query("all") === "true" + const sessions = await Array.fromAsync(Session.list({ all })) pipe( - await Array.fromAsync(Session.list()), + sessions, filter((s) => !s.time.archived), sortBy((s) => s.time.updated), ) diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts index 0776590d6a9..43aca2f689f 100644 --- a/packages/opencode/src/session/index.ts +++ b/packages/opencode/src/session/index.ts @@ -286,10 +286,23 @@ export namespace Session { }, ) - export async function* list() { + export interface ListOptions { + /** + * When true, returns all sessions for the project regardless of directory. + * When false (default), only returns sessions created in the current directory. + */ + all?: boolean + } + + export async function* list(options?: ListOptions) { const project = Instance.project + const currentDirectory = Instance.directory for (const item of await Storage.list(["session", project.id])) { - yield Storage.read(item) + const session = await Storage.read(item) + if (options?.all !== true && session.directory !== currentDirectory) { + continue + } + yield session } }