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
5 changes: 5 additions & 0 deletions .changeset/huge-ants-stick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"openwiki": patch
---

chore: reorganize repo code to make into domain specific directories and improve test coverage to prevent regressions
4 changes: 2 additions & 2 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ jobs:
run: pnpm run build

- name: Smoke test CLI
run: node dist/cli.js code --dry-run --init
run: node dist/cli/cli.js code --dry-run --init
env:
OPENWIKI_DEV: "1"

Expand Down Expand Up @@ -146,7 +146,7 @@ jobs:
run: pnpm install --frozen-lockfile

- name: Run Windows portability tests
run: pnpm exec vitest run test/skills.test.ts test/env-behavior.test.ts
run: pnpm exec vitest run test/agent/skills.test.ts test/config/env-behavior.test.ts

audit:
name: Audit
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ pnpm run lint
pnpm test
```

`format` and `lint` match the checks that run on every PR, and `test` runs the
Vitest suite.
`format` and `lint` match the checks that run on every PR, and `test`
typechecks, builds, and runs the Vitest suite with coverage.

If your change should ship in a release, also add a changeset (see below).

Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"node": ">=22"
},
"bin": {
"openwiki": "./dist/cli.js"
"openwiki": "./dist/cli/cli.js"
},
"repository": {
"type": "git",
Expand All @@ -34,21 +34,21 @@
"cli"
],
"scripts": {
"openwiki": "node dist/cli.js",
"openwiki": "node dist/cli/cli.js",
"build": "tsc -p tsconfig.json && tsc -p tsconfig.client.json",
"changeset:version": "changeset version",
"clean": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"",
"coverage": "vitest run --coverage",
"dev": "tsx src/cli.tsx",
"dev": "tsx src/cli/cli.tsx",
"format": "prettier --write .",
"format:check": "prettier --check .",
"lint": "eslint . --fix",
"lint:check": "eslint .",
"prebuild": "pnpm run clean",
"prepack": "pnpm run build",
"release": "pnpm run build && changeset publish",
"start": "node dist/cli.js",
"test": "vitest run",
"start": "node dist/cli/cli.js",
"test": "pnpm run typecheck && pnpm run build && pnpm run coverage",
"typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.client.json"
},
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion src/agent/docs-only-backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
type ReadResult,
type WriteResult,
} from "deepagents";
import { OPEN_WIKI_DIR } from "../constants.js";
import { OPEN_WIKI_DIR } from "../config/constants.js";
import { OPENWIKI_IGNORE_FILE, OpenWikiIgnore } from "./openwiki-ignore.js";
import type { OpenWikiOutputMode } from "./types.js";

Expand Down
14 changes: 7 additions & 7 deletions src/agent/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@ import {
loadOpenWikiEnv,
openWikiEnvDir,
saveOpenWikiEnv,
} from "../env.js";
import { isFileNotFoundError } from "../fs-errors.js";
} from "../config/env.js";
import { isFileNotFoundError } from "../platform/fs-errors.js";
import {
sanitizeDiagnosticText,
SECRET_KEY_PATTERN_SOURCE,
} from "../diagnostics.js";
} from "../platform/diagnostics.js";
import {
openWikiConversationHistoryDir,
openWikiLocalWikiDir,
openWikiSkillsDir,
} from "../openwiki-home.js";
import { resolveLanguage } from "../language.js";
} from "../config/openwiki-home.js";
import { resolveLanguage } from "../platform/language.js";
import {
resolveConceptTypeLabel,
resolveIndexLabels,
Expand Down Expand Up @@ -121,11 +121,11 @@ import {
resolveProviderRegion,
resolveProviderRetryAttempts,
type OpenWikiProvider,
} from "../constants.js";
} from "../config/constants.js";
import {
resolveExternalCliCredential,
validateExternalCliCredential,
} from "../external-cli-auth.js";
} from "../auth/external-cli-auth.js";
import {
createOpenWikiContentSnapshot,
getUpdateNoopStatus,
Expand Down
2 changes: 1 addition & 1 deletion src/agent/openai-chatgpt-oauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
OPENAI_CHATGPT_EXPIRES_AT_ENV_KEY,
OPENAI_CHATGPT_PLAN_ENV_KEY,
OPENAI_CHATGPT_REFRESH_TOKEN_ENV_KEY,
} from "../constants.js";
} from "../config/constants.js";

/**
* ChatGPT/Codex OAuth client.
Expand Down
2 changes: 1 addition & 1 deletion src/agent/openwiki-ignore.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { readFile } from "node:fs/promises";
import path from "node:path";
import { isFileNotFoundError } from "../fs-errors.js";
import { isFileNotFoundError } from "../platform/fs-errors.js";

/**
* Name of the gitignore-style file that lists paths the doc agent must not touch.
Expand Down
5 changes: 4 additions & 1 deletion src/agent/skills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import {
} from "node:fs/promises";
import { fileURLToPath } from "node:url";
import path from "node:path";
import { ensureOpenWikiHome, openWikiSkillsDir } from "../openwiki-home.js";
import {
ensureOpenWikiHome,
openWikiSkillsDir,
} from "../config/openwiki-home.js";

const bundledSkillsDir = fileURLToPath(
new URL("../../skills", import.meta.url),
Expand Down
2 changes: 1 addition & 1 deletion src/agent/translation-middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { HumanMessage, SystemMessage } from "@langchain/core/messages";
import type { BackendProtocolV2, FileInfo } from "deepagents";
import { createMiddleware } from "langchain";
import path from "node:path";
import { getErrorMessage } from "../diagnostics.js";
import { getErrorMessage } from "../platform/diagnostics.js";
import {
OPENWIKI_TRANSLATION_PENDING_FIELD,
readFrontmatterField,
Expand Down
8 changes: 4 additions & 4 deletions src/agent/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import { createHash } from "node:crypto";
import { mkdir, readdir, readFile, rm, writeFile } from "node:fs/promises";
import path from "node:path";
import { promisify } from "node:util";
import { OPEN_WIKI_DIR, UPDATE_METADATA_PATH } from "../constants.js";
import { OPEN_WIKI_DIR, UPDATE_METADATA_PATH } from "../config/constants.js";
import {
isExpectedSnapshotRaceError,
isFileNotFoundError,
} from "../fs-errors.js";
import { resolveLanguage } from "../language.js";
} from "../platform/fs-errors.js";
import { resolveLanguage } from "../platform/language.js";
import {
readOpenWikiOnboardingConfig,
readRepositoryWikiInstructions,
} from "../onboarding.js";
} from "../setup/onboarding.js";
import { OpenWikiIgnore } from "./openwiki-ignore.js";
import type {
OpenWikiCommand,
Expand Down
2 changes: 1 addition & 1 deletion src/agent/vertex-surface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GoogleAuth } from "google-auth-library";
import { ANTHROPIC_API_KEY_ENV_KEY } from "../constants.js";
import { ANTHROPIC_API_KEY_ENV_KEY } from "../config/constants.js";

/**
* A Vertex AI Model Garden model can be served over one of several distinct API
Expand Down
4 changes: 2 additions & 2 deletions src/auth/configure.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { chmod, readFile, writeFile } from "node:fs/promises";
import { OPENWIKI_NOTION_MCP_ACCESS_TOKEN_ENV_KEY } from "../constants.js";
import { OPENWIKI_NOTION_MCP_ACCESS_TOKEN_ENV_KEY } from "../config/constants.js";
import {
ensureConnectorHome,
getConnectorConfigPath,
} from "../openwiki-home.js";
} from "../config/openwiki-home.js";
import {
discoverMcpConnectorTools,
isMcpConnectorId,
Expand Down
2 changes: 1 addition & 1 deletion src/external-cli-auth.ts → src/auth/external-cli-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
providerUsesExternalCliAuth,
type ExternalCliAuthAdapter,
type OpenWikiProvider,
} from "./constants.js";
} from "../config/constants.js";

const execFileAsync = promisify(execFile);
const EXTERNAL_CLI_TIMEOUT_MS = 5_000;
Expand Down
2 changes: 1 addition & 1 deletion src/auth/ngrok.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { spawn } from "node:child_process";
import type { ChildProcess } from "node:child_process";
import { saveOpenWikiEnv } from "../env.js";
import { saveOpenWikiEnv } from "../config/env.js";

const DEFAULT_CALLBACK_PORT = 53682;
const OAUTH_CALLBACK_PORT_ENV_KEY = "OPENWIKI_OAUTH_CALLBACK_PORT";
Expand Down
2 changes: 1 addition & 1 deletion src/auth/oauth.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createHash, randomBytes } from "node:crypto";
import { execFile } from "node:child_process";
import http from "node:http";
import { loadOpenWikiEnv, saveOpenWikiEnv } from "../env.js";
import { loadOpenWikiEnv, saveOpenWikiEnv } from "../config/env.js";
import {
discoverAuthorizationServerMetadata,
discoverProtectedResourceMetadata,
Expand Down
2 changes: 1 addition & 1 deletion src/auth/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
OPENWIKI_X_CLIENT_ID_ENV_KEY,
OPENWIKI_X_CLIENT_SECRET_ENV_KEY,
OPENWIKI_X_REFRESH_TOKEN_ENV_KEY,
} from "../constants.js";
} from "../config/constants.js";
import type { AuthProviderId, OAuthProviderConfig } from "./types.js";

export const AUTH_PROVIDERS: Record<AuthProviderId, OAuthProviderConfig> = {
Expand Down
2 changes: 1 addition & 1 deletion src/auth/tokens.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { loadOpenWikiEnv, saveOpenWikiEnv } from "../env.js";
import { loadOpenWikiEnv, saveOpenWikiEnv } from "../config/env.js";
import {
discoverAuthorizationServerMetadata,
discoverProtectedResourceMetadata,
Expand Down
43 changes: 23 additions & 20 deletions src/cli.tsx → src/cli/cli.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ import {
configureAuthProvider,
listAuthProviderTools,
shouldDiscoverToolsAfterAuth,
} from "./auth/configure.js";
import { startNgrokTunnel } from "./auth/ngrok.js";
import { runVisualizeServer } from "./visualize/server.js";
import { formatAuthProviderList, runOAuthAuth } from "./auth/oauth.js";
import { ensureCodeModeRepoSetup, runCodeModeConnectors } from "./code-mode.js";
} from "../auth/configure.js";
import { startNgrokTunnel } from "../auth/ngrok.js";
import { runVisualizeServer } from "../visualize/server.js";
import { formatAuthProviderList, runOAuthAuth } from "../auth/oauth.js";
import {
ensureCodeModeRepoSetup,
runCodeModeConnectors,
} from "../ingestion/code-mode.js";
import {
commandEmitsTelemetry,
helpContent,
Expand All @@ -28,37 +31,37 @@ import {
InitSetup,
needsCredentialSetup,
type InitSetupResult,
} from "./credentials.js";
} from "../setup/credentials.js";
import {
getCredentialDiagnostics,
getShellEnvValue,
loadOpenWikiEnv,
saveOpenWikiEnv,
type CredentialDiagnostic,
} from "./env.js";
import { createOpenWikiThreadId, runOpenWikiAgent } from "./agent/index.js";
import { installCrashGuard } from "./agent/crash-guard.js";
import { formatChatGptAccountFromEnv } from "./agent/openai-chatgpt-oauth.js";
} from "../config/env.js";
import { createOpenWikiThreadId, runOpenWikiAgent } from "../agent/index.js";
import { installCrashGuard } from "../agent/crash-guard.js";
import { formatChatGptAccountFromEnv } from "../agent/openai-chatgpt-oauth.js";
import {
getErrorMessage,
isAuthError,
isSecretLikeKey,
sanitizeDiagnosticText,
} from "./diagnostics.js";
import { stripHtmlTags } from "./utils.js";
} from "../platform/diagnostics.js";
import { stripHtmlTags } from "../platform/utils.js";
import {
type OpenWikiRunEvent,
type OpenWikiRunResult,
} from "./agent/types.js";
} from "../agent/types.js";
import {
runOpenWikiIngestion,
type OpenWikiIngestionResult,
} from "./ingestion.js";
} from "../ingestion/ingestion.js";
import {
readOpenWikiOnboardingConfig,
saveOpenWikiOnboardingConfig,
} from "./onboarding.js";
import { openWikiLocalWikiDir } from "./openwiki-home.js";
} from "../setup/onboarding.js";
import { openWikiLocalWikiDir } from "../config/openwiki-home.js";
import {
deleteConnectorSchedules,
getSavedPowerScheduleStatus,
Expand All @@ -68,7 +71,7 @@ import {
type ConnectorScheduleStatus,
type PowerScheduleStatus,
type ScheduleMutationResult,
} from "./schedules.js";
} from "../scheduling/schedules.js";
import {
getDefaultModelId,
getMissingProviderEnvKey,
Expand All @@ -87,20 +90,20 @@ import {
SELECTABLE_OPENWIKI_PROVIDERS,
OPENWIKI_VERSION,
type OpenWikiProvider,
} from "./constants.js";
} from "../config/constants.js";
import type {
OpenWikiCommand,
OpenWikiOutputMode,
OpenWikiRunOptions,
} from "./agent/types.js";
} from "../agent/types.js";
import {
firstRunNoticePending,
FIRST_RUN_NOTICE_BODY,
FIRST_RUN_NOTICE_OPT_OUT,
FIRST_RUN_NOTICE_VERIFY,
withRunTelemetry,
type RunTelemetryContext,
} from "./telemetry/index.js";
} from "../telemetry/index.js";

// Register the last-resort handlers before any run starts, so a rejection that
// escapes every catch (e.g. a subagent error surfacing on the microtask queue) is
Expand Down
15 changes: 9 additions & 6 deletions src/commands.ts → src/cli/commands.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { isValidModelId, normalizeModelId } from "./constants.js";
import type { OpenWikiCommand } from "./agent/types.js";
import { resolveLanguage } from "./language.js";
import { isAuthProviderId } from "./auth/providers.js";
import type { AuthProviderId } from "./auth/types.js";
import { parseIngestionTarget, type IngestionTarget } from "./ingestion.js";
import { isValidModelId, normalizeModelId } from "../config/constants.js";
import type { OpenWikiCommand } from "../agent/types.js";
import { resolveLanguage } from "../platform/language.js";
import { isAuthProviderId } from "../auth/providers.js";
import type { AuthProviderId } from "../auth/types.js";
import {
parseIngestionTarget,
type IngestionTarget,
} from "../ingestion/ingestion.js";

export type HelpRow = {
label: string;
Expand Down
8 changes: 4 additions & 4 deletions src/startup.ts → src/cli/startup.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { shouldCheckUpdateNoop, getUpdateNoopStatus } from "./agent/utils.js";
import { readCodexTokensFromEnv } from "./agent/openai-chatgpt-oauth.js";
import { shouldCheckUpdateNoop, getUpdateNoopStatus } from "../agent/utils.js";
import { readCodexTokensFromEnv } from "../agent/openai-chatgpt-oauth.js";
import type { CliCommand } from "./commands.js";
import {
OPENAI_CHATGPT_ACCOUNT_ID_ENV_KEY,
Expand All @@ -12,8 +12,8 @@ import {
providerUsesOAuth,
resolveConfiguredProvider,
type OpenWikiProvider,
} from "./constants.js";
import { resolveExternalCliCredential } from "./external-cli-auth.js";
} from "../config/constants.js";
import { resolveExternalCliCredential } from "../auth/external-cli-auth.js";

type ResolveStartupCommandOptions = {
cwd?: string;
Expand Down
2 changes: 1 addition & 1 deletion src/constants.ts → src/config/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -928,4 +928,4 @@ export function isValidModelId(value: string): boolean {
// Derived at runtime from package.json (single source of truth) rather than
// hardcoded here; re-exported so existing importers of `OPENWIKI_VERSION` are
// unchanged.
export { OPENWIKI_VERSION } from "./version.js";
export { OPENWIKI_VERSION } from "../version.js";
4 changes: 2 additions & 2 deletions src/env.ts → src/config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ import {
OPENWIKI_PROVIDER_RETRY_ATTEMPTS_ENV_KEY,
resolveProviderRetryAttempts,
} from "./constants.js";
import { isFileNotFoundError } from "./fs-errors.js";
import { restrictDirToCurrentUser } from "./windows-acl.js";
import { isFileNotFoundError } from "../platform/fs-errors.js";
import { restrictDirToCurrentUser } from "../platform/windows-acl.js";

export const openWikiEnvDir = path.join(os.homedir(), ".openwiki");
export const openWikiEnvPath = path.join(openWikiEnvDir, ".env");
Expand Down
Loading