@wenathlan/devthink 1.1.9 → 1.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -103
- package/package.json +1 -1
- package/terminal-ui.tsx +33 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,107 +1,14 @@
|
|
|
1
|
-
#
|
|
1
|
+
# DevThink release notes
|
|
2
2
|
|
|
3
|
-
## 1.1.
|
|
4
|
-
|
|
5
|
-
This release reconstructs DevThink as one command-first terminal workspace across its static React workbench and interactive CLI. The browser is the route-addressable React surface; the CLI is a React Ink terminal surface with the same categories, empty states, local credential boundary and command rail.
|
|
6
|
-
|
|
7
|
-
| Area | Change |
|
|
8
|
-
| --- | --- |
|
|
9
|
-
| Shared information architecture | Aligns `features`, `bugs`, `refactor`, `snippets`, `tasks`, `notes`, `all` and `settings` across web and CLI. |
|
|
10
|
-
| Browser workbench | Replaces the dashboard shell with a sparse black terminal workspace, top category strip, central canvas and bottom command rail. |
|
|
11
|
-
| Interactive CLI | Adds an Ink React renderer for TTY sessions, preserving the canonical ANSI fallback for noninteractive and compatibility contexts. |
|
|
12
|
-
| Binary portability | Uses Ink rather than a native TUI dependency so Bun can bundle the CLI for Linux, macOS and Windows release targets. |
|
|
13
|
-
| Release metadata | Aligns the CLI, static workbench, mobile shell, extension and package adapters on version 1.1.9. |
|
|
14
|
-
|
|
15
|
-
## 1.1.8 — Workflow trust boundaries and package adapters
|
|
16
|
-
|
|
17
|
-
This release removes `workflow_run` as a trigger from privileged distribution workflows. Publishing jobs now check out only a release tag or a manually supplied authenticated release tag, preventing a completed workflow from selecting arbitrary source code before package or release credentials become available.
|
|
18
|
-
|
|
19
|
-
| Area | Change |
|
|
20
|
-
| --- | --- |
|
|
21
|
-
| CodeQL remediation | Removes untrusted `workflow_run.head_sha` checkouts from npm, GitHub Packages, extension, container, GHCR and mobile publication workflows. |
|
|
22
|
-
| Maven | Adds a Java 17 process adapter and a source-backed Maven publication workflow for GitHub Packages. |
|
|
23
|
-
| NuGet | Adds a .NET 8 process adapter, package README and a source-backed NuGet publication workflow for GitHub Packages. |
|
|
24
|
-
| RubyGems | Adds a Ruby process adapter and a source-backed RubyGems publication workflow for GitHub Packages. |
|
|
25
|
-
| Release metadata | Aligns the CLI, static workbench, mobile shell, extension and adapter packages on version 1.1.8. |
|
|
26
|
-
|
|
27
|
-
## 1.1.7 — Security remediation
|
|
28
|
-
|
|
29
|
-
This release resolves the Trivy Dockerfile finding `DS-0026` by declaring an executable container health check that verifies the Bun-compiled DevThink CLI is available in the nonroot distroless runtime. The security workflow keeps its active Trivy, OSV, pnpm-audit and verified-secret gates; no scanner, severity threshold or release protection is weakened.
|
|
30
|
-
|
|
31
|
-
| Area | Change |
|
|
32
|
-
| --- | --- |
|
|
33
|
-
| Container hardening | Adds a native `HEALTHCHECK` instruction that executes `devthink --help` without requiring a shell in the distroless runtime. |
|
|
34
|
-
| Gateway reliability | Requests an operating-system-assigned loopback port by default, avoiding HTTP-client restricted ports during concurrent test execution in CI. |
|
|
35
|
-
| Dependency review | Confirms the workbench audit has no known vulnerabilities at low, moderate, high or critical severity. |
|
|
36
|
-
| Mobile dependency graph | Retains the `uuid` 11.1.1 override that removes the previously vulnerable transitive UUID version. |
|
|
37
|
-
| Release metadata | Aligns the CLI, static workbench, mobile shell and browser extension on version 1.1.7. |
|
|
38
|
-
|
|
39
|
-
## 1.1.6 — Mobile artifact activation
|
|
40
|
-
|
|
41
|
-
This release corrects the mobile workflow's source detector for the JSON Capacitor configuration. Android development APK/AAB and iOS simulator application packaging now execute whenever the source is present.
|
|
42
|
-
|
|
43
|
-
## 1.1.5 — Minimal container runtime
|
|
44
|
-
|
|
45
|
-
This release replaces the container runtime with a nonroot distroless compatibility image. The image contains only the compiled DevThink binary and its required C/C++ runtime libraries, reducing the operating-system package surface scanned before GHCR publication.
|
|
46
|
-
|
|
47
|
-
## 1.1.4 — Container runtime compatibility
|
|
48
|
-
|
|
49
|
-
This release runs the Bun-compiled CLI in a Bun runtime image, avoiding dynamic-library mismatches during GHCR smoke tests. Security workflows retain Trivy SARIF evidence even when the configured gate detects a high-severity issue.
|
|
50
|
-
|
|
51
|
-
## 1.1.3 — Distribution repair
|
|
52
|
-
|
|
53
|
-
This release corrects the mobile Capacitor configuration and resolves the vulnerable UUID transitively selected by the initial mobile lockfile. It also moves the Bun container runtime to a glibc-compatible base, so the compiled CLI runs in the released image, and limits Maven, NuGet, and RubyGems publication to manual source-backed dispatches.
|
|
54
|
-
|
|
55
|
-
## 1.1.2 — Distribution surfaces and artifacts
|
|
56
|
-
|
|
57
|
-
This release keeps `@wenathlan/devthink` as the only npm package and adds source-backed distribution surfaces for a browser extension, a Bun-compiled container, Android development artifacts, and an iOS simulator artifact. Maven, NuGet and RubyGems remain source-gated because the repository does not contain Java, .NET, or Ruby package sources.
|
|
58
|
-
|
|
59
|
-
| Area | Change |
|
|
60
|
-
| --- | --- |
|
|
61
|
-
| npm | Publishes only the DevThink CLI package. |
|
|
62
|
-
| Browser extension | Packages the static workbench as a Manifest V3 release ZIP with explicit local-gateway host permissions. |
|
|
63
|
-
| Container | Compiles the CLI with Bun in a multi-stage image and publishes a container release archive and GHCR image when triggered. |
|
|
64
|
-
| Mobile | Uses Capacitor source with Bun-built web assets to produce Android development artifacts and an unsigned iOS simulator application. |
|
|
65
|
-
|
|
66
|
-
## 1.1.1 — DevThink publication and workflow reconciliation
|
|
67
|
-
|
|
68
|
-
This release aligns the CLI and static workbench at version 1.1.1, refreshes direct web dependencies, and updates the GitHub Actions toolchain. The workbench remains a static deployment surface and is not published as a separate npm package.
|
|
69
|
-
|
|
70
|
-
| Area | Change |
|
|
71
|
-
| --- | --- |
|
|
72
|
-
| Distribution | Publishes only `@wenathlan/devthink` through the credential-safe npm workflow. |
|
|
73
|
-
| Workflows | Updates Actions runtimes and adds source-aware guards for optional ecosystem packages. |
|
|
74
|
-
| Compatibility | Raises the declared Node.js baseline to 26.7.0 and refreshes direct web dependencies to their current releases. |
|
|
75
|
-
| Static web | Preserves the deployable `web/` artifact for GitHub Pages, Vercel and Netlify. |
|
|
76
|
-
|
|
77
|
-
## Embedded gateway and web workbench implementation
|
|
78
|
-
|
|
79
|
-
This implementation turns the audited repository context into the DevThink feature map and expands the DevThink CLI with provider-owned endpoints, normalized streaming and a local embedded gateway.
|
|
80
|
-
|
|
81
|
-
| Area | Change |
|
|
82
|
-
| --- | --- |
|
|
83
|
-
| Documentation | Adds the DevThink feature-map collection, correction specification, canonical audit coverage, provider families, known regressions, terminal design and web plan |
|
|
84
|
-
| Gateway | Adds provider-specific endpoint overrides, embedded streaming diagnostics and secret redaction without a separate proxy subsystem |
|
|
85
|
-
| Providers | Adds registry entries for DeepSeek, Groq, Mistral, xAI and Ollama while retaining OpenAI, Z.AI, Anthropic, Google, OpenRouter and Qwen |
|
|
86
|
-
| CLI | Adds `gateway status`, explicit `auth login`, canonical `devthink.json` persistence and the terminal logo from `docs/logo.md` |
|
|
87
|
-
| Tests | Adds embedded-gateway, nested credential-redaction and configuration-path coverage |
|
|
88
|
-
| Web | Adds the DevThink browser-like workbench directly under `web/`, including tabs, provider rail, stream canvas, route inspector, command palette, responsive layout and canonical ANSI branding |
|
|
89
|
-
| Security | Keeps cookie capture, CAPTCHA solving, stealth automation and anti-bot evasion outside the product core |
|
|
90
|
-
|
|
91
|
-
## 1.0.0 — 2026-08-19
|
|
3
|
+
## 1.1.10 — Entry and browser-workspace redesign
|
|
92
4
|
|
|
93
5
|
### Added
|
|
94
6
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
This release deliberately excludes browser-cookie capture, undocumented web-session automation, CAPTCHA solving, anti-bot evasion, device-fingerprint forgery, and credential extraction. Provider failures are surfaced explicitly, and the release workflow scans product files for common embedded-secret patterns before publishing.
|
|
104
|
-
|
|
105
|
-
### Distribution
|
|
106
|
-
|
|
107
|
-
GitHub Actions builds self-contained Bun binaries for Linux x64, macOS arm64, and Windows x64 from version tags. The workflow reads the release version from `package.json`, runs tests, generates SHA-256 checksums, and attaches artifacts to the GitHub release.
|
|
7
|
+
| Area | Addition |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| Landing entry | A first-command introduction with the canonical DevThink ANSI mark behind an oversized wordmark and one focused command field. |
|
|
10
|
+
| First-command transition | A submitted natural-language intention creates a local identity, records the first session intent and opens the workspace. |
|
|
11
|
+
| Browser workspace | A two-level navigation model with browser-shaped session chrome, an active local tab, task-category pills and a persistent command rail. |
|
|
12
|
+
| Visual system | Original black editorial surfaces, layered charcoal browser material, intentional orange states and orb-blue local connection signals. |
|
|
13
|
+
| CLI parity | The Ink renderer now starts on the same command-first entry surface and opens the same local workspace semantics after the first command. |
|
|
14
|
+
| Release packaging | Locked CLI dependencies are installed before Bun binary compilation and inside the container build so the React Ink renderer is included consistently. |
|
package/package.json
CHANGED
package/terminal-ui.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** Design: DevThink v1.1.10 — Ink renders the same landing-to-browser-workspace progression as the React workbench. */
|
|
2
2
|
import { Box, Text, render, useApp, useInput, useWindowSize } from "ink";
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import type { DevThinkConfig } from "./config.ts";
|
|
@@ -7,6 +7,7 @@ import type { Session } from "./session.ts";
|
|
|
7
7
|
|
|
8
8
|
const categories = ["features", "bugs", "refactor", "snippets", "tasks", "notes", "all", "settings"] as const;
|
|
9
9
|
const categoryGlyphs: Record<(typeof categories)[number], string> = { features: "ϟ", bugs: "⊗", refactor: "◌", snippets: "◫", tasks: "☑", notes: "□", all: "◉", settings: "⚙" };
|
|
10
|
+
const entryArt = [" +++++", " +++++++++++++++", " ++++++ ++++++", " +++++ +++++", " +++++ +++++", " +++++ +++++", " ++++++ ++++++", " +++++++++++++", " +++++"];
|
|
10
11
|
|
|
11
12
|
type Runtime = { config: DevThinkConfig };
|
|
12
13
|
type Execute = (prompt: string, current: Session | undefined, onEvent: (event: ChatEvent) => void) => Promise<Session | undefined>;
|
|
@@ -16,9 +17,25 @@ function clip(value: string, width: number): string {
|
|
|
16
17
|
return value.length > width ? `${value.slice(0, Math.max(0, width - 1))}…` : value;
|
|
17
18
|
}
|
|
18
19
|
|
|
20
|
+
function TerminalEntry({ draft, provider, width }: { draft: string; provider: string; width: number }) {
|
|
21
|
+
return <Box flexDirection="column" width="100%" height="100%" minHeight={20} paddingX={2} paddingY={1} justifyContent="space-between">
|
|
22
|
+
<Box justifyContent="space-between"><Text color="#807970">✦ DEVTHINK</Text><Text color="#8ab4f8">LOCAL-FIRST WORKBENCH</Text></Box>
|
|
23
|
+
<Box flexDirection="column" alignItems="center">
|
|
24
|
+
<Box flexDirection="column" alignItems="center">{entryArt.map((line, index) => <Text key={`${line}-${index}`} color="#382c23">{line}</Text>)}</Box>
|
|
25
|
+
<Box marginTop={-1}><Text color="#ff5f00" bold>DEVTHINK</Text></Box>
|
|
26
|
+
<Box marginTop={1}><Text color="#746f66">begin with one intention</Text></Box>
|
|
27
|
+
<Box marginTop={2}><Text color="#282724">┌{"─".repeat(Math.max(16, width - 2))}┐</Text></Box>
|
|
28
|
+
<Text color="#e8e1d7">│ <Text color="#ff5f00">›_ </Text><Text color={draft ? "#e8e1d7" : "#746f66"}>{clip(draft || "Ask anything…", Math.max(12, width - 22))}</Text><Text color="#8ab4f8"> {provider}</Text><Text color="#ff5f00"> [open]</Text> │</Text>
|
|
29
|
+
<Text color="#282724">└{"─".repeat(Math.max(16, width - 2))}┘</Text>
|
|
30
|
+
</Box>
|
|
31
|
+
<Text color="#746f66">enter opens a local workspace · esc exits</Text>
|
|
32
|
+
</Box>;
|
|
33
|
+
}
|
|
34
|
+
|
|
19
35
|
function TerminalWorkspace({ runtime, execute, version }: { runtime: Runtime; execute: Execute; version: string }) {
|
|
20
36
|
const { exit } = useApp();
|
|
21
37
|
const { columns } = useWindowSize();
|
|
38
|
+
const [entered, setEntered] = useState(false);
|
|
22
39
|
const [active, setActive] = useState<(typeof categories)[number]>("all");
|
|
23
40
|
const [entries, setEntries] = useState<Entry[]>([]);
|
|
24
41
|
const [session, setSession] = useState<Session>();
|
|
@@ -34,6 +51,12 @@ function TerminalWorkspace({ runtime, execute, version }: { runtime: Runtime; ex
|
|
|
34
51
|
const prompt = draft.trim();
|
|
35
52
|
if (!prompt || pending) return;
|
|
36
53
|
if (prompt === "/exit" || prompt === "/quit") return exit();
|
|
54
|
+
if (!entered) {
|
|
55
|
+
setEntries([{ role: "user", title: "first intention", body: prompt }, { role: "devthink", title: "local workspace ready", body: "The first command opened a local DevThink session. Configure a provider whenever the work needs a model." }]);
|
|
56
|
+
setDraft("");
|
|
57
|
+
setEntered(true);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
37
60
|
if (prompt === "/clear") { setEntries([]); setDraft(""); return; }
|
|
38
61
|
if (prompt === "/new") { setSession(undefined); setEntries([]); setDraft(""); return; }
|
|
39
62
|
if (prompt === "/help") {
|
|
@@ -59,22 +82,25 @@ function TerminalWorkspace({ runtime, execute, version }: { runtime: Runtime; ex
|
|
|
59
82
|
|
|
60
83
|
useInput((input, key) => {
|
|
61
84
|
if (key.escape || (key.ctrl && input === "c")) return exit();
|
|
62
|
-
if (key.leftArrow || key.tab) return setActive((current) => categories[(categories.indexOf(current) + categories.length - 1) % categories.length]);
|
|
63
|
-
if (key.rightArrow) return setActive((current) => categories[(categories.indexOf(current) + 1) % categories.length]);
|
|
64
85
|
if (key.return) return void submit();
|
|
65
86
|
if (key.backspace || key.delete) return setDraft((current) => current.slice(0, -1));
|
|
87
|
+
if (entered && (key.leftArrow || key.tab)) return setActive((current) => categories[(categories.indexOf(current) + categories.length - 1) % categories.length]);
|
|
88
|
+
if (entered && key.rightArrow) return setActive((current) => categories[(categories.indexOf(current) + 1) % categories.length]);
|
|
66
89
|
if (!key.ctrl && !key.meta && input) setDraft((current) => current + input);
|
|
67
90
|
});
|
|
68
91
|
|
|
92
|
+
if (!entered) return <TerminalEntry draft={draft} provider={provider} width={terminalWidth} />;
|
|
93
|
+
|
|
69
94
|
return <Box flexDirection="column" width="100%" height="100%" minHeight={20} paddingX={compact ? 1 : 3} paddingY={1}>
|
|
70
|
-
<Text color="#a19a91"
|
|
95
|
+
<Box justifyContent="space-between"><Text color="#a19a91">✦ DEVTHINK <Text color="#746f66">/ local session</Text></Text><Text color="#8ab4f8">◉ {provider.toUpperCase()}</Text></Box>
|
|
71
96
|
<Text color="#282724">{"─".repeat(terminalWidth)}</Text>
|
|
72
|
-
<Text color="#
|
|
97
|
+
<Text color="#746f66">{clip(tabLine, terminalWidth)}</Text>
|
|
98
|
+
<Box marginTop={1}><Text color="#e8e1d7">{categoryGlyphs[active]} {active.toUpperCase()} <Text color="#746f66">· {entries.length} entries · {clip(model, 22)}</Text></Text></Box>
|
|
73
99
|
<Box flexDirection="column" flexGrow={1} justifyContent={entries.length ? "flex-start" : "center"} alignItems={entries.length ? "flex-start" : "center"}>
|
|
74
|
-
{entries.length ? entries.map((entry, index) => <Box key={`${entry.title}-${index}`} flexDirection="column" marginBottom={1} paddingLeft={1}><Box><Text color={entry.role === "user" ? "#ff5f00" : entry.role === "error" ? "#ff6b6b" : "#8ab4f8"}>▎ {entry.title.toUpperCase()}</Text></Box><Box><Text color="#e8e1d7">{clip(entry.body, terminalWidth - 6)}</Text></Box></Box>) : <Box flexDirection="column" alignItems="center"><Box><Text color="#4b4842">
|
|
100
|
+
{entries.length ? entries.map((entry, index) => <Box key={`${entry.title}-${index}`} flexDirection="column" marginBottom={1} paddingLeft={1}><Box><Text color={entry.role === "user" ? "#ff5f00" : entry.role === "error" ? "#ff6b6b" : "#8ab4f8"}>▎ {entry.title.toUpperCase()}</Text></Box><Box><Text color="#e8e1d7">{clip(entry.body, terminalWidth - 6)}</Text></Box></Box>) : <Box flexDirection="column" alignItems="center"><Box><Text color="#4b4842">Nothing is active yet.</Text></Box><Box><Text color="#625c54">Describe the next feature, bug or piece of work below.</Text></Box><Box marginTop={2}><Text color="#ff5f00" bold>DEVTHINK</Text></Box></Box>}
|
|
75
101
|
</Box>
|
|
76
102
|
<Text color="#282724">┌{"─".repeat(Math.max(16, terminalWidth - 2))}┐</Text>
|
|
77
|
-
<Text color="#e8e1d7">│ <Text color="#ff5f00">›_ </Text><Text color={draft ? "#e8e1d7" : "#746f66"}>{clip(draft || `
|
|
103
|
+
<Text color="#e8e1d7">│ <Text color="#ff5f00">›_ </Text><Text color={draft ? "#e8e1d7" : "#746f66"}>{clip(draft || `Ask DevThink about ${active === "all" ? "the work…" : `${active}…`}`, Math.max(12, terminalWidth - 20))}</Text><Text color="#8ab4f8"> {provider}</Text><Text color="#ff5f00"> [run]</Text> │</Text>
|
|
78
104
|
<Text color="#282724">└{"─".repeat(Math.max(16, terminalWidth - 2))}┘</Text>
|
|
79
105
|
<Text color="#746f66">provider credentials stay in the local cli · v{version} · esc exit</Text>
|
|
80
106
|
</Box>;
|