@fjall/ai-tools 3.5.2 → 3.6.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/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/manageDomainCommands.d.ts +43 -0
- package/dist/manageDomainCommands.js +98 -0
- package/dist/registry.d.ts +2 -1
- package/dist/registry.js +4 -2
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export type { ToolTier, ToolSpec, AiToolName } from "./types.js";
|
|
2
2
|
export { AI_TOOL_NAMES } from "./types.js";
|
|
3
3
|
export { AI_TOOL_REGISTRY, getToolSpec } from "./registry.js";
|
|
4
|
+
export { MANAGE_DOMAIN_MUTATION_COMMANDS, MANAGE_DOMAIN_MUTATION_CONTRACT, MANAGE_DOMAIN_MUTATION_SUMMARY, buildMutationCommands, } from "./manageDomainCommands.js";
|
|
5
|
+
export type { ManageDomainMutationCommand } from "./manageDomainCommands.js";
|
|
4
6
|
export * from "./schemas/index.js";
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { AI_TOOL_NAMES } from "./types.js";
|
|
2
2
|
export { AI_TOOL_REGISTRY, getToolSpec } from "./registry.js";
|
|
3
|
+
export { MANAGE_DOMAIN_MUTATION_COMMANDS, MANAGE_DOMAIN_MUTATION_CONTRACT, MANAGE_DOMAIN_MUTATION_SUMMARY, buildMutationCommands, } from "./manageDomainCommands.js";
|
|
3
4
|
export * from "./schemas/index.js";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for the manage_domain mutation-command catalogue.
|
|
3
|
+
*
|
|
4
|
+
* The registry description, the webapp executor's mutation_commands result,
|
|
5
|
+
* and the webapp system prompt all enumerate these commands; each copy must
|
|
6
|
+
* be DERIVED from this catalogue so the enumerations cannot drift. Content
|
|
7
|
+
* ported verbatim from the webapp executor's buildMutationCommands
|
|
8
|
+
* (webapp app/.server/services/ai/tools/manageDomain.ts), which imports it
|
|
9
|
+
* back from here once the swap phase lands.
|
|
10
|
+
*/
|
|
11
|
+
/** One ceremony-gated (or safe) CLI command the read-only tool relays. */
|
|
12
|
+
export interface ManageDomainMutationCommand {
|
|
13
|
+
/** CLI invocation template; "<zone>" marks the zone argument. */
|
|
14
|
+
command: string;
|
|
15
|
+
purpose: string;
|
|
16
|
+
/** How the destruction ceremony gates this command; null for safe verbs. */
|
|
17
|
+
ceremony: string | null;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The no-destructive-consent contract, phrased the way the CLI's exit-4
|
|
21
|
+
* (DESTRUCTION_WITHHELD) help text and the agent destruction-gate recipe
|
|
22
|
+
* phrase it, so the model relays the ceremony instead of trying to bypass it.
|
|
23
|
+
*/
|
|
24
|
+
export declare const MANAGE_DOMAIN_MUTATION_CONTRACT: readonly string[];
|
|
25
|
+
/** Every mutation command the manage_domain tool relays but never executes. */
|
|
26
|
+
export declare const MANAGE_DOMAIN_MUTATION_COMMANDS: readonly ManageDomainMutationCommand[];
|
|
27
|
+
/**
|
|
28
|
+
* The catalogue's command verbs joined with "/" -- interpolated into the
|
|
29
|
+
* registry description (and, post-swap, the webapp system prompt) so every
|
|
30
|
+
* prose enumeration is derived from the one list and cannot drift.
|
|
31
|
+
*/
|
|
32
|
+
export declare const MANAGE_DOMAIN_MUTATION_SUMMARY: string;
|
|
33
|
+
/**
|
|
34
|
+
* The mutation_commands executor payload: the contract plus the catalogue
|
|
35
|
+
* with "<zone>" substituted when the caller already knows the zone. The
|
|
36
|
+
* caller passes an already-normalised zone (the webapp keeps
|
|
37
|
+
* normaliseRecordName at its boundary); ceremony prose placeholders such as
|
|
38
|
+
* "<name>/<TYPE>" are consent syntax, never substituted.
|
|
39
|
+
*/
|
|
40
|
+
export declare function buildMutationCommands(zone?: string): {
|
|
41
|
+
contract: string[];
|
|
42
|
+
commands: ManageDomainMutationCommand[];
|
|
43
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for the manage_domain mutation-command catalogue.
|
|
3
|
+
*
|
|
4
|
+
* The registry description, the webapp executor's mutation_commands result,
|
|
5
|
+
* and the webapp system prompt all enumerate these commands; each copy must
|
|
6
|
+
* be DERIVED from this catalogue so the enumerations cannot drift. Content
|
|
7
|
+
* ported verbatim from the webapp executor's buildMutationCommands
|
|
8
|
+
* (webapp app/.server/services/ai/tools/manageDomain.ts), which imports it
|
|
9
|
+
* back from here once the swap phase lands.
|
|
10
|
+
*/
|
|
11
|
+
/** Placeholder substituted by {@link buildMutationCommands} when a zone is known. */
|
|
12
|
+
const ZONE_PLACEHOLDER = "<zone>";
|
|
13
|
+
/**
|
|
14
|
+
* The no-destructive-consent contract, phrased the way the CLI's exit-4
|
|
15
|
+
* (DESTRUCTION_WITHHELD) help text and the agent destruction-gate recipe
|
|
16
|
+
* phrase it, so the model relays the ceremony instead of trying to bypass it.
|
|
17
|
+
*/
|
|
18
|
+
export const MANAGE_DOMAIN_MUTATION_CONTRACT = [
|
|
19
|
+
"This tool is read-only: it never executes domain mutations and never holds destructive-consent power. Run the commands below from the repository's CLI instead.",
|
|
20
|
+
"Destructive domain surfaces stop at an unconditional destruction gate — no flag disengages it, and --auto-approve, --skip-confirmation, --force and approval tokens never satisfy it. The command stops with exit 4 (DESTRUCTION_WITHHELD): success-shaped — nothing was deleted, nothing was deployed — and prints a ticket naming each affected record.",
|
|
21
|
+
"Relay the ticket to the user verbatim and let them pick each row's verb — never self-select a destructive verb on the user's behalf: 'recreate' destroys the live record's data and 'forget' abandons it.",
|
|
22
|
+
"Consent is per-row and exact: --remediate '<name>/<TYPE>[@<setIdentifier>]'=recreate (repeatable; exact spelling from the ticket — the @ tail appears on routing-policy variants), optionally bound with --destruction-consent-digest <digest>. A misspelt name, surplus consent, or illegal verb fails closed with a per-name verdict table.",
|
|
23
|
+
];
|
|
24
|
+
/** Every mutation command the manage_domain tool relays but never executes. */
|
|
25
|
+
export const MANAGE_DOMAIN_MUTATION_COMMANDS = [
|
|
26
|
+
{
|
|
27
|
+
command: `fjall create domain --name ${ZONE_PLACEHOLDER}`,
|
|
28
|
+
purpose: "Register a domain (add --external when DNS stays managed outside Fjall).",
|
|
29
|
+
ceremony: null,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
command: `fjall domain import ${ZONE_PLACEHOLDER} --from-route53`,
|
|
33
|
+
purpose: "Migrate existing DNS in — curates infrastructure.ts; the first deploy of an adopted zone runs the takeover ceremony.",
|
|
34
|
+
ceremony: null,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
command: `fjall domain deploy ${ZONE_PLACEHOLDER}`,
|
|
38
|
+
purpose: "Apply domain infrastructure ('fjall deploy domain' is the same operation, same flags, same exit codes).",
|
|
39
|
+
ceremony: "Deploying an adopted live zone stops at a record-takeover ticket: one consent per row, --remediate '<name>/<TYPE>[@<setIdentifier>]'=recreate; exit 4 means consent was withheld and nothing was deployed.",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
command: `fjall domain sync ${ZONE_PLACEHOLDER} --fix`,
|
|
43
|
+
purpose: "Delete residue records (the records sync_report classifies 'residue').",
|
|
44
|
+
ceremony: "Same consent shape: --remediate '<name>/<TYPE>[@<setIdentifier>]'=recreate. 'unknown' rows never appear on the ticket — classification fails closed; exit 4 means nothing was deleted.",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
command: `fjall domain delegate ${ZONE_PLACEHOLDER}`,
|
|
48
|
+
purpose: "Write (or report) a delegated child's NS records into the parent zone.",
|
|
49
|
+
ceremony: null,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
command: `fjall domain destroy ${ZONE_PLACEHOLDER}`,
|
|
53
|
+
purpose: "Destroy the domain stack and its hosted zone.",
|
|
54
|
+
ceremony: "Apex row: --remediate '<zoneName>'=recreate; delegated-child NS row: --remediate '<childZone>/NS'=recreate (or =forget when the parent cannot delete the record). Children are NS-delete-first; exit 4 means nothing was destroyed.",
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
/**
|
|
58
|
+
* Distinguishing verb of a catalogue command: the first token after the
|
|
59
|
+
* binary name that is neither the "domain" noun nor a flag, plus any mode
|
|
60
|
+
* flags positioned after the zone argument (so "sync" reads "sync --fix" --
|
|
61
|
+
* bare "sync" is the read-only report, not a mutation).
|
|
62
|
+
*/
|
|
63
|
+
function mutationCommandVerb(command) {
|
|
64
|
+
const tokens = command.split(" ");
|
|
65
|
+
const verb = tokens
|
|
66
|
+
.slice(1)
|
|
67
|
+
.find((token) => token !== "domain" &&
|
|
68
|
+
token !== ZONE_PLACEHOLDER &&
|
|
69
|
+
!token.startsWith("--"));
|
|
70
|
+
const zoneIndex = tokens.indexOf(ZONE_PLACEHOLDER);
|
|
71
|
+
const modeFlags = zoneIndex === -1
|
|
72
|
+
? []
|
|
73
|
+
: tokens.slice(zoneIndex + 1).filter((token) => token.startsWith("--"));
|
|
74
|
+
return [verb ?? command, ...modeFlags].join(" ");
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The catalogue's command verbs joined with "/" -- interpolated into the
|
|
78
|
+
* registry description (and, post-swap, the webapp system prompt) so every
|
|
79
|
+
* prose enumeration is derived from the one list and cannot drift.
|
|
80
|
+
*/
|
|
81
|
+
export const MANAGE_DOMAIN_MUTATION_SUMMARY = MANAGE_DOMAIN_MUTATION_COMMANDS.map((entry) => mutationCommandVerb(entry.command)).join("/");
|
|
82
|
+
/**
|
|
83
|
+
* The mutation_commands executor payload: the contract plus the catalogue
|
|
84
|
+
* with "<zone>" substituted when the caller already knows the zone. The
|
|
85
|
+
* caller passes an already-normalised zone (the webapp keeps
|
|
86
|
+
* normaliseRecordName at its boundary); ceremony prose placeholders such as
|
|
87
|
+
* "<name>/<TYPE>" are consent syntax, never substituted.
|
|
88
|
+
*/
|
|
89
|
+
export function buildMutationCommands(zone) {
|
|
90
|
+
const target = zone ?? ZONE_PLACEHOLDER;
|
|
91
|
+
return {
|
|
92
|
+
contract: [...MANAGE_DOMAIN_MUTATION_CONTRACT],
|
|
93
|
+
commands: MANAGE_DOMAIN_MUTATION_COMMANDS.map((entry) => ({
|
|
94
|
+
...entry,
|
|
95
|
+
command: entry.command.replaceAll(ZONE_PLACEHOLDER, target),
|
|
96
|
+
})),
|
|
97
|
+
};
|
|
98
|
+
}
|
package/dist/registry.d.ts
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This is the single source of truth for tool names, descriptions, tiers,
|
|
5
5
|
* and input schemas. The webapp imports these to build the Anthropic API
|
|
6
|
-
* tool array; the
|
|
6
|
+
* tool array; it is currently the package's only consumer (the CLI has no
|
|
7
|
+
* dependency on @fjall/ai-tools).
|
|
7
8
|
*/
|
|
8
9
|
import type { ToolSpec } from "./types.js";
|
|
9
10
|
/** All AI tool specifications, ordered: read tools first, then write tools. */
|
package/dist/registry.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This is the single source of truth for tool names, descriptions, tiers,
|
|
5
5
|
* and input schemas. The webapp imports these to build the Anthropic API
|
|
6
|
-
* tool array; the
|
|
6
|
+
* tool array; it is currently the package's only consumer (the CLI has no
|
|
7
|
+
* dependency on @fjall/ai-tools).
|
|
7
8
|
*/
|
|
8
9
|
import { queryInfrastructureSchema } from "./schemas/queryInfrastructure.js";
|
|
9
10
|
import { queryComplianceSchema } from "./schemas/queryCompliance.js";
|
|
@@ -19,6 +20,7 @@ import { manageSecretSchema } from "./schemas/manageSecret.js";
|
|
|
19
20
|
import { updateConfigurationSchema } from "./schemas/updateConfiguration.js";
|
|
20
21
|
import { manageDomainSchema } from "./schemas/manageDomain.js";
|
|
21
22
|
import { provisionRegionSchema } from "./schemas/provisionRegion.js";
|
|
23
|
+
import { MANAGE_DOMAIN_MUTATION_SUMMARY } from "./manageDomainCommands.js";
|
|
22
24
|
function spec(name, description, inputSchema, tier, requiredRole) {
|
|
23
25
|
return { name, description, inputSchema, tier, requiredRole };
|
|
24
26
|
}
|
|
@@ -38,7 +40,7 @@ export const AI_TOOL_REGISTRY = [
|
|
|
38
40
|
spec("trigger_deployment", "Trigger a new deployment for an application. Verifies the application exists, has a connected AWS account and repository, and no active deployment is running. Creates a deployment record and enqueues it for processing.", triggerDeploymentSchema, "write", "admin"),
|
|
39
41
|
spec("manage_secret", "Manage application secrets stored in AWS SSM Parameter Store. Supports: list (show secret names without values), set (create or update), and delete. Never exposes secret values — the get operation is intentionally excluded.", manageSecretSchema, "write", "admin"),
|
|
40
42
|
spec("update_configuration", "Update an application's configuration — name, description, or config path. Only safe, non-security-sensitive fields can be changed. At least one field must be provided.", updateConfigurationSchema, "write", "admin"),
|
|
41
|
-
spec("manage_domain",
|
|
43
|
+
spec("manage_domain", `Read-only domain management mirroring the CLI domain surface. Operations: list (declared domains with live zone and stack status), records_list (every live record with its ownership classification - declared/satellite/residue/unknown; unknown is never remediable, classification fails closed), sync_report (the same classification as a read-only report - this tool never deletes records), verify (DNS nameserver delegation check), and mutation_commands (the exact ceremony-gated CLI commands for ${MANAGE_DOMAIN_MUTATION_SUMMARY}, which this tool never executes - destructive consent stays with the user).`, manageDomainSchema, "read"),
|
|
42
44
|
spec("provision_region", "Add an AWS region to the organisation and deploy infrastructure to it. Shows a consequence preview (affected accounts, deployment shape) before asking the user to confirm. Requires admin role.", provisionRegionSchema, "write", "admin"),
|
|
43
45
|
];
|
|
44
46
|
/** Look up a tool spec by name. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjall/ai-tools",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"description": "Shared AI tool schemas and registry for Fjall webapp and CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -51,5 +51,5 @@
|
|
|
51
51
|
"engines": {
|
|
52
52
|
"node": ">=22.0.0"
|
|
53
53
|
},
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "10366db602d7e80669e22825a52071a47e05c3b7"
|
|
55
55
|
}
|