rigjs 4.0.18 → 4.1.0
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/.claude/skills/rig-cicd/SKILL.md +288 -0
- package/.claude/skills/rig-package/SKILL.md +162 -0
- package/RIG_CICD_SKILL.md +288 -0
- package/RIG_CREW_SKILL.md +50 -50
- package/RIG_PACKAGE_SKILL.md +162 -0
- package/built/index.js +346 -259
- package/lib/classes/cicd/CICD.ts +17 -0
- package/lib/classes/cicd/Deploy/ESA.ts +117 -0
- package/lib/crew/ask.ts +3 -3
- package/lib/crew/board.ts +14 -14
- package/lib/crew/config.ts +2 -2
- package/lib/crew/dispatchCommand.ts +58 -0
- package/lib/crew/doctor.ts +1 -1
- package/lib/crew/engine.test.ts +73 -0
- package/lib/crew/engine.ts +103 -0
- package/lib/crew/index.ts +48 -27
- package/lib/crew/init.ts +3 -3
- package/lib/crew/{inbox.ts → pendingQuestions.ts} +6 -7
- package/lib/crew/project.ts +1 -1
- package/lib/crew/role.ts +3 -3
- package/lib/crew/runtime.test.ts +160 -0
- package/lib/crew/runtime.ts +192 -0
- package/lib/crew/status.ts +4 -4
- package/lib/crew/stub.ts +2 -2
- package/lib/crew/task.ts +3 -3
- package/lib/crew/vault.ts +14 -14
- package/lib/init/index.ts +16 -9
- package/lib/publish/index.ts +78 -1
- package/lib/wiki/lint.ts +23 -1
- package/package.json +11 -3
- package/scripts/sync-skill.mjs +2 -0
- package/skills.md +5 -1
- package/lib/utils/redact.test.ts +0 -43
package/lib/publish/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import CICD from '@/classes/cicd/CICD';
|
|
1
|
+
import CICD, { DeployTarget } from '@/classes/cicd/CICD';
|
|
2
2
|
import CICDCmd from '@/classes/cicd/CICDCmd';
|
|
3
3
|
import CDN from '@/classes/cicd/Deploy/CDN';
|
|
4
|
+
import ESA from '@/classes/cicd/Deploy/ESA';
|
|
4
5
|
|
|
5
6
|
const delay = async (ms: number) => {
|
|
6
7
|
await new Promise((resolve) => {
|
|
@@ -69,6 +70,76 @@ const refreshCache = async (urls: string[], cdn: CDN) => {
|
|
|
69
70
|
console.log('RefreshCache Done');
|
|
70
71
|
};
|
|
71
72
|
|
|
73
|
+
/**
|
|
74
|
+
* ESA publish path (edge_provider === 'esa'). Sets back-to-origin URI rewrite
|
|
75
|
+
* rules per domain, then purges the entry URLs.
|
|
76
|
+
*
|
|
77
|
+
* Mapping vs CDN: hash mode only needs the entry page rewritten to
|
|
78
|
+
* `/<deployDir>/index.html` (publicPath already carries deployDir so static
|
|
79
|
+
* files resolve at the OSS origin directly). history/mpa additionally prepend
|
|
80
|
+
* deployDir for static files and fall back to the entry for extension-less
|
|
81
|
+
* routes — those dynamic-rewrite expressions need validation on a live ESA site.
|
|
82
|
+
*/
|
|
83
|
+
const publishViaEsa = async (
|
|
84
|
+
cicd: CICD,
|
|
85
|
+
cicdCmd: CICDCmd,
|
|
86
|
+
target: DeployTarget
|
|
87
|
+
) => {
|
|
88
|
+
const esa = new ESA(target);
|
|
89
|
+
if (!cicdCmd.endpoints || cicdCmd.endpoints.length === 0) {
|
|
90
|
+
throw new Error('Endpoints.length Can Not Be 0!');
|
|
91
|
+
}
|
|
92
|
+
const purgeByDomain: { [domain: string]: string[] } = {};
|
|
93
|
+
for (const endpoint of cicdCmd.endpoints) {
|
|
94
|
+
const deployDir = endpoint.deployDir.replace(/\\/g, '/');
|
|
95
|
+
const webEntryPath = endpoint.web_entry_path || target.web_entry_path || '/';
|
|
96
|
+
const ruleBase = `rig-${deployDir.replace(/[^\w]+/g, '-')}`.replace(
|
|
97
|
+
/-+/g,
|
|
98
|
+
'-'
|
|
99
|
+
);
|
|
100
|
+
for (const domain of endpoint.domains) {
|
|
101
|
+
if (cicd.web_type === 'hash') {
|
|
102
|
+
await esa.setRewriteRule(
|
|
103
|
+
domain,
|
|
104
|
+
`${ruleBase}-entry`,
|
|
105
|
+
`(http.request.uri.path eq "${webEntryPath}")`,
|
|
106
|
+
'static',
|
|
107
|
+
`/${deployDir}/index.html`,
|
|
108
|
+
1
|
|
109
|
+
);
|
|
110
|
+
} else {
|
|
111
|
+
await esa.setRewriteRule(
|
|
112
|
+
domain,
|
|
113
|
+
`${ruleBase}-file`,
|
|
114
|
+
`(http.request.uri.path.extension ne "")`,
|
|
115
|
+
'dynamic',
|
|
116
|
+
`concat("/${deployDir}", http.request.uri.path)`,
|
|
117
|
+
1
|
|
118
|
+
);
|
|
119
|
+
await esa.setRewriteRule(
|
|
120
|
+
domain,
|
|
121
|
+
`${ruleBase}-entry`,
|
|
122
|
+
'true',
|
|
123
|
+
cicd.web_type === 'mpa' ? 'dynamic' : 'static',
|
|
124
|
+
cicd.web_type === 'mpa'
|
|
125
|
+
? `concat("/${deployDir}", http.request.uri.path, ".html")`
|
|
126
|
+
: `/${deployDir}/index.html`,
|
|
127
|
+
2
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
if (!purgeByDomain[domain]) {
|
|
131
|
+
purgeByDomain[domain] = [];
|
|
132
|
+
}
|
|
133
|
+
purgeByDomain[domain].push(`https://${domain}${webEntryPath}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
for (const domain of Object.keys(purgeByDomain)) {
|
|
137
|
+
console.log(`ESA purge ${domain}:`, purgeByDomain[domain]);
|
|
138
|
+
await esa.purgeCache(domain, purgeByDomain[domain]);
|
|
139
|
+
}
|
|
140
|
+
console.log('ESA rewrite rules + purge done');
|
|
141
|
+
};
|
|
142
|
+
|
|
72
143
|
export default async (cmd: any) => {
|
|
73
144
|
try {
|
|
74
145
|
const rewriteConfigs: {
|
|
@@ -99,6 +170,12 @@ export default async (cmd: any) => {
|
|
|
99
170
|
? cicdCmd.cicd.target[0]
|
|
100
171
|
: cicdCmd.cicd.target;
|
|
101
172
|
|
|
173
|
+
if (target.edge_provider === 'esa') {
|
|
174
|
+
await publishViaEsa(cicd, cicdCmd, target);
|
|
175
|
+
console.log('Publish Done-----');
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
102
179
|
const cdn = new CDN(target);
|
|
103
180
|
const urls: string[] = [];
|
|
104
181
|
if (!cicdCmd.endpoints || cicdCmd.endpoints.length === 0) {
|
package/lib/wiki/lint.ts
CHANGED
|
@@ -42,6 +42,7 @@ interface Findings {
|
|
|
42
42
|
const REQUIRED_KEYS = ['type', 'sources', 'ingested-at', 'last-updated'] as const;
|
|
43
43
|
const SOURCE_EXTRA_KEYS = ['source-sha', 'source-path'] as const;
|
|
44
44
|
const WIKI_SUBDIRS = ['sources', 'entities', 'concepts', 'synthesis', 'queries'] as const;
|
|
45
|
+
const TOP_LEVEL_WIKILINK_TARGETS = ['index', 'overview', 'log', 'reviews', 'purpose', 'schema'] as const;
|
|
45
46
|
|
|
46
47
|
export default async function wikiLint(opts: LintOpts): Promise<void> {
|
|
47
48
|
const target = requireVault();
|
|
@@ -89,6 +90,10 @@ function lintOne(wiki: WikiEntry): Findings {
|
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
const slugToRel = new Map<string, string>();
|
|
93
|
+
for (const slug of TOP_LEVEL_WIKILINK_TARGETS) {
|
|
94
|
+
const rel = `${slug}.md`;
|
|
95
|
+
if (fs.existsSync(path.join(wiki.path, rel))) slugToRel.set(slug, rel);
|
|
96
|
+
}
|
|
92
97
|
for (const p of pages) slugToRel.set(p.slug, p.rel);
|
|
93
98
|
|
|
94
99
|
const linkedSlugs = new Set<string>();
|
|
@@ -103,7 +108,7 @@ function lintOne(wiki: WikiEntry): Findings {
|
|
|
103
108
|
}
|
|
104
109
|
const sourcePath = String(p.frontmatter['source-path'] || '');
|
|
105
110
|
if (sourcePath) {
|
|
106
|
-
const abs =
|
|
111
|
+
const abs = resolveSourcePath(wiki, sourcePath);
|
|
107
112
|
if (!fs.existsSync(abs)) {
|
|
108
113
|
f.missingRawSource.push({ rel: p.rel, sourcePath });
|
|
109
114
|
} else {
|
|
@@ -188,6 +193,23 @@ function extractWikilinks(body: string): string[] {
|
|
|
188
193
|
return out;
|
|
189
194
|
}
|
|
190
195
|
|
|
196
|
+
function resolveSourcePath(wiki: WikiEntry, sourcePath: string): string {
|
|
197
|
+
const obsidian = parseObsidianFilePath(sourcePath);
|
|
198
|
+
if (obsidian) return path.resolve(path.dirname(wiki.path), obsidian);
|
|
199
|
+
return path.isAbsolute(sourcePath) ? sourcePath : path.resolve(wiki.path, sourcePath);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function parseObsidianFilePath(sourcePath: string): string | null {
|
|
203
|
+
if (!sourcePath.startsWith('obsidian://open?')) return null;
|
|
204
|
+
try {
|
|
205
|
+
const url = new URL(sourcePath);
|
|
206
|
+
const file = url.searchParams.get('file');
|
|
207
|
+
return file && file.trim() ? file : null;
|
|
208
|
+
} catch {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
191
213
|
function sha256(file: string): string {
|
|
192
214
|
return crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex');
|
|
193
215
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rigjs",
|
|
3
|
-
"version": "4.0
|
|
4
|
-
"versionCode":
|
|
3
|
+
"version": "4.1.0",
|
|
4
|
+
"versionCode": 26053101,
|
|
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",
|
|
@@ -36,9 +36,13 @@
|
|
|
36
36
|
"doc",
|
|
37
37
|
"scripts",
|
|
38
38
|
".claude/skills/rig-wiki",
|
|
39
|
+
".claude/skills/rig-package",
|
|
40
|
+
".claude/skills/rig-cicd",
|
|
39
41
|
".claude-plugin",
|
|
40
42
|
"RIG_WIKI_SKILL.md",
|
|
41
43
|
"RIG_CREW_SKILL.md",
|
|
44
|
+
"RIG_PACKAGE_SKILL.md",
|
|
45
|
+
"RIG_CICD_SKILL.md",
|
|
42
46
|
"skills.md",
|
|
43
47
|
"index.js",
|
|
44
48
|
"README.md",
|
|
@@ -56,13 +60,17 @@
|
|
|
56
60
|
"t": "node lib/rig/index.js tag",
|
|
57
61
|
"deliver": "node scripts/publish.mjs",
|
|
58
62
|
"deliver:alpha": "rig tag && yarn build && node scripts/publish.mjs --tag alpha",
|
|
59
|
-
"build": "esbuild lib/rig/index.ts --platform=node --bundle --sourcemap=inline --minify --outfile=built/index.js --external:shelljs --external:better-sqlite3 --external:bindings --external:proxy-agent --external:@tobilu/qmd",
|
|
63
|
+
"build": "esbuild lib/rig/index.ts --platform=node --bundle --sourcemap=inline --minify --outfile=built/index.js --external:shelljs --external:better-sqlite3 --external:bindings --external:proxy-agent --external:@tobilu/qmd && yarn scan:built",
|
|
64
|
+
"scan:built": "GOMAXPROCS=2 gitleaks detect --source built --no-git --no-banner --redact --exit-code 1",
|
|
60
65
|
"version:code": "node scripts/version-code.mjs",
|
|
61
66
|
"version:code:peek": "node scripts/version-code.mjs --peek",
|
|
62
67
|
"prepublishOnly": "node scripts/version-code.mjs && node scripts/sync-skill.mjs && yarn build",
|
|
63
68
|
"postinstall": "node scripts/postinstall.mjs"
|
|
64
69
|
},
|
|
65
70
|
"dependencies": {
|
|
71
|
+
"@alicloud/esa20240910": "^3.1.2",
|
|
72
|
+
"@alicloud/openapi-client": "^0.4.15",
|
|
73
|
+
"@alicloud/tea-util": "^1.4.11",
|
|
66
74
|
"@tobilu/qmd": "~2.5.2",
|
|
67
75
|
"@types/ali-oss": "^6.16.3",
|
|
68
76
|
"@types/json5": "^2.2.0",
|
package/scripts/sync-skill.mjs
CHANGED
|
@@ -14,6 +14,8 @@ const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'
|
|
|
14
14
|
|
|
15
15
|
const skills = [
|
|
16
16
|
['RIG_WIKI_SKILL.md', '.claude/skills/rig-wiki/SKILL.md'],
|
|
17
|
+
['RIG_PACKAGE_SKILL.md', '.claude/skills/rig-package/SKILL.md'],
|
|
18
|
+
['RIG_CICD_SKILL.md', '.claude/skills/rig-cicd/SKILL.md'],
|
|
17
19
|
];
|
|
18
20
|
|
|
19
21
|
for (const [srcRel, destRel] of skills) {
|
package/skills.md
CHANGED
|
@@ -8,6 +8,8 @@ This page is the skill index for the `rigjs` package. The root `README.md` keeps
|
|
|
8
8
|
|---|---|---|---|---|
|
|
9
9
|
| `rig-wiki` | [`RIG_WIKI_SKILL.md`](./RIG_WIKI_SKILL.md) | [`.claude/skills/rig-wiki/SKILL.md`](./.claude/skills/rig-wiki/SKILL.md) | `rig wiki *` | Karpathy-style LLM wiki operations: scan, fetch, ingest, query, lint, rebuild. |
|
|
10
10
|
| `rig-crew` | [`RIG_CREW_SKILL.md`](./RIG_CREW_SKILL.md) | (none — vault-level guidance) | `rig crew *` | File-backed, Leader-first multi-agent coordination over an Obsidian vault. |
|
|
11
|
+
| `rig-package` | [`RIG_PACKAGE_SKILL.md`](./RIG_PACKAGE_SKILL.md) | [`.claude/skills/rig-package/SKILL.md`](./.claude/skills/rig-package/SKILL.md) | `rig init` / `install` / `add` / `dev` / `tag` | Git-tag + ssh package manager that replaces a private npm registry; documents every `package.rig.json5#dependencies` field. |
|
|
12
|
+
| `rig-cicd` | [`RIG_CICD_SKILL.md`](./RIG_CICD_SKILL.md) | [`.claude/skills/rig-cicd/SKILL.md`](./.claude/skills/rig-cicd/SKILL.md) | `rig build` / `deploy` / `publish` | Aliyun OSS + CDN static-site CI/CD; one bucket → many sites via CDN URI rewrites set during `rig publish`. Supports hash, history, mpa, pre-built HTML dirs. |
|
|
11
13
|
|
|
12
14
|
`rig-crew` is intentionally not copied into the rigjs package's own `.claude/skills/`. Its instructions belong at the Vault level (the project that uses crew), not at the tool level (rigjs itself).
|
|
13
15
|
|
|
@@ -89,6 +91,8 @@ Canonical skill files live at the package root:
|
|
|
89
91
|
|
|
90
92
|
- [`RIG_WIKI_SKILL.md`](./RIG_WIKI_SKILL.md)
|
|
91
93
|
- [`RIG_CREW_SKILL.md`](./RIG_CREW_SKILL.md)
|
|
94
|
+
- [`RIG_PACKAGE_SKILL.md`](./RIG_PACKAGE_SKILL.md)
|
|
95
|
+
- [`RIG_CICD_SKILL.md`](./RIG_CICD_SKILL.md)
|
|
92
96
|
|
|
93
97
|
A package-internal mirror lives under `.claude/skills/` so the rig package itself (when checked out by another agent) can read its own skills:
|
|
94
98
|
|
|
@@ -96,7 +100,7 @@ A package-internal mirror lives under `.claude/skills/` so the rig package itsel
|
|
|
96
100
|
node scripts/sync-skill.mjs
|
|
97
101
|
```
|
|
98
102
|
|
|
99
|
-
`prepublishOnly` runs the sync script before packaging.
|
|
103
|
+
`prepublishOnly` runs the sync script before packaging. The plugin-copy set covers `rig-wiki`, `rig-package`, and `rig-cicd`; `rig-crew` remains Vault-level guidance and has no in-package `.claude/skills/` copy.
|
|
100
104
|
|
|
101
105
|
## Documentation Policy
|
|
102
106
|
|
package/lib/utils/redact.test.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { maskSecret, redactTarget, redactCdnUrl } from '@/utils/redact';
|
|
2
|
-
|
|
3
|
-
test('maskSecret keeps a head+tail hint for long secrets', () => {
|
|
4
|
-
const ak = 'LTAI5t9GjXQc7itTohf68ZLq';
|
|
5
|
-
const masked = maskSecret(ak);
|
|
6
|
-
expect(masked).not.toContain('GjXQc7it'); // no middle bytes
|
|
7
|
-
expect(masked.startsWith('LTAI')).toBe(true);
|
|
8
|
-
expect(masked.endsWith('8ZLq')).toBe(true);
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
test('maskSecret returns plain mask for short / empty input', () => {
|
|
12
|
-
expect(maskSecret('')).toBe('');
|
|
13
|
-
expect(maskSecret(undefined)).toBe('');
|
|
14
|
-
expect(maskSecret('abc')).toBe('****');
|
|
15
|
-
expect(maskSecret('abcdefgh')).toBe('****');
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
test('redactTarget masks access_key / access_secret only', () => {
|
|
19
|
-
const out = redactTarget({
|
|
20
|
-
id: 'alicloud',
|
|
21
|
-
type: 'alicloud',
|
|
22
|
-
bucket: 'my-bucket',
|
|
23
|
-
region: 'oss-ap-southeast-1',
|
|
24
|
-
access_key: 'LTAI5t9GjXQc7itTohf68ZLq',
|
|
25
|
-
access_secret: '8jfykQQoK66RldfSo9YlfdLh423GXA',
|
|
26
|
-
root_path: '/',
|
|
27
|
-
});
|
|
28
|
-
expect(out.bucket).toBe('my-bucket');
|
|
29
|
-
expect(out.region).toBe('oss-ap-southeast-1');
|
|
30
|
-
expect(out.root_path).toBe('/');
|
|
31
|
-
expect(out.access_key).not.toContain('GjXQc7it');
|
|
32
|
-
expect(out.access_secret).not.toContain('QQoK66Rld');
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
test('redactCdnUrl masks AccessKeyId and Signature only', () => {
|
|
36
|
-
const url =
|
|
37
|
-
'http://cdn.ap-southeast-1.aliyuncs.com?AccessKeyId=LTAI5t9GjXQc7itTohf68ZLq&Action=BatchSetCdnDomainConfig&Signature=iUppVaZSIecVi3DhZZeBCf24Ag0%3D&Timestamp=2026-05-25T08%3A40%3A51.135Z';
|
|
38
|
-
const masked = redactCdnUrl(url);
|
|
39
|
-
expect(masked).not.toContain('LTAI5t9GjXQc7itTohf68ZLq');
|
|
40
|
-
expect(masked).not.toContain('iUppVaZSIecVi3DhZZeBCf24Ag0');
|
|
41
|
-
expect(masked).toContain('Action=BatchSetCdnDomainConfig');
|
|
42
|
-
expect(masked).toContain('Timestamp=2026-05-25');
|
|
43
|
-
});
|