@emaxe/oa 0.2.0 → 0.3.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/CHANGELOG.md +15 -0
- package/CHANGELOG.ru.md +15 -0
- package/README.md +34 -7
- package/README.ru.md +34 -7
- package/dist/__tests__/org-resolution.test.js +60 -0
- package/dist/__tests__/org-resolution.test.js.map +1 -0
- package/dist/__tests__/project-config.test.js +87 -0
- package/dist/__tests__/project-config.test.js.map +1 -0
- package/dist/client.js +6 -2
- package/dist/client.js.map +1 -1
- package/dist/commands/artifacts.js +14 -2
- package/dist/commands/artifacts.js.map +1 -1
- package/dist/commands/login.js +15 -5
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/orgs.js +52 -0
- package/dist/commands/orgs.js.map +1 -0
- package/dist/commands/share.js +8 -3
- package/dist/commands/share.js.map +1 -1
- package/dist/config.js +6 -3
- package/dist/config.js.map +1 -1
- package/dist/index.js +18 -4
- package/dist/index.js.map +1 -1
- package/dist/org.js +31 -0
- package/dist/org.js.map +1 -0
- package/dist/project-config.js +53 -0
- package/dist/project-config.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
## [0.3.0] - 2026-09-11
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- **Personal API Keys**: `oa login` now issues a personal key by default — valid across every team you belong to (with your real role in each), instead of one agent key per team. Use `oa login --agent` for the old behavior: a key locked to one team, for CI and narrowly-scoped use cases.
|
|
16
|
+
- **`oa orgs`**: Lists the teams your key can act in, marking the one currently selected for this project.
|
|
17
|
+
- **`oa use <team>`**: Sets the default team for the current project, saved to a `.oa.json` file next to it (no secrets — safe to commit). Pass `--global` to set it for the whole machine instead.
|
|
18
|
+
- **`--org <team>` flag**: Added to `oa list` and `oa push` to override the resolved default team for a single invocation.
|
|
19
|
+
- **Project-scoped config resolution**: `.oa.json` is found by walking up from the current directory, the same way `.git`/`.eslintrc` are — so the right team is picked up automatically no matter which subdirectory a command runs from.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- Structured handling of the new `org_required` error: when a personal key belongs to more than one team and none is selected, the CLI prints the candidate list and points at `oa use`/`--org` instead of a raw error.
|
|
23
|
+
- Credentials file permissions (`600`) are now re-applied on every login, not just when the file is first created.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
12
27
|
## [0.2.0] - 2026-09-11
|
|
13
28
|
|
|
14
29
|
### Added
|
package/CHANGELOG.ru.md
CHANGED
|
@@ -9,6 +9,21 @@
|
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
## [0.3.0] - 2026-09-11
|
|
13
|
+
|
|
14
|
+
### Добавлено
|
|
15
|
+
- **Личные API-ключи**: `oa login` теперь по умолчанию выпускает личный ключ — действующий во всех ваших командах (с вашей реальной ролью в каждой) вместо отдельного ключа агента на команду. Прежнее поведение (ключ, запертый в одной команде — для CI и узких прав) доступно через `oa login --agent`.
|
|
16
|
+
- **`oa orgs`**: Список команд, доступных ключу, с отметкой текущей выбранной для этого проекта.
|
|
17
|
+
- **`oa use <team>`**: Устанавливает команду по умолчанию для текущего проекта — сохраняется в файл `.oa.json` рядом с ним (без секретов, можно коммитить). Флаг `--global` задаёт значение для всего компьютера.
|
|
18
|
+
- **Флаг `--org <team>`**: Добавлен в `oa list` и `oa push` для разового переопределения выбранной команды.
|
|
19
|
+
- **Разрешение конфигурации по проекту**: `.oa.json` ищется подъёмом вверх по дереву каталогов от текущей директории — так же, как `.git`/`.eslintrc` — поэтому нужная команда подхватывается автоматически из любой вложенной папки.
|
|
20
|
+
|
|
21
|
+
### Изменено
|
|
22
|
+
- Структурированная обработка новой ошибки `org_required`: если у личного ключа несколько команд и ни одна не выбрана, CLI печатает список кандидатов и подсказывает `oa use`/`--org` вместо сырой ошибки.
|
|
23
|
+
- Права на файл с учётными данными (`600`) теперь применяются при каждом логине, а не только при первом создании файла.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
12
27
|
## [0.2.0] - 2026-09-11
|
|
13
28
|
|
|
14
29
|
### Добавлено
|
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ Connect to your Open Artifacts server using the interactive OAuth Device Flow:
|
|
|
42
42
|
oa login --server https://artifacts.your-company.com
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
The CLI outputs a short code (e.g. `ABCD-1234`) and an activation link. Open the link in your browser
|
|
45
|
+
The CLI outputs a short code (e.g. `ABCD-1234`) and an activation link. Open the link in your browser and approve access. This issues a **personal key** by default — it's valid across every team you belong to, not locked to one. Credentials are saved locally to `~/.config/open-artifacts/credentials.json` (`600` permissions).
|
|
46
46
|
|
|
47
47
|
Verify your session at any time:
|
|
48
48
|
|
|
@@ -50,7 +50,18 @@ Verify your session at any time:
|
|
|
50
50
|
oa whoami
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
### 2.
|
|
53
|
+
### 2. Pick a team
|
|
54
|
+
|
|
55
|
+
If you belong to more than one team, tell the CLI which one to use for this project:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
oa orgs # list your teams, with a * next to the current default
|
|
59
|
+
oa use <team> # set the default for this project (writes a secret-free .oa.json you can commit)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
With exactly one team, this step is optional — it's used automatically. Override it for a single command with `--org <team>` on `oa list` / `oa push`, without changing the saved default.
|
|
63
|
+
|
|
64
|
+
### 3. Publish Content
|
|
54
65
|
|
|
55
66
|
```bash
|
|
56
67
|
# Publish an HTML file and get a public shareable URL:
|
|
@@ -76,12 +87,27 @@ Authorizes the CLI with an Open Artifacts server using the OAuth device flow.
|
|
|
76
87
|
```bash
|
|
77
88
|
oa login [options]
|
|
78
89
|
--server <url> Open Artifacts server URL (default: "http://localhost:3000")
|
|
79
|
-
--name <name>
|
|
90
|
+
--name <name> Name to register this device/agent as
|
|
80
91
|
--scopes <scopes> Comma-separated list of scopes (default: "artifacts:read,artifacts:write,shares:write")
|
|
92
|
+
--agent Issue an agent key locked to one team, instead of a personal key spanning all your teams
|
|
81
93
|
```
|
|
82
94
|
|
|
83
95
|
### `oa whoami`
|
|
84
|
-
Displays current credentials, server endpoint,
|
|
96
|
+
Displays current credentials, server endpoint, key type, effective team, and token expiration.
|
|
97
|
+
|
|
98
|
+
### `oa orgs`
|
|
99
|
+
Lists the teams your key can act in, marking the one currently selected for this project.
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
oa orgs [--json]
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### `oa use <team>`
|
|
106
|
+
Sets the default team (by id or slug) for the current project, or for the whole machine.
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
oa use <team> [--global]
|
|
110
|
+
```
|
|
85
111
|
|
|
86
112
|
### `oa push <file>`
|
|
87
113
|
Creates a new artifact or updates an existing one from a local file.
|
|
@@ -95,14 +121,15 @@ oa push <file> [options]
|
|
|
95
121
|
--password <pass> Protect the share link with a password (implies --share)
|
|
96
122
|
--expires <ttl> Share expiration: 1h, 1d, 7d, 30d (implies --share)
|
|
97
123
|
--message <msg> Version commit message
|
|
124
|
+
--org <team> Team id or slug to publish into (overrides the project/machine default)
|
|
98
125
|
--json Output result as JSON
|
|
99
126
|
```
|
|
100
127
|
|
|
101
128
|
### `oa list`
|
|
102
|
-
Lists all artifacts in your active
|
|
129
|
+
Lists all artifacts in your active team.
|
|
103
130
|
|
|
104
131
|
```bash
|
|
105
|
-
oa list [--json]
|
|
132
|
+
oa list [--org <team>] [--json]
|
|
106
133
|
```
|
|
107
134
|
|
|
108
135
|
### `oa get <artifact-id>`
|
|
@@ -147,7 +174,7 @@ export OA_SERVER="https://artifacts.your-company.com"
|
|
|
147
174
|
export OA_TOKEN="oa_live_xxxxxxxxxxxxxxxxxxxxxxxx"
|
|
148
175
|
```
|
|
149
176
|
|
|
150
|
-
|
|
177
|
+
For CI, an agent key (`oa login --agent`, or generated in the web dashboard under **Team > Agents**) is usually the right choice — it's locked to one team, which keeps the blast radius of a leaked CI secret small. A personal key issued from **Settings > Личные API-ключи** also works via `OA_TOKEN`, but it spans every team you belong to.
|
|
151
178
|
|
|
152
179
|
---
|
|
153
180
|
|
package/README.ru.md
CHANGED
|
@@ -42,7 +42,7 @@ npx @emaxe/oa --help
|
|
|
42
42
|
oa login --server https://artifacts.your-company.com
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
Утилита сгенерирует короткий код подтверждения (например, `ABCD-1234`) и ссылку на страницу активации. Перейдите по
|
|
45
|
+
Утилита сгенерирует короткий код подтверждения (например, `ABCD-1234`) и ссылку на страницу активации. Перейдите по ссылке и разрешите доступ. По умолчанию выпускается **личный ключ** — он действует во всех ваших командах, а не запертый в одной. Токен сохранится локально в `~/.config/open-artifacts/credentials.json` с правами `600`.
|
|
46
46
|
|
|
47
47
|
Проверить статус сессии в любой момент:
|
|
48
48
|
|
|
@@ -50,7 +50,18 @@ oa login --server https://artifacts.your-company.com
|
|
|
50
50
|
oa whoami
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
### 2.
|
|
53
|
+
### 2. Выбор команды
|
|
54
|
+
|
|
55
|
+
Если вы состоите в нескольких командах, укажите CLI, какую использовать для этого проекта:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
oa orgs # список ваших команд с отметкой * у текущей по умолчанию
|
|
59
|
+
oa use <team> # задать команду по умолчанию для проекта (пишет .oa.json без секретов, можно коммитить)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Если команда одна — этот шаг не нужен, она подставится автоматически. Переопределить для одного вызова можно флагом `--org <team>` у `oa list`/`oa push`, не меняя сохранённое значение по умолчанию.
|
|
63
|
+
|
|
64
|
+
### 3. Публикация файлов
|
|
54
65
|
|
|
55
66
|
```bash
|
|
56
67
|
# Опубликовать HTML-страницу и получить публичную ссылку:
|
|
@@ -76,12 +87,27 @@ oa push diagram.svg --title "Схема базы данных" --share
|
|
|
76
87
|
```bash
|
|
77
88
|
oa login [options]
|
|
78
89
|
--server <url> URL сервера Open Artifacts (по умолчанию: "http://localhost:3000")
|
|
79
|
-
--name <name> Имя регистрируемого
|
|
90
|
+
--name <name> Имя регистрируемого устройства/агента
|
|
80
91
|
--scopes <scopes> Список запрашиваемых прав через запятую (по умолчанию: "artifacts:read,artifacts:write,shares:write")
|
|
92
|
+
--agent Выпустить ключ агента, запертый в одной команде, вместо личного ключа на все ваши команды
|
|
81
93
|
```
|
|
82
94
|
|
|
83
95
|
### `oa whoami`
|
|
84
|
-
Показывает текущие
|
|
96
|
+
Показывает текущие учётные данные, адрес сервера, тип ключа, выбранную команду и статус токена.
|
|
97
|
+
|
|
98
|
+
### `oa orgs`
|
|
99
|
+
Список команд, доступных ключу, с отметкой текущей выбранной для этого проекта.
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
oa orgs [--json]
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### `oa use <team>`
|
|
106
|
+
Задаёт команду по умолчанию (по id или slug) для текущего проекта или для всего компьютера.
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
oa use <team> [--global]
|
|
110
|
+
```
|
|
85
111
|
|
|
86
112
|
### `oa push <file>`
|
|
87
113
|
Создает новый артефакт или обновляет существующий из локального файла.
|
|
@@ -95,14 +121,15 @@ oa push <file> [options]
|
|
|
95
121
|
--password <pass> Защитить ссылку паролем (включает --share)
|
|
96
122
|
--expires <ttl> Срок действия ссылки: 1h, 1d, 7d, 30d (включает --share)
|
|
97
123
|
--message <msg> Сообщение версии
|
|
124
|
+
--org <team> Команда для публикации (переопределяет значение по умолчанию проекта/машины)
|
|
98
125
|
--json Вывод результата в формате JSON
|
|
99
126
|
```
|
|
100
127
|
|
|
101
128
|
### `oa list`
|
|
102
|
-
Выводит список всех артефактов в текущей
|
|
129
|
+
Выводит список всех артефактов в текущей команде.
|
|
103
130
|
|
|
104
131
|
```bash
|
|
105
|
-
oa list [--json]
|
|
132
|
+
oa list [--org <team>] [--json]
|
|
106
133
|
```
|
|
107
134
|
|
|
108
135
|
### `oa get <artifact-id>`
|
|
@@ -147,7 +174,7 @@ export OA_SERVER="https://artifacts.your-company.com"
|
|
|
147
174
|
export OA_TOKEN="oa_live_xxxxxxxxxxxxxxxxxxxxxxxx"
|
|
148
175
|
```
|
|
149
176
|
|
|
150
|
-
|
|
177
|
+
Для CI обычно правильный выбор — ключ агента (`oa login --agent`, либо выпущенный в панели управления в разделе **Команда > Агенты**): он заперт в одной команде, что ограничивает ущерб от утечки CI-секрета. Личный ключ из **Настройки > Личные API-ключи** тоже подходит для `OA_TOKEN`, но действует во всех ваших командах.
|
|
151
178
|
|
|
152
179
|
---
|
|
153
180
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
5
|
+
import { resolveOrg } from "../org.js";
|
|
6
|
+
let dir;
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
if (dir)
|
|
9
|
+
rmSync(dir, { recursive: true, force: true });
|
|
10
|
+
dir = undefined;
|
|
11
|
+
});
|
|
12
|
+
function makeTmpDir() {
|
|
13
|
+
dir = mkdtempSync(join(tmpdir(), "oa-org-resolution-"));
|
|
14
|
+
return dir;
|
|
15
|
+
}
|
|
16
|
+
const userCreds = { server: "https://oa.example.com", token: "oa_live_x", expiresAt: null, kind: "user", userId: "u1" };
|
|
17
|
+
const legacyAgentCreds = { server: "https://oa.example.com", token: "oa_live_x", expiresAt: null, agentId: "a1", orgId: "org-legacy" };
|
|
18
|
+
describe("resolveOrg priority", () => {
|
|
19
|
+
it("--org flag wins over everything else", () => {
|
|
20
|
+
const root = makeTmpDir();
|
|
21
|
+
writeFileSync(join(root, ".oa.json"), JSON.stringify({ orgId: "org-project" }));
|
|
22
|
+
const res = resolveOrg({ flag: "org-flag", cwd: root, env: { OA_ORG: "org-env" }, creds: userCreds });
|
|
23
|
+
expect(res).toEqual({ orgId: "org-flag", source: "flag" });
|
|
24
|
+
});
|
|
25
|
+
it("OA_ORG env wins over the project config", () => {
|
|
26
|
+
const root = makeTmpDir();
|
|
27
|
+
writeFileSync(join(root, ".oa.json"), JSON.stringify({ orgId: "org-project" }));
|
|
28
|
+
const res = resolveOrg({ cwd: root, env: { OA_ORG: "org-env" }, creds: userCreds });
|
|
29
|
+
expect(res).toEqual({ orgId: "org-env", source: "env" });
|
|
30
|
+
});
|
|
31
|
+
it("falls back to the project's .oa.json when no flag or env is given", () => {
|
|
32
|
+
const root = makeTmpDir();
|
|
33
|
+
writeFileSync(join(root, ".oa.json"), JSON.stringify({ orgId: "org-project", server: "https://oa.example.com" }));
|
|
34
|
+
const res = resolveOrg({ cwd: root, env: {}, creds: userCreds });
|
|
35
|
+
expect(res).toEqual({ orgId: "org-project", source: "project", configPath: join(root, ".oa.json") });
|
|
36
|
+
});
|
|
37
|
+
it("ignores a project config written for a different server", () => {
|
|
38
|
+
const root = makeTmpDir();
|
|
39
|
+
writeFileSync(join(root, ".oa.json"), JSON.stringify({ orgId: "org-project", server: "https://other.example.com" }));
|
|
40
|
+
const res = resolveOrg({ cwd: root, env: {}, creds: userCreds });
|
|
41
|
+
expect(res).toEqual({ source: "none" });
|
|
42
|
+
});
|
|
43
|
+
it("falls back to a legacy agent credentials file's locked org when nothing else resolves", () => {
|
|
44
|
+
const root = makeTmpDir();
|
|
45
|
+
const res = resolveOrg({ cwd: root, env: {}, creds: legacyAgentCreds });
|
|
46
|
+
expect(res).toEqual({ orgId: "org-legacy", source: "credentials" });
|
|
47
|
+
});
|
|
48
|
+
it("never falls back to credentials.orgId for a personal (kind: user) key", () => {
|
|
49
|
+
const root = makeTmpDir();
|
|
50
|
+
const personalWithOrg = { ...userCreds, orgId: "should-not-be-used" };
|
|
51
|
+
const res = resolveOrg({ cwd: root, env: {}, creds: personalWithOrg });
|
|
52
|
+
expect(res).toEqual({ source: "none" });
|
|
53
|
+
});
|
|
54
|
+
it("resolves to 'none' with no flag, env, project config, or usable credentials fallback", () => {
|
|
55
|
+
const root = makeTmpDir();
|
|
56
|
+
const res = resolveOrg({ cwd: root, env: {}, creds: userCreds });
|
|
57
|
+
expect(res).toEqual({ source: "none" });
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
//# sourceMappingURL=org-resolution.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org-resolution.test.js","sourceRoot":"","sources":["../../src/__tests__/org-resolution.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
5
|
+
import { findProjectConfig, projectConfigTarget, writeProjectConfig } from "../project-config.js";
|
|
6
|
+
let dir;
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
if (dir)
|
|
9
|
+
rmSync(dir, { recursive: true, force: true });
|
|
10
|
+
dir = undefined;
|
|
11
|
+
});
|
|
12
|
+
function makeTmpDir() {
|
|
13
|
+
dir = mkdtempSync(join(tmpdir(), "oa-project-config-"));
|
|
14
|
+
return dir;
|
|
15
|
+
}
|
|
16
|
+
describe("findProjectConfig", () => {
|
|
17
|
+
it("returns null when no .oa.json exists anywhere up to the filesystem root", () => {
|
|
18
|
+
const root = makeTmpDir();
|
|
19
|
+
const nested = join(root, "a", "b");
|
|
20
|
+
mkdirSync(nested, { recursive: true });
|
|
21
|
+
expect(findProjectConfig(nested)).toBeNull();
|
|
22
|
+
});
|
|
23
|
+
it("finds .oa.json in the exact cwd", () => {
|
|
24
|
+
const root = makeTmpDir();
|
|
25
|
+
writeFileSync(join(root, ".oa.json"), JSON.stringify({ orgId: "org-1" }));
|
|
26
|
+
const found = findProjectConfig(root);
|
|
27
|
+
expect(found?.config.orgId).toBe("org-1");
|
|
28
|
+
});
|
|
29
|
+
it("walks up from a nested subdirectory to find .oa.json in an ancestor", () => {
|
|
30
|
+
const root = makeTmpDir();
|
|
31
|
+
const nested = join(root, "a", "b", "c");
|
|
32
|
+
mkdirSync(nested, { recursive: true });
|
|
33
|
+
writeFileSync(join(root, ".oa.json"), JSON.stringify({ orgId: "org-root" }));
|
|
34
|
+
const found = findProjectConfig(nested);
|
|
35
|
+
expect(found?.config.orgId).toBe("org-root");
|
|
36
|
+
expect(found?.path).toBe(join(root, ".oa.json"));
|
|
37
|
+
});
|
|
38
|
+
it("prefers the nearest .oa.json over one further up the tree", () => {
|
|
39
|
+
const root = makeTmpDir();
|
|
40
|
+
const nested = join(root, "a", "b");
|
|
41
|
+
mkdirSync(nested, { recursive: true });
|
|
42
|
+
writeFileSync(join(root, ".oa.json"), JSON.stringify({ orgId: "org-root" }));
|
|
43
|
+
writeFileSync(join(nested, ".oa.json"), JSON.stringify({ orgId: "org-nested" }));
|
|
44
|
+
expect(findProjectConfig(nested)?.config.orgId).toBe("org-nested");
|
|
45
|
+
});
|
|
46
|
+
it("warns and returns null instead of throwing on invalid JSON", () => {
|
|
47
|
+
const root = makeTmpDir();
|
|
48
|
+
writeFileSync(join(root, ".oa.json"), "{ not valid json");
|
|
49
|
+
expect(findProjectConfig(root)).toBeNull();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
describe("projectConfigTarget", () => {
|
|
53
|
+
it("returns the path of an existing .oa.json when one is found", () => {
|
|
54
|
+
const root = makeTmpDir();
|
|
55
|
+
writeFileSync(join(root, ".oa.json"), JSON.stringify({ orgId: "org-1" }));
|
|
56
|
+
expect(projectConfigTarget(root)).toBe(join(root, ".oa.json"));
|
|
57
|
+
});
|
|
58
|
+
it("targets the git root when no .oa.json exists yet", () => {
|
|
59
|
+
const root = makeTmpDir();
|
|
60
|
+
mkdirSync(join(root, ".git"));
|
|
61
|
+
const nested = join(root, "src", "lib");
|
|
62
|
+
mkdirSync(nested, { recursive: true });
|
|
63
|
+
expect(projectConfigTarget(nested)).toBe(join(root, ".oa.json"));
|
|
64
|
+
});
|
|
65
|
+
it("falls back to cwd when neither .oa.json nor a .git root is found", () => {
|
|
66
|
+
const root = makeTmpDir();
|
|
67
|
+
const nested = join(root, "a");
|
|
68
|
+
mkdirSync(nested, { recursive: true });
|
|
69
|
+
expect(projectConfigTarget(nested)).toBe(join(nested, ".oa.json"));
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe("writeProjectConfig", () => {
|
|
73
|
+
it("creates a new file with the given patch", () => {
|
|
74
|
+
const root = makeTmpDir();
|
|
75
|
+
const path = join(root, ".oa.json");
|
|
76
|
+
writeProjectConfig(path, { orgId: "org-1", orgSlug: "acme" });
|
|
77
|
+
expect(findProjectConfig(root)?.config).toEqual({ orgId: "org-1", orgSlug: "acme" });
|
|
78
|
+
});
|
|
79
|
+
it("merges into an existing file rather than replacing it", () => {
|
|
80
|
+
const root = makeTmpDir();
|
|
81
|
+
const path = join(root, ".oa.json");
|
|
82
|
+
writeFileSync(path, JSON.stringify({ server: "https://oa.example.com" }));
|
|
83
|
+
writeProjectConfig(path, { orgId: "org-1" });
|
|
84
|
+
expect(findProjectConfig(root)?.config).toEqual({ server: "https://oa.example.com", orgId: "org-1" });
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=project-config.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-config.test.js","sourceRoot":"","sources":["../../src/__tests__/project-config.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAElG,IAAI,GAAuB,CAAC;AAE5B,SAAS,CAAC,GAAG,EAAE;IACb,IAAI,GAAG;QAAE,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,GAAG,GAAG,SAAS,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,SAAS,UAAU;IACjB,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,oBAAoB,CAAC,CAAC,CAAC;IACxD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;QACjF,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACpC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QAC1E,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACzC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;QAE7E,MAAM,KAAK,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACpC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;QAC7E,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;QAEjF,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,kBAAkB,CAAC,CAAC;QAC1D,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QAC1E,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QACxC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEvC,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC/B,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACpC,kBAAkB,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACpC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAAC,CAAC;QAC1E,kBAAkB,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7C,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,wBAAwB,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IACxG,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/client.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
export class CliApiError extends Error {
|
|
2
2
|
code;
|
|
3
3
|
status;
|
|
4
|
-
|
|
4
|
+
body;
|
|
5
|
+
constructor(code, message, status,
|
|
6
|
+
/** The parsed error body, e.g. `{ error: { code, message, orgs } }` for `org_required`. */
|
|
7
|
+
body) {
|
|
5
8
|
super(message);
|
|
6
9
|
this.code = code;
|
|
7
10
|
this.status = status;
|
|
11
|
+
this.body = body;
|
|
8
12
|
}
|
|
9
13
|
}
|
|
10
14
|
export function makeClient(creds) {
|
|
@@ -20,7 +24,7 @@ export function makeClient(creds) {
|
|
|
20
24
|
});
|
|
21
25
|
const body = (await res.json().catch(() => ({})));
|
|
22
26
|
if (!res.ok) {
|
|
23
|
-
throw new CliApiError(body?.error?.code ?? "unknown_error", body?.error?.message ?? res.statusText, res.status);
|
|
27
|
+
throw new CliApiError(body?.error?.code ?? "unknown_error", body?.error?.message ?? res.statusText, res.status, body);
|
|
24
28
|
}
|
|
25
29
|
return body;
|
|
26
30
|
}
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAUA,MAAM,OAAO,WAAY,SAAQ,KAAK;IAE3B;IAEA;IAEA;IALT,YACS,IAAY,EACnB,OAAe,EACR,MAAc;IACrB,2FAA2F;IACpF,IAA0E;QAEjF,KAAK,CAAC,OAAO,CAAC,CAAC;QANR,SAAI,GAAJ,IAAI,CAAQ;QAEZ,WAAM,GAAN,MAAM,CAAQ;QAEd,SAAI,GAAJ,IAAI,CAAsE;IAGnF,CAAC;CACF;AAED,MAAM,UAAU,UAAU,CAAC,KAAkB;IAC3C,MAAM,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC;IAEzD,KAAK,UAAU,OAAO,CAAI,IAAY,EAAE,UAAuB,EAAE;QAC/D,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,EAAE;YACxC,GAAG,OAAO;YACV,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,KAAK,CAAC,KAAK,EAAE;gBACtC,GAAG,OAAO,CAAC,OAAO;aACnB;SACF,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAwE,CAAC;QACzH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,IAAI,eAAe,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,IAAI,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACxH,CAAC;QACD,OAAO,IAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,GAAG,EAAE,CAAI,IAAY,EAAE,EAAE,CAAC,OAAO,CAAI,IAAI,CAAC;QAC1C,IAAI,EAAE,CAAI,IAAY,EAAE,IAAc,EAAE,EAAE,CAAC,OAAO,CAAI,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;QAC9H,KAAK,EAAE,CAAI,IAAY,EAAE,IAAc,EAAE,OAAgC,EAAE,EAAE,CAC3E,OAAO,CAAI,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;QAC5E,MAAM,EAAE,CAAI,IAAY,EAAE,EAAE,CAAC,OAAO,CAAI,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;KACpE,CAAC;AACJ,CAAC"}
|
|
@@ -2,6 +2,7 @@ import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { extname, basename } from "node:path";
|
|
3
3
|
import { requireCredentials } from "../config.js";
|
|
4
4
|
import { makeClient, CliApiError } from "../client.js";
|
|
5
|
+
import { resolveOrg } from "../org.js";
|
|
5
6
|
export function inferKind(filePath) {
|
|
6
7
|
const ext = extname(filePath).toLowerCase();
|
|
7
8
|
if (ext === ".md" || ext === ".markdown")
|
|
@@ -19,8 +20,9 @@ function die(message) {
|
|
|
19
20
|
export async function listCommand(opts) {
|
|
20
21
|
const creds = requireCredentials();
|
|
21
22
|
const client = makeClient(creds);
|
|
23
|
+
const org = resolveOrg({ flag: opts.org, creds });
|
|
22
24
|
try {
|
|
23
|
-
const data = await client.get(`/artifacts?orgId=${
|
|
25
|
+
const data = await client.get(`/artifacts${org.orgId ? `?orgId=${org.orgId}` : ""}`);
|
|
24
26
|
if (opts.json) {
|
|
25
27
|
console.log(JSON.stringify(data.artifacts, null, 2));
|
|
26
28
|
return;
|
|
@@ -47,7 +49,10 @@ export async function pushCommand(filePath, opts) {
|
|
|
47
49
|
await client.patch(`/artifacts/${artifactId}`, { content, message: opts.message });
|
|
48
50
|
}
|
|
49
51
|
else {
|
|
50
|
-
|
|
52
|
+
// Updating an existing artifact never needs an org (the id alone identifies it) — only
|
|
53
|
+
// resolve one when we're about to create.
|
|
54
|
+
const org = resolveOrg({ flag: opts.org, creds });
|
|
55
|
+
const res = await client.post(`/artifacts${org.orgId ? `?orgId=${org.orgId}` : ""}`, {
|
|
51
56
|
title,
|
|
52
57
|
kind,
|
|
53
58
|
content,
|
|
@@ -104,6 +109,9 @@ export async function rmCommand(id) {
|
|
|
104
109
|
handleError(err);
|
|
105
110
|
}
|
|
106
111
|
}
|
|
112
|
+
export function formatOrgChoices(orgs) {
|
|
113
|
+
return orgs.map((o) => ` ${o.slug.padEnd(24)} ${o.role.padEnd(7)} ${o.name}`).join("\n");
|
|
114
|
+
}
|
|
107
115
|
export function handleError(err) {
|
|
108
116
|
if (err instanceof CliApiError) {
|
|
109
117
|
if (err.code === "key_expired") {
|
|
@@ -115,6 +123,10 @@ export function handleError(err) {
|
|
|
115
123
|
if (err.code === "version_conflict") {
|
|
116
124
|
die("Someone else changed this artifact since you last read it (409). Fetch the latest with `oa get` and retry.");
|
|
117
125
|
}
|
|
126
|
+
if (err.code === "org_required") {
|
|
127
|
+
const orgs = err.body?.error?.orgs ?? [];
|
|
128
|
+
die(`Not sure which team to publish to — you belong to several:\n${formatOrgChoices(orgs)}\n\nRun \`oa use <slug>\` to set a default for this project, or pass --org <slug>.`);
|
|
129
|
+
}
|
|
118
130
|
die(`Error (${err.code}): ${err.message}`);
|
|
119
131
|
}
|
|
120
132
|
throw err;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/commands/artifacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/commands/artifacts.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/login.js
CHANGED
|
@@ -5,11 +5,14 @@ function sleep(ms) {
|
|
|
5
5
|
}
|
|
6
6
|
export async function login(opts) {
|
|
7
7
|
const server = opts.server.replace(/\/$/, "");
|
|
8
|
-
|
|
8
|
+
// Personal (spans every team the approver belongs to) is the default — `--agent` is for CI and
|
|
9
|
+
// other narrowly-scoped, single-team use cases.
|
|
10
|
+
const grantKind = opts.agent ? "agent" : "user";
|
|
11
|
+
const agentName = opts.name ?? (grantKind === "agent" ? `cli-${hostname()}` : hostname());
|
|
9
12
|
const codeRes = await fetch(`${server}/api/v1/oauth/device/code`, {
|
|
10
13
|
method: "POST",
|
|
11
14
|
headers: { "Content-Type": "application/json" },
|
|
12
|
-
body: JSON.stringify({ agentName, scopes: opts.scopes }),
|
|
15
|
+
body: JSON.stringify({ agentName, scopes: opts.scopes, grantKind }),
|
|
13
16
|
});
|
|
14
17
|
if (!codeRes.ok) {
|
|
15
18
|
console.error(`Failed to start device authorization: ${codeRes.status} ${await codeRes.text()}`);
|
|
@@ -18,7 +21,7 @@ export async function login(opts) {
|
|
|
18
21
|
const device = (await codeRes.json());
|
|
19
22
|
console.log(`\nTo authorize this device, open:\n\n ${device.verification_uri_complete}\n`);
|
|
20
23
|
console.log(`If prompted, enter code: ${device.user_code}\n`);
|
|
21
|
-
console.log("Waiting for approval...");
|
|
24
|
+
console.log(grantKind === "user" ? "Requesting personal access to all your teams. Waiting for approval..." : "Waiting for approval...");
|
|
22
25
|
const deadline = Date.now() + device.expires_in * 1000;
|
|
23
26
|
let interval = device.interval * 1000;
|
|
24
27
|
while (Date.now() < deadline) {
|
|
@@ -30,8 +33,15 @@ export async function login(opts) {
|
|
|
30
33
|
});
|
|
31
34
|
const body = (await tokenRes.json());
|
|
32
35
|
if ("api_key" in body) {
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
if (body.grant_kind === "user") {
|
|
37
|
+
saveCredentials({ server, token: body.api_key, expiresAt: body.expires_at, kind: "user", userId: body.user_id });
|
|
38
|
+
console.log("\nLogged in with a personal key, valid across every team you belong to.");
|
|
39
|
+
console.log("Run `oa orgs` to see them, or `oa use <team>` to pick a default for this project.");
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
saveCredentials({ server, token: body.api_key, expiresAt: body.expires_at, kind: "agent", agentId: body.agent_id, orgId: body.org_id });
|
|
43
|
+
console.log(`\nLogged in. Credentials saved to ~/.config/open-artifacts/credentials.json`);
|
|
44
|
+
}
|
|
35
45
|
return;
|
|
36
46
|
}
|
|
37
47
|
if (body.error === "slow_down") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { requireCredentials, saveCredentials } from "../config.js";
|
|
2
|
+
import { makeClient } from "../client.js";
|
|
3
|
+
import { resolveOrg } from "../org.js";
|
|
4
|
+
import { projectConfigTarget, writeProjectConfig } from "../project-config.js";
|
|
5
|
+
import { handleError, formatOrgChoices } from "./artifacts.js";
|
|
6
|
+
export async function orgsCommand(opts) {
|
|
7
|
+
const creds = requireCredentials();
|
|
8
|
+
const client = makeClient(creds);
|
|
9
|
+
try {
|
|
10
|
+
const data = await client.get("/me/orgs");
|
|
11
|
+
if (opts.json) {
|
|
12
|
+
console.log(JSON.stringify(data.orgs, null, 2));
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const current = resolveOrg({ creds });
|
|
16
|
+
if (data.orgs.length === 0) {
|
|
17
|
+
console.log("No teams found.");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
console.log(data.orgs
|
|
21
|
+
.map((o) => `${o.orgId === current.orgId ? "* " : " "}${o.slug.padEnd(24)} ${o.role.padEnd(7)} ${o.name}`)
|
|
22
|
+
.join("\n"));
|
|
23
|
+
console.log(current.orgId ? `\nCurrent: ${current.orgId} (from ${current.source})` : "\nNo default team selected for this project — run `oa use <slug>`.");
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
handleError(err);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export async function useCommand(idOrSlug, opts) {
|
|
30
|
+
const creds = requireCredentials();
|
|
31
|
+
const client = makeClient(creds);
|
|
32
|
+
try {
|
|
33
|
+
const data = await client.get("/me/orgs");
|
|
34
|
+
const match = data.orgs.find((o) => o.orgId === idOrSlug || o.slug === idOrSlug);
|
|
35
|
+
if (!match) {
|
|
36
|
+
console.error(`No team matching "${idOrSlug}". Run \`oa orgs\` to see what you belong to:\n${formatOrgChoices(data.orgs)}`);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
if (opts.global) {
|
|
40
|
+
saveCredentials({ ...creds, orgId: match.orgId });
|
|
41
|
+
console.log(`Default team for this machine set to ${match.name} (${match.slug}).`);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const target = projectConfigTarget(process.cwd());
|
|
45
|
+
writeProjectConfig(target, { orgId: match.orgId, orgSlug: match.slug, server: creds.server });
|
|
46
|
+
console.log(`Default team for this project set to ${match.name} (${match.slug}) — saved to ${target}`);
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
handleError(err);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=orgs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orgs.js","sourceRoot":"","sources":["../../src/commands/orgs.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/share.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { requireCredentials } from "../config.js";
|
|
2
2
|
import { makeClient } from "../client.js";
|
|
3
|
+
import { resolveOrg } from "../org.js";
|
|
3
4
|
import { handleError } from "./artifacts.js";
|
|
4
5
|
export async function shareCommand(id, opts) {
|
|
5
6
|
const creds = requireCredentials();
|
|
@@ -31,12 +32,16 @@ export async function unshareCommand(shareId) {
|
|
|
31
32
|
export async function whoamiCommand() {
|
|
32
33
|
const creds = requireCredentials();
|
|
33
34
|
const client = makeClient(creds);
|
|
35
|
+
const kind = creds.kind ?? "agent"; // pre-0.3.0 credentials files never recorded kind — always an agent grant
|
|
36
|
+
const org = resolveOrg({ creds });
|
|
34
37
|
console.log(`Server: ${creds.server}`);
|
|
35
|
-
console.log(`
|
|
36
|
-
|
|
38
|
+
console.log(`Auth: ${kind === "user" ? "personal key (all your teams)" : "agent key"}`);
|
|
39
|
+
if (kind === "agent" && creds.agentId)
|
|
40
|
+
console.log(`Agent: ${creds.agentId}`);
|
|
37
41
|
console.log(`Expires: ${creds.expiresAt ?? "never"}`);
|
|
42
|
+
console.log(`Team: ${org.orgId ? `${org.orgId} (from ${org.source})` : "not selected — run `oa orgs` / `oa use <team>`"}`);
|
|
38
43
|
try {
|
|
39
|
-
await client.get(`/artifacts?orgId=${
|
|
44
|
+
await client.get(`/artifacts${org.orgId ? `?orgId=${org.orgId}` : ""}`);
|
|
40
45
|
console.log("Token is valid.");
|
|
41
46
|
}
|
|
42
47
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"share.js","sourceRoot":"","sources":["../../src/commands/share.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,EAAU,EAAE,IAA+D;IAC5G,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAiC,cAAc,EAAE,SAAS,EAAE;YACvF,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ;YAC3C,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;SAC3D,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,WAAW,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAe;IAClD,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,MAAM,CAAC,WAAW,OAAO,EAAE,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,WAAW,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"share.js","sourceRoot":"","sources":["../../src/commands/share.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
const CONFIG_DIR = join(homedir(), ".config", "open-artifacts");
|
|
@@ -7,15 +7,18 @@ export function loadCredentials() {
|
|
|
7
7
|
const envToken = process.env.OA_TOKEN;
|
|
8
8
|
const envServer = process.env.OA_SERVER;
|
|
9
9
|
if (envToken) {
|
|
10
|
-
return { server: envServer ?? "http://localhost:3000", token: envToken,
|
|
10
|
+
return { server: envServer ?? "http://localhost:3000", token: envToken, expiresAt: null };
|
|
11
11
|
}
|
|
12
12
|
if (!existsSync(CREDENTIALS_PATH))
|
|
13
13
|
return null;
|
|
14
14
|
return JSON.parse(readFileSync(CREDENTIALS_PATH, "utf8"));
|
|
15
15
|
}
|
|
16
16
|
export function saveCredentials(creds) {
|
|
17
|
-
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
17
|
+
mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
18
18
|
writeFileSync(CREDENTIALS_PATH, JSON.stringify(creds, null, 2), { mode: 0o600 });
|
|
19
|
+
// `mode` above is only honored when the file is newly created — chmod explicitly so an
|
|
20
|
+
// overwrite of a pre-existing (possibly more permissive) file still ends up locked down.
|
|
21
|
+
chmodSync(CREDENTIALS_PATH, 0o600);
|
|
19
22
|
}
|
|
20
23
|
export function requireCredentials() {
|
|
21
24
|
const creds = loadCredentials();
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAcjC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC;AAChE,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;AAE9D,MAAM,UAAU,eAAe;IAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;IACtC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;IACxC,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,EAAE,MAAM,EAAE,SAAS,IAAI,uBAAuB,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC5F,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAkB;IAChD,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,aAAa,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACjF,uFAAuF;IACvF,yFAAyF;IACzF,SAAS,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,6EAA6E,CAAC,CAAC;QAC7F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QACzE,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,14 +4,16 @@ import { isValidScope, API_KEY_SCOPES } from "./scopes.js";
|
|
|
4
4
|
import { login } from "./commands/login.js";
|
|
5
5
|
import { listCommand, pushCommand, getCommand, rmCommand } from "./commands/artifacts.js";
|
|
6
6
|
import { shareCommand, unshareCommand, whoamiCommand } from "./commands/share.js";
|
|
7
|
+
import { orgsCommand, useCommand } from "./commands/orgs.js";
|
|
7
8
|
const program = new Command();
|
|
8
|
-
program.name("oa").description("CLI for Open Artifacts — self-hosted artifact hosting for AI agents").version("0.
|
|
9
|
+
program.name("oa").description("CLI for Open Artifacts — self-hosted artifact hosting for AI agents").version("0.3.0");
|
|
9
10
|
program
|
|
10
11
|
.command("login")
|
|
11
12
|
.description("Authorize this device via OAuth device flow and save credentials")
|
|
12
13
|
.option("--server <url>", "Open Artifacts server URL", "http://localhost:3000")
|
|
13
|
-
.option("--name <name>", "Name to register this agent as")
|
|
14
|
+
.option("--name <name>", "Name to register this agent/device as")
|
|
14
15
|
.option("--scopes <scopes>", "Comma-separated scopes to request", "artifacts:read,artifacts:write,shares:write")
|
|
16
|
+
.option("--agent", "Issue an agent key locked to one team, instead of a personal key spanning all your teams")
|
|
15
17
|
.action(async (opts) => {
|
|
16
18
|
const scopes = String(opts.scopes).split(",").map((s) => s.trim());
|
|
17
19
|
for (const scope of scopes) {
|
|
@@ -20,13 +22,24 @@ program
|
|
|
20
22
|
process.exit(1);
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
|
-
await login({ server: opts.server, name: opts.name, scopes });
|
|
25
|
+
await login({ server: opts.server, name: opts.name, scopes, agent: opts.agent });
|
|
24
26
|
});
|
|
25
27
|
program.command("whoami").description("Show the current credentials and verify they work").action(whoamiCommand);
|
|
28
|
+
program
|
|
29
|
+
.command("orgs")
|
|
30
|
+
.description("List the teams your key can act in, and which one is currently selected")
|
|
31
|
+
.option("--json", "Output raw JSON")
|
|
32
|
+
.action(orgsCommand);
|
|
33
|
+
program
|
|
34
|
+
.command("use <team>")
|
|
35
|
+
.description("Set the default team (by id or slug) for this project, or --global for this machine")
|
|
36
|
+
.option("--global", "Set the default for this machine instead of writing .oa.json in the project")
|
|
37
|
+
.action(useCommand);
|
|
26
38
|
program
|
|
27
39
|
.command("list")
|
|
28
|
-
.description("List artifacts in your
|
|
40
|
+
.description("List artifacts in your team")
|
|
29
41
|
.option("--json", "Output raw JSON")
|
|
42
|
+
.option("--org <team>", "Team id or slug (overrides the project/machine default)")
|
|
30
43
|
.action(listCommand);
|
|
31
44
|
program
|
|
32
45
|
.command("push <file>")
|
|
@@ -38,6 +51,7 @@ program
|
|
|
38
51
|
.option("--password <password>", "Create a password-protected share instead of a public one (implies --share)")
|
|
39
52
|
.option("--message <message>", "Version message")
|
|
40
53
|
.option("--json", "Output raw JSON")
|
|
54
|
+
.option("--org <team>", "Team id or slug to publish into (overrides the project/machine default)")
|
|
41
55
|
.action((file, opts) => pushCommand(file, { ...opts, share: opts.share || !!opts.password }));
|
|
42
56
|
program
|
|
43
57
|
.command("get <id>")
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAC1F,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/org.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { findProjectConfig } from "./project-config.js";
|
|
2
|
+
/**
|
|
3
|
+
* Priority: --org flag > OA_ORG env > .oa.json found by walking up from cwd > a pre-0.3.0
|
|
4
|
+
* (agent-only) credentials file's locked org. Resolving to nothing isn't an error — the server
|
|
5
|
+
* auto-picks when a personal key's holder belongs to exactly one team, or returns `org_required`
|
|
6
|
+
* with the candidate list otherwise (see services/org-scope.ts on the server).
|
|
7
|
+
*/
|
|
8
|
+
export function resolveOrg(opts) {
|
|
9
|
+
if (opts.flag)
|
|
10
|
+
return { orgId: opts.flag, source: "flag" };
|
|
11
|
+
const env = opts.env ?? process.env;
|
|
12
|
+
if (env.OA_ORG)
|
|
13
|
+
return { orgId: env.OA_ORG, source: "env" };
|
|
14
|
+
const project = findProjectConfig(opts.cwd);
|
|
15
|
+
if (project?.config.orgId) {
|
|
16
|
+
// An orgId only makes sense on the server it was written for. A mismatch would otherwise
|
|
17
|
+
// surface as an opaque "forbidden" from the API instead of a clear "wrong server" warning.
|
|
18
|
+
if (project.config.server && opts.creds?.server && project.config.server !== opts.creds.server) {
|
|
19
|
+
console.error(`Warning: ${project.path} was written for ${project.config.server}, not ${opts.creds.server} — ignoring its orgId.`);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
return { orgId: project.config.orgId, source: "project", configPath: project.path };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// A pre-0.3.0 credentials file has no `kind` and always carries the single org its agent key
|
|
26
|
+
// was locked to. A personal (kind: "user") key has no such single org to fall back to.
|
|
27
|
+
if (!opts.creds?.kind && opts.creds?.orgId)
|
|
28
|
+
return { orgId: opts.creds.orgId, source: "credentials" };
|
|
29
|
+
return { source: "none" };
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=org.js.map
|
package/dist/org.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org.js","sourceRoot":"","sources":["../src/org.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAiBxD;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,IAAoB;IAC7C,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAE3D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACpC,IAAI,GAAG,CAAC,MAAM;QAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAE5D,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QAC1B,yFAAyF;QACzF,2FAA2F;QAC3F,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YAC/F,OAAO,CAAC,KAAK,CAAC,YAAY,OAAO,CAAC,IAAI,oBAAoB,OAAO,CAAC,MAAM,CAAC,MAAM,SAAS,IAAI,CAAC,KAAK,CAAC,MAAM,wBAAwB,CAAC,CAAC;QACrI,CAAC;aAAM,CAAC;YACN,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;QACtF,CAAC;IACH,CAAC;IAED,6FAA6F;IAC7F,uFAAuF;IACvF,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,KAAK;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IAEtG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
export const PROJECT_CONFIG_FILENAME = ".oa.json";
|
|
4
|
+
/** Walks up from `cwd` to the filesystem root looking for `.oa.json`, the same way git/eslint find their config. */
|
|
5
|
+
export function findProjectConfig(cwd = process.cwd()) {
|
|
6
|
+
let dir = cwd;
|
|
7
|
+
for (;;) {
|
|
8
|
+
const path = join(dir, PROJECT_CONFIG_FILENAME);
|
|
9
|
+
if (existsSync(path)) {
|
|
10
|
+
try {
|
|
11
|
+
return { path, config: JSON.parse(readFileSync(path, "utf8")) };
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
console.error(`Warning: ${path} is not valid JSON — ignoring it.`);
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const parent = dirname(dir);
|
|
19
|
+
if (parent === dir)
|
|
20
|
+
return null; // reached the filesystem root
|
|
21
|
+
dir = parent;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Where a fresh `.oa.json` should be written: the nearest existing one, else the repo root, else cwd. */
|
|
25
|
+
export function projectConfigTarget(cwd = process.cwd()) {
|
|
26
|
+
const existing = findProjectConfig(cwd);
|
|
27
|
+
if (existing)
|
|
28
|
+
return existing.path;
|
|
29
|
+
let dir = cwd;
|
|
30
|
+
for (;;) {
|
|
31
|
+
if (existsSync(join(dir, ".git")))
|
|
32
|
+
return join(dir, PROJECT_CONFIG_FILENAME);
|
|
33
|
+
const parent = dirname(dir);
|
|
34
|
+
if (parent === dir)
|
|
35
|
+
break;
|
|
36
|
+
dir = parent;
|
|
37
|
+
}
|
|
38
|
+
return join(cwd, PROJECT_CONFIG_FILENAME);
|
|
39
|
+
}
|
|
40
|
+
/** Merges `patch` into the config at `path`, creating it if needed. */
|
|
41
|
+
export function writeProjectConfig(path, patch) {
|
|
42
|
+
let current = {};
|
|
43
|
+
if (existsSync(path)) {
|
|
44
|
+
try {
|
|
45
|
+
current = JSON.parse(readFileSync(path, "utf8"));
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Corrupt file holds no secrets worth preserving — just overwrite it.
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
writeFileSync(path, `${JSON.stringify({ ...current, ...patch }, null, 2)}\n`, "utf8");
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=project-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-config.js","sourceRoot":"","sources":["../src/project-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAU,CAAC;AAclD,oHAAoH;AACpH,MAAM,UAAU,iBAAiB,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC3D,IAAI,GAAG,GAAG,GAAG,CAAC;IACd,SAAS,CAAC;QACR,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAC;QAChD,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAkB,EAAE,CAAC;YACnF,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,KAAK,CAAC,YAAY,IAAI,mCAAmC,CAAC,CAAC;gBACnE,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,CAAC,8BAA8B;QAC/D,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC;AAED,0GAA0G;AAC1G,MAAM,UAAU,mBAAmB,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC7D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC,IAAI,CAAC;IAEnC,IAAI,GAAG,GAAG,GAAG,CAAC;IACd,SAAS,CAAC;QACR,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAC;QAC7E,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAC;AAC5C,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,KAA6B;IAC5E,IAAI,OAAO,GAAkB,EAAE,CAAC;IAChC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAkB,CAAC;QACpE,CAAC;QAAC,MAAM,CAAC;YACP,sEAAsE;QACxE,CAAC;IACH,CAAC;IACD,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACxF,CAAC"}
|
package/package.json
CHANGED