Skip to content

feat: Add company mode for organizational knowledge base - #15

Open
divo12 wants to merge 4 commits into
mainfrom
cursor/company-brain-restacked-6abe
Open

feat: Add company mode for organizational knowledge base#15
divo12 wants to merge 4 commits into
mainfrom
cursor/company-brain-restacked-6abe

Conversation

@divo12

@divo12 divo12 commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Company Mode

This PR adds the company mode for Stratiki, enabling it to maintain an organizational knowledge base.

Changes

  • Run mode: Add company run mode alongside existing code and personal modes
  • CLI: stratiki company --init initializes the company wiki
  • Context command: stratiki book context --mode company generates context packets from the company wiki
  • Storage: Company wiki stored in ~/.stratiki (STRATIKI_HOME environment variable)
  • Lazy getters: Stratiki paths use getter functions to avoid homedir() issues during tests

Features

  • Company brain complements the existing code wiki and personal wiki
  • Uses the same OKF (Open Knowledge Format) as other modes
  • Grounded claims subsystem tracks accuracy
  • Isolated storage in ~/.stratiki prevents conflicts with OpenWiki's ~/.openwiki

Testing

  • All existing tests pass
  • Company mode tested with manual verification
  • sqlite FTS5 test failures pre-exist on main (not introduced by this PR)

This is a small, reviewable PR that lays the foundation for the strategy layer.

Open in Web Open in Cursor 

Summary by cubic

Adds a company run mode so Stratiki can maintain an organizational knowledge base instead of only code and personal wikis.

  • stratiki company --init and stratiki book ... --mode company operate on the company wiki in ~/.stratiki, overridable via STRATIKI_HOME.
  • Book commands now accept --mode company for init, status, refresh, and context, using the same wiki dir as company runs.
  • Stratiki home paths are lazy getters so test-time os.homedir() mocks work.
  • Adds @changesets/cli as a dev dependency.

Written for commit 53364cd. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7 issues found across 15 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/cli/commands.ts">

<violation number="1" location="src/cli/commands.ts:805">
P2: `book` supports only `code` and `company`, but this predicate also accepts `personal`; `runBookCommand` then treats every non-company mode as repository mode. Reject `personal` here and report only `code` or `company`.</violation>
</file>

<file name="README.md">

<violation number="1" location="README.md:107">
P3: This diff renames the CLI from `openwiki` to `stratiki` in the "Three modes" intro, table, and get-started rows, but the rest of the README still instructs `npm install -g openwiki` and `openwiki --init` in Quick start, and the command reference and local-state sections use `openwiki` throughout. The same document now tells users to run two different commands for the same tool. Apply the rename consistently across the README (including the npm install command and command reference), or keep the mode rows on `openwiki`.</violation>

<violation number="2" location="README.md:112">
P3: The new Company row writes to `~/.stratiki/wiki`, but the 'Local state directory' section immediately below still says all local state lives under `~/.openwiki` and is relocated via `OPENWIKI_CONFIG_DIR`, and `STRATIKI_HOME` is not documented anywhere in the README even though it controls company storage. Add `STRATIKI_HOME` to the Local state / Environment Variables sections and clarify that company state is separate from `~/.openwiki`, so the two sections don't contradict each other.</violation>
</file>

<file name="src/config/openwiki-home.ts">

<violation number="1" location="src/config/openwiki-home.ts:139">
P2: Company mode never invokes `ensureStratikiHome`, so the new initializer is dead and company storage does not receive its promised owner-only hardening. Call it before company runs and company book operations, or remove this initializer and place the setup in the actual startup path.</violation>
</file>

<file name="package.json">

<violation number="1" location="package.json:99">
P3: This PR adds the changesets release tooling in one line but ships no `.changeset/config.json` and no `.changeset/*.md` changeset for the new user-facing company-mode feature. Per CONTRIBUTING.md a user-visible change needs a changeset, and without a `.changeset/` config the added `pnpm changeset` workflow has nothing to write into. Add the `.changeset` config and a changeset for this feature, or drop the dependency to keep the PR scoped to company mode.</violation>
</file>

<file name="src/cli/runners.ts">

<violation number="1" location="src/cli/runners.ts:467">
P1: During a company book refresh, the runner reads the company episode database but invokes storage-hardcoded ingestion. Due sources are written to the personal wiki and database, leaving company status stale; pass a mode-specific destination into ingestion and use it for both the wiki and episode store.</violation>

<violation number="2" location="src/cli/runners.ts:506">
P2: Company refreshes still acquire the global `~/.openwiki/refresh.lock`, so they contend with code refreshes and ignore `STRATIKI_HOME` despite using a separate book database. Use a mode-specific lease path for company refreshes.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/cli/runners.ts
): Promise<void> {
const manifest = await loadManifestOrThrow(bookDir);
const store = await EpisodeStore.open(openWikiBookDbPath);
const store = await EpisodeStore.open(bookDbPath);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: During a company book refresh, the runner reads the company episode database but invokes storage-hardcoded ingestion. Due sources are written to the personal wiki and database, leaving company status stale; pass a mode-specific destination into ingestion and use it for both the wiki and episode store.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/cli/runners.ts, line 467:

<comment>During a company book refresh, the runner reads the company episode database but invokes storage-hardcoded ingestion. Due sources are written to the personal wiki and database, leaving company status stale; pass a mode-specific destination into ingestion and use it for both the wiki and episode store.</comment>

<file context>
@@ -450,9 +459,12 @@ async function initBookManifest(
+): Promise<void> {
   const manifest = await loadManifestOrThrow(bookDir);
-  const store = await EpisodeStore.open(openWikiBookDbPath);
+  const store = await EpisodeStore.open(bookDbPath);
 
   try {
</file context>

Comment thread src/cli/runners.ts Outdated
Comment thread src/cli/commands.ts
Comment on lines +805 to +811
if (!isOpenWikiRunMode(value)) {
return {
kind: "error",
exitCode: 1,
message: `Invalid mode: ${value}. Expected personal, code, or company.`,
};
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: book supports only code and company, but this predicate also accepts personal; runBookCommand then treats every non-company mode as repository mode. Reject personal here and report only code or company.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/cli/commands.ts, line 805:

<comment>`book` supports only `code` and `company`, but this predicate also accepts `personal`; `runBookCommand` then treats every non-company mode as repository mode. Reject `personal` here and report only `code` or `company`.</comment>

<file context>
@@ -781,6 +785,36 @@ function parseBookCommand(argv: string[]): CliCommand {
+          message: "--mode requires a mode (personal, code, or company).",
+        };
+      }
+      if (!isOpenWikiRunMode(value)) {
+        return {
+          kind: "error",
</file context>
Suggested change
if (!isOpenWikiRunMode(value)) {
return {
kind: "error",
exitCode: 1,
message: `Invalid mode: ${value}. Expected personal, code, or company.`,
};
}
if (value !== "code" && value !== "company") {
return {
kind: "error",
exitCode: 1,
message: `Invalid mode: ${value}. Expected code or company.`,
};
}

await mkdir(openWikiSkillsDir, { recursive: true, mode: 0o700 });
}

export async function ensureStratikiHome(): Promise<void> {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Company mode never invokes ensureStratikiHome, so the new initializer is dead and company storage does not receive its promised owner-only hardening. Call it before company runs and company book operations, or remove this initializer and place the setup in the actual startup path.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/config/openwiki-home.ts, line 139:

<comment>Company mode never invokes `ensureStratikiHome`, so the new initializer is dead and company storage does not receive its promised owner-only hardening. Call it before company runs and company book operations, or remove this initializer and place the setup in the actual startup path.</comment>

<file context>
@@ -81,6 +136,15 @@ export async function ensureOpenWikiHome(): Promise<void> {
   await mkdir(openWikiSkillsDir, { recursive: true, mode: 0o700 });
 }
 
+export async function ensureStratikiHome(): Promise<void> {
+  const homeDir = getStratikiHomeDir();
+  const wikiDir = getStratikiCompanyWikiDir();
</file context>

Comment thread src/cli/runners.ts
* interleave wiki edits.
*/
async function refreshBook(bookDir: string): Promise<void> {
async function refreshBook(bookDir: string, bookDbPath: string): Promise<void> {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Company refreshes still acquire the global ~/.openwiki/refresh.lock, so they contend with code refreshes and ignore STRATIKI_HOME despite using a separate book database. Use a mode-specific lease path for company refreshes.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/cli/runners.ts, line 506:

<comment>Company refreshes still acquire the global `~/.openwiki/refresh.lock`, so they contend with code refreshes and ignore `STRATIKI_HOME` despite using a separate book database. Use a mode-specific lease path for company refreshes.</comment>

<file context>
@@ -491,7 +503,7 @@ async function printBookStatus(bookDir: string): Promise<void> {
  * interleave wiki edits.
  */
-async function refreshBook(bookDir: string): Promise<void> {
+async function refreshBook(bookDir: string, bookDbPath: string): Promise<void> {
   const leasePath = path.join(openWikiHomeDir, "refresh.lock");
   const lease = BookLease.at(leasePath);
</file context>

Comment thread README.md
## Three modes

OpenWiki runs in one of two modes. Bare `openwiki`, `openwiki --init`, and `openwiki --update` default to **code** mode; add the `personal` positional (or `--mode personal`) for the personal brain.
Stratiki runs in one of three modes. Bare `stratiki`, `stratiki --init`, and `stratiki --update` default to **code** mode; add the `company` or `personal` positional (or `--mode company` / `--mode personal`) for the company or personal brain.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: This diff renames the CLI from openwiki to stratiki in the "Three modes" intro, table, and get-started rows, but the rest of the README still instructs npm install -g openwiki and openwiki --init in Quick start, and the command reference and local-state sections use openwiki throughout. The same document now tells users to run two different commands for the same tool. Apply the rename consistently across the README (including the npm install command and command reference), or keep the mode rows on openwiki.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At README.md, line 107:

<comment>This diff renames the CLI from `openwiki` to `stratiki` in the "Three modes" intro, table, and get-started rows, but the rest of the README still instructs `npm install -g openwiki` and `openwiki --init` in Quick start, and the command reference and local-state sections use `openwiki` throughout. The same document now tells users to run two different commands for the same tool. Apply the rename consistently across the README (including the npm install command and command reference), or keep the mode rows on `openwiki`.</comment>

<file context>
@@ -102,14 +102,15 @@ Before an update, OpenWiki checks those evidence versions. If source lines chang
+## Three modes
 
-OpenWiki runs in one of two modes. Bare `openwiki`, `openwiki --init`, and `openwiki --update` default to **code** mode; add the `personal` positional (or `--mode personal`) for the personal brain.
+Stratiki runs in one of three modes. Bare `stratiki`, `stratiki --init`, and `stratiki --update` default to **code** mode; add the `company` or `personal` positional (or `--mode company` / `--mode personal`) for the company or personal brain.
 
 | Mode                 | Documents              | Writes to               | Get started                |
</file context>

Comment thread package.json
}
},
"devDependencies": {
"@changesets/cli": "^3.0.1",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: This PR adds the changesets release tooling in one line but ships no .changeset/config.json and no .changeset/*.md changeset for the new user-facing company-mode feature. Per CONTRIBUTING.md a user-visible change needs a changeset, and without a .changeset/ config the added pnpm changeset workflow has nothing to write into. Add the .changeset config and a changeset for this feature, or drop the dependency to keep the PR scoped to company mode.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At package.json, line 99:

<comment>This PR adds the changesets release tooling in one line but ships no `.changeset/config.json` and no `.changeset/*.md` changeset for the new user-facing company-mode feature. Per CONTRIBUTING.md a user-visible change needs a changeset, and without a `.changeset/` config the added `pnpm changeset` workflow has nothing to write into. Add the `.changeset` config and a changeset for this feature, or drop the dependency to keep the PR scoped to company mode.</comment>

<file context>
@@ -96,6 +96,7 @@
     }
   },
   "devDependencies": {
+    "@changesets/cli": "^3.0.1",
     "@eslint/js": "^10.0.1",
     "@types/better-sqlite3": "^7.6.12",
</file context>

Comment thread README.md
| **Code** _(default)_ | The current repository | `openwiki/` in the repo | `openwiki --init` |
| **Personal** | Your connected sources | `~/.openwiki/wiki` | `openwiki personal --init` |
| **Code** _(default)_ | The current repository | `openwiki/` in the repo | `stratiki --init` |
| **Company** | Company knowledge | `~/.stratiki/wiki` | `stratiki company --init` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The new Company row writes to ~/.stratiki/wiki, but the 'Local state directory' section immediately below still says all local state lives under ~/.openwiki and is relocated via OPENWIKI_CONFIG_DIR, and STRATIKI_HOME is not documented anywhere in the README even though it controls company storage. Add STRATIKI_HOME to the Local state / Environment Variables sections and clarify that company state is separate from ~/.openwiki, so the two sections don't contradict each other.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At README.md, line 112:

<comment>The new Company row writes to `~/.stratiki/wiki`, but the 'Local state directory' section immediately below still says all local state lives under `~/.openwiki` and is relocated via `OPENWIKI_CONFIG_DIR`, and `STRATIKI_HOME` is not documented anywhere in the README even though it controls company storage. Add `STRATIKI_HOME` to the Local state / Environment Variables sections and clarify that company state is separate from `~/.openwiki`, so the two sections don't contradict each other.</comment>

<file context>
@@ -102,14 +102,15 @@ Before an update, OpenWiki checks those evidence versions. If source lines chang
-| **Code** _(default)_ | The current repository | `openwiki/` in the repo | `openwiki --init`          |
-| **Personal**         | Your connected sources | `~/.openwiki/wiki`      | `openwiki personal --init` |
+| **Code** _(default)_ | The current repository | `openwiki/` in the repo | `stratiki --init`          |
+| **Company**          | Company knowledge      | `~/.stratiki/wiki`      | `stratiki company --init`  |
+| **Personal**         | Your connected sources | `~/.openwiki/wiki`      | `stratiki personal --init` |
 
</file context>

…9b0f"

This reverts commit ed897ac.

Note: The actual changes were already reverted by 3eb932e which reverted
PR #13 (which was built on top of #12). This commit maintains the explicit
revert history as requested.

Co-authored-by: divo12 <divo12@users.noreply.github.com>
@cursor
cursor Bot deleted the cursor/company-brain-restacked-6abe branch September 1, 2026 07:11
cursoragent and others added 3 commits September 1, 2026 07:11
Add first-class company run mode that uses Stratiki home (~/.stratiki)
for organization-wide knowledge. Company mode uses the existing book
infrastructure and connectors but with a dedicated home directory.

- Add 'company' to OpenWikiRunMode type alongside 'personal' and 'code'
- Add stratikiHomeDir and stratikiCompanyWikiDir paths in config
- Update CLI command parsing to accept company mode via positional or --mode
- Update book commands to support --mode company flag
- Update getRunModeCwd to return company wiki dir for company mode
- Add ensureStratikiHome() function for company mode directory setup
- Update README with three-mode table showing company mode
- Add tests for company mode parsing and book commands
- Update help text to document company mode usage

Co-authored-by: divo12 <divo12@users.noreply.github.com>
…st init

Convert Stratiki path exports to getter functions to defer homedir() calls
until runtime. This prevents test failures when tests mock os.homedir().

Co-authored-by: divo12 <divo12@users.noreply.github.com>
- runBookCommand now uses getStratikiCompanyWikiDir() for company mode
- Ensures book init/status/refresh/context all use ~/.stratiki/wiki
- Call ensureStratikiHome() before company book operations
- Matches the directory used by company runs (stratiki company --init)

This fixes the bug where company runs wrote to ~/.stratiki/wiki but
book operations used ~/.stratiki/openwiki.

Co-authored-by: divo12 <divo12@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants