insta 0.0.82 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -29
- package/dist/agent.js +2 -2
- package/dist/api.js +19 -4
- package/dist/build-logs.js +32 -8
- package/dist/commands/agent-policy.js +1 -1
- package/dist/commands/auth.js +32 -18
- package/dist/commands/billing.js +5 -5
- package/dist/commands/compute.js +83 -41
- package/dist/commands/db-query.js +18 -14
- package/dist/commands/deploy.js +1 -1
- package/dist/commands/domain.js +49 -2
- package/dist/commands/env.js +1 -1
- package/dist/commands/managed-db.js +34 -0
- package/dist/commands/mcp.js +2 -2
- package/dist/commands/metrics.js +6 -5
- package/dist/commands/observe.js +2 -2
- package/dist/commands/{db.js → postgres.js} +32 -32
- package/dist/commands/regions.js +1 -1
- package/dist/commands/services.js +31 -70
- package/dist/commands/setup.js +8 -7
- package/dist/commands/storage.js +17 -2
- package/dist/commands/template.js +4 -4
- package/dist/commands/upgrade.js +20 -8
- package/dist/config.js +49 -31
- package/dist/deploy-archive.js +65 -56
- package/dist/ensure-skills.js +1 -1
- package/dist/index.js +227 -161
- package/dist/observe/hook.js +1 -1
- package/dist/observe/install.js +1 -1
- package/dist/resolve-service.js +4 -4
- package/dist/telemetry.js +8 -8
- package/dist/util.js +9 -6
- package/package.json +1 -1
package/dist/deploy-archive.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
1
2
|
import { handleApproval } from './util.js';
|
|
2
3
|
export function archiveBuildSpec(hasDockerfile) {
|
|
3
4
|
return hasDockerfile ? { type: 'dockerfile' } : { type: 'nixpacks' };
|
|
@@ -79,69 +80,77 @@ export async function deployArchive(api, projectId, ref, branch, opts, now = Dat
|
|
|
79
80
|
const operationId = started.body?.operationId;
|
|
80
81
|
if (typeof operationId !== 'string' || !operationId)
|
|
81
82
|
throw new Error('the platform accepted the deploy but returned no operation id — re-run the deploy');
|
|
82
|
-
log(`build logs: insta build
|
|
83
|
+
log(`build logs: insta build logs ${operationId}`);
|
|
83
84
|
if (started.body?.resumed === true)
|
|
84
85
|
log('resuming the deploy this archive already started');
|
|
85
86
|
const deadline = now() + DEPLOY_DEADLINE_MS;
|
|
86
87
|
const overdue = () => new Error(`the deploy did not finish within ${Math.round(DEPLOY_DEADLINE_MS / 60000)} minutes — check \`insta status\` or re-run`);
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const remaining = deadline - now();
|
|
93
|
-
if (remaining <= 0)
|
|
94
|
-
throw overdue();
|
|
95
|
-
const res = await api.rawRequest('GET', `/projects/${projectId}/archive-deploys/${encodeURIComponent(operationId)}`, undefined, {
|
|
96
|
-
signal: AbortSignal.timeout(Math.min(remaining, POLL_REQUEST_TIMEOUT_MS)),
|
|
97
|
-
}).catch((e) => {
|
|
98
|
-
if (!isAbort(e))
|
|
99
|
-
throw e;
|
|
100
|
-
throw remaining <= POLL_REQUEST_TIMEOUT_MS ? overdue() : new Error(`the platform did not answer a status poll within ${POLL_REQUEST_TIMEOUT_MS / 1000}s — check \`insta status\` or re-run`);
|
|
101
|
-
});
|
|
102
|
-
const state = res.body?.state;
|
|
103
|
-
await watchLogs?.(operationId, state === 'failed' || state === 'live', Math.max(0, deadline - now()));
|
|
104
|
-
// A failed operation is an ANSWER, not a transport error: the poll worked, and the sentence
|
|
105
|
-
// it carries (usually the gateway's own, e.g. "no Dockerfile at ./api") is the one to show.
|
|
106
|
-
if (state === 'failed') {
|
|
107
|
-
// `||` would let a non-string through and the CLI would print "[object Object]" for the one
|
|
108
|
-
// sentence that explains the failure. Only a non-empty string is a message.
|
|
109
|
-
const error = res.body?.error;
|
|
110
|
-
return { failed: typeof error === 'string' && error ? error : 'the deploy failed' };
|
|
88
|
+
const logController = new AbortController();
|
|
89
|
+
const logTask = watchLogs ? (async () => {
|
|
90
|
+
while (!logController.signal.aborted && now() < deadline) {
|
|
91
|
+
await watchLogs(operationId, false, Math.max(0, deadline - now()), logController.signal);
|
|
92
|
+
await delay(Math.min(POLL_MS, Math.max(0, deadline - now())), undefined, { signal: logController.signal });
|
|
111
93
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
94
|
+
})().catch(() => {
|
|
95
|
+
if (!logController.signal.aborted)
|
|
96
|
+
log(`Could not follow build logs. Retry with: insta build logs ${operationId}`);
|
|
97
|
+
}) : undefined;
|
|
98
|
+
let last = '';
|
|
99
|
+
try {
|
|
100
|
+
for (;;) {
|
|
101
|
+
const remaining = deadline - now();
|
|
102
|
+
if (remaining <= 0)
|
|
103
|
+
throw overdue();
|
|
104
|
+
const res = await api.rawRequest('GET', `/projects/${projectId}/archive-deploys/${encodeURIComponent(operationId)}`, undefined, {
|
|
105
|
+
signal: AbortSignal.timeout(Math.min(remaining, POLL_REQUEST_TIMEOUT_MS)),
|
|
106
|
+
}).catch((e) => {
|
|
107
|
+
if (!isAbort(e))
|
|
108
|
+
throw e;
|
|
109
|
+
throw remaining <= POLL_REQUEST_TIMEOUT_MS ? overdue() : new Error(`the platform did not answer a status poll within ${POLL_REQUEST_TIMEOUT_MS / 1000}s — check \`insta status\` or re-run`);
|
|
110
|
+
});
|
|
111
|
+
const state = res.body?.state;
|
|
112
|
+
if (state === 'failed' || state === 'live') {
|
|
113
|
+
logController.abort();
|
|
114
|
+
await logTask;
|
|
115
|
+
await watchLogs?.(operationId, true, Math.max(0, deadline - now()));
|
|
117
116
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
117
|
+
if (state === 'failed') {
|
|
118
|
+
const error = res.body?.error;
|
|
119
|
+
return { failed: typeof error === 'string' && error ? error : 'the deploy failed' };
|
|
120
|
+
}
|
|
121
|
+
if (state === 'live') {
|
|
122
|
+
const image = res.body?.imageRef;
|
|
123
|
+
const url = res.body?.url;
|
|
124
|
+
if (typeof image !== 'string' || !image || typeof url !== 'string' || !url) {
|
|
125
|
+
throw new Error('the deploy finished but the platform returned no image or URL for it — check `insta status`');
|
|
126
|
+
}
|
|
127
|
+
const optionalString = (field, v) => {
|
|
128
|
+
if (v === undefined || v === null)
|
|
129
|
+
return undefined;
|
|
130
|
+
if (typeof v !== 'string')
|
|
131
|
+
throw new Error(`the platform returned a non-string ${field} for the deploy — upgrade with \`insta upgrade\``);
|
|
132
|
+
return v;
|
|
133
|
+
};
|
|
134
|
+
return {
|
|
135
|
+
image, url,
|
|
136
|
+
branch: optionalString('branch', res.body.branch) ?? branch,
|
|
137
|
+
group: optionalString('group', res.body.group) ?? opts.group ?? '',
|
|
138
|
+
machineId: optionalString('machineId', res.body.machineId),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
if (state !== 'queued' && state !== 'building' && state !== 'deploying') {
|
|
142
|
+
throw new Error(`the platform reported an unknown deploy state (${JSON.stringify(state)}) — upgrade with \`insta upgrade\``);
|
|
143
|
+
}
|
|
144
|
+
if (state !== last) {
|
|
145
|
+
log(state === 'deploying' ? 'image built, deploying it' : `${state}…`);
|
|
146
|
+
last = state;
|
|
147
|
+
}
|
|
148
|
+
await wait(POLL_MS);
|
|
143
149
|
}
|
|
144
|
-
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
logController.abort();
|
|
153
|
+
await logTask;
|
|
145
154
|
}
|
|
146
155
|
}
|
|
147
156
|
//# sourceMappingURL=deploy-archive.js.map
|
package/dist/ensure-skills.js
CHANGED
|
@@ -27,7 +27,7 @@ const GITIGNORE_COMMENT = '# InstaCloud: agent skills installed by `npx skills a
|
|
|
27
27
|
// existing AI_AGENT (e.g. running inside another agent) rather than clobbering it.
|
|
28
28
|
const defaultRunner = (cmdIn, argsIn, inherit = false) => new Promise((resolve) => {
|
|
29
29
|
// resolveSpawnable: on Windows `npx` is a .cmd shim spawn() refuses without a shell —
|
|
30
|
-
// re-enter npm's CLI script via node instead (same treatment as `insta setup
|
|
30
|
+
// re-enter npm's CLI script via node instead (same treatment as `insta agent setup`).
|
|
31
31
|
const { cmd, args } = resolveSpawnable(cmdIn, argsIn);
|
|
32
32
|
const env = { ...process.env, AI_AGENT: process.env.AI_AGENT || 'insta' };
|
|
33
33
|
// npx exports its flags as npm_config_* to children; npm_config_package would pin the inner
|