Skip to content
Merged
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
32 changes: 16 additions & 16 deletions .agents/skills/gen-changesets/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,25 @@ description: Use when generating changesets in the pythinker-code repository, in

`pythinker-code` uses changesets to manage versions and changelogs. The current user-facing published package is:

- `@pythoughts/pythinker-code`: the CLI
- `@pymodel/pythinker-code`: the CLI

All other `@pythoughts/*` packages are treated as internal packages, including `@pythoughts/pythinker-code-sdk`, `agent-core`, `kosong`, `kaos`, `pythinker-code-oauth`, `pythinker-telemetry`, and `migration-legacy`.
All other `@pymodel/*` packages are treated as internal packages, including `@pymodel/pythinker-code-sdk`, `agent-core`, `kosong`, `kaos`, `pythinker-code-oauth`, `pythinker-telemetry`, and `migration-legacy`.

## Core Rules

1. **Inspect the actual changes first.** Use `git status` / `git diff --name-only` to identify which packages were actually changed.
2. **List packages that changesets can release.** If a changed package is ignored in `.changeset/config.json`, do not put that ignored package in frontmatter together with a non-ignored package; changesets rejects mixed ignored/non-ignored frontmatter.
3. **Map ignored internal changes to the affected released package.** If an ignored internal package changes CLI output or behavior, list `@pythoughts/pythinker-code` and describe the actual user-visible or release-artifact change in the changelog text.
4. **Internal package source changes that enter the CLI bundle must manually list the CLI.** `@pythoughts/pythinker-code` inline-bundles `@pythoughts/*` source, but those internal packages are devDependencies from the CLI's perspective, so changesets will not automatically propagate bumps. If a change enters the CLI output, list `@pythoughts/pythinker-code`.
- **Web app (`@pythoughts/pythinker-web`) changes always enter the CLI bundle.** `@pythoughts/pythinker-web` is ignored by changesets (see `.changeset/config.json`) and cannot be mixed with `@pythoughts/pythinker-code` in one changeset frontmatter. Describe the web change in the changelog text, but list `@pythoughts/pythinker-code` so the CLI release carries the bundled `dist-web` output.
3. **Map ignored internal changes to the affected released package.** If an ignored internal package changes CLI output or behavior, list `@pymodel/pythinker-code` and describe the actual user-visible or release-artifact change in the changelog text.
4. **Internal package source changes that enter the CLI bundle must manually list the CLI.** `@pymodel/pythinker-code` inline-bundles `@pymodel/*` source, but those internal packages are devDependencies from the CLI's perspective, so changesets will not automatically propagate bumps. If a change enters the CLI output, list `@pymodel/pythinker-code`.
- **Web app (`@pymodel/pythinker-web`) changes always enter the CLI bundle.** `@pymodel/pythinker-web` is ignored by changesets (see `.changeset/config.json`) and cannot be mixed with `@pymodel/pythinker-code` in one changeset frontmatter. Describe the web change in the changelog text, but list `@pymodel/pythinker-code` so the CLI release carries the bundled `dist-web` output.
5. **Docs-only and tests-only changes usually do not need a changeset.** README, internal docs, and `test/` changes that do not enter package output do not trigger a CLI bump.
6. `@pythoughts/dashboard` / `dashboard-server` / `dashboard-web` are ignored by changesets and should not be handled.
6. `@pymodel/dashboard` / `dashboard-server` / `dashboard-web` are ignored by changesets and should not be handled.

## Workflow

1. List the changed packages and check whether each one is ignored by `.changeset/config.json`.
2. Choose a bump level for each package.
3. If an ignored internal package change enters the CLI bundle, put `@pythoughts/pythinker-code` in frontmatter instead of mixing the ignored package into the same changeset.
3. If an ignored internal package change enters the CLI bundle, put `@pymodel/pythinker-code` in frontmatter instead of mixing the ignored package into the same changeset.
4. Create a short kebab-case file under `.changeset/`.
5. Split unrelated changes into separate changesets; keep one logical change in one file.

Expand Down Expand Up @@ -70,7 +70,7 @@ An internal package fixes a bug visible to CLI users:

```markdown
---
"@pythoughts/pythinker-code": patch
"@pymodel/pythinker-code": patch
---

Fix occasional loss of tool call results in long conversations.
Expand All @@ -80,7 +80,7 @@ An internal package has an internal-only change, but it enters the CLI bundle:

```markdown
---
"@pythoughts/pythinker-code": patch
"@pymodel/pythinker-code": patch
---

Unify tool execution metadata handling.
Expand All @@ -90,15 +90,15 @@ Only SDK source changed, and the CLI does not use it:

```markdown
---
"@pythoughts/pythinker-code-sdk": patch
"@pymodel/pythinker-code-sdk": patch
---

Clarify session status typing for internal SDK callers.
```

## Web app changes

`@pythoughts/pythinker-web` is ignored by changesets and must **never** appear in a changeset frontmatter. Because the web app is bundled into the CLI release artifact, any web change that ships must list `@pythoughts/pythinker-code` instead and describe the actual web-facing change in the text.
`@pymodel/pythinker-web` is ignored by changesets and must **never** appear in a changeset frontmatter. Because the web app is bundled into the CLI release artifact, any web change that ships must list `@pymodel/pythinker-code` instead and describe the actual web-facing change in the text.

- If a PR contains both web UI changes and server API changes, split them into separate changesets so each entry has a focused description.
- Do not enumerate every micro-tweak; keep it to one sentence that captures what the web user gets.
Expand All @@ -107,7 +107,7 @@ Web-only fix:

```markdown
---
"@pythoughts/pythinker-code": patch
"@pymodel/pythinker-code": patch
---

Fix the web chat not scrolling to the bottom after sending a message.
Expand All @@ -117,15 +117,15 @@ Web UI plus server APIs in the same PR (split into two changesets):

```markdown
---
"@pythoughts/pythinker-code": minor
"@pymodel/pythinker-code": minor
---

Add the server-hosted web UI, including chat layout and session list behaviors.
```

```markdown
---
"@pythoughts/pythinker-code": minor
"@pymodel/pythinker-code": minor
---

Add the server REST and WebSocket APIs that power the web UI.
Expand All @@ -134,9 +134,9 @@ Add the server REST and WebSocket APIs that power the web UI.
## Red Flags

- You are about to write `major` without asking the user.
- Internal package source enters the CLI bundle, but `@pythoughts/pythinker-code` is missing.
- Internal package source enters the CLI bundle, but `@pymodel/pythinker-code` is missing.
- A changeset frontmatter mixes ignored internal packages with non-ignored packages.
- `packages/node-sdk` was not changed, but `@pythoughts/pythinker-code-sdk` was listed for "internal package sync".
- `packages/node-sdk` was not changed, but `@pymodel/pythinker-code-sdk` was listed for "internal package sync".
- The changelog entry is in Chinese.
- The wording claims more than the diff actually did.
- The CLI wording mentions internal package names, class names, or PR numbers.
Expand Down
8 changes: 4 additions & 4 deletions .agents/skills/sync-changelog/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: Use after a release succeeds, when maintainers need to sync apps/py

## Overview

`pythinker-code` uses changesets for versioning. Each package gets its own `CHANGELOG.md`. The user-facing CLI package, `@pythoughts/pythinker-code`, writes its changelog here:
`pythinker-code` uses changesets for versioning. Each package gets its own `CHANGELOG.md`. The user-facing CLI package, `@pymodel/pythinker-code`, writes its changelog here:

```text
apps/pythinker-code/CHANGELOG.md
Expand Down Expand Up @@ -38,7 +38,7 @@ Core rule: the English docs changelog is the source of truth for user-facing rel

Before editing, confirm:

- The released version exists on npm (`npm view @pythoughts/pythinker-code versions --json`) or has a matching GitHub Release tag on `PyModel/pythinker-code`.
- The released version exists on npm (`npm view @pymodel/pythinker-code versions --json`) or has a matching GitHub Release tag on `PyModel/pythinker-code`.
- The top of `apps/pythinker-code/CHANGELOG.md` is that new version.
- The current branch is clean, or you are on a dedicated docs-sync branch.

Expand Down Expand Up @@ -76,7 +76,7 @@ Keep:

Remove:

- The upstream H1 `# @pythoughts/pythinker-code` because the docs page already has `# Changelog`.
- The upstream H1 `# @pymodel/pythinker-code` because the docs page already has `# Changelog`.
- Changesets subheadings such as `### Patch Changes`, `### Minor Changes`, and `### Major Changes`.
- PR links such as `[#317](...)`.
- Commit hash links such as ``[`2f51db4`](...)``.
Expand Down Expand Up @@ -156,7 +156,7 @@ Every version heading must carry its release date in parentheses:
Take the date from the version's published GitHub Release tag, not from when you run the sync:

```bash
git log -1 --format=%cs "@pythoughts/pythinker-code@<version>"
git log -1 --format=%cs "@pymodel/pythinker-code@<version>"
```

Use the half-width parenthesis form ` (YYYY-MM-DD)` on the English page. Never invent or guess a date; if the tag is missing, stop and confirm with the user.
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/write-tui/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ When a controller or `PythinkerTUI` section keeps growing, split pure functions,
The feature type decides the landing spot:

- **CLI arguments** → `src/cli/commands.ts` / `src/cli/options.ts`, passed into the TUI via `src/cli/run-shell.ts`. The CLI never operates on the session directly.
- **CLI subcommands** → `src/cli/sub/`, non-interactive only; reach core via `@pythoughts/pythinker-code-sdk`.
- **CLI subcommands** → `src/cli/sub/`, non-interactive only; reach core via `@pymodel/pythinker-code-sdk`.
- **Slash commands** → declare/parse/type under `src/tui/commands/`; add the execution entry in `PythinkerTUI`'s slash-command handler section; sink complex logic into `utils` or a focused component.
- **Skill-derived commands** → hook into `buildSkillSlashCommands` / the skill command map; do not hard-code a single skill.
- **Transcript message types** → define the shape in `src/tui/types.ts`, add/extend a `components/messages/` component, register the renderer in the transcript builder.
Expand Down
54 changes: 27 additions & 27 deletions .changeset/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,41 @@ Current publishable packages:

| Package | Directory | Description |
| --- | --- | --- |
| `@pythoughts/pythinker-code` | `apps/pythinker-code` | CLI / TUI application — provides the `pythinker` command after install |
| `@pythoughts/pythinker-code-sdk` | `packages/node-sdk` | Public TypeScript SDK |
| `@pymodel/pythinker-code` | `apps/pythinker-code` | CLI / TUI application — provides the `pythinker` command after install |
| `@pymodel/pythinker-code-sdk` | `packages/node-sdk` | Public TypeScript SDK |

All other workspace packages are private internal packages, are not published to npm, and are excluded via `ignore` in `.changeset/config.json`:

- `@pythoughts/acp-adapter`
- `@pythoughts/agent-core`
- `@pythoughts/kaos`
- `@pythoughts/pythinker-code-oauth`
- `@pythoughts/pythinker-telemetry`
- `@pythoughts/pythinker-web`
- `@pythoughts/kosong`
- `@pythoughts/migration-legacy`
- `@pythoughts/protocol`
- `@pythoughts/server`
- `@pythoughts/server-e2e`
- `@pythoughts/dashboard`
- `@pythoughts/dashboard-server`
- `@pythoughts/dashboard-web`
- `@pymodel/acp-adapter`
- `@pymodel/agent-core`
- `@pymodel/kaos`
- `@pymodel/pythinker-code-oauth`
- `@pymodel/pythinker-telemetry`
- `@pymodel/pythinker-web`
- `@pymodel/kosong`
- `@pymodel/migration-legacy`
- `@pymodel/protocol`
- `@pymodel/server`
- `@pymodel/server-e2e`
- `@pymodel/dashboard`
- `@pymodel/dashboard-server`
- `@pymodel/dashboard-web`
- `pythinker-migration-legacy`

Version impact from internal dependencies must be judged manually. The published artifacts for CLI and SDK bundle internal workspace packages into the artifact itself; runtime `dependencies` of published packages must not include any `@pythoughts/*` internal workspace packages.
Version impact from internal dependencies must be judged manually. The published artifacts for CLI and SDK bundle internal workspace packages into the artifact itself; runtime `dependencies` of published packages must not include any `@pymodel/*` internal workspace packages.

The repository's `.changeset/config.json` sets `updateInternalDependencies: "patch"`. Because internal packages are not published, you still need to manually select all affected publishable packages in the changeset — do not rely solely on automatic dependency bumps to express user-visible changes.

Example scenarios:

| Change | Changeset selection |
| --- | --- |
| Only modifies TUI behavior in `@pythoughts/pythinker-code` | Add `patch` / `minor` / `major` to `@pythoughts/pythinker-code` |
| Only modifies TUI behavior in `@pymodel/pythinker-code` | Add `patch` / `minor` / `major` to `@pymodel/pythinker-code` |
| Only modifies internal packages, no user-visible change in SDK / CLI | Usually no changeset needed |
| Internal package fix changes the CLI user experience | Add a changeset to `@pythoughts/pythinker-code` describing the user-visible fix |
| Internal package adds a new capability exposed by the SDK | Add a changeset to `@pythoughts/pythinker-code-sdk` |
| SDK behavior change affects CLI user experience | Add changesets to both `@pythoughts/pythinker-code-sdk` and `@pythoughts/pythinker-code` |
| Provider abstraction change affects SDK / CLI | Add changesets to the affected `@pythoughts/pythinker-code-sdk` and/or `@pythoughts/pythinker-code` |
| Internal package fix changes the CLI user experience | Add a changeset to `@pymodel/pythinker-code` describing the user-visible fix |
| Internal package adds a new capability exposed by the SDK | Add a changeset to `@pymodel/pythinker-code-sdk` |
| SDK behavior change affects CLI user experience | Add changesets to both `@pymodel/pythinker-code-sdk` and `@pymodel/pythinker-code` |
| Provider abstraction change affects SDK / CLI | Add changesets to the affected `@pymodel/pythinker-code-sdk` and/or `@pymodel/pythinker-code` |
| Test-only, internal refactor, docs, or private debug tooling changes | Usually no changeset needed |
| Bundled official plugin change under `plugins/` (e.g. `pythinker-datasource`) | No changeset — the plugin is versioned via its own `pythinker.plugin.json` / `plugins/marketplace.json` and shipped through the marketplace CDN, not the npm package |

Expand All @@ -54,7 +54,7 @@ This repository uses npm's **Trusted Publishing** (OIDC-based) for publishing

### Configuration steps

1. Open each publishable package's page on the npm website, e.g. `https://www.npmjs.com/package/@pythoughts/pythinker-code`.
1. Open each publishable package's page on the npm website, e.g. `https://www.npmjs.com/package/@pymodel/pythinker-code`.
2. Go to **Settings** -> **Publishing access**.
3. Find **Automate publishing with GitHub Actions** or **Add trusted publisher**.
4. Click **Add a new trusted publisher**.
Expand Down Expand Up @@ -146,12 +146,12 @@ The root-level `pnpm run publish` first runs typecheck, lint, sherif, test, buil
## Notes

- Every PR that affects publishable-package behavior or public API should include a corresponding changeset.
- Changes under `plugins/` (the bundled official plugins such as `pythinker-datasource`) do **not** need a changeset: each plugin carries its own version in `pythinker.plugin.json` and `plugins/marketplace.json` and is distributed via the marketplace CDN, separately from the `@pythoughts/pythinker-code` npm package.
- Changes under `plugins/` (the bundled official plugins such as `pythinker-datasource`) do **not** need a changeset: each plugin carries its own version in `pythinker.plugin.json` and `plugins/marketplace.json` and is distributed via the marketplace CDN, separately from the `@pymodel/pythinker-code` npm package.
- Changeset files must be committed to the repository — release PRs are only triggered after they're merged.
- Release PRs require human review and merge; they will not publish automatically.
- Do not add release changesets for private internal packages; only select `@pythoughts/pythinker-code` and `@pythoughts/pythinker-code-sdk`.
- If a change in an underlying internal package alters user-visible behavior or public API of a publishable package, add a changeset to the affected publishable package. For example, when a bug fixed in `@pythoughts/agent-core` resolves an issue CLI users encounter, add a changeset to `@pythoughts/pythinker-code` describing the user-visible fix.
- `@pythoughts/pythinker-code` is the official CLI package name; after a global install it provides the `pythinker` command.
- Do not add release changesets for private internal packages; only select `@pymodel/pythinker-code` and `@pymodel/pythinker-code-sdk`.
- If a change in an underlying internal package alters user-visible behavior or public API of a publishable package, add a changeset to the affected publishable package. For example, when a bug fixed in `@pymodel/agent-core` resolves an issue CLI users encounter, add a changeset to `@pymodel/pythinker-code` describing the user-visible fix.
- `@pymodel/pythinker-code` is the official CLI package name; after a global install it provides the `pythinker` command.
- Make sure each publishable package on npm has a Trusted Publisher configured.

## References
Expand Down
28 changes: 14 additions & 14 deletions .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [
"@pythoughts/acp-adapter",
"@pythoughts/agent-core",
"@pythoughts/kaos",
"@pythoughts/pythinker-code-oauth",
"@pythoughts/pythinker-telemetry",
"@pythoughts/pythinker-web",
"@pythoughts/kosong",
"@pythoughts/migration-legacy",
"@pythoughts/protocol",
"@pythoughts/server",
"@pythoughts/server-e2e",
"@pythoughts/dashboard",
"@pythoughts/dashboard-server",
"@pythoughts/dashboard-web",
"@pymodel/acp-adapter",
"@pymodel/agent-core",
"@pymodel/kaos",
"@pymodel/pythinker-code-oauth",
"@pymodel/pythinker-telemetry",
"@pymodel/pythinker-web",
"@pymodel/kosong",
"@pymodel/migration-legacy",
"@pymodel/protocol",
"@pymodel/server",
"@pymodel/server-e2e",
"@pymodel/dashboard",
"@pymodel/dashboard-server",
"@pymodel/dashboard-web",
"pythinker-migration-legacy"
],
"snapshot": {
Expand Down
2 changes: 1 addition & 1 deletion .changeset/model-picker-keeps-effort.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
"@pythoughts/pythinker-code": patch
"@pymodel/pythinker-code": patch
---

Keep the current thinking effort when switching models in the model picker instead of silently saving the new model's lowest level as the default, and repair a stale thinking mode in the config when saving an effort.
2 changes: 1 addition & 1 deletion .changeset/persist-cycled-effort.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
"@pythoughts/pythinker-code": patch
"@pymodel/pythinker-code": patch
---

Keep the thinking effort chosen with Ctrl-T/Shift-Tab as the default across restarts.
5 changes: 5 additions & 0 deletions .changeset/pymodel-npm-scope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@pymodel/pythinker-code": minor
---

Publish the CLI under the @pymodel npm scope; install with `npm install -g @pymodel/pythinker-code`. The old @pythoughts scope is deprecated and no longer receives releases.
2 changes: 1 addition & 1 deletion .changeset/thinking-indicator-only.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
"@pythoughts/pythinker-code": patch
"@pymodel/pythinker-code": patch
---

Show only the animated thinking indicator while the model thinks; the streamed thinking text no longer appears in the transcript unless expanded with Ctrl+O.
Loading
Loading