Skip to content
Open
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/issue-237/panel-prompts.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshots/issue-237/panel-skills.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
533 changes: 533 additions & 0 deletions experiments/render-examples-output.txt

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions experiments/render-examples.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { writeFileSync } from "node:fs"
import { defaultTemplateConfig } from "../packages/lib/dist/core/domain.js"
import { renderClaudeGlobalPromptSetup } from "../packages/lib/dist/core/templates-entrypoint/claude-extra-config.js"
import { renderEntrypointAgentsNotice } from "../packages/lib/dist/core/templates-entrypoint/agents-notice.js"
import { renderEntrypointProjectCodexSkillsSync } from "../packages/lib/dist/core/templates-entrypoint/codex.js"
import { renderEntrypointGeminiConfig } from "../packages/lib/dist/core/templates-entrypoint/gemini.js"

const cfg = {
...defaultTemplateConfig,
repoUrl: "https://github.com/ProverCoderAI/docker-git.git",
containerName: "dg-docker-git",
serviceName: "dg-docker-git",
sshUser: "dev",
targetDir: "/home/dev/workspaces/ProverCoderAI/docker-git/issue-237",
volumeName: "dg-docker-git-home",
dockerGitPath: "/home/dev/.docker-git",
authorizedKeysPath: "/home/dev/.docker-git/authorized_keys",
envGlobalPath: "/home/dev/.docker-git/.orch/env/global.env",
envProjectPath: "/home/dev/workspaces/ProverCoderAI/docker-git/issue-237/.orch/env/project.env",
codexAuthPath: "/home/dev/.docker-git/.orch/auth/codex",
codexSharedAuthPath: "/home/dev/.docker-git/.orch/auth/codex-shared",
geminiAuthPath: "/home/dev/.docker-git/.orch/auth/gemini",
repoRef: "issue-237"
}

const banner = (title) => `\n${"=".repeat(80)}\n${title}\n${"=".repeat(80)}\n`

const output = [
banner("CLAUDE.md prompt setup (~/.claude/CLAUDE.md)"),
renderClaudeGlobalPromptSetup(cfg),
banner(".codex/AGENTS.md prompt setup"),
renderEntrypointAgentsNotice(cfg),
banner("GEMINI.md prompt setup (full Gemini config block)"),
renderEntrypointGeminiConfig(cfg),
banner("Codex project skills sync (with CODEX_EXTRA_SKILLS_PATHS support)"),
renderEntrypointProjectCodexSkillsSync(cfg)
].join("\n")

writeFileSync("experiments/render-examples-output.txt", output)
console.log(`Wrote ${output.length} chars`)
44 changes: 44 additions & 0 deletions experiments/render-examples.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { defaultTemplateConfig, type TemplateConfig } from "../packages/lib/src/core/domain.ts"
import { renderClaudeGlobalPromptSetup } from "../packages/lib/src/core/templates-entrypoint/claude-extra-config.ts"
import { renderEntrypointAgentsNotice } from "../packages/lib/src/core/templates-entrypoint/agents-notice.ts"
import {
renderEntrypointProjectCodexSkillsSync
} from "../packages/lib/src/core/templates-entrypoint/codex.ts"
import { renderEntrypointGeminiConfig } from "../packages/lib/src/core/templates-entrypoint/gemini.ts"

const cfg: TemplateConfig = {
...defaultTemplateConfig,
repoUrl: "https://github.com/ProverCoderAI/docker-git.git",
containerName: "dg-docker-git",
serviceName: "dg-docker-git",
sshUser: "dev",
targetDir: "/home/dev/workspaces/ProverCoderAI/docker-git/issue-237",
volumeName: "dg-docker-git-home",
dockerGitPath: "/home/dev/.docker-git",
authorizedKeysPath: "/home/dev/.docker-git/authorized_keys",
envGlobalPath: "/home/dev/.docker-git/.orch/env/global.env",
envProjectPath: "/home/dev/workspaces/ProverCoderAI/docker-git/issue-237/.orch/env/project.env",
codexAuthPath: "/home/dev/.docker-git/.orch/auth/codex",
codexSharedAuthPath: "/home/dev/.docker-git/.orch/auth/codex-shared",
geminiAuthPath: "/home/dev/.docker-git/.orch/auth/gemini",
repoRef: "issue-237"
}

import { writeFileSync } from "node:fs"

const banner = (title: string): string =>
`\n${"=".repeat(80)}\n${title}\n${"=".repeat(80)}\n`

const output = [
banner("CLAUDE.md prompt setup (~/.claude/CLAUDE.md)"),
renderClaudeGlobalPromptSetup(cfg),
banner(".codex/AGENTS.md prompt setup"),
renderEntrypointAgentsNotice(cfg),
banner("GEMINI.md prompt setup (full Gemini config block)"),
renderEntrypointGeminiConfig(cfg),
banner("Codex project skills sync (with CODEX_EXTRA_SKILLS_PATHS support)"),
renderEntrypointProjectCodexSkillsSync(cfg)
].join("\n")

writeFileSync("experiments/render-examples-output.txt", output)
console.log(`Wrote ${output.length} bytes to experiments/render-examples-output.txt`)
165 changes: 165 additions & 0 deletions experiments/ui-examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# Container UI examples (issue #237)

These are the rendered files that the user sees inside a running container after
the entrypoint executes. The new `*_SYSTEM_PROMPT_OVERRIDE` and
`*_SYSTEM_PROMPT_OVERRIDE_FILE` env vars (plus `CODEX_EXTRA_SKILLS_PATHS`) let
operators replace the body of any of these files without forking the templates.

---

## 1. Default behaviour (no overrides set)

Container env: `CLAUDE_AUTO_SYSTEM_PROMPT=1` (default), no override vars.

### `~/.claude/CLAUDE.md`

```markdown
<!-- docker-git-managed:claude-md -->
Ты автономный агент, который имеет полностью все права управления контейнером. У тебя есть доступ к командам sudo, gh, bun, codex, opencode, oh-my-opencode, sshpass, claude, git, node и всем остальным другим. Проекты с которыми идёт работа лежат по пути ~
Рабочая папка проекта (git clone): /home/dev/workspaces/ProverCoderAI/docker-git/issue-237
Доступные workspace пути: /home/dev/workspaces/ProverCoderAI/docker-git/issue-237
Контекст workspace: issue #237 (https://github.com/ProverCoderAI/docker-git/issues/237)
Фокус задачи: работай только в workspace, который запрашивает пользователь. Текущий workspace: /home/dev/workspaces/ProverCoderAI/docker-git/issue-237
Доступ к интернету: есть. Если чего-то не знаешь — ищи в интернете или по кодовой базе.
Для решения задач обязательно используй subagents. Сам агент обязан выполнять финальную проверку, интеграцию и валидацию результата перед ответом пользователю.
Если ты видишь файлы AGENTS.md или CLAUDE.md внутри проекта, ты обязан их читать и соблюдать инструкции.
<!-- /docker-git-managed:claude-md -->
```

### `~/.codex/AGENTS.md`

```markdown
Ты автономный агент, который имеет полностью все права управления контейнером. У тебя есть доступ к командам sudo, gh, bun, codex, opencode, oh-my-opencode, sshpass, git, node и всем остальным другим. Проекты с которыми идёт работа лежат по пути ~
<!-- docker-git:managed:start -->
Рабочая папка проекта (git clone): /home/dev/workspaces/ProverCoderAI/docker-git/issue-237
Доступные workspace пути: /home/dev/workspaces/ProverCoderAI/docker-git/issue-237
Контекст workspace: issue #237 (https://github.com/ProverCoderAI/docker-git/issues/237)
Фокус задачи: работай только в workspace, который запрашивает пользователь. Текущий workspace: /home/dev/workspaces/ProverCoderAI/docker-git/issue-237
Доступ к интернету: есть. Если чего-то не знаешь — ищи в интернете или по кодовой базе.
Для решения задач обязательно используй subagents. Сам агент обязан выполнять финальную проверку, интеграцию и валидацию результата перед ответом пользователю.
<!-- docker-git:managed:end -->
Если ты видишь файлы AGENTS.md внутри проекта, ты обязан их читать и соблюдать инструкции.
```

### `~/.gemini/GEMINI.md`

```markdown
<!-- docker-git-managed:gemini-md -->
Ты автономный агент Gemini, у тебя есть доступ к sudo, gh, gemini-cli, bun, git, node и всем остальным. Проекты с которыми идёт работа лежат по пути ~
Рабочая папка проекта (git clone): /home/dev/workspaces/ProverCoderAI/docker-git/issue-237
Доступные workspace пути: /home/dev/workspaces/ProverCoderAI/docker-git/issue-237
Контекст workspace: issue #237 (https://github.com/ProverCoderAI/docker-git/issues/237)
Фокус задачи: работай только в workspace, который запрашивает пользователь. Текущий workspace: /home/dev/workspaces/ProverCoderAI/docker-git/issue-237
Доступ к интернету: есть. Если чего-то не знаешь — ищи в интернете или по кодовой базе.
Для решения задач обязательно используй subagents. Сам агент обязан выполнять финальную проверку, интеграцию и валидацию результата перед ответом пользователю.
<!-- /docker-git-managed:gemini-md -->
```

### `ls ~/.codex/skills/.docker-git-project/` (no extra skills)

```
20-agents-skills -> /home/dev/workspaces/ProverCoderAI/docker-git/issue-237/.agents/skills
```

---

## 2. Inline override via `CLAUDE_SYSTEM_PROMPT_OVERRIDE`

Container env (in `.orch/env/project.env`):

```bash
CLAUDE_SYSTEM_PROMPT_OVERRIDE="You are a senior reviewer. Be terse. Only modify files in /home/dev/workspaces/ProverCoderAI/docker-git/issue-237."
```

### `~/.claude/CLAUDE.md`

```markdown
<!-- docker-git-managed:claude-md -->
You are a senior reviewer. Be terse. Only modify files in /home/dev/workspaces/ProverCoderAI/docker-git/issue-237.
<!-- /docker-git-managed:claude-md -->
```

The managed-block markers are preserved, so the next container restart still
detects the file as docker-git-managed and refreshes it idempotently.

---

## 3. File override via `CODEX_SYSTEM_PROMPT_OVERRIDE_FILE`

```bash
# .orch/env/project.env
CODEX_SYSTEM_PROMPT_OVERRIDE_FILE=/home/dev/.docker-git/prompts/codex.txt
```

```bash
# /home/dev/.docker-git/prompts/codex.txt
You are running inside docker-git. Workspace: /home/dev/workspaces/ProverCoderAI/docker-git/issue-237.
Always start by running `git status` and `gh issue view 237`.
```

### `~/.codex/AGENTS.md` (managed lines replaced)

```markdown
Ты автономный агент, который имеет полностью все права управления контейнером. У тебя есть доступ к командам sudo, gh, bun, codex, opencode, oh-my-opencode, sshpass, git, node и всем остальным другим. Проекты с которыми идёт работа лежат по пути ~
<!-- docker-git:managed:start -->
You are running inside docker-git. Workspace: /home/dev/workspaces/ProverCoderAI/docker-git/issue-237.
Always start by running `git status` and `gh issue view 237`.
<!-- docker-git:managed:end -->
Если ты видишь файлы AGENTS.md внутри проекта, ты обязан их читать и соблюдать инструкции.
```

`*_OVERRIDE_FILE` always wins over `*_OVERRIDE`. If neither is set, the default
content above is used.

---

## 4. Extra skills via `CODEX_EXTRA_SKILLS_PATHS`

```bash
# .orch/env/project.env
CODEX_EXTRA_SKILLS_PATHS="50-team-skills::team/skills,60-shared-rituals::infra/codex/rituals"
```

Project layout:

```
/home/dev/workspaces/ProverCoderAI/docker-git/issue-237/
├── .agents/skills/...
├── team/skills/...
└── infra/codex/rituals/...
```

### `ls ~/.codex/skills/.docker-git-project/` (extras now mounted)

```
20-agents-skills -> /home/dev/workspaces/ProverCoderAI/docker-git/issue-237/.agents/skills
50-team-skills -> /home/dev/workspaces/ProverCoderAI/docker-git/issue-237/team/skills
60-shared-rituals -> /home/dev/workspaces/ProverCoderAI/docker-git/issue-237/infra/codex/rituals
```

The built-in priority list (`.skills`, `.agents/skills`, `.agents/.skills`,
`.codex/skills`, `.codex/.skills`) is preserved. Extras are appended only when
the relative path exists, so misconfigured entries are silently ignored.

---

## 5. Container terminal session showing the override hooks

```text
dev@dg-docker-git:~$ cat ~/.codex/AGENTS.md | head -3
Ты автономный агент, который имеет полностью все права управления контейнером...
<!-- docker-git:managed:start -->
You are running inside docker-git. Workspace: /home/dev/workspaces/ProverCoderAI/docker-git/issue-237.

dev@dg-docker-git:~$ ls -l ~/.codex/skills/.docker-git-project/
total 0
lrwxrwxrwx 1 dev dev 65 May 5 12:30 20-agents-skills -> /home/dev/workspaces/ProverCoderAI/docker-git/issue-237/.agents/skills
lrwxrwxrwx 1 dev dev 60 May 5 12:30 50-team-skills -> /home/dev/workspaces/ProverCoderAI/docker-git/issue-237/team/skills
lrwxrwxrwx 1 dev dev 64 May 5 12:30 60-shared-rituals -> /home/dev/workspaces/ProverCoderAI/docker-git/issue-237/infra/codex/rituals

dev@dg-docker-git:~$ env | grep -E '_(SYSTEM_PROMPT_OVERRIDE|EXTRA_SKILLS)'
CLAUDE_SYSTEM_PROMPT_OVERRIDE_FILE=/home/dev/.docker-git/prompts/claude.txt
CODEX_SYSTEM_PROMPT_OVERRIDE_FILE=/home/dev/.docker-git/prompts/codex.txt
GEMINI_SYSTEM_PROMPT_OVERRIDE=You are running inside docker-git...
CODEX_EXTRA_SKILLS_PATHS=50-team-skills::team/skills,60-shared-rituals::infra/codex/rituals
```
62 changes: 62 additions & 0 deletions packages/api/src/api/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,68 @@ export type ProjectAuthRequest = {
readonly label?: string | null | undefined
}

export type ProjectPromptKind = "claude" | "codex" | "gemini"

export type ProjectPromptFile = {
readonly kind: ProjectPromptKind
readonly fileName: string
readonly relativePath: string
readonly absolutePath: string
readonly exists: boolean
readonly bytes: number
readonly content: string
}

export type ProjectPromptsSnapshot = {
readonly projectId: string
readonly projectKey: string
readonly projectDir: string
readonly prompts: ReadonlyArray<ProjectPromptFile>
}

export type ProjectPromptUpdateRequest = {
readonly content: string
}

export type ProjectSkillScope =
| "skills"
| "agents/skills"
| "agents/.skills"
| "claude/skills"
| "codex/skills"
| "gemini/skills"

export type ProjectSkillFile = {
readonly id: string
readonly scope: ProjectSkillScope
readonly name: string
readonly relativePath: string
readonly absolutePath: string
readonly bytes: number
readonly content: string
readonly updatedAtIso: string | null
}

export type ProjectSkillScopeInfo = {
readonly scope: ProjectSkillScope
readonly relativeRoot: string
readonly absoluteRoot: string
}

export type ProjectSkillsSnapshot = {
readonly projectId: string
readonly projectKey: string
readonly projectDir: string
readonly skills: ReadonlyArray<ProjectSkillFile>
readonly scopes: ReadonlyArray<ProjectSkillScopeInfo>
}

export type ProjectSkillUpdateRequest = {
readonly scope: ProjectSkillScope
readonly name: string
readonly content: string
}

export type StateInitRequest = {
readonly repoUrl: string
readonly repoRef?: string | undefined
Expand Down
25 changes: 25 additions & 0 deletions packages/api/src/api/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,27 @@ export const ProjectAuthRequestSchema = Schema.Struct({
label: OptionalNullableString
})

export const ProjectPromptKindSchema = Schema.Literal("claude", "codex", "gemini")

export const ProjectPromptUpdateRequestSchema = Schema.Struct({
content: Schema.String
})

export const ProjectSkillScopeSchema = Schema.Literal(
"skills",
"agents/skills",
"agents/.skills",
"claude/skills",
"codex/skills",
"gemini/skills"
)

export const ProjectSkillUpdateRequestSchema = Schema.Struct({
scope: ProjectSkillScopeSchema,
name: Schema.String,
content: Schema.String
})

export const StateInitRequestSchema = Schema.Struct({
repoUrl: Schema.String,
repoRef: OptionalString
Expand Down Expand Up @@ -289,6 +310,10 @@ export type CodexAuthImportRequestInput = Schema.Schema.Type<typeof CodexAuthImp
export type CodexAuthLoginRequestInput = Schema.Schema.Type<typeof CodexAuthLoginRequestSchema>
export type CodexAuthLogoutRequestInput = Schema.Schema.Type<typeof CodexAuthLogoutRequestSchema>
export type ProjectAuthRequestInput = Schema.Schema.Type<typeof ProjectAuthRequestSchema>
export type ProjectPromptKindInput = Schema.Schema.Type<typeof ProjectPromptKindSchema>
export type ProjectPromptUpdateRequestInput = Schema.Schema.Type<typeof ProjectPromptUpdateRequestSchema>
export type ProjectSkillScopeInput = Schema.Schema.Type<typeof ProjectSkillScopeSchema>
export type ProjectSkillUpdateRequestInput = Schema.Schema.Type<typeof ProjectSkillUpdateRequestSchema>
export type StateInitRequestInput = Schema.Schema.Type<typeof StateInitRequestSchema>
export type StateCommitRequestInput = Schema.Schema.Type<typeof StateCommitRequestSchema>
export type StateSyncRequestInput = Schema.Schema.Type<typeof StateSyncRequestSchema>
Expand Down
Loading