rigjs 4.0.6 → 4.0.7

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/lib/wiki/index.ts CHANGED
@@ -19,8 +19,8 @@ import { registerDaemonCommands } from './daemon';
19
19
  export function registerWikiCommands(program: any): void {
20
20
  const wiki = program.command('wiki').description('Karpathy-style LLM Wiki ops (macOS only in v1)');
21
21
 
22
- wiki.command('init <path>')
23
- .description('bootstrap a vault at <path> (recommended: `rig-wiki` at the project root)')
22
+ wiki.command('init <scope>')
23
+ .description('bootstrap a vault scoped to <scope>/ an existing data subdir of the project. Metadata is auto-created at ./rig-wiki/.')
24
24
  .action(wikiInit);
25
25
 
26
26
  wiki.command('scan')
package/lib/wiki/init.ts CHANGED
@@ -1,8 +1,31 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
+ import os from 'os';
3
4
  import print from '../print';
4
5
  import { guardPath, refusalMessage } from './pathGuard';
5
- import { saveVaultConfig, VaultConfig } from './config';
6
+ import { saveVaultConfig, loadVaultConfig, VaultConfig } from './config';
7
+ import { vaultConfigPath } from './paths';
8
+
9
+ /**
10
+ * `rig wiki init <scope>`
11
+ *
12
+ * The user runs this from a project root. The CWD is treated as the project
13
+ * (the conceptual "vault"); `<scope>` names a data subdir under it that the
14
+ * wiki should ingest from (e.g. `personal` for `<project>/personal/`).
15
+ *
16
+ * Vault metadata always lives at `<CWD>/rig-wiki/` (fixed name). The scope
17
+ * is recorded in `<CWD>/rig-wiki/.rig/config.yml` as the scan root, so the
18
+ * user's data dir stays untouched.
19
+ *
20
+ * $ cd overmind
21
+ * $ rig wiki init personal
22
+ * ⇒ creates overmind/rig-wiki/ with templates + .rig/config.yml
23
+ * ⇒ config.yml.root = "../personal", config.yml.name = "personal"
24
+ *
25
+ * Idempotent for the same scope. Errors if rig-wiki/ already exists with a
26
+ * different scope (manual `.rig/config.yml` edit required to switch).
27
+ */
28
+ const VAULT_DIRNAME = 'rig-wiki';
6
29
 
7
30
  const PURPOSE_TMPL = `# Purpose
8
31
 
@@ -57,12 +80,6 @@ const SCHEMA_TMPL = `# Schema
57
80
 
58
81
  const SUBDIRS = ['sources', 'entities', 'concepts', 'synthesis', 'queries'];
59
82
 
60
- // What lives inside the vault but must not enter git / Obsidian Sync:
61
- // - qmd's project-local vector cache (sqlite-vec, non-deterministic, rebuilds
62
- // locally with `rig wiki index` / `rig wiki rebuild`)
63
- // - lint reports (auto-regenerated)
64
- // - daemon proposal diffs (transient, per-machine)
65
- // - editor scratch
66
83
  const GITIGNORE_TMPL = `# rig wiki — local-only artifacts (do not commit)
67
84
  # qmd vector cache (sqlite-vec, machine-specific, rebuildable)
68
85
  .qmd/index.sqlite*
@@ -78,71 +95,107 @@ proposals/
78
95
  `;
79
96
 
80
97
  /**
81
- * Sensible defaults for a fresh vault. The user can edit
98
+ * Defaults for a freshly-scoped vault. The user can edit
82
99
  * `<vault>/.rig/config.yml` afterwards.
83
100
  *
84
- * Note: hidden directories (any path segment starting with `.`) and files
85
- * matched by the project's `.gitignore` are skipped automatically by the
86
- * scanner — there is no need to add `.git/**` or `node_modules/**` here.
101
+ * Hidden directories (segments starting with `.`) and `.gitignore`'d files
102
+ * are skipped automatically by the scanner no need to list them here.
87
103
  */
88
- const DEFAULT_VAULT_CONFIG = (vaultBasename: string): VaultConfig => ({
89
- name: vaultBasename,
90
- root: '..',
91
- include: ['**/*.md'],
92
- exclude: [`${vaultBasename}/**`],
93
- schedule: { scan: '0 */6 * * *', lint: '0 3 * * *', ingest: null },
94
- ingestRules: [{ match: 'raw/**/*.md', mode: 'auto-on-new' }],
95
- });
96
-
97
- export default function wikiInit(givenPath?: string): void {
98
- if (!givenPath || !givenPath.trim()) {
99
- print.error('rig wiki init requires a target subdirectory.');
100
- print.info('usage: rig wiki init <subdir> (recommended: `rig wiki init rig-wiki` at the project root)');
101
- print.info('refusing to default to CWD — that would litter the project root with vault templates.');
104
+ function defaultVaultConfig(scope: string, rootRel: string): VaultConfig {
105
+ return {
106
+ name: scope,
107
+ root: rootRel,
108
+ include: ['**/*.md'],
109
+ exclude: [],
110
+ schedule: { scan: '0 */6 * * *', lint: '0 3 * * *', ingest: null },
111
+ ingestRules: [{ match: 'raw/**/*.md', mode: 'auto-on-new' }],
112
+ };
113
+ }
114
+
115
+ export default function wikiInit(scope?: string): void {
116
+ if (!scope || !scope.trim()) {
117
+ print.error('rig wiki init requires a scope.');
118
+ print.info('usage: rig wiki init <scope> (e.g. `rig wiki init personal` to ingest from ./personal/)');
119
+ print.info(`<scope> is an existing data subdir of the project. Vault metadata is auto-created at ./${VAULT_DIRNAME}/.`);
120
+ process.exit(1);
121
+ }
122
+
123
+ const cwd = process.cwd();
124
+ const vaultDir = path.join(cwd, VAULT_DIRNAME);
125
+ const scopeAbs = path.resolve(cwd, scope);
126
+
127
+ // The scope must already exist — pointing the wiki at a missing dir would
128
+ // hide what is almost certainly a typo.
129
+ if (!fs.existsSync(scopeAbs) || !fs.statSync(scopeAbs).isDirectory()) {
130
+ print.error(`scope dir not found: ${scope}`);
131
+ print.info(`expected an existing data subdir at ${shortPath(scopeAbs)}`);
132
+ process.exit(1);
133
+ }
134
+ // The scope can't be (or contain) the vault dir itself.
135
+ if (scopeAbs === vaultDir || vaultDir.startsWith(scopeAbs + path.sep)) {
136
+ print.error(`scope cannot be or contain the vault dir (${VAULT_DIRNAME}/).`);
102
137
  process.exit(1);
103
138
  }
104
- const root = path.resolve(givenPath);
105
- const guard = guardPath(root, process.cwd());
139
+
140
+ const guard = guardPath(vaultDir, cwd);
106
141
  if (!guard.ok) {
107
- print.error('refusing to initialize a vault at a hidden or gitignored path.');
142
+ print.error(`refusing to initialize the vault at a hidden or gitignored path.`);
108
143
  // eslint-disable-next-line no-console
109
- console.error(refusalMessage(root, guard));
144
+ console.error(refusalMessage(vaultDir, guard));
110
145
  process.exit(1);
111
146
  }
112
- fs.mkdirSync(root, { recursive: true });
113
147
 
114
- writeIfMissing(path.join(root, 'purpose.md'), PURPOSE_TMPL);
115
- writeIfMissing(path.join(root, 'schema.md'), SCHEMA_TMPL);
116
- writeIfMissing(path.join(root, 'index.md'), '# Index\n');
117
- writeIfMissing(path.join(root, 'overview.md'), '# Overview\n');
118
- writeIfMissing(path.join(root, 'log.md'), '# Log\n');
119
- writeIfMissing(path.join(root, 'reviews.md'), '# Reviews\n');
120
- writeIfMissing(path.join(root, '.gitignore'), GITIGNORE_TMPL);
148
+ // If the vault already has a config, it must already be scoped to the
149
+ // same data dir — otherwise the user is trying to re-target an existing
150
+ // vault, which we won't do silently. Manual config edit only.
151
+ const cfgFile = vaultConfigPath(vaultDir);
152
+ if (fs.existsSync(cfgFile)) {
153
+ const existing = loadVaultConfig(vaultDir);
154
+ const existingRootAbs = existing?.root
155
+ ? path.resolve(vaultDir, existing.root)
156
+ : path.dirname(vaultDir);
157
+ if (existingRootAbs !== scopeAbs) {
158
+ print.error(`vault already initialized at ${shortPath(vaultDir)} for scope "${existing?.name ?? '?'}" (root: ${existing?.root ?? '..'}).`);
159
+ print.info(`to switch scopes, edit ${shortPath(cfgFile)} (name + root) by hand.`);
160
+ process.exit(1);
161
+ }
162
+ }
163
+
164
+ fs.mkdirSync(vaultDir, { recursive: true });
165
+ writeIfMissing(path.join(vaultDir, 'purpose.md'), PURPOSE_TMPL);
166
+ writeIfMissing(path.join(vaultDir, 'schema.md'), SCHEMA_TMPL);
167
+ writeIfMissing(path.join(vaultDir, 'index.md'), '# Index\n');
168
+ writeIfMissing(path.join(vaultDir, 'overview.md'), '# Overview\n');
169
+ writeIfMissing(path.join(vaultDir, 'log.md'), '# Log\n');
170
+ writeIfMissing(path.join(vaultDir, 'reviews.md'), '# Reviews\n');
171
+ writeIfMissing(path.join(vaultDir, '.gitignore'), GITIGNORE_TMPL);
121
172
 
122
- fs.mkdirSync(path.join(root, 'raw'), { recursive: true });
123
- writeIfMissing(path.join(root, 'raw', '.gitkeep'), '');
173
+ fs.mkdirSync(path.join(vaultDir, 'raw'), { recursive: true });
174
+ writeIfMissing(path.join(vaultDir, 'raw', '.gitkeep'), '');
124
175
 
125
- // Page tree lives at the vault root — no extra `wiki/` nesting.
126
176
  for (const sub of SUBDIRS) {
127
- const d = path.join(root, sub);
177
+ const d = path.join(vaultDir, sub);
128
178
  fs.mkdirSync(d, { recursive: true });
129
179
  writeIfMissing(path.join(d, '.gitkeep'), '');
130
180
  }
131
181
 
132
- // Seed `<vault>/.rig/config.yml` with sensible defaults. Idempotent: if the
133
- // user has already authored one, leave it alone.
134
- const vaultCfgFile = path.join(root, '.rig', 'config.yml');
135
- if (!fs.existsSync(vaultCfgFile)) {
136
- saveVaultConfig(root, DEFAULT_VAULT_CONFIG(path.basename(root)));
182
+ if (!fs.existsSync(cfgFile)) {
183
+ const rootRel = path.relative(vaultDir, scopeAbs);
184
+ saveVaultConfig(vaultDir, defaultVaultConfig(scope, rootRel));
137
185
  }
138
186
 
139
- print.succeed(`vault initialized at ${root}`);
140
- print.info('next: edit purpose.md + schema.md (and .rig/config.yml if scope differs from defaults).');
141
- print.info('discovery is automatic cd into this dir (or any subdir) and run `rig wiki *` commands.');
142
- print.info('on a new device, after cloning, run `rig wiki rebuild` to refresh local caches.');
187
+ print.succeed(`vault initialized at ${shortPath(vaultDir)} (scope: ${scope})`);
188
+ print.info(`next: edit ${shortPath(path.join(vaultDir, 'purpose.md'))} to describe what this wiki is for.`);
189
+ print.info(`then run \`rig wiki scan\` from anywhere inside ${shortPath(cwd)} to see what will be ingested.`);
143
190
  }
144
191
 
145
192
  function writeIfMissing(file: string, content: string) {
146
193
  if (fs.existsSync(file)) return;
147
194
  fs.writeFileSync(file, content, 'utf8');
148
195
  }
196
+
197
+ function shortPath(p: string): string {
198
+ const home = os.homedir();
199
+ if (p.startsWith(home + path.sep)) return '~' + p.slice(home.length);
200
+ return p;
201
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rigjs",
3
- "version": "4.0.6",
4
- "versionCode": 26052413,
3
+ "version": "4.0.7",
4
+ "versionCode": 26052414,
5
5
  "description": "A multi-repos dev tool based on yarn and git.Rigjs is intended to be the simplest way to develop,share and deliver codes between different developers or different projects.",
6
6
  "keywords": [
7
7
  "modular",