empuno 1.0.1 → 1.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/README.md +18 -0
- package/empuno.mjs +273 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,6 +51,22 @@ komutu CLI güncellemesi olmadan görünür.
|
|
|
51
51
|
- `--json '{…}'` / `--json @govde.json`, `--dry-run`, `--output yol`,
|
|
52
52
|
`--profile ad` (birden çok firma).
|
|
53
53
|
|
|
54
|
+
## Talepler (empuno ekibine)
|
|
55
|
+
|
|
56
|
+
Ajanınız yapamadığı bir işlemi, bir hatayı ya da geliştirme önerisini empuno
|
|
57
|
+
ekibine talep olarak iletir; yazışma çok mesajlıdır, ekip yanıtlar ve kapatır.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
empuno tickets open "Toplu izin onayı" --kind feature --body "Bekleyen izinleri tek komutla onaylamak istiyoruz." --command leave-requests.approve
|
|
61
|
+
empuno tickets --unread # ekibin yanıtladıkları
|
|
62
|
+
empuno tickets show TK-7Q3M9X # yazışmayı oku
|
|
63
|
+
empuno tickets reply TK-7Q3M9X "Her ay sonu gerekiyor."
|
|
64
|
+
empuno tickets close TK-7Q3M9X --note "Çözüldü"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Türler: `feature`, `bug`, `criticism`, `question`, `missing_command`, `docs`.
|
|
68
|
+
Gövde için `--body @not.md` ya da `--body -` (stdin) kullanılabilir.
|
|
69
|
+
|
|
54
70
|
## Çıktı sözleşmesi
|
|
55
71
|
|
|
56
72
|
- stdout **her zaman JSON** (TTY'de girintili).
|
|
@@ -66,6 +82,8 @@ empuno İK sistemine `empuno` CLI ile erişimin var. Önce `empuno commands <ana
|
|
|
66
82
|
ile komutu bul, `empuno describe <komut>` ile parametrelerini öğren, sonra çalıştır.
|
|
67
83
|
422 → `errors` alanlarını düzeltip tekrar dene; 403 → yetki yetmiyor, kullanıcıya
|
|
68
84
|
`required_permission`ı söyle. Geri alınamaz işlemlerden önce kullanıcıdan onay al.
|
|
85
|
+
Yapamadığın işlem / hata / öneri için: empuno tickets open "<başlık>" --kind missing_command|bug|feature --body "…";
|
|
86
|
+
yanıtları `empuno tickets --unread` ile kontrol et.
|
|
69
87
|
```
|
|
70
88
|
|
|
71
89
|
## Güvenlik
|
package/empuno.mjs
CHANGED
|
@@ -21,7 +21,7 @@ import os from 'node:os';
|
|
|
21
21
|
import path from 'node:path';
|
|
22
22
|
import crypto from 'node:crypto';
|
|
23
23
|
|
|
24
|
-
const VERSION = '1.0
|
|
24
|
+
const VERSION = '1.1.0'; // EMPUNO_CLI_VERSION — config/agent_api.php cli_version + package.json ile aynı tutulur
|
|
25
25
|
const NPM_PACKAGE = 'empuno';
|
|
26
26
|
const DEFAULT_URL = 'https://empuno.com';
|
|
27
27
|
const CATALOG_TTL_MS = 10 * 60 * 1000;
|
|
@@ -89,7 +89,8 @@ function resolveAuth(flags) {
|
|
|
89
89
|
const profile = cfg.profiles?.[profileName] || {};
|
|
90
90
|
const key = flags.key || process.env.EMPUNO_API_KEY || profile.key || null;
|
|
91
91
|
const url = (flags.url || process.env.EMPUNO_URL || profile.url || DEFAULT_URL).replace(/\/+$/, '');
|
|
92
|
-
|
|
92
|
+
const staffToken = flags.token || process.env.EMPUNO_STAFF_TOKEN || profile.staff_token || null;
|
|
93
|
+
return { key, url, profileName, staffToken };
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
function requireKey(auth) {
|
|
@@ -103,14 +104,15 @@ function requireKey(auth) {
|
|
|
103
104
|
|
|
104
105
|
// ─── argüman ayrıştırma ────────────────────────────────────────────────────
|
|
105
106
|
|
|
106
|
-
const GLOBAL_FLAGS = new Set(['key', 'url', 'profile', 'pretty', 'compact', 'text', 'json-out', 'dry-run', 'output', 'refresh', 'all', 'full', 'module', 'writes', 'reads', 'help', 'key-stdin', 'query', 'json', 'file', 'quiet']);
|
|
107
|
+
const GLOBAL_FLAGS = new Set(['key', 'token', 'url', 'profile', 'pretty', 'compact', 'text', 'json-out', 'dry-run', 'output', 'refresh', 'all', 'full', 'module', 'writes', 'reads', 'help', 'key-stdin', 'query', 'json', 'file', 'quiet']);
|
|
107
108
|
const BOOLEAN_FLAGS = new Set(['pretty', 'compact', 'text', 'json-out', 'dry-run', 'refresh', 'all', 'full', 'writes', 'reads', 'help', 'key-stdin', 'quiet']);
|
|
108
109
|
|
|
109
110
|
/**
|
|
110
111
|
* argv → { positional: [], flags: {global}, fields: [[name, rawValue]] }.
|
|
111
112
|
* `--ad değer`, `--ad=değer`, tekrar eden bayrak → dizi, `--` sonrası hep positional.
|
|
112
113
|
*/
|
|
113
|
-
function parseArgs(argv) {
|
|
114
|
+
function parseArgs(argv, extraBooleans = []) {
|
|
115
|
+
const extraBool = new Set(extraBooleans);
|
|
114
116
|
const positional = [];
|
|
115
117
|
const flags = { query: [], file: [] };
|
|
116
118
|
const fields = [];
|
|
@@ -134,7 +136,7 @@ function parseArgs(argv) {
|
|
|
134
136
|
name = name.slice(0, eq);
|
|
135
137
|
}
|
|
136
138
|
|
|
137
|
-
if (GLOBAL_FLAGS.has(name) && BOOLEAN_FLAGS.has(name)) {
|
|
139
|
+
if ((GLOBAL_FLAGS.has(name) && BOOLEAN_FLAGS.has(name)) || extraBool.has(name)) {
|
|
138
140
|
flags[name] = value === undefined ? true : !['0', 'false', 'no'].includes(value);
|
|
139
141
|
i++;
|
|
140
142
|
continue;
|
|
@@ -393,7 +395,7 @@ async function findCommand(auth, name, flags) {
|
|
|
393
395
|
if (cmd) {
|
|
394
396
|
const need = cmd.requires_company_admin ? ['company_admin'] : cmd.permissions;
|
|
395
397
|
const err = new UsageError(`"${name}" bu anahtarın kapsamında değil. Gereken yetki: ${need.join(', ') || '—'}. Anahtar kapsamını panelden genişletin (Firma Ayarları → API).`);
|
|
396
|
-
err.payload = { ok: false, error: 'scope_required', command: name, required: need };
|
|
398
|
+
err.payload = { ok: false, error: 'scope_required', command: name, required: need, hint: 'Kapsamı anahtar sahibi panelden genişletir; kullanıcıya bildirin.' };
|
|
397
399
|
throw err;
|
|
398
400
|
}
|
|
399
401
|
|
|
@@ -402,7 +404,13 @@ async function findCommand(auth, name, flags) {
|
|
|
402
404
|
.filter((c) => c.includes(name.split('.')[0]) || name.includes(c.split('.')[0]))
|
|
403
405
|
.slice(0, 8);
|
|
404
406
|
const err = new UsageError(`bilinmeyen komut "${name}".${suggestions.length ? ` Şunlardan biri mi: ${suggestions.join(', ')}` : ' `empuno commands` ile listeleyin.'}`);
|
|
405
|
-
err.payload = {
|
|
407
|
+
err.payload = {
|
|
408
|
+
ok: false,
|
|
409
|
+
error: 'unknown_command',
|
|
410
|
+
command: name,
|
|
411
|
+
suggestions,
|
|
412
|
+
hint: `Gereken işlem yoksa talep açın: empuno tickets open "<başlık>" --kind missing_command --command ${name} --body "<ne yapmak istediğiniz>"`,
|
|
413
|
+
};
|
|
406
414
|
throw err;
|
|
407
415
|
}
|
|
408
416
|
|
|
@@ -671,6 +679,241 @@ async function cmdUpdate(args) {
|
|
|
671
679
|
return 0;
|
|
672
680
|
}
|
|
673
681
|
|
|
682
|
+
// ─── talepler (ticket) ─────────────────────────────────────────────────────
|
|
683
|
+
|
|
684
|
+
const TICKET_KINDS = {
|
|
685
|
+
feature: 'Geliştirme isteği',
|
|
686
|
+
bug: 'Hata bildirimi',
|
|
687
|
+
criticism: 'Eleştiri / geri bildirim',
|
|
688
|
+
question: 'Soru',
|
|
689
|
+
missing_command: 'Eksik komut / işlem',
|
|
690
|
+
docs: 'Dokümantasyon',
|
|
691
|
+
};
|
|
692
|
+
|
|
693
|
+
/** Alan bayraklarını nesneye çevirir (son değer kazanır). */
|
|
694
|
+
function fieldMap(fields) {
|
|
695
|
+
const out = {};
|
|
696
|
+
for (const [k, v] of fields) out[k] = v;
|
|
697
|
+
return out;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/** "@dosya.md" → dosya içeriği; "-" → stdin; diğerleri olduğu gibi. */
|
|
701
|
+
function readText(value) {
|
|
702
|
+
if (value === undefined || value === null || value === true) return undefined;
|
|
703
|
+
const text = String(value);
|
|
704
|
+
if (text === '-') return fs.readFileSync(0, 'utf8');
|
|
705
|
+
if (text.startsWith('@') && text.length > 1) {
|
|
706
|
+
const file = text.slice(1);
|
|
707
|
+
if (!fs.existsSync(file)) throw new UsageError(`dosya bulunamadı: ${file}`);
|
|
708
|
+
return fs.readFileSync(file, 'utf8');
|
|
709
|
+
}
|
|
710
|
+
return text;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
function ticketNumber(value) {
|
|
714
|
+
if (!value) throw new UsageError('talep numarası gerekli (ör. TK-7Q3M9X)');
|
|
715
|
+
const n = String(value).toUpperCase();
|
|
716
|
+
return n.startsWith('TK-') ? n : `TK-${n}`;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
function printTicketList(result, perspective) {
|
|
720
|
+
if (!wantsText() || !Array.isArray(result?.data)) {
|
|
721
|
+
print(result);
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
for (const t of result.data) {
|
|
725
|
+
const dot = t.unread ? '●' : ' ';
|
|
726
|
+
const who = perspective === 'staff' && t.company ? ` · ${t.company.name}` : '';
|
|
727
|
+
process.stdout.write(`${dot} ${t.number} ${t.status.padEnd(8)} ${t.kind.padEnd(15)} ${t.title}${who}\n`);
|
|
728
|
+
}
|
|
729
|
+
const total = result.meta?.total ?? result.data.length;
|
|
730
|
+
process.stdout.write(`\n${total} talep. Ayrıntı: empuno ${perspective === 'staff' ? 'support' : 'tickets'} show <numara>\n`);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
function printTicket(result) {
|
|
734
|
+
const t = result?.data;
|
|
735
|
+
if (!wantsText() || !t?.messages) {
|
|
736
|
+
print(result);
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
process.stdout.write(`${t.number} · ${t.title}\n${t.kind_label} · öncelik ${t.priority} · ${t.status}${t.company ? ` · ${t.company.name}` : ''}\n`);
|
|
740
|
+
for (const m of t.messages) {
|
|
741
|
+
if (m.author_type === 'system') {
|
|
742
|
+
process.stdout.write(`\n — ${m.body} (${m.created_at})\n`);
|
|
743
|
+
continue;
|
|
744
|
+
}
|
|
745
|
+
process.stdout.write(`\n[${m.author_type === 'staff' ? 'empuno' : 'ajan'}] ${m.author} — ${m.created_at}\n${m.body}\n`);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
async function cmdTickets(args) {
|
|
750
|
+
const { flags, fields, positional } = args;
|
|
751
|
+
const auth = resolveAuth(flags);
|
|
752
|
+
requireKey(auth);
|
|
753
|
+
const opts = fieldMap(fields);
|
|
754
|
+
const [action = 'list', ...rest] = positional;
|
|
755
|
+
const base = '/api/company/v1/tickets';
|
|
756
|
+
|
|
757
|
+
const send = async (method, urlPath, body = null, query = {}) => {
|
|
758
|
+
const response = await request(auth, method, urlPath, { body, query, dryRun: flags['dry-run'] });
|
|
759
|
+
return response;
|
|
760
|
+
};
|
|
761
|
+
|
|
762
|
+
switch (action) {
|
|
763
|
+
case 'list':
|
|
764
|
+
case 'ls': {
|
|
765
|
+
const query = {};
|
|
766
|
+
if (opts.status) query.status = opts.status;
|
|
767
|
+
if (flags.mine) query.mine = 1;
|
|
768
|
+
if (flags.unread) query.unread = 1;
|
|
769
|
+
if (opts.page) query.page = opts.page;
|
|
770
|
+
if (opts.per_page) query.per_page = opts.per_page;
|
|
771
|
+
const r = await send('GET', base, null, query);
|
|
772
|
+
if (r.dryRun) return print(r.result), 0;
|
|
773
|
+
printTicketList(r.result, 'agent');
|
|
774
|
+
return r.ok ? 0 : 1;
|
|
775
|
+
}
|
|
776
|
+
case 'open':
|
|
777
|
+
case 'new': {
|
|
778
|
+
const title = rest[0] ?? opts.title;
|
|
779
|
+
const body = readText(opts.body ?? rest[1]);
|
|
780
|
+
const kind = opts.kind ?? 'feature';
|
|
781
|
+
if (!title || !body) {
|
|
782
|
+
throw new UsageError('kullanım: empuno tickets open "<başlık>" --kind feature|bug|criticism|question|missing_command|docs --body "<açıklama>"|@dosya.md');
|
|
783
|
+
}
|
|
784
|
+
let context = opts.context ? readJsonArg(String(opts.context)) : {};
|
|
785
|
+
if (opts.command) context = { ...context, command: String(opts.command) };
|
|
786
|
+
const r = await send('POST', base, { title: String(title), kind, body, priority: opts.priority, context: Object.keys(context).length ? context : undefined });
|
|
787
|
+
if (r.dryRun) return print(r.result), 0;
|
|
788
|
+
print(r.result);
|
|
789
|
+
return r.ok ? 0 : 1;
|
|
790
|
+
}
|
|
791
|
+
case 'show':
|
|
792
|
+
case 'get': {
|
|
793
|
+
const r = await send('GET', `${base}/${ticketNumber(rest[0])}`);
|
|
794
|
+
if (r.dryRun) return print(r.result), 0;
|
|
795
|
+
printTicket(r.result);
|
|
796
|
+
return r.ok ? 0 : 1;
|
|
797
|
+
}
|
|
798
|
+
case 'reply': {
|
|
799
|
+
const body = readText(opts.body ?? rest[1]);
|
|
800
|
+
if (!body) throw new UsageError('kullanım: empuno tickets reply <numara> "<mesaj>" (ya da --body @dosya.md)');
|
|
801
|
+
const r = await send('POST', `${base}/${ticketNumber(rest[0])}/messages`, { body });
|
|
802
|
+
print(r.result);
|
|
803
|
+
return r.ok || r.dryRun ? 0 : 1;
|
|
804
|
+
}
|
|
805
|
+
case 'close': {
|
|
806
|
+
const note = readText(opts.note ?? rest[1]);
|
|
807
|
+
const r = await send('POST', `${base}/${ticketNumber(rest[0])}/close`, note ? { note } : {});
|
|
808
|
+
print(r.result);
|
|
809
|
+
return r.ok || r.dryRun ? 0 : 1;
|
|
810
|
+
}
|
|
811
|
+
case 'kinds':
|
|
812
|
+
print({ kinds: TICKET_KINDS, priorities: ['low', 'normal', 'high'] });
|
|
813
|
+
return 0;
|
|
814
|
+
default:
|
|
815
|
+
throw new UsageError(`bilinmeyen tickets işlemi "${action}". Kullanım: empuno tickets [list|open|show|reply|close|kinds]`);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
// ─── destek (yalnız empuno ekibinin ajanları — emp_staff_ jetonu) ────────────
|
|
820
|
+
|
|
821
|
+
function requireStaff(auth) {
|
|
822
|
+
if (!auth.staffToken) {
|
|
823
|
+
throw new UsageError('destek jetonu yok. `empuno support login` ya da EMPUNO_STAFF_TOKEN. Jeton: empuno root paneli → Ajan Talepleri → Destek ajanları.');
|
|
824
|
+
}
|
|
825
|
+
if (!auth.staffToken.startsWith('emp_staff_')) {
|
|
826
|
+
throw new UsageError('geçersiz destek jetonu biçimi (emp_staff_ ile başlamalı).');
|
|
827
|
+
}
|
|
828
|
+
return { ...auth, key: auth.staffToken };
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
async function cmdSupport(args) {
|
|
832
|
+
const { flags, fields, positional } = args;
|
|
833
|
+
const opts = fieldMap(fields);
|
|
834
|
+
const [action = 'tickets', ...rest] = positional;
|
|
835
|
+
const base = '/api/support/v1';
|
|
836
|
+
|
|
837
|
+
if (action === 'login') {
|
|
838
|
+
let token = flags.token || process.env.EMPUNO_STAFF_TOKEN || rest[0];
|
|
839
|
+
if (flags['token-stdin'] || (!token && !process.stdin.isTTY)) token = fs.readFileSync(0, 'utf8').trim();
|
|
840
|
+
else if (!token) token = await prompt('Destek jetonu (emp_staff_…): ');
|
|
841
|
+
const auth = requireStaff({ ...resolveAuth(flags), staffToken: token?.trim() });
|
|
842
|
+
const { ok, result } = await request(auth, 'GET', `${base}/me`);
|
|
843
|
+
if (!ok) {
|
|
844
|
+
print(result);
|
|
845
|
+
return 1;
|
|
846
|
+
}
|
|
847
|
+
const cfg = readConfig();
|
|
848
|
+
cfg.profiles = cfg.profiles || {};
|
|
849
|
+
const name = auth.profileName;
|
|
850
|
+
cfg.profiles[name] = { ...(cfg.profiles[name] || { url: auth.url }), staff_token: auth.key };
|
|
851
|
+
if (!cfg.default || !cfg.profiles[cfg.default]) cfg.default = name;
|
|
852
|
+
writeConfig(cfg);
|
|
853
|
+
print({ ok: true, profile: name, token: result.token, counts: result.counts });
|
|
854
|
+
return 0;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
const auth = requireStaff(resolveAuth(flags));
|
|
858
|
+
const call = (method, urlPath, body = null, query = {}) => request(auth, method, urlPath, { body, query, dryRun: flags['dry-run'] });
|
|
859
|
+
|
|
860
|
+
switch (action) {
|
|
861
|
+
case 'whoami':
|
|
862
|
+
case 'me': {
|
|
863
|
+
const r = await call('GET', `${base}/me`);
|
|
864
|
+
print(r.result);
|
|
865
|
+
return r.ok || r.dryRun ? 0 : 1;
|
|
866
|
+
}
|
|
867
|
+
case 'tickets':
|
|
868
|
+
case 'list':
|
|
869
|
+
case 'ls': {
|
|
870
|
+
const query = {};
|
|
871
|
+
for (const k of ['status', 'kind', 'company', 'q', 'page', 'per_page']) if (opts[k] !== undefined) query[k] = opts[k];
|
|
872
|
+
if (flags.unread) query.unread = 1;
|
|
873
|
+
const r = await call('GET', `${base}/tickets`, null, query);
|
|
874
|
+
if (r.dryRun) return print(r.result), 0;
|
|
875
|
+
printTicketList(r.result, 'staff');
|
|
876
|
+
return r.ok ? 0 : 1;
|
|
877
|
+
}
|
|
878
|
+
case 'show':
|
|
879
|
+
case 'get': {
|
|
880
|
+
const r = await call('GET', `${base}/tickets/${ticketNumber(rest[0])}`);
|
|
881
|
+
if (r.dryRun) return print(r.result), 0;
|
|
882
|
+
printTicket(r.result);
|
|
883
|
+
return r.ok ? 0 : 1;
|
|
884
|
+
}
|
|
885
|
+
case 'reply': {
|
|
886
|
+
const body = readText(opts.body ?? rest[1]);
|
|
887
|
+
if (!body) throw new UsageError('kullanım: empuno support reply <numara> "<yanıt>" [--close]');
|
|
888
|
+
const r = await call('POST', `${base}/tickets/${ticketNumber(rest[0])}/messages`, { body, close: flags.close ? true : undefined });
|
|
889
|
+
print(r.result);
|
|
890
|
+
return r.ok || r.dryRun ? 0 : 1;
|
|
891
|
+
}
|
|
892
|
+
case 'close': {
|
|
893
|
+
const note = readText(opts.note ?? rest[1]);
|
|
894
|
+
const r = await call('POST', `${base}/tickets/${ticketNumber(rest[0])}/close`, note ? { note } : {});
|
|
895
|
+
print(r.result);
|
|
896
|
+
return r.ok || r.dryRun ? 0 : 1;
|
|
897
|
+
}
|
|
898
|
+
case 'reopen': {
|
|
899
|
+
const r = await call('POST', `${base}/tickets/${ticketNumber(rest[0])}/reopen`);
|
|
900
|
+
print(r.result);
|
|
901
|
+
return r.ok || r.dryRun ? 0 : 1;
|
|
902
|
+
}
|
|
903
|
+
case 'set': {
|
|
904
|
+
const body = {};
|
|
905
|
+
if (opts.kind) body.kind = opts.kind;
|
|
906
|
+
if (opts.priority) body.priority = opts.priority;
|
|
907
|
+
if (!Object.keys(body).length) throw new UsageError('kullanım: empuno support set <numara> [--kind bug] [--priority high]');
|
|
908
|
+
const r = await call('PATCH', `${base}/tickets/${ticketNumber(rest[0])}`, body);
|
|
909
|
+
print(r.result);
|
|
910
|
+
return r.ok || r.dryRun ? 0 : 1;
|
|
911
|
+
}
|
|
912
|
+
default:
|
|
913
|
+
throw new UsageError(`bilinmeyen support işlemi "${action}". Kullanım: empuno support [login|whoami|tickets|show|reply|close|reopen|set]`);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
|
|
674
917
|
const HELP = `empuno ${VERSION} — empuno İK sistemini komut satırından (ve ajanlardan) yönetin
|
|
675
918
|
|
|
676
919
|
KURULUM
|
|
@@ -700,6 +943,18 @@ ALANLAR
|
|
|
700
943
|
--alan @./dosya.pdf | --file alan=./dosya.pdf # multipart yükleme
|
|
701
944
|
--query anahtar=değer # yazma isteğinde ek sorgu parametresi
|
|
702
945
|
|
|
946
|
+
TALEPLER (geliştirme isteği, hata, eleştiri, soru → empuno ekibi)
|
|
947
|
+
empuno tickets [--status active|open|answered|closed|all] [--unread] [--mine]
|
|
948
|
+
empuno tickets open "Toplu izin onayı" --kind feature --body "…"|@not.md [--priority high] [--command leave-requests.approve]
|
|
949
|
+
empuno tickets show TK-7Q3M9X # yazışmayı okur (okunmadı bayrağı düşer)
|
|
950
|
+
empuno tickets reply TK-7Q3M9X "Ek bilgi…"
|
|
951
|
+
empuno tickets close TK-7Q3M9X [--note "Çözüldü"]
|
|
952
|
+
empuno tickets kinds # feature, bug, criticism, question, missing_command, docs
|
|
953
|
+
|
|
954
|
+
EMPUNO EKİBİ (destek jetonu emp_staff_…, EMPUNO_STAFF_TOKEN)
|
|
955
|
+
empuno support login | whoami | tickets [--unread] [--status] [--kind] [--company]
|
|
956
|
+
empuno support show|reply|close|reopen <numara> ["mesaj"] [--close] · empuno support set <numara> --priority high
|
|
957
|
+
|
|
703
958
|
GENEL BAYRAKLAR
|
|
704
959
|
--profile ad --key emp_live_… --url https://empuno.com --dry-run --output yol
|
|
705
960
|
--text | --json-out --pretty | --compact --refresh (katalog önbelleğini tazele)
|
|
@@ -714,7 +969,8 @@ BELGE: https://empuno.com/api-docs/agent
|
|
|
714
969
|
|
|
715
970
|
async function main() {
|
|
716
971
|
const argv = process.argv.slice(2);
|
|
717
|
-
const
|
|
972
|
+
const ticketish = ['tickets', 'ticket', 'support'].includes(argv.find((a) => !a.startsWith('--')) ?? '');
|
|
973
|
+
const args = parseArgs(argv, ticketish ? ['mine', 'unread', 'close', 'token-stdin'] : []);
|
|
718
974
|
const [sub, ...rest] = args.positional;
|
|
719
975
|
args.positional = rest;
|
|
720
976
|
|
|
@@ -723,6 +979,10 @@ async function main() {
|
|
|
723
979
|
return 0;
|
|
724
980
|
}
|
|
725
981
|
if (args.flags.help) {
|
|
982
|
+
if (['tickets', 'ticket', 'support', 'login', 'commands', 'describe', 'call', 'api'].includes(sub)) {
|
|
983
|
+
process.stdout.write(HELP);
|
|
984
|
+
return 0;
|
|
985
|
+
}
|
|
726
986
|
args.positional = [sub];
|
|
727
987
|
return cmdDescribe(args);
|
|
728
988
|
}
|
|
@@ -750,6 +1010,11 @@ async function main() {
|
|
|
750
1010
|
return cmdApi(args);
|
|
751
1011
|
case 'update':
|
|
752
1012
|
return cmdUpdate(args);
|
|
1013
|
+
case 'tickets':
|
|
1014
|
+
case 'ticket':
|
|
1015
|
+
return cmdTickets(args);
|
|
1016
|
+
case 'support':
|
|
1017
|
+
return cmdSupport(args);
|
|
753
1018
|
case 'run':
|
|
754
1019
|
if (!args.positional[0]) throw new UsageError('kullanım: empuno run <komut> …');
|
|
755
1020
|
return cmdRun({ ...args, positional: args.positional.slice(1) }, args.positional[0]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "empuno",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "empuno İK platformunun komut satırı: yönetim panelindeki tüm işlemleri (izin, bordro, vardiya, PDKS, zimmet, masraf, işe alım) yapay zekâ ajanlarına ve otomasyonlara açar.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|