@jawache/flow 0.1.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/LICENCE +21 -0
- package/README.md +309 -0
- package/dist/flow.mjs +167 -0
- package/dist/index.mjs +18 -0
- package/dist/packs.mjs +116 -0
- package/dist/types/adapter/archive.d.ts +45 -0
- package/dist/types/adapter/claude.d.ts +157 -0
- package/dist/types/adapter/domain.d.ts +1112 -0
- package/dist/types/adapter/product.d.ts +10 -0
- package/dist/types/checks/domain.d.ts +792 -0
- package/dist/types/engine/domain.d.ts +747 -0
- package/dist/types/engine/state.d.ts +104 -0
- package/dist/types/errors.d.ts +14 -0
- package/dist/types/flow.d.ts +1 -0
- package/dist/types/glob.d.ts +53 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/language/domain.d.ts +641 -0
- package/dist/types/packs/docs.d.ts +49 -0
- package/dist/types/packs/fcis.d.ts +71 -0
- package/dist/types/packs/flow.d.ts +50 -0
- package/dist/types/packs/git.d.ts +107 -0
- package/dist/types/packs/index.d.ts +10 -0
- package/dist/types/packs/justfile.d.ts +83 -0
- package/dist/types/packs/node.d.ts +39 -0
- package/dist/types/packs/secrets.d.ts +117 -0
- package/dist/types/packs/tdd.d.ts +52 -0
- package/dist/types/packs/typescript.d.ts +101 -0
- package/dist/types/packs/work.d.ts +49 -0
- package/dist/types/version.d.ts +2 -0
- package/package.json +61 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { Category, SessionFacts } from "../language/domain.ts";
|
|
2
|
+
import { type Attribution, type Identity, type RecordedStep, type Recording, type Row, type SessionRows, type SessionState } from "./domain.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Create `.flow/`, self-ignored, and answer whether it is there.
|
|
5
|
+
*
|
|
6
|
+
* The `.gitignore` is written by whoever gets there first rather than by an install step, because
|
|
7
|
+
* the first writer is usually a hook: a repo whose guard ran before anyone typed a flow command
|
|
8
|
+
* would otherwise find a directory of telemetry sitting in `git status`. It is idempotent and it
|
|
9
|
+
* covers itself — `*` ignores the ignore file too.
|
|
10
|
+
*/
|
|
11
|
+
export declare function ensureFlowDir(root: string): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Is the guard switched off here?
|
|
14
|
+
*
|
|
15
|
+
* Fail-safe in the ON direction, deliberately: any error reading the marker is treated as "on", so
|
|
16
|
+
* a filesystem hiccup can never silence a gate. The only thing that turns flow off is a file that
|
|
17
|
+
* is definitely there.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isOff(root: string): boolean;
|
|
20
|
+
/** This session × agent's stored state. Absent, unreadable or corrupt → nothing known. */
|
|
21
|
+
export declare function loadState(root: string, session: string, agent: string): SessionState;
|
|
22
|
+
/** Store it. Dropped silently on any error — see the note at the top of this file. */
|
|
23
|
+
export declare function saveState(root: string, session: string, agent: string, state: SessionState): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Who this session × agent is, read once and then remembered — the sticky verdict, tied to disk.
|
|
26
|
+
*
|
|
27
|
+
* The two halves are proved separately next door and here; this is the ONE place they meet, so
|
|
28
|
+
* there is no second spelling of "look it up, and if it was fresh, write it down". A caller that
|
|
29
|
+
* assembled it by hand would eventually be a caller that forgot the write, and a classification
|
|
30
|
+
* that silently re-derives every hook is the flapping identity the sticky rule exists to prevent.
|
|
31
|
+
*/
|
|
32
|
+
export declare function stickyIdentity(root: string, session: string, agent: string, facts: SessionFacts, categories: readonly Category[]): Identity;
|
|
33
|
+
export interface LogContext {
|
|
34
|
+
readonly root: string;
|
|
35
|
+
readonly session: string;
|
|
36
|
+
/** The branch this worktree has out, for the stream's meta row. The adapter knows it; this does not. */
|
|
37
|
+
readonly branch: string | null;
|
|
38
|
+
/** Injected, because a clock inside a decision is a decision nobody can test. */
|
|
39
|
+
readonly now?: () => Date;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Append rows to this session's stream, stamping each with the time and the next event index.
|
|
43
|
+
*
|
|
44
|
+
* The FIRST write creates the file with its meta row, which is the fail-loud "armed" marker — a
|
|
45
|
+
* present-but-quiet log and a missing one are different facts, and a reader that cannot tell them
|
|
46
|
+
* apart reports an armed guard as an absent one.
|
|
47
|
+
*/
|
|
48
|
+
export declare function appendRows(ctx: LogContext, rows: readonly Row[]): boolean;
|
|
49
|
+
/** Every row in one stream file, in the order it was written. Unreadable → nothing. */
|
|
50
|
+
export declare function readRowsFile(file: string): Row[];
|
|
51
|
+
/** Every row of one session's stream. */
|
|
52
|
+
export declare function readRows(root: string, session: string): Row[];
|
|
53
|
+
/**
|
|
54
|
+
* Every session that has a stream here, oldest file first.
|
|
55
|
+
*
|
|
56
|
+
* `commit` is included: its rows still count toward what an entry has done, and only the SESSION
|
|
57
|
+
* count excludes it — a shared file is not a chat, and the metrics say so where it matters.
|
|
58
|
+
*/
|
|
59
|
+
export declare function sessionIds(root: string): string[];
|
|
60
|
+
/** The whole recorded history of a repo — every stream, read. */
|
|
61
|
+
export declare function readHistory(root: string): SessionRows[];
|
|
62
|
+
/**
|
|
63
|
+
* The conversations already dealt with. Existence is the fact; a marker means READ, never merely
|
|
64
|
+
* seen. Unreadable or absent is an empty set, which re-offers history — the harmless direction.
|
|
65
|
+
*/
|
|
66
|
+
export declare function alreadyRead(root: string): Set<string>;
|
|
67
|
+
/**
|
|
68
|
+
* Mark conversations read, so the backlog starts after them next time.
|
|
69
|
+
*
|
|
70
|
+
* Only ANALYSED ids are ever passed — never the deferred ones — which is what keeps "a marker
|
|
71
|
+
* means read" true and stops a capped run declaring skipped history done. Bookkeeping, so it
|
|
72
|
+
* answers with a count rather than throwing, like every other writer in this file.
|
|
73
|
+
*/
|
|
74
|
+
export declare function markRead(root: string, ids: readonly string[]): number;
|
|
75
|
+
/**
|
|
76
|
+
* Is this repo capturing replayable recordings?
|
|
77
|
+
*
|
|
78
|
+
* Fail-safe in the OFF direction, which is the opposite of the kill switch's and right for the
|
|
79
|
+
* opposite reason: a filesystem hiccup must never silence a gate, and it must never start writing
|
|
80
|
+
* a megabyte of transcript nobody asked for either.
|
|
81
|
+
*/
|
|
82
|
+
export declare function isRecording(root: string): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Append steps to this session's recording. Best-effort, like every other writer in this file.
|
|
85
|
+
*
|
|
86
|
+
* The header is written by whoever gets there first, exactly as the log's meta row is — the first
|
|
87
|
+
* writer is a hook, and a recording that only became valid once somebody ran a command would miss
|
|
88
|
+
* the opening of every session.
|
|
89
|
+
*/
|
|
90
|
+
export declare function appendSteps(root: string, session: string, steps: readonly RecordedStep[]): boolean;
|
|
91
|
+
/** One recording, read off disk. A file that is not there is an empty one, never an error. */
|
|
92
|
+
export declare function loadRecording(file: string): Recording;
|
|
93
|
+
/**
|
|
94
|
+
* Leave the live session × agent where the commit gate can find it.
|
|
95
|
+
*
|
|
96
|
+
* The gate is spawned by git, outside any session, so it cannot know which chat a commit belongs to
|
|
97
|
+
* — nor which of that chat's actors was working, which is a second question and the one that
|
|
98
|
+
* decides whether an actor-scoped rule can fire at the commit moment. Written on every edit, so the
|
|
99
|
+
* marker tracks the session's latest activity and its timestamp is what `attribution` judges
|
|
100
|
+
* freshness by.
|
|
101
|
+
*/
|
|
102
|
+
export declare function writeMarker(root: string, session: string, agent: string, branch: string | null, at?: Date): boolean;
|
|
103
|
+
/** Who this worktree's commit belongs to — the fresh marker's session × agent, or `commit`. */
|
|
104
|
+
export declare function commitAttribution(root: string, branch: string | null, nowMs?: number): Attribution;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Refusal, type LoadResult, type LoadedEntry } from "./language/domain.ts";
|
|
2
|
+
/**
|
|
3
|
+
* The config would not load. Every refusal rides along, each naming the entry it is about.
|
|
4
|
+
*
|
|
5
|
+
* The WORDING is `refusalText`'s, not this file's. The engine refuses a gated moment with the same
|
|
6
|
+
* block of text, so a person who has read one has read the other — and a second copy of the
|
|
7
|
+
* sentence here is how the exception and the block would come to disagree.
|
|
8
|
+
*/
|
|
9
|
+
export declare class FlowConfigError extends Error {
|
|
10
|
+
readonly refusals: readonly Refusal[];
|
|
11
|
+
constructor(refusals: readonly Refusal[]);
|
|
12
|
+
}
|
|
13
|
+
/** The loaded entries, or the error carrying every reason there are none. */
|
|
14
|
+
export declare function entriesOrThrow(result: LoadResult): readonly LoadedEntry[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export declare function escapeRe(s: string): string;
|
|
2
|
+
/** One piece of a glob. The whole dialect: `**` · `*` · `?` · `{a,b}` · literal text. */
|
|
3
|
+
export type GlobToken = {
|
|
4
|
+
readonly kind: "literal";
|
|
5
|
+
readonly text: string;
|
|
6
|
+
}
|
|
7
|
+
/** `*` — anything within one path segment. */
|
|
8
|
+
| {
|
|
9
|
+
readonly kind: "star";
|
|
10
|
+
}
|
|
11
|
+
/** `**` — anything, across segments. Consumes a `/` immediately after it. */
|
|
12
|
+
| {
|
|
13
|
+
readonly kind: "globstar";
|
|
14
|
+
}
|
|
15
|
+
/** `?` — exactly one character, not a separator. */
|
|
16
|
+
| {
|
|
17
|
+
readonly kind: "single";
|
|
18
|
+
}
|
|
19
|
+
/** `{a,b}` — one of these literals. */
|
|
20
|
+
| {
|
|
21
|
+
readonly kind: "options";
|
|
22
|
+
readonly options: readonly string[];
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Read a glob as tokens.
|
|
26
|
+
*
|
|
27
|
+
* An UNCLOSED `{` is a literal brace rather than an error or a swallowed rest-of-string. It cannot
|
|
28
|
+
* throw (this is a pure home) and refusing would mean every caller needs a failure path for a glob
|
|
29
|
+
* that is almost certainly just a brace in a filename; reading it literally is what the shell does
|
|
30
|
+
* too.
|
|
31
|
+
*/
|
|
32
|
+
export declare function tokenizeGlob(glob: string): GlobToken[];
|
|
33
|
+
/**
|
|
34
|
+
* One token → its regex source.
|
|
35
|
+
*
|
|
36
|
+
* Every construct emits something with NO quantifier of its own beyond a bare `.*` or `[^/]*`, and
|
|
37
|
+
* an alternation carries none at all — which is what keeps the output inside dependency-cruiser's
|
|
38
|
+
* ReDoS guard (it rejects grouped and nested quantifiers, never a plain group). The two emitters
|
|
39
|
+
* differ only in how they anchor the whole string, never in what a token means.
|
|
40
|
+
*/
|
|
41
|
+
export declare function globTokenToRegExp(token: GlobToken): string;
|
|
42
|
+
/** A glob → an anchored RegExp. Supports `**` (across /), `*` (within a segment), `?`, `{a,b}`. */
|
|
43
|
+
export declare function globToRegExp(glob: string): RegExp;
|
|
44
|
+
export declare function matchGlob(path: string, glob: string): boolean;
|
|
45
|
+
export declare function matchAny(path: string, globs: readonly string[] | null | undefined): boolean;
|
|
46
|
+
export interface FileParts {
|
|
47
|
+
dir: string;
|
|
48
|
+
base: string;
|
|
49
|
+
name: string;
|
|
50
|
+
path: string;
|
|
51
|
+
}
|
|
52
|
+
export declare function fileParts(file: string): FileParts;
|
|
53
|
+
export declare function expandTemplate(tpl: string, file: string): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { guardrail, breadcrumb, type Sentence, type EntrySpec, type GuardrailSpec, type BreadcrumbSpec, type GuardrailSentence, type BreadcrumbSentence, type EntryGroup, type DisabledMark, } from "./language/domain.ts";
|
|
2
|
+
export { definePack, pack, override, defineConfig, type Pack, type PackDefinition, type EntryRef, type RefTarget, type FlowConfig, type Binding, type PackBinding, type OverrideBinding, type ConfigSentence, } from "./language/domain.ts";
|
|
3
|
+
export { defineCheck, type Check, type Ctx, type World, type Verdict, type ExecResult, type TurnAction, type Case, type CaseWorld, type Cases, } from "./language/domain.ts";
|
|
4
|
+
export { defineCategory, type Category, type Classifier, type SessionFacts } from "./language/domain.ts";
|
|
5
|
+
export { astGrep, banCommands, canonicalFiles, changeTogether, commitReason, depcruise, execPasses, jsonInvariant, protectedPath, ranSinceEdit, siblingExists, symbolsInSibling, textBan, type CanonOptions, type ChangeGroup, type Dialect, type DiffAdds, type ForbidEdge, type JsonAssert, type RequireEdge, } from "./checks/domain.ts";
|
|
6
|
+
export { substitutionInProse, SUBSTITUTION_MESSAGE } from "./checks/domain.ts";
|
|
7
|
+
export { commitMessage, gitDirPrefix, gitInvocations, givesReason, quoteArg, tokenizeCommand, type GitInvocation, } from "./checks/domain.ts";
|
|
8
|
+
export { spawnedAs, type SpawnRecipe } from "./engine/domain.ts";
|
|
9
|
+
export { write, command, commit, deletion, turnEnd, session, touch, type Moment, type GuardrailMoment, type BreadcrumbMoment, } from "./language/domain.ts";
|
|
10
|
+
export { loadConfig, refusalText, REFUSAL_CODES, type Refusal, type RefusalCode, type LoadResult, type LoadedEntry, type Settings, } from "./language/domain.ts";
|
|
11
|
+
export { escapeRe } from "./glob.ts";
|
|
12
|
+
export { FlowConfigError, entriesOrThrow } from "./errors.ts";
|