@imagina-build/ias-cli 0.2.2 → 0.3.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.
- package/README.md +188 -22
- package/package.json +1 -1
- package/schema/ias.schema.json +46 -1
- package/shared/vault/index.mjs +25 -0
- package/shared/vault/policy-vectors.mjs +237 -0
- package/shared/vault/policy.mjs +427 -0
- package/shared/vault/test-vectors/ias-policy-1/policy.json +4016 -0
- package/shared/vault/vectors.mjs +2 -0
- package/src/apple/capabilities.mjs +96 -0
- package/src/apple/inventory.mjs +75 -0
- package/src/apple/signing.mjs +134 -0
- package/src/applications.mjs +114 -0
- package/src/cli.mjs +28 -10
- package/src/commands/apps/index.mjs +61 -11
- package/src/commands/apps/store.mjs +367 -0
- package/src/commands/auth/index.mjs +3 -3
- package/src/commands/build/index.mjs +2 -0
- package/src/commands/builds/index.mjs +20 -0
- package/src/commands/credentials/apple.mjs +1118 -0
- package/src/commands/credentials/generate.mjs +122 -0
- package/src/commands/credentials/index.mjs +114 -44
- package/src/commands/credentials/seal.mjs +44 -0
- package/src/commands/devices/asc.mjs +50 -8
- package/src/commands/devices/index.mjs +2 -1
- package/src/commands/devices/sync.mjs +57 -4
- package/src/commands/dist/index.mjs +12 -0
- package/src/commands/doctor/index.mjs +3 -0
- package/src/commands/github/index.mjs +13 -3
- package/src/commands/init/index.mjs +6 -3
- package/src/commands/policy/index.mjs +583 -0
- package/src/commands/policy/policy.mjs +182 -0
- package/src/commands/policy/progress.mjs +20 -0
- package/src/commands/releases/index.mjs +225 -0
- package/src/commands/rollout/index.mjs +186 -0
- package/src/commands/runners/index.mjs +19 -0
- package/src/commands/sdk/index.mjs +31 -4
- package/src/commands/setup/index.mjs +184 -0
- package/src/commands/skill/index.mjs +43 -0
- package/src/commands/submit/index.mjs +135 -19
- package/src/commands/testflight/index.mjs +309 -0
- package/src/commands/tokens/index.mjs +99 -0
- package/src/commands/update/index.mjs +26 -5
- package/src/commands/vault/approvers.mjs +5 -1
- package/src/commands/vault/index.mjs +26 -6
- package/src/commands/vault/runners.mjs +48 -2
- package/src/commands/webhooks/index.mjs +19 -5
- package/src/config.mjs +16 -1
- package/src/errors.mjs +52 -6
- package/src/op.mjs +83 -0
- package/src/ota-key.mjs +53 -0
- package/src/provisioning.mjs +281 -0
- package/src/schema.mjs +3 -0
- package/src/setup-state.mjs +76 -0
- package/src/setup.mjs +701 -0
- package/src/skill-files.generated.mjs +10 -0
- package/src/skill.mjs +256 -0
- package/src/team-vault.mjs +2 -2
- package/src/token-store.mjs +1 -1
|
@@ -12,6 +12,7 @@ import { EXIT_CODE } from '../../output.mjs';
|
|
|
12
12
|
import { probe as systemProbe } from '../../process.mjs';
|
|
13
13
|
import { SDK_PACKAGE, compatibleRange, isCompatible, packageManager, sdkState } from '../../sdk.mjs';
|
|
14
14
|
import { isReference } from '../../secrets.mjs';
|
|
15
|
+
import { skillHint } from '../../skill.mjs';
|
|
15
16
|
|
|
16
17
|
const MIN_NODE = 22;
|
|
17
18
|
const MAC_TOOLS = ['plutil', 'security', 'sips', 'unzip'];
|
|
@@ -147,6 +148,8 @@ export function doctor(dir, { env, output }) {
|
|
|
147
148
|
const count = (status) => checks.filter((check) => check.status === status).length;
|
|
148
149
|
const failures = count('fail');
|
|
149
150
|
output.log(`${output.prefix}: ${failures === 0 ? 'ready' : `${failures} ${failures === 1 ? 'thing stops' : 'things stop'} a command`}${count('warn') > 0 ? `, ${count('warn')} to look at` : ''}`);
|
|
151
|
+
const hint = skillHint(dir, env);
|
|
152
|
+
if (hint) output.log(`${output.prefix}: ${hint}`);
|
|
150
153
|
return { ok: failures === 0, checks, [EXIT_CODE]: failures > 0 ? 1 : 0 };
|
|
151
154
|
}
|
|
152
155
|
|
|
@@ -16,12 +16,19 @@ export function repositoryOf(text) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
async function link(context) {
|
|
19
|
-
const { positionals, output } = context;
|
|
19
|
+
const { values, positionals, output } = context;
|
|
20
20
|
const project = projectOf(context);
|
|
21
21
|
const code = applicationOf(context, project);
|
|
22
22
|
const repository = repositoryOf(positionals[0]);
|
|
23
|
-
const { status, data } = await connect(context, project).request('PUT', `/apps/${code}/github`, { json: { repository } });
|
|
24
23
|
const panel = `${serverOrigin(project, context.env)}/admin/applications/${code}/integrations`;
|
|
24
|
+
if (values['dry-run']) {
|
|
25
|
+
output.progress(`dry run: would link ${code} to github.com/${repository} (PUT /apps/${code}/github)`);
|
|
26
|
+
output.progress(' the server would make the secret of the webhook GitHub calls, or keep the one it already has, and show it once');
|
|
27
|
+
output.progress(` the token of GitHub is loaded in the panel, with a passkey: ${panel}`);
|
|
28
|
+
output.progress('nothing was linked and no secret was shown.');
|
|
29
|
+
return { dry_run: true, app: code, repository, created: false, webhook_url: null, webhook_secret: null, token_set: false };
|
|
30
|
+
}
|
|
31
|
+
const { status, data } = await connect(context, project).request('PUT', `/apps/${code}/github`, { json: { repository } });
|
|
25
32
|
output.log(`${code} is linked to github.com/${data.repository}.`);
|
|
26
33
|
if (data.webhook_secret) {
|
|
27
34
|
output.log('In the repository on GitHub (Settings › Webhooks › Add webhook):');
|
|
@@ -46,7 +53,10 @@ export default {
|
|
|
46
53
|
name: 'link',
|
|
47
54
|
summary: 'Link a repository; the first time, print the secret of the webhook GitHub will call',
|
|
48
55
|
positionals: [{ name: 'repository', description: 'owner/name, or its https://github.com URL.' }],
|
|
49
|
-
options: {
|
|
56
|
+
options: {
|
|
57
|
+
app: { type: 'string', value: '<code>', description: 'The application (app of ias.json by default).' },
|
|
58
|
+
'dry-run': { type: 'boolean', description: 'Say what it would link, without linking it or showing the webhook secret.' },
|
|
59
|
+
},
|
|
50
60
|
run: link,
|
|
51
61
|
},
|
|
52
62
|
],
|
|
@@ -6,6 +6,7 @@ import { CONFIG_FILE, DEFAULT_SERVER, LEGACY_FILES, MANIFEST_PATH, readExpo, rea
|
|
|
6
6
|
import { IasError } from '../../errors.mjs';
|
|
7
7
|
import { validate } from '../../schema.mjs';
|
|
8
8
|
import { isReference, writtenSecrets } from '../../secrets.mjs';
|
|
9
|
+
import { discoverSkill } from '../../skill.mjs';
|
|
9
10
|
|
|
10
11
|
const ENVIRONMENTS = ['development', 'preview', 'production'];
|
|
11
12
|
const CODE = /^[a-z0-9][a-z0-9-]{0,31}$/;
|
|
@@ -188,7 +189,7 @@ function submitProfiles(profiles, leave) {
|
|
|
188
189
|
}
|
|
189
190
|
|
|
190
191
|
/** Writes ias.json (unless it exists, or with force) and says where each part came from and what stayed out. */
|
|
191
|
-
export function init(dir, { app, force = false, dryRun = false }, output) {
|
|
192
|
+
export function init(dir, { app, force = false, dryRun = false, noSkill = false, env = process.env }, output) {
|
|
192
193
|
const file = join(dir, CONFIG_FILE);
|
|
193
194
|
if (existsSync(file) && !force && !dryRun) throw new IasError(`${CONFIG_FILE} already exists in ${dir}`, { fix: 'ias doctor checks it; ias init --force writes it again, and loses what was changed by hand' });
|
|
194
195
|
const { config, from, leftOut } = initialConfig(dir, { app });
|
|
@@ -204,7 +205,8 @@ export function init(dir, { app, force = false, dryRun = false }, output) {
|
|
|
204
205
|
const legacy = Object.values(LEGACY_FILES).filter((name) => existsSync(join(dir, name)));
|
|
205
206
|
if (legacy.length > 0) output.log(`${legacy.join(' and ')} can go once nothing runs tools/ any more: ias reads ias.json first.`);
|
|
206
207
|
output.log('ias doctor checks it; ias sdk install puts the SDK @imagina-build/ias in the app, with its plugin, which writes ias.json into the builds.');
|
|
207
|
-
|
|
208
|
+
const skill = noSkill ? undefined : discoverSkill(dir, { dryRun }, output);
|
|
209
|
+
return { file, written: !dryRun, config, from, left_out: leftOut, ...(skill ? { skill } : {}) };
|
|
208
210
|
}
|
|
209
211
|
|
|
210
212
|
function describe(part, value) {
|
|
@@ -222,6 +224,7 @@ export default {
|
|
|
222
224
|
app: { type: 'string', value: '<code>', description: 'The code of the application (php artisan apps:create), if it cannot be read from updates.url or dist.config.json.' },
|
|
223
225
|
force: { type: 'boolean', description: 'Write ias.json again if it exists.' },
|
|
224
226
|
'dry-run': { type: 'boolean', description: 'Print the ias.json it would write, and write nothing.' },
|
|
227
|
+
'no-skill': { type: 'boolean', description: 'Do not add the agent skill catalog to opencode.jsonc nor the IAS section to AGENTS.md.' },
|
|
225
228
|
},
|
|
226
|
-
run: ({ values, cwd, output }) => init(resolve(cwd, values.project ?? '.'), { app: values.app, force: values.force, dryRun: values['dry-run'] }, output),
|
|
229
|
+
run: ({ values, cwd, env, output }) => init(resolve(cwd, values.project ?? '.'), { app: values.app, force: values.force, dryRun: values['dry-run'], noSkill: values['no-skill'], env }, output),
|
|
227
230
|
};
|