shakers-cli-beta 0.8.0-beta.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/LICENSE +59 -0
- package/README.md +1175 -0
- package/bin/add-agent.js +88 -0
- package/bin/add-project.js +88 -0
- package/bin/add-role.js +61 -0
- package/bin/add-skill.js +88 -0
- package/bin/ai-usage.js +81 -0
- package/bin/alma.js +99 -0
- package/bin/applications.js +69 -0
- package/bin/availability.js +70 -0
- package/bin/certifications.js +69 -0
- package/bin/certify.js +73 -0
- package/bin/change-role.js +61 -0
- package/bin/config.js +120 -0
- package/bin/experiences.js +69 -0
- package/bin/find-projects.js +89 -0
- package/bin/invitations.js +69 -0
- package/bin/lang.js +70 -0
- package/bin/login.js +283 -0
- package/bin/mcp.js +98 -0
- package/bin/me.js +69 -0
- package/bin/onboarding.js +134 -0
- package/bin/portfolios.js +69 -0
- package/bin/rate.js +70 -0
- package/bin/register.js +325 -0
- package/bin/report-html.js +134 -0
- package/bin/save.js +77 -0
- package/bin/shakers.js +344 -0
- package/bin/share.js +72 -0
- package/bin/show-project.js +72 -0
- package/bin/socials.js +70 -0
- package/bin/superadmin.js +351 -0
- package/package.json +40 -0
- package/src/agent-category.js +13 -0
- package/src/agent-evaluation.js +177 -0
- package/src/agent-org-chart.js +355 -0
- package/src/agent-synthesis.js +132 -0
- package/src/agent-usage.js +118 -0
- package/src/agents-client.js +165 -0
- package/src/ai-fluency-cell.js +72 -0
- package/src/ai-profile-client.js +45 -0
- package/src/ai-profile-preview.js +154 -0
- package/src/ai.js +66 -0
- package/src/alma-client.js +123 -0
- package/src/alma-flow.js +32 -0
- package/src/alma-repo-context.js +47 -0
- package/src/alma-shell.js +161 -0
- package/src/ansi.js +62 -0
- package/src/applications-client.js +79 -0
- package/src/applications-flow.js +58 -0
- package/src/auth-client.js +144 -0
- package/src/auth-device-client.js +118 -0
- package/src/auth-method-picker.js +44 -0
- package/src/auth-methods.js +35 -0
- package/src/auth-session-store.js +214 -0
- package/src/authorship.js +203 -0
- package/src/automations-detector.js +170 -0
- package/src/availability-client.js +92 -0
- package/src/availability-flow.js +105 -0
- package/src/backend-request.js +170 -0
- package/src/blind-approval-extract.js +48 -0
- package/src/brand-ansi.js +14 -0
- package/src/brand-svg.js +9 -0
- package/src/browser-tools-detector.js +21 -0
- package/src/build-next-level.js +56 -0
- package/src/certifications-client.js +89 -0
- package/src/certifications-flow.js +75 -0
- package/src/certify-dimension-client.js +217 -0
- package/src/certify-dimension-flow.js +193 -0
- package/src/certify-disclaimer.js +51 -0
- package/src/certify-remediation-prompt.js +23 -0
- package/src/cli-args.js +83 -0
- package/src/config-dir.js +120 -0
- package/src/config.js +778 -0
- package/src/consent-flow.js +115 -0
- package/src/consent-skip.js +27 -0
- package/src/decisions-extract.js +43 -0
- package/src/detect-repos.js +145 -0
- package/src/detected-tools.js +15 -0
- package/src/detection-evidence.js +105 -0
- package/src/detection-noise.js +132 -0
- package/src/detectors.js +221 -0
- package/src/device-auth-store.js +100 -0
- package/src/device-login.js +118 -0
- package/src/email-verification.js +152 -0
- package/src/env-paths.js +16 -0
- package/src/find-projects-cache.js +89 -0
- package/src/find-projects-client.js +138 -0
- package/src/find-projects-flow.js +164 -0
- package/src/git-activity.js +123 -0
- package/src/graph-certs.js +58 -0
- package/src/graph-generator.js +230 -0
- package/src/graph-scan.js +239 -0
- package/src/i18n.js +3264 -0
- package/src/inter-fonts.js +6 -0
- package/src/interactive-select.js +183 -0
- package/src/interview-client.js +226 -0
- package/src/interview-transcript.js +56 -0
- package/src/inventory-client.js +90 -0
- package/src/invitations-client.js +66 -0
- package/src/invitations-flow.js +50 -0
- package/src/lang-client.js +147 -0
- package/src/lang-codes.js +14 -0
- package/src/lang-flow.js +85 -0
- package/src/legal-notice.js +53 -0
- package/src/locale.js +51 -0
- package/src/markdown-ansi.js +50 -0
- package/src/maturity.js +111 -0
- package/src/mcp-ai-usage-result-tool.js +109 -0
- package/src/mcp-ai-usage-tool.js +333 -0
- package/src/mcp-alma-tools.js +91 -0
- package/src/mcp-applications-tools.js +42 -0
- package/src/mcp-ask-tools.js +50 -0
- package/src/mcp-auth-form.js +282 -0
- package/src/mcp-availability-tools.js +43 -0
- package/src/mcp-certifications-tools.js +42 -0
- package/src/mcp-certify-dimension-tools.js +58 -0
- package/src/mcp-detector.js +223 -0
- package/src/mcp-device-login-tools.js +173 -0
- package/src/mcp-find-projects-tools.js +67 -0
- package/src/mcp-install.js +245 -0
- package/src/mcp-invitations-tools.js +42 -0
- package/src/mcp-lang-tools.js +39 -0
- package/src/mcp-onboarding-tools.js +388 -0
- package/src/mcp-portfolios-tools.js +46 -0
- package/src/mcp-profile-tools.js +46 -0
- package/src/mcp-rate-tools.js +42 -0
- package/src/mcp-register-tools.js +517 -0
- package/src/mcp-report-tools.js +101 -0
- package/src/mcp-role-tools.js +112 -0
- package/src/mcp-saved-positions-tools.js +55 -0
- package/src/mcp-server.js +170 -0
- package/src/mcp-show-project-tools.js +50 -0
- package/src/mcp-socials-tools.js +39 -0
- package/src/memory-structure-detector.js +108 -0
- package/src/model-call-record.js +198 -0
- package/src/onboarding-availability.js +26 -0
- package/src/onboarding-client.js +364 -0
- package/src/onboarding-flow.js +1078 -0
- package/src/onboarding-livekit-client.js +102 -0
- package/src/onboarding-status-client.js +42 -0
- package/src/open-file.js +32 -0
- package/src/osc-link.js +16 -0
- package/src/portfolio-client.js +164 -0
- package/src/portfolio-git-info.js +61 -0
- package/src/portfolios-client.js +85 -0
- package/src/portfolios-flow.js +79 -0
- package/src/profile-client.js +125 -0
- package/src/profile-flow.js +115 -0
- package/src/profile-switch.js +46 -0
- package/src/prompt-select.js +29 -0
- package/src/rate-client.js +82 -0
- package/src/rate-flow.js +137 -0
- package/src/render-ai-fluency.js +266 -0
- package/src/render-certification.js +177 -0
- package/src/render-html.js +140 -0
- package/src/render-report-text.js +27 -0
- package/src/render-sheet.js +261 -0
- package/src/render-terminal.js +109 -0
- package/src/render-usage-report-text.js +155 -0
- package/src/repo-context.js +215 -0
- package/src/report-gating.js +49 -0
- package/src/report-store.js +226 -0
- package/src/report-theme.js +177 -0
- package/src/report-view-client.js +50 -0
- package/src/reveal-output.js +29 -0
- package/src/roadmap-content.js +453 -0
- package/src/roadmap-personalization.js +132 -0
- package/src/roadmap-prompt.js +154 -0
- package/src/roles-client.js +114 -0
- package/src/roles-flow.js +192 -0
- package/src/sanitize-network-text.js +36 -0
- package/src/saved-positions-client.js +71 -0
- package/src/saved-positions-flow.js +50 -0
- package/src/scan-exclusions.js +50 -0
- package/src/scanner.js +612 -0
- package/src/scope-signals.js +148 -0
- package/src/secret-prompt.js +72 -0
- package/src/session-gate.js +30 -0
- package/src/session-refresh.js +51 -0
- package/src/session-scan.js +336 -0
- package/src/session-signals.js +36 -0
- package/src/shakers-wordmark.js +17 -0
- package/src/share-card.js +362 -0
- package/src/share-certification.js +111 -0
- package/src/share-consent-state.js +157 -0
- package/src/share-payload.js +300 -0
- package/src/share.js +184 -0
- package/src/show-project-client.js +58 -0
- package/src/show-project-flow.js +119 -0
- package/src/signup-client.js +91 -0
- package/src/skills-client.js +102 -0
- package/src/socials-client.js +91 -0
- package/src/socials-flow.js +83 -0
- package/src/specificity-extract.js +41 -0
- package/src/start-add-agents.js +306 -0
- package/src/start-add-portfolio.js +388 -0
- package/src/start-add-skills.js +260 -0
- package/src/stdin-ask.js +129 -0
- package/src/steering-extract.js +43 -0
- package/src/strip-internal-comments.js +45 -0
- package/src/tech-detector.js +295 -0
- package/src/templates/report-sheet.html +572 -0
- package/src/terminal-agents.js +199 -0
- package/src/terminal-format.js +85 -0
- package/src/terminal-progress.js +106 -0
- package/src/terminal-sections.js +219 -0
- package/src/tier-analysis.js +126 -0
- package/src/tier-engine.js +114 -0
- package/src/tier-projection.js +117 -0
- package/src/transcript-turns.js +49 -0
- package/src/translations-client.js +84 -0
- package/src/typewriter.js +154 -0
- package/src/usage-model-calls.js +119 -0
- package/src/usage-oneshot-commands.js +180 -0
- package/src/usage-repo-scope.js +162 -0
- package/src/usage-run-steps.js +338 -0
- package/src/work-streams.js +74 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// `certifications` — the talent's dimension certifications (src/certifications-flow.js).
|
|
5
|
+
|
|
6
|
+
const { detectReportLang, getCatalog } = require('../src/i18n');
|
|
7
|
+
const { loadAuthSession, sessionStatus } = require('../src/auth-session-store');
|
|
8
|
+
const { createStdinAsk } = require('../src/stdin-ask');
|
|
9
|
+
const { makeIo } = require('./register');
|
|
10
|
+
const { makeRevealSink } = require('../src/reveal-output');
|
|
11
|
+
const { runCertifications, makeCertificationsDeps } = require('../src/certifications-flow');
|
|
12
|
+
|
|
13
|
+
function parseCertificationsArgs(argv = []) {
|
|
14
|
+
const o = { lang: null, help: false, json: false };
|
|
15
|
+
for (let i = 0; i < argv.length; i++) {
|
|
16
|
+
const a = argv[i];
|
|
17
|
+
if (a === '--help' || a === '-h') o.help = true;
|
|
18
|
+
else if (a === '--lang') { const v = argv[++i]; o.lang = v === 'es' || v === 'en' ? v : null; }
|
|
19
|
+
else if (a.startsWith('--lang=')) { const v = a.slice(7); o.lang = v === 'es' || v === 'en' ? v : null; }
|
|
20
|
+
else if (a === '--json') o.json = true;
|
|
21
|
+
}
|
|
22
|
+
return o;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function run(
|
|
26
|
+
argv = process.argv.slice(2),
|
|
27
|
+
{ ask: injectedAsk = null, stdinIsTTY: ttyOverride = undefined, deps = null, session: injectedSession = null, out = null } = {},
|
|
28
|
+
) {
|
|
29
|
+
const opts = parseCertificationsArgs(argv);
|
|
30
|
+
const lang = opts.lang || detectReportLang();
|
|
31
|
+
const catalog = getCatalog(lang);
|
|
32
|
+
const fp = catalog.certifications;
|
|
33
|
+
const write = out || ((s) => process.stdout.write(s));
|
|
34
|
+
|
|
35
|
+
if (opts.help) {
|
|
36
|
+
write(fp.help + '\n');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const session = injectedSession || loadAuthSession();
|
|
41
|
+
if (sessionStatus(session) !== 'active') {
|
|
42
|
+
process.stderr.write(`\n ${fp.loginRequired}\n\n`);
|
|
43
|
+
process.exitCode = 1;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const stdinIsTTY = ttyOverride !== undefined ? ttyOverride : !!process.stdin.isTTY;
|
|
48
|
+
const ask = injectedAsk || createStdinAsk();
|
|
49
|
+
const sink = makeRevealSink({ json: opts.json, interactive: false, out, env: process.env });
|
|
50
|
+
try {
|
|
51
|
+
const io = makeIo({ ask, lang, out: sink.write, stdinIsTTY });
|
|
52
|
+
const result = await runCertifications({
|
|
53
|
+
io, rawOut: sink.write, session, catalog,
|
|
54
|
+
opts: { json: opts.json },
|
|
55
|
+
deps: deps || makeCertificationsDeps(),
|
|
56
|
+
});
|
|
57
|
+
await sink.finish();
|
|
58
|
+
if (result && result.ok === false) process.exitCode = 1;
|
|
59
|
+
return result;
|
|
60
|
+
} finally {
|
|
61
|
+
if (!injectedAsk) ask.close();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = { run, parseCertificationsArgs };
|
|
66
|
+
|
|
67
|
+
if (require.main === module) {
|
|
68
|
+
run();
|
|
69
|
+
}
|
package/bin/certify.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// `certify` — dimension certification interview over LiveKit (src/certify-dimension-flow.js).
|
|
5
|
+
|
|
6
|
+
const { detectReportLang, getCatalog } = require('../src/i18n');
|
|
7
|
+
const { loadAuthSession, sessionStatus } = require('../src/auth-session-store');
|
|
8
|
+
const { createStdinAsk } = require('../src/stdin-ask');
|
|
9
|
+
const { makeIo } = require('./register');
|
|
10
|
+
const { runCertifyDimension, makeCertifyDimensionDeps } = require('../src/certify-dimension-flow');
|
|
11
|
+
|
|
12
|
+
function parseCertifyArgs(argv = []) {
|
|
13
|
+
const o = { lang: null, help: false, dimension: null, acceptDisclaimer: false };
|
|
14
|
+
for (let i = 0; i < argv.length; i++) {
|
|
15
|
+
const a = argv[i];
|
|
16
|
+
if (a === '--help' || a === '-h') o.help = true;
|
|
17
|
+
else if (a === '--lang') { const v = argv[++i]; o.lang = v === 'es' || v === 'en' ? v : null; }
|
|
18
|
+
else if (a.startsWith('--lang=')) { const v = a.slice(7); o.lang = v === 'es' || v === 'en' ? v : null; }
|
|
19
|
+
else if (a === '--dimension') o.dimension = argv[++i] != null ? argv[i] : null;
|
|
20
|
+
else if (a.startsWith('--dimension=')) o.dimension = a.slice('--dimension='.length);
|
|
21
|
+
else if (a === '--accept-disclaimer') o.acceptDisclaimer = true;
|
|
22
|
+
}
|
|
23
|
+
return o;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async function run(
|
|
27
|
+
argv = process.argv.slice(2),
|
|
28
|
+
{ ask: injectedAsk = null, stdinIsTTY: ttyOverride = undefined, deps = null, session: injectedSession = null, out = null, input = undefined, output = undefined } = {},
|
|
29
|
+
) {
|
|
30
|
+
const opts = parseCertifyArgs(argv);
|
|
31
|
+
const lang = opts.lang || detectReportLang();
|
|
32
|
+
const catalog = getCatalog(lang);
|
|
33
|
+
const cd = catalog.certifyDimension;
|
|
34
|
+
const write = out || ((s) => process.stdout.write(s));
|
|
35
|
+
|
|
36
|
+
if (opts.help) {
|
|
37
|
+
write(cd.help + '\n');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const session = injectedSession || loadAuthSession();
|
|
42
|
+
if (sessionStatus(session) !== 'active') {
|
|
43
|
+
process.stderr.write(`\n ${cd.loginRequired}\n\n`);
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const stdinIsTTY = ttyOverride !== undefined ? ttyOverride : !!process.stdin.isTTY;
|
|
49
|
+
const ask = injectedAsk || createStdinAsk();
|
|
50
|
+
try {
|
|
51
|
+
const io = makeIo({ ask, lang, out: write, acceptDisclaimer: opts.acceptDisclaimer, stdinIsTTY });
|
|
52
|
+
const result = await runCertifyDimension({
|
|
53
|
+
io,
|
|
54
|
+
ask,
|
|
55
|
+
stdinIsTTY,
|
|
56
|
+
session,
|
|
57
|
+
lang,
|
|
58
|
+
catalog,
|
|
59
|
+
opts: { dimension: opts.dimension, input, output },
|
|
60
|
+
deps: deps || makeCertifyDimensionDeps(),
|
|
61
|
+
});
|
|
62
|
+
if (result && result.ok === false) process.exitCode = 1;
|
|
63
|
+
return result;
|
|
64
|
+
} finally {
|
|
65
|
+
if (!injectedAsk) ask.close();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = { run, parseCertifyArgs };
|
|
70
|
+
|
|
71
|
+
if (require.main === module) {
|
|
72
|
+
run();
|
|
73
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// `change-role` — set the MAIN role to one the talent already holds (src/roles-flow.js).
|
|
5
|
+
|
|
6
|
+
const { detectReportLang, getCatalog } = require('../src/i18n');
|
|
7
|
+
const { loadAuthSession, sessionStatus } = require('../src/auth-session-store');
|
|
8
|
+
const { createStdinAsk } = require('../src/stdin-ask');
|
|
9
|
+
const { makeIo } = require('./register');
|
|
10
|
+
const { runChangeMainRole, makeRolesDeps } = require('../src/roles-flow');
|
|
11
|
+
|
|
12
|
+
function parseArgs(argv = []) {
|
|
13
|
+
const o = { lang: null, help: false };
|
|
14
|
+
for (let i = 0; i < argv.length; i++) {
|
|
15
|
+
const a = argv[i];
|
|
16
|
+
if (a === '--help' || a === '-h') o.help = true;
|
|
17
|
+
else if (a === '--lang') { const v = argv[++i]; o.lang = v === 'es' || v === 'en' ? v : null; }
|
|
18
|
+
else if (a.startsWith('--lang=')) { const v = a.slice(7); o.lang = v === 'es' || v === 'en' ? v : null; }
|
|
19
|
+
}
|
|
20
|
+
return o;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function run(
|
|
24
|
+
argv = process.argv.slice(2),
|
|
25
|
+
{ ask: injectedAsk = null, stdinIsTTY: ttyOverride = undefined, deps = null, session: injectedSession = null, out = null } = {},
|
|
26
|
+
) {
|
|
27
|
+
const opts = parseArgs(argv);
|
|
28
|
+
const lang = opts.lang || detectReportLang();
|
|
29
|
+
const catalog = getCatalog(lang);
|
|
30
|
+
const r = catalog.roles;
|
|
31
|
+
const write = out || ((s) => process.stdout.write(s));
|
|
32
|
+
|
|
33
|
+
if (opts.help) {
|
|
34
|
+
write(r.changeHelp + '\n');
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const session = injectedSession || loadAuthSession();
|
|
39
|
+
if (sessionStatus(session) !== 'active') {
|
|
40
|
+
process.stderr.write(`\n ${r.loginRequired}\n\n`);
|
|
41
|
+
process.exitCode = 1;
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const stdinIsTTY = ttyOverride !== undefined ? ttyOverride : !!process.stdin.isTTY;
|
|
46
|
+
const ask = injectedAsk || createStdinAsk();
|
|
47
|
+
try {
|
|
48
|
+
const io = makeIo({ ask, lang, out: write, stdinIsTTY });
|
|
49
|
+
const result = await runChangeMainRole({ io, session, catalog, deps: deps || makeRolesDeps() });
|
|
50
|
+
if (result && result.ok === false) process.exitCode = 1;
|
|
51
|
+
return result;
|
|
52
|
+
} finally {
|
|
53
|
+
if (!injectedAsk) ask.close();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = { run, parseArgs };
|
|
58
|
+
|
|
59
|
+
if (require.main === module) {
|
|
60
|
+
run();
|
|
61
|
+
}
|
package/bin/config.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { detectReportLang } = require('../src/i18n');
|
|
5
|
+
const {
|
|
6
|
+
loadConfigFile,
|
|
7
|
+
saveConfigFile,
|
|
8
|
+
validateEndpoint,
|
|
9
|
+
getCertsBase,
|
|
10
|
+
getHubBase,
|
|
11
|
+
getTalentProfileUrl,
|
|
12
|
+
getIngestEndpoint,
|
|
13
|
+
} = require('../src/config');
|
|
14
|
+
|
|
15
|
+
const VALID_LANGS = new Set(['es', 'en']);
|
|
16
|
+
const ENDPOINT_KEYS = new Set(['certsBase', 'hubBase', 'ingestEndpoint', 'profileUrl']);
|
|
17
|
+
const PROFILE_VALUES = new Set(['external', 'talent']);
|
|
18
|
+
const SETTABLE = new Set([...ENDPOINT_KEYS, 'profile']);
|
|
19
|
+
|
|
20
|
+
const COPY = {
|
|
21
|
+
es: {
|
|
22
|
+
help: 'config — lee/escribe la configuracion NO sensible del CLI (bases de hub/certs, perfil). Uso: shakers config <list|get [clave]|set clave valor>\n Claves: certsBase, hubBase, ingestEndpoint, profileUrl, profile.\n Los secretos (tokens/credenciales) NUNCA se guardan aqui: se obtienen con `shakers login` o por entorno.',
|
|
23
|
+
unknownKey: (k) => `clave desconocida: ${k}. Claves validas: ${[...SETTABLE].join(', ')}.`,
|
|
24
|
+
needValue: 'set necesita <clave> <valor>.',
|
|
25
|
+
badEndpoint: (k, r) => `valor invalido para ${k} (${r}). Debe ser una URL http de loopback o https.`,
|
|
26
|
+
badProfile: 'profile debe ser "external" o "talent".',
|
|
27
|
+
saved: (k, v) => `guardado ${k} = ${v}`,
|
|
28
|
+
resolvedHeading: 'Resueltos (env > config.json > default local):',
|
|
29
|
+
},
|
|
30
|
+
en: {
|
|
31
|
+
help: 'config — read/write the CLI NON-sensitive configuration (hub/certs bases, profile). Usage: shakers config <list|get [key]|set key value>\n Keys: certsBase, hubBase, ingestEndpoint, profileUrl, profile.\n Secrets (tokens/credentials) are NEVER stored here: get them via `shakers login` or the environment.',
|
|
32
|
+
unknownKey: (k) => `unknown key: ${k}. Valid keys: ${[...SETTABLE].join(', ')}.`,
|
|
33
|
+
needValue: 'set needs <key> <value>.',
|
|
34
|
+
badEndpoint: (k, r) => `invalid value for ${k} (${r}). Must be a loopback http URL or https.`,
|
|
35
|
+
badProfile: 'profile must be "external" or "talent".',
|
|
36
|
+
saved: (k, v) => `saved ${k} = ${v}`,
|
|
37
|
+
resolvedHeading: 'Resolved (env > config.json > local default):',
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
function parseArgs(argv) {
|
|
42
|
+
const o = { lang: null, help: false, rest: [] };
|
|
43
|
+
for (let i = 0; i < argv.length; i++) {
|
|
44
|
+
const a = argv[i];
|
|
45
|
+
if (a === '--lang') o.lang = VALID_LANGS.has(argv[++i]) ? argv[i] : null;
|
|
46
|
+
else if (a.startsWith('--lang=')) { const v = a.slice(7); o.lang = VALID_LANGS.has(v) ? v : null; }
|
|
47
|
+
else if (a === '--help' || a === '-h') o.help = true;
|
|
48
|
+
else o.rest.push(a);
|
|
49
|
+
}
|
|
50
|
+
return o;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function resolvedView(env) {
|
|
54
|
+
return {
|
|
55
|
+
certsBase: getCertsBase(env),
|
|
56
|
+
hubBase: getHubBase(env),
|
|
57
|
+
ingestEndpoint: getIngestEndpoint(env),
|
|
58
|
+
profileUrl: getTalentProfileUrl(env),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function run(argv = process.argv.slice(2), { env = process.env, out = null } = {}) {
|
|
63
|
+
const o = parseArgs(argv);
|
|
64
|
+
const lang = o.lang || detectReportLang();
|
|
65
|
+
const c = COPY[lang] || COPY.en;
|
|
66
|
+
const write = out || ((s) => process.stdout.write(s));
|
|
67
|
+
const line = (s) => write(` ${s}\n`);
|
|
68
|
+
|
|
69
|
+
if (o.help || o.rest.length === 0) {
|
|
70
|
+
write(`\n ${c.help}\n\n`);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const [sub, key, ...valueParts] = o.rest;
|
|
75
|
+
|
|
76
|
+
if (sub === 'list') {
|
|
77
|
+
const config = loadConfigFile(env);
|
|
78
|
+
for (const k of SETTABLE) {
|
|
79
|
+
if (config[k] !== undefined) line(`${k} = ${config[k]}`);
|
|
80
|
+
}
|
|
81
|
+
line(c.resolvedHeading);
|
|
82
|
+
const r = resolvedView(env);
|
|
83
|
+
for (const k of Object.keys(r)) line(` ${k} = ${r[k] === null ? '(unset)' : r[k]}`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (sub === 'get') {
|
|
88
|
+
if (!key) { line(c.needValue); process.exitCode = 1; return; }
|
|
89
|
+
if (!SETTABLE.has(key)) { line(c.unknownKey(key)); process.exitCode = 1; return; }
|
|
90
|
+
const config = loadConfigFile(env);
|
|
91
|
+
line(config[key] !== undefined ? String(config[key]) : '(unset)');
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (sub === 'set') {
|
|
96
|
+
const value = valueParts.join(' ').trim();
|
|
97
|
+
if (!key || !value) { line(c.needValue); process.exitCode = 1; return; }
|
|
98
|
+
if (!SETTABLE.has(key)) { line(c.unknownKey(key)); process.exitCode = 1; return; }
|
|
99
|
+
if (key === 'profile') {
|
|
100
|
+
if (!PROFILE_VALUES.has(value)) { line(c.badProfile); process.exitCode = 1; return; }
|
|
101
|
+
} else if (key !== 'profileUrl') {
|
|
102
|
+
const v = validateEndpoint(value);
|
|
103
|
+
if (!v.ok) { line(c.badEndpoint(key, v.reason)); process.exitCode = 1; return; }
|
|
104
|
+
}
|
|
105
|
+
const config = loadConfigFile(env);
|
|
106
|
+
config[key] = value;
|
|
107
|
+
try { saveConfigFile(config, env); } catch { line('could not write config.json'); process.exitCode = 1; return; }
|
|
108
|
+
line(c.saved(key, value));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
write(`\n ${c.help}\n\n`);
|
|
113
|
+
process.exitCode = 1;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
module.exports = { run, parseArgs, SETTABLE, ENDPOINT_KEYS };
|
|
117
|
+
|
|
118
|
+
if (require.main === module) {
|
|
119
|
+
run();
|
|
120
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// `experiences` — the talent's work experiences (portfolios type=EXPERIENCE).
|
|
5
|
+
|
|
6
|
+
const { detectReportLang, getCatalog } = require('../src/i18n');
|
|
7
|
+
const { loadAuthSession, sessionStatus } = require('../src/auth-session-store');
|
|
8
|
+
const { createStdinAsk } = require('../src/stdin-ask');
|
|
9
|
+
const { makeIo } = require('./register');
|
|
10
|
+
const { makeRevealSink } = require('../src/reveal-output');
|
|
11
|
+
const { runPortfolioList, makePortfoliosDeps } = require('../src/portfolios-flow');
|
|
12
|
+
|
|
13
|
+
function parseArgs(argv = []) {
|
|
14
|
+
const o = { lang: null, help: false, json: false };
|
|
15
|
+
for (let i = 0; i < argv.length; i++) {
|
|
16
|
+
const a = argv[i];
|
|
17
|
+
if (a === '--help' || a === '-h') o.help = true;
|
|
18
|
+
else if (a === '--lang') { const v = argv[++i]; o.lang = v === 'es' || v === 'en' ? v : null; }
|
|
19
|
+
else if (a.startsWith('--lang=')) { const v = a.slice(7); o.lang = v === 'es' || v === 'en' ? v : null; }
|
|
20
|
+
else if (a === '--json') o.json = true;
|
|
21
|
+
}
|
|
22
|
+
return o;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function run(
|
|
26
|
+
argv = process.argv.slice(2),
|
|
27
|
+
{ ask: injectedAsk = null, stdinIsTTY: ttyOverride = undefined, deps = null, session: injectedSession = null, out = null } = {},
|
|
28
|
+
) {
|
|
29
|
+
const opts = parseArgs(argv);
|
|
30
|
+
const lang = opts.lang || detectReportLang();
|
|
31
|
+
const catalog = getCatalog(lang);
|
|
32
|
+
const fp = catalog.experiences;
|
|
33
|
+
const write = out || ((s) => process.stdout.write(s));
|
|
34
|
+
|
|
35
|
+
if (opts.help) {
|
|
36
|
+
write(fp.help + '\n');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const session = injectedSession || loadAuthSession();
|
|
41
|
+
if (sessionStatus(session) !== 'active') {
|
|
42
|
+
process.stderr.write(`\n ${fp.loginRequired}\n\n`);
|
|
43
|
+
process.exitCode = 1;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const stdinIsTTY = ttyOverride !== undefined ? ttyOverride : !!process.stdin.isTTY;
|
|
48
|
+
const ask = injectedAsk || createStdinAsk();
|
|
49
|
+
const sink = makeRevealSink({ json: opts.json, out, env: process.env });
|
|
50
|
+
try {
|
|
51
|
+
const io = makeIo({ ask, lang, out: sink.write, stdinIsTTY });
|
|
52
|
+
const result = await runPortfolioList({
|
|
53
|
+
io, rawOut: sink.write, lang, session, catalog, kind: 'experiences',
|
|
54
|
+
opts: { json: opts.json },
|
|
55
|
+
deps: deps || makePortfoliosDeps(),
|
|
56
|
+
});
|
|
57
|
+
await sink.finish();
|
|
58
|
+
if (result && result.ok === false) process.exitCode = 1;
|
|
59
|
+
return result;
|
|
60
|
+
} finally {
|
|
61
|
+
if (!injectedAsk) ask.close();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = { run, parseArgs };
|
|
66
|
+
|
|
67
|
+
if (require.main === module) {
|
|
68
|
+
run();
|
|
69
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// `find-projects` — list the Positions/Projects available to the talent (src/find-projects-flow.js).
|
|
5
|
+
|
|
6
|
+
const { detectReportLang, getCatalog } = require('../src/i18n');
|
|
7
|
+
const { loadAuthSession, sessionStatus } = require('../src/auth-session-store');
|
|
8
|
+
const { createStdinAsk } = require('../src/stdin-ask');
|
|
9
|
+
const { makeIo } = require('./register');
|
|
10
|
+
const { runFindProjects, makeFindProjectsDeps } = require('../src/find-projects-flow');
|
|
11
|
+
const { makeRevealSink } = require('../src/reveal-output');
|
|
12
|
+
|
|
13
|
+
function toInt(v) {
|
|
14
|
+
const n = Number.parseInt(v, 10);
|
|
15
|
+
return Number.isInteger(n) ? n : null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function parseFindProjectsArgs(argv = []) {
|
|
19
|
+
const o = { lang: null, help: false, tab: null, json: false, limit: null, page: null, attendance: null, country: null, recommended: false };
|
|
20
|
+
for (let i = 0; i < argv.length; i++) {
|
|
21
|
+
const a = argv[i];
|
|
22
|
+
if (a === '--help' || a === '-h') o.help = true;
|
|
23
|
+
else if (a === '--lang') { const v = argv[++i]; o.lang = v === 'es' || v === 'en' ? v : null; }
|
|
24
|
+
else if (a.startsWith('--lang=')) { const v = a.slice(7); o.lang = v === 'es' || v === 'en' ? v : null; }
|
|
25
|
+
else if (a === '--tab') o.tab = argv[++i] != null ? argv[i] : null;
|
|
26
|
+
else if (a.startsWith('--tab=')) o.tab = a.slice('--tab='.length);
|
|
27
|
+
else if (a === '--limit') o.limit = toInt(argv[++i]);
|
|
28
|
+
else if (a.startsWith('--limit=')) o.limit = toInt(a.slice('--limit='.length));
|
|
29
|
+
else if (a === '--page') o.page = toInt(argv[++i]);
|
|
30
|
+
else if (a.startsWith('--page=')) o.page = toInt(a.slice('--page='.length));
|
|
31
|
+
else if (a === '--attendance') o.attendance = argv[++i] != null ? argv[i] : null;
|
|
32
|
+
else if (a.startsWith('--attendance=')) o.attendance = a.slice('--attendance='.length);
|
|
33
|
+
else if (a === '--country') o.country = argv[++i] != null ? argv[i] : null;
|
|
34
|
+
else if (a.startsWith('--country=')) o.country = a.slice('--country='.length);
|
|
35
|
+
else if (a === '--recommended') o.recommended = true;
|
|
36
|
+
else if (a === '--json') o.json = true;
|
|
37
|
+
}
|
|
38
|
+
return o;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function run(
|
|
42
|
+
argv = process.argv.slice(2),
|
|
43
|
+
{ ask: injectedAsk = null, stdinIsTTY: ttyOverride = undefined, deps = null, session: injectedSession = null, out = null } = {},
|
|
44
|
+
) {
|
|
45
|
+
const opts = parseFindProjectsArgs(argv);
|
|
46
|
+
const lang = opts.lang || detectReportLang();
|
|
47
|
+
const catalog = getCatalog(lang);
|
|
48
|
+
const fp = catalog.findProjects;
|
|
49
|
+
const write = out || ((s) => process.stdout.write(s));
|
|
50
|
+
|
|
51
|
+
if (opts.help) {
|
|
52
|
+
write(fp.help + '\n');
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const session = injectedSession || loadAuthSession();
|
|
57
|
+
if (sessionStatus(session) !== 'active') {
|
|
58
|
+
process.stderr.write(`\n ${fp.loginRequired}\n\n`);
|
|
59
|
+
process.exitCode = 1;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const stdinIsTTY = ttyOverride !== undefined ? ttyOverride : !!process.stdin.isTTY;
|
|
64
|
+
const ask = injectedAsk || createStdinAsk();
|
|
65
|
+
const sink = makeRevealSink({ json: opts.json, out, env: process.env });
|
|
66
|
+
try {
|
|
67
|
+
const io = makeIo({ ask, lang, out: sink.write, stdinIsTTY });
|
|
68
|
+
const result = await runFindProjects({
|
|
69
|
+
io,
|
|
70
|
+
rawOut: sink.write,
|
|
71
|
+
session,
|
|
72
|
+
lang,
|
|
73
|
+
catalog,
|
|
74
|
+
opts: { tab: opts.tab, json: opts.json, limit: opts.limit, page: opts.page, attendance: opts.attendance, country: opts.country, recommended: opts.recommended },
|
|
75
|
+
deps: deps || makeFindProjectsDeps(),
|
|
76
|
+
});
|
|
77
|
+
await sink.finish();
|
|
78
|
+
if (result && result.ok === false) process.exitCode = 1;
|
|
79
|
+
return result;
|
|
80
|
+
} finally {
|
|
81
|
+
if (!injectedAsk) ask.close();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
module.exports = { run, parseFindProjectsArgs };
|
|
86
|
+
|
|
87
|
+
if (require.main === module) {
|
|
88
|
+
run();
|
|
89
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// `invitations` — the talent's unread position invitations (src/invitations-flow.js).
|
|
5
|
+
|
|
6
|
+
const { detectReportLang, getCatalog } = require('../src/i18n');
|
|
7
|
+
const { loadAuthSession, sessionStatus } = require('../src/auth-session-store');
|
|
8
|
+
const { createStdinAsk } = require('../src/stdin-ask');
|
|
9
|
+
const { makeIo } = require('./register');
|
|
10
|
+
const { makeRevealSink } = require('../src/reveal-output');
|
|
11
|
+
const { runInvitations, makeInvitationsDeps } = require('../src/invitations-flow');
|
|
12
|
+
|
|
13
|
+
function parseInvitationsArgs(argv = []) {
|
|
14
|
+
const o = { lang: null, help: false, json: false };
|
|
15
|
+
for (let i = 0; i < argv.length; i++) {
|
|
16
|
+
const a = argv[i];
|
|
17
|
+
if (a === '--help' || a === '-h') o.help = true;
|
|
18
|
+
else if (a === '--lang') { const v = argv[++i]; o.lang = v === 'es' || v === 'en' ? v : null; }
|
|
19
|
+
else if (a.startsWith('--lang=')) { const v = a.slice(7); o.lang = v === 'es' || v === 'en' ? v : null; }
|
|
20
|
+
else if (a === '--json') o.json = true;
|
|
21
|
+
}
|
|
22
|
+
return o;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function run(
|
|
26
|
+
argv = process.argv.slice(2),
|
|
27
|
+
{ ask: injectedAsk = null, stdinIsTTY: ttyOverride = undefined, deps = null, session: injectedSession = null, out = null } = {},
|
|
28
|
+
) {
|
|
29
|
+
const opts = parseInvitationsArgs(argv);
|
|
30
|
+
const lang = opts.lang || detectReportLang();
|
|
31
|
+
const catalog = getCatalog(lang);
|
|
32
|
+
const fp = catalog.invitations;
|
|
33
|
+
const write = out || ((s) => process.stdout.write(s));
|
|
34
|
+
|
|
35
|
+
if (opts.help) {
|
|
36
|
+
write(fp.help + '\n');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const session = injectedSession || loadAuthSession();
|
|
41
|
+
if (sessionStatus(session) !== 'active') {
|
|
42
|
+
process.stderr.write(`\n ${fp.loginRequired}\n\n`);
|
|
43
|
+
process.exitCode = 1;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const stdinIsTTY = ttyOverride !== undefined ? ttyOverride : !!process.stdin.isTTY;
|
|
48
|
+
const ask = injectedAsk || createStdinAsk();
|
|
49
|
+
const sink = makeRevealSink({ json: opts.json, interactive: false, out, env: process.env });
|
|
50
|
+
try {
|
|
51
|
+
const io = makeIo({ ask, lang, out: sink.write, stdinIsTTY });
|
|
52
|
+
const result = await runInvitations({
|
|
53
|
+
io, rawOut: sink.write, session, catalog,
|
|
54
|
+
opts: { json: opts.json },
|
|
55
|
+
deps: deps || makeInvitationsDeps(),
|
|
56
|
+
});
|
|
57
|
+
await sink.finish();
|
|
58
|
+
if (result && result.ok === false) process.exitCode = 1;
|
|
59
|
+
return result;
|
|
60
|
+
} finally {
|
|
61
|
+
if (!injectedAsk) ask.close();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = { run, parseInvitationsArgs };
|
|
66
|
+
|
|
67
|
+
if (require.main === module) {
|
|
68
|
+
run();
|
|
69
|
+
}
|
package/bin/lang.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// `lang` — view or set the talent's languages (src/lang-flow.js).
|
|
5
|
+
|
|
6
|
+
const { detectReportLang, getCatalog } = require('../src/i18n');
|
|
7
|
+
const { loadAuthSession, sessionStatus } = require('../src/auth-session-store');
|
|
8
|
+
const { createStdinAsk } = require('../src/stdin-ask');
|
|
9
|
+
const { makeIo } = require('./register');
|
|
10
|
+
const { makeRevealSink } = require('../src/reveal-output');
|
|
11
|
+
const { runLang, makeLangDeps } = require('../src/lang-flow');
|
|
12
|
+
|
|
13
|
+
function parseLangArgs(argv = []) {
|
|
14
|
+
const o = { lang: null, help: false, json: false, set: false };
|
|
15
|
+
for (let i = 0; i < argv.length; i++) {
|
|
16
|
+
const a = argv[i];
|
|
17
|
+
if (a === '--help' || a === '-h') o.help = true;
|
|
18
|
+
else if (a === '--lang') { const v = argv[++i]; o.lang = v === 'es' || v === 'en' ? v : null; }
|
|
19
|
+
else if (a.startsWith('--lang=')) { const v = a.slice(7); o.lang = v === 'es' || v === 'en' ? v : null; }
|
|
20
|
+
else if (a === '--json') o.json = true;
|
|
21
|
+
else if (a === '--set') o.set = true;
|
|
22
|
+
}
|
|
23
|
+
return o;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async function run(
|
|
27
|
+
argv = process.argv.slice(2),
|
|
28
|
+
{ ask: injectedAsk = null, stdinIsTTY: ttyOverride = undefined, deps = null, session: injectedSession = null, out = null } = {},
|
|
29
|
+
) {
|
|
30
|
+
const opts = parseLangArgs(argv);
|
|
31
|
+
const lang = opts.lang || detectReportLang();
|
|
32
|
+
const catalog = getCatalog(lang);
|
|
33
|
+
const fp = catalog.lang;
|
|
34
|
+
const write = out || ((s) => process.stdout.write(s));
|
|
35
|
+
|
|
36
|
+
if (opts.help) {
|
|
37
|
+
write(fp.help + '\n');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const session = injectedSession || loadAuthSession();
|
|
42
|
+
if (sessionStatus(session) !== 'active') {
|
|
43
|
+
process.stderr.write(`\n ${fp.loginRequired}\n\n`);
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const stdinIsTTY = ttyOverride !== undefined ? ttyOverride : !!process.stdin.isTTY;
|
|
49
|
+
const ask = injectedAsk || createStdinAsk();
|
|
50
|
+
const sink = makeRevealSink({ json: opts.json, interactive: !!opts.set, out, env: process.env });
|
|
51
|
+
try {
|
|
52
|
+
const io = makeIo({ ask, lang, out: sink.write, stdinIsTTY });
|
|
53
|
+
const result = await runLang({
|
|
54
|
+
io, rawOut: sink.write, ask, session, catalog,
|
|
55
|
+
opts: { json: opts.json, set: opts.set, stdinIsTTY },
|
|
56
|
+
deps: deps || makeLangDeps(),
|
|
57
|
+
});
|
|
58
|
+
await sink.finish();
|
|
59
|
+
if (result && result.ok === false) process.exitCode = 1;
|
|
60
|
+
return result;
|
|
61
|
+
} finally {
|
|
62
|
+
if (!injectedAsk) ask.close();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = { run, parseLangArgs };
|
|
67
|
+
|
|
68
|
+
if (require.main === module) {
|
|
69
|
+
run();
|
|
70
|
+
}
|