@biznetgio/neo-app 0.4.43 → 0.4.46
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 +1 -1
- package/src/mcp/tools.js +49 -2
package/package.json
CHANGED
package/src/mcp/tools.js
CHANGED
|
@@ -210,6 +210,13 @@ export const TOOLS = [
|
|
|
210
210
|
environments: ['staging', 'production'],
|
|
211
211
|
pricing,
|
|
212
212
|
costConsent: { estimateAvailable: true, dryRunIncludesCost: true, planApplyEnforced: true, note: 'neo_plan_stack returns a costed immutable plan; neo_apply_stack is server-enforced (hash/expiry/one-shot) so a billable stack requires a reviewed plan (handoff 3.3-3.5)' },
|
|
213
|
+
// Project/organization lifecycle (issue #107 §3). Honest to THIS build: project
|
|
214
|
+
// deletion is zero-write-preview → exact-name server confirmation → cascade delete;
|
|
215
|
+
// a dedicated costed plan (neo_plan_project_deletion) is not yet exposed, so
|
|
216
|
+
// requiresPlan is false. Organization deletion is unsupported and out of scope —
|
|
217
|
+
// no org-delete tool exists, and deleting a project never deletes its organization.
|
|
218
|
+
project: { delete: true, cascadeDelete: true, requiresPlan: false, requiresConfirmation: true, note: 'neo_delete_project: zero-write preview → exact-name, single-use server confirmation → cascade delete of all child resources.' },
|
|
219
|
+
organization: { delete: false, note: 'Organization deletion is unsupported and out of scope; no organization-delete tool is exposed.' },
|
|
213
220
|
minClientVersion: pkgVersion(),
|
|
214
221
|
deprecations: [],
|
|
215
222
|
};
|
|
@@ -264,7 +271,7 @@ export const TOOLS = [
|
|
|
264
271
|
},
|
|
265
272
|
{
|
|
266
273
|
name: 'neo_confirm_action',
|
|
267
|
-
description: 'Record a human DECISION on a confirmation (NEVER creates or deletes anything itself) — the server-enforced approval step for a high-risk action (project/service deletion, billable create). decision is approve | decline | cancel. Approving a DELETION requires confirmationPhrase to exactly equal the target name (the human must type it). After approve, call the action tool again with this confirmationId to actually perform it (single-use). Show the human the summary from the preview and ask once; never infer consent.',
|
|
274
|
+
description: 'Record a human DECISION on a confirmation (NEVER creates or deletes anything itself) — the server-enforced approval step for a high-risk action (project/service deletion, billable create). decision is approve | decline | cancel. Approving a DELETION requires confirmationPhrase to exactly equal the target name (the human must type it — never manufacture it). If the confirmation has ackRequired:true (a project with production resources), approving ALSO requires acknowledgeNoRefund:true. After approve, call the action tool again with this confirmationId to actually perform it (single-use). Show the human the summary from the preview and ask once; never infer consent.',
|
|
268
275
|
mutating: true,
|
|
269
276
|
schema: {
|
|
270
277
|
type: 'object',
|
|
@@ -272,11 +279,12 @@ export const TOOLS = [
|
|
|
272
279
|
confirmationId: str('Confirmation id (from a destructive preview or a plan)'),
|
|
273
280
|
decision: { type: 'string', enum: ['approve', 'decline', 'cancel'], description: 'approve | decline | cancel' },
|
|
274
281
|
confirmationPhrase: str('For a deletion: the EXACT target name, typed by the human, required to approve'),
|
|
282
|
+
acknowledgeNoRefund: { type: 'boolean', description: 'Required to approve when the confirmation has ackRequired:true (production project delete): the human explicitly acknowledges there is no refund, credit, or proration.' },
|
|
275
283
|
},
|
|
276
284
|
required: ['confirmationId', 'decision'],
|
|
277
285
|
},
|
|
278
286
|
async call(api, args) {
|
|
279
|
-
const { status, data } = await api.post(`/api/v1/confirmations/${args.confirmationId}/decide`, { decision: args.decision, confirmationPhrase: args.confirmationPhrase });
|
|
287
|
+
const { status, data } = await api.post(`/api/v1/confirmations/${args.confirmationId}/decide`, { decision: args.decision, confirmationPhrase: args.confirmationPhrase, acknowledgeNoRefund: args.acknowledgeNoRefund === true });
|
|
280
288
|
return result(status, data);
|
|
281
289
|
},
|
|
282
290
|
},
|
|
@@ -1250,6 +1258,45 @@ export const TOOLS = [
|
|
|
1250
1258
|
return result(status, data);
|
|
1251
1259
|
},
|
|
1252
1260
|
},
|
|
1261
|
+
{
|
|
1262
|
+
name: 'neo_plan_project_deletion',
|
|
1263
|
+
description:
|
|
1264
|
+
'Create a ZERO-WRITE, immutable deletion plan for a project (#107 §4): enumerates the full child inventory, pins it (planId/planHash, expires in 15 min), and returns the reverse-dependency delete phases + a server-side exact-name project_delete confirmation. Deletes NOTHING. Then: show the user the inventory + no-refund warning, call neo_confirm_action(confirmationId, "approve", confirmationPhrase=<EXACT project name>, and acknowledgeNoRefund:true if ackRequired), then neo_apply_project_deletion(planId, planHash, confirmationId). Poll neo_get_operation/neo_wait_operation. Destructive, irreversible, no refund; the organization is never deleted.',
|
|
1265
|
+
mutating: false,
|
|
1266
|
+
schema: {
|
|
1267
|
+
type: 'object',
|
|
1268
|
+
properties: {
|
|
1269
|
+
projectId: str('Project id'),
|
|
1270
|
+
cascade: { type: 'boolean', description: 'REQUIRED true for a non-empty project — plan deleting the project AND all of its resources.' },
|
|
1271
|
+
},
|
|
1272
|
+
required: ['projectId'],
|
|
1273
|
+
},
|
|
1274
|
+
async call(api, args) {
|
|
1275
|
+
const { status, data } = await api.post(`/api/v1/projects/${args.projectId}/plans/deletion`, { cascade: args.cascade === true });
|
|
1276
|
+
return redactSecrets(result(status, data));
|
|
1277
|
+
},
|
|
1278
|
+
},
|
|
1279
|
+
{
|
|
1280
|
+
name: 'neo_apply_project_deletion',
|
|
1281
|
+
description:
|
|
1282
|
+
'Apply an APPROVED project-deletion plan (#107 §8): deletes the project and ALL its resources in reverse dependency order, server-enforced + single-use. Requires planId + planHash (from neo_plan_project_deletion) and an APPROVED confirmationId (from neo_confirm_action). Returns an operationId — poll neo_get_operation / neo_wait_operation for per-resource phase status (deleting_scheduled_jobs → applications → bindings → queues_and_buckets → databases → deleting_project → reconciling_metering; terminal applied|partial). Destructive, irreversible, no refund; the organization is never deleted.',
|
|
1283
|
+
mutating: true,
|
|
1284
|
+
destructive: true,
|
|
1285
|
+
schema: {
|
|
1286
|
+
type: 'object',
|
|
1287
|
+
properties: {
|
|
1288
|
+
planId: str('Plan id from neo_plan_project_deletion'),
|
|
1289
|
+
planHash: str('Plan hash from neo_plan_project_deletion'),
|
|
1290
|
+
confirmationId: str('An APPROVED project_delete confirmation id (from neo_confirm_action)'),
|
|
1291
|
+
idempotencyKey: str('Optional idempotency key'),
|
|
1292
|
+
},
|
|
1293
|
+
required: ['planId', 'planHash', 'confirmationId'],
|
|
1294
|
+
},
|
|
1295
|
+
async call(api, args) {
|
|
1296
|
+
const { status, data } = await api.post(`/api/v1/plans/${args.planId}/apply`, { planHash: args.planHash, confirmationId: args.confirmationId, idempotencyKey: args.idempotencyKey });
|
|
1297
|
+
return redactSecrets(result(status, data));
|
|
1298
|
+
},
|
|
1299
|
+
},
|
|
1253
1300
|
// --- Costed plan / apply backbone (handoff 3.3-3.5 + 7): plan a whole stack
|
|
1254
1301
|
// zero-write, review the cost, then apply with the plan id+hash. The server
|
|
1255
1302
|
// enforces the plan (hash/expiry/one-shot) and runs it in dependency order. ---
|