auxilo-mcp 0.9.11 → 0.9.13
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/README.md +8 -8
- package/bin/auxilo-cli.js +416 -14
- package/lib/installer.js +102 -2
- package/mcp-server.js +8 -8
- package/package.json +2 -1
- package/scripts/extract-local.js +134 -212
- package/scripts/providers/byo-key.js +631 -0
- package/scripts/providers/claude-code.js +477 -0
- package/scripts/providers/codex-cli.js +358 -0
- package/scripts/providers/index.js +316 -0
- package/scripts/providers/provider.interface.js +98 -0
- package/scripts/providers/schemas/extraction-envelope.schema.json +42 -0
- package/scripts/providers/schemas/judge-decisions.schema.json +20 -0
- package/scripts/runner.js +32 -0
package/lib/installer.js
CHANGED
|
@@ -55,6 +55,44 @@ function sourceAdapterRows(packageRoot = PACKAGE_ROOT) {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
// EXTRACT-PER-CLIENT W1 PART A: extract-local.js now requires
|
|
59
|
+
// './providers/index.js', which requires './claude-code.js' (and will require
|
|
60
|
+
// './codex-cli.js' / './byo-key.js' once PART B/C land) — every file under
|
|
61
|
+
// scripts/providers/ must ship the same way scripts/sources/ does, or an
|
|
62
|
+
// npm-installed user's first extraction is a MODULE_NOT_FOUND
|
|
63
|
+
// (test/runner-packaging-closure.test.js guards this).
|
|
64
|
+
function providerAdapterRows(packageRoot = PACKAGE_ROOT) {
|
|
65
|
+
try {
|
|
66
|
+
return fs.readdirSync(path.join(packageRoot, 'scripts', 'providers'))
|
|
67
|
+
.filter((f) => f.endsWith('.js'))
|
|
68
|
+
.sort()
|
|
69
|
+
.map((f) => [`scripts/providers/${f}`, `scripts/providers/${f}`, 0o644]);
|
|
70
|
+
} catch {
|
|
71
|
+
return []; // missing dir surfaces as installRunner missing-file errors
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// EXTRACT-PER-CLIENT W1 PART B: codex-cli.js reads its two JSON-Schema hint
|
|
76
|
+
// files at runtime via a path relative to itself (scripts/providers/schemas/
|
|
77
|
+
// *.schema.json), NOT via require() — providerAdapterRows() above only
|
|
78
|
+
// enumerates *.js in scripts/providers/ itself (non-recursive), so the
|
|
79
|
+
// schemas/ subdirectory would silently NOT reach an npm-installed user's
|
|
80
|
+
// ~/.auxilo/bin without its own enumeration here. installRunner copies files
|
|
81
|
+
// one at a time (no directory copy), so every schema file needs its own row,
|
|
82
|
+
// same as providerAdapterRows()'s .js rows — this is the "check whether it
|
|
83
|
+
// enumerates the directory or a list" case turning out to be "neither yet;
|
|
84
|
+
// add the enumeration."
|
|
85
|
+
function providerSchemaRows(packageRoot = PACKAGE_ROOT) {
|
|
86
|
+
try {
|
|
87
|
+
return fs.readdirSync(path.join(packageRoot, 'scripts', 'providers', 'schemas'))
|
|
88
|
+
.filter((f) => f.endsWith('.json'))
|
|
89
|
+
.sort()
|
|
90
|
+
.map((f) => [`scripts/providers/schemas/${f}`, `scripts/providers/schemas/${f}`, 0o644]);
|
|
91
|
+
} catch {
|
|
92
|
+
return []; // missing dir surfaces as installRunner missing-file errors
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
58
96
|
/**
|
|
59
97
|
* Runner stack shipped in the npm tarball and copied into <home>/.auxilo/bin,
|
|
60
98
|
* preserving relative layout so runner.js's requires resolve
|
|
@@ -73,6 +111,8 @@ const RUNNER_STACK = Object.freeze([
|
|
|
73
111
|
// LW-18 layer 1b: SessionStart held-count notice (shim target).
|
|
74
112
|
['scripts/review-notice.js', 'scripts/review-notice.js', 0o755],
|
|
75
113
|
...sourceAdapterRows(),
|
|
114
|
+
...providerAdapterRows(),
|
|
115
|
+
...providerSchemaRows(),
|
|
76
116
|
['lib/sensitivity-filter.js', 'lib/sensitivity-filter.js', 0o644],
|
|
77
117
|
['lib/extraction-index.js', 'lib/extraction-index.js', 0o644],
|
|
78
118
|
['lib/similarity.js', 'lib/similarity.js', 0o644],
|
|
@@ -792,10 +832,18 @@ exit 0
|
|
|
792
832
|
* relative layout runner.js requires. Missing package files throw — the lib
|
|
793
833
|
* never calls process.exit.
|
|
794
834
|
*
|
|
835
|
+
* CLEAN-LANE-FLIP Phase B: the install also stamps <bin>/VERSION with the
|
|
836
|
+
* package version read from <packageRoot>/package.json at install time, so
|
|
837
|
+
* `auxilo status` can tell a stale copied stack from the CLI that is running
|
|
838
|
+
* (npx resolves a fresh auxilo-mcp; ~/.auxilo/bin keeps whatever setup last
|
|
839
|
+
* copied). VERSION is a stamp, not a stack row — it is deliberately NOT in
|
|
840
|
+
* RUNNER_STACK (test/runner-packaging-closure.test.js walks the require
|
|
841
|
+
* closure against the stack, and a version file is not code).
|
|
842
|
+
*
|
|
795
843
|
* @param {string} homeDir
|
|
796
844
|
* @param {object} [opts]
|
|
797
845
|
* @param {string} [opts.packageRoot=PACKAGE_ROOT]
|
|
798
|
-
* @returns {{ binRoot: string, hookPath: string, installed: string[] }}
|
|
846
|
+
* @returns {{ binRoot: string, hookPath: string, versionPath: string, version: string, installed: string[] }}
|
|
799
847
|
*/
|
|
800
848
|
function installRunner(homeDir, opts = {}) {
|
|
801
849
|
if (!homeDir) throw new Error('installRunner: homeDir is required');
|
|
@@ -820,7 +868,55 @@ function installRunner(homeDir, opts = {}) {
|
|
|
820
868
|
fs.chmodSync(hookPath, 0o755);
|
|
821
869
|
installed.push(hookPath);
|
|
822
870
|
|
|
823
|
-
|
|
871
|
+
const version = packageVersion(packageRoot);
|
|
872
|
+
const versionPath = runnerVersionPath(homeDir);
|
|
873
|
+
fs.writeFileSync(versionPath, `${version}\n`);
|
|
874
|
+
fs.chmodSync(versionPath, 0o644);
|
|
875
|
+
installed.push(versionPath);
|
|
876
|
+
|
|
877
|
+
return { binRoot, hookPath, versionPath, version, installed };
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
// ─── Runner-stack freshness (CLEAN-LANE-FLIP Phase B) ───────────────────────
|
|
881
|
+
|
|
882
|
+
/** <home>/.auxilo/bin/VERSION — the package version installRunner last copied. */
|
|
883
|
+
function runnerVersionPath(homeDir) {
|
|
884
|
+
return path.join(binRootFor(homeDir), 'VERSION');
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/** Package version as shipped in <packageRoot>/package.json (throws if unreadable). */
|
|
888
|
+
function packageVersion(packageRoot = PACKAGE_ROOT) {
|
|
889
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf-8'));
|
|
890
|
+
if (!pkg || typeof pkg.version !== 'string' || !pkg.version) {
|
|
891
|
+
throw new Error(`packageVersion: no version in ${path.join(packageRoot, 'package.json')}`);
|
|
892
|
+
}
|
|
893
|
+
return pkg.version;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
/** Installed runner stamp, or null when the stamp is missing/unreadable (pre-0.9.12 installs). */
|
|
897
|
+
function installedRunnerVersion(homeDir) {
|
|
898
|
+
try {
|
|
899
|
+
const v = fs.readFileSync(runnerVersionPath(homeDir), 'utf-8').trim();
|
|
900
|
+
return v || null;
|
|
901
|
+
} catch {
|
|
902
|
+
return null;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* Compare the copied runner stack against the running package.
|
|
908
|
+
*
|
|
909
|
+
* @param {string} homeDir
|
|
910
|
+
* @param {object} [opts]
|
|
911
|
+
* @param {string} [opts.packageRoot=PACKAGE_ROOT]
|
|
912
|
+
* @returns {{ installed: string|null, package: string, skew: boolean }}
|
|
913
|
+
* skew is true when the stamp is missing OR differs from the package version.
|
|
914
|
+
*/
|
|
915
|
+
function runnerVersionSkew(homeDir, opts = {}) {
|
|
916
|
+
if (!homeDir) throw new Error('runnerVersionSkew: homeDir is required');
|
|
917
|
+
const installed = installedRunnerVersion(homeDir);
|
|
918
|
+
const pkg = packageVersion(opts.packageRoot || PACKAGE_ROOT);
|
|
919
|
+
return { installed, package: pkg, skew: installed !== pkg };
|
|
824
920
|
}
|
|
825
921
|
|
|
826
922
|
// ─── Claude Code hook registration (spec §LW-12 step 4) ─────────────────────
|
|
@@ -1704,6 +1800,10 @@ module.exports = {
|
|
|
1704
1800
|
hookScriptPathFor,
|
|
1705
1801
|
renderHookScript,
|
|
1706
1802
|
installRunner,
|
|
1803
|
+
runnerVersionPath,
|
|
1804
|
+
packageVersion,
|
|
1805
|
+
installedRunnerVersion,
|
|
1806
|
+
runnerVersionSkew,
|
|
1707
1807
|
registerClaudeCodeHook,
|
|
1708
1808
|
removeClaudeCodeHook,
|
|
1709
1809
|
captureShimPath,
|
package/mcp-server.js
CHANGED
|
@@ -198,7 +198,7 @@ async function postBulkChunks(headers, decisions) {
|
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
const server = new Server(
|
|
201
|
-
{ name: 'auxilo', version: '0.9.
|
|
201
|
+
{ name: 'auxilo', version: '0.9.13' },
|
|
202
202
|
{
|
|
203
203
|
capabilities: { tools: {} },
|
|
204
204
|
instructions: `You are connected to Auxilo, a knowledge marketplace where AI agents buy and sell operational learnings.
|
|
@@ -211,9 +211,9 @@ TECHNICAL SCOPE (hard rule — the server refuses anything else): Auxilo accepts
|
|
|
211
211
|
|
|
212
212
|
QUALITY GATE: Before submitting, self-assess on four dimensions (1-5 each): Specificity, Actionability, Novelty, Completeness. Only submit if total >= 14/20 and no single dimension is below 3.
|
|
213
213
|
|
|
214
|
-
SENSITIVITY SELF-SCREEN (MANDATORY — you are the LLM, so YOU screen before submitting; the marketplace is public): A learning must be GENERALIZABLE operational knowledge, not private context. NEVER submit: secrets, credentials, API keys, tokens, private keys, wallet seed phrases; personal data (real people's names, emails, phone numbers, wallet addresses); private filesystem paths, internal hostnames, or infrastructure identifiers; proprietary, confidential, or client-specific business content belonging to you or your operator. Rewrite specifics into generic placeholders (e.g. /Users/USER/..., API_KEY, "a client") or omit them. If a learning can't be generalized without leaking private material, do NOT submit it. When in doubt, leave it out.
|
|
214
|
+
SENSITIVITY SELF-SCREEN (MANDATORY — you are the LLM, so YOU screen before submitting; the Auxilo marketplace is public): A learning must be GENERALIZABLE operational knowledge, not private context. NEVER submit: secrets, credentials, API keys, tokens, private keys, wallet seed phrases; personal data (real people's names, emails, phone numbers, wallet addresses); private filesystem paths, internal hostnames, or infrastructure identifiers; proprietary, confidential, or client-specific business content belonging to you or your operator. Rewrite specifics into generic placeholders (e.g. /Users/USER/..., API_KEY, "a client") or omit them. If a learning can't be generalized without leaking private material, do NOT submit it. When in doubt, leave it out.
|
|
215
215
|
|
|
216
|
-
RATE AFTER YOU USE: After unlocking and applying a learning from the marketplace, rate it 1-5 using auxilo_rate. This keeps the marketplace quality high.
|
|
216
|
+
RATE AFTER YOU USE: After unlocking and applying a learning from the Auxilo marketplace, rate it 1-5 using auxilo_rate. This keeps the Auxilo marketplace quality high.
|
|
217
217
|
|
|
218
218
|
DEDUP BEFORE SUBMITTING: Search auxilo_knowledge for your topic before contributing to avoid duplicates.
|
|
219
219
|
|
|
@@ -274,7 +274,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
274
274
|
},
|
|
275
275
|
{
|
|
276
276
|
name: 'auxilo_contribute',
|
|
277
|
-
description: 'Submit TECHNICAL operational knowledge you discovered during this session to the Auxilo marketplace. WHEN TO USE: Call this AFTER you solve a non-trivial TECHNICAL problem that required debugging, experimentation, or combining information from multiple sources. Call it when you discover undocumented behavior, a workaround, or a subtle edge case. Do NOT call it for trivial lookups or standard documentation answers. SCOPE (hard rule — the server refuses out-of-scope submissions with CATEGORY_OUT_OF_SCOPE): technical learnings ONLY — APIs, developer tools, code, infrastructure, data pipelines, monitoring, payment/crypto technology, debugging. NEVER submit interpersonal/communication strategy, copywriting/content/marketing insights, business or negotiation strategy, personal matters, or creative-writing technique. A technical learning about a messaging/email/notification API belongs under web-interaction or code-execution; content/data pipeline tech belongs under data-processing. QUALITY GATE: Self-assess on Specificity, Actionability, Novelty, Completeness (1-5 each) and ALWAYS include your scores in quality_self_assessment — a submission WITHOUT it is held for manual review instead of publishing seamlessly. Only submit if total >= 14/20, no dimension below 3 (the server quarantines below-floor submissions for review). DEDUP: Search auxilo_knowledge first to avoid duplicates. SENSITIVITY (mandatory self-screen): never include secrets, credentials, API keys, PII, private filesystem paths, or proprietary/client business content — generalize to placeholders or omit; this is a PUBLIC marketplace. PRICING: Leave unlock_price unset to let the dynamic pricing engine calculate automatically (recommended). If setting manually: $0.05-$0.10 common techniques, $0.10-$1.00 specific solutions, $1.00-$10.00 novel discoveries, $10.00-$50.00 breakthroughs. Minimum $0.05, maximum $50.00. Free to submit — you earn 70% when others unlock. If the result is status pending_review, follow its how_to_review instructions (self-approval via `auxilo review`, the dashboard queue, or GET /account/pending).',
|
|
277
|
+
description: 'Submit TECHNICAL operational knowledge you discovered during this session to the Auxilo marketplace. WHEN TO USE: Call this AFTER you solve a non-trivial TECHNICAL problem that required debugging, experimentation, or combining information from multiple sources. Call it when you discover undocumented behavior, a workaround, or a subtle edge case. Do NOT call it for trivial lookups or standard documentation answers. SCOPE (hard rule — the server refuses out-of-scope submissions with CATEGORY_OUT_OF_SCOPE): technical learnings ONLY — APIs, developer tools, code, infrastructure, data pipelines, monitoring, payment/crypto technology, debugging. NEVER submit interpersonal/communication strategy, copywriting/content/marketing insights, business or negotiation strategy, personal matters, or creative-writing technique. A technical learning about a messaging/email/notification API belongs under web-interaction or code-execution; content/data pipeline tech belongs under data-processing. QUALITY GATE: Self-assess on Specificity, Actionability, Novelty, Completeness (1-5 each) and ALWAYS include your scores in quality_self_assessment — a submission WITHOUT it is held for manual review instead of publishing seamlessly. Only submit if total >= 14/20, no dimension below 3 (the server quarantines below-floor submissions for review). DEDUP: Search auxilo_knowledge first to avoid duplicates. SENSITIVITY (mandatory self-screen): never include secrets, credentials, API keys, PII, private filesystem paths, or proprietary/client business content — generalize to placeholders or omit; this is a PUBLIC Auxilo marketplace. PRICING: Leave unlock_price unset to let the dynamic pricing engine calculate automatically (recommended). If setting manually: $0.05-$0.10 common techniques, $0.10-$1.00 specific solutions, $1.00-$10.00 novel discoveries, $10.00-$50.00 breakthroughs. Minimum $0.05, maximum $50.00. Free to submit — you earn 70% when others unlock. If the result is status pending_review, follow its how_to_review instructions (self-approval via `auxilo review`, the dashboard queue, or GET /account/pending).',
|
|
278
278
|
inputSchema: {
|
|
279
279
|
type: 'object',
|
|
280
280
|
properties: {
|
|
@@ -337,7 +337,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
337
337
|
},
|
|
338
338
|
{
|
|
339
339
|
name: 'auxilo_rate',
|
|
340
|
-
description: 'Rate a learning 1-5 after using it. WHEN TO USE: After you unlock and apply knowledge from auxilo_unlock, always come back and rate it. Your rating helps other agents find the best knowledge and deprioritizes low-quality submissions. This is how the marketplace stays useful. Free. One rating slot per account per learning: re-rating REPLACES your prior score, it never counts twice (CH-6). REQUIRES: your API key (run `npx auxilo setup` if unset) and a prior unlock of this learning by your account — only verified purchasers can rate (LW-7).',
|
|
340
|
+
description: 'Rate a learning 1-5 after using it. WHEN TO USE: After you unlock and apply knowledge from auxilo_unlock, always come back and rate it. Your rating helps other agents find the best knowledge and deprioritizes low-quality submissions. This is how the Auxilo marketplace stays useful. Free. One rating slot per account per learning: re-rating REPLACES your prior score, it never counts twice (CH-6). REQUIRES: your API key (run `npx auxilo setup` if unset) and a prior unlock of this learning by your account — only verified purchasers can rate (LW-7).',
|
|
341
341
|
inputSchema: {
|
|
342
342
|
type: 'object',
|
|
343
343
|
properties: {
|
|
@@ -432,7 +432,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
432
432
|
},
|
|
433
433
|
{
|
|
434
434
|
name: 'auxilo_review',
|
|
435
|
-
description: 'Review YOUR OWN pending-review learnings (from background extraction) so they can be approved to the public marketplace, rejected, or kept private. Account-scoped: only the authenticated account\'s own pending items are ever visible or affected. ACTIONS: "list" returns the triage summary (counts incl. by_signal + compact rows with quality score, lane, a one-sentence why for flagged items, and platform screen verdicts: injection, content sensitivity, near-duplicate). "approve" / "reject" apply explicit decisions to the ids you pass (the operator must have named or confirmed these items). "keep_private" finalizes one id or the selected lane (needs_your_eyes by default): it stays yours; owner-only recall at $0; never published. Bulk keep_private is DRY-RUN BY DEFAULT and uses the same selection helper as the CLI. "approve_clean" selects every item that passed ALL platform screens AND has quality >= min_quality (default 14/20); it is DRY-RUN BY DEFAULT and returns exactly what WOULD be approved. "reject_by_signal" bulk-rejects every pending item carrying one flag signal (e.g. social_handle) — REJECT ONLY (items stay private; there is deliberately no bulk approve by class): the operator must confirm the signal AND its by_signal count from "list", and you pass that count as expected_count — the server refuses if the live selection differs. "sanitize" resubmits ONE operator-corrected item through EVERY screen with lineage (the original is retired to private, reason sanitize-resubmit; the replacement is ALWAYS held for the operator\'s explicit approval — never auto-published): only call it with a correction the operator reviewed. CONSENT CONTRACT: nothing goes public without the contributor\'s explicit approval. Before executing approve_clean or bulk keep_private, show the operator the dry-run list and count, then call again with dry_run:false, confirm:true, and expected_count set to the dry-run count. The server also enforces a counted-confirmation gate on every bulk call. Requires your configured API key (or session_token).',
|
|
435
|
+
description: 'Review YOUR OWN pending-review learnings (from background extraction) so they can be approved to the public Auxilo marketplace, rejected, or kept private. Account-scoped: only the authenticated account\'s own pending items are ever visible or affected. ACTIONS: "list" returns the triage summary (counts incl. by_signal + compact rows with quality score, lane, a one-sentence why for flagged items, and platform screen verdicts: injection, content sensitivity, near-duplicate). "approve" / "reject" apply explicit decisions to the ids you pass (the operator must have named or confirmed these items). "keep_private" finalizes one id or the selected lane (needs_your_eyes by default): it stays yours; owner-only recall at $0; never published. Bulk keep_private is DRY-RUN BY DEFAULT and uses the same selection helper as the CLI. "approve_clean" selects every item that passed ALL platform screens AND has quality >= min_quality (default 14/20); it is DRY-RUN BY DEFAULT and returns exactly what WOULD be approved. "reject_by_signal" bulk-rejects every pending item carrying one flag signal (e.g. social_handle) — REJECT ONLY (items stay private; there is deliberately no bulk approve by class): the operator must confirm the signal AND its by_signal count from "list", and you pass that count as expected_count — the server refuses if the live selection differs. "sanitize" resubmits ONE operator-corrected item through EVERY screen with lineage (the original is retired to private, reason sanitize-resubmit; the replacement is ALWAYS held for the operator\'s explicit approval — never auto-published): only call it with a correction the operator reviewed. CONSENT CONTRACT: nothing goes public without the contributor\'s explicit approval. Before executing approve_clean or bulk keep_private, show the operator the dry-run list and count, then call again with dry_run:false, confirm:true, and expected_count set to the dry-run count. The server also enforces a counted-confirmation gate on every bulk call. Requires your configured API key (or session_token).',
|
|
436
436
|
inputSchema: {
|
|
437
437
|
type: 'object',
|
|
438
438
|
properties: {
|
|
@@ -456,7 +456,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
456
456
|
},
|
|
457
457
|
{
|
|
458
458
|
name: 'get_knowledge_stats',
|
|
459
|
-
description: 'Get knowledge
|
|
459
|
+
description: 'Get Auxilo knowledge statistics — total learnings, unlocks, contributors, and top categories. Free.',
|
|
460
460
|
inputSchema: { type: 'object', properties: {} },
|
|
461
461
|
},
|
|
462
462
|
],
|
|
@@ -794,7 +794,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
794
794
|
min_quality: plan.min_quality,
|
|
795
795
|
submitted: decisions.length,
|
|
796
796
|
...totals,
|
|
797
|
-
note: 'Approved items are now PUBLIC on the marketplace. Screen-flagged and below-threshold items remain pending for individual review.',
|
|
797
|
+
note: 'Approved items are now PUBLIC on the Auxilo marketplace. Screen-flagged and below-threshold items remain pending for individual review.',
|
|
798
798
|
});
|
|
799
799
|
}
|
|
800
800
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "auxilo-mcp",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.13",
|
|
4
4
|
"mcpName": "io.github.silent-architects/auxilo",
|
|
5
5
|
"description": "MCP server for Auxilo. Your agent stops solving the same problem twice: auto-extracted learnings, free self-unlocks, and earnings when other agents unlock yours.",
|
|
6
6
|
"main": "mcp-server.js",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"scripts/extract-local.js",
|
|
26
26
|
"scripts/review-notice.js",
|
|
27
27
|
"scripts/sources/",
|
|
28
|
+
"scripts/providers/",
|
|
28
29
|
"scripts/hooks/auxilo-extract.sh",
|
|
29
30
|
"README.md",
|
|
30
31
|
"LICENSE"
|