prior-cli 1.2.3 → 1.2.5
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/bin/prior.js +108 -18
- package/lib/api.js +11 -1
- package/package.json +1 -1
package/bin/prior.js
CHANGED
|
@@ -14,6 +14,13 @@ const { renderMarkdown } = require('../lib/render');
|
|
|
14
14
|
const { getToken, getUsername, saveAuth, clearAuth } = require('../lib/config');
|
|
15
15
|
const { runAgent, CONFIRM_TOOLS } = require('../lib/agent');
|
|
16
16
|
|
|
17
|
+
function decodeToken(token) {
|
|
18
|
+
try {
|
|
19
|
+
const payload = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
|
|
20
|
+
return payload;
|
|
21
|
+
} catch { return {}; }
|
|
22
|
+
}
|
|
23
|
+
|
|
17
24
|
// ── Theme ──────────────────────────────────────────────────────
|
|
18
25
|
const THEME = '#9CE2D4';
|
|
19
26
|
const c = {
|
|
@@ -490,6 +497,78 @@ async function doLoginFlow() {
|
|
|
490
497
|
return username;
|
|
491
498
|
}
|
|
492
499
|
|
|
500
|
+
// ── Organization ToS flow ──────────────────────────────────────
|
|
501
|
+
const ORG_TOS = `
|
|
502
|
+
PRIOR NETWORK — ORGANIZATION ACCOUNT TERMS OF SERVICE
|
|
503
|
+
══════════════════════════════════════════════════════
|
|
504
|
+
|
|
505
|
+
By accepting, you agree to the following:
|
|
506
|
+
|
|
507
|
+
1. USAGE LIMITS
|
|
508
|
+
Organization accounts receive up to 500,000 tokens per day.
|
|
509
|
+
Abuse, automated scraping, or intentional limit exhaustion
|
|
510
|
+
may result in immediate account suspension.
|
|
511
|
+
|
|
512
|
+
2. ACCEPTABLE USE
|
|
513
|
+
You may use Prior AI for legitimate business, research, and
|
|
514
|
+
productivity purposes. You may not use it to generate harmful,
|
|
515
|
+
illegal, or malicious content.
|
|
516
|
+
|
|
517
|
+
3. DATA & PRIVACY
|
|
518
|
+
Conversations may be logged for safety and abuse monitoring.
|
|
519
|
+
Do not share confidential credentials or personal data.
|
|
520
|
+
|
|
521
|
+
4. ACCOUNTABILITY
|
|
522
|
+
Organization account holders are responsible for all activity
|
|
523
|
+
on their account. Sharing credentials with unauthorized users
|
|
524
|
+
is prohibited.
|
|
525
|
+
|
|
526
|
+
5. TERMINATION
|
|
527
|
+
Prior Network reserves the right to revoke organization access
|
|
528
|
+
at any time for violations of these terms.
|
|
529
|
+
|
|
530
|
+
These terms are legally binding upon acceptance.
|
|
531
|
+
`;
|
|
532
|
+
|
|
533
|
+
async function checkOrgTos(rl) {
|
|
534
|
+
const token = getToken();
|
|
535
|
+
if (!token) return;
|
|
536
|
+
const payload = decodeToken(token);
|
|
537
|
+
if (payload.role !== 'organization') return;
|
|
538
|
+
if (payload.tos_accepted) return;
|
|
539
|
+
|
|
540
|
+
console.clear();
|
|
541
|
+
banner();
|
|
542
|
+
console.log(DIVIDER);
|
|
543
|
+
console.log(c.bold(' Organization Account — Terms of Service'));
|
|
544
|
+
console.log(DIVIDER);
|
|
545
|
+
console.log(c.muted(ORG_TOS));
|
|
546
|
+
console.log(DIVIDER);
|
|
547
|
+
console.log(c.warn(' You must accept these terms to use your Organization account.'));
|
|
548
|
+
console.log('');
|
|
549
|
+
|
|
550
|
+
const accepted = await askConfirmKey('I accept the Terms of Service', rl);
|
|
551
|
+
if (!accepted) {
|
|
552
|
+
console.log('');
|
|
553
|
+
console.log(c.err(' Terms not accepted. Exiting.'));
|
|
554
|
+
console.log('');
|
|
555
|
+
process.exit(0);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
process.stdout.write(c.dim(' Saving acceptance…'));
|
|
559
|
+
try {
|
|
560
|
+
const result = await api.acceptTos();
|
|
561
|
+
if (result.token) saveAuth(result.token, getUsername());
|
|
562
|
+
clearLine();
|
|
563
|
+
console.log(c.ok(' ✓ Terms accepted. Welcome to Prior Organization.'));
|
|
564
|
+
console.log('');
|
|
565
|
+
} catch (err) {
|
|
566
|
+
clearLine();
|
|
567
|
+
console.log(c.err(` ✗ Could not save acceptance: ${err.message}`));
|
|
568
|
+
console.log('');
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
493
572
|
// ── Interactive Chat ───────────────────────────────────────────
|
|
494
573
|
async function startChat(opts = {}) {
|
|
495
574
|
// If not logged in, prompt inline instead of erroring out
|
|
@@ -505,6 +584,25 @@ async function startChat(opts = {}) {
|
|
|
505
584
|
}
|
|
506
585
|
|
|
507
586
|
const user = getUsername();
|
|
587
|
+
const payload = decodeToken(getToken() || '');
|
|
588
|
+
const isOrg = payload.role === 'organization';
|
|
589
|
+
|
|
590
|
+
// ── Readline needed early for ToS prompt ─────────────────────
|
|
591
|
+
const rl = readline.createInterface({
|
|
592
|
+
input: process.stdin,
|
|
593
|
+
output: process.stdout,
|
|
594
|
+
terminal: true,
|
|
595
|
+
historySize: 100,
|
|
596
|
+
completer: line => {
|
|
597
|
+
const cmds = ['/help', '/clear', '/model ', '/tools', '/uncensored', '/censored', '/login', '/logout', '/exit'];
|
|
598
|
+
if (!line.startsWith('/')) return [[], line];
|
|
599
|
+
const hits = cmds.filter(cmd => cmd.startsWith(line));
|
|
600
|
+
return [hits, line];
|
|
601
|
+
},
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
// ToS check for org accounts (before showing the chat UI)
|
|
605
|
+
await checkOrgTos(rl);
|
|
508
606
|
|
|
509
607
|
console.clear();
|
|
510
608
|
banner();
|
|
@@ -513,12 +611,16 @@ async function startChat(opts = {}) {
|
|
|
513
611
|
// Header row
|
|
514
612
|
const modelLabel = opts.model || 'default';
|
|
515
613
|
const cwdShort = process.cwd().replace(os.homedir(), '~');
|
|
614
|
+
const accountBadge = isOrg
|
|
615
|
+
? c.brand(' ◈ Organization Account')
|
|
616
|
+
: c.muted(' ◈ Standard Account');
|
|
516
617
|
console.log(
|
|
517
618
|
c.brand(' Prior AI') +
|
|
518
619
|
c.muted(' · ') +
|
|
519
620
|
c.bold(`@${user}`) +
|
|
520
621
|
c.muted(` · ${modelLabel}`)
|
|
521
622
|
);
|
|
623
|
+
console.log(accountBadge);
|
|
522
624
|
console.log(c.muted(` ${cwdShort}`));
|
|
523
625
|
console.log(c.ok(' ◉') + c.muted(' Agent mode ') + c.dim('· file web shell image prior-network'));
|
|
524
626
|
|
|
@@ -533,19 +635,6 @@ async function startChat(opts = {}) {
|
|
|
533
635
|
let currentModel = opts.model || null;
|
|
534
636
|
let uncensored = opts.uncensored || false;
|
|
535
637
|
|
|
536
|
-
const rl = readline.createInterface({
|
|
537
|
-
input: process.stdin,
|
|
538
|
-
output: process.stdout,
|
|
539
|
-
terminal: true,
|
|
540
|
-
historySize: 100,
|
|
541
|
-
completer: line => {
|
|
542
|
-
const cmds = ['/help', '/clear', '/model ', '/tools', '/uncensored', '/censored', '/login', '/logout', '/exit'];
|
|
543
|
-
if (!line.startsWith('/')) return [[], line];
|
|
544
|
-
const hits = cmds.filter(cmd => cmd.startsWith(line));
|
|
545
|
-
return [hits, line];
|
|
546
|
-
},
|
|
547
|
-
});
|
|
548
|
-
|
|
549
638
|
// ── Live slash-command suggestions ──────────────────────────
|
|
550
639
|
let clearSuggestions = () => {};
|
|
551
640
|
|
|
@@ -581,14 +670,12 @@ async function startChat(opts = {}) {
|
|
|
581
670
|
clearSuggestions();
|
|
582
671
|
if (!matches.length) return;
|
|
583
672
|
_suggCount = matches.length;
|
|
584
|
-
process.stdout.write('\x1b[s');
|
|
585
|
-
// Print newlines to scroll terminal and guarantee room below the prompt
|
|
586
|
-
process.stdout.write('\n'.repeat(matches.length));
|
|
587
|
-
process.stdout.write(`\x1b[${matches.length}A`); // move cursor back up to prompt line
|
|
673
|
+
process.stdout.write('\x1b[s'); // save cursor at end of typed input
|
|
588
674
|
for (const { cmd, desc } of matches) {
|
|
675
|
+
// \x1b[B = cursor down 1 (no scroll), \r = col 0, \x1b[2K = clear line
|
|
589
676
|
process.stdout.write(`\x1b[B\r\x1b[2K${c.brand(' ' + cmd.padEnd(14))}${c.dim(desc)}`);
|
|
590
677
|
}
|
|
591
|
-
process.stdout.write('\x1b[u');
|
|
678
|
+
process.stdout.write('\x1b[u'); // restore cursor to end of typed input
|
|
592
679
|
}
|
|
593
680
|
|
|
594
681
|
process.stdin.on('keypress', (ch, key) => {
|
|
@@ -857,7 +944,10 @@ Keep it under 350 words. Write prior.md now.`;
|
|
|
857
944
|
const used = data.used ?? data.tokens_used ?? data.tokensUsed ?? data.totalTokens ?? 0;
|
|
858
945
|
const limit = data.limit ?? data.token_limit ?? data.dailyLimit ?? null;
|
|
859
946
|
const pct = limit ? Math.min(100, Math.round((used / limit) * 100)) : null;
|
|
947
|
+
const role = data.role || decodeToken(getToken() || '').role || 'user';
|
|
948
|
+
const acctLabel = role === 'organization' ? c.brand(' Organization Account') : c.muted(' Standard Account');
|
|
860
949
|
console.log('');
|
|
950
|
+
console.log(acctLabel);
|
|
861
951
|
if (pct !== null) {
|
|
862
952
|
console.log(` ${progressBar(pct)}`);
|
|
863
953
|
console.log(` ${c.bold(used.toLocaleString())} ${c.muted('/')} ${limit.toLocaleString()} tokens ${c.muted(`(${pct}%)`)}`);
|
package/lib/api.js
CHANGED
|
@@ -191,8 +191,18 @@ async function search(query) {
|
|
|
191
191
|
return data;
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
+
async function acceptTos() {
|
|
195
|
+
const res = await fetch(`${BASE}/network/api/user/tos-accept`, {
|
|
196
|
+
method: 'POST',
|
|
197
|
+
headers: authHeaders(),
|
|
198
|
+
});
|
|
199
|
+
const data = await res.json();
|
|
200
|
+
if (!res.ok) throw new Error(data.error || 'Failed to accept ToS');
|
|
201
|
+
return data; // { ok, token, tos_accepted_at }
|
|
202
|
+
}
|
|
203
|
+
|
|
194
204
|
module.exports = {
|
|
195
|
-
login, infer,
|
|
205
|
+
login, infer, acceptTos,
|
|
196
206
|
generate,
|
|
197
207
|
generateImage, pollImageProgress, downloadImage,
|
|
198
208
|
getModels, getChats, getUsage, getWeather, search,
|