@clue-ai/cli 0.0.6 → 0.0.8
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 +11 -14
- package/bin/clue-cli.mjs +114 -21
- package/commands/claude-code/clue-init.md +6 -5
- package/commands/codex/clue-init.md +6 -5
- package/package.json +1 -1
- package/src/ai-provider.mjs +3 -2
- package/src/command-spec.mjs +2 -0
- package/src/contracts.mjs +5 -4
- package/src/init-tool.mjs +5 -6
- package/src/public-schema.cjs +47 -0
- package/src/semantic-agent-runner.mjs +157 -0
- package/src/semantic-ai-config.mjs +17 -0
- package/src/semantic-ci.mjs +419 -57
- package/src/setup-check.mjs +28 -2
- package/src/setup-prepare.mjs +181 -14
- package/src/setup-tool.mjs +159 -11
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
export const SEMANTIC_AGENT_RUNNER_VERSION = "semantic-agent-runner-v1";
|
|
2
|
+
|
|
3
|
+
export const SEMANTIC_AGENT_ROLE_IDS = {
|
|
4
|
+
routeInventory: "route_inventory",
|
|
5
|
+
reuseJudge: "semantic_reuse_judge",
|
|
6
|
+
routeSemanticGenerator: "route_semantic_generator",
|
|
7
|
+
semanticSelector: "semantic_selector",
|
|
8
|
+
semanticAuditor: "semantic_auditor",
|
|
9
|
+
snapshotFinalizer: "snapshot_finalizer",
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const requiredRoleIds = new Set(Object.values(SEMANTIC_AGENT_ROLE_IDS));
|
|
13
|
+
|
|
14
|
+
export const semanticAgentSkillBundle = () => ({
|
|
15
|
+
runner_version: SEMANTIC_AGENT_RUNNER_VERSION,
|
|
16
|
+
execution_model: "ci_semantic_agent_runner",
|
|
17
|
+
ci_entrypoint: "clue-ai semantic-gen",
|
|
18
|
+
rules: [
|
|
19
|
+
"GitHub Actions runs only the CLI; the CLI owns route coverage, AI role orchestration, schema validation, and upload.",
|
|
20
|
+
"Mechanically scan every route before any AI call.",
|
|
21
|
+
"Use AI only for semantic judgment: reuse decision, route semantics, and semantic field selection.",
|
|
22
|
+
"Never use AI to decide whether a discovered route can be skipped.",
|
|
23
|
+
"Fail closed when the previous snapshot cannot be loaded, unless explicit full regeneration is enabled.",
|
|
24
|
+
"Persist only schema-validated, privacy-safe semantic snapshot payloads.",
|
|
25
|
+
],
|
|
26
|
+
roles: [
|
|
27
|
+
{
|
|
28
|
+
id: SEMANTIC_AGENT_ROLE_IDS.routeInventory,
|
|
29
|
+
kind: "mechanical",
|
|
30
|
+
responsibility:
|
|
31
|
+
"Discover every backend route and produce deterministic operation_source_key values before AI execution.",
|
|
32
|
+
ai_allowed: false,
|
|
33
|
+
output_contract: "deterministic_route_inventory",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: SEMANTIC_AGENT_ROLE_IDS.reuseJudge,
|
|
37
|
+
kind: "ai",
|
|
38
|
+
responsibility:
|
|
39
|
+
"Judge whether a changed route can safely keep its previous privacy-safe semantics.",
|
|
40
|
+
ai_allowed: true,
|
|
41
|
+
output_contract: "return_reuse_decision",
|
|
42
|
+
failure_policy: "needs_review",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: SEMANTIC_AGENT_ROLE_IDS.routeSemanticGenerator,
|
|
46
|
+
kind: "ai",
|
|
47
|
+
responsibility:
|
|
48
|
+
"Generate privacy-safe route semantic candidates for new or changed routes only.",
|
|
49
|
+
ai_allowed: true,
|
|
50
|
+
output_contract: "return_route_semantics",
|
|
51
|
+
failure_policy: "fallback_unknown_route_semantics",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: SEMANTIC_AGENT_ROLE_IDS.semanticSelector,
|
|
55
|
+
kind: "ai",
|
|
56
|
+
responsibility:
|
|
57
|
+
"Select adopted semantic fields from deterministic and AI candidates without inventing ids, hashes, paths, or raw code.",
|
|
58
|
+
ai_allowed: true,
|
|
59
|
+
output_contract: "return_semantic_selection",
|
|
60
|
+
failure_policy: "fail_snapshot_generation",
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: SEMANTIC_AGENT_ROLE_IDS.semanticAuditor,
|
|
64
|
+
kind: "mechanical",
|
|
65
|
+
responsibility:
|
|
66
|
+
"Verify route coverage, privacy boundaries, generation contract, and snapshot schema before upload.",
|
|
67
|
+
ai_allowed: false,
|
|
68
|
+
output_contract: "deterministic_audit_result",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: SEMANTIC_AGENT_ROLE_IDS.snapshotFinalizer,
|
|
72
|
+
kind: "mechanical",
|
|
73
|
+
responsibility:
|
|
74
|
+
"Finalize content-based snapshot version, idempotency key, and Clue API upload payload.",
|
|
75
|
+
ai_allowed: false,
|
|
76
|
+
output_contract: "semantic_snapshot_request",
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
export const validateSemanticAgentSkillBundle = (bundle) => {
|
|
82
|
+
if (!bundle || typeof bundle !== "object") {
|
|
83
|
+
throw new Error("semantic agent skill bundle must be an object");
|
|
84
|
+
}
|
|
85
|
+
if (bundle.runner_version !== SEMANTIC_AGENT_RUNNER_VERSION) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`semantic agent skill bundle runner_version must be ${SEMANTIC_AGENT_RUNNER_VERSION}`,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
if (bundle.execution_model !== "ci_semantic_agent_runner") {
|
|
91
|
+
throw new Error(
|
|
92
|
+
"semantic agent skill bundle execution_model must be ci_semantic_agent_runner",
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
if (!Array.isArray(bundle.roles)) {
|
|
96
|
+
throw new Error("semantic agent skill bundle roles must be an array");
|
|
97
|
+
}
|
|
98
|
+
const roleIds = new Set();
|
|
99
|
+
for (const role of bundle.roles) {
|
|
100
|
+
if (!role || typeof role !== "object") {
|
|
101
|
+
throw new Error("semantic agent skill bundle contains an invalid role");
|
|
102
|
+
}
|
|
103
|
+
if (typeof role.id !== "string" || !requiredRoleIds.has(role.id)) {
|
|
104
|
+
throw new Error(`semantic agent skill bundle contains unknown role`);
|
|
105
|
+
}
|
|
106
|
+
if (roleIds.has(role.id)) {
|
|
107
|
+
throw new Error(`semantic agent skill bundle contains duplicate role`);
|
|
108
|
+
}
|
|
109
|
+
roleIds.add(role.id);
|
|
110
|
+
if (role.kind !== "ai" && role.kind !== "mechanical") {
|
|
111
|
+
throw new Error(`semantic agent role ${role.id} has invalid kind`);
|
|
112
|
+
}
|
|
113
|
+
if (
|
|
114
|
+
typeof role.responsibility !== "string" ||
|
|
115
|
+
role.responsibility.trim() === ""
|
|
116
|
+
) {
|
|
117
|
+
throw new Error(
|
|
118
|
+
`semantic agent role ${role.id} must describe its responsibility`,
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const missingRoles = [...requiredRoleIds].filter((roleId) => !roleIds.has(roleId));
|
|
123
|
+
if (missingRoles.length > 0) {
|
|
124
|
+
throw new Error(
|
|
125
|
+
`semantic agent skill bundle missing roles: ${missingRoles.join(",")}`,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
return bundle;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export const semanticAgentRole = ({ bundle, roleId }) => {
|
|
132
|
+
const validated = validateSemanticAgentSkillBundle(bundle);
|
|
133
|
+
const role = validated.roles.find((entry) => entry.id === roleId);
|
|
134
|
+
if (!role) {
|
|
135
|
+
throw new Error(`semantic agent role is not available: ${roleId}`);
|
|
136
|
+
}
|
|
137
|
+
return role;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export const semanticAgentPromptEnvelope = ({ bundle, roleId }) => {
|
|
141
|
+
const role = semanticAgentRole({ bundle, roleId });
|
|
142
|
+
return {
|
|
143
|
+
agent_runner: {
|
|
144
|
+
runner_version: bundle.runner_version,
|
|
145
|
+
execution_model: bundle.execution_model,
|
|
146
|
+
ci_entrypoint: bundle.ci_entrypoint,
|
|
147
|
+
},
|
|
148
|
+
agent_role: {
|
|
149
|
+
id: role.id,
|
|
150
|
+
kind: role.kind,
|
|
151
|
+
responsibility: role.responsibility,
|
|
152
|
+
output_contract: role.output_contract,
|
|
153
|
+
failure_policy: role.failure_policy ?? null,
|
|
154
|
+
},
|
|
155
|
+
coordination_rules: bundle.rules,
|
|
156
|
+
};
|
|
157
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const CLUE_CLIENT_CI_SEMANTIC_AI_MODE = "client_ci";
|
|
2
|
+
export const CLUE_CLIENT_CI_SEMANTIC_AI_MODEL_SOURCE = "customer_ci_secret";
|
|
3
|
+
|
|
4
|
+
export const clueClientCiSemanticAiRuntime = ({
|
|
5
|
+
provider,
|
|
6
|
+
model,
|
|
7
|
+
roleIds,
|
|
8
|
+
runnerVersion,
|
|
9
|
+
}) => ({
|
|
10
|
+
mode: CLUE_CLIENT_CI_SEMANTIC_AI_MODE,
|
|
11
|
+
provider,
|
|
12
|
+
model,
|
|
13
|
+
model_source: CLUE_CLIENT_CI_SEMANTIC_AI_MODEL_SOURCE,
|
|
14
|
+
runner_version: runnerVersion,
|
|
15
|
+
role_ids: roleIds,
|
|
16
|
+
temperature: 0,
|
|
17
|
+
});
|