@clue-ai/cli 0.0.9 → 0.0.11
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 +37 -26
- package/bin/clue-cli.mjs +93 -54
- package/package.json +1 -1
- package/src/cli-invocation.mjs +34 -0
- package/src/command-spec.mjs +3 -0
- package/src/init-tool.mjs +2 -1
- package/src/lifecycle-guard.mjs +168 -103
- package/src/lifecycle-init.mjs +593 -187
- package/src/semantic-agent-runner.mjs +3 -1
- package/src/setup-check.mjs +641 -47
- package/src/setup-help.mjs +69 -0
- package/src/setup-prepare.mjs +78 -15
- package/src/setup-tool.mjs +421 -388
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CLUE_CLI_INVOCATION_CONTRACT,
|
|
3
|
+
clueCliCommand,
|
|
4
|
+
} from "./cli-invocation.mjs";
|
|
5
|
+
|
|
6
|
+
export const AI_SETUP_HELP_VERSION = "2026-05-10.lifecycle-placement-only.v1";
|
|
7
|
+
|
|
8
|
+
export const buildAiSetupHelp = () => ({
|
|
9
|
+
name: "@clue-ai/cli AI setup help",
|
|
10
|
+
version: AI_SETUP_HELP_VERSION,
|
|
11
|
+
purpose:
|
|
12
|
+
"Machine-readable Clue setup contract for AI coding agents. Use this before editing a customer repository for Clue setup.",
|
|
13
|
+
cli_invocation: CLUE_CLI_INVOCATION_CONTRACT,
|
|
14
|
+
setup_execution_contract: {
|
|
15
|
+
agent_primary_task:
|
|
16
|
+
"Decide where to place ClueInit, ClueIdentify, ClueSetAccount, and ClueLogout in existing repository lifecycle boundaries, then apply only those minimal Clue SDK wiring changes.",
|
|
17
|
+
implementation_workstreams: ["sdk_lifecycle_placement"],
|
|
18
|
+
lifecycle_apis_in_scope: [
|
|
19
|
+
"ClueInit",
|
|
20
|
+
"ClueIdentify",
|
|
21
|
+
"ClueSetAccount",
|
|
22
|
+
"ClueLogout",
|
|
23
|
+
],
|
|
24
|
+
lifecycle_apis_out_of_scope_by_default: ["ClueTrack"],
|
|
25
|
+
allowed_change_scope: {
|
|
26
|
+
rule: "Only changes required to place ClueInit, ClueIdentify, ClueSetAccount, and ClueLogout are allowed.",
|
|
27
|
+
allowed: [
|
|
28
|
+
"Clue SDK dependency declarations and lockfile changes needed to install those SDKs",
|
|
29
|
+
"Clue SDK imports, bootstrap adapters, and single initialization points",
|
|
30
|
+
"backend-owned browser token endpoints required so frontend SDK code never exposes CLUE_API_KEY",
|
|
31
|
+
"Clue lifecycle calls at existing clear login, logout, account, workspace, organization, or tenant boundaries",
|
|
32
|
+
"tests or verification scripts directly proving the four lifecycle API placement decisions",
|
|
33
|
+
],
|
|
34
|
+
forbidden: [
|
|
35
|
+
"ClueTrack instrumentation unless the user explicitly requested product event tracking",
|
|
36
|
+
"semantic snapshot implementation or CI workflow edits during lifecycle placement",
|
|
37
|
+
"unrelated refactors, renames, file moves, formatting churn, or broad cleanup",
|
|
38
|
+
"business logic changes that are not required for Clue setup",
|
|
39
|
+
"auth/session flow rewrites beyond the minimal Clue hook insertion point",
|
|
40
|
+
"UI layout, styling, copy, or navigation changes unrelated to Clue setup",
|
|
41
|
+
"dependency upgrades unrelated to Clue SDK installability",
|
|
42
|
+
"hand-authored semantic snapshot artifacts or runtime request files",
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
setup_watch: {
|
|
46
|
+
owner: "user",
|
|
47
|
+
ai_agent_must_run: false,
|
|
48
|
+
command: clueCliCommand("setup-watch --local"),
|
|
49
|
+
rule: "Do not run setup-watch during implementation. setup-watch and the Clue setup screen require user-operated local services and real login/logout/account flows.",
|
|
50
|
+
ai_agent_responsibility:
|
|
51
|
+
"Report the command and required user verification as pending when it was not run by the user.",
|
|
52
|
+
},
|
|
53
|
+
completion_boundary: {
|
|
54
|
+
ai_may_claim: [
|
|
55
|
+
"Clue setup code changes were applied",
|
|
56
|
+
"static setup-check passed",
|
|
57
|
+
"SDK dependency install/import/build/typecheck checks passed when actually run",
|
|
58
|
+
],
|
|
59
|
+
ai_must_not_claim: [
|
|
60
|
+
"setup completed",
|
|
61
|
+
"event delivery verified",
|
|
62
|
+
"setup-watch passed",
|
|
63
|
+
"Clue setup screen verification passed",
|
|
64
|
+
],
|
|
65
|
+
final_status_when_setup_watch_not_user_verified:
|
|
66
|
+
"user_verification_pending",
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
});
|
package/src/setup-prepare.mjs
CHANGED
|
@@ -4,6 +4,10 @@ import {
|
|
|
4
4
|
buildSemanticWorkflowRequestFromFlags,
|
|
5
5
|
writeSemanticWorkflow,
|
|
6
6
|
} from "./init-tool.mjs";
|
|
7
|
+
import {
|
|
8
|
+
CLUE_CLI_INVOCATION_CONTRACT,
|
|
9
|
+
clueCliCommand,
|
|
10
|
+
} from "./cli-invocation.mjs";
|
|
7
11
|
import { runSetupDetect } from "./setup-detect.mjs";
|
|
8
12
|
|
|
9
13
|
const DEFAULT_SETUP_MANIFEST_PATH = ".clue/setup-manifest.json";
|
|
@@ -169,6 +173,9 @@ const buildServiceEnvBlock = ({ target, setupContext }) => {
|
|
|
169
173
|
name: "CLUE_INGEST_ENDPOINT",
|
|
170
174
|
value: buildEndpoint(setupContext.clue_api_base_url, ingestPath),
|
|
171
175
|
},
|
|
176
|
+
...(target.kind === "backend"
|
|
177
|
+
? [{ name: "CLUE_API_BASE_URL", value: setupContext.clue_api_base_url }]
|
|
178
|
+
: []),
|
|
172
179
|
{ name: "CLUE_PROJECT_KEY", value: setupContext.project_key },
|
|
173
180
|
{ name: "CLUE_ENVIRONMENT", value: setupContext.environment },
|
|
174
181
|
{ name: "CLUE_SERVICE_KEY", value: target.service_key },
|
|
@@ -222,6 +229,9 @@ const buildEnvironmentInstructions = ({ manifest, setupContext }) => {
|
|
|
222
229
|
},
|
|
223
230
|
],
|
|
224
231
|
variables: [
|
|
232
|
+
{ name: "CLUE_PROJECT_KEY", value: setupContext.project_key },
|
|
233
|
+
{ name: "CLUE_ENVIRONMENT", value: setupContext.environment },
|
|
234
|
+
{ name: "CLUE_API_BASE_URL", value: setupContext.clue_api_base_url },
|
|
225
235
|
{
|
|
226
236
|
name: "CLUE_AI_PROVIDER",
|
|
227
237
|
value: aiProviderGuide.provider,
|
|
@@ -282,8 +292,7 @@ const summarizeEnvironmentInstructions = (instructions) => {
|
|
|
282
292
|
return {
|
|
283
293
|
status: "ready",
|
|
284
294
|
env_file_path: instructions.env_file_path,
|
|
285
|
-
message:
|
|
286
|
-
`${instructions.env_file_path} を開き、各サービスの env と GitHub Secrets に反映してください。`,
|
|
295
|
+
message: `${instructions.env_file_path} を開き、各サービスの env と GitHub Secrets に反映してください。`,
|
|
287
296
|
service_env_block_count: instructions.service_env_blocks.length,
|
|
288
297
|
github_secret_names: instructions.ci_github.secrets.map(
|
|
289
298
|
(entry) => entry.name,
|
|
@@ -326,8 +335,18 @@ export const runSetupPrepare = async ({
|
|
|
326
335
|
ai_next_scope: "blocked_until_backend_routes_are_detected",
|
|
327
336
|
machine_owned_artifacts: [],
|
|
328
337
|
ai_owned_workstreams: [
|
|
329
|
-
"
|
|
338
|
+
"sdk_lifecycle_placement_after_blockers_are_resolved",
|
|
330
339
|
],
|
|
340
|
+
ai_implementation_scope: {
|
|
341
|
+
rule: "AI implementation is limited to placing ClueInit, ClueIdentify, ClueSetAccount, and ClueLogout in existing lifecycle boundaries after blockers are resolved.",
|
|
342
|
+
lifecycle_apis: [
|
|
343
|
+
"ClueInit",
|
|
344
|
+
"ClueIdentify",
|
|
345
|
+
"ClueSetAccount",
|
|
346
|
+
"ClueLogout",
|
|
347
|
+
],
|
|
348
|
+
out_of_scope_by_default: ["ClueTrack"],
|
|
349
|
+
},
|
|
331
350
|
};
|
|
332
351
|
await writeJson({
|
|
333
352
|
repoRoot: resolvedRepoRoot,
|
|
@@ -340,8 +359,9 @@ export const runSetupPrepare = async ({
|
|
|
340
359
|
});
|
|
341
360
|
return {
|
|
342
361
|
...manifest,
|
|
343
|
-
environment_instructions:
|
|
344
|
-
|
|
362
|
+
environment_instructions: summarizeEnvironmentInstructions(
|
|
363
|
+
environmentInstructions,
|
|
364
|
+
),
|
|
345
365
|
};
|
|
346
366
|
}
|
|
347
367
|
|
|
@@ -349,9 +369,6 @@ export const runSetupPrepare = async ({
|
|
|
349
369
|
framework: candidate.framework,
|
|
350
370
|
backendRootPath: candidate.backend_root_path,
|
|
351
371
|
serviceKey: candidate.service_key,
|
|
352
|
-
projectKey: setupContext.project_key,
|
|
353
|
-
environment: setupContext.environment,
|
|
354
|
-
clueApiBaseUrl: setupContext.clue_api_base_url,
|
|
355
372
|
});
|
|
356
373
|
const workflow = await writeSemanticWorkflow({
|
|
357
374
|
repoRoot: resolvedRepoRoot,
|
|
@@ -373,6 +390,7 @@ export const runSetupPrepare = async ({
|
|
|
373
390
|
frontend_env_name: "CLUE_SERVICE_KEY",
|
|
374
391
|
producer_id_derivation: "producer_id defaults to service_key",
|
|
375
392
|
},
|
|
393
|
+
cli_invocation: CLUE_CLI_INVOCATION_CONTRACT,
|
|
376
394
|
clue_context: {
|
|
377
395
|
project_key: setupContext.project_key,
|
|
378
396
|
environment: setupContext.environment,
|
|
@@ -391,9 +409,11 @@ export const runSetupPrepare = async ({
|
|
|
391
409
|
: null,
|
|
392
410
|
},
|
|
393
411
|
lifecycle_verification: {
|
|
412
|
+
owner: "user",
|
|
413
|
+
ai_agent_must_run_setup_watch: false,
|
|
394
414
|
watch_target_format:
|
|
395
415
|
"frontend:<service-key>[init,identify,set-account,logout,event-sent]=<frontend-url>,backend:<service-key>[init,identify,set-account,logout,event-sent]=<backend-url>",
|
|
396
|
-
rule: "setup-watch --local uses the structured watch_targets below
|
|
416
|
+
rule: "setup-watch --local uses the structured watch_targets below, but it is user-operated verification. AI implementation agents must not run setup-watch automatically.",
|
|
397
417
|
watch_targets: buildWatchTargets(detection, candidate),
|
|
398
418
|
},
|
|
399
419
|
artifacts: {
|
|
@@ -403,12 +423,54 @@ export const runSetupPrepare = async ({
|
|
|
403
423
|
},
|
|
404
424
|
machine_owned_artifacts: [workflow.ci_workflow_path, setupManifestPath],
|
|
405
425
|
ai_must_not_edit: [workflow.ci_workflow_path],
|
|
406
|
-
ai_owned_workstreams: ["
|
|
426
|
+
ai_owned_workstreams: ["sdk_lifecycle_placement"],
|
|
427
|
+
ai_implementation_scope: {
|
|
428
|
+
rule: "AI implementation is limited to placing ClueInit, ClueIdentify, ClueSetAccount, and ClueLogout in existing lifecycle boundaries plus the minimal SDK wiring required for those calls.",
|
|
429
|
+
lifecycle_apis: [
|
|
430
|
+
"ClueInit",
|
|
431
|
+
"ClueIdentify",
|
|
432
|
+
"ClueSetAccount",
|
|
433
|
+
"ClueLogout",
|
|
434
|
+
],
|
|
435
|
+
out_of_scope_by_default: ["ClueTrack"],
|
|
436
|
+
},
|
|
407
437
|
required_final_check: {
|
|
408
|
-
command:
|
|
409
|
-
`
|
|
410
|
-
|
|
438
|
+
command: clueCliCommand(
|
|
439
|
+
`setup-check --framework ${candidate.framework} ` +
|
|
440
|
+
`--backend-root-path ${candidate.backend_root_path} --repo . --target ${target} --require-sdk-lifecycle`,
|
|
441
|
+
),
|
|
411
442
|
},
|
|
443
|
+
required_final_verification: [
|
|
444
|
+
{
|
|
445
|
+
id: "static_setup_check",
|
|
446
|
+
command: clueCliCommand(
|
|
447
|
+
`setup-check --framework ${candidate.framework} ` +
|
|
448
|
+
`--backend-root-path ${candidate.backend_root_path} --repo . --target ${target} --require-sdk-lifecycle`,
|
|
449
|
+
),
|
|
450
|
+
completion_meaning:
|
|
451
|
+
"static_passed_only_dependency_install_import_app_startup_and_event_delivery_still_required",
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
id: "sdk_dependency_install_and_import",
|
|
455
|
+
command:
|
|
456
|
+
"run the repository package-manager install plus frontend/backend SDK import checks in the target environments",
|
|
457
|
+
completion_meaning:
|
|
458
|
+
"required before claiming SDK lifecycle setup is complete",
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
id: "app_startup",
|
|
462
|
+
command:
|
|
463
|
+
"start the affected frontend/backend services and verify their configured local URLs respond",
|
|
464
|
+
completion_meaning:
|
|
465
|
+
"required before setup-watch local completion can be trusted",
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
id: "local_event_delivery",
|
|
469
|
+
command: `user runs ${clueCliCommand("setup-watch --local")}`,
|
|
470
|
+
completion_meaning:
|
|
471
|
+
"requires user-operated local services plus expected lifecycle event delivery; AI agents must report user_verification_pending when user evidence is not provided",
|
|
472
|
+
},
|
|
473
|
+
],
|
|
412
474
|
required_env_names: [
|
|
413
475
|
"CLUE_SERVICE_KEY",
|
|
414
476
|
"CLUE_API_KEY",
|
|
@@ -450,7 +512,8 @@ export const runSetupPrepare = async ({
|
|
|
450
512
|
...manifestWithEnvironmentArtifact.artifacts,
|
|
451
513
|
environment_file_path: environmentFilePath,
|
|
452
514
|
},
|
|
453
|
-
environment_instructions:
|
|
454
|
-
|
|
515
|
+
environment_instructions: summarizeEnvironmentInstructions(
|
|
516
|
+
environmentInstructions,
|
|
517
|
+
),
|
|
455
518
|
};
|
|
456
519
|
};
|