rigjs 4.0.6 → 4.0.8

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/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,120 @@ 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
+ * `include` defaults to `**` (everything) rig wiki is multimodal: Claude
102
+ * Read tool handles markdown / code / json natively, images and PDFs are
103
+ * read as visual / document inputs. The user can tighten this per-vault.
104
+ *
105
+ * `exclude` defaults to common binary-archive extensions whose contents
106
+ * can't be ingested without unpacking. Hidden directories (segments starting
107
+ * with `.`) and `.gitignore`'d files are skipped automatically by the
108
+ * scanner — no need to list them.
87
109
  */
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.');
110
+ function defaultVaultConfig(scope: string, rootRel: string): VaultConfig {
111
+ return {
112
+ name: scope,
113
+ root: rootRel,
114
+ include: ['**'],
115
+ exclude: [
116
+ '*.zip', '**/*.zip',
117
+ '*.tar', '**/*.tar',
118
+ '*.tar.gz', '**/*.tar.gz',
119
+ '*.tgz', '**/*.tgz',
120
+ '*.7z', '**/*.7z',
121
+ '*.rar', '**/*.rar',
122
+ ],
123
+ schedule: { scan: '0 */6 * * *', lint: '0 3 * * *', ingest: null },
124
+ ingestRules: [{ match: 'raw/**/*.*', mode: 'auto-on-new' }],
125
+ };
126
+ }
127
+
128
+ export default function wikiInit(scope?: string): void {
129
+ if (!scope || !scope.trim()) {
130
+ print.error('rig wiki init requires a scope.');
131
+ print.info('usage: rig wiki init <scope> (e.g. `rig wiki init personal` to ingest from ./personal/)');
132
+ print.info(`<scope> is an existing data subdir of the project. Vault metadata is auto-created at ./${VAULT_DIRNAME}/.`);
102
133
  process.exit(1);
103
134
  }
104
- const root = path.resolve(givenPath);
105
- const guard = guardPath(root, process.cwd());
135
+
136
+ const cwd = process.cwd();
137
+ const vaultDir = path.join(cwd, VAULT_DIRNAME);
138
+ const scopeAbs = path.resolve(cwd, scope);
139
+
140
+ // The scope must already exist — pointing the wiki at a missing dir would
141
+ // hide what is almost certainly a typo.
142
+ if (!fs.existsSync(scopeAbs) || !fs.statSync(scopeAbs).isDirectory()) {
143
+ print.error(`scope dir not found: ${scope}`);
144
+ print.info(`expected an existing data subdir at ${shortPath(scopeAbs)}`);
145
+ process.exit(1);
146
+ }
147
+ // The scope can't be (or contain) the vault dir itself.
148
+ if (scopeAbs === vaultDir || vaultDir.startsWith(scopeAbs + path.sep)) {
149
+ print.error(`scope cannot be or contain the vault dir (${VAULT_DIRNAME}/).`);
150
+ process.exit(1);
151
+ }
152
+
153
+ const guard = guardPath(vaultDir, cwd);
106
154
  if (!guard.ok) {
107
- print.error('refusing to initialize a vault at a hidden or gitignored path.');
155
+ print.error(`refusing to initialize the vault at a hidden or gitignored path.`);
108
156
  // eslint-disable-next-line no-console
109
- console.error(refusalMessage(root, guard));
157
+ console.error(refusalMessage(vaultDir, guard));
110
158
  process.exit(1);
111
159
  }
112
- fs.mkdirSync(root, { recursive: true });
113
160
 
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);
161
+ // If the vault already has a config, it must already be scoped to the
162
+ // same data dir — otherwise the user is trying to re-target an existing
163
+ // vault, which we won't do silently. Manual config edit only.
164
+ const cfgFile = vaultConfigPath(vaultDir);
165
+ if (fs.existsSync(cfgFile)) {
166
+ const existing = loadVaultConfig(vaultDir);
167
+ const existingRootAbs = existing?.root
168
+ ? path.resolve(vaultDir, existing.root)
169
+ : path.dirname(vaultDir);
170
+ if (existingRootAbs !== scopeAbs) {
171
+ print.error(`vault already initialized at ${shortPath(vaultDir)} for scope "${existing?.name ?? '?'}" (root: ${existing?.root ?? '..'}).`);
172
+ print.info(`to switch scopes, edit ${shortPath(cfgFile)} (name + root) by hand.`);
173
+ process.exit(1);
174
+ }
175
+ }
176
+
177
+ fs.mkdirSync(vaultDir, { recursive: true });
178
+ writeIfMissing(path.join(vaultDir, 'purpose.md'), PURPOSE_TMPL);
179
+ writeIfMissing(path.join(vaultDir, 'schema.md'), SCHEMA_TMPL);
180
+ writeIfMissing(path.join(vaultDir, 'index.md'), '# Index\n');
181
+ writeIfMissing(path.join(vaultDir, 'overview.md'), '# Overview\n');
182
+ writeIfMissing(path.join(vaultDir, 'log.md'), '# Log\n');
183
+ writeIfMissing(path.join(vaultDir, 'reviews.md'), '# Reviews\n');
184
+ writeIfMissing(path.join(vaultDir, '.gitignore'), GITIGNORE_TMPL);
121
185
 
122
- fs.mkdirSync(path.join(root, 'raw'), { recursive: true });
123
- writeIfMissing(path.join(root, 'raw', '.gitkeep'), '');
186
+ fs.mkdirSync(path.join(vaultDir, 'raw'), { recursive: true });
187
+ writeIfMissing(path.join(vaultDir, 'raw', '.gitkeep'), '');
124
188
 
125
- // Page tree lives at the vault root — no extra `wiki/` nesting.
126
189
  for (const sub of SUBDIRS) {
127
- const d = path.join(root, sub);
190
+ const d = path.join(vaultDir, sub);
128
191
  fs.mkdirSync(d, { recursive: true });
129
192
  writeIfMissing(path.join(d, '.gitkeep'), '');
130
193
  }
131
194
 
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)));
195
+ if (!fs.existsSync(cfgFile)) {
196
+ const rootRel = path.relative(vaultDir, scopeAbs);
197
+ saveVaultConfig(vaultDir, defaultVaultConfig(scope, rootRel));
137
198
  }
138
199
 
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.');
200
+ print.succeed(`vault initialized at ${shortPath(vaultDir)} (scope: ${scope})`);
201
+ print.info(`next: edit ${shortPath(path.join(vaultDir, 'purpose.md'))} to describe what this wiki is for.`);
202
+ print.info(`then run \`rig wiki scan\` from anywhere inside ${shortPath(cwd)} to see what will be ingested.`);
143
203
  }
144
204
 
145
205
  function writeIfMissing(file: string, content: string) {
146
206
  if (fs.existsSync(file)) return;
147
207
  fs.writeFileSync(file, content, 'utf8');
148
208
  }
209
+
210
+ function shortPath(p: string): string {
211
+ const home = os.homedir();
212
+ if (p.startsWith(home + path.sep)) return '~' + p.slice(home.length);
213
+ return p;
214
+ }
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.8",
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",