@attentionform/astra 0.0.0-stage → 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/LICENSE +206 -0
- package/NOTICE +12 -0
- package/README.md +211 -2
- package/dist/cli.js +40911 -0
- package/dist/packages/cli/src/cli/batch-cmd.d.ts +169 -0
- package/dist/packages/cli/src/cli/create-cmd.d.ts +4 -0
- package/dist/packages/cli/src/cli/errors.d.ts +86 -0
- package/dist/packages/cli/src/cli/export-cmd.d.ts +2 -0
- package/dist/packages/cli/src/cli/history-cmd.d.ts +5 -0
- package/dist/packages/cli/src/cli/import-cmd.d.ts +2 -0
- package/dist/packages/cli/src/cli/inspect-cmd.d.ts +3 -0
- package/dist/packages/cli/src/cli/io.d.ts +60 -0
- package/dist/packages/cli/src/cli/normalize-cmd.d.ts +9 -0
- package/dist/packages/cli/src/cli/output.d.ts +95 -0
- package/dist/packages/cli/src/cli/run.d.ts +6 -0
- package/dist/packages/cli/src/cli/sanitize-cmd.d.ts +26 -0
- package/dist/packages/cli/src/cli/search-cmd.d.ts +2 -0
- package/dist/packages/cli/src/cli/stats-cmd.d.ts +2 -0
- package/dist/packages/cli/src/cli/usage.d.ts +8 -0
- package/dist/packages/cli/src/cli/validate-cmd.d.ts +2 -0
- package/dist/packages/cli/src/cli/visual-cmd.d.ts +34 -0
- package/dist/packages/cli/src/cli.d.ts +44 -0
- package/dist/packages/cli/src/export.d.ts +18 -0
- package/dist/packages/ooxml-validator/src/index.d.ts +33 -0
- package/dist/packages/ooxml-validator/src/one-shot.d.ts +2 -0
- package/dist/packages/ooxml-validator/src/protocol.d.ts +30 -0
- package/dist/packages/ooxml-validator/src/resolve-binary.d.ts +5 -0
- package/dist/packages/ooxml-validator/src/types.d.ts +65 -0
- package/dist/packages/ooxml-validator/src/worker-client.d.ts +38 -0
- package/package.json +70 -4
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { type DryRunPreview, type StyleGuideConfig } from '@attentionform/astra-engine';
|
|
2
|
+
import { type GlobalOpts } from './output';
|
|
3
|
+
import { type ZipCeilingOverrides } from './io';
|
|
4
|
+
/** Canonical per-action ops examples (`batch --schema`). */
|
|
5
|
+
export declare function batchSchemaPayload(): Record<string, unknown>;
|
|
6
|
+
export interface OpsFile {
|
|
7
|
+
operations: unknown[];
|
|
8
|
+
sequential?: boolean;
|
|
9
|
+
rollbackOnError?: boolean;
|
|
10
|
+
maxSteps?: number;
|
|
11
|
+
maxRatio?: number;
|
|
12
|
+
maxUncompressedBytes?: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function parseOpsFile(raw: string): OpsFile;
|
|
15
|
+
export declare function printBatchSchema(out: GlobalOpts): number;
|
|
16
|
+
/**
|
|
17
|
+
* Expand CLI-level op extensions before the engine schema gate:
|
|
18
|
+
* - `insert type:heading level:1..3` -> `insert type:xml` carrying a
|
|
19
|
+
* Heading1..3 paragraph (the engine insert schema has no heading type, and
|
|
20
|
+
* this CLI must not grow engine-side edges — the rewrite keeps one op, one
|
|
21
|
+
* anchor, no extra ids).
|
|
22
|
+
* - `{action:'clearDoc'}` (alias `clear-doc`) -> counted separately; the body
|
|
23
|
+
* reset itself runs via clearDocumentBody() before the remaining ops.
|
|
24
|
+
*/
|
|
25
|
+
export declare function expandCliOps(operations: unknown[]): {
|
|
26
|
+
ops: unknown[];
|
|
27
|
+
clearCount: number;
|
|
28
|
+
};
|
|
29
|
+
export interface BackupState {
|
|
30
|
+
/** Resolved backup path, or undefined when --backup was not given or this is a dry run. */
|
|
31
|
+
path: string | undefined;
|
|
32
|
+
done: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface BatchJob {
|
|
35
|
+
opsFile: OpsFile;
|
|
36
|
+
target: string;
|
|
37
|
+
rowLabel: string | undefined;
|
|
38
|
+
}
|
|
39
|
+
export interface RunBatchJobCtx {
|
|
40
|
+
file: string;
|
|
41
|
+
docx: Buffer;
|
|
42
|
+
opsFile: OpsFile;
|
|
43
|
+
target: string;
|
|
44
|
+
sequential: boolean | undefined;
|
|
45
|
+
skipValidate: boolean;
|
|
46
|
+
flagCeilings: ZipCeilingOverrides;
|
|
47
|
+
dryRun: boolean;
|
|
48
|
+
backupState: BackupState;
|
|
49
|
+
rowLabel: string | undefined;
|
|
50
|
+
reproducible: boolean | undefined;
|
|
51
|
+
macroOpts: {
|
|
52
|
+
allowMacros: true;
|
|
53
|
+
} | {
|
|
54
|
+
stripMacros: true;
|
|
55
|
+
} | undefined;
|
|
56
|
+
allowedDir?: string | undefined;
|
|
57
|
+
/** Resolved --style-guide config (omitted = built-in defaults, byte-identical). */
|
|
58
|
+
styleGuide?: StyleGuideConfig | undefined;
|
|
59
|
+
/** Parser diagnostics of the resolved --style-guide (ride JSON styleWarnings). */
|
|
60
|
+
styleGuideWarnings?: string[] | undefined;
|
|
61
|
+
}
|
|
62
|
+
export declare function resolveBackupPath(file: string, raw: string | undefined): string;
|
|
63
|
+
/**
|
|
64
|
+
* Snapshot the pre-batch input bytes before the first write. Returns an
|
|
65
|
+
* exit code when the backup itself fails closed (target left untouched),
|
|
66
|
+
* or undefined when the backup is done (or not requested / already done).
|
|
67
|
+
*/
|
|
68
|
+
export declare function ensureBackupCopy(out: GlobalOpts, file: string, docx: Buffer, target: string, backupState: BackupState): Promise<number | undefined>;
|
|
69
|
+
/** Split one CSV line (double-quote escaping, "" = literal quote). */
|
|
70
|
+
export declare function splitCsvLine(line: string, source: string): string[];
|
|
71
|
+
/**
|
|
72
|
+
* Minimal CSV reader for --matrix: first non-blank line is the header,
|
|
73
|
+
* every later non-blank line is one data row (one row = one --out).
|
|
74
|
+
*/
|
|
75
|
+
export declare function parseMatrixCsv(raw: string, source: string): {
|
|
76
|
+
headers: string[];
|
|
77
|
+
rows: Array<Record<string, string>>;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Literal {{var}} substitution: header names only, single pass over the
|
|
81
|
+
* original string (values are never re-scanned), no expressions,
|
|
82
|
+
* conditionals, loops, or filters. Unknown names fail closed.
|
|
83
|
+
*/
|
|
84
|
+
export declare const MATRIX_VAR_RE: RegExp;
|
|
85
|
+
export declare function substituteMatrixString(template: string, row: Record<string, string>, ctx: string): string;
|
|
86
|
+
export declare function substituteMatrixVars(value: unknown, row: Record<string, string>, ctx: string): unknown;
|
|
87
|
+
export declare function truncLine(text: string, max: number): string;
|
|
88
|
+
/** Unified diff of the affected nodes (changed nodes only). */
|
|
89
|
+
export declare function renderUnifiedDiff(preview: DryRunPreview[]): string;
|
|
90
|
+
/** Human + --json report for a successful dry run (writes nothing). */
|
|
91
|
+
export declare function reportDryRun(out: GlobalOpts, args: {
|
|
92
|
+
file: string;
|
|
93
|
+
target: string;
|
|
94
|
+
appliedCount: number;
|
|
95
|
+
cleared: number;
|
|
96
|
+
preview: DryRunPreview[];
|
|
97
|
+
normalized: string[];
|
|
98
|
+
rowLabel: string | undefined;
|
|
99
|
+
possiblyStaleBodyRefs?: {
|
|
100
|
+
nodeId: string;
|
|
101
|
+
preview: string;
|
|
102
|
+
}[];
|
|
103
|
+
}): void;
|
|
104
|
+
export declare function cmdBatch(out: GlobalOpts, args: string[]): Promise<number>;
|
|
105
|
+
export declare function runBatchJob(out: GlobalOpts, ctx: RunBatchJobCtx): Promise<number>;
|
|
106
|
+
export type StreamOnError = 'abort' | 'continue';
|
|
107
|
+
export declare const STREAM_DEFAULT_ON_ERROR: StreamOnError;
|
|
108
|
+
export declare const STREAM_DEFAULT_MAX_ERRORS = 10;
|
|
109
|
+
export interface StreamCmdArgs {
|
|
110
|
+
file: string | undefined;
|
|
111
|
+
opsPath: string | undefined;
|
|
112
|
+
outPath: string | undefined;
|
|
113
|
+
sequential: boolean | undefined;
|
|
114
|
+
skipValidate: boolean;
|
|
115
|
+
flagCeilings: ZipCeilingOverrides;
|
|
116
|
+
dryRun: boolean;
|
|
117
|
+
backupGiven: boolean;
|
|
118
|
+
backupRaw: string | undefined;
|
|
119
|
+
matrixRaw: string | undefined;
|
|
120
|
+
targetTextRaw: string | undefined;
|
|
121
|
+
appendRaw: string | undefined;
|
|
122
|
+
onErrorRaw: string | undefined;
|
|
123
|
+
maxErrorsRaw: string | undefined;
|
|
124
|
+
force: boolean;
|
|
125
|
+
reproducible: boolean | undefined;
|
|
126
|
+
macroOpts: {
|
|
127
|
+
allowMacros: true;
|
|
128
|
+
} | {
|
|
129
|
+
stripMacros: true;
|
|
130
|
+
} | undefined;
|
|
131
|
+
allowedDir?: string | undefined;
|
|
132
|
+
/** Resolved --style-guide config (one guide for the invocation; streams apply it wholesale). */
|
|
133
|
+
styleGuide?: StyleGuideConfig | undefined;
|
|
134
|
+
/** Parser diagnostics of the resolved --style-guide (ride the stream eof summary). */
|
|
135
|
+
styleGuideWarnings?: string[] | undefined;
|
|
136
|
+
}
|
|
137
|
+
export interface StreamSessionOpts {
|
|
138
|
+
file: string;
|
|
139
|
+
target: string;
|
|
140
|
+
sequential: boolean | undefined;
|
|
141
|
+
skipValidate: boolean;
|
|
142
|
+
flagCeilings: ZipCeilingOverrides;
|
|
143
|
+
backupState: BackupState;
|
|
144
|
+
backupSource: Buffer;
|
|
145
|
+
reproducible: boolean | undefined;
|
|
146
|
+
macroOpts: {
|
|
147
|
+
allowMacros: true;
|
|
148
|
+
} | {
|
|
149
|
+
stripMacros: true;
|
|
150
|
+
} | undefined;
|
|
151
|
+
onError: StreamOnError;
|
|
152
|
+
maxErrors: number;
|
|
153
|
+
allowedDir?: string | undefined;
|
|
154
|
+
/** Resolved --style-guide config (one guide for the whole stream). */
|
|
155
|
+
styleGuide?: StyleGuideConfig | undefined;
|
|
156
|
+
/** Parser diagnostics of the resolved --style-guide (ride the stream eof summary). */
|
|
157
|
+
styleGuideWarnings?: string[] | undefined;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Flag/arg validation for --stream plus session wiring. Pre-session failures
|
|
161
|
+
* use the standard fail path (nothing streamed yet, so no acks are owed).
|
|
162
|
+
*/
|
|
163
|
+
export declare function cmdBatchStream(out: GlobalOpts, args: StreamCmdArgs): Promise<number>;
|
|
164
|
+
/**
|
|
165
|
+
* Resident stream session over an explicit line source. Emits exactly one ack
|
|
166
|
+
* per non-blank line plus one closing summary, then returns the exit code.
|
|
167
|
+
* Exported so tests can drive it with array lines (no stdin mocking).
|
|
168
|
+
*/
|
|
169
|
+
export declare function runStreamSession(out: GlobalOpts, docx: Buffer, opts: StreamSessionOpts, lines: Iterable<string> | AsyncIterable<string>, emit: (ack: Record<string, unknown>) => void): Promise<number>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type GlobalOpts } from './output';
|
|
2
|
+
export declare const CREATE_TEMPLATES: readonly ["report", "memo", "blank"];
|
|
3
|
+
export type CreateTemplate = (typeof CREATE_TEMPLATES)[number];
|
|
4
|
+
export declare function cmdCreate(out: GlobalOpts, args: string[]): Promise<number>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { type EngineErrorCode } from '@attentionform/astra-engine';
|
|
2
|
+
import { type GlobalOpts } from './output';
|
|
3
|
+
export declare const KNOWN_CLI_CODES: readonly EngineErrorCode[];
|
|
4
|
+
export type KnownCliCode = EngineErrorCode;
|
|
5
|
+
/** Collapse to one line and strip V8 frames / absolute paths. */
|
|
6
|
+
export declare function cleanCliMessage(raw: string): string;
|
|
7
|
+
/** Rewrite engine/MCP-surface remedy names to CLI-correct ones. */
|
|
8
|
+
export declare function rewriteMcpRemedies(message: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Sanitize a verbose stack for stderr: same hygiene as the one-liner
|
|
11
|
+
* (relative paths, no emoji, no absolute paths) but multi-line so `at`
|
|
12
|
+
* frames survive. Used only when `--verbose` is set; default output is
|
|
13
|
+
* untouched (exactly one line, never frames).
|
|
14
|
+
*/
|
|
15
|
+
export declare function sanitizeVerboseDetail(raw: string): string;
|
|
16
|
+
/** Classify an operational failure into { code, message, remedy }. */
|
|
17
|
+
export declare function toCliError(err: unknown, opts?: {
|
|
18
|
+
file?: string;
|
|
19
|
+
fallbackCode?: KnownCliCode;
|
|
20
|
+
fallbackRemedy?: string;
|
|
21
|
+
}): {
|
|
22
|
+
code: KnownCliCode;
|
|
23
|
+
message: string;
|
|
24
|
+
remedy: string;
|
|
25
|
+
verboseDetail?: string;
|
|
26
|
+
};
|
|
27
|
+
/** Emit the canonical one-line human error (+ optional --json) and return EXIT_FAIL. */
|
|
28
|
+
export declare function failHuman(out: GlobalOpts, err: unknown, opts?: {
|
|
29
|
+
file?: string;
|
|
30
|
+
fallbackCode?: KnownCliCode;
|
|
31
|
+
fallbackRemedy?: string;
|
|
32
|
+
extra?: Record<string, unknown>;
|
|
33
|
+
}): number;
|
|
34
|
+
export declare function fail(out: GlobalOpts, message: string, extra?: Record<string, unknown>): number;
|
|
35
|
+
/**
|
|
36
|
+
* Gate engine-side console chatter (console.error/console.warn) during an
|
|
37
|
+
* engine call. The engine logs raw diagnostics (stacks, absolute paths) that
|
|
38
|
+
* would break CLI error hygiene; the CLI's own one-line [CODE] error carries
|
|
39
|
+
* the failure instead. Both default and `--verbose` gate the raw output so
|
|
40
|
+
* the canonical one-liner stays first; `--verbose` re-adds sanitized frames
|
|
41
|
+
* after it via failHuman/failWithCode (relative paths, no emoji).
|
|
42
|
+
*/
|
|
43
|
+
export declare function withGatedEngineOutput<T>(_out: GlobalOpts, fn: () => Promise<T>): Promise<T>;
|
|
44
|
+
export type CliErrorCode = EngineErrorCode;
|
|
45
|
+
/** Extract the engine code from an error (`.code` prop or message prefix). */
|
|
46
|
+
export declare function extractCliErrorCode(err: unknown): CliErrorCode | undefined;
|
|
47
|
+
/** Extract with fallback (strict: callers always name the expected code). */
|
|
48
|
+
export declare function resolveCliErrorCode(err: unknown, fallback: CliErrorCode): CliErrorCode;
|
|
49
|
+
/** Ensure a human message carries its `[CODE]` prefix plus remedy. */
|
|
50
|
+
export declare function ensureCliErrorCodePrefix(message: string, code: CliErrorCode, remedy?: string): string;
|
|
51
|
+
export declare function failWithCode(out: GlobalOpts, message: string, code: KnownCliCode, extra?: Record<string, unknown>, remedy?: string, verboseDetail?: unknown): number;
|
|
52
|
+
export declare function inferBatchCode(err: unknown, fallback?: CliErrorCode): CliErrorCode;
|
|
53
|
+
export interface FileReadClassification {
|
|
54
|
+
code: KnownCliCode;
|
|
55
|
+
message: string;
|
|
56
|
+
remedy: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Normalize a file-read failure to the single missing/corrupt shape the
|
|
60
|
+
* human one-liner uses (same regexes, messages, and remedies as
|
|
61
|
+
* toCliError above). Batch read sites bypass toCliError via failWithCode
|
|
62
|
+
* with the raw message, so they classify here first: without this the raw
|
|
63
|
+
* ENOENT/ADM-ZIP/EISDIR text leaks into the one-liner with the wrong
|
|
64
|
+
* remedy. Returns undefined when the error is not a read failure and the
|
|
65
|
+
* caller should keep its existing code/remedy path.
|
|
66
|
+
*/
|
|
67
|
+
export declare function classifyFileReadError(err: unknown, file: string): FileReadClassification | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Location-aware remedy for a post-batch OOXML gate failure. Mirrors the
|
|
70
|
+
* wording and branch logic of the MCP save path
|
|
71
|
+
* (packages/mcp-server/src/lib/mcp/diff.ts remedyForValidationError) with
|
|
72
|
+
* CLI verbs (`astra inspect` / `astra batch` / retry instead of TOON /
|
|
73
|
+
* execute_batch / save_document). The fallback keeps the long-standing
|
|
74
|
+
* generic values hint byte-identical for shapes no branch names.
|
|
75
|
+
*/
|
|
76
|
+
export declare function remedyForPostBatchValidation(xPath: unknown, description: unknown): string;
|
|
77
|
+
/** Remedy text without a leading `Remedy:` label or trailing punctuation. */
|
|
78
|
+
export declare function normalizeRemedyText(raw: unknown): string | undefined;
|
|
79
|
+
/** Pull an engine `Remedy: ...` out of a raw error message, if present. */
|
|
80
|
+
export declare function extractEngineRemedy(rawMsg: string): string | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* Read an engine `.remedy` prop (tmp/sandbox throws carry the remedy ONLY on
|
|
83
|
+
* the prop — e.g. `$ASTRA_TMPDIR` symlink refusals — with no `Remedy:` text
|
|
84
|
+
* in the message, so message-only extraction loses it).
|
|
85
|
+
*/
|
|
86
|
+
export declare function readErrRemedyProp(err: unknown): string | undefined;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type GlobalOpts } from './output';
|
|
2
|
+
export declare function cmdHistory(out: GlobalOpts, args: string[]): Promise<number>;
|
|
3
|
+
export declare function cmdPreviewRevert(out: GlobalOpts, args: string[]): Promise<number>;
|
|
4
|
+
export declare function cmdRevert(out: GlobalOpts, args: string[]): Promise<number>;
|
|
5
|
+
export declare function cmdRedo(out: GlobalOpts, args: string[]): Promise<number>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export declare function readDocx(file: string): Promise<Buffer>;
|
|
2
|
+
/**
|
|
3
|
+
* R-44: read piped stdin fully as UTF-8 (for `batch <docx> -`).
|
|
4
|
+
* Callers check `process.stdin.isTTY` first and reject a terminal with a
|
|
5
|
+
* usage error, so this never blocks on interactive input. A closed pipe
|
|
6
|
+
* with no data (`< /dev/null`) resolves to '' and the caller rejects that
|
|
7
|
+
* as a usage error too — empty check, not a timeout, so a slow-but-live
|
|
8
|
+
* pipe still completes while empty stdin fails fast with exit 2.
|
|
9
|
+
*/
|
|
10
|
+
export declare function readStdinText(): Promise<string>;
|
|
11
|
+
export interface ZipCeilingOverrides {
|
|
12
|
+
maxRatio?: number;
|
|
13
|
+
maxUncompressedBytes?: number;
|
|
14
|
+
}
|
|
15
|
+
/** Validate a `--max-ratio <n>` value: positive finite number (cap guards typos). */
|
|
16
|
+
export declare function parseMaxRatioFlag(raw: string | undefined): number;
|
|
17
|
+
/** Validate a `--max-uncompressed-bytes <n>` value: positive integer bytes. */
|
|
18
|
+
export declare function parseMaxUncompressedBytesFlag(raw: string | undefined): number;
|
|
19
|
+
export interface MacroFlagChoice {
|
|
20
|
+
allowMacros: boolean;
|
|
21
|
+
stripMacros: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare function macroOptsFromFlags(f: MacroFlagChoice): {
|
|
24
|
+
allowMacros: true;
|
|
25
|
+
} | {
|
|
26
|
+
stripMacros: true;
|
|
27
|
+
} | undefined;
|
|
28
|
+
export declare function macroFlagsUsageError(): string;
|
|
29
|
+
/**
|
|
30
|
+
* Scope ceiling overrides around a DocxParser load. The engine resolves
|
|
31
|
+
* ceilings from env at check time (pre-read + central-directory gates), so
|
|
32
|
+
* temporarily setting the env is the non-invasive plumb for CLI flags.
|
|
33
|
+
* Restores prior values (including unset) afterwards.
|
|
34
|
+
*/
|
|
35
|
+
export declare function withZipCeilingEnv<T>(ceilings: ZipCeilingOverrides, fn: () => T | Promise<T>): Promise<T>;
|
|
36
|
+
/**
|
|
37
|
+
* Reproducible scoping: explicit --no-reproducible sets ASTRA_NO_REPRODUCIBLE=1
|
|
38
|
+
* around engine + save so revision/comment/cover dates see wall-clock;
|
|
39
|
+
* explicit --reproducible clears the opt-out and pins ASTRA_REPRODUCIBLE=1;
|
|
40
|
+
* undefined leaves env untouched (default deterministic unless env opts out).
|
|
41
|
+
*/
|
|
42
|
+
export declare function withReproducibleEnv<T>(reproducible: boolean | undefined, fn: () => T | Promise<T>): Promise<T>;
|
|
43
|
+
/**
|
|
44
|
+
* Author scoping: --author <name> sets ASTRA_AUTHOR around the engine run, so the document's
|
|
45
|
+
* default author (used by every tracked change and comment that does not name one) is the
|
|
46
|
+
* caller's. undefined leaves the environment untouched.
|
|
47
|
+
*/
|
|
48
|
+
export declare function withAuthorEnv<T>(author: string | undefined, fn: () => T | Promise<T>): Promise<T>;
|
|
49
|
+
export { computeDocStats, tableCellTextSpaced } from '@attentionform/astra-engine';
|
|
50
|
+
export type { DocStats } from '@attentionform/astra-engine';
|
|
51
|
+
export declare function escapeXmlText(text: string): string;
|
|
52
|
+
export declare function buildSnippet(text: string, query: string, radius?: number, maxLen?: number): string;
|
|
53
|
+
/**
|
|
54
|
+
* Reset the document body to a single empty paragraph, keeping styles,
|
|
55
|
+
* numbering, settings and all package props byte-identical. CLI-level only:
|
|
56
|
+
* the engine schema has no clear op, so `batch` expands `{action:'clearDoc'}`
|
|
57
|
+
* through this function before the remaining ops run.
|
|
58
|
+
*/
|
|
59
|
+
export declare function clearDocumentBody(buf: Buffer): Buffer;
|
|
60
|
+
export declare function writeDocx(file: string, buf: Buffer): Promise<void>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type GlobalOpts } from './output';
|
|
2
|
+
/**
|
|
3
|
+
* Repair-as-action entry for legacy files: runs the engine allowlist
|
|
4
|
+
* normalizer (display-only against the core API — see the surface block at
|
|
5
|
+
* the top of this file), then the strict validation gate, then writes.
|
|
6
|
+
* Chosen over a `validate --fix` alias: `validate` is pinned read-only
|
|
7
|
+
* fail-closed by scripts, so a mutating alias would break its contract.
|
|
8
|
+
*/
|
|
9
|
+
export declare function cmdNormalize(out: GlobalOpts, args: string[]): Promise<number>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export declare const CLI_NAME = "astra";
|
|
2
|
+
export declare const CLI_VERSION: string;
|
|
3
|
+
export declare const EXIT_OK = 0;
|
|
4
|
+
export declare const EXIT_FAIL = 1;
|
|
5
|
+
export declare const EXIT_USAGE = 2;
|
|
6
|
+
/** Fallback terminal width when --wrap cannot detect one (piped stdout). */
|
|
7
|
+
export declare const INSPECT_DEFAULT_WRAP_COLUMNS = 80;
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the human-presentation wrap width for inspect: an explicit
|
|
10
|
+
* --width wins; --wrap auto-detects the terminal width (fallback 80 when
|
|
11
|
+
* piped or unknown); neither means no wrapping (machine 1-line-per-node
|
|
12
|
+
* default stays). `columns` is injectable for tests; callers omit it to
|
|
13
|
+
* read process.stdout.columns.
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveInspectWidth(opts: {
|
|
16
|
+
width?: number;
|
|
17
|
+
wrap?: boolean;
|
|
18
|
+
columns?: number | undefined;
|
|
19
|
+
}): number | undefined;
|
|
20
|
+
export type NormalizedRewrite = string;
|
|
21
|
+
/** Display-only read of the core's own normalizer log (defensive: [] when absent). */
|
|
22
|
+
export declare function readParserNormalizations(parser: unknown): NormalizedRewrite[];
|
|
23
|
+
/** Display-only read of an engine result's `normalized` report (defensive: [] when absent). */
|
|
24
|
+
export declare function readEngineNormalized(res: unknown): NormalizedRewrite[];
|
|
25
|
+
/**
|
|
26
|
+
* Display-only would-be rewrites for dry-run: parse + rezip a copy through
|
|
27
|
+
* the core and report its log, discarding the bytes. No repair logic here —
|
|
28
|
+
* the copy is thrown away, nothing is written. Parse failures propagate to
|
|
29
|
+
* the caller so a corrupt input fails closed instead of reporting empty.
|
|
30
|
+
*/
|
|
31
|
+
export declare function previewNormalizedForDisplay(buf: Buffer, macroOpts?: {
|
|
32
|
+
allowMacros?: boolean;
|
|
33
|
+
stripMacros?: boolean;
|
|
34
|
+
}): NormalizedRewrite[];
|
|
35
|
+
/** Display-only repair entry: core parse + rezip (the hook heals), or passthrough on failure. */
|
|
36
|
+
export declare function applyNormalizerForDisplay(buf: Buffer): {
|
|
37
|
+
buffer: Buffer;
|
|
38
|
+
normalized: NormalizedRewrite[];
|
|
39
|
+
};
|
|
40
|
+
/** Inline `normalized=N [...]` fragment for result lines (bounded to 5 shown). */
|
|
41
|
+
export declare function formatNormalizedInline(list: readonly string[]): string;
|
|
42
|
+
/**
|
|
43
|
+
* Merge core logs across the rezips one save performs (gate rezip + save
|
|
44
|
+
* rezip), dropping exact duplicates. The gate's internal rezip already heals
|
|
45
|
+
* and logs, so reading only the final rezip would report a dishonest zero —
|
|
46
|
+
* capture both, report every rewrite once.
|
|
47
|
+
*/
|
|
48
|
+
export declare function mergeNormalized(...lists: string[][]): string[];
|
|
49
|
+
/**
|
|
50
|
+
* T-13: ANSI escape sequence regex — CSI (with `;` and `:` sub-params for
|
|
51
|
+
* colon truecolor `38:2::r:g:b` / `4:3`), OSC hyperlinks/titles (`ESC ] … BEL/ST`),
|
|
52
|
+
* charset designators (`ESC ( B`), and residual single-char ESC sequences.
|
|
53
|
+
* Alternation order matters: OSC first so `ESC ] …` is consumed whole instead
|
|
54
|
+
* of partially matching the CSI branch.
|
|
55
|
+
*/
|
|
56
|
+
export declare const ANSI_REGEX: RegExp;
|
|
57
|
+
/**
|
|
58
|
+
* T-13: Strip ANSI escape sequences from text.
|
|
59
|
+
*/
|
|
60
|
+
export declare function stripAnsi(text: string): string;
|
|
61
|
+
/**
|
|
62
|
+
* T-13: Check if color stripping is required (!process.stdout.isTTY or
|
|
63
|
+
* NO_COLOR present with a non-empty value, per https://no-color.org:
|
|
64
|
+
* empty-string NO_COLOR must NOT strip).
|
|
65
|
+
*/
|
|
66
|
+
export declare function shouldStripColor(stream?: 'stdout' | 'stderr' | {
|
|
67
|
+
isTTY?: boolean;
|
|
68
|
+
}): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* T-13: Format message respecting TTY and NO_COLOR.
|
|
71
|
+
*/
|
|
72
|
+
export declare function formatCliOutput(message: string, stream?: 'stdout' | 'stderr' | {
|
|
73
|
+
isTTY?: boolean;
|
|
74
|
+
}): string;
|
|
75
|
+
/**
|
|
76
|
+
* T-13: Serialize a --json payload, stripping ANSI when color is disabled
|
|
77
|
+
* (non-TTY stdout or non-empty NO_COLOR). ANSI inside JSON string values
|
|
78
|
+
* must not leak raw escapes into piped JSON consumers.
|
|
79
|
+
*/
|
|
80
|
+
/**
|
|
81
|
+
* Recursively strip ANSI from JSON string values (arrays + plain objects).
|
|
82
|
+
* JSON.stringify escapes raw ESC as `\\u001b` text, so stripping must happen
|
|
83
|
+
* BEFORE serialization — a post-serialization regex would miss the escaped
|
|
84
|
+
* form. Non-plain objects pass through untouched.
|
|
85
|
+
*/
|
|
86
|
+
export declare function stripAnsiDeep(value: unknown): unknown;
|
|
87
|
+
export declare function stringifyJsonPayload(payload: unknown, space?: string | number): string;
|
|
88
|
+
export type Fidelity = 'compact' | 'standard' | 'full';
|
|
89
|
+
export interface GlobalOpts {
|
|
90
|
+
json: boolean;
|
|
91
|
+
verbose: boolean;
|
|
92
|
+
}
|
|
93
|
+
export declare function print(out: GlobalOpts, message: string): void;
|
|
94
|
+
export declare function printStderr(message: string): void;
|
|
95
|
+
export declare function printJson(out: GlobalOpts, payload: unknown): void;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type GlobalOpts } from './output';
|
|
2
|
+
export declare function isSanitizeBodyPartName(name: string): boolean;
|
|
3
|
+
export declare function isSanitizeCommentFamilyName(name: string): boolean;
|
|
4
|
+
export declare function isSanitizeStyleFamilyName(name: string): boolean;
|
|
5
|
+
export declare function isSanitizeGenericTextName(name: string): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Count revision/comment markup surviving in a sanitized package (count-only,
|
|
8
|
+
* never echoes values). Revisions cover w:ins/w:del/move + cell markers +
|
|
9
|
+
* range markers + *Change wrappers; comments cover range/reference elements
|
|
10
|
+
* plus comment definitions in comment parts. Used to gate the partial-flag
|
|
11
|
+
* WARNING so a clean file stays quiet.
|
|
12
|
+
*/
|
|
13
|
+
export declare function countSanitizeSurvivors(docxBuf: Buffer): {
|
|
14
|
+
revisions: number;
|
|
15
|
+
comments: number;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Structural locations of body PII that sanitize will redact (count-only,
|
|
19
|
+
* never echoes values). One entry per redaction hit (`part#p<idx>` for
|
|
20
|
+
* body/comment parts, `part#text` for generic text carriers). Bounded at
|
|
21
|
+
* 1000 entries. Falls back to part-level markers when paragraph slicing
|
|
22
|
+
* finds nothing but the whole-part count is non-zero, so a non-zero
|
|
23
|
+
* bodyRedactions count never prints with an empty location list.
|
|
24
|
+
*/
|
|
25
|
+
export declare function collectBodyPiiLocations(inputBuf: Buffer): string[];
|
|
26
|
+
export declare function cmdSanitize(out: GlobalOpts, args: string[]): Promise<number>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type GlobalOpts } from './output';
|
|
2
|
+
export declare function printUsage(out: GlobalOpts): number;
|
|
3
|
+
export declare const USAGE_CODE = "E_USAGE";
|
|
4
|
+
export declare const USAGE_REMEDY = "check arguments with `astra --help` (or `astra <command> --help`), then retry";
|
|
5
|
+
export declare function usage(out: GlobalOpts, message?: string): number;
|
|
6
|
+
export declare function commandHelpText(cmd: string): string | undefined;
|
|
7
|
+
export declare function printCommandHelp(out: GlobalOpts, cmd: string): number;
|
|
8
|
+
export declare function hasHelpFlag(args: string[]): boolean;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { renderDocxToImages, type DocumentAST, type VisualImageFormat, type VisualTelemetry } from '@attentionform/astra-engine';
|
|
2
|
+
import { type GlobalOpts } from './output';
|
|
3
|
+
/**
|
|
4
|
+
* Single CLI visual-telemetry builder (two entry points: `visual` below and
|
|
5
|
+
* `inspect --visual` in inspect-cmd.ts — both call this, never the engine
|
|
6
|
+
* directly, so the wireframe/warnings stay identical across surfaces).
|
|
7
|
+
* `renderTotalPages` is the renderer's (LibreOffice) actual page count: the
|
|
8
|
+
* single source of truth for the `[PAGE n OF m]` marker whenever it differs
|
|
9
|
+
* from the word-layout map embedded in the structural summary.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildCliVisualTelemetry(ast: DocumentAST, summary: unknown, page?: number, renderTotalPages?: number): VisualTelemetry;
|
|
12
|
+
/**
|
|
13
|
+
* Single CLI visual-render path (two entry points: `visual --out` below and
|
|
14
|
+
* `inspect --visual` in inspect-cmd.ts — both call this, never
|
|
15
|
+
* `renderDocxToImages` directly, so DPI/quality/page-selection stay
|
|
16
|
+
* identical: same `pages: [page]` + `format` args on every invocation).
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildCliVisualRenderArgs(page: number, format: VisualImageFormat): {
|
|
19
|
+
pages: [number];
|
|
20
|
+
format: VisualImageFormat;
|
|
21
|
+
};
|
|
22
|
+
export declare function renderCliVisualPage(buf: Buffer, page: number, format: VisualImageFormat): Promise<Awaited<ReturnType<typeof renderDocxToImages>>>;
|
|
23
|
+
/**
|
|
24
|
+
* Single CLI visual-telemetry printer (both entry points call this, so the
|
|
25
|
+
* wireframe/warnings/tokens lines stay identical across surfaces).
|
|
26
|
+
* Callers pass the EFFECTIVE page (the renderer's clamped pick, not the raw
|
|
27
|
+
* request) so the `[PAGE n OF m]` marker always describes the image shown,
|
|
28
|
+
* and the renderer's actual page count as `renderTotalPages` so `OF m` is
|
|
29
|
+
* the renderer's count — the image came from the renderer, the marker must
|
|
30
|
+
* name it. Divergence from the word-layout page map and any --page beyond
|
|
31
|
+
* that map warn on stderr (never silent; stdout stays JSON-clean).
|
|
32
|
+
*/
|
|
33
|
+
export declare function printCliVisualTelemetry(out: GlobalOpts, ast: DocumentAST, summary: unknown, page: number, renderTotalPages?: number): VisualTelemetry;
|
|
34
|
+
export declare function cmdVisual(out: GlobalOpts, args: string[]): Promise<number>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @attentionform/astra — Track-B command line (`astra` bin).
|
|
4
|
+
*
|
|
5
|
+
* Commands (all fail-closed — any operational failure exits non-zero):
|
|
6
|
+
* inspect <docx> [--fidelity compact|standard|full] [--section <id>] [--max-text <n>] [--width <n>] [--wrap] [--visual] [--format png|jpeg] [--max-ratio <n>] [--max-uncompressed-bytes <n>]
|
|
7
|
+
* validate <docx> [--max-ratio <n>] [--max-uncompressed-bytes <n>] [--style-guide <name|path>]
|
|
8
|
+
* sanitize <in.docx> <out.docx> [--client-safe] [--redact-pii] [--zero-retention] [--replacement-author <name>] [--accept-all-revisions] [--strip-comments] [--metadata-only]
|
|
9
|
+
* (bare sanitize = metadata preset: zero-retention + accept-all-revisions + strip-comments + neutral author, body text kept; --redact-pii/--client-safe also redact body PII)
|
|
10
|
+
* batch <docx> [<ops.json|->] [--target-text <needle> --append <text>] [--append <text>] [--out <docx>] [--sequential|--no-sequential] [--no-validate] [--schema] [--max-ratio <n>] [--max-uncompressed-bytes <n>] [--dry-run] [--backup[=<path>]] [--matrix <vars.csv>] [--reproducible|--no-reproducible] [--stream [--on-error abort|continue] [--max-errors <n>]] [--style-guide <name|path>]
|
|
11
|
+
* (ops path `-` reads ops JSON from stdin; see `batch --help`)
|
|
12
|
+
* (ops support CLI-level `insert type:heading level:1..3` and `{action:'clearDoc'}`; see `batch --schema`)
|
|
13
|
+
* normalize <docx> [--out <docx>] [--dry-run] [--backup[=<path>]] (repair-as-action for legacy files; `validate` stays read-only, no --fix alias)
|
|
14
|
+
* export <docx> [--format html|markdown|md|pdf] [-o <outPath>]
|
|
15
|
+
* search <docx> <query> [--limit <n>]
|
|
16
|
+
* create <out.docx> [--template report|memo|blank] [--force] [--from-md <file.md>] [--allowed-dir <dir>] [--dollar-math] [--style-guide <name|path>]
|
|
17
|
+
* import <file.md> [-o <out.docx>] [--template report|memo|blank] [--force] [--allowed-dir <dir>] [--dollar-math]
|
|
18
|
+
* stats <docx>
|
|
19
|
+
*
|
|
20
|
+
* Exit codes: 0 ok · 1 operational failure (invalid docx, bad ops, batch
|
|
21
|
+
* failure/rollback, failed validation — never writes corruption) · 2 usage.
|
|
22
|
+
*
|
|
23
|
+
* Engine wiring:
|
|
24
|
+
* imports resolve to the `@attentionform/astra-engine` package.
|
|
25
|
+
* CLI command names, flags and exit-code contract stay identical
|
|
26
|
+
* across refactors (scripts pin them).
|
|
27
|
+
*/
|
|
28
|
+
export * from './cli/output';
|
|
29
|
+
export * from './cli/errors';
|
|
30
|
+
export * from './cli/usage';
|
|
31
|
+
export * from './cli/io';
|
|
32
|
+
export * from './cli/inspect-cmd';
|
|
33
|
+
export * from './cli/validate-cmd';
|
|
34
|
+
export * from './cli/sanitize-cmd';
|
|
35
|
+
export * from './cli/batch-cmd';
|
|
36
|
+
export * from './cli/normalize-cmd';
|
|
37
|
+
export * from './cli/export-cmd';
|
|
38
|
+
export * from './cli/search-cmd';
|
|
39
|
+
export * from './cli/create-cmd';
|
|
40
|
+
export * from './cli/import-cmd';
|
|
41
|
+
export * from './cli/stats-cmd';
|
|
42
|
+
export * from './cli/visual-cmd';
|
|
43
|
+
export * from './cli/history-cmd';
|
|
44
|
+
export * from './cli/run';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface ExportResult {
|
|
2
|
+
ok: boolean;
|
|
3
|
+
path: string;
|
|
4
|
+
format: 'html' | 'markdown' | 'pdf';
|
|
5
|
+
bytes: number;
|
|
6
|
+
assets?: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface ExportOptions {
|
|
9
|
+
/** Render untagged PDF (default false = tagged render). */
|
|
10
|
+
untagged?: boolean;
|
|
11
|
+
/** Fail closed on preflight blockers (default false = warn-only). */
|
|
12
|
+
strict?: boolean;
|
|
13
|
+
/** Markdown only: embed data URLs (default) or write folder references. */
|
|
14
|
+
imageMode?: 'embed' | 'file';
|
|
15
|
+
/** Markdown file mode: relative folder for image files (default media). */
|
|
16
|
+
assetPrefix?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function executeExport(docxPath: string, formatInput?: string, outPath?: string, options?: ExportOptions): Promise<ExportResult>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export { resolveEmbeddedBinary, resolveBinaryDetails } from './resolve-binary.js';
|
|
2
|
+
import { OFFICE_VERSIONS, type OfficeVersion, type ValidateOptions, type ValidationError, type ValidationResult, type ValidatorPoolOptions, type BackendInfo, type ValidatorInstance, type ErrorNode, type ValidationErrorClass } from './types.js';
|
|
3
|
+
export { OFFICE_VERSIONS };
|
|
4
|
+
export type { OfficeVersion, ValidateOptions, ValidationError, ValidationResult, ValidatorPoolOptions, BackendInfo, ValidatorInstance, ErrorNode, ValidationErrorClass, };
|
|
5
|
+
/**
|
|
6
|
+
* Validates a single OOXML file from disk.
|
|
7
|
+
* Defaults to 'Microsoft365' to match standard ECMA-376 / ISO-29500 behavior.
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateFile(filePath: string, options?: ValidateOptions): Promise<ValidationResult>;
|
|
10
|
+
/**
|
|
11
|
+
* Convenience helper returning a boolean indicating if the document is valid.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isValid(filePath: string, options?: ValidateOptions): Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Validates an in-memory DOCX buffer without creating temporary files.
|
|
16
|
+
* Defaults to 'Office2019' matching the ASTra engine's standard validation target.
|
|
17
|
+
*/
|
|
18
|
+
export declare function validateBuffer(bytes: Buffer | Uint8Array, options?: ValidateOptions): Promise<ValidationResult>;
|
|
19
|
+
/**
|
|
20
|
+
* Creates an isolated validator worker client instance.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createValidator(opts?: ValidatorPoolOptions): ValidatorInstance;
|
|
23
|
+
/**
|
|
24
|
+
* Returns diagnostic metadata about the resolved binary and platform package.
|
|
25
|
+
*/
|
|
26
|
+
export declare function backendInfo(): Promise<BackendInfo>;
|
|
27
|
+
/**
|
|
28
|
+
* Runs a self-diagnostic validating an embedded known-good and known-bad document.
|
|
29
|
+
*/
|
|
30
|
+
export declare function selfTest(): Promise<{
|
|
31
|
+
ok: boolean;
|
|
32
|
+
details: string;
|
|
33
|
+
}>;
|