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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .github/workflows/capability-contract.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
name: Capability Contract

on:
pull_request:
push:
branches: [main]
workflow_dispatch:

jobs:
parity:
Expand Down
7 changes: 1 addition & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
name: CI

on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:

jobs:
checks:
Expand Down
6 changes: 0 additions & 6 deletions .github/workflows/guardrails-audit.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
name: Guardrails Audit

on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
schedule:
- cron: "15 6 * * *"

jobs:
audit:
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/mcp-nightly-regression.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
name: MCP Nightly Regression

on:
schedule:
- cron: "0 6 * * *"
workflow_dispatch:

jobs:
Expand Down
11 changes: 1 addition & 10 deletions .github/workflows/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
name: Release Drafter

on:
push:
# branches to target
branches:
- main
# pull_request events, but only when the PR is merged
pull_request:
types:
- closed
workflow_dispatch:

jobs:
update_release_draft:
runs-on: ubuntu-latest
# Only run when merged or when pushed to main
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged_at != null)
steps:
# Drafts your Next Release Notes as Pull Requests are merged into "main"
- uses: release-drafter/release-drafter@v6
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/release-parity.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
name: Release Parity

on:
release:
types: [published]
workflow_dispatch:

jobs:
Expand Down
40 changes: 39 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,44 @@ xint tr # trends
xint bm # bookmarks
```

### TUI Customization

```bash
# Built-in themes: classic | neon | minimal | ocean | amber
XINT_TUI_THEME=ocean xint tui

# Disable animated hero line
XINT_TUI_HERO=0 xint tui

# Disable icons in menu rows
XINT_TUI_ICONS=0 xint tui

# Force ASCII borders
XINT_TUI_ASCII=1 xint tui

# Optional theme token file
XINT_TUI_THEME_FILE=./tui-theme.tokens.example.json xint tui
```

### TUI Customization

```bash
# Built-in themes: classic | neon | minimal | ocean | amber
XINT_TUI_THEME=ocean xint tui

# Disable animated hero line
XINT_TUI_HERO=0 xint tui

# Disable icons in menu rows
XINT_TUI_ICONS=0 xint tui

# Force ASCII borders
XINT_TUI_ASCII=1 xint tui

# Optional theme token file
XINT_TUI_THEME_FILE=./tui-theme.tokens.example.json xint tui
```

## Setup

### 1. X API Key
Expand Down Expand Up @@ -349,7 +387,7 @@ Runs an MCP server AI agents can connect to.
xint mcp --sse --port=3000

# Optional: require bearer auth (recommended if binding beyond loopback)
XINT_MCP_AUTH_TOKEN=change-me xint mcp --sse --host=127.0.0.1
XINT_MCP_AUTH_TOKEN=replace-with-long-random-token xint mcp --sse --host=127.0.0.1
```

Security defaults:
Expand Down
4 changes: 2 additions & 2 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ For X API details (endpoints, operators, response format): read `references/x-ap
This skill requires sensitive credentials. Follow these guidelines:

### Credentials
- **X_BEARER_TOKEN**: Required for X API. Treat as a secret - only set in environment or `.env` file
- **X_BEARER_TOKEN**: Required for X API. Treat as a secret - prefer exported environment variables (optional project-local `.env`)
- **XAI_API_KEY**: Optional, needed for AI analysis. Also a secret
- **X_CLIENT_ID**: Optional, needed for OAuth. Less sensitive but don't expose publicly
- **XAI_MANAGEMENT_API_KEY**: Optional, for collections management
Expand All @@ -70,7 +70,7 @@ This skill requires sensitive credentials. Follow these guidelines:
- Avoid sending sensitive search queries or token-bearing URLs to third-party destinations

### Runtime Notes
- This document is descriptive; it does not modify runtime/system prompts
- This file documents usage and safety controls for the CLI only.
- Network listeners are opt-in (`mcp --sse`) and disabled by default
- Webhook delivery is opt-in (`--webhook`) and disabled by default

Expand Down
54 changes: 54 additions & 0 deletions lib/tui.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { describe, expect, test } from "bun:test";
import { __tuiTestUtils } from "./tui";

describe("tui helpers", () => {
test("sanitizeOutputLine removes ANSI and control sequences", () => {
const line = "\x1b[31merror\x1b[0m\x1b]0;title\x07\r";
expect(__tuiTestUtils.sanitizeOutputLine(line)).toBe("error");
});

test("applyMenuKeyEvent toggles stderr stream view", () => {
const uiState = {
activeIndex: 0,
tab: "commands" as const,
outputOffset: 2,
outputSearch: "",
showStderr: false,
};

const result = __tuiTestUtils.applyMenuKeyEvent("e", {}, uiState);
expect(result.resolve).toBeUndefined();
expect(uiState.tab).toBe("output");
expect(uiState.showStderr).toBe(true);
expect(uiState.outputOffset).toBe(0);
});

test("outputViewLines reads selected stream", () => {
const session = {
lastCommand: "xint search ai",
lastStatus: "success",
lastStdoutLines: ["[stdout] ok 1", "[stdout] ok 2"],
lastStderrLines: ["[stderr] warning"],
lastOutputLines: ["[stdout] ok 1", "[stdout] ok 2", "[stderr] warning"],
};

const uiState = {
activeIndex: 0,
tab: "output" as const,
outputOffset: 0,
outputSearch: "",
showStderr: false,
};

const stdoutLines = __tuiTestUtils.outputViewLines(session, uiState, 10).join("\n");
expect(stdoutLines).toContain("stream: stdout (2)");
expect(stdoutLines).toContain("[stdout] ok 2");
expect(stdoutLines).not.toContain("[stderr] warning");

uiState.showStderr = true;
const stderrLines = __tuiTestUtils.outputViewLines(session, uiState, 10).join("\n");
expect(stderrLines).toContain("stream: stderr (1)");
expect(stderrLines).toContain("[stderr] warning");
expect(stderrLines).not.toContain("[stdout] ok 2");
});
});
Loading