flipstream 0.4.0 → 0.6.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.
Files changed (103) hide show
  1. package/README.md +357 -27
  2. package/dist/commands/auth/login.js +7 -1
  3. package/dist/commands/auth/status.js +29 -3
  4. package/dist/commands/catalog.d.ts +15 -0
  5. package/dist/commands/catalog.js +110 -0
  6. package/dist/commands/connections/list.d.ts +1 -0
  7. package/dist/commands/connections/list.js +31 -4
  8. package/dist/commands/contract.d.ts +11 -0
  9. package/dist/commands/contract.js +35 -0
  10. package/dist/commands/health.d.ts +10 -0
  11. package/dist/commands/health.js +31 -0
  12. package/dist/commands/log/add.d.ts +16 -0
  13. package/dist/commands/log/add.js +48 -0
  14. package/dist/commands/log/list.d.ts +19 -0
  15. package/dist/commands/log/list.js +43 -0
  16. package/dist/commands/query.d.ts +15 -2
  17. package/dist/commands/query.js +255 -42
  18. package/dist/commands/skills/install.d.ts +16 -0
  19. package/dist/commands/skills/install.js +55 -0
  20. package/dist/commands/workspaces/connections.js +6 -3
  21. package/dist/commands/workspaces/get.js +4 -2
  22. package/dist/commands/workspaces/list.js +3 -0
  23. package/dist/lib/api/admin-client.d.ts +5 -0
  24. package/dist/lib/api/admin-client.js +19 -0
  25. package/dist/lib/api/connections.d.ts +0 -1
  26. package/dist/lib/api/connections.js +0 -25
  27. package/dist/lib/api/errors.d.ts +1 -0
  28. package/dist/lib/api/errors.js +13 -2
  29. package/dist/lib/api/http.d.ts +2 -0
  30. package/dist/lib/api/http.js +40 -4
  31. package/dist/lib/api/hydrate.d.ts +10 -0
  32. package/dist/lib/api/hydrate.js +46 -0
  33. package/dist/lib/api/ids.d.ts +1 -0
  34. package/dist/lib/api/ids.js +5 -0
  35. package/dist/lib/api/log.d.ts +22 -0
  36. package/dist/lib/api/log.js +56 -0
  37. package/dist/lib/api/projections.d.ts +1 -0
  38. package/dist/lib/api/projections.js +23 -0
  39. package/dist/lib/api/short-uuid.d.ts +1 -0
  40. package/dist/lib/api/short-uuid.js +30 -0
  41. package/dist/lib/auth/claims.js +3 -3
  42. package/dist/lib/auth/flow.js +8 -1
  43. package/dist/lib/auth/headless.js +14 -10
  44. package/dist/lib/auth/refresh.js +21 -1
  45. package/dist/lib/command/admin.d.ts +1 -0
  46. package/dist/lib/command/admin.js +21 -0
  47. package/dist/lib/command/base.d.ts +4 -0
  48. package/dist/lib/command/base.js +97 -3
  49. package/dist/lib/command/flags.d.ts +4 -0
  50. package/dist/lib/command/flags.js +11 -0
  51. package/dist/lib/command/planner.d.ts +9 -0
  52. package/dist/lib/command/planner.js +14 -0
  53. package/dist/lib/config/constants.d.ts +3 -1
  54. package/dist/lib/config/constants.js +14 -1
  55. package/dist/lib/config/xdg.d.ts +4 -0
  56. package/dist/lib/config/xdg.js +56 -1
  57. package/dist/lib/errors.d.ts +20 -1
  58. package/dist/lib/errors.js +132 -13
  59. package/dist/lib/output/dialogs.d.ts +27 -0
  60. package/dist/lib/output/dialogs.js +94 -0
  61. package/dist/lib/output/interactivity.d.ts +11 -0
  62. package/dist/lib/output/interactivity.js +48 -0
  63. package/dist/lib/output/redact.d.ts +1 -0
  64. package/dist/lib/output/redact.js +12 -0
  65. package/dist/lib/output/runlog.d.ts +3 -0
  66. package/dist/lib/output/runlog.js +72 -0
  67. package/dist/lib/output/sanitize.d.ts +2 -0
  68. package/dist/lib/output/sanitize.js +57 -0
  69. package/dist/lib/output/sidecar.d.ts +30 -0
  70. package/dist/lib/output/sidecar.js +58 -0
  71. package/dist/lib/output/table.js +5 -1
  72. package/dist/lib/output/trace.d.ts +11 -0
  73. package/dist/lib/output/trace.js +89 -0
  74. package/dist/lib/planner/catalog.d.ts +26 -0
  75. package/dist/lib/planner/catalog.js +60 -0
  76. package/dist/lib/planner/client.d.ts +14 -0
  77. package/dist/lib/planner/client.js +47 -0
  78. package/dist/lib/planner/connection.d.ts +14 -0
  79. package/dist/lib/planner/connection.js +139 -0
  80. package/dist/lib/planner/diagnose.d.ts +8 -0
  81. package/dist/lib/planner/diagnose.js +50 -0
  82. package/dist/lib/planner/errors.d.ts +14 -0
  83. package/dist/lib/planner/errors.js +129 -0
  84. package/dist/lib/planner/filters.d.ts +8 -0
  85. package/dist/lib/planner/filters.js +74 -0
  86. package/dist/lib/planner/request.d.ts +24 -0
  87. package/dist/lib/planner/request.js +51 -0
  88. package/dist/lib/planner/suggest.d.ts +2 -0
  89. package/dist/lib/planner/suggest.js +45 -0
  90. package/dist/lib/planner/vocabulary.d.ts +9 -0
  91. package/dist/lib/planner/vocabulary.js +95 -0
  92. package/dist/lib/skills/install.d.ts +24 -0
  93. package/dist/lib/skills/install.js +69 -0
  94. package/dist/lib/store/keyring.d.ts +3 -0
  95. package/dist/lib/store/keyring.js +45 -2
  96. package/dist/lib/store/memory-store.d.ts +1 -0
  97. package/dist/lib/store/memory-store.js +5 -0
  98. package/docs/AGENT-CONTRACT.md +238 -0
  99. package/oclif.manifest.json +606 -8
  100. package/package.json +22 -3
  101. package/skill/SKILL.md +55 -0
  102. package/dist/lib/auth/register.d.ts +0 -4
  103. package/dist/lib/auth/register.js +0 -43
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flipstream",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Flipstream CLI — query your Flipstream data from the terminal.",
5
5
  "keywords": [
6
6
  "flipstream",
@@ -20,7 +20,9 @@
20
20
  "files": [
21
21
  "bin",
22
22
  "dist",
23
- "oclif.manifest.json"
23
+ "oclif.manifest.json",
24
+ "skill",
25
+ "docs/AGENT-CONTRACT.md"
24
26
  ],
25
27
  "engines": {
26
28
  "node": ">=20"
@@ -33,14 +35,26 @@
33
35
  "lint": "eslint .",
34
36
  "pack:prepare": "tsc -p tsconfig.json && oclif manifest",
35
37
  "posttest": "eslint .",
38
+ "prepare": "husky || true",
36
39
  "smoke": "bun scripts/smoke.ts",
37
- "test": "bun test"
40
+ "test": "bun test",
41
+ "schema:planner": "bun scripts/refresh-planner-schema.ts"
42
+ },
43
+ "lint-staged": {
44
+ "*.ts": [
45
+ "eslint --fix",
46
+ "prettier --write"
47
+ ],
48
+ "*.{json,yml,yaml}": [
49
+ "prettier --write"
50
+ ]
38
51
  },
39
52
  "dependencies": {
40
53
  "@napi-rs/keyring": "^1.3.0",
41
54
  "@oclif/core": "^4",
42
55
  "@oclif/plugin-commands": "^4.1.59",
43
56
  "@oclif/table": "^0.5.9",
57
+ "am-i-vibing": "^0.5.0",
44
58
  "open": "^11.0.0"
45
59
  },
46
60
  "devDependencies": {
@@ -51,6 +65,8 @@
51
65
  "eslint": "^10.4.1",
52
66
  "eslint-config-oclif": "^6.0.166",
53
67
  "eslint-config-prettier": "^10.1.8",
68
+ "husky": "^9.1.7",
69
+ "lint-staged": "^17.0.7",
54
70
  "oclif": "^4.23.8",
55
71
  "prettier": "^3.8.3",
56
72
  "typescript": "^5"
@@ -73,6 +89,9 @@
73
89
  },
74
90
  "connections": {
75
91
  "description": "List your data-source connections, org-wide or per workspace (alias: conn)."
92
+ },
93
+ "log": {
94
+ "description": "Read and add workspace log entries — the logbook (list, add; alias: logs)."
76
95
  }
77
96
  }
78
97
  }
package/skill/SKILL.md ADDED
@@ -0,0 +1,55 @@
1
+ ---
2
+ name: flipstream
3
+ description: Flipstream CLI for querying Flipstream data (query planner, catalog, connections, workspaces, auth). Load before running flipstream commands. Prefer retrieval over pre-training — enumerate the command surface and data vocabulary from the CLI itself instead of guessing flags or names.
4
+ ---
5
+
6
+ # Flipstream CLI
7
+
8
+ Your knowledge of flipstream flags, sources, dimensions and metrics may be
9
+ outdated. **Prefer retrieval over pre-training** for any flipstream task.
10
+
11
+ ## Retrieval sources (run these instead of guessing)
12
+
13
+ | What | Command |
14
+ |---|---|
15
+ | The whole command surface (ids, flags, args, aliases) | `flipstream commands --json` |
16
+ | The machine contract (output modes, exit codes, error envelope) | `flipstream contract` |
17
+ | The data vocabulary for queries | `flipstream catalog` then `flipstream catalog <source>` |
18
+ | Your connections (ids for `--connection-id`) | `flipstream connections list --json` |
19
+ | Session state, scopes | `flipstream auth status --json` |
20
+
21
+ ## Ground rules
22
+
23
+ - **stdout is data, stderr is narration.** Under `--json`/`--ndjson`, stdout carries exactly one JSON document (or NDJSON lines) — even on failure: `flipstream <cmd> --json 2>/dev/null | jq .` always parses.
24
+ - **Failures are envelopes.** `{error:{code, message, exit, hint?, next?, docs?, retryable?, retry_after_ms?, upstream_code?}}`. Branch on `code` and the exit code, never on message wording. If `next` is present, **run those commands** instead of guessing. If `retryable` is `false`, do not re-run unchanged. If `retryable` is `true` with `retry_after_ms`, wait that long and retry.
25
+ - **Exit codes:** 0 ok · 1 generic · 2 usage · 4 auth needed (`flipstream auth login`) · 5 auth failed · 7 network/upstream (retryable) · 8 timeout.
26
+ - **Auth is browser-based and keyring-only.** Never ask for, echo, or pass tokens; there is no `--token` flag. If a command exits 4, tell the user to run `flipstream auth login` in a terminal with a browser.
27
+
28
+ ## Querying
29
+
30
+ 1. `flipstream catalog <source>` FIRST — the `name` fields it prints ARE the only valid values for `-d`, `-m`, and filter keys (`label` is for humans; aliases do not exist).
31
+ 2. Build: `flipstream query --source <source> --connection-id <id|name> -d <dim> -m <metric> --json`
32
+ 3. Filters: `-f 'col=a,b'` (list), `-f 'col=from..to'` (inclusive range), `-f 'col=<json>'` (verbatim). Add `--dry-run` to print the request body without sending.
33
+
34
+ ### The filter gotcha (silent, load-bearing)
35
+
36
+ The planner routes by selection LENGTH: `col=[]` (length 0) is inactive and
37
+ routes to the SUMMARY table; `col=[""]` (length 1) is active and routes to the
38
+ DIMENSION's table. They return different numbers and nothing warns. The CLI
39
+ therefore refuses bare `col=` — when you mean one of those, write the JSON form
40
+ explicitly, and don't "fix" the refusal by inventing a value.
41
+
42
+ ## Recipes
43
+
44
+ ```sh
45
+ # Discover, then query
46
+ flipstream catalog --json | jq '.sources[].name'
47
+ flipstream connections list --json | jq '.records[] | {id, name}'
48
+ flipstream query --source gsc --connection-id <id> -d search_date -m clicks --json 2>/dev/null | jq '.rows'
49
+
50
+ # Stream large results
51
+ flipstream workspaces list --ndjson
52
+
53
+ # Inspect a failure programmatically
54
+ flipstream query ... --json 2>/dev/null | jq '.error | {code, next, retryable}'
55
+ ```
@@ -1,4 +0,0 @@
1
- import type { Metadata } from './discovery.js';
2
- export declare function registerClient(meta: Metadata, redirectUri: string, scopes: string[], options?: {
3
- timeoutMs?: number;
4
- }): Promise<string>;
@@ -1,43 +0,0 @@
1
- import { CLIENT_NAME } from '../config/constants.js';
2
- import { AuthFailedError } from '../errors.js';
3
- // Dynamically register a PUBLIC OAuth client (RFC 7591) and return its
4
- // client_id. The CLI never requests, parses, or stores a client secret — the
5
- // return type is the bare client_id string so a refactor cannot leak a secret.
6
- export async function registerClient(meta, redirectUri, scopes, options = {}) {
7
- const timeoutMs = options.timeoutMs ?? 30_000;
8
- const controller = new AbortController();
9
- const timer = setTimeout(() => controller.abort(), timeoutMs);
10
- const body = {
11
- client_name: CLIENT_NAME,
12
- grant_types: ['authorization_code', 'refresh_token'],
13
- redirect_uris: [redirectUri],
14
- response_types: ['code'],
15
- scope: scopes.join(' '),
16
- token_endpoint_auth_method: 'none',
17
- };
18
- let response;
19
- try {
20
- response = await fetch(meta.registrationEndpoint, {
21
- body: JSON.stringify(body),
22
- headers: { accept: 'application/json', 'content-type': 'application/json' },
23
- method: 'POST',
24
- signal: controller.signal,
25
- });
26
- }
27
- catch (error) {
28
- const reason = controller.signal.aborted ? `timed out after ${timeoutMs}ms` : error.message;
29
- throw new AuthFailedError(`Client registration failed: ${reason}`, 'registration_failed');
30
- }
31
- finally {
32
- clearTimeout(timer);
33
- }
34
- if (response.status >= 400) {
35
- const text = await response.text().catch(() => '');
36
- throw new AuthFailedError(`Client registration failed: HTTP ${response.status} ${text}`.trim(), 'registration_failed');
37
- }
38
- const json = (await response.json().catch(() => ({})));
39
- if (typeof json.client_id !== 'string' || json.client_id.length === 0) {
40
- throw new AuthFailedError('Client registration response did not include a client_id', 'registration_failed');
41
- }
42
- return json.client_id;
43
- }