@basou/core 0.38.0 → 0.40.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 +117 -16
- package/dist/index.js +175 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/schemas/manifest.schema.json +20 -0
package/dist/index.d.ts
CHANGED
|
@@ -107,21 +107,12 @@ declare function removeStopHook(settings: unknown): StopHookRemoval;
|
|
|
107
107
|
declare function findBasouStopHookCommand(settings: unknown): string | null;
|
|
108
108
|
|
|
109
109
|
/**
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
* Every object here is `looseObject` (NOT the default strip), so unknown keys
|
|
117
|
-
* at every level survive parse. The manifest is the declarative source of truth
|
|
118
|
-
* and is git-tracked and read-modify-written by `basou project` commands; with
|
|
119
|
-
* the default strip, a field this basou does not recognize — a newer version's
|
|
120
|
-
* additive field, a future adapter under `adapters`, a hand-added key — would be
|
|
121
|
-
* silently dropped on the next write. Preserving them keeps basou from destroying
|
|
122
|
-
* config it does not understand (forward-compatible), while known fields are still
|
|
123
|
-
* fully type-checked and validated. {@link unknownManifestKeys} surfaces the
|
|
124
|
-
* unrecognized top-level keys so preservation is not silent.
|
|
110
|
+
* The manifest, plus one guard the loose object cannot express: a TOP-LEVEL
|
|
111
|
+
* `confidential` is refused. It belongs under `policies`, and because the
|
|
112
|
+
* object is loose, a stray top-level spelling would otherwise parse fine and be
|
|
113
|
+
* silently ignored — an operator would believe the workspace is protected while
|
|
114
|
+
* the face is still written. A safety key that is not honoured must fail
|
|
115
|
+
* loudly, not quietly.
|
|
125
116
|
*/
|
|
126
117
|
declare const ManifestSchema: z.ZodObject<{
|
|
127
118
|
schema_version: z.ZodString;
|
|
@@ -197,6 +188,12 @@ declare const ManifestSchema: z.ZodObject<{
|
|
|
197
188
|
self: "self";
|
|
198
189
|
}>>;
|
|
199
190
|
}, z.core.$loose>>>;
|
|
191
|
+
channels: z.ZodOptional<z.ZodObject<{
|
|
192
|
+
codex: z.ZodOptional<z.ZodBoolean>;
|
|
193
|
+
}, z.core.$loose>>;
|
|
194
|
+
policies: z.ZodOptional<z.ZodObject<{
|
|
195
|
+
confidential: z.ZodOptional<z.ZodBoolean>;
|
|
196
|
+
}, z.core.$loose>>;
|
|
200
197
|
}, z.core.$loose>;
|
|
201
198
|
/** Inferred runtime type for {@link ManifestSchema}. */
|
|
202
199
|
type Manifest = z.infer<typeof ManifestSchema>;
|
|
@@ -821,6 +818,110 @@ declare function resolveCodexCommand(lookup?: CommandLookup): Promise<{
|
|
|
821
818
|
command: string;
|
|
822
819
|
}>;
|
|
823
820
|
|
|
821
|
+
/**
|
|
822
|
+
* Pure transforms for registering / removing basou's SessionStart hook inside a
|
|
823
|
+
* parsed Codex `hooks.json` object. No disk or environment access: the CLI reads
|
|
824
|
+
* and writes the file, parses the JSON, and passes the object here so the
|
|
825
|
+
* merge/removal logic stays deterministic and unit-testable. The Codex twin of
|
|
826
|
+
* the Claude Code `settings-hook` transforms.
|
|
827
|
+
*
|
|
828
|
+
* Why a hook, and why this shape: `~/.codex/hooks.json` is user-global, but a
|
|
829
|
+
* hook stores nothing — Codex runs it when a session starts and passes the
|
|
830
|
+
* session's own `cwd` on stdin, and whatever the hook prints on stdout becomes
|
|
831
|
+
* developer context for THAT session only. basou resolves the workspace from
|
|
832
|
+
* that `cwd` and prints that workspace's position. So one installed hook serves
|
|
833
|
+
* every workspace on the machine while no workspace's position is ever written
|
|
834
|
+
* where another workspace's session reads it — the property the retired
|
|
835
|
+
* `~/.codex/AGENTS.md` orientation render could not have.
|
|
836
|
+
*
|
|
837
|
+
* `hooks.json` holds other events and other people's hooks; these functions
|
|
838
|
+
* clone the input and touch ONLY the `hooks.SessionStart` handler that basou
|
|
839
|
+
* owns, preserving everything else byte-for-byte through the round-trip.
|
|
840
|
+
*/
|
|
841
|
+
/**
|
|
842
|
+
* Seconds before Codex kills the hook. `basou orient` reads the store and
|
|
843
|
+
* probes the native logs for staleness; on a large store that is seconds, not
|
|
844
|
+
* minutes. Codex's own default is 600 — far too long for a session-start
|
|
845
|
+
* handler whose failure mode is "the session waits".
|
|
846
|
+
*/
|
|
847
|
+
declare const SESSION_START_HOOK_TIMEOUT_SECONDS = 30;
|
|
848
|
+
/**
|
|
849
|
+
* Which SessionStart sources fire the hook. Codex applies the matcher to the
|
|
850
|
+
* payload's `source`: `startup` (a new session), `resume`, `clear` (context
|
|
851
|
+
* reset). `compact` is left out: the position is already in the context being
|
|
852
|
+
* compacted, and re-injecting ~10 KB after every compaction would crowd the
|
|
853
|
+
* budget the compaction just freed.
|
|
854
|
+
*/
|
|
855
|
+
declare const SESSION_START_HOOK_MATCHER = "startup|resume|clear";
|
|
856
|
+
/**
|
|
857
|
+
* Codex caps each hook's model-visible output at roughly 2,500 tokens by default
|
|
858
|
+
* and spills the rest to a temp file, handing the model a head-and-tail preview
|
|
859
|
+
* plus the path. A position is ~10 KB and is useless truncated — the open
|
|
860
|
+
* tracks and the next step sit at the end — so the cap is disabled for this
|
|
861
|
+
* handler (`0` passes the complete output).
|
|
862
|
+
*/
|
|
863
|
+
declare const SESSION_START_HOOK_CONTEXT_LIMIT = 0;
|
|
864
|
+
/** Shown in the Codex UI while the hook runs. */
|
|
865
|
+
declare const SESSION_START_HOOK_STATUS_MESSAGE = "basou orient";
|
|
866
|
+
declare function isBasouSessionStartHookCommand(command: string): boolean;
|
|
867
|
+
/**
|
|
868
|
+
* Build the shell command basou registers as a Codex SessionStart hook. Uses
|
|
869
|
+
* the node path (the `basou` alias is often absent from a hook's PATH) and a
|
|
870
|
+
* `2>/dev/null || true` wrapper so a stale dist path or any crash fails open —
|
|
871
|
+
* a session start must never be blocked by its orientation. The handler itself
|
|
872
|
+
* is also fail-open, so the wrapper is belt-and-braces. The entry path is
|
|
873
|
+
* shell-quoted for directories containing spaces or metacharacters.
|
|
874
|
+
*/
|
|
875
|
+
declare function buildSessionStartHookCommand(options: {
|
|
876
|
+
cliEntry: string;
|
|
877
|
+
}): string;
|
|
878
|
+
type CodexHooksFile = Record<string, unknown>;
|
|
879
|
+
type SessionStartHookUpsert = {
|
|
880
|
+
hooksFile: CodexHooksFile;
|
|
881
|
+
/** `installed` = a new entry was appended; `updated` = an existing basou entry was rewritten; `unchanged` = already canonical. */
|
|
882
|
+
action: "installed" | "updated" | "unchanged";
|
|
883
|
+
};
|
|
884
|
+
type SessionStartHookRemoval = {
|
|
885
|
+
hooksFile: CodexHooksFile;
|
|
886
|
+
action: "removed" | "absent";
|
|
887
|
+
};
|
|
888
|
+
/**
|
|
889
|
+
* Where basou's handler sits in the file. Codex records trust per handler under
|
|
890
|
+
* `[hooks.state."<hooks.json path>:session_start:<group>:<handler>"]` in
|
|
891
|
+
* `config.toml`, so the two indexes are what `hook status codex` needs to look
|
|
892
|
+
* the trust entry up.
|
|
893
|
+
*/
|
|
894
|
+
type SessionStartHookLocation = {
|
|
895
|
+
command: string;
|
|
896
|
+
groupIndex: number;
|
|
897
|
+
handlerIndex: number;
|
|
898
|
+
/** The matcher of the group the handler sits in (undefined = fires on every source). */
|
|
899
|
+
matcher: string | undefined;
|
|
900
|
+
/**
|
|
901
|
+
* The handler object exactly as installed. Codex hashes the installed fields
|
|
902
|
+
* (not basou's canonical ones) when it decides whether the hook is trusted, so
|
|
903
|
+
* a status check must hash what is in the file.
|
|
904
|
+
*/
|
|
905
|
+
handler: Record<string, unknown>;
|
|
906
|
+
};
|
|
907
|
+
/**
|
|
908
|
+
* Register (or upgrade in place) basou's SessionStart hook. Idempotent: an
|
|
909
|
+
* existing basou handler is rewritten to the canonical fields; a foreign
|
|
910
|
+
* handler, another event, or any other key is left untouched. A new install
|
|
911
|
+
* appends its own matcher group so it never widens or narrows someone else's
|
|
912
|
+
* matcher.
|
|
913
|
+
*/
|
|
914
|
+
declare function upsertSessionStartHook(hooksFile: unknown, command: string): SessionStartHookUpsert;
|
|
915
|
+
/**
|
|
916
|
+
* Remove every basou-owned SessionStart handler. A group emptied by the removal
|
|
917
|
+
* is dropped; a now-empty `hooks.SessionStart` / `hooks` container is deleted so
|
|
918
|
+
* the file does not accumulate empty scaffolding. Foreign handlers and other
|
|
919
|
+
* keys are preserved.
|
|
920
|
+
*/
|
|
921
|
+
declare function removeSessionStartHook(hooksFile: unknown): SessionStartHookRemoval;
|
|
922
|
+
/** Locate the installed basou SessionStart handler, or null if none is registered. */
|
|
923
|
+
declare function findBasouSessionStartHook(hooksFile: unknown): SessionStartHookLocation | null;
|
|
924
|
+
|
|
824
925
|
/**
|
|
825
926
|
* The `source` string stamped on every event derived from an OpenAI Codex
|
|
826
927
|
* native rollout log, and the matching session `source.kind`.
|
|
@@ -6880,4 +6981,4 @@ declare function overwriteYamlFile(filePath: string, value: unknown): Promise<vo
|
|
|
6880
6981
|
*/
|
|
6881
6982
|
declare const BASOU_CORE_VERSION = "0.1.0";
|
|
6882
6983
|
|
|
6883
|
-
export { ACTIVE_GAP_CAP_MS, AGENT_INFRA_DIRS, type ActiveTimeBasis, type AdapterOutputEvent, type AdoptCandidate, type AdoptCandidateKind, type AnchorStarterInput, type AnchorStarterRepo, type AppendBasouGitignoreOptions, type AppendBasouGitignoreResult, type AppendEventToExistingInput, type AppendEventToExistingResult, type Approval, type ApprovalApprovedEvent, type ApprovalExpiredEvent, ApprovalIdSchema, type ApprovalLocation, type ApprovalRejectedEvent, type ApprovalRequestedEvent, ApprovalSchema, type ApprovalStatus, ApprovalStatusSchema, type ArchivePlan, type ArchiveTaskInput, type ArchiveTaskResult, type AttachTaskInput, type AttachUpdateTaskStatusInput, type AttachableStatus, BASOU_CORE_VERSION, type BasouPaths, type BuildStopHookCommandOptions, type BulkChainResult, CLAUDE_IMPORT_SOURCE, CODEX_IMPORT_SOURCE, type CaptureMode, type ChainBreakReason, type ChainTailState, type ChainVerdict, type ChainVerdictStatus, type ChainedEvents, ChildProcessRunner, type CitedReview, type ClaudeSettings, type ClaudeTranscriptRecord, type ClaudeTranscriptToPayloadOptions, type CodexCommandLookup, type CodexRolloutRecord, type CodexRolloutToPayloadOptions, type CommandExecutedEvent, type CommandLookup, type CreateAdHocSessionInput, type CreateAdHocSessionResult, type CreateAdHocTaskInput, type CreateManifestInput, type CreateTaskInput, type CreateTaskResult, DEFAULT_STOP_HOOK_MIN_EDITS, type DayWorkStats, DecisionIdSchema, type DecisionRecordedEvent, type DecisionsRendererInput, type DecisionsRendererResult, type DeleteTaskInput, type DeleteTaskResult, type DiffResult, type EditTaskInput, type EditTaskResult, type Event, EventIdSchema, EventSchema, EventSourceSchema, type ExistingViewLink, FailedToFinalizeError, type FederatedRoot, type FileChange, type FileChangeStatus, type FileChangedEvent, GENERATED_END, GENERATED_START, type GitSnapshot, type GitSnapshotEvent, type GitignorePlanSummary, type HandoffRendererInput, type HandoffRendererResult, ID_PREFIXES, type IdPrefix, type ImportSessionOptions, type ImportSessionResult, type IncompleteWiring, type InstructionFileFact, type InstructionSymlinkFact, type InstructionSymlinkState, IsoTimestampSchema, JSON_SCHEMA_VERSION, type JsonSchemaArtifact, type LoadFederatedOptions, type LoadSessionEntriesOptions, type LoadTaskEntriesOptions, type LoadedApproval, type LockHandle, type LockScope, type Manifest, ManifestSchema, type MarkerSection, type Markers, type MeasureAvailability, type MissingCanonical, type NoteAddedEvent, ORIENTATION_END, ORIENTATION_START, type OrientationRendererInput, type OrientationRendererResult, type OrientationSummary, PROTOCOL_END, PROTOCOL_START, type PrefixedId, type PresetAction, type PresetCollision, type PresetMarkerConflict, type PresetMarkerKind, type PresetPlanSummary, type PresetRepo, type PresetStrings, type ProcessRunner, type PublishKind, type PublishTarget, REVIEW_RECORD_NO_INPUT_HINT, type RechainOptions, type RechainResult, type ReconcileAllResult, type ReconcileAllTasksInput, type ReconcileAllTasksOptions, type ReconcileFailure, type ReconcileResult, type ReconcileTaskInput, type RefreshLinkageInput, type RefreshLinkageResult, type ReimportOptions, type ReimportResult, type RenamePlan, type ReplayOptions, type ReplayWarning, type RepoEntry, type RepoGitignoreFacts, type RepoGitignorePlan, type RepoInstructions, type RepoLanguage, type RepoPathProblem, type RepoPresetFacts, type RepoPresetPlan, type RepoSymlinkFacts, type RepoSymlinkPlan, type RepoVisibility, type RepoWiringFacts, type ReportApprovalItem, type ReportData, type ReportDecisionItem, type ReportRendererInput, type ReportRendererResult, type ReportSessionItem, type ReportTaskItem, type RetrofitAction, type RetrofitAgentsState, type RetrofitFacts, type RetrofitPlan, type RetrofitReason, type ReviewBlocked, type ReviewFinding, type ReviewGapRepoSummary, type ReviewGapUnit, type ReviewGapVerdict, type ReviewGapsInput, type ReviewGapsSummary, type ReviewGateResult, type ReviewGateSilentReason, type ReviewRecordBlockedInput, type ReviewRecordFindingInput, type ReviewRecordInput, type ReviewRecordedEvent, type RiskLevel, RiskLevelSchema, type RosterAdoptionPlan, type RosterDriftSummary, type RunOptions, type RunResult, STOP_HOOK_TIMEOUT_SECONDS, STUCK_THRESHOLD_MS, type SanitizePathOptions, type SanitizeRelatedFilesResult, SchemaVersionSchema, type SelfReportedReview, type Session, type SessionEndedEvent, type SessionEntry, SessionIdSchema, type SessionImportPayload, SessionImportPayloadSchema, type SessionInnerImportInput, SessionInnerImportSchema, type SessionIntegrity, SessionIntegritySchema, type SessionMetrics, SessionMetricsSchema, SessionSchema, type SessionSkipReason, type SessionSourceKind, SessionSourceKindSchema, type SessionStartedEvent, type SessionStatus, type SessionStatusChangedEvent, SessionStatusSchema, type SessionWorkStats, type SourceRootScope, type SourceRootsReconcile, type SourceWorkStats, type StatusCount, StatusSchema, type StatusSnapshot, type StopHookEvaluation, type StopHookEvaluationInput, type StopHookRemoval, type StopHookSilentReason, type StopHookUpsert, type SuspectReason, type SymlinkCollision, type SymlinkConflict, type SymlinkPlanSummary, type Task, type TaskArchivedEvent, type TaskCreatedEvent, type TaskDeletedEvent, type TaskDocument, TaskIdSchema, type TaskLinkageRefreshedEvent, type TaskReconciledEvent, TaskSchema, type TaskSkipReason, type TaskStatus, type TaskStatusChangedEvent, type TaskStatusCount, TaskStatusSchema, TaskWriteAfterEventError, type TaskWriteAfterEventPhase, type TokenTotals, type UnattachedSelfReports, type UnbindableRepo, type UpdateAdHocTaskStatusInput, type UpdateTaskStatusInput, type UpdateTaskStatusResult, type ViewCollision, type ViewConflict, type ViewLanguage, type ViewLinkState, type ViewPresetInput, type ViewPresetRepo, type ViewRepoFact, type ViewStrayUnknown, type ViewStrings, type ViewWiringFacts, type WiringCollision, type WiringConflict, type WiringDriftSummary, type WiringRisk, type WiringSummary, type WorkStatsInput, type WorkStatsResult, type WorkStatsTotals, WorkspaceIdSchema, type WorkspaceViewPlan, type WriteEventsBulkOptions, type WriteTaskFileMode, acquireLock, appendBasouGitignore, appendChainedEvent, appendChainedEventLocked, appendEvent, appendEventToExistingSession, archiveTask, assertBasouRootSafe, basouPaths, buildJsonSchemas, buildReviewRecordLabel, buildReviewRecordedEvent, buildStatusSnapshot, buildStopHookCommand, chainEvents, chainRawJsonLines, classifyFilesBySourceRoot, classifyRetrofit, classifySuspect, claudeCodeAdapterMetadata, claudeTranscriptToImportPayload, codexAdapterMetadata, codexRolloutToImportPayload, computeWorkStats, createAdHocSessionWithEvent, createManifest, createTaskWithEvent, deleteTask, editTask, ensureBasouDirectory, enumerateApprovals, enumerateArchivedTaskIds, enumerateSessionDirs, enumerateTaskIds, evaluateStopHook, finalizeSessionYaml, findBasouStopHookCommand, findErrorCode, findReviewGaps, findUnbindableRepos, formatDurationMs, genesisHash, getDiff, getSnapshot, importSessionFromJson, inspectChainTail, instructionMode, isBasouStopHookCommand, isGitNotFound, isImportDerivedSource, isLazyExpired, isRenderable, isValidPrefixedId, lineHash, linkYamlFile, loadApproval, loadFederatedSessionEntries, loadSessionEntries, loadTaskEntries, normalizeRepoKey, normalizeRepoPath, overwriteYamlFile, parseDuration, parseMarkers, parseReviewRecordInput, pathBasename, planArchive, planGitignore, planRename, planRosterAdoption, planWorkspaceView, prefixedUlid, presetStrings, readAllEvents, readManifest, readMarkdownFile, readSessionYaml, readStatus, readTaskFile, readTaskFileWithArchiveFallback, readYamlFile, rechainSessionInPlace, reconcileAllTasks, reconcileSourceRoots, reconcileTask, refreshTaskLinkedSessions, reimportPreservingId, removeMarkerSection, removeStopHook, renderAnchorStarter, renderDecisions, renderHandoff, renderOrientation, renderPresetBlock, renderReport, renderViewPresetBlock, renderWithMarkers, replayEvents, resolveAnchorContentLanguage, resolveBasouRepositoryRoot, resolveClaudeCodeCommand, resolveCodexCommand, resolveRepoContentLanguage, resolveRepoRoot, resolveRepositoryRoot, resolveSessionId, resolveTaskId, resolveViewLanguage, resolveViewLanguageFromPaths, safeSimpleGit, sanitizePath, sanitizeRelatedFiles, sanitizeWorkingDirectory, seedMarkers, serializeEventLine, serializeJsonSchema, sessionWorkStatsFromEvents, summarizeAdapterOutput, summarizeOrientation, summarizePresetPlan, summarizeRosterDrift, summarizeSymlinkPlan, summarizeWiring, summarizeWiringDrift, tryRemoteUrl, ulid, unknownManifestKeys, updateTaskStatusWithEvent, upsertStopHook, verifyEventsChain, viewStrings, writeEventsBulk, writeManifest, writeMarkdownFile, writeStatus, writeTaskFile, writeYamlFile };
|
|
6984
|
+
export { ACTIVE_GAP_CAP_MS, AGENT_INFRA_DIRS, type ActiveTimeBasis, type AdapterOutputEvent, type AdoptCandidate, type AdoptCandidateKind, type AnchorStarterInput, type AnchorStarterRepo, type AppendBasouGitignoreOptions, type AppendBasouGitignoreResult, type AppendEventToExistingInput, type AppendEventToExistingResult, type Approval, type ApprovalApprovedEvent, type ApprovalExpiredEvent, ApprovalIdSchema, type ApprovalLocation, type ApprovalRejectedEvent, type ApprovalRequestedEvent, ApprovalSchema, type ApprovalStatus, ApprovalStatusSchema, type ArchivePlan, type ArchiveTaskInput, type ArchiveTaskResult, type AttachTaskInput, type AttachUpdateTaskStatusInput, type AttachableStatus, BASOU_CORE_VERSION, type BasouPaths, type BuildStopHookCommandOptions, type BulkChainResult, CLAUDE_IMPORT_SOURCE, CODEX_IMPORT_SOURCE, type CaptureMode, type ChainBreakReason, type ChainTailState, type ChainVerdict, type ChainVerdictStatus, type ChainedEvents, ChildProcessRunner, type CitedReview, type ClaudeSettings, type ClaudeTranscriptRecord, type ClaudeTranscriptToPayloadOptions, type CodexCommandLookup, type CodexHooksFile, type CodexRolloutRecord, type CodexRolloutToPayloadOptions, type CommandExecutedEvent, type CommandLookup, type CreateAdHocSessionInput, type CreateAdHocSessionResult, type CreateAdHocTaskInput, type CreateManifestInput, type CreateTaskInput, type CreateTaskResult, DEFAULT_STOP_HOOK_MIN_EDITS, type DayWorkStats, DecisionIdSchema, type DecisionRecordedEvent, type DecisionsRendererInput, type DecisionsRendererResult, type DeleteTaskInput, type DeleteTaskResult, type DiffResult, type EditTaskInput, type EditTaskResult, type Event, EventIdSchema, EventSchema, EventSourceSchema, type ExistingViewLink, FailedToFinalizeError, type FederatedRoot, type FileChange, type FileChangeStatus, type FileChangedEvent, GENERATED_END, GENERATED_START, type GitSnapshot, type GitSnapshotEvent, type GitignorePlanSummary, type HandoffRendererInput, type HandoffRendererResult, ID_PREFIXES, type IdPrefix, type ImportSessionOptions, type ImportSessionResult, type IncompleteWiring, type InstructionFileFact, type InstructionSymlinkFact, type InstructionSymlinkState, IsoTimestampSchema, JSON_SCHEMA_VERSION, type JsonSchemaArtifact, type LoadFederatedOptions, type LoadSessionEntriesOptions, type LoadTaskEntriesOptions, type LoadedApproval, type LockHandle, type LockScope, type Manifest, ManifestSchema, type MarkerSection, type Markers, type MeasureAvailability, type MissingCanonical, type NoteAddedEvent, ORIENTATION_END, ORIENTATION_START, type OrientationRendererInput, type OrientationRendererResult, type OrientationSummary, PROTOCOL_END, PROTOCOL_START, type PrefixedId, type PresetAction, type PresetCollision, type PresetMarkerConflict, type PresetMarkerKind, type PresetPlanSummary, type PresetRepo, type PresetStrings, type ProcessRunner, type PublishKind, type PublishTarget, REVIEW_RECORD_NO_INPUT_HINT, type RechainOptions, type RechainResult, type ReconcileAllResult, type ReconcileAllTasksInput, type ReconcileAllTasksOptions, type ReconcileFailure, type ReconcileResult, type ReconcileTaskInput, type RefreshLinkageInput, type RefreshLinkageResult, type ReimportOptions, type ReimportResult, type RenamePlan, type ReplayOptions, type ReplayWarning, type RepoEntry, type RepoGitignoreFacts, type RepoGitignorePlan, type RepoInstructions, type RepoLanguage, type RepoPathProblem, type RepoPresetFacts, type RepoPresetPlan, type RepoSymlinkFacts, type RepoSymlinkPlan, type RepoVisibility, type RepoWiringFacts, type ReportApprovalItem, type ReportData, type ReportDecisionItem, type ReportRendererInput, type ReportRendererResult, type ReportSessionItem, type ReportTaskItem, type RetrofitAction, type RetrofitAgentsState, type RetrofitFacts, type RetrofitPlan, type RetrofitReason, type ReviewBlocked, type ReviewFinding, type ReviewGapRepoSummary, type ReviewGapUnit, type ReviewGapVerdict, type ReviewGapsInput, type ReviewGapsSummary, type ReviewGateResult, type ReviewGateSilentReason, type ReviewRecordBlockedInput, type ReviewRecordFindingInput, type ReviewRecordInput, type ReviewRecordedEvent, type RiskLevel, RiskLevelSchema, type RosterAdoptionPlan, type RosterDriftSummary, type RunOptions, type RunResult, SESSION_START_HOOK_CONTEXT_LIMIT, SESSION_START_HOOK_MATCHER, SESSION_START_HOOK_STATUS_MESSAGE, SESSION_START_HOOK_TIMEOUT_SECONDS, STOP_HOOK_TIMEOUT_SECONDS, STUCK_THRESHOLD_MS, type SanitizePathOptions, type SanitizeRelatedFilesResult, SchemaVersionSchema, type SelfReportedReview, type Session, type SessionEndedEvent, type SessionEntry, SessionIdSchema, type SessionImportPayload, SessionImportPayloadSchema, type SessionInnerImportInput, SessionInnerImportSchema, type SessionIntegrity, SessionIntegritySchema, type SessionMetrics, SessionMetricsSchema, SessionSchema, type SessionSkipReason, type SessionSourceKind, SessionSourceKindSchema, type SessionStartHookLocation, type SessionStartHookRemoval, type SessionStartHookUpsert, type SessionStartedEvent, type SessionStatus, type SessionStatusChangedEvent, SessionStatusSchema, type SessionWorkStats, type SourceRootScope, type SourceRootsReconcile, type SourceWorkStats, type StatusCount, StatusSchema, type StatusSnapshot, type StopHookEvaluation, type StopHookEvaluationInput, type StopHookRemoval, type StopHookSilentReason, type StopHookUpsert, type SuspectReason, type SymlinkCollision, type SymlinkConflict, type SymlinkPlanSummary, type Task, type TaskArchivedEvent, type TaskCreatedEvent, type TaskDeletedEvent, type TaskDocument, TaskIdSchema, type TaskLinkageRefreshedEvent, type TaskReconciledEvent, TaskSchema, type TaskSkipReason, type TaskStatus, type TaskStatusChangedEvent, type TaskStatusCount, TaskStatusSchema, TaskWriteAfterEventError, type TaskWriteAfterEventPhase, type TokenTotals, type UnattachedSelfReports, type UnbindableRepo, type UpdateAdHocTaskStatusInput, type UpdateTaskStatusInput, type UpdateTaskStatusResult, type ViewCollision, type ViewConflict, type ViewLanguage, type ViewLinkState, type ViewPresetInput, type ViewPresetRepo, type ViewRepoFact, type ViewStrayUnknown, type ViewStrings, type ViewWiringFacts, type WiringCollision, type WiringConflict, type WiringDriftSummary, type WiringRisk, type WiringSummary, type WorkStatsInput, type WorkStatsResult, type WorkStatsTotals, WorkspaceIdSchema, type WorkspaceViewPlan, type WriteEventsBulkOptions, type WriteTaskFileMode, acquireLock, appendBasouGitignore, appendChainedEvent, appendChainedEventLocked, appendEvent, appendEventToExistingSession, archiveTask, assertBasouRootSafe, basouPaths, buildJsonSchemas, buildReviewRecordLabel, buildReviewRecordedEvent, buildSessionStartHookCommand, buildStatusSnapshot, buildStopHookCommand, chainEvents, chainRawJsonLines, classifyFilesBySourceRoot, classifyRetrofit, classifySuspect, claudeCodeAdapterMetadata, claudeTranscriptToImportPayload, codexAdapterMetadata, codexRolloutToImportPayload, computeWorkStats, createAdHocSessionWithEvent, createManifest, createTaskWithEvent, deleteTask, editTask, ensureBasouDirectory, enumerateApprovals, enumerateArchivedTaskIds, enumerateSessionDirs, enumerateTaskIds, evaluateStopHook, finalizeSessionYaml, findBasouSessionStartHook, findBasouStopHookCommand, findErrorCode, findReviewGaps, findUnbindableRepos, formatDurationMs, genesisHash, getDiff, getSnapshot, importSessionFromJson, inspectChainTail, instructionMode, isBasouSessionStartHookCommand, isBasouStopHookCommand, isGitNotFound, isImportDerivedSource, isLazyExpired, isRenderable, isValidPrefixedId, lineHash, linkYamlFile, loadApproval, loadFederatedSessionEntries, loadSessionEntries, loadTaskEntries, normalizeRepoKey, normalizeRepoPath, overwriteYamlFile, parseDuration, parseMarkers, parseReviewRecordInput, pathBasename, planArchive, planGitignore, planRename, planRosterAdoption, planWorkspaceView, prefixedUlid, presetStrings, readAllEvents, readManifest, readMarkdownFile, readSessionYaml, readStatus, readTaskFile, readTaskFileWithArchiveFallback, readYamlFile, rechainSessionInPlace, reconcileAllTasks, reconcileSourceRoots, reconcileTask, refreshTaskLinkedSessions, reimportPreservingId, removeMarkerSection, removeSessionStartHook, removeStopHook, renderAnchorStarter, renderDecisions, renderHandoff, renderOrientation, renderPresetBlock, renderReport, renderViewPresetBlock, renderWithMarkers, replayEvents, resolveAnchorContentLanguage, resolveBasouRepositoryRoot, resolveClaudeCodeCommand, resolveCodexCommand, resolveRepoContentLanguage, resolveRepoRoot, resolveRepositoryRoot, resolveSessionId, resolveTaskId, resolveViewLanguage, resolveViewLanguageFromPaths, safeSimpleGit, sanitizePath, sanitizeRelatedFiles, sanitizeWorkingDirectory, seedMarkers, serializeEventLine, serializeJsonSchema, sessionWorkStatsFromEvents, summarizeAdapterOutput, summarizeOrientation, summarizePresetPlan, summarizeRosterDrift, summarizeSymlinkPlan, summarizeWiring, summarizeWiringDrift, tryRemoteUrl, ulid, unknownManifestKeys, updateTaskStatusWithEvent, upsertSessionStartHook, upsertStopHook, verifyEventsChain, viewStrings, writeEventsBulk, writeManifest, writeMarkdownFile, writeStatus, writeTaskFile, writeYamlFile };
|
package/dist/index.js
CHANGED
|
@@ -660,6 +660,135 @@ async function resolveCodexCommand(lookup = isOnPath) {
|
|
|
660
660
|
throw new Error("Codex CLI not found in PATH. Install codex first.");
|
|
661
661
|
}
|
|
662
662
|
|
|
663
|
+
// src/adapters/codex/hooks-json.ts
|
|
664
|
+
var SESSION_START_HOOK_TIMEOUT_SECONDS = 30;
|
|
665
|
+
var SESSION_START_HOOK_MATCHER = "startup|resume|clear";
|
|
666
|
+
var SESSION_START_HOOK_CONTEXT_LIMIT = 0;
|
|
667
|
+
var SESSION_START_HOOK_STATUS_MESSAGE = "basou orient";
|
|
668
|
+
var BASOU_SESSION_START_HOOK = /(?:\bbasou|(?:@basou|packages)\/cli\/dist\/index\.js['"]?)\s+hook\s+session-start\b/;
|
|
669
|
+
function isBasouSessionStartHookCommand(command) {
|
|
670
|
+
return BASOU_SESSION_START_HOOK.test(command);
|
|
671
|
+
}
|
|
672
|
+
function shellQuote2(value) {
|
|
673
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
674
|
+
}
|
|
675
|
+
function buildSessionStartHookCommand(options) {
|
|
676
|
+
return `node ${shellQuote2(options.cliEntry)} hook session-start 2>/dev/null || true`;
|
|
677
|
+
}
|
|
678
|
+
function isRecord2(value) {
|
|
679
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
680
|
+
}
|
|
681
|
+
function cloneHooksFile(hooksFile) {
|
|
682
|
+
if (hooksFile === void 0 || hooksFile === null) return {};
|
|
683
|
+
if (!isRecord2(hooksFile)) {
|
|
684
|
+
throw new Error("The Codex hooks.json is not a JSON object.");
|
|
685
|
+
}
|
|
686
|
+
return structuredClone(hooksFile);
|
|
687
|
+
}
|
|
688
|
+
function canonicalHandler(command) {
|
|
689
|
+
return {
|
|
690
|
+
type: "command",
|
|
691
|
+
command,
|
|
692
|
+
timeout: SESSION_START_HOOK_TIMEOUT_SECONDS,
|
|
693
|
+
statusMessage: SESSION_START_HOOK_STATUS_MESSAGE,
|
|
694
|
+
additionalContextLimit: SESSION_START_HOOK_CONTEXT_LIMIT
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
function handlerIsCanonical(entry, command) {
|
|
698
|
+
const want = canonicalHandler(command);
|
|
699
|
+
return Object.keys(want).every((k) => entry[k] === want[k]);
|
|
700
|
+
}
|
|
701
|
+
function upsertSessionStartHook(hooksFile, command) {
|
|
702
|
+
const root = cloneHooksFile(hooksFile);
|
|
703
|
+
if (root.hooks === void 0) {
|
|
704
|
+
root.hooks = {};
|
|
705
|
+
} else if (!isRecord2(root.hooks)) {
|
|
706
|
+
throw new Error("The 'hooks' key in the Codex hooks.json is not an object.");
|
|
707
|
+
}
|
|
708
|
+
const hooks = root.hooks;
|
|
709
|
+
if (hooks.SessionStart === void 0) {
|
|
710
|
+
hooks.SessionStart = [];
|
|
711
|
+
} else if (!Array.isArray(hooks.SessionStart)) {
|
|
712
|
+
throw new Error("The 'hooks.SessionStart' key in the Codex hooks.json is not an array.");
|
|
713
|
+
}
|
|
714
|
+
const groups = hooks.SessionStart;
|
|
715
|
+
for (const group of groups) {
|
|
716
|
+
if (!isRecord2(group) || !Array.isArray(group.hooks)) continue;
|
|
717
|
+
for (const entry of group.hooks) {
|
|
718
|
+
if (!isRecord2(entry)) continue;
|
|
719
|
+
if (typeof entry.command === "string" && isBasouSessionStartHookCommand(entry.command)) {
|
|
720
|
+
const unchanged = handlerIsCanonical(entry, command);
|
|
721
|
+
Object.assign(entry, canonicalHandler(command));
|
|
722
|
+
return { hooksFile: root, action: unchanged ? "unchanged" : "updated" };
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
groups.push({ matcher: SESSION_START_HOOK_MATCHER, hooks: [canonicalHandler(command)] });
|
|
727
|
+
return { hooksFile: root, action: "installed" };
|
|
728
|
+
}
|
|
729
|
+
function removeSessionStartHook(hooksFile) {
|
|
730
|
+
const root = cloneHooksFile(hooksFile);
|
|
731
|
+
if (!isRecord2(root.hooks) || !Array.isArray(root.hooks.SessionStart)) {
|
|
732
|
+
return { hooksFile: root, action: "absent" };
|
|
733
|
+
}
|
|
734
|
+
const hooks = root.hooks;
|
|
735
|
+
const groups = hooks.SessionStart;
|
|
736
|
+
let removed = false;
|
|
737
|
+
const kept = [];
|
|
738
|
+
for (const group of groups) {
|
|
739
|
+
if (!isRecord2(group) || !Array.isArray(group.hooks)) {
|
|
740
|
+
kept.push(group);
|
|
741
|
+
continue;
|
|
742
|
+
}
|
|
743
|
+
const keptHandlers = group.hooks.filter((entry) => {
|
|
744
|
+
if (isRecord2(entry) && typeof entry.command === "string" && isBasouSessionStartHookCommand(entry.command)) {
|
|
745
|
+
removed = true;
|
|
746
|
+
return false;
|
|
747
|
+
}
|
|
748
|
+
return true;
|
|
749
|
+
});
|
|
750
|
+
if (keptHandlers.length === group.hooks.length) {
|
|
751
|
+
kept.push(group);
|
|
752
|
+
} else if (keptHandlers.length > 0) {
|
|
753
|
+
group.hooks = keptHandlers;
|
|
754
|
+
kept.push(group);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
if (!removed) return { hooksFile: root, action: "absent" };
|
|
758
|
+
if (kept.length === 0) {
|
|
759
|
+
delete hooks.SessionStart;
|
|
760
|
+
} else {
|
|
761
|
+
hooks.SessionStart = kept;
|
|
762
|
+
}
|
|
763
|
+
if (Object.keys(hooks).length === 0) {
|
|
764
|
+
delete root.hooks;
|
|
765
|
+
}
|
|
766
|
+
return { hooksFile: root, action: "removed" };
|
|
767
|
+
}
|
|
768
|
+
function findBasouSessionStartHook(hooksFile) {
|
|
769
|
+
if (!isRecord2(hooksFile) || !isRecord2(hooksFile.hooks) || !Array.isArray(hooksFile.hooks.SessionStart)) {
|
|
770
|
+
return null;
|
|
771
|
+
}
|
|
772
|
+
const groups = hooksFile.hooks.SessionStart;
|
|
773
|
+
for (let g = 0; g < groups.length; g++) {
|
|
774
|
+
const group = groups[g];
|
|
775
|
+
if (!isRecord2(group) || !Array.isArray(group.hooks)) continue;
|
|
776
|
+
for (let h = 0; h < group.hooks.length; h++) {
|
|
777
|
+
const entry = group.hooks[h];
|
|
778
|
+
if (isRecord2(entry) && typeof entry.command === "string" && isBasouSessionStartHookCommand(entry.command)) {
|
|
779
|
+
return {
|
|
780
|
+
command: entry.command,
|
|
781
|
+
groupIndex: g,
|
|
782
|
+
handlerIndex: h,
|
|
783
|
+
matcher: typeof group.matcher === "string" ? group.matcher : void 0,
|
|
784
|
+
handler: structuredClone(entry)
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
return null;
|
|
790
|
+
}
|
|
791
|
+
|
|
663
792
|
// src/adapters/codex/rollout-importer.ts
|
|
664
793
|
var CODEX_IMPORT_SOURCE = "codex-import";
|
|
665
794
|
function codexRolloutToImportPayload(records, options) {
|
|
@@ -1782,7 +1911,30 @@ var WorkspaceMetaSchema = z4.looseObject({
|
|
|
1782
1911
|
*/
|
|
1783
1912
|
view: SourceRootSchema.optional()
|
|
1784
1913
|
});
|
|
1785
|
-
var
|
|
1914
|
+
var ChannelsSchema = z4.looseObject({
|
|
1915
|
+
/** Retired (see above). Parsed for compatibility; has no effect. */
|
|
1916
|
+
codex: z4.boolean().optional().meta({
|
|
1917
|
+
description: "Retired and ignored. It used to opt this workspace into rendering its orientation into the user-global ~/.codex/AGENTS.md; nothing is written there any more \u2014 a Codex session receives the workspace's position from the SessionStart hook (`basou hook install codex`)."
|
|
1918
|
+
})
|
|
1919
|
+
});
|
|
1920
|
+
var PoliciesSchema = z4.looseObject({
|
|
1921
|
+
/**
|
|
1922
|
+
* This workspace's provenance must not persist where another workspace's
|
|
1923
|
+
* tool reads it. That is the GOAL the key states. The one writer it used to
|
|
1924
|
+
* gate — the orientation render into the user-global `~/.codex/AGENTS.md` —
|
|
1925
|
+
* is retired, so today the key gates nothing: basou has no per-workspace path
|
|
1926
|
+
* that writes a position anywhere another workspace's tool reads. It is kept,
|
|
1927
|
+
* parsed, and honoured as a declaration, so a future writer to a shared
|
|
1928
|
+
* surface must consult it before it ships (`basou protocol sync`, a global
|
|
1929
|
+
* render rather than a per-workspace one, does not consult it). A top-level
|
|
1930
|
+
* `confidential` is still refused rather than ignored, for the same reason it
|
|
1931
|
+
* always was: a safety key that is not honoured must fail loudly.
|
|
1932
|
+
*/
|
|
1933
|
+
confidential: z4.boolean().optional().meta({
|
|
1934
|
+
description: "Posture: this workspace's provenance must not persist where another workspace's tool reads it. The one writer this used to gate \u2014 rendering the orientation into the user-global ~/.codex/AGENTS.md \u2014 is retired, so today the key gates nothing; it stays declared so a future writer to a shared surface must consult it. A top-level `confidential` is rejected rather than ignored."
|
|
1935
|
+
})
|
|
1936
|
+
});
|
|
1937
|
+
var ManifestObjectSchema = z4.looseObject({
|
|
1786
1938
|
schema_version: SchemaVersionSchema,
|
|
1787
1939
|
// Same forward-compatible format gate as schema_version (accept 0.x.y, gate a
|
|
1788
1940
|
// higher major with an upgrade error) rather than a hard literal. `basou_version`
|
|
@@ -1796,9 +1948,20 @@ var ManifestSchema = z4.looseObject({
|
|
|
1796
1948
|
adapters: AdaptersSchema,
|
|
1797
1949
|
git: GitConfigSchema,
|
|
1798
1950
|
import: ImportConfigSchema.optional(),
|
|
1799
|
-
repos: z4.array(RepoEntrySchema).min(1).optional()
|
|
1951
|
+
repos: z4.array(RepoEntrySchema).min(1).optional(),
|
|
1952
|
+
channels: ChannelsSchema.optional(),
|
|
1953
|
+
policies: PoliciesSchema.optional()
|
|
1954
|
+
});
|
|
1955
|
+
var ManifestSchema = ManifestObjectSchema.superRefine((manifest, ctx) => {
|
|
1956
|
+
if ("confidential" in manifest) {
|
|
1957
|
+
ctx.addIssue({
|
|
1958
|
+
code: "custom",
|
|
1959
|
+
path: ["confidential"],
|
|
1960
|
+
message: "`confidential` is declared under `policies` (policies.confidential: true). A top-level `confidential` is not honoured, so it is rejected rather than ignored."
|
|
1961
|
+
});
|
|
1962
|
+
}
|
|
1800
1963
|
});
|
|
1801
|
-
var KNOWN_TOP_LEVEL_KEYS = new Set(Object.keys(
|
|
1964
|
+
var KNOWN_TOP_LEVEL_KEYS = new Set(Object.keys(ManifestObjectSchema.shape));
|
|
1802
1965
|
function unknownManifestKeys(manifest) {
|
|
1803
1966
|
return Object.keys(manifest).filter((k) => !KNOWN_TOP_LEVEL_KEYS.has(k)).sort();
|
|
1804
1967
|
}
|
|
@@ -9412,6 +9575,10 @@ export {
|
|
|
9412
9575
|
PROTOCOL_START,
|
|
9413
9576
|
REVIEW_RECORD_NO_INPUT_HINT,
|
|
9414
9577
|
RiskLevelSchema,
|
|
9578
|
+
SESSION_START_HOOK_CONTEXT_LIMIT,
|
|
9579
|
+
SESSION_START_HOOK_MATCHER,
|
|
9580
|
+
SESSION_START_HOOK_STATUS_MESSAGE,
|
|
9581
|
+
SESSION_START_HOOK_TIMEOUT_SECONDS,
|
|
9415
9582
|
STOP_HOOK_TIMEOUT_SECONDS,
|
|
9416
9583
|
STUCK_THRESHOLD_MS,
|
|
9417
9584
|
SchemaVersionSchema,
|
|
@@ -9441,6 +9608,7 @@ export {
|
|
|
9441
9608
|
buildJsonSchemas,
|
|
9442
9609
|
buildReviewRecordLabel,
|
|
9443
9610
|
buildReviewRecordedEvent,
|
|
9611
|
+
buildSessionStartHookCommand,
|
|
9444
9612
|
buildStatusSnapshot,
|
|
9445
9613
|
buildStopHookCommand,
|
|
9446
9614
|
chainEvents,
|
|
@@ -9465,6 +9633,7 @@ export {
|
|
|
9465
9633
|
enumerateTaskIds,
|
|
9466
9634
|
evaluateStopHook,
|
|
9467
9635
|
finalizeSessionYaml,
|
|
9636
|
+
findBasouSessionStartHook,
|
|
9468
9637
|
findBasouStopHookCommand,
|
|
9469
9638
|
findErrorCode,
|
|
9470
9639
|
findReviewGaps,
|
|
@@ -9476,6 +9645,7 @@ export {
|
|
|
9476
9645
|
importSessionFromJson,
|
|
9477
9646
|
inspectChainTail,
|
|
9478
9647
|
instructionMode,
|
|
9648
|
+
isBasouSessionStartHookCommand,
|
|
9479
9649
|
isBasouStopHookCommand,
|
|
9480
9650
|
isGitNotFound,
|
|
9481
9651
|
isImportDerivedSource,
|
|
@@ -9517,6 +9687,7 @@ export {
|
|
|
9517
9687
|
refreshTaskLinkedSessions,
|
|
9518
9688
|
reimportPreservingId,
|
|
9519
9689
|
removeMarkerSection,
|
|
9690
|
+
removeSessionStartHook,
|
|
9520
9691
|
removeStopHook,
|
|
9521
9692
|
renderAnchorStarter,
|
|
9522
9693
|
renderDecisions,
|
|
@@ -9557,6 +9728,7 @@ export {
|
|
|
9557
9728
|
ulid,
|
|
9558
9729
|
unknownManifestKeys,
|
|
9559
9730
|
updateTaskStatusWithEvent,
|
|
9731
|
+
upsertSessionStartHook,
|
|
9560
9732
|
upsertStopHook,
|
|
9561
9733
|
verifyEventsChain,
|
|
9562
9734
|
viewStrings,
|