pinsay-cli 0.14.1 → 0.14.2
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 +4 -0
- package/dist/cli.js +98 -43
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -62,6 +62,10 @@ Full guides: https://pinsay.dev/docs/ · Issues: https://github.com/moamen-ui/pi
|
|
|
62
62
|
|
|
63
63
|
## Changelog
|
|
64
64
|
|
|
65
|
+
### 0.14.2
|
|
66
|
+
|
|
67
|
+
- A saved session the server ended early (for example after your role changed) no longer fails with "Your saved key no longer works": the CLI signs in again with the saved key once and retries. Only a key the server rejects still asks you to sign in.
|
|
68
|
+
|
|
65
69
|
### 0.14.1
|
|
66
70
|
|
|
67
71
|
- Delegation is off unless `.pinsay/config.json` has `"delegation": "auto"`: the apply prompt header says `delegation=off` and `apply --mark` with one model no longer prints the "Delegation is on…" warning.
|
package/dist/cli.js
CHANGED
|
@@ -392,7 +392,7 @@ var init_build_constants = __esm({
|
|
|
392
392
|
"src/build-constants.ts"() {
|
|
393
393
|
"use strict";
|
|
394
394
|
BUILD_DEFAULT_SERVER = true ? "https://app.pinsay.dev" : "https://app.pinsay.dev";
|
|
395
|
-
BUILD_CLI_VERSION = true ? "0.14.
|
|
395
|
+
BUILD_CLI_VERSION = true ? "0.14.2" : "0.0.0-dev";
|
|
396
396
|
}
|
|
397
397
|
});
|
|
398
398
|
|
|
@@ -1379,7 +1379,45 @@ function parseRetryAfter(value, now = Date.now()) {
|
|
|
1379
1379
|
return void 0;
|
|
1380
1380
|
return Math.max(1, Math.ceil((at - now) / 1e3));
|
|
1381
1381
|
}
|
|
1382
|
+
function registerRenewableToken(token, renew) {
|
|
1383
|
+
renewers.set(token, renew);
|
|
1384
|
+
}
|
|
1385
|
+
async function currentToken(token) {
|
|
1386
|
+
let t = token;
|
|
1387
|
+
while (t && replaced.has(t)) {
|
|
1388
|
+
const next = await replaced.get(t).catch(() => void 0);
|
|
1389
|
+
if (!next || next === t)
|
|
1390
|
+
break;
|
|
1391
|
+
t = next;
|
|
1392
|
+
}
|
|
1393
|
+
return t;
|
|
1394
|
+
}
|
|
1395
|
+
function renewToken(token) {
|
|
1396
|
+
let next = replaced.get(token);
|
|
1397
|
+
if (!next) {
|
|
1398
|
+
const renew = renewers.get(token);
|
|
1399
|
+
if (!renew)
|
|
1400
|
+
return Promise.resolve(void 0);
|
|
1401
|
+
renewers.delete(token);
|
|
1402
|
+
next = renew();
|
|
1403
|
+
replaced.set(token, next);
|
|
1404
|
+
}
|
|
1405
|
+
return next;
|
|
1406
|
+
}
|
|
1382
1407
|
async function api(server, path, options = {}) {
|
|
1408
|
+
const token = await currentToken(options.token);
|
|
1409
|
+
try {
|
|
1410
|
+
return await request(server, path, { ...options, token });
|
|
1411
|
+
} catch (err) {
|
|
1412
|
+
if (!(err instanceof ApiError) || err.code !== 401 || !token)
|
|
1413
|
+
throw err;
|
|
1414
|
+
const fresh = await renewToken(token);
|
|
1415
|
+
if (!fresh || fresh === token)
|
|
1416
|
+
throw err;
|
|
1417
|
+
return request(server, path, { ...options, token: fresh });
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
async function request(server, path, options = {}) {
|
|
1383
1421
|
const url = `${server.replace(/\/$/, "")}${path}`;
|
|
1384
1422
|
const headers = { "Accept": "application/json" };
|
|
1385
1423
|
if (options.token)
|
|
@@ -1412,7 +1450,7 @@ async function api(server, path, options = {}) {
|
|
|
1412
1450
|
const body = await res.json();
|
|
1413
1451
|
return body.data !== void 0 ? body.data : body;
|
|
1414
1452
|
}
|
|
1415
|
-
var ApiError, NetworkError, API_TIMEOUT_MS;
|
|
1453
|
+
var ApiError, NetworkError, API_TIMEOUT_MS, renewers, replaced;
|
|
1416
1454
|
var init_api = __esm({
|
|
1417
1455
|
"src/api.ts"() {
|
|
1418
1456
|
"use strict";
|
|
@@ -1433,6 +1471,8 @@ var init_api = __esm({
|
|
|
1433
1471
|
}
|
|
1434
1472
|
};
|
|
1435
1473
|
API_TIMEOUT_MS = 3e4;
|
|
1474
|
+
renewers = /* @__PURE__ */ new Map();
|
|
1475
|
+
replaced = /* @__PURE__ */ new Map();
|
|
1436
1476
|
}
|
|
1437
1477
|
});
|
|
1438
1478
|
|
|
@@ -2512,19 +2552,7 @@ function isJwtExpired(token) {
|
|
|
2512
2552
|
return false;
|
|
2513
2553
|
}
|
|
2514
2554
|
}
|
|
2515
|
-
async function
|
|
2516
|
-
await removeStaleRepoTokenCache(cwd2);
|
|
2517
|
-
const apiKey = explicitApiKey || await readApiKey(cwd2, server);
|
|
2518
|
-
if (!apiKey)
|
|
2519
|
-
return void 0;
|
|
2520
|
-
const cacheFile = tokenCacheFile(server, apiKey);
|
|
2521
|
-
try {
|
|
2522
|
-
const cached = JSON.parse(await fs22.readFile(cacheFile, "utf8"));
|
|
2523
|
-
const token = typeof cached?.token === "string" ? cached.token.trim() : "";
|
|
2524
|
-
if (token && !isJwtExpired(token))
|
|
2525
|
-
return token;
|
|
2526
|
-
} catch {
|
|
2527
|
-
}
|
|
2555
|
+
async function exchangeKey2(server, apiKey, cacheFile) {
|
|
2528
2556
|
try {
|
|
2529
2557
|
const login = await api(
|
|
2530
2558
|
server,
|
|
@@ -2551,6 +2579,31 @@ async function resolveToken(server, cwd2, explicitApiKey) {
|
|
|
2551
2579
|
}
|
|
2552
2580
|
return void 0;
|
|
2553
2581
|
}
|
|
2582
|
+
async function resolveToken(server, cwd2, explicitApiKey) {
|
|
2583
|
+
await removeStaleRepoTokenCache(cwd2);
|
|
2584
|
+
const apiKey = explicitApiKey || await readApiKey(cwd2, server);
|
|
2585
|
+
if (!apiKey)
|
|
2586
|
+
return void 0;
|
|
2587
|
+
const cacheFile = tokenCacheFile(server, apiKey);
|
|
2588
|
+
const track = (token) => {
|
|
2589
|
+
registerRenewableToken(token, async () => {
|
|
2590
|
+
await fs22.rm(cacheFile, { force: true }).catch(() => {
|
|
2591
|
+
});
|
|
2592
|
+
const fresh2 = await exchangeKey2(server, apiKey, cacheFile);
|
|
2593
|
+
return fresh2 ? track(fresh2) : void 0;
|
|
2594
|
+
});
|
|
2595
|
+
return token;
|
|
2596
|
+
};
|
|
2597
|
+
try {
|
|
2598
|
+
const cached = JSON.parse(await fs22.readFile(cacheFile, "utf8"));
|
|
2599
|
+
const token = typeof cached?.token === "string" ? cached.token.trim() : "";
|
|
2600
|
+
if (token && !isJwtExpired(token))
|
|
2601
|
+
return track(token);
|
|
2602
|
+
} catch {
|
|
2603
|
+
}
|
|
2604
|
+
const fresh = await exchangeKey2(server, apiKey, cacheFile);
|
|
2605
|
+
return fresh ? track(fresh) : void 0;
|
|
2606
|
+
}
|
|
2554
2607
|
var init_auth = __esm({
|
|
2555
2608
|
"src/auth.ts"() {
|
|
2556
2609
|
"use strict";
|
|
@@ -2701,8 +2754,9 @@ async function download(url, file, expectedSize, opts) {
|
|
|
2701
2754
|
if (have && have.isFile() && (expectedSize === null ? have.size > 0 : have.size === expectedSize))
|
|
2702
2755
|
return null;
|
|
2703
2756
|
const headers = {};
|
|
2704
|
-
|
|
2705
|
-
|
|
2757
|
+
const token = await currentToken(opts.token);
|
|
2758
|
+
if (token)
|
|
2759
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
2706
2760
|
const doFetch = opts.fetchImpl ?? fetch;
|
|
2707
2761
|
let res;
|
|
2708
2762
|
try {
|
|
@@ -2871,6 +2925,7 @@ var MEDIA_DIR, MEDIA_MAX_AGE_DAYS, DOWNLOAD_TIMEOUT_MS, MAX_MEDIA_BYTES, SAFE_EX
|
|
|
2871
2925
|
var init_media = __esm({
|
|
2872
2926
|
"src/apply/media.ts"() {
|
|
2873
2927
|
"use strict";
|
|
2928
|
+
init_api();
|
|
2874
2929
|
init_git_exclude();
|
|
2875
2930
|
MEDIA_DIR = join22(".pinsay", "media");
|
|
2876
2931
|
MEDIA_MAX_AGE_DAYS = 7;
|
|
@@ -14345,13 +14400,13 @@ var Protocol = class {
|
|
|
14345
14400
|
}
|
|
14346
14401
|
Promise.resolve().then(() => handler(notification)).catch((error) => this._onerror(new Error(`Uncaught error in notification handler: ${error}`)));
|
|
14347
14402
|
}
|
|
14348
|
-
_onrequest(
|
|
14403
|
+
_onrequest(request2) {
|
|
14349
14404
|
var _a, _b;
|
|
14350
|
-
const handler = (_a = this._requestHandlers.get(
|
|
14405
|
+
const handler = (_a = this._requestHandlers.get(request2.method)) !== null && _a !== void 0 ? _a : this.fallbackRequestHandler;
|
|
14351
14406
|
if (handler === void 0) {
|
|
14352
14407
|
(_b = this._transport) === null || _b === void 0 ? void 0 : _b.send({
|
|
14353
14408
|
jsonrpc: "2.0",
|
|
14354
|
-
id:
|
|
14409
|
+
id: request2.id,
|
|
14355
14410
|
error: {
|
|
14356
14411
|
code: ErrorCode.MethodNotFound,
|
|
14357
14412
|
message: "Method not found"
|
|
@@ -14360,8 +14415,8 @@ var Protocol = class {
|
|
|
14360
14415
|
return;
|
|
14361
14416
|
}
|
|
14362
14417
|
const abortController = new AbortController();
|
|
14363
|
-
this._requestHandlerAbortControllers.set(
|
|
14364
|
-
Promise.resolve().then(() => handler(
|
|
14418
|
+
this._requestHandlerAbortControllers.set(request2.id, abortController);
|
|
14419
|
+
Promise.resolve().then(() => handler(request2, { signal: abortController.signal })).then((result) => {
|
|
14365
14420
|
var _a2;
|
|
14366
14421
|
if (abortController.signal.aborted) {
|
|
14367
14422
|
return;
|
|
@@ -14369,7 +14424,7 @@ var Protocol = class {
|
|
|
14369
14424
|
return (_a2 = this._transport) === null || _a2 === void 0 ? void 0 : _a2.send({
|
|
14370
14425
|
result,
|
|
14371
14426
|
jsonrpc: "2.0",
|
|
14372
|
-
id:
|
|
14427
|
+
id: request2.id
|
|
14373
14428
|
});
|
|
14374
14429
|
}, (error) => {
|
|
14375
14430
|
var _a2, _b2;
|
|
@@ -14378,14 +14433,14 @@ var Protocol = class {
|
|
|
14378
14433
|
}
|
|
14379
14434
|
return (_a2 = this._transport) === null || _a2 === void 0 ? void 0 : _a2.send({
|
|
14380
14435
|
jsonrpc: "2.0",
|
|
14381
|
-
id:
|
|
14436
|
+
id: request2.id,
|
|
14382
14437
|
error: {
|
|
14383
14438
|
code: Number.isSafeInteger(error["code"]) ? error["code"] : ErrorCode.InternalError,
|
|
14384
14439
|
message: (_b2 = error.message) !== null && _b2 !== void 0 ? _b2 : "Internal error"
|
|
14385
14440
|
}
|
|
14386
14441
|
});
|
|
14387
14442
|
}).catch((error) => this._onerror(new Error(`Failed to send response: ${error}`))).finally(() => {
|
|
14388
|
-
this._requestHandlerAbortControllers.delete(
|
|
14443
|
+
this._requestHandlerAbortControllers.delete(request2.id);
|
|
14389
14444
|
});
|
|
14390
14445
|
}
|
|
14391
14446
|
_onprogress(notification) {
|
|
@@ -14428,7 +14483,7 @@ var Protocol = class {
|
|
|
14428
14483
|
*
|
|
14429
14484
|
* Do not use this method to emit notifications! Use notification() instead.
|
|
14430
14485
|
*/
|
|
14431
|
-
request(
|
|
14486
|
+
request(request2, resultSchema, options) {
|
|
14432
14487
|
return new Promise((resolve11, reject) => {
|
|
14433
14488
|
var _a, _b, _c, _d;
|
|
14434
14489
|
if (!this._transport) {
|
|
@@ -14436,19 +14491,19 @@ var Protocol = class {
|
|
|
14436
14491
|
return;
|
|
14437
14492
|
}
|
|
14438
14493
|
if (((_a = this._options) === null || _a === void 0 ? void 0 : _a.enforceStrictCapabilities) === true) {
|
|
14439
|
-
this.assertCapabilityForMethod(
|
|
14494
|
+
this.assertCapabilityForMethod(request2.method);
|
|
14440
14495
|
}
|
|
14441
14496
|
(_b = options === null || options === void 0 ? void 0 : options.signal) === null || _b === void 0 ? void 0 : _b.throwIfAborted();
|
|
14442
14497
|
const messageId = this._requestMessageId++;
|
|
14443
14498
|
const jsonrpcRequest = {
|
|
14444
|
-
...
|
|
14499
|
+
...request2,
|
|
14445
14500
|
jsonrpc: "2.0",
|
|
14446
14501
|
id: messageId
|
|
14447
14502
|
};
|
|
14448
14503
|
if (options === null || options === void 0 ? void 0 : options.onprogress) {
|
|
14449
14504
|
this._progressHandlers.set(messageId, options.onprogress);
|
|
14450
14505
|
jsonrpcRequest.params = {
|
|
14451
|
-
...
|
|
14506
|
+
...request2.params,
|
|
14452
14507
|
_meta: { progressToken: messageId }
|
|
14453
14508
|
};
|
|
14454
14509
|
}
|
|
@@ -14526,7 +14581,7 @@ var Protocol = class {
|
|
|
14526
14581
|
setRequestHandler(requestSchema, handler) {
|
|
14527
14582
|
const method = requestSchema.shape.method.value;
|
|
14528
14583
|
this.assertRequestHandlerCapability(method);
|
|
14529
|
-
this._requestHandlers.set(method, (
|
|
14584
|
+
this._requestHandlers.set(method, (request2, extra) => Promise.resolve(handler(requestSchema.parse(request2), extra)));
|
|
14530
14585
|
}
|
|
14531
14586
|
/**
|
|
14532
14587
|
* Removes the request handler for the given method.
|
|
@@ -14579,7 +14634,7 @@ var Server = class extends Protocol {
|
|
|
14579
14634
|
this._serverInfo = _serverInfo;
|
|
14580
14635
|
this._capabilities = (_a = options === null || options === void 0 ? void 0 : options.capabilities) !== null && _a !== void 0 ? _a : {};
|
|
14581
14636
|
this._instructions = options === null || options === void 0 ? void 0 : options.instructions;
|
|
14582
|
-
this.setRequestHandler(InitializeRequestSchema, (
|
|
14637
|
+
this.setRequestHandler(InitializeRequestSchema, (request2) => this._oninitialize(request2));
|
|
14583
14638
|
this.setNotificationHandler(InitializedNotificationSchema, () => {
|
|
14584
14639
|
var _a2;
|
|
14585
14640
|
return (_a2 = this.oninitialized) === null || _a2 === void 0 ? void 0 : _a2.call(this);
|
|
@@ -14678,10 +14733,10 @@ var Server = class extends Protocol {
|
|
|
14678
14733
|
break;
|
|
14679
14734
|
}
|
|
14680
14735
|
}
|
|
14681
|
-
async _oninitialize(
|
|
14682
|
-
const requestedVersion =
|
|
14683
|
-
this._clientCapabilities =
|
|
14684
|
-
this._clientVersion =
|
|
14736
|
+
async _oninitialize(request2) {
|
|
14737
|
+
const requestedVersion = request2.params.protocolVersion;
|
|
14738
|
+
this._clientCapabilities = request2.params.capabilities;
|
|
14739
|
+
this._clientVersion = request2.params.clientInfo;
|
|
14685
14740
|
return {
|
|
14686
14741
|
protocolVersion: SUPPORTED_PROTOCOL_VERSIONS.includes(requestedVersion) ? requestedVersion : LATEST_PROTOCOL_VERSION,
|
|
14687
14742
|
capabilities: this.getCapabilities(),
|
|
@@ -15905,9 +15960,9 @@ function createMcpServer(ctx) {
|
|
|
15905
15960
|
tools: [...ALL_TOOLS]
|
|
15906
15961
|
};
|
|
15907
15962
|
});
|
|
15908
|
-
server.setRequestHandler(CallToolRequestSchema, async (
|
|
15909
|
-
const name =
|
|
15910
|
-
const args =
|
|
15963
|
+
server.setRequestHandler(CallToolRequestSchema, async (request2) => {
|
|
15964
|
+
const name = request2.params.name;
|
|
15965
|
+
const args = request2.params.arguments || {};
|
|
15911
15966
|
try {
|
|
15912
15967
|
const result = await executeTool(name, args, ctx);
|
|
15913
15968
|
return {
|
|
@@ -15958,8 +16013,8 @@ function createMcpServer(ctx) {
|
|
|
15958
16013
|
]
|
|
15959
16014
|
};
|
|
15960
16015
|
});
|
|
15961
|
-
server.setRequestHandler(ReadResourceRequestSchema, async (
|
|
15962
|
-
const uri =
|
|
16016
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request2) => {
|
|
16017
|
+
const uri = request2.params.uri;
|
|
15963
16018
|
if (uri !== "pinsay://project") {
|
|
15964
16019
|
throw new Error(`Unknown resource URI: ${uri}`);
|
|
15965
16020
|
}
|
|
@@ -16006,12 +16061,12 @@ function createMcpServer(ctx) {
|
|
|
16006
16061
|
]
|
|
16007
16062
|
};
|
|
16008
16063
|
});
|
|
16009
|
-
server.setRequestHandler(GetPromptRequestSchema, async (
|
|
16010
|
-
const name =
|
|
16064
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request2) => {
|
|
16065
|
+
const name = request2.params.name;
|
|
16011
16066
|
if (name !== "pinsay_apply_instructions") {
|
|
16012
16067
|
throw new Error(`Unknown prompt: ${name}`);
|
|
16013
16068
|
}
|
|
16014
|
-
const env =
|
|
16069
|
+
const env = request2.params.arguments?.environment;
|
|
16015
16070
|
const clientCtx = {
|
|
16016
16071
|
server: ctx.server,
|
|
16017
16072
|
project: ctx.project,
|
package/package.json
CHANGED