@cleocode/contracts 2026.9.23 → 2026.9.25
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/branch-lock.d.ts +51 -0
- package/dist/branch-lock.d.ts.map +1 -1
- package/dist/branch-lock.js +25 -3
- package/dist/branch-lock.js.map +1 -1
- package/dist/cloud/api.d.ts +1 -1
- package/dist/data-accessor.d.ts +270 -16
- package/dist/data-accessor.d.ts.map +1 -1
- package/dist/data-accessor.js.map +1 -1
- package/dist/decide.d.ts +110 -1
- package/dist/decide.d.ts.map +1 -1
- package/dist/decide.js +23 -0
- package/dist/decide.js.map +1 -1
- package/dist/dispatch/operations-registry.d.ts.map +1 -1
- package/dist/dispatch/operations-registry.js +137 -6
- package/dist/dispatch/operations-registry.js.map +1 -1
- package/dist/doctor.d.ts +9 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/exit-codes.d.ts +7 -0
- package/dist/exit-codes.d.ts.map +1 -1
- package/dist/exit-codes.js +7 -0
- package/dist/exit-codes.js.map +1 -1
- package/dist/index.d.ts +10 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/knowledge-health.d.ts +21 -0
- package/dist/knowledge-health.d.ts.map +1 -1
- package/dist/nexus-account.d.ts +160 -0
- package/dist/nexus-account.d.ts.map +1 -0
- package/dist/nexus-account.js +68 -0
- package/dist/nexus-account.js.map +1 -0
- package/dist/operations/focus.d.ts +7 -3
- package/dist/operations/focus.d.ts.map +1 -1
- package/dist/operations/nexus-scope-map.d.ts +8 -0
- package/dist/operations/nexus-scope-map.d.ts.map +1 -1
- package/dist/operations/nexus-scope-map.js +8 -0
- package/dist/operations/nexus-scope-map.js.map +1 -1
- package/dist/operations/nexus.d.ts +265 -0
- package/dist/operations/nexus.d.ts.map +1 -1
- package/dist/operations/nexus.js +9 -1
- package/dist/operations/nexus.js.map +1 -1
- package/dist/operations/orchestrate.d.ts +6 -1
- package/dist/operations/orchestrate.d.ts.map +1 -1
- package/dist/operations/output-contracts-data.d.ts.map +1 -1
- package/dist/operations/output-contracts-data.js +115 -1
- package/dist/operations/output-contracts-data.js.map +1 -1
- package/dist/operations/tasks.d.ts +73 -9
- package/dist/operations/tasks.d.ts.map +1 -1
- package/dist/operations/tasks.js.map +1 -1
- package/dist/project-lifecycle.d.ts +6 -2
- package/dist/project-lifecycle.d.ts.map +1 -1
- package/dist/row-identity.d.ts +128 -0
- package/dist/row-identity.d.ts.map +1 -0
- package/dist/row-identity.js +20 -0
- package/dist/row-identity.js.map +1 -0
- package/dist/session.d.ts +19 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +9 -2
- package/dist/session.js.map +1 -1
- package/dist/task.d.ts +56 -2
- package/dist/task.d.ts.map +1 -1
- package/dist/tools/score-task-priority.d.ts +1 -1
- package/dist/tools/score-task-priority.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/__snapshots__/operations-registry.test.ts.snap +1 -1
- package/src/branch-lock.ts +80 -3
- package/src/data-accessor.ts +283 -17
- package/src/decide.ts +127 -1
- package/src/dispatch/operations-registry.ts +144 -6
- package/src/doctor.ts +9 -0
- package/src/exit-codes.ts +7 -0
- package/src/index.ts +56 -0
- package/src/knowledge-health.ts +22 -0
- package/src/nexus-account.ts +181 -0
- package/src/operations/focus.ts +7 -3
- package/src/operations/nexus-scope-map.ts +9 -0
- package/src/operations/nexus.ts +281 -0
- package/src/operations/orchestrate.ts +6 -2
- package/src/operations/output-contracts-data.ts +125 -1
- package/src/operations/tasks.ts +78 -12
- package/src/project-lifecycle.ts +6 -2
- package/src/row-identity.ts +132 -0
- package/src/session.ts +20 -2
- package/src/task.ts +58 -2
- package/src/tools/score-task-priority.ts +1 -1
|
@@ -3072,6 +3072,14 @@ export const OPERATIONS: OperationDef[] = [
|
|
|
3072
3072
|
description: 'taskId parameter',
|
|
3073
3073
|
cli: { positional: true },
|
|
3074
3074
|
},
|
|
3075
|
+
{
|
|
3076
|
+
name: 'expectedUpdatedAt',
|
|
3077
|
+
type: 'string',
|
|
3078
|
+
required: false,
|
|
3079
|
+
description:
|
|
3080
|
+
'Optimistic-concurrency guard: fail with E_CONFLICT unless the task updatedAt still equals this value',
|
|
3081
|
+
cli: { flag: 'if-match' },
|
|
3082
|
+
},
|
|
3075
3083
|
] satisfies ParamDef[],
|
|
3076
3084
|
},
|
|
3077
3085
|
{
|
|
@@ -3748,7 +3756,8 @@ export const OPERATIONS: OperationDef[] = [
|
|
|
3748
3756
|
gateway: 'mutate',
|
|
3749
3757
|
domain: 'tasks',
|
|
3750
3758
|
operation: 'start',
|
|
3751
|
-
description:
|
|
3759
|
+
description:
|
|
3760
|
+
"tasks.start (mutate) — start work and take the caller session's leased claim (E_TASK_CLAIMED when another session holds it)",
|
|
3752
3761
|
tier: 0,
|
|
3753
3762
|
idempotent: false,
|
|
3754
3763
|
sessionRequired: false,
|
|
@@ -3761,6 +3770,20 @@ export const OPERATIONS: OperationDef[] = [
|
|
|
3761
3770
|
description: 'taskId parameter',
|
|
3762
3771
|
cli: { positional: true },
|
|
3763
3772
|
},
|
|
3773
|
+
{
|
|
3774
|
+
name: 'takeOver',
|
|
3775
|
+
type: 'boolean',
|
|
3776
|
+
required: false,
|
|
3777
|
+
description: "Take over another session's EXPIRED claim lease (audited)",
|
|
3778
|
+
cli: { flag: 'take-over' },
|
|
3779
|
+
},
|
|
3780
|
+
{
|
|
3781
|
+
name: 'forceClaim',
|
|
3782
|
+
type: 'boolean',
|
|
3783
|
+
required: false,
|
|
3784
|
+
description: "Take over another session's LIVE claim lease (audited)",
|
|
3785
|
+
cli: { flag: 'force-claim' },
|
|
3786
|
+
},
|
|
3764
3787
|
] satisfies ParamDef[],
|
|
3765
3788
|
},
|
|
3766
3789
|
{
|
|
@@ -3869,11 +3892,12 @@ export const OPERATIONS: OperationDef[] = [
|
|
|
3869
3892
|
gateway: 'mutate',
|
|
3870
3893
|
domain: 'tasks',
|
|
3871
3894
|
operation: 'claim',
|
|
3872
|
-
description:
|
|
3895
|
+
description:
|
|
3896
|
+
"tasks.claim (mutate) — take, renew or override the caller session's leased claim on a task (never the human assignee)",
|
|
3873
3897
|
tier: 0,
|
|
3874
3898
|
idempotent: false,
|
|
3875
3899
|
sessionRequired: true,
|
|
3876
|
-
requiredParams: ['taskId'
|
|
3900
|
+
requiredParams: ['taskId'],
|
|
3877
3901
|
params: [
|
|
3878
3902
|
{
|
|
3879
3903
|
name: 'taskId',
|
|
@@ -3884,8 +3908,27 @@ export const OPERATIONS: OperationDef[] = [
|
|
|
3884
3908
|
{
|
|
3885
3909
|
name: 'agentId',
|
|
3886
3910
|
type: 'string',
|
|
3887
|
-
required:
|
|
3888
|
-
description:
|
|
3911
|
+
required: false,
|
|
3912
|
+
description:
|
|
3913
|
+
"Agent ID recorded with the lease (default: the session's agent / CLEO_AGENT_ID)",
|
|
3914
|
+
},
|
|
3915
|
+
{
|
|
3916
|
+
name: 'renew',
|
|
3917
|
+
type: 'boolean',
|
|
3918
|
+
required: false,
|
|
3919
|
+
description: "Renew the caller's own lease",
|
|
3920
|
+
},
|
|
3921
|
+
{
|
|
3922
|
+
name: 'takeOver',
|
|
3923
|
+
type: 'boolean',
|
|
3924
|
+
required: false,
|
|
3925
|
+
description: "Take over another session's EXPIRED lease (audited)",
|
|
3926
|
+
},
|
|
3927
|
+
{
|
|
3928
|
+
name: 'forceClaim',
|
|
3929
|
+
type: 'boolean',
|
|
3930
|
+
required: false,
|
|
3931
|
+
description: "Take over another session's LIVE lease (audited)",
|
|
3889
3932
|
},
|
|
3890
3933
|
],
|
|
3891
3934
|
},
|
|
@@ -3893,7 +3936,8 @@ export const OPERATIONS: OperationDef[] = [
|
|
|
3893
3936
|
gateway: 'mutate',
|
|
3894
3937
|
domain: 'tasks',
|
|
3895
3938
|
operation: 'unclaim',
|
|
3896
|
-
description:
|
|
3939
|
+
description:
|
|
3940
|
+
"tasks.unclaim (mutate) — release the caller session's claim lease (never the human assignee)",
|
|
3897
3941
|
tier: 0,
|
|
3898
3942
|
idempotent: false,
|
|
3899
3943
|
sessionRequired: true,
|
|
@@ -3905,6 +3949,12 @@ export const OPERATIONS: OperationDef[] = [
|
|
|
3905
3949
|
required: true,
|
|
3906
3950
|
description: 'Task ID to unclaim',
|
|
3907
3951
|
},
|
|
3952
|
+
{
|
|
3953
|
+
name: 'forceClaim',
|
|
3954
|
+
type: 'boolean',
|
|
3955
|
+
required: false,
|
|
3956
|
+
description: "Release another session's lease (audited)",
|
|
3957
|
+
},
|
|
3908
3958
|
],
|
|
3909
3959
|
},
|
|
3910
3960
|
{
|
|
@@ -4164,6 +4214,20 @@ export const OPERATIONS: OperationDef[] = [
|
|
|
4164
4214
|
description:
|
|
4165
4215
|
'When true (default), adds toTaskId as a dependency on fromTaskId so it cannot complete before the pivot resolves',
|
|
4166
4216
|
},
|
|
4217
|
+
{
|
|
4218
|
+
name: 'takeOver',
|
|
4219
|
+
type: 'boolean',
|
|
4220
|
+
required: false,
|
|
4221
|
+
description: "Take over another session's EXPIRED claim on toTaskId (audited)",
|
|
4222
|
+
cli: { flag: 'take-over' },
|
|
4223
|
+
},
|
|
4224
|
+
{
|
|
4225
|
+
name: 'forceClaim',
|
|
4226
|
+
type: 'boolean',
|
|
4227
|
+
required: false,
|
|
4228
|
+
description: "Take over another session's LIVE claim on toTaskId (audited)",
|
|
4229
|
+
cli: { flag: 'force-claim' },
|
|
4230
|
+
},
|
|
4167
4231
|
],
|
|
4168
4232
|
},
|
|
4169
4233
|
// parallel.start and parallel.end merged into orchestrate.parallel via action param (T5615)
|
|
@@ -6907,6 +6971,80 @@ export const OPERATIONS: OperationDef[] = [
|
|
|
6907
6971
|
params: [],
|
|
6908
6972
|
},
|
|
6909
6973
|
|
|
6974
|
+
{
|
|
6975
|
+
gateway: 'query' as const,
|
|
6976
|
+
domain: 'nexus',
|
|
6977
|
+
operation: 'projects.fleet',
|
|
6978
|
+
description:
|
|
6979
|
+
'nexus.projects.fleet (query) — fleet view: every project with its location on each device, last recorded git state (local, and remote as of the last fetch) and staleness; paged, counts first, read-only',
|
|
6980
|
+
tier: 1,
|
|
6981
|
+
idempotent: true,
|
|
6982
|
+
sessionRequired: false,
|
|
6983
|
+
requiredParams: [],
|
|
6984
|
+
params: [
|
|
6985
|
+
{
|
|
6986
|
+
name: 'device',
|
|
6987
|
+
type: 'string',
|
|
6988
|
+
required: false,
|
|
6989
|
+
description: 'Only locations on this device (device id, hostname, or current)',
|
|
6990
|
+
},
|
|
6991
|
+
{
|
|
6992
|
+
name: 'missing',
|
|
6993
|
+
type: 'boolean',
|
|
6994
|
+
required: false,
|
|
6995
|
+
description: 'Only projects with a missing location',
|
|
6996
|
+
},
|
|
6997
|
+
{
|
|
6998
|
+
name: 'dirty',
|
|
6999
|
+
type: 'boolean',
|
|
7000
|
+
required: false,
|
|
7001
|
+
description: 'Only projects with a dirty location',
|
|
7002
|
+
},
|
|
7003
|
+
{
|
|
7004
|
+
name: 'behind',
|
|
7005
|
+
type: 'boolean',
|
|
7006
|
+
required: false,
|
|
7007
|
+
description: 'Only projects with a location behind its upstream (as of the last fetch)',
|
|
7008
|
+
},
|
|
7009
|
+
{
|
|
7010
|
+
name: 'ahead',
|
|
7011
|
+
type: 'boolean',
|
|
7012
|
+
required: false,
|
|
7013
|
+
description: 'Only projects with a location ahead of its upstream (as of the last fetch)',
|
|
7014
|
+
},
|
|
7015
|
+
{
|
|
7016
|
+
name: 'stale',
|
|
7017
|
+
type: 'boolean',
|
|
7018
|
+
required: false,
|
|
7019
|
+
description: 'Only projects with a never-probed, old-probe or old-fetch location',
|
|
7020
|
+
},
|
|
7021
|
+
{
|
|
7022
|
+
name: 'errored',
|
|
7023
|
+
type: 'boolean',
|
|
7024
|
+
required: false,
|
|
7025
|
+
description: 'Only projects whose last probe recorded an error',
|
|
7026
|
+
},
|
|
7027
|
+
{
|
|
7028
|
+
name: 'staleAfterMs',
|
|
7029
|
+
type: 'number',
|
|
7030
|
+
required: false,
|
|
7031
|
+
description: 'Staleness window for probes, fetches and heartbeats (default 24h)',
|
|
7032
|
+
},
|
|
7033
|
+
{
|
|
7034
|
+
name: 'limit',
|
|
7035
|
+
type: 'number',
|
|
7036
|
+
required: false,
|
|
7037
|
+
description: 'Page size in projects (default 50, max 500; 0 = all)',
|
|
7038
|
+
},
|
|
7039
|
+
{
|
|
7040
|
+
name: 'offset',
|
|
7041
|
+
type: 'number',
|
|
7042
|
+
required: false,
|
|
7043
|
+
description: 'Projects skipped before the page',
|
|
7044
|
+
},
|
|
7045
|
+
],
|
|
7046
|
+
},
|
|
7047
|
+
|
|
6910
7048
|
{
|
|
6911
7049
|
gateway: 'mutate' as const,
|
|
6912
7050
|
domain: 'nexus',
|
package/src/doctor.ts
CHANGED
|
@@ -880,6 +880,15 @@ export interface DbSubstrateSurveyOptions {
|
|
|
880
880
|
* `false` → leave the corrupt DB in place; only report it.
|
|
881
881
|
*/
|
|
882
882
|
autoQuarantine?: boolean;
|
|
883
|
+
/**
|
|
884
|
+
* Directory the survey was invoked from (T12708). Quarantine moves a
|
|
885
|
+
* project's live store; from a linked worktree of that project it needs
|
|
886
|
+
* {@link DbSubstrateSurveyOptions.confirmOwnerStore}, and it never moves a
|
|
887
|
+
* store inside a worktree. Defaults to the process directory.
|
|
888
|
+
*/
|
|
889
|
+
cwd?: string;
|
|
890
|
+
/** Confirm quarantining the owning project's LIVE store from a worktree (T12708). */
|
|
891
|
+
confirmOwnerStore?: boolean;
|
|
883
892
|
}
|
|
884
893
|
|
|
885
894
|
/**
|
package/src/exit-codes.ts
CHANGED
|
@@ -75,6 +75,13 @@ export enum ExitCode {
|
|
|
75
75
|
SCOPE_CONFLICT = 32,
|
|
76
76
|
SCOPE_INVALID = 33,
|
|
77
77
|
TASK_NOT_IN_SCOPE = 34,
|
|
78
|
+
/**
|
|
79
|
+
* Another session holds the claim lease on the task (`cleo start`,
|
|
80
|
+
* `cleo claim`, spawn). LAFS code `E_TASK_CLAIMED`; the details
|
|
81
|
+
* (`TaskClaimedDetails`) name the holder session and agent, the lease
|
|
82
|
+
* expiry, and the explicit, audited override: `--take-over` for an expired
|
|
83
|
+
* lease, `--force-claim` for a live one. @task T12502
|
|
84
|
+
*/
|
|
78
85
|
TASK_CLAIMED = 35,
|
|
79
86
|
SESSION_REQUIRED = 36,
|
|
80
87
|
SESSION_CLOSE_BLOCKED = 37,
|
package/src/index.ts
CHANGED
|
@@ -362,6 +362,12 @@ export type {
|
|
|
362
362
|
QueryTasksResult,
|
|
363
363
|
TaskAuditLogQuery,
|
|
364
364
|
TaskAuditLogRow,
|
|
365
|
+
TaskClaimedDetails,
|
|
366
|
+
TaskClaimGuard,
|
|
367
|
+
TaskClaimMode,
|
|
368
|
+
TaskClaimRequest,
|
|
369
|
+
TaskConflictChange,
|
|
370
|
+
TaskConflictDetails,
|
|
365
371
|
TaskFieldUpdates,
|
|
366
372
|
TaskPopulation,
|
|
367
373
|
TaskQueryFilters,
|
|
@@ -808,6 +814,7 @@ export type {
|
|
|
808
814
|
KnowledgeEvidenceRef,
|
|
809
815
|
KnowledgeFileEvidence,
|
|
810
816
|
KnowledgeHealth,
|
|
817
|
+
KnowledgeHealthSummary,
|
|
811
818
|
KnowledgeRepairAction,
|
|
812
819
|
KnowledgeRepairClass,
|
|
813
820
|
KnowledgeRepairFinding,
|
|
@@ -1492,6 +1499,12 @@ export type {
|
|
|
1492
1499
|
NexusDiscoverHit,
|
|
1493
1500
|
NexusDiscoverParams,
|
|
1494
1501
|
NexusDiscoverResult,
|
|
1502
|
+
NexusFleetDevice,
|
|
1503
|
+
NexusFleetDeviceSummary,
|
|
1504
|
+
NexusFleetFlag,
|
|
1505
|
+
NexusFleetGitSummary,
|
|
1506
|
+
NexusFleetLocation,
|
|
1507
|
+
NexusFleetProject,
|
|
1495
1508
|
NexusFlowEntry,
|
|
1496
1509
|
NexusFlowsParams,
|
|
1497
1510
|
NexusFlowsResult,
|
|
@@ -1541,6 +1554,8 @@ export type {
|
|
|
1541
1554
|
NexusProjectsCleanRemoval,
|
|
1542
1555
|
NexusProjectsCleanResult,
|
|
1543
1556
|
NexusProjectsCleanUnreadable,
|
|
1557
|
+
NexusProjectsFleetParams,
|
|
1558
|
+
NexusProjectsFleetResult,
|
|
1544
1559
|
NexusProjectsListParams,
|
|
1545
1560
|
NexusProjectsListResult,
|
|
1546
1561
|
NexusProjectsRegisterParams,
|
|
@@ -1621,6 +1636,7 @@ export type {
|
|
|
1621
1636
|
NexusWhyResult,
|
|
1622
1637
|
NexusWikiParams,
|
|
1623
1638
|
} from './operations/nexus.js';
|
|
1639
|
+
export { NEXUS_FLEET_SCHEMA_VERSION } from './operations/nexus.js';
|
|
1624
1640
|
// === Nexus Scope Contracts (T9145 + T9146) ===
|
|
1625
1641
|
export type {
|
|
1626
1642
|
MetaWithNexusScope,
|
|
@@ -2270,6 +2286,14 @@ export type {
|
|
|
2270
2286
|
TaskRefPriority,
|
|
2271
2287
|
TaskSummary,
|
|
2272
2288
|
} from './results.js';
|
|
2289
|
+
// === Row Identity Types (T12341 — uid merge keys) ===
|
|
2290
|
+
export type {
|
|
2291
|
+
RowIdentityKind,
|
|
2292
|
+
RowIdentityRef,
|
|
2293
|
+
RowIdentitySpec,
|
|
2294
|
+
StoredRefUid,
|
|
2295
|
+
SymmetricEdge,
|
|
2296
|
+
} from './row-identity.js';
|
|
2273
2297
|
// === Scaffold + Diagnostic Result Types (SG-ARCH-SOLID T9831 / E-CONTRACTS-FOUNDATION T9832) ===
|
|
2274
2298
|
export type {
|
|
2275
2299
|
CheckResult,
|
|
@@ -2500,6 +2524,7 @@ export type {
|
|
|
2500
2524
|
SeverityAttestation,
|
|
2501
2525
|
SignedSeverityAttestation,
|
|
2502
2526
|
Task,
|
|
2527
|
+
TaskClaim,
|
|
2503
2528
|
TaskCreate,
|
|
2504
2529
|
// T944 new axes (T9072: renamed TaskRole → TaskKind)
|
|
2505
2530
|
TaskKind,
|
|
@@ -2890,6 +2915,12 @@ export {
|
|
|
2890
2915
|
export type {
|
|
2891
2916
|
ChoiceDecisionAnswer,
|
|
2892
2917
|
ChoiceDecisionQuestion,
|
|
2918
|
+
DecideProfileConnection,
|
|
2919
|
+
DecideProfileListResult,
|
|
2920
|
+
DecideProfileProbe,
|
|
2921
|
+
DecideProfileSummary,
|
|
2922
|
+
DecideProfileUrlSource,
|
|
2923
|
+
DecideProviderState,
|
|
2893
2924
|
DecisionAnswer,
|
|
2894
2925
|
DecisionBatchItem,
|
|
2895
2926
|
DecisionInstructions,
|
|
@@ -2912,6 +2943,9 @@ export type {
|
|
|
2912
2943
|
export {
|
|
2913
2944
|
choiceDecisionAnswerSchema,
|
|
2914
2945
|
choiceDecisionQuestionSchema,
|
|
2946
|
+
DECIDE_DEFAULT_PROFILE_NAME,
|
|
2947
|
+
DECIDE_PROFILE_DEFAULT_URL,
|
|
2948
|
+
DECIDE_PROFILE_NAME_PATTERN,
|
|
2915
2949
|
DECISION_OUTCOME_SOURCES,
|
|
2916
2950
|
DECISION_PROVIDER_KINDS,
|
|
2917
2951
|
DECISION_QUESTION_TYPES,
|
|
@@ -2926,6 +2960,7 @@ export {
|
|
|
2926
2960
|
decisionQuestionTypeSchema,
|
|
2927
2961
|
decisionRequestSchema,
|
|
2928
2962
|
decisionStateSchema,
|
|
2963
|
+
JEV_DEFAULT_BASE_URL,
|
|
2929
2964
|
JEV_MINIMUM_CAPABILITIES,
|
|
2930
2965
|
LAYAHOST_BASE_URL,
|
|
2931
2966
|
LAYAHOST_DEFAULT_MODEL,
|
|
@@ -2949,4 +2984,25 @@ export type {
|
|
|
2949
2984
|
} from './decide-sites.js';
|
|
2950
2985
|
export { DECISION_RUNGS, DECISION_SITE_MODES } from './decide-sites.js';
|
|
2951
2986
|
|
|
2987
|
+
export type {
|
|
2988
|
+
NexusAccountErrorCode,
|
|
2989
|
+
NexusAccountMe,
|
|
2990
|
+
NexusAccountOrganization,
|
|
2991
|
+
NexusAccountStatus,
|
|
2992
|
+
NexusAccountUser,
|
|
2993
|
+
NexusLoginResult,
|
|
2994
|
+
NexusLogoutResult,
|
|
2995
|
+
NexusProjectLink,
|
|
2996
|
+
NexusProjectLinkResult,
|
|
2997
|
+
NexusSessionState,
|
|
2998
|
+
} from './nexus-account.js';
|
|
2999
|
+
export {
|
|
3000
|
+
NEXUS_ACCOUNT_ERROR_CODES,
|
|
3001
|
+
NEXUS_CLI_CLIENT_ID,
|
|
3002
|
+
NEXUS_DEFAULT_API_URL,
|
|
3003
|
+
NEXUS_LOGIN_TARGET,
|
|
3004
|
+
nexusAccountMeSchema,
|
|
3005
|
+
nexusAccountOrganizationSchema,
|
|
3006
|
+
nexusAccountUserSchema,
|
|
3007
|
+
} from './nexus-account.js';
|
|
2952
3008
|
export { isStorableTaskId, isTaskId, TASK_ID_REGEX, type TaskId } from './task-id.js';
|
package/src/knowledge-health.ts
CHANGED
|
@@ -258,6 +258,28 @@ export interface KnowledgeHealth {
|
|
|
258
258
|
findings: KnowledgeRepairFinding[];
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Orientation summary of {@link KnowledgeHealth} for envelopes that already
|
|
263
|
+
* carry the coverage object at their top level (`briefing.show`'s
|
|
264
|
+
* `knowledgeCoverage`, `focus.show`'s `coverage`).
|
|
265
|
+
*
|
|
266
|
+
* The coverage object is emitted once per envelope; this summary points at it
|
|
267
|
+
* through {@link KnowledgeHealthSummary.coverageRef} instead of repeating it
|
|
268
|
+
* (T12522). Every other field keeps the {@link KnowledgeHealth} meaning. The
|
|
269
|
+
* full assessment, coverage included, remains available from
|
|
270
|
+
* `cleo doctor knowledge`.
|
|
271
|
+
*
|
|
272
|
+
* @task T12522
|
|
273
|
+
*/
|
|
274
|
+
export interface KnowledgeHealthSummary extends Omit<KnowledgeHealth, 'coverage'> {
|
|
275
|
+
/**
|
|
276
|
+
* JSON Pointer, relative to the envelope's `data`, of the coverage object
|
|
277
|
+
* this summary describes — e.g. `/knowledgeCoverage` (briefing) or
|
|
278
|
+
* `/coverage` (focus). Prefix `/data` for `cleo ... --field`.
|
|
279
|
+
*/
|
|
280
|
+
coverageRef: string;
|
|
281
|
+
}
|
|
282
|
+
|
|
261
283
|
/** Responsibility for resolving a knowledge defect. */
|
|
262
284
|
export type KnowledgeRepairClass = 'automatic' | 'agent-resolvable' | 'owner-decision';
|
|
263
285
|
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleo Nexus account contracts: the CLI's signed-in session with the Cleo
|
|
3
|
+
* Nexus API (device-code login, logout, status, project link).
|
|
4
|
+
*
|
|
5
|
+
* The API is a better-auth app: the device-code grant (RFC 8628) issues a
|
|
6
|
+
* session token that the bearer plugin accepts on every `/v1` route. These
|
|
7
|
+
* types describe what CLEO emits and persists about that session. None of
|
|
8
|
+
* them carries the token: results and status rows are secret-free by
|
|
9
|
+
* construction, so they are safe in LAFS envelopes and logs.
|
|
10
|
+
*
|
|
11
|
+
* Not part of `./cloud`: that directory mirrors the server's
|
|
12
|
+
* `@cleo-nexus/shared` contract one-to-one. The `/v1/account/me` subset
|
|
13
|
+
* below is read-only and client-side.
|
|
14
|
+
*
|
|
15
|
+
* This file is types + zod schemas + const data only (arch gate 10).
|
|
16
|
+
*
|
|
17
|
+
* @task T12712
|
|
18
|
+
* @epic T12322
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { z } from 'zod';
|
|
22
|
+
|
|
23
|
+
/** Production Cleo Nexus API origin. */
|
|
24
|
+
export const NEXUS_DEFAULT_API_URL = 'https://api.cleocode.dev';
|
|
25
|
+
|
|
26
|
+
/** The OAuth client id the Nexus API accepts for the device-code grant. */
|
|
27
|
+
export const NEXUS_CLI_CLIENT_ID = 'cleo-cli';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The reserved `cleo login` target for a Cleo Nexus account. It is checked
|
|
31
|
+
* before the LLM provider registry, so no provider can shadow it.
|
|
32
|
+
*/
|
|
33
|
+
export const NEXUS_LOGIN_TARGET = 'nexus';
|
|
34
|
+
|
|
35
|
+
/** Stable error codes of the Nexus account flows. */
|
|
36
|
+
export const NEXUS_ACCOUNT_ERROR_CODES = [
|
|
37
|
+
'E_NEXUS_INVALID_API_URL',
|
|
38
|
+
'E_NEXUS_NOT_SIGNED_IN',
|
|
39
|
+
'E_NEXUS_SESSION_EXPIRED',
|
|
40
|
+
'E_NEXUS_DEVICE_CODE_START_FAILED',
|
|
41
|
+
'E_NEXUS_UNTRUSTED_VERIFICATION_URI',
|
|
42
|
+
'E_NEXUS_DEVICE_CODE_EXPIRED',
|
|
43
|
+
'E_NEXUS_ACCESS_DENIED',
|
|
44
|
+
'E_NEXUS_DEVICE_CODE_FAILED',
|
|
45
|
+
'E_NEXUS_REVOKE_FAILED',
|
|
46
|
+
'E_NEXUS_REQUEST_FAILED',
|
|
47
|
+
'E_NEXUS_NOT_A_PROJECT',
|
|
48
|
+
'E_NEXUS_INVALID_LABEL',
|
|
49
|
+
] as const;
|
|
50
|
+
|
|
51
|
+
/** One of {@link NEXUS_ACCOUNT_ERROR_CODES}. */
|
|
52
|
+
export type NexusAccountErrorCode = (typeof NEXUS_ACCOUNT_ERROR_CODES)[number];
|
|
53
|
+
|
|
54
|
+
/** The signed-in user, as `/v1/account/me` reports it. */
|
|
55
|
+
export const nexusAccountUserSchema = z.object({
|
|
56
|
+
id: z.string(),
|
|
57
|
+
email: z.string(),
|
|
58
|
+
name: z.string().nullable().optional(),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
/** A user's organization membership, as `/v1/account/me` reports it. */
|
|
62
|
+
export const nexusAccountOrganizationSchema = z.object({
|
|
63
|
+
id: z.string(),
|
|
64
|
+
name: z.string(),
|
|
65
|
+
slug: z.string().nullable().optional(),
|
|
66
|
+
role: z.string().optional(),
|
|
67
|
+
/** `true` for the personal organization created at sign-up. */
|
|
68
|
+
personal: z.boolean().optional(),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The subset of `GET /v1/account/me` the CLI reads. Unknown fields are
|
|
73
|
+
* ignored (zod strips them), so the server can grow the payload freely.
|
|
74
|
+
*/
|
|
75
|
+
export const nexusAccountMeSchema = z.object({
|
|
76
|
+
user: nexusAccountUserSchema,
|
|
77
|
+
organizations: z.array(nexusAccountOrganizationSchema).default([]),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
/** Parsed `GET /v1/account/me` subset. */
|
|
81
|
+
export type NexusAccountMe = z.infer<typeof nexusAccountMeSchema>;
|
|
82
|
+
|
|
83
|
+
/** A signed-in user (no secrets). */
|
|
84
|
+
export type NexusAccountUser = z.infer<typeof nexusAccountUserSchema>;
|
|
85
|
+
|
|
86
|
+
/** An organization reference (no secrets). */
|
|
87
|
+
export type NexusAccountOrganization = z.infer<typeof nexusAccountOrganizationSchema>;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Session state for one API origin.
|
|
91
|
+
*
|
|
92
|
+
* - `signed-in` — a token is stored and, when checked live, the API accepted it.
|
|
93
|
+
* - `unverified` — a token is stored but the API could not be reached.
|
|
94
|
+
* - `expired` — the API answered 401: the session expired or was revoked.
|
|
95
|
+
* - `not-signed-in` — no token is stored for the origin.
|
|
96
|
+
*/
|
|
97
|
+
export type NexusSessionState = 'signed-in' | 'unverified' | 'expired' | 'not-signed-in';
|
|
98
|
+
|
|
99
|
+
/** Secret-free status row for `cleo status` and `cleo auth list`. */
|
|
100
|
+
export interface NexusAccountStatus {
|
|
101
|
+
/** API origin the row describes, e.g. `https://api.cleocode.dev`. */
|
|
102
|
+
apiUrl: string;
|
|
103
|
+
/** Session state. */
|
|
104
|
+
state: NexusSessionState;
|
|
105
|
+
/** Signed-in user's email, when known. */
|
|
106
|
+
email: string | null;
|
|
107
|
+
/** Primary organization (the personal one, else the first), when known. */
|
|
108
|
+
organization: string | null;
|
|
109
|
+
/** ISO time the stored token expires, when the server said so. */
|
|
110
|
+
expiresAt: string | null;
|
|
111
|
+
/** One human line: "signed in as a@b.c (Org)", "session expired", "not signed in". */
|
|
112
|
+
summary: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Result of `cleo login nexus` (never carries the token). */
|
|
116
|
+
export interface NexusLoginResult {
|
|
117
|
+
/** API origin the session belongs to. */
|
|
118
|
+
apiUrl: string;
|
|
119
|
+
/** The signed-in user, when `/v1/account/me` answered. */
|
|
120
|
+
user: NexusAccountUser | null;
|
|
121
|
+
/** Primary organization, when known. */
|
|
122
|
+
organization: NexusAccountOrganization | null;
|
|
123
|
+
/** ISO time the token expires, when the server said so. */
|
|
124
|
+
expiresAt: string | null;
|
|
125
|
+
/** Absolute path of the credential store the token was written to. */
|
|
126
|
+
credentialsPath: string;
|
|
127
|
+
/** Non-fatal problems, e.g. the account lookup failed after a good login. */
|
|
128
|
+
warnings: string[];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Result of `cleo logout nexus`. */
|
|
132
|
+
export interface NexusLogoutResult {
|
|
133
|
+
/** API origin the session belonged to. */
|
|
134
|
+
apiUrl: string;
|
|
135
|
+
/** `true` when a stored token existed and was deleted locally. */
|
|
136
|
+
removedLocally: boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Server-side revocation outcome: `revoked` (the API ended the session),
|
|
139
|
+
* `already-invalid` (the API reported it was already gone), `failed`
|
|
140
|
+
* (network or server error: the local token is deleted anyway), or
|
|
141
|
+
* `skipped` (nothing was stored).
|
|
142
|
+
*/
|
|
143
|
+
revocation: 'revoked' | 'already-invalid' | 'failed' | 'skipped';
|
|
144
|
+
/** Non-fatal problems. */
|
|
145
|
+
warnings: string[];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The binding of a local CLEO project to its Nexus registration, persisted in
|
|
150
|
+
* the project's machine-local `.cleo/nexus-link.json`, keyed by API origin.
|
|
151
|
+
*/
|
|
152
|
+
export interface NexusProjectLink {
|
|
153
|
+
/** API origin the project is registered with. */
|
|
154
|
+
apiUrl: string;
|
|
155
|
+
/** The local CLEO project id (the tracked `.cleo/project-id`). */
|
|
156
|
+
localProjectId: string;
|
|
157
|
+
/** The project id the server returned (the server keys projects by the CLEO id). */
|
|
158
|
+
remoteProjectId: string;
|
|
159
|
+
/** Owning organization id. */
|
|
160
|
+
organizationId: string;
|
|
161
|
+
/** Plaintext display-name label the server holds, or `null` when it has none. */
|
|
162
|
+
label: string | null;
|
|
163
|
+
/** Journal stream id for the project. */
|
|
164
|
+
streamId: string;
|
|
165
|
+
/** ISO time of the last successful link. */
|
|
166
|
+
linkedAt: string;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** Result of `cleo project link`. */
|
|
170
|
+
export interface NexusProjectLinkResult {
|
|
171
|
+
/** The persisted binding. */
|
|
172
|
+
link: NexusProjectLink;
|
|
173
|
+
/**
|
|
174
|
+
* `true` when the server already had this project id (HTTP 200; its label
|
|
175
|
+
* was updated to the one sent), `false` when this call registered it (201).
|
|
176
|
+
* Linking is idempotent either way.
|
|
177
|
+
*/
|
|
178
|
+
alreadyLinked: boolean;
|
|
179
|
+
/** Absolute path of the local binding file. */
|
|
180
|
+
linkPath: string;
|
|
181
|
+
}
|
package/src/operations/focus.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import type {
|
|
16
16
|
KnowledgeCoverage,
|
|
17
17
|
KnowledgeDiagnostic,
|
|
18
|
-
|
|
18
|
+
KnowledgeHealthSummary,
|
|
19
19
|
} from '../knowledge-health.js';
|
|
20
20
|
import type { MviDigest } from '../mvi.js';
|
|
21
21
|
import type { AttentionScopeKind } from './attention.js';
|
|
@@ -195,8 +195,12 @@ export interface FocusBrainContext {
|
|
|
195
195
|
export interface FocusShowResult {
|
|
196
196
|
/** Assessed graph coverage; absence on legacy responses is not healthy coverage. */
|
|
197
197
|
coverage?: KnowledgeCoverage;
|
|
198
|
-
/**
|
|
199
|
-
|
|
198
|
+
/**
|
|
199
|
+
* Bounded deterministic maintenance and sourced repair findings for the
|
|
200
|
+
* foreground caller. Its coverage is not repeated: `coverageRef` is
|
|
201
|
+
* `/coverage`, the single coverage object of this result (T12522).
|
|
202
|
+
*/
|
|
203
|
+
knowledgeHealth?: KnowledgeHealthSummary;
|
|
200
204
|
/** Failed auxiliary reads are distinct from successfully empty sources. */
|
|
201
205
|
sourceDiagnostics?: Record<string, KnowledgeDiagnostic>;
|
|
202
206
|
/** Core identity of the focused entity. */
|
|
@@ -473,6 +473,15 @@ export const NEXUS_SCOPE_MAP = {
|
|
|
473
473
|
stores: ['nexus-registry'],
|
|
474
474
|
requiresProject: false,
|
|
475
475
|
},
|
|
476
|
+
'projects.fleet': {
|
|
477
|
+
op: 'projects.fleet',
|
|
478
|
+
description:
|
|
479
|
+
'Fleet view: every project, where it lives on each device, and its last recorded git state (read-only).',
|
|
480
|
+
scope: 'global',
|
|
481
|
+
effect: 'read',
|
|
482
|
+
stores: ['nexus-registry'],
|
|
483
|
+
requiresProject: false,
|
|
484
|
+
},
|
|
476
485
|
'projects.register': {
|
|
477
486
|
op: 'projects.register',
|
|
478
487
|
description: 'Register a project (alias: register).',
|