@nomac/cli 0.17.0 → 0.18.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/package.json +1 -1
- package/skill/SKILL.md +6 -6
- package/src/cli.mjs +15 -0
- package/src/hosted-sessions.mjs +4 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nomac/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "A real cloud Mac for AI agents: Xcode, the iOS Simulator, signing, TestFlight and App Store publishing, by the minute, over MCP, SSH and HTTPS.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
package/skill/SKILL.md
CHANGED
|
@@ -186,9 +186,9 @@ more than twice.
|
|
|
186
186
|
|
|
187
187
|
## Feedback
|
|
188
188
|
|
|
189
|
-
When you stop a Mac, its answer asks
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
189
|
+
When you stop a Mac or a phone, its answer asks what got in your way, failed,
|
|
190
|
+
was missing or was slow. Answer in a sentence or two: `report_issue` with
|
|
191
|
+
`kind: "feedback"` and the `session_id`, or `nomac feedback "..."` after
|
|
192
|
+
`nomac stop`. Leave out code, secrets and personal data. Send it once: a person
|
|
193
|
+
at NoMac reads it and answers in that ticket (`report_issue` with no
|
|
194
|
+
description shows the answer).
|
package/src/cli.mjs
CHANGED
|
@@ -9,6 +9,7 @@ Start:
|
|
|
9
9
|
nomac start start a Mac, or reconnect to yours
|
|
10
10
|
nomac attach use from this folder the Mac your agent started elsewhere (MCP, dashboard)
|
|
11
11
|
nomac stop stop the Mac: deletes it and its files (not ~/drive), billing ends
|
|
12
|
+
nomac feedback "..." tell NoMac what got in your way, failed, was missing or was slow
|
|
12
13
|
|
|
13
14
|
Use it:
|
|
14
15
|
nomac exec -- ls run a command; prints its output, keeps its exit code
|
|
@@ -170,6 +171,20 @@ export async function main(argv) {
|
|
|
170
171
|
console.log(describeApple(view));
|
|
171
172
|
return view;
|
|
172
173
|
}
|
|
174
|
+
case "feedback": {
|
|
175
|
+
// A note for NoMac, about this folder's last Mac when there is one (nomac stop asks for it).
|
|
176
|
+
const description = rest.join(" ").trim();
|
|
177
|
+
if (isHelp(rest) || description.length < 10) {
|
|
178
|
+
const usage = 'Usage: nomac feedback "what got in your way, failed, was missing or was slow"\n A person at NoMac reads it and answers. Leave out code, secrets and personal data.';
|
|
179
|
+
if (isHelp(rest)) return console.log(usage);
|
|
180
|
+
throw new CliError("feedback usage", usage);
|
|
181
|
+
}
|
|
182
|
+
const { sessionStore } = await import("./session-store.mjs");
|
|
183
|
+
const last = sessionStore().load();
|
|
184
|
+
const answer = await api("POST", "/api/v1/report-issue", { body: { description, kind: "feedback", ...(last?.mode === "hosted" && last.id ? { session_id: last.id } : {}) } });
|
|
185
|
+
console.log(answer.note ?? `Sent (${answer.ticket_id}).`);
|
|
186
|
+
return answer;
|
|
187
|
+
}
|
|
173
188
|
case "whoami": {
|
|
174
189
|
const [me, credit] = await Promise.all([api("GET", "/api/v1/me"), api("GET", "/api/v1/mac/credits").catch(() => null)]);
|
|
175
190
|
const o = me.org ?? {}, c = credit?.credits ?? credit ?? {};
|
package/src/hosted-sessions.mjs
CHANGED
|
@@ -14,6 +14,8 @@ import { refreshSshConfig, sshConfigBlock, writeSshConfig } from "./ssh-config.m
|
|
|
14
14
|
const WORKSPACE = "/Users/agent/workspace";
|
|
15
15
|
/** How long the CLI keeps trying to put a project on the drive before it gives up for now. */
|
|
16
16
|
const PLACE_BUDGET_MS = 120_000;
|
|
17
|
+
/** Stop's ask, as the API's feedback_request words it, with the CLI's way to answer (nomac feedback). */
|
|
18
|
+
const FEEDBACK_REQUEST = 'What got in your way, failed, was missing or was slow in this session? Tell NoMac in a sentence or two: nomac feedback "...". A person reads each one. Leave out code, secrets and personal data.';
|
|
17
19
|
|
|
18
20
|
const HELP = `Nomac cloud Mac sessions
|
|
19
21
|
nomac start [--wait 300] [--max-duration 7200] [--idle-timeout 600] [--max-cost 5] [--json]
|
|
@@ -385,7 +387,7 @@ export async function hostedSessionCommand(command, argv, { store = sessionStore
|
|
|
385
387
|
: "Check: nomac status";
|
|
386
388
|
// A ready Mac says what is on it, as nomac status does.
|
|
387
389
|
const mac = result.session.state === "ready" && macLine(lastImage) ? `${macLine(lastImage)}\n` : "";
|
|
388
|
-
print(`${result.attached ? `${result.attached}\n` : ""}${result.session.id}: ${result.session.state}\n${mac}${next}\n${usage}${result.warning ? `\n${result.warning}` : ""}`);
|
|
390
|
+
print(`${result.attached ? `${result.attached}\n` : ""}${result.session.id}: ${result.session.state}\n${mac}${next}\n${usage}${result.warning ? `\n${result.warning}` : ""}${result.feedback_request ? `\n\n${result.feedback_request}` : ""}`);
|
|
389
391
|
return result;
|
|
390
392
|
};
|
|
391
393
|
const saveView = (local, view) => {
|
|
@@ -833,7 +835,7 @@ export async function hostedSessionCommand(command, argv, { store = sessionStore
|
|
|
833
835
|
saveView(local, (await request("DELETE", `/api/v1/mac/sessions/${sessionId(local.id)}`)).session);
|
|
834
836
|
const deadline = now() + wait * 1000;
|
|
835
837
|
while (!["stopped", "failed"].includes(local.state) && now() < deadline) { await sleep(1000); await refresh(local); }
|
|
836
|
-
return output({ session: local.snapshot });
|
|
838
|
+
return output({ session: local.snapshot, feedback_request: FEEDBACK_REQUEST });
|
|
837
839
|
}
|
|
838
840
|
await ready(local);
|
|
839
841
|
if (command === "sync") {
|