@halyard/cli 0.1.1 → 0.2.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 +115 -0
- package/dist/cli.js +30 -3
- package/dist/cli.js.map +1 -1
- package/dist/commands/api-keys.d.ts +3 -0
- package/dist/commands/api-keys.d.ts.map +1 -0
- package/dist/commands/api-keys.js +90 -0
- package/dist/commands/api-keys.js.map +1 -0
- package/dist/commands/hook.d.ts +6 -0
- package/dist/commands/hook.d.ts.map +1 -0
- package/dist/commands/hook.js +106 -0
- package/dist/commands/hook.js.map +1 -0
- package/dist/commands/login.d.ts +17 -0
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +170 -65
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/orgs.d.ts +3 -0
- package/dist/commands/orgs.d.ts.map +1 -0
- package/dist/commands/orgs.js +102 -0
- package/dist/commands/orgs.js.map +1 -0
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +29 -6
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/sessions.d.ts +3 -0
- package/dist/commands/sessions.d.ts.map +1 -0
- package/dist/commands/sessions.js +139 -0
- package/dist/commands/sessions.js.map +1 -0
- package/dist/commands/setup.d.ts +3 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +58 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/skills.d.ts +12 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/skills.js +171 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +51 -49
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/users.d.ts +13 -0
- package/dist/commands/users.d.ts.map +1 -0
- package/dist/commands/users.js +205 -0
- package/dist/commands/users.js.map +1 -0
- package/dist/commands/whoami.d.ts +21 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +77 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/lib/api-client.d.ts +64 -2
- package/dist/lib/api-client.d.ts.map +1 -1
- package/dist/lib/api-client.js +32 -7
- package/dist/lib/api-client.js.map +1 -1
- package/dist/lib/auth.d.ts +43 -6
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +106 -25
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/config-files.d.ts +6 -0
- package/dist/lib/config-files.d.ts.map +1 -0
- package/dist/lib/config-files.js +27 -0
- package/dist/lib/config-files.js.map +1 -0
- package/dist/lib/config.d.ts +13 -7
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +22 -8
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/copilot-export.d.ts +31 -0
- package/dist/lib/copilot-export.d.ts.map +1 -0
- package/dist/lib/copilot-export.js +129 -0
- package/dist/lib/copilot-export.js.map +1 -0
- package/dist/lib/discovery.d.ts +60 -2
- package/dist/lib/discovery.d.ts.map +1 -1
- package/dist/lib/discovery.js +187 -15
- package/dist/lib/discovery.js.map +1 -1
- package/dist/lib/hook-discovery.d.ts +43 -0
- package/dist/lib/hook-discovery.d.ts.map +1 -0
- package/dist/lib/hook-discovery.js +90 -0
- package/dist/lib/hook-discovery.js.map +1 -0
- package/dist/lib/hook-input.d.ts +36 -0
- package/dist/lib/hook-input.d.ts.map +1 -0
- package/dist/lib/hook-input.js +161 -0
- package/dist/lib/hook-input.js.map +1 -0
- package/dist/lib/hook-runner.d.ts +48 -0
- package/dist/lib/hook-runner.d.ts.map +1 -0
- package/dist/lib/hook-runner.js +306 -0
- package/dist/lib/hook-runner.js.map +1 -0
- package/dist/lib/http.d.ts +18 -0
- package/dist/lib/http.d.ts.map +1 -0
- package/dist/lib/http.js +54 -0
- package/dist/lib/http.js.map +1 -0
- package/dist/lib/opencode-export.d.ts +22 -0
- package/dist/lib/opencode-export.d.ts.map +1 -0
- package/dist/lib/opencode-export.js +53 -0
- package/dist/lib/opencode-export.js.map +1 -0
- package/dist/lib/output.d.ts +27 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +74 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/preflight.d.ts +35 -0
- package/dist/lib/preflight.d.ts.map +1 -0
- package/dist/lib/preflight.js +54 -0
- package/dist/lib/preflight.js.map +1 -0
- package/dist/lib/repo-binding.d.ts +43 -0
- package/dist/lib/repo-binding.d.ts.map +1 -0
- package/dist/lib/repo-binding.js +158 -0
- package/dist/lib/repo-binding.js.map +1 -0
- package/dist/lib/repo-identity.d.ts +29 -0
- package/dist/lib/repo-identity.d.ts.map +1 -0
- package/dist/lib/repo-identity.js +113 -0
- package/dist/lib/repo-identity.js.map +1 -0
- package/dist/lib/setup-hooks.d.ts +41 -0
- package/dist/lib/setup-hooks.d.ts.map +1 -0
- package/dist/lib/setup-hooks.js +276 -0
- package/dist/lib/setup-hooks.js.map +1 -0
- package/dist/lib/setup.d.ts +47 -0
- package/dist/lib/setup.d.ts.map +1 -0
- package/dist/lib/setup.js +179 -0
- package/dist/lib/setup.js.map +1 -0
- package/dist/lib/skill-batches.d.ts +16 -0
- package/dist/lib/skill-batches.d.ts.map +1 -0
- package/dist/lib/skill-batches.js +35 -0
- package/dist/lib/skill-batches.js.map +1 -0
- package/dist/lib/skill-files.d.ts +4 -0
- package/dist/lib/skill-files.d.ts.map +1 -0
- package/dist/lib/skill-files.js +36 -0
- package/dist/lib/skill-files.js.map +1 -0
- package/dist/lib/skill-fingerprint.d.ts +55 -0
- package/dist/lib/skill-fingerprint.d.ts.map +1 -0
- package/dist/lib/skill-fingerprint.js +204 -0
- package/dist/lib/skill-fingerprint.js.map +1 -0
- package/dist/lib/skills-discovery.d.ts +57 -0
- package/dist/lib/skills-discovery.d.ts.map +1 -0
- package/dist/lib/skills-discovery.js +157 -0
- package/dist/lib/skills-discovery.js.map +1 -0
- package/dist/lib/skills-sync.d.ts +66 -0
- package/dist/lib/skills-sync.d.ts.map +1 -0
- package/dist/lib/skills-sync.js +251 -0
- package/dist/lib/skills-sync.js.map +1 -0
- package/dist/lib/sync-runner.d.ts +56 -0
- package/dist/lib/sync-runner.d.ts.map +1 -0
- package/dist/lib/sync-runner.js +106 -0
- package/dist/lib/sync-runner.js.map +1 -0
- package/dist/lib/sync-state.d.ts +36 -6
- package/dist/lib/sync-state.d.ts.map +1 -1
- package/dist/lib/sync-state.js +41 -11
- package/dist/lib/sync-state.js.map +1 -1
- package/package.json +16 -8
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { apiFetch, ApiError } from '../lib/http.js';
|
|
3
|
+
import { printTable, printJson, formatDate, confirm, fail } from '../lib/output.js';
|
|
4
|
+
const ACCESS_ROLES = ['ADMIN', 'MEMBER'];
|
|
5
|
+
const AVAILABILITIES = ['ONLINE', 'AWAY', 'DND'];
|
|
6
|
+
/** Split a comma-separated flag value; empty string clears the list. */
|
|
7
|
+
function splitList(value) {
|
|
8
|
+
if (value.trim() === '')
|
|
9
|
+
return [];
|
|
10
|
+
return value
|
|
11
|
+
.split(',')
|
|
12
|
+
.map((item) => item.trim())
|
|
13
|
+
.filter((item) => item.length > 0);
|
|
14
|
+
}
|
|
15
|
+
/** Build the PATCH body from provided flags only (server treats undefined as no-change). */
|
|
16
|
+
export function buildUserUpdateBody(opts) {
|
|
17
|
+
const body = {};
|
|
18
|
+
if (opts.name !== undefined)
|
|
19
|
+
body['name'] = opts.name;
|
|
20
|
+
if (opts.accessRole !== undefined)
|
|
21
|
+
body['accessRole'] = opts.accessRole;
|
|
22
|
+
if (opts.roles !== undefined)
|
|
23
|
+
body['roles'] = splitList(opts.roles);
|
|
24
|
+
if (opts.skills !== undefined)
|
|
25
|
+
body['skills'] = splitList(opts.skills);
|
|
26
|
+
if (opts.availability !== undefined)
|
|
27
|
+
body['availability'] = opts.availability;
|
|
28
|
+
if (opts.routable !== undefined)
|
|
29
|
+
body['routable'] = opts.routable === 'true';
|
|
30
|
+
return body;
|
|
31
|
+
}
|
|
32
|
+
export function usersCommand() {
|
|
33
|
+
const users = new Command('users').description('Manage users in the current organization');
|
|
34
|
+
users
|
|
35
|
+
.command('list')
|
|
36
|
+
.description('List users in the organization')
|
|
37
|
+
.action(async function () {
|
|
38
|
+
const globalOpts = this.optsWithGlobals();
|
|
39
|
+
const apiUrl = globalOpts.apiUrl;
|
|
40
|
+
let response;
|
|
41
|
+
try {
|
|
42
|
+
response = await apiFetch(apiUrl, '/api/v1/users');
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
fail(err instanceof Error ? err.message : String(err));
|
|
46
|
+
}
|
|
47
|
+
if (globalOpts.json) {
|
|
48
|
+
printJson(response);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
printTable(response.users, [
|
|
52
|
+
{ key: 'id', header: 'ID' },
|
|
53
|
+
{ key: 'name', header: 'NAME' },
|
|
54
|
+
{ key: 'email', header: 'EMAIL' },
|
|
55
|
+
{ key: 'accessRole', header: 'ACCESS' },
|
|
56
|
+
{
|
|
57
|
+
key: 'roles',
|
|
58
|
+
header: 'ROLES',
|
|
59
|
+
format: (v) => {
|
|
60
|
+
const joined = Array.isArray(v) ? v.join(',') : '';
|
|
61
|
+
if (joined === '')
|
|
62
|
+
return '-';
|
|
63
|
+
return joined.length > 30 ? `${joined.slice(0, 27)}...` : joined;
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{ key: 'availability', header: 'AVAILABILITY' },
|
|
67
|
+
{ key: 'lastLoginAt', header: 'LAST LOGIN', format: formatDate },
|
|
68
|
+
]);
|
|
69
|
+
});
|
|
70
|
+
users
|
|
71
|
+
.command('describe')
|
|
72
|
+
.description('Show details for a user')
|
|
73
|
+
.argument('<id>', 'User ID (from `halyard users list`)')
|
|
74
|
+
.action(async function (id) {
|
|
75
|
+
const globalOpts = this.optsWithGlobals();
|
|
76
|
+
const apiUrl = globalOpts.apiUrl;
|
|
77
|
+
let response;
|
|
78
|
+
try {
|
|
79
|
+
response = await apiFetch(apiUrl, `/api/v1/users/${id}`);
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
fail(err instanceof Error ? err.message : String(err));
|
|
83
|
+
}
|
|
84
|
+
if (globalOpts.json) {
|
|
85
|
+
printJson(response);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const user = response.user;
|
|
89
|
+
const counts = user['_count'];
|
|
90
|
+
const row = (label, value) => {
|
|
91
|
+
const rendered = value === null || value === undefined || value === ''
|
|
92
|
+
? '-'
|
|
93
|
+
: Array.isArray(value)
|
|
94
|
+
? value.length > 0
|
|
95
|
+
? value.join(', ')
|
|
96
|
+
: '-'
|
|
97
|
+
: String(value);
|
|
98
|
+
console.log(`${label.padEnd(14)}${rendered}`);
|
|
99
|
+
};
|
|
100
|
+
row('ID:', user['id']);
|
|
101
|
+
row('Name:', user['name']);
|
|
102
|
+
row('Email:', user['email']);
|
|
103
|
+
row('Access role:', user['accessRole']);
|
|
104
|
+
row('Roles:', user['roles']);
|
|
105
|
+
row('Skills:', user['skills']);
|
|
106
|
+
row('Availability:', user['availability']);
|
|
107
|
+
row('Last login:', formatDate(user['lastLoginAt']));
|
|
108
|
+
row('Created:', formatDate(user['createdAt']));
|
|
109
|
+
if (counts) {
|
|
110
|
+
row('Sessions:', counts.sessions ?? 0);
|
|
111
|
+
row('Messages:', counts.messages ?? 0);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
users
|
|
115
|
+
.command('update')
|
|
116
|
+
.description('Update a user (self, or others as admin)')
|
|
117
|
+
.argument('<id>', 'User ID')
|
|
118
|
+
.option('--name <name>', 'Display name')
|
|
119
|
+
.option('--access-role <role>', `Org access role (${ACCESS_ROLES.join('|')})`)
|
|
120
|
+
.option('--roles <roles>', 'Comma-separated role list; "" clears')
|
|
121
|
+
.option('--skills <skills>', 'Comma-separated skill list; "" clears')
|
|
122
|
+
.option('--availability <availability>', `Availability (${AVAILABILITIES.join('|')})`)
|
|
123
|
+
.option('--routable <true|false>', 'Whether teammate questions are routed to this user')
|
|
124
|
+
.action(async function (id) {
|
|
125
|
+
const globalOpts = this.optsWithGlobals();
|
|
126
|
+
const apiUrl = globalOpts.apiUrl;
|
|
127
|
+
const opts = this.opts();
|
|
128
|
+
const body = buildUserUpdateBody(opts);
|
|
129
|
+
if (Object.keys(body).length === 0) {
|
|
130
|
+
fail('Nothing to update; pass at least one of --name/--access-role/--roles/--skills/--availability/--routable');
|
|
131
|
+
}
|
|
132
|
+
if (opts.accessRole !== undefined &&
|
|
133
|
+
!ACCESS_ROLES.includes(opts.accessRole)) {
|
|
134
|
+
fail(`--access-role must be one of: ${ACCESS_ROLES.join(', ')}`);
|
|
135
|
+
}
|
|
136
|
+
if (opts.availability !== undefined &&
|
|
137
|
+
!AVAILABILITIES.includes(opts.availability)) {
|
|
138
|
+
fail(`--availability must be one of: ${AVAILABILITIES.join(', ')}`);
|
|
139
|
+
}
|
|
140
|
+
if (opts.routable !== undefined && !['true', 'false'].includes(opts.routable)) {
|
|
141
|
+
fail('--routable must be true or false');
|
|
142
|
+
}
|
|
143
|
+
let response;
|
|
144
|
+
try {
|
|
145
|
+
response = await apiFetch(apiUrl, `/api/v1/users/${id}`, {
|
|
146
|
+
method: 'PATCH',
|
|
147
|
+
body,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
fail(err instanceof Error ? err.message : String(err));
|
|
152
|
+
}
|
|
153
|
+
if (globalOpts.json) {
|
|
154
|
+
printJson(response);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
console.log(`Updated user ${response.user.name ?? response.user.id}.`);
|
|
158
|
+
});
|
|
159
|
+
users
|
|
160
|
+
.command('invite')
|
|
161
|
+
.description('Invite a person by email. Invites are email-only and not tracked - there is no list or cancel.')
|
|
162
|
+
.argument('<email>', 'Email address to invite')
|
|
163
|
+
.action(async function (email) {
|
|
164
|
+
const globalOpts = this.optsWithGlobals();
|
|
165
|
+
const apiUrl = globalOpts.apiUrl;
|
|
166
|
+
try {
|
|
167
|
+
await apiFetch(apiUrl, '/api/v1/users/invite', { method: 'POST', body: { email } });
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
fail(err instanceof Error ? err.message : String(err));
|
|
171
|
+
}
|
|
172
|
+
if (globalOpts.json) {
|
|
173
|
+
printJson({ success: true, email });
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
console.log(`Invite sent to ${email}.`);
|
|
177
|
+
console.log('Note: pending invites cannot be listed or canceled.');
|
|
178
|
+
});
|
|
179
|
+
users
|
|
180
|
+
.command('remove')
|
|
181
|
+
.description('Remove a user from the organization (admin only)')
|
|
182
|
+
.argument('<id>', 'User ID')
|
|
183
|
+
.option('-f, --force', 'Skip the confirmation prompt')
|
|
184
|
+
.action(async function (id) {
|
|
185
|
+
const globalOpts = this.optsWithGlobals();
|
|
186
|
+
const apiUrl = globalOpts.apiUrl;
|
|
187
|
+
const force = !!this.opts().force;
|
|
188
|
+
const confirmed = await confirm(`Remove user ${id}? This permanently deletes the user and their knowledge grants.`, { force });
|
|
189
|
+
if (!confirmed) {
|
|
190
|
+
fail('Aborted.');
|
|
191
|
+
}
|
|
192
|
+
try {
|
|
193
|
+
await apiFetch(apiUrl, `/api/v1/users/${id}`, { method: 'DELETE' });
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
if (err instanceof ApiError && err.status === 404) {
|
|
197
|
+
fail('User not found in this organization.');
|
|
198
|
+
}
|
|
199
|
+
fail(err instanceof Error ? err.message : String(err));
|
|
200
|
+
}
|
|
201
|
+
console.log('User removed.');
|
|
202
|
+
});
|
|
203
|
+
return users;
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=users.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/commands/users.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
export interface MeResponse {
|
|
3
|
+
user: {
|
|
4
|
+
id: string;
|
|
5
|
+
email: string | null;
|
|
6
|
+
name: string | null;
|
|
7
|
+
accessRole: string;
|
|
8
|
+
isAdmin: boolean;
|
|
9
|
+
};
|
|
10
|
+
organization: {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
slug: string;
|
|
14
|
+
} | null;
|
|
15
|
+
authenticatedVia?: {
|
|
16
|
+
type: string;
|
|
17
|
+
clientName: string | null;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare function whoamiCommand(): Command;
|
|
21
|
+
//# sourceMappingURL=whoami.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAMnC,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAA;QACV,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;QACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;QACnB,UAAU,EAAE,MAAM,CAAA;QAClB,OAAO,EAAE,OAAO,CAAA;KACjB,CAAA;IACD,YAAY,EAAE;QACZ,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;KACb,GAAG,IAAI,CAAA;IACR,gBAAgB,CAAC,EAAE;QACjB,IAAI,EAAE,MAAM,CAAA;QACZ,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAC1B,CAAA;CACF;AA4BD,wBAAgB,aAAa,IAAI,OAAO,CAuDvC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { apiFetch } from '../lib/http.js';
|
|
3
|
+
import { getCredentials } from '../lib/auth.js';
|
|
4
|
+
import { findRepoBinding } from '../lib/repo-binding.js';
|
|
5
|
+
import { printJson, fail } from '../lib/output.js';
|
|
6
|
+
function describeAuthMode(me) {
|
|
7
|
+
if (process.env['HALYARD_TOKEN']) {
|
|
8
|
+
return process.env['HALYARD_TOKEN'].startsWith('sk_halyard_')
|
|
9
|
+
? 'API key (HALYARD_TOKEN)'
|
|
10
|
+
: 'Token (HALYARD_TOKEN)';
|
|
11
|
+
}
|
|
12
|
+
const creds = getCredentials();
|
|
13
|
+
if (creds?.accessToken.startsWith('sk_halyard_'))
|
|
14
|
+
return 'API key';
|
|
15
|
+
if (me?.authenticatedVia?.type === 'oauth') {
|
|
16
|
+
return me.authenticatedVia.clientName ? `OAuth (${me.authenticatedVia.clientName})` : 'OAuth';
|
|
17
|
+
}
|
|
18
|
+
return 'OAuth';
|
|
19
|
+
}
|
|
20
|
+
function printBindingLine() {
|
|
21
|
+
const binding = findRepoBinding();
|
|
22
|
+
if (binding) {
|
|
23
|
+
console.log(`Repo binding: ${binding.org} (${binding.rootDir})`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function whoamiCommand() {
|
|
27
|
+
return new Command('whoami')
|
|
28
|
+
.description('Show the authenticated user and organization')
|
|
29
|
+
.action(async function () {
|
|
30
|
+
const globalOpts = this.optsWithGlobals();
|
|
31
|
+
const apiUrl = globalOpts.apiUrl;
|
|
32
|
+
// sk_ API keys can't call the OAuth-only /api/v1/me (401); identify
|
|
33
|
+
// them via the API-key bootstrap route instead.
|
|
34
|
+
const creds = getCredentials();
|
|
35
|
+
if (creds?.accessToken.startsWith('sk_halyard_')) {
|
|
36
|
+
let key;
|
|
37
|
+
try {
|
|
38
|
+
key = await apiFetch(apiUrl, '/api/v1/api-keys/me');
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
fail(err instanceof Error ? err.message : String(err));
|
|
42
|
+
}
|
|
43
|
+
if (globalOpts.json) {
|
|
44
|
+
printJson(key);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
console.log(`API key: ${key.id}`);
|
|
48
|
+
console.log(`API URL: ${key.apiUrl}`);
|
|
49
|
+
console.log('Organization: bound to the API key (not exposed by the API)');
|
|
50
|
+
console.log(`Auth: ${describeAuthMode(null)}`);
|
|
51
|
+
printBindingLine();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
let me;
|
|
55
|
+
try {
|
|
56
|
+
me = await apiFetch(apiUrl, '/api/v1/me');
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
fail(err instanceof Error ? err.message : String(err));
|
|
60
|
+
}
|
|
61
|
+
if (globalOpts.json) {
|
|
62
|
+
printJson(me);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const email = me.user.email ? ` <${me.user.email}>` : '';
|
|
66
|
+
console.log(`User: ${me.user.name ?? me.user.id}${email} (${me.user.accessRole})`);
|
|
67
|
+
if (me.organization) {
|
|
68
|
+
console.log(`Organization: ${me.organization.name} (${me.organization.slug}) [${me.organization.id}]`);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
console.log('Organization: -');
|
|
72
|
+
}
|
|
73
|
+
console.log(`Auth: ${describeAuthMode(me)}`);
|
|
74
|
+
printBindingLine();
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=whoami.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AA0BlD,SAAS,gBAAgB,CAAC,EAAqB;IAC7C,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;QACjC,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC;YAC3D,CAAC,CAAC,yBAAyB;YAC3B,CAAC,CAAC,uBAAuB,CAAA;IAC7B,CAAC;IACD,MAAM,KAAK,GAAG,cAAc,EAAE,CAAA;IAC9B,IAAI,KAAK,EAAE,WAAW,CAAC,UAAU,CAAC,aAAa,CAAC;QAAE,OAAO,SAAS,CAAA;IAClE,IAAI,EAAE,EAAE,gBAAgB,EAAE,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3C,OAAO,EAAE,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,gBAAgB,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,OAAO,CAAA;IAC/F,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAS,gBAAgB;IACvB,MAAM,OAAO,GAAG,eAAe,EAAE,CAAA;IACjC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,kBAAkB,OAAO,CAAC,GAAG,KAAK,OAAO,CAAC,OAAO,GAAG,CAAC,CAAA;IACnE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC;SACzB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,MAAM,CAAC,KAAK;QACX,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,CAAA;QACzC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAgB,CAAA;QAE1C,oEAAoE;QACpE,gDAAgD;QAChD,MAAM,KAAK,GAAG,cAAc,EAAE,CAAA;QAC9B,IAAI,KAAK,EAAE,WAAW,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACjD,IAAI,GAAqB,CAAA;YACzB,IAAI,CAAC;gBACH,GAAG,GAAG,MAAM,QAAQ,CAAmB,MAAM,EAAE,qBAAqB,CAAC,CAAA;YACvE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;YACxD,CAAC;YAED,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;gBACpB,SAAS,CAAC,GAAG,CAAC,CAAA;gBACd,OAAM;YACR,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,EAAE,EAAE,CAAC,CAAA;YACvC,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;YAC3C,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAA;YAC3E,OAAO,CAAC,GAAG,CAAC,kBAAkB,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACvD,gBAAgB,EAAE,CAAA;YAClB,OAAM;QACR,CAAC;QAED,IAAI,EAAc,CAAA;QAClB,IAAI,CAAC;YACH,EAAE,GAAG,MAAM,QAAQ,CAAa,MAAM,EAAE,YAAY,CAAC,CAAA;QACvD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;QACxD,CAAC;QAED,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YACpB,SAAS,CAAC,EAAE,CAAC,CAAA;YACb,OAAM;QACR,CAAC;QAED,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;QACxD,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,MAAM,EAAE,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAA;QAC5F,IAAI,EAAE,CAAC,YAAY,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CACT,kBAAkB,EAAE,CAAC,YAAY,CAAC,IAAI,KAAK,EAAE,CAAC,YAAY,CAAC,IAAI,OAAO,EAAE,CAAC,YAAY,CAAC,EAAE,GAAG,CAC5F,CAAA;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;QACjC,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,kBAAkB,gBAAgB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;QACrD,gBAAgB,EAAE,CAAA;IACpB,CAAC,CAAC,CAAA;AACN,CAAC"}
|
package/dist/lib/api-client.d.ts
CHANGED
|
@@ -3,7 +3,69 @@ export interface UploadResult {
|
|
|
3
3
|
sessionId: string;
|
|
4
4
|
}
|
|
5
5
|
/**
|
|
6
|
-
* Upload
|
|
6
|
+
* Upload session log content to the Halyard ingest endpoint.
|
|
7
|
+
*
|
|
8
|
+
* Callers pass the bytes rather than a path because not every provider is
|
|
9
|
+
* file-backed — OpenCode and Copilot sessions are exported from local
|
|
10
|
+
* stores at upload time (see lib/discovery.ts `loadSessionContent`).
|
|
7
11
|
*/
|
|
8
|
-
export declare function uploadSession(
|
|
12
|
+
export declare function uploadSession(content: Buffer, fileName: string, provider: string, sessionId: string, authHeaders: Record<string, string>, apiUrl: string): Promise<UploadResult>;
|
|
13
|
+
/**
|
|
14
|
+
* One manifest row of a skill upload. `content` carries the file verbatim —
|
|
15
|
+
* UTF-8 text as-is, anything else base64 — except for SKILL.md, whose bytes
|
|
16
|
+
* already travel as `frontmatterRaw` + `body` and are never sent twice.
|
|
17
|
+
*/
|
|
18
|
+
export interface SkillFileUpload {
|
|
19
|
+
path: string;
|
|
20
|
+
size: number;
|
|
21
|
+
sha256: string;
|
|
22
|
+
content?: string;
|
|
23
|
+
encoding?: 'utf8' | 'base64';
|
|
24
|
+
}
|
|
25
|
+
/** One locally discovered skill, as sent to `POST /api/v1/skills/sync`. */
|
|
26
|
+
export interface SkillUpload {
|
|
27
|
+
/** Front-matter `name`, else the folder name. */
|
|
28
|
+
name: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
/** Top-level front-matter fields as written. */
|
|
31
|
+
frontmatter: Record<string, string>;
|
|
32
|
+
/** Verbatim front-matter block, at most 64 KiB; the server parses it losslessly. */
|
|
33
|
+
frontmatterRaw?: string;
|
|
34
|
+
/** SKILL.md without its front-matter block. */
|
|
35
|
+
body: string;
|
|
36
|
+
scope: 'user' | 'project';
|
|
37
|
+
/** Repo identity for project skills; empty for user skills (the server keys those by user). */
|
|
38
|
+
scopeKey: string;
|
|
39
|
+
/** Skill directory relative to the home dir or repo root, posix separators. */
|
|
40
|
+
relativePath: string;
|
|
41
|
+
harnesses: string[];
|
|
42
|
+
/** Every relative path the skill was found at (symlink aliases). */
|
|
43
|
+
locations: string[];
|
|
44
|
+
/** sha256 over the sorted file manifest. */
|
|
45
|
+
treeHash: string;
|
|
46
|
+
/** Manifest (first 500 files); `fileCount` says how many the hash actually covers. */
|
|
47
|
+
files: SkillFileUpload[];
|
|
48
|
+
fileCount: number;
|
|
49
|
+
/** Newest mtime in the tree, ISO 8601. */
|
|
50
|
+
modifiedAt: string;
|
|
51
|
+
}
|
|
52
|
+
export interface SkillSyncResult {
|
|
53
|
+
scope: 'user' | 'project';
|
|
54
|
+
relativePath: string;
|
|
55
|
+
status: 'created' | 'updated' | 'unchanged';
|
|
56
|
+
knowledgeEntryId: string;
|
|
57
|
+
/** Manifest files whose bytes the server now holds (absent from older servers). */
|
|
58
|
+
storedFiles?: number;
|
|
59
|
+
/** Non-fatal server-side problems, e.g. front-matter that is not valid YAML. */
|
|
60
|
+
warnings?: string[];
|
|
61
|
+
}
|
|
62
|
+
export interface SkillSyncResponse {
|
|
63
|
+
results: SkillSyncResult[];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Upload a batch of skills. The server upserts each one by
|
|
67
|
+
* (org, provider, externalId) and compares `treeHash`, so re-sending an
|
|
68
|
+
* unchanged skill is a cheap `unchanged` rather than a duplicate.
|
|
69
|
+
*/
|
|
70
|
+
export declare function syncSkills(skills: SkillUpload[], authHeaders: Record<string, string>, apiUrl: string, fetchImpl?: typeof fetch): Promise<SkillSyncResponse>;
|
|
9
71
|
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,SAAS,GAAG,WAAW,CAAA;IAC/B,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,CAAC,CA0BvB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAA;CAC7B;AAED,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,oFAAoF;IACpF,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,+FAA+F;IAC/F,QAAQ,EAAE,MAAM,CAAA;IAChB,+EAA+E;IAC/E,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,oEAAoE;IACpE,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAA;IAChB,sFAAsF;IACtF,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,CAAA;IAC3C,gBAAgB,EAAE,MAAM,CAAA;IACxB,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,eAAe,EAAE,CAAA;CAC3B;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,WAAW,EAAE,EACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,OAAO,KAAa,GAC9B,OAAO,CAAC,iBAAiB,CAAC,CAuB5B"}
|
package/dist/lib/api-client.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { basename } from 'node:path';
|
|
1
|
+
import { ApiError } from './http.js';
|
|
3
2
|
/**
|
|
4
|
-
* Upload
|
|
3
|
+
* Upload session log content to the Halyard ingest endpoint.
|
|
4
|
+
*
|
|
5
|
+
* Callers pass the bytes rather than a path because not every provider is
|
|
6
|
+
* file-backed — OpenCode and Copilot sessions are exported from local
|
|
7
|
+
* stores at upload time (see lib/discovery.ts `loadSessionContent`).
|
|
5
8
|
*/
|
|
6
|
-
export async function uploadSession(
|
|
7
|
-
const fileContent = readFileSync(filePath);
|
|
8
|
-
const fileName = basename(filePath);
|
|
9
|
+
export async function uploadSession(content, fileName, provider, sessionId, authHeaders, apiUrl) {
|
|
9
10
|
// Build multipart form data
|
|
10
11
|
const formData = new FormData();
|
|
11
12
|
formData.append('provider', provider);
|
|
12
13
|
formData.append('sessionId', sessionId);
|
|
13
|
-
formData.append('file', new Blob([
|
|
14
|
+
formData.append('file', new Blob([content]), fileName);
|
|
14
15
|
const res = await fetch(`${apiUrl}/api/v1/sessions/ingest`, {
|
|
15
16
|
method: 'POST',
|
|
16
17
|
headers: {
|
|
@@ -28,4 +29,28 @@ export async function uploadSession(filePath, provider, sessionId, authHeaders,
|
|
|
28
29
|
}
|
|
29
30
|
return (await res.json());
|
|
30
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Upload a batch of skills. The server upserts each one by
|
|
34
|
+
* (org, provider, externalId) and compares `treeHash`, so re-sending an
|
|
35
|
+
* unchanged skill is a cheap `unchanged` rather than a duplicate.
|
|
36
|
+
*/
|
|
37
|
+
export async function syncSkills(skills, authHeaders, apiUrl, fetchImpl = fetch) {
|
|
38
|
+
const res = await fetchImpl(`${apiUrl}/api/v1/skills/sync`, {
|
|
39
|
+
method: 'POST',
|
|
40
|
+
headers: { ...authHeaders, 'Content-Type': 'application/json' },
|
|
41
|
+
body: JSON.stringify({ skills }),
|
|
42
|
+
});
|
|
43
|
+
if (res.status === 401) {
|
|
44
|
+
throw new ApiError('Authentication failed. Run `halyard login` or check your HALYARD_TOKEN.', res.status, await res.text());
|
|
45
|
+
}
|
|
46
|
+
if (!res.ok) {
|
|
47
|
+
const body = await res.text();
|
|
48
|
+
throw new ApiError(`Skills sync failed (${res.status}): ${body}`, res.status, body);
|
|
49
|
+
}
|
|
50
|
+
const parsed = (await res.json());
|
|
51
|
+
if (!parsed || !Array.isArray(parsed.results)) {
|
|
52
|
+
throw new Error('Skills sync failed: unexpected response (no results array)');
|
|
53
|
+
}
|
|
54
|
+
return { results: parsed.results };
|
|
55
|
+
}
|
|
31
56
|
//# sourceMappingURL=api-client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAOpC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAe,EACf,QAAgB,EAChB,QAAgB,EAChB,SAAiB,EACjB,WAAmC,EACnC,MAAc;IAEd,4BAA4B;IAC5B,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAA;IAC/B,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;IACrC,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;IACvC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;IAEtD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,yBAAyB,EAAE;QAC1D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,GAAG,WAAW;YACd,0EAA0E;SAC3E;QACD,IAAI,EAAE,QAAQ;KACf,CAAC,CAAA;IAEF,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAA;IAC5F,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;QAC7B,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAA;IAC3D,CAAC;IAED,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAiB,CAAA;AAC3C,CAAC;AA0DD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAqB,EACrB,WAAmC,EACnC,MAAc,EACd,YAA0B,KAAK;IAE/B,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,MAAM,qBAAqB,EAAE;QAC1D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,GAAG,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/D,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACjC,CAAC,CAAA;IAEF,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,MAAM,IAAI,QAAQ,CAChB,yEAAyE,EACzE,GAAG,CAAC,MAAM,EACV,MAAM,GAAG,CAAC,IAAI,EAAE,CACjB,CAAA;IACH,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;QAC7B,MAAM,IAAI,QAAQ,CAAC,uBAAuB,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACrF,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsC,CAAA;IACtE,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAA;IAC/E,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAA;AACpC,CAAC"}
|
package/dist/lib/auth.d.ts
CHANGED
|
@@ -1,25 +1,62 @@
|
|
|
1
|
+
import { type RepoBinding } from './repo-binding.js';
|
|
1
2
|
export interface Credentials {
|
|
2
3
|
accessToken: string;
|
|
3
4
|
refreshToken: string;
|
|
5
|
+
clientId: string;
|
|
4
6
|
expiresAt: number;
|
|
5
7
|
apiUrl: string;
|
|
8
|
+
/** Set for per-org credential files (~/.halyard/credentials/<orgId>.json) */
|
|
9
|
+
orgId?: string;
|
|
10
|
+
orgSlug?: string;
|
|
6
11
|
}
|
|
12
|
+
export interface CredentialsWithSource {
|
|
13
|
+
creds: Credentials;
|
|
14
|
+
/** File the credentials were read from; null when from the HALYARD_TOKEN env var. */
|
|
15
|
+
filePath: string | null;
|
|
16
|
+
}
|
|
17
|
+
/** Path of the per-org credential file for an org. */
|
|
18
|
+
export declare function perOrgCredentialsPath(orgId: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Get stored credentials plus the file they came from, so token refresh can
|
|
21
|
+
* write back to the same chain it read.
|
|
22
|
+
*
|
|
23
|
+
* Resolution order:
|
|
24
|
+
* 1. HALYARD_TOKEN env var (headless/CI override; no backing file)
|
|
25
|
+
* 2. Per-org file in ~/.halyard/credentials/ whose orgSlug matches the
|
|
26
|
+
* repo binding (when invoked inside a bound repo)
|
|
27
|
+
* 3. Legacy ~/.halyard/credentials.json (default chain)
|
|
28
|
+
*/
|
|
29
|
+
export declare function getCredentialsWithSource(binding?: RepoBinding | null): CredentialsWithSource | null;
|
|
7
30
|
/**
|
|
8
31
|
* Get stored credentials, or fall back to HALYARD_TOKEN env var.
|
|
9
32
|
* Returns null if no credentials are available.
|
|
10
33
|
*/
|
|
11
|
-
export declare function getCredentials(): Credentials | null;
|
|
34
|
+
export declare function getCredentials(binding?: RepoBinding | null): Credentials | null;
|
|
12
35
|
/**
|
|
13
36
|
* Get authorization headers for API requests.
|
|
14
|
-
* Auto-refreshes expired OAuth tokens
|
|
37
|
+
* Auto-refreshes expired OAuth tokens, writing the rotated tokens back to the
|
|
38
|
+
* same file the credentials were read from (per-org or legacy).
|
|
15
39
|
*/
|
|
16
|
-
export declare function getAuthHeaders(apiUrl: string): Promise<Record<string, string>>;
|
|
40
|
+
export declare function getAuthHeaders(apiUrl: string, binding?: RepoBinding | null): Promise<Record<string, string>>;
|
|
41
|
+
/** Where refreshed credentials should be persisted. */
|
|
42
|
+
export interface PersistTarget {
|
|
43
|
+
filePath: string;
|
|
44
|
+
orgId?: string;
|
|
45
|
+
orgSlug?: string;
|
|
46
|
+
}
|
|
17
47
|
/**
|
|
18
48
|
* Refresh an expired OAuth access token.
|
|
49
|
+
* Persists to `persist.filePath` when given (per-org chains keep refreshing
|
|
50
|
+
* their own file); defaults to the legacy credentials file.
|
|
19
51
|
*/
|
|
20
|
-
export declare function refreshToken(refreshTokenValue: string, apiUrl: string): Promise<Credentials>;
|
|
52
|
+
export declare function refreshToken(refreshTokenValue: string, clientId: string, apiUrl: string, orgId?: string, persist?: PersistTarget): Promise<Credentials>;
|
|
21
53
|
/**
|
|
22
|
-
* Save credentials to disk
|
|
54
|
+
* Save credentials to disk (legacy file by default, or an explicit per-org
|
|
55
|
+
* file). Directories are created 0700, files written 0600.
|
|
23
56
|
*/
|
|
24
|
-
export declare function saveCredentials(creds: Credentials): void;
|
|
57
|
+
export declare function saveCredentials(creds: Credentials, filePath?: string): void;
|
|
58
|
+
/** Save credentials to the per-org store (requires orgId to be set). */
|
|
59
|
+
export declare function savePerOrgCredentials(creds: Credentials & {
|
|
60
|
+
orgId: string;
|
|
61
|
+
}): void;
|
|
25
62
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/lib/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAErE,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,WAAW,CAAA;IAClB,qFAAqF;IACrF,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAED,sDAAsD;AACtD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,GAAE,WAAW,GAAG,IAAwB,GAC9C,qBAAqB,GAAG,IAAI,CA4B9B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,OAAO,GAAE,WAAW,GAAG,IAAwB,GAC9C,WAAW,GAAG,IAAI,CAEpB;AAwBD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,WAAW,GAAG,IAAwB,GAC9C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAqCjC;AAED,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,iBAAiB,EAAE,MAAM,EACzB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,WAAW,CAAC,CAwCtB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,GAAE,MAA0B,GAAG,IAAI,CAI9F;AAED,wEAAwE;AACxE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAElF"}
|