sim 2.1.8-dev.94.1 → 2.1.8-preview.100.1

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.
Files changed (56) hide show
  1. package/README.md +52 -20
  2. package/THIRD_PARTY_LICENSES +42 -0
  3. package/dist/index.js +3713 -1160
  4. package/package.json +6 -16
  5. package/dist/auth/device-flow.d.ts +0 -38
  6. package/dist/commands/auth.d.ts +0 -5
  7. package/dist/commands/configure.d.ts +0 -2
  8. package/dist/commands/credentials.d.ts +0 -3
  9. package/dist/commands/protocol/chat.d.ts +0 -11
  10. package/dist/commands/protocol/files-get.d.ts +0 -25
  11. package/dist/commands/protocol/files-upload.d.ts +0 -2
  12. package/dist/commands/protocol/index.d.ts +0 -3
  13. package/dist/commands/protocol/knowledge-document-upload.d.ts +0 -2
  14. package/dist/commands/protocol/logs-follow.d.ts +0 -39
  15. package/dist/commands/protocol/resource-directory.d.ts +0 -24
  16. package/dist/commands/protocol/result.d.ts +0 -2
  17. package/dist/commands/protocol/tables-import.d.ts +0 -2
  18. package/dist/commands/protocol/workflow-run-follow.d.ts +0 -56
  19. package/dist/commands/protocol/workflow-run-get.d.ts +0 -15
  20. package/dist/commands/protocol/workflow-run-wait.d.ts +0 -3
  21. package/dist/commands/secrets.d.ts +0 -3
  22. package/dist/config/index.d.ts +0 -2
  23. package/dist/config/ini.d.ts +0 -111
  24. package/dist/config/paths.d.ts +0 -10
  25. package/dist/config/profile.d.ts +0 -158
  26. package/dist/context.d.ts +0 -21
  27. package/dist/contract/commands.d.ts +0 -14
  28. package/dist/contract/types.d.ts +0 -292
  29. package/dist/embed-context.d.ts +0 -83
  30. package/dist/embed-output.d.ts +0 -15
  31. package/dist/generated/v2-api.d.ts +0 -12969
  32. package/dist/helpers.d.ts +0 -9
  33. package/dist/http/client.d.ts +0 -166
  34. package/dist/http/environment.d.ts +0 -32
  35. package/dist/output/presentation.d.ts +0 -4
  36. package/dist/output/render.d.ts +0 -60
  37. package/dist/output/terminal-text.d.ts +0 -17
  38. package/dist/output/trace.d.ts +0 -3
  39. package/dist/program.d.ts +0 -21
  40. package/dist/runtime/build.d.ts +0 -38
  41. package/dist/runtime/derive.d.ts +0 -20
  42. package/dist/runtime/execute.d.ts +0 -30
  43. package/dist/runtime/naming.d.ts +0 -25
  44. package/dist/runtime/options.d.ts +0 -7
  45. package/dist/runtime/renamed.d.ts +0 -20
  46. package/dist/runtime/request.d.ts +0 -109
  47. package/dist/runtime/result.d.ts +0 -50
  48. package/dist/runtime/types.d.ts +0 -23
  49. package/dist/runtime.d.ts +0 -4
  50. package/dist/runtime.js +0 -16832
  51. package/dist/terminal/secret-input.d.ts +0 -15
  52. package/dist/terminal.d.ts +0 -6
  53. package/dist/transfer/local-file.d.ts +0 -16
  54. package/dist/transfer/streaming-upload.d.ts +0 -16
  55. package/dist/transfer/upload-session.d.ts +0 -18
  56. package/dist/version.d.ts +0 -10
package/package.json CHANGED
@@ -1,17 +1,14 @@
1
1
  {
2
2
  "name": "sim",
3
- "version": "2.1.8-dev.94.1",
3
+ "version": "2.1.8-preview.100.1",
4
4
  "description": "Sim CLI - talk to the Sim API from your terminal",
5
5
  "type": "module",
6
- "imports": {
7
- "#cli/*": "./src/*.ts"
8
- },
9
6
  "bin": {
10
7
  "sim": "dist/index.js"
11
8
  },
12
9
  "scripts": {
13
10
  "prebuild": "bun run clean",
14
- "build": "bun build src/index.ts src/runtime.ts --target=node --format=esm --packages=bundle --reject-unresolved --outdir=dist && tsc -p tsconfig.types.json",
11
+ "build": "bun build src/index.ts --target=node --format=esm --packages=bundle --reject-unresolved --outfile=dist/index.js",
15
12
  "clean": "bun -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"",
16
13
  "type-check": "tsc --noEmit",
17
14
  "lint": "biome check --write --unsafe .",
@@ -52,23 +49,16 @@
52
49
  "dependencies": {
53
50
  "chalk": "5.6.2",
54
51
  "commander": "^11.1.0",
55
- "js-yaml": "4.3.1"
52
+ "js-yaml": "4.3.1",
53
+ "proper-lockfile": "4.1.2"
56
54
  },
57
55
  "devDependencies": {
58
56
  "@sim/tsconfig": "0.0.0",
57
+ "@sim/utils": "0.1.0",
59
58
  "@types/js-yaml": "4.0.9",
60
59
  "@types/node": "24.2.1",
60
+ "@types/proper-lockfile": "4.1.4",
61
61
  "typescript": "^7.0.2",
62
62
  "vitest": "^4.1.0"
63
- },
64
- "exports": {
65
- "./embed": {
66
- "types": "./src/embed.ts",
67
- "default": "./src/embed.ts"
68
- },
69
- "./runtime": {
70
- "types": "./dist/runtime.d.ts",
71
- "default": "./dist/runtime.js"
72
- }
73
63
  }
74
64
  }
@@ -1,38 +0,0 @@
1
- export type CliAuthScope = 'copilot' | 'platform';
2
- export interface AuthRequest {
3
- /** Semi-public rendezvous handle; travels in the browser URL. */
4
- request: string;
5
- /** Never leaves this process until the poll redeems it. */
6
- pollSecret: string;
7
- /** BASE64URL(SHA256(pollSecret)), registered when the user approves. */
8
- challenge: string;
9
- /** Printed for the user to compare against the browser. Never sent to the API. */
10
- pairing: string;
11
- }
12
- export interface MintedKey {
13
- id: string;
14
- apiKey: string;
15
- scope: CliAuthScope;
16
- /** The workspace picked in the browser — the profile's default target. */
17
- workspaceId: string | null;
18
- /** Whether the key can *only* reach that workspace. */
19
- workspaceBound: boolean;
20
- }
21
- export declare function createAuthRequest(): AuthRequest;
22
- export declare function buildApprovalUrl(endpoint: string, auth: AuthRequest, scope: CliAuthScope, workspaceId?: string): string;
23
- /**
24
- * Polls until the user approves in the browser.
25
- *
26
- * Transport failures are swallowed and retried rather than aborting the login:
27
- * a laptop that slept, a VPN reconnecting, or a deploy rolling the server mid-
28
- * wait are all recoverable, and the approval sits in Redis with its own TTL. A
29
- * non-2xx *response*, by contrast, is the server refusing on purpose and is
30
- * surfaced immediately.
31
- *
32
- * Retried is not the same as unreported: once
33
- * {@link TRANSPORT_FAILURES_BEFORE_WARNING} attempts in a row fail to reach the
34
- * endpoint at all, the reason is printed once to stderr and the poll carries on.
35
- * Without it a typo'd endpoint was indistinguishable from a slow approval for
36
- * the entire 15-minute timeout.
37
- */
38
- export declare function pollForKey(endpoint: string, auth: AuthRequest, signal?: AbortSignal): Promise<MintedKey>;
@@ -1,5 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function loginCommand(): Command;
3
- export declare function logoutCommand(): Command;
4
- export declare function whoamiCommand(): Command;
5
- export declare function profilesCommand(): Command;
@@ -1,2 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function configureCommand(): Command;
@@ -1,3 +0,0 @@
1
- import { type Command } from 'commander';
2
- /** Adds the human-facing OAuth connection commands backed by the v2 credentials API. */
3
- export declare function attachCredentialCommands(program: Command): void;
@@ -1,11 +0,0 @@
1
- import type { Command } from 'commander';
2
- /**
3
- * Adds `sim chat`.
4
- *
5
- * A protocol command rather than a generated one: the generated pass can only
6
- * make one JSON request, while a chat turn can run for minutes and is consumed
7
- * as an NDJSON stream so the reply prints as it generates and heartbeats keep
8
- * proxies from idling the connection out. The generated `chat` operation is
9
- * hidden in the CLI contract in favour of this command.
10
- */
11
- export declare function attachChat(program: Command): void;
@@ -1,25 +0,0 @@
1
- import { type WriteStream } from 'node:fs';
2
- import { type Writable } from 'node:stream';
3
- import type { Command } from 'commander';
4
- /** Streams a fetch body to disk while honoring write-stream backpressure. */
5
- export declare function streamToFile(body: ReadableStream<Uint8Array>, file: Writable & Pick<WriteStream, 'path'>, reportedPath?: WriteStream['path']): Promise<void>;
6
- /**
7
- * Removes the staging directory when a signal ends the process.
8
- *
9
- * `saveStagedFile` cleans up in normal control flow, which a signal never
10
- * reaches: the process is torn down mid-`pipeline`, so every Ctrl-C left
11
- * another `.sim-download-*` holding a partial payload beside the destination.
12
- * The removal is synchronous because the termination that follows gives an
13
- * async `rm` no turn to run.
14
- *
15
- * Exported for its own test: driving it through a real interrupt would take the
16
- * test runner down with it.
17
- */
18
- export declare function removeStagingOnSignal(stagingDirectory: () => string | null, terminate?: (signal: NodeJS.Signals) => void): () => void;
19
- /** Publishes a complete staged body atomically, with overwrite requiring explicit force. */
20
- export declare function saveToFile(body: ReadableStream<Uint8Array>, target: string, force: boolean): Promise<void>;
21
- /** Streams a fetch body to stdout without closing the process-wide stream. */
22
- export declare function streamToStdout(body: ReadableStream<Uint8Array>, output?: NodeJS.WriteStream): Promise<void>;
23
- /** Returns whether content can be written directly to an interactive terminal. */
24
- export declare function isTerminalSafeContentType(contentType: string | null): boolean;
25
- export declare function attachFileGet(files: Command): void;
@@ -1,2 +0,0 @@
1
- import type { Command } from 'commander';
2
- export declare function attachFileUpload(files: Command): void;
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- /** Attaches commands whose multi-request or binary protocols cannot be generated. */
3
- export declare function attachProtocolCommands(program: Command): void;
@@ -1,2 +0,0 @@
1
- import { type Command } from 'commander';
2
- export declare function attachKnowledgeDocumentUpload(documents: Command): void;
@@ -1,39 +0,0 @@
1
- import { type Command } from 'commander';
2
- import { type ListLogsResponse } from '../../generated/v2-api';
3
- /** One run, as `GET /api/v2/logs` returns it. */
4
- export type LogRow = ListLogsResponse['data'][number];
5
- /** Widest a table column renders, matching the `logs list` table. */
6
- export declare const MAX_CELL_WIDTH = 60;
7
- export interface FollowStatus {
8
- /** Replaces the status line, if there is a terminal to draw it on. */
9
- note: (message: string) => void;
10
- /**
11
- * Reports something the reader has to know, on its own line.
12
- *
13
- * Unlike {@link note} this is not progress and is never erased: it records
14
- * that rows are missing, which stays true after the follow moves on. It is
15
- * written even when stderr is not a terminal, because a piped log is exactly
16
- * where an unexplained hole is hardest to spot.
17
- */
18
- warn: (message: string) => void;
19
- /** Erases the line, if anything was ever written to it. */
20
- clear: () => void;
21
- }
22
- /**
23
- * Reports what the follow is doing, on stderr.
24
- *
25
- * The rule `pageProgress` follows: stdout is the stream of rows and gets piped,
26
- * so anything that is not a row goes to stderr, and only to a terminal.
27
- */
28
- export declare function followStatus(): FollowStatus;
29
- /**
30
- * Adds `sim logs follow`.
31
- *
32
- * A sibling command rather than `logs list --follow`, because `logs list` is
33
- * generated from the CLI contract, which describes the HTTP surface: `--follow`
34
- * has no wire counterpart, and its paging is the inverse of the contract's —
35
- * re-reading the newest page forever, rather than walking a cursor to the end
36
- * once. The filters are the same ones `logs list` exposes, so the two commands
37
- * take the same arguments and render the same columns.
38
- */
39
- export declare function attachLogsFollow(logs: Command): void;
@@ -1,24 +0,0 @@
1
- import { type Command } from 'commander';
2
- type ResourceDirectoryConfig = {
3
- kind: 'file';
4
- resources: 'listFiles';
5
- folders: 'listFileFolders';
6
- createFolder: 'createFileFolder';
7
- } | {
8
- kind: 'knowledge';
9
- resources: 'listKnowledgeBases';
10
- folders: 'listKnowledgeFolders';
11
- createFolder: 'createKnowledgeFolder';
12
- } | {
13
- kind: 'table';
14
- resources: 'listTables';
15
- folders: 'listTableFolders';
16
- createFolder: 'createTableFolder';
17
- } | {
18
- kind: 'workflow';
19
- resources: 'listWorkflows';
20
- folders: 'listWorkflowFolders';
21
- createFolder: 'createWorkflowFolder';
22
- };
23
- export declare function attachResourceDirectoryCommands(group: Command, config: ResourceDirectoryConfig): void;
24
- export {};
@@ -1,2 +0,0 @@
1
- import type { OutputFormat } from '../../config/index';
2
- export declare function printProtocolResult(format: OutputFormat, result: Record<string, unknown>): void;
@@ -1,2 +0,0 @@
1
- import { type Command } from 'commander';
2
- export declare function attachTableImport(tables: Command): void;
@@ -1,56 +0,0 @@
1
- import type { Command } from 'commander';
2
- /** The sink live commentary is written to; `process.stderr` satisfies it. */
3
- export interface CommentaryWriter {
4
- write(text: string): unknown;
5
- }
6
- export interface FollowOptions {
7
- includeThinking: boolean;
8
- includeToolCalls: boolean;
9
- stderr: CommentaryWriter;
10
- }
11
- type WorkflowRunSelection = {
12
- source: 'manual';
13
- } | {
14
- source: 'manual';
15
- entry: {
16
- type: 'trigger';
17
- blockId?: string;
18
- useMockPayload?: boolean;
19
- };
20
- } | {
21
- source: 'manual';
22
- entry: {
23
- type: 'block';
24
- blockId: string;
25
- sourceRunId: string;
26
- };
27
- };
28
- /** Projects friendly CLI flags into the API's strict nested run selector. */
29
- export declare function resolveWorkflowRunSelection(flags: Record<string, unknown>): WorkflowRunSelection | undefined;
30
- /**
31
- * Renders one execute stream, returning the `final` envelope.
32
- *
33
- * Everything rendered here is commentary and goes to `stderr`: the payload a
34
- * script captures is the final envelope, which the caller prints to stdout in
35
- * the profile's output format. Streaming the answer text to stdout as well
36
- * would put the same content in the redirect twice, once unparseable.
37
- *
38
- * Throws on a terminal `error` frame and on a stream that stops before either
39
- * terminal frame arrives — a truncated stream is a failed run, and reporting it
40
- * as an empty success is the one outcome a caller cannot detect afterwards.
41
- */
42
- export declare function renderRunStream(body: ReadableStream<Uint8Array>, options: FollowOptions): Promise<Record<string, unknown>>;
43
- /**
44
- * Teaches the generated `workflows run` leaf to stream.
45
- *
46
- * `--follow` rides on `run` rather than standing up a sibling command because
47
- * it is the same operation with a different response encoding: the input,
48
- * output-selection, and `--async` flags all still apply, and a second command
49
- * would have to restate every one of them and then drift.
50
- *
51
- * Commander offers no way to read the action it already holds, so the existing
52
- * handler is captured and delegated to — every non-`--follow` invocation still
53
- * runs the generated path byte for byte.
54
- */
55
- export declare function attachWorkflowRunFollow(workflows: Command): void;
56
- export {};
@@ -1,15 +0,0 @@
1
- import type { Command } from 'commander';
2
- /**
3
- * Teaches the generated `workflows runs get` leaf the block names
4
- * `workflows run --select-output` already takes.
5
- *
6
- * The run resource matches recorded block ids only — it never loads the
7
- * workflow — so `--select-output summarize.result`, the spelling the run was
8
- * started with, came back `400` and the fix was to go and look up an id. The
9
- * lookup is done here instead: a selection with any name-headed selector reads
10
- * the workflow's blocks once, rewrites names onto ids, and reads the run keyed
11
- * the way it was asked. A selection of ids alone, or no selection, still runs
12
- * the generated handler byte for byte. Commander offers no way to read the
13
- * action it holds, so it is captured and delegated to, as `--follow` does.
14
- */
15
- export declare function attachWorkflowRunGet(runs: Command): void;
@@ -1,3 +0,0 @@
1
- import { type Command } from 'commander';
2
- /** Adds `workflows runs wait` — poll one run until it stops moving. */
3
- export declare function attachWorkflowRunWait(runs: Command): void;
@@ -1,3 +0,0 @@
1
- import { type Command } from 'commander';
2
- /** Adds interactive secret entry while preserving an explicit value flag for scripts. */
3
- export declare function attachSecretCommands(program: Command): void;
@@ -1,2 +0,0 @@
1
- export { configDir, configPath, credentialsPath } from './paths';
2
- export { DEFAULT_ENDPOINT, DEFAULT_PROFILE, deleteProfile, FORBIDDEN_IN_VALUE, listAuthenticationDependents, listProfiles, normalizeEndpoint, normalizeWorkspaceId, OUTPUT_FORMATS, type OutputFormat, PROFILE_NAME_PATTERN, ProfileConfigError, type ProfileOverrides, type ResolvedProfile, readConfigProfile, readCredentialsProfile, resolveAuthenticationProfileName, resolveProfile, type SettingSource, validateProfileName, writeConfigProfile, writeCredentialsProfile, } from './profile';
@@ -1,111 +0,0 @@
1
- /**
2
- * A minimal INI reader/writer for the AWS-style `~/.sim/config` and
3
- * `~/.sim/credentials` files.
4
- *
5
- * Parsing keeps every line it did not understand — comments, blank lines,
6
- * unrecognized keys — and writing re-emits them in place. These are files people
7
- * hand-edit, so a round trip through `sim login` must not silently delete the
8
- * comment above someone's staging endpoint.
9
- *
10
- * Deliberately not a general INI implementation: no nested sections, no `[a.b]`
11
- * paths, no quoting rules beyond trimming. The format only has to carry a
12
- * handful of flat string settings.
13
- */
14
- /**
15
- * An invalid stored setting, or a value the config files cannot represent.
16
- *
17
- * Defined here rather than in `profile.ts` because the writer below is the
18
- * lowest layer that rejects input, and `profile.ts` already imports this module.
19
- * `profile.ts` re-exports it, so callers keep seeing one error type — the one
20
- * the entrypoint renders as a message instead of a stack trace.
21
- */
22
- export declare class ProfileConfigError extends Error {
23
- constructor(message: string);
24
- }
25
- type Entry = {
26
- kind: 'kv';
27
- key: string;
28
- value: string;
29
- } | {
30
- kind: 'raw';
31
- text: string;
32
- };
33
- interface Section {
34
- name: string;
35
- /**
36
- * The header line exactly as it was read, re-emitted verbatim.
37
- *
38
- * {@link parseIni} trims the bracketed text to get {@link name}, so writing
39
- * `[${name}]` back rewrote the header of every section in the file — a
40
- * `configure --set-output` on `default` silently reformatted a hand-written
41
- * `[profile padded ]` it was never asked to touch. Absent only on a
42
- * section {@link setSectionValues} created, which has no original line.
43
- */
44
- header?: string;
45
- entries: Entry[];
46
- }
47
- export interface IniDocument {
48
- /** Lines before the first section header. */
49
- preamble: string[];
50
- sections: Section[];
51
- }
52
- /**
53
- * Characters a stored value may not contain.
54
- *
55
- * The format has no escape syntax (see the module note), so text that can end a
56
- * line is structure, not data: a value carrying a line break was written
57
- * verbatim and read back on the next load as a *second* setting in the same
58
- * section. That is the class of bug this closes — untrusted text reaching the
59
- * serializer could add settings nobody typed.
60
- *
61
- * The set is every C0 and C1 control character plus U+2028 and U+2029, the two
62
- * Unicode line separators. The separators matter for a second reason: they are
63
- * not line breaks to the reader below, so {@link KV_PATTERN} (whose `.` never
64
- * matches them) fails and the line is kept as opaque `raw` text — the key
65
- * silently vanishes on the next read although the write reported success, and
66
- * because the dead line no longer matches the key, the write after that appends
67
- * a duplicate.
68
- *
69
- * Exported because callers that refuse untrusted text *before* writing — so they
70
- * can say which side produced it — have to refuse exactly this set. A second
71
- * hand-kept copy drifted from this one once already, and the gap let a rejected
72
- * write land after an accepted one.
73
- */
74
- export declare const FORBIDDEN_IN_VALUE: RegExp;
75
- export declare function parseIni(text: string): IniDocument;
76
- export declare function serializeIni(doc: IniDocument): string;
77
- /**
78
- * Reads a section's keys, merging every block that repeats its name.
79
- *
80
- * A hand-edited file can carry two `[default]` blocks; reading only the first
81
- * silently dropped the second's keys and reported them as unset. The merge is
82
- * **first wins** per key, matching {@link setSectionValues}, which upserts into
83
- * the first block — so a value written through this module is the one read back.
84
- */
85
- export declare function getSection(doc: IniDocument, name: string): Record<string, string> | null;
86
- export declare function listSections(doc: IniDocument): string[];
87
- /**
88
- * Upserts values into a section, creating it when absent. A `null` value removes
89
- * the key. Existing keys are updated where they sit so surrounding comments keep
90
- * describing the line they were written above.
91
- *
92
- * A write targets the first block of that name, matching the first-wins read in
93
- * {@link getSection}. A removal instead has to clear every block and every
94
- * repeat of the key within one: deleting only the first left a later duplicate
95
- * to win the merged read, so `--unset` reported success while the value stayed
96
- * in force. A removal against a section that is not there writes nothing at all.
97
- *
98
- * This is the one place untrusted text enters the document, so it is where the
99
- * write is refused: see {@link FORBIDDEN_IN_VALUE} for what cannot be stored
100
- * and why the answer is a refusal rather than an escape.
101
- */
102
- export declare function setSectionValues(doc: IniDocument, name: string, values: Record<string, string | null>): void;
103
- /**
104
- * Drops every block carrying the name, and reports whether one was there.
105
- *
106
- * A hand-edited file can repeat a section, and {@link getSection} merges them
107
- * all — so removing only the first left `sim logout` reporting a profile gone
108
- * while its later block still answered every read.
109
- */
110
- export declare function removeSection(doc: IniDocument, name: string): boolean;
111
- export {};
@@ -1,10 +0,0 @@
1
- /**
2
- * Where the CLI keeps its state. `SIM_CONFIG_DIR` overrides the location
3
- * wholesale, which is what lets tests and CI point at a scratch directory
4
- * instead of the invoking user's real credentials.
5
- */
6
- export declare function configDir(): string;
7
- /** Non-secret per-profile settings. Safe to commit to a dotfiles repo. */
8
- export declare function configPath(): string;
9
- /** API keys, written 0600. Kept apart from `config` so the two can be handled differently. */
10
- export declare function credentialsPath(): string;
@@ -1,158 +0,0 @@
1
- import { ProfileConfigError } from './ini';
2
- export declare const DEFAULT_PROFILE = "default";
3
- /**
4
- * The API host, which is the `www` one and not the apex.
5
- *
6
- * `sim.ai` answers `/api/**` with a 301 to `www.sim.ai`, and the CLI refuses to
7
- * follow a redirect — a 301 rewrites a POST into a bodyless GET, so following
8
- * one turns a write into a silent no-op and hands the API key to whatever host
9
- * `Location` names. Defaulting to the apex therefore made every command fail
10
- * for anyone who never set an endpoint, and before the refusal existed it was
11
- * worse: reads succeeded while writes quietly did nothing.
12
- */
13
- export declare const DEFAULT_ENDPOINT = "https://www.sim.ai";
14
- /**
15
- * Output formats, in the order `--help` lists them.
16
- *
17
- * `table` is for reading, `json`/`yaml` for piping into a parser, and `text` is
18
- * the one for shell loops: tab-separated, no header, no colour, so `cut`/`awk`/
19
- * `while read` work without a JSON tool on the box.
20
- */
21
- export declare const OUTPUT_FORMATS: readonly ['table', 'json', 'yaml', 'text'];
22
- export type OutputFormat = (typeof OUTPUT_FORMATS)[number];
23
- export { FORBIDDEN_IN_VALUE, ProfileConfigError } from './ini';
24
- /**
25
- * Makes a rejected value safe to quote inside an error message.
26
- *
27
- * A message is one terminal line, so a value carrying a line break appends
28
- * lines that read as the CLI's own output. Every message that interpolates text
29
- * the CLI did not produce — a flag, an environment variable, a hand-edited
30
- * setting — goes through this, so the rule does not have to be rediscovered at
31
- * each new message.
32
- */
33
- export declare function redact(value: string): string;
34
- /**
35
- * A root flag typed with a value the CLI cannot use.
36
- *
37
- * Separate from the rest of {@link ProfileConfigError} so a caller that
38
- * deliberately tolerates an unresolvable profile — `profiles` shows a broken
39
- * one as a marked row rather than aborting, because that is the command you run
40
- * *because* a profile is broken — can still refuse the caller's own argument.
41
- * The class is the discriminator on purpose: matching the message text would
42
- * stop working the first time the wording changes.
43
- */
44
- export declare class ProfileOverrideError extends ProfileConfigError {
45
- constructor(message: string);
46
- }
47
- /**
48
- * The shape a newly created profile name has to have.
49
- *
50
- * Enforced only when a profile is being created. A name reaches the config file
51
- * as part of a section header, and the file format has no escape syntax, so a
52
- * name that carries a bracket or a line break would forge a header for another
53
- * profile — the writer refuses that outright, and this pattern is the friendlier
54
- * refusal that names the rule instead of the mechanism.
55
- */
56
- export declare const PROFILE_NAME_PATTERN: RegExp;
57
- /**
58
- * Refuses a name for a profile that does not exist yet.
59
- *
60
- * Creation only, deliberately: a hand-written `[profile my stack]` predates this
61
- * rule and must keep resolving, so the read path stays governed by
62
- * {@link requireKnownProfile} alone.
63
- */
64
- export declare function validateProfileName(name: string): void;
65
- /** Everything a command needs to make a call, after the resolution chain runs. */
66
- export interface ResolvedProfile {
67
- name: string;
68
- endpoint: string;
69
- apiKey: string | null;
70
- workspaceId: string | null;
71
- output: OutputFormat;
72
- /**
73
- * Replaces global `fetch` for every request. Only an embedding server sets it, to
74
- * answer its own v2 routes in-process; the installed CLI never does.
75
- */
76
- transport?: typeof fetch;
77
- signal?: AbortSignal;
78
- /** Where each value came from, for `sim whoami` to explain surprising results. */
79
- sources: {
80
- endpoint: SettingSource;
81
- apiKey: SettingSource;
82
- workspaceId: SettingSource;
83
- output: SettingSource;
84
- };
85
- }
86
- export type SettingSource = 'flag' | 'env' | 'config' | 'credentials' | 'default' | 'unset';
87
- export interface ProfileOverrides {
88
- profile?: string;
89
- endpoint?: string;
90
- apiKey?: string;
91
- workspaceId?: string;
92
- output?: OutputFormat;
93
- /**
94
- * Skips the "does this profile exist?" check for the two commands that
95
- * legitimately name a profile before it exists — `sim login --profile x` and
96
- * `sim configure --profile x --set-…`, both of which create it.
97
- */
98
- allowUnknownProfile?: boolean;
99
- }
100
- export declare function readConfigProfile(profile: string): Record<string, string>;
101
- export declare function readCredentialsProfile(profile: string): Record<string, string>;
102
- /**
103
- * Resolves the one stored identity a profile authenticates through.
104
- *
105
- * Existing profiles authenticate through their same-named credentials section.
106
- * A workspace alias may instead name one direct `auth_profile`; references are
107
- * deliberately non-recursive so a hand-edited cycle or missing target fails
108
- * with the setting that needs repair rather than surfacing later as "no key".
109
- */
110
- export declare function resolveAuthenticationProfileName(profile: string): string;
111
- /**
112
- * Every profile named by either file, deduplicated and sorted.
113
- *
114
- * The name is taken verbatim from what follows `profile `, without a second
115
- * trim. `configSectionName` builds the header back by prefixing `profile `, so
116
- * trimming here made the two disagree for a hand-written `[profile padded]`:
117
- * it listed and passed the "does this profile exist?" check as `padded`, while
118
- * every read looked for `profile padded` and found nothing — so `-P padded`
119
- * silently resolved to the built-in defaults, and the spelling that does name
120
- * the section was refused as unknown. Reporting the padded name keeps the one
121
- * that selects it the one that is shown, which is also how the credentials
122
- * file's sections have always been listed.
123
- */
124
- export declare function listProfiles(): string[];
125
- /** Profiles that directly share the named profile's stored authentication. */
126
- export declare function listAuthenticationDependents(authProfile: string): string[];
127
- export declare function writeConfigProfile(profile: string, values: Record<string, string | null>): void;
128
- export declare function writeCredentialsProfile(profile: string, apiKey: string | null): void;
129
- /** Drops the profile from both files. Returns whether anything was removed. */
130
- export declare function deleteProfile(profile: string): {
131
- config: boolean;
132
- credentials: boolean;
133
- };
134
- /**
135
- * Validates an endpoint and strips its trailing slashes.
136
- *
137
- * The check has to live here rather than at the call sites because an endpoint
138
- * reaches the HTTP client from four directions — `--endpoint`, `SIM_ENDPOINT`,
139
- * `configure --set-endpoint`, and a hand-edited `~/.sim/config` — and an
140
- * unparseable one escapes as a raw `TypeError: Invalid URL` stack trace from
141
- * inside Node's URL parser instead of a CLI error.
142
- *
143
- * `source` names where the value came from, so the message points at the thing
144
- * the user has to edit.
145
- */
146
- export declare function normalizeEndpoint(endpoint: string, source: string): string;
147
- /**
148
- * Validates a workspace id on its way into the config file.
149
- *
150
- * The sibling of {@link normalizeEndpoint}, and for the same reason: a stored
151
- * setting is read back as a real setting, so a value that could carry a line
152
- * break would come back as an extra setting the user never typed — including an
153
- * `endpoint`, which decides where the API key is sent. Only structure is
154
- * checked, not the id's shape: ids are server-minted and the CLI has no business
155
- * deciding what one may look like.
156
- */
157
- export declare function normalizeWorkspaceId(workspaceId: string, source: string): string;
158
- export declare function resolveProfile(overrides?: ProfileOverrides): ResolvedProfile;
package/dist/context.d.ts DELETED
@@ -1,21 +0,0 @@
1
- import type { Command } from 'commander';
2
- import { type OutputFormat, type ProfileOverrides, type ResolvedProfile } from './config/index';
3
- import { SimClient } from './http/client';
4
- /** Global flags, shared by every subcommand. */
5
- export interface GlobalOptions {
6
- profile?: string;
7
- endpoint?: string;
8
- workspace?: string;
9
- output?: OutputFormat;
10
- }
11
- /**
12
- * Commander stores globals on the root command, not on the leaf that ran, so a
13
- * subcommand handler has to walk up to find them. `optsWithGlobals()` does that
14
- * walk; reading `command.opts()` alone silently drops `--profile`.
15
- */
16
- export declare function globalsOf(command: Command): GlobalOptions;
17
- export declare function profileFrom(command: Command, extra?: ProfileOverrides): ResolvedProfile;
18
- export declare function clientFrom(command: Command): {
19
- client: SimClient;
20
- profile: ResolvedProfile;
21
- };
@@ -1,14 +0,0 @@
1
- import type { CliContract } from './types';
2
- /**
3
- * The CLI contract for the v2 surface.
4
- *
5
- * Read this as a diff against what is already derivable — an operation absent
6
- * from this table still gets a command, built entirely from the generated
7
- * operation table. Only the entries below needed a human.
8
- *
9
- * Derived by default:
10
- * listTables → sim tables list
11
- * getKnowledgeDocument → sim knowledge documents get <knowledgeBaseId> <documentId>
12
- * upsertTableRow → sim tables upsert <tableId>
13
- */
14
- export declare const CLI_CONTRACT: CliContract;