@notis_ai/cli 0.2.0-beta.118.1 → 0.2.0-beta.121.1
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/package.json
CHANGED
|
@@ -561,6 +561,14 @@ export async function ensureDevInstall({
|
|
|
561
561
|
const skills = resolveConfiguredAppSkills(appConfig, projectDir);
|
|
562
562
|
let linkedState = readLinkedState(projectDir);
|
|
563
563
|
let linkedApp = null;
|
|
564
|
+
if (linkedState?.dev_app_id) {
|
|
565
|
+
const devApp = await getAccessibleApp(ctx.runtime, linkedState.dev_app_id, runTool);
|
|
566
|
+
if (!devApp || devApp.manifest?.is_dev !== true) {
|
|
567
|
+
const { dev_app_id: _devAppId, dev_linked_at: _devLinkedAt, ...rest } = linkedState;
|
|
568
|
+
linkedState = rest;
|
|
569
|
+
writeLinkedState(projectDir, linkedState);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
564
572
|
if (linkedState?.app_id) {
|
|
565
573
|
linkedApp = await getAccessibleApp(ctx.runtime, linkedState.app_id, runTool);
|
|
566
574
|
if (linkedApp?.manifest?.is_dev === true) {
|
|
@@ -631,7 +639,7 @@ async function getAccessibleApp(runtime, appId, runTool = runToolCommand) {
|
|
|
631
639
|
const result = await runTool({
|
|
632
640
|
runtime,
|
|
633
641
|
toolName: GET_APP_TOOL,
|
|
634
|
-
arguments_: { app_id: appId },
|
|
642
|
+
arguments_: { app_id: appId, include_documents: false },
|
|
635
643
|
});
|
|
636
644
|
if (result.payload?.app) {
|
|
637
645
|
return {
|
|
@@ -640,7 +648,11 @@ async function getAccessibleApp(runtime, appId, runTool = runToolCommand) {
|
|
|
640
648
|
};
|
|
641
649
|
}
|
|
642
650
|
const message = typeof result.payload?.message === 'string' ? result.payload.message : '';
|
|
643
|
-
|
|
651
|
+
const errorCode = result.payload?.code || result.payload?.error?.code;
|
|
652
|
+
if (
|
|
653
|
+
result.payload?.status === 'error'
|
|
654
|
+
&& (errorCode === 'app_not_found' || /^App not found\.?$/i.test(message.trim()))
|
|
655
|
+
) {
|
|
644
656
|
return null;
|
|
645
657
|
}
|
|
646
658
|
throw usageError(`Could not verify access to app ${appId}${message ? `: ${message}` : '.'}`);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
2
|
import { existsSync, readFileSync } from 'node:fs';
|
|
3
3
|
import { usageError } from '../runtime/errors.js';
|
|
4
4
|
import {
|
|
@@ -178,6 +178,11 @@ async function executeReadOnlySql(ctx, query, phase) {
|
|
|
178
178
|
tools: [{ tool_slug: toolName, arguments: { query } }],
|
|
179
179
|
},
|
|
180
180
|
mutating: false,
|
|
181
|
+
// Always a fresh key, never the operator's --idempotency-key: a diagnostic
|
|
182
|
+
// must observe current state rather than replay a cached response, and two
|
|
183
|
+
// different queries under one reused key would collide on the request hash.
|
|
184
|
+
idempotencyKey: randomUUID(),
|
|
185
|
+
sendIdempotencyKeyWhenReading: true,
|
|
181
186
|
});
|
|
182
187
|
if (result.payload?.successful === false || result.payload?.error) {
|
|
183
188
|
throw usageError(
|
|
@@ -56,12 +56,18 @@ export async function runToolCommand({
|
|
|
56
56
|
mutating = false,
|
|
57
57
|
idempotencyKey,
|
|
58
58
|
fileBindings = [],
|
|
59
|
+
sendIdempotencyKeyWhenReading = false,
|
|
59
60
|
}) {
|
|
61
|
+
// The server owns effect classification and requires a key whenever *its*
|
|
62
|
+
// metadata says write or unknown — a client-side `mutating: false` hint does
|
|
63
|
+
// not exempt the call. Callers that knowingly dispatch through an
|
|
64
|
+
// unknown-classified wrapper (e.g. COMPOSIO_MULTI_EXECUTE_TOOL) opt in so the
|
|
65
|
+
// request carries a key instead of being rejected as idempotency_key_required.
|
|
60
66
|
const result = await callTool({
|
|
61
67
|
runtime: { ...runtime, mutating },
|
|
62
68
|
toolName,
|
|
63
69
|
arguments_,
|
|
64
|
-
idempotencyKey: mutating ? idempotencyKey : null,
|
|
70
|
+
idempotencyKey: mutating || sendIdempotencyKeyWhenReading ? idempotencyKey : null,
|
|
65
71
|
fileBindings,
|
|
66
72
|
});
|
|
67
73
|
return result;
|