newo 3.7.4 → 3.7.5
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 -2
- package/README.md +70 -2
- package/dist/cli/commands/get-skill.d.ts +3 -0
- package/dist/cli/commands/get-skill.js +72 -0
- package/dist/cli/commands/help.js +29 -0
- package/dist/cli/commands/logs.d.ts +6 -1
- package/dist/cli/commands/logs.js +62 -14
- package/dist/cli/commands/sandbox.d.ts +10 -4
- package/dist/cli/commands/sandbox.js +182 -51
- package/dist/cli/commands/update-skill.d.ts +4 -0
- package/dist/cli/commands/update-skill.js +119 -0
- package/dist/cli.js +8 -0
- package/dist/domain/strategies/sync/V2ProjectSyncStrategy.d.ts +3 -0
- package/dist/domain/strategies/sync/V2ProjectSyncStrategy.js +67 -19
- package/dist/sandbox/chat.d.ts +23 -3
- package/dist/sandbox/chat.js +83 -30
- package/dist/sync/remote-skill.d.ts +33 -0
- package/dist/sync/remote-skill.js +52 -0
- package/package.json +1 -1
- package/src/cli/commands/get-skill.ts +84 -0
- package/src/cli/commands/help.ts +29 -0
- package/src/cli/commands/logs.ts +83 -15
- package/src/cli/commands/sandbox.ts +238 -60
- package/src/cli/commands/update-skill.ts +139 -0
- package/src/cli.ts +10 -0
- package/src/domain/strategies/sync/V2ProjectSyncStrategy.ts +101 -20
- package/src/sandbox/chat.ts +106 -29
- package/src/sync/remote-skill.ts +92 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.7.5] - 2026-06-17
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`newo sandbox` connector selection (R1)** — new `--connector <connector_idn>` and `--integration <idn>` flags select which connector to chat through instead of always taking the first running connector of the `sandbox` integration (which made agents like Vibe Builder's `vibe_agent` unreachable from the CLI when another connector, e.g. `convo_agent_sandbox`, came first). `--list-connectors` prints the running connectors (with `--json` for machine output). When `--connector` is not found, the error lists the available running connectors. Without flags, behavior is unchanged (first running connector). Surfaced during PR #2076 superagent testing.
|
|
15
|
+
- **`newo sandbox` long messages and machine-readable output (R2)** — `--file <path>` and `--stdin` send message text without shell-argument limits (tested scenarios used 40k–400k char messages); `--timeout <seconds>` overrides the previously hardcoded 60-second response-poll limit (long VibeFlow turns ran 1–7 minutes); `--json` emits `{actor_id, persona_id, connector_idn, external_event_id, user_external_event_id, agent_external_event_id, response, elapsed_ms, timed_out, flow_idn, skill_idn, session_id}`. The `external_event_id` of the user turn is the correlation key for `newo logs --event-id`, closing the gap that previously required ad-hoc scripts importing `dist/api.js` directly.
|
|
16
|
+
- **`newo get-skill` / `newo update-skill` (R3)** — point inspection and point edits of a single skill on the platform by IDN path (`<skill-idn> --project <idn> --agent <idn> --flow <idn>`), with no pulled workspace required. `get-skill` shows the live model, runner_type, parameters, and prompt_script (`--json` supported). `update-skill` changes `--model <provider_idn>/<model_idn>` and/or `--script <file>`, leaving everything else untouched; `--publish` (with optional `--publish-description`) publishes the flow afterwards, otherwise changes stay draft. Warns when a local pulled workspace exists and now diverges. Covers the "switch model → run test → switch back" scenario in two commands.
|
|
17
|
+
- **`newo logs --name <ActionName>` (R4)** — client-side filter on `data.name` (e.g. only `Gen` or `GetMemory` action calls), replacing `--json` + jq post-filtering. Help text now documents that the model of a turn must be read from `data.source.model` in `--json` output, not inferred from actor/agent names.
|
|
18
|
+
- **`newo logs --raw`** — JSONL output: one JSON object per log line (sorted oldest-first), with no banners or empty-result text, so stdout is a clean machine-readable stream for piping (`newo logs --raw | jq ...`). Distinct from `--json`, which emits a single pretty-printed JSON array.
|
|
19
|
+
- **`src/sync/remote-skill.ts`** — shared resolver (`resolveRemoteSkill`, `parseModelFlag`) that maps a project/agent/flow/skill IDN path to platform IDs with descriptive errors listing available IDNs at the failing level.
|
|
20
|
+
- **20 unit tests** — 14 in `test/sandbox-skill-commands.test.js` covering connector selection (legacy first-running behavior, exact match, non-running exclusion, error listings), poll timeout override, user/agent `external_event_id` capture, IDN-path resolution, and `--model` flag parsing, plus 6 in `test/logs-command.test.js` covering `--name` client-side filtering, pagination, and `--raw` JSONL output — all against a fake axios client, no network.
|
|
21
|
+
|
|
10
22
|
## [3.7.4] - 2026-06-10
|
|
11
23
|
|
|
12
24
|
### Added
|
|
@@ -1080,7 +1092,8 @@ Another Item: $Price [Modifiers: modifier3]
|
|
|
1080
1092
|
- GitHub Actions CI/CD integration
|
|
1081
1093
|
- Robust authentication with token refresh
|
|
1082
1094
|
|
|
1083
|
-
[Unreleased]: https://github.com/sabbah13/newo-cli/compare/v3.7.
|
|
1095
|
+
[Unreleased]: https://github.com/sabbah13/newo-cli/compare/v3.7.5...HEAD
|
|
1096
|
+
[3.7.5]: https://github.com/sabbah13/newo-cli/compare/v3.7.4...v3.7.5
|
|
1084
1097
|
[3.7.4]: https://github.com/sabbah13/newo-cli/compare/v3.7.3...v3.7.4
|
|
1085
1098
|
[3.7.3]: https://github.com/sabbah13/newo-cli/compare/v3.7.2...v3.7.3
|
|
1086
1099
|
[3.7.2]: https://github.com/sabbah13/newo-cli/compare/v3.7.1...v3.7.2
|
|
@@ -1115,4 +1128,4 @@ Another Item: $Price [Modifiers: modifier3]
|
|
|
1115
1128
|
[1.4.0]: https://github.com/sabbah13/newo-cli/compare/v1.2.1...v1.4.0
|
|
1116
1129
|
[1.3.0]: https://github.com/sabbah13/newo-cli/compare/v1.2.1...v1.3.0
|
|
1117
1130
|
[1.2.2]: https://github.com/sabbah13/newo-cli/compare/v1.2.1...v1.2.2
|
|
1118
|
-
[1.2.1]: https://github.com/sabbah13/newo-cli/releases/tag/v1.2.1
|
|
1131
|
+
[1.2.1]: https://github.com/sabbah13/newo-cli/releases/tag/v1.2.1
|
package/README.md
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
Sync NEWO "Project → Agent → Flow → Skills" structure to local files with:
|
|
11
11
|
- 🆕 **V2 skill creation on push** (v3.7.4) - adding a skill inline to a `newo_v2` `{FlowIdn}.yaml` and pushing now creates it on the platform (previously only updates of existing skills worked)
|
|
12
|
+
- 🆕 **Sandbox connector selection + automation** (v3.7.5) - `newo sandbox --connector <idn>`, `--list-connectors`, `--file`/`--stdin` for long messages, `--timeout`, and `--json` with `external_event_id` for log correlation
|
|
13
|
+
- 🆕 **Point skill edits** (v3.7.5) - `newo get-skill` / `newo update-skill` inspect and modify a single skill (model, script) on the platform without a pulled workspace, with optional `--publish`
|
|
12
14
|
- 🆕 **Canvas blank-screen hardening** (v3.7.3) - JSON-typed attributes (e.g. Workflow Builder canvas) with Markdown `\_` escapes or structural newlines no longer corrupt the canvas on push ([#7](https://github.com/sabbah13/newo-cli/pull/7))
|
|
13
15
|
- 🆕 **Flow metadata sync** (v3.7.2) - `newo push` now reconciles flow title, events, and state_fields from local `metadata.yaml` to the platform (closes [#3](https://github.com/sabbah13/newo-cli/issues/3))
|
|
14
16
|
- 🆕 **Dual format support** (v3.6.0) - `cli_v1` (native) and `newo_v2` (platform compatible), auto-detected per customer
|
|
@@ -150,12 +152,78 @@ NEWO_REFRESH_URL=custom_refresh_endpoint # Custom refresh endpoint
|
|
|
150
152
|
| `newo push [--format <fmt>]` | Upload local changes to NEWO | • Works with both formats<br>• Hash-based change detection<br>• Library skill updates<br>• Publishes flows automatically |
|
|
151
153
|
| `newo status [--format <fmt>]` | Show modified files | • Format-aware status<br>• Multiple file warnings<br>• Per-customer status |
|
|
152
154
|
| `newo export [--output <file>]` | Download V2 bulk ZIP from platform | • Complete organization export<br>• Projects, agents, flows, skills, attributes, AKB<br>• Compatible with platform UI import |
|
|
153
|
-
| `newo sandbox` | Test agents in sandbox chat mode | • Single-command mode for automation<br>• Multi-turn conversation support<br>• Debug info for agent development |
|
|
155
|
+
| `newo sandbox` | Test agents in sandbox chat mode | • Single-command mode for automation<br>• Multi-turn conversation support<br>• Debug info for agent development<br>• v3.7.5: `--connector`, `--list-connectors`, `--file`/`--stdin`, `--timeout`, `--json` |
|
|
156
|
+
| `newo get-skill` / `newo update-skill` | Inspect / point-edit one skill on the platform (NEW v3.7.5) | • No pulled workspace required<br>• `--model <provider>/<model>`, `--script <file>`<br>• Optional `--publish` |
|
|
154
157
|
| `newo conversations` | Pull conversation history | • User personas and chat history<br>• YAML format output<br>• Pagination support |
|
|
155
158
|
| `newo list-customers` | List configured customers | • Shows default customer<br>• Multi-customer discovery |
|
|
156
159
|
| `newo import-akb` | Import knowledge base articles | • Structured text parsing<br>• Bulk article import<br>• Validation and error reporting |
|
|
157
160
|
| `newo meta` | Get project metadata (debug) | • Project structure analysis<br>• Metadata validation |
|
|
158
161
|
|
|
162
|
+
### Sandbox Connector Selection & Automation (NEW v3.7.5)
|
|
163
|
+
|
|
164
|
+
`newo sandbox` previously always chatted through the **first** running connector of the `sandbox` integration, making other agents (e.g. a Vibe Builder behind a `vibe_agent` connector) unreachable from the CLI. v3.7.5 adds connector selection plus automation-friendly I/O:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
newo sandbox --list-connectors # show running sandbox connectors
|
|
168
|
+
newo sandbox "ping" --connector vibe_agent # chat through a specific connector
|
|
169
|
+
newo sandbox "ping" --integration sandbox --connector vibe_agent # explicit pair (default integration: sandbox)
|
|
170
|
+
|
|
171
|
+
newo sandbox --file ./chunk1.txt --actor <id> --json # long message from file, machine-readable output
|
|
172
|
+
cat chunk1.txt | newo sandbox --stdin --actor <id> # message from stdin
|
|
173
|
+
newo sandbox "ping" --timeout 420 # wait up to 7 minutes for slow agent turns (default: 60s)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
`--json` output includes the correlation keys for `newo logs`:
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"actor_id": "…", "persona_id": "…", "connector_idn": "vibe_agent",
|
|
181
|
+
"external_event_id": "…", // user turn — use with: newo logs --event-id <id>
|
|
182
|
+
"user_external_event_id": "…", "agent_external_event_id": "…",
|
|
183
|
+
"response": "…", "elapsed_ms": 12345, "timed_out": false,
|
|
184
|
+
"flow_idn": "VibeFlow", "skill_idn": "…", "session_id": "…"
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Without `--connector`, behavior is unchanged (first running connector), so existing scripts keep working. When the requested connector is missing, the error lists the available running connectors.
|
|
189
|
+
|
|
190
|
+
This makes agent integration tests scriptable in plain bash: send chunks via `newo sandbox --file … --json`, then verify behavior via `newo logs --event-id … --json` — no more ad-hoc Node scripts importing `dist/api.js`.
|
|
191
|
+
|
|
192
|
+
### Point Skill Inspection & Edits (NEW v3.7.5)
|
|
193
|
+
|
|
194
|
+
Inspect or modify a **single skill** directly on the platform by IDN path — no pulled `newo_customers/` workspace required, nothing else gets touched:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# What lives on the platform right now? (model, runner_type, parameters, prompt_script)
|
|
198
|
+
newo get-skill structured_generation --project vibe --agent VibeAgent --flow VibeFlow [--json]
|
|
199
|
+
|
|
200
|
+
# Temporarily switch a model, publish, run tests, switch back:
|
|
201
|
+
newo update-skill structured_generation --project vibe --agent VibeAgent --flow VibeFlow \
|
|
202
|
+
--model google/gemini25_pro --publish
|
|
203
|
+
# …run your tests…
|
|
204
|
+
newo update-skill structured_generation --project vibe --agent VibeAgent --flow VibeFlow \
|
|
205
|
+
--model openai/gpt54 --publish
|
|
206
|
+
|
|
207
|
+
# Replace a skill script from a file (draft only, without --publish):
|
|
208
|
+
newo update-skill get_memory --project vibe --agent VibeAgent --flow VibeFlow --script ./patched.nsl
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
- `--model <provider_idn>/<model_idn>` and `--script <file>` can be combined; everything else (title, parameters, runner) is preserved.
|
|
212
|
+
- `--publish` publishes the flow after the update (same as push); without it the change stays draft. `--publish-description "<text>"` sets the publish note.
|
|
213
|
+
- If a pulled local workspace exists for the project, the CLI warns that it now diverges from the platform.
|
|
214
|
+
|
|
215
|
+
### Logs: Action-Name Filter (NEW v3.7.5)
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
newo logs --type call --name Gen --json # only Gen action calls
|
|
219
|
+
newo logs --name GetMemory --hours 24 # only GetMemory calls, last 24h
|
|
220
|
+
newo logs --type call --raw | jq '.data.name' # JSONL stream, one log per line, for piping
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
`--name` filters by `data.name` client-side (the API has no such query param). Note: the **model used for a turn** is in `data.source.model` of the `--json` output — do not infer it from actor/agent names.
|
|
224
|
+
|
|
225
|
+
`--raw` emits **JSONL** — one JSON object per log line (oldest-first), with no banners or "no logs found" text — so stdout is a clean stream for `jq`/piping. This differs from `--json`, which prints a single pretty-printed JSON array.
|
|
226
|
+
|
|
159
227
|
### Flow Metadata Sync (NEW v3.7.2)
|
|
160
228
|
|
|
161
229
|
`newo push` now reconciles **flow-level metadata** — title, `events:`, and `state_fields:` — from local YAML to the platform. Before v3.7.2 push only uploaded skill scripts, so edits to a flow's `metadata.yaml` (V1) or `{FlowIdn}.yaml` (V2) silently never reached the platform; events added via `newo create-event` could appear to disappear after a pull → push cycle. Closes [#3](https://github.com/sabbah13/newo-cli/issues/3).
|
|
@@ -1379,4 +1447,4 @@ NEWO CLI integrates with these NEWO platform endpoints:
|
|
|
1379
1447
|
|
|
1380
1448
|
---
|
|
1381
1449
|
|
|
1382
|
-
**Built with ❤️ by the NEWO team**
|
|
1450
|
+
**Built with ❤️ by the NEWO team**
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get Skill Command Handler - Inspect a skill's live state on the platform
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* newo get-skill <skill-idn> --project <idn> --agent <idn> --flow <idn> [--json]
|
|
6
|
+
*
|
|
7
|
+
* Shows the skill as it currently lives on the platform (model, runner_type,
|
|
8
|
+
* parameters, prompt_script) without requiring a pulled local workspace.
|
|
9
|
+
*/
|
|
10
|
+
import { requireSingleCustomer } from '../customer-selection.js';
|
|
11
|
+
import { makeClient } from '../../api.js';
|
|
12
|
+
import { getValidAccessToken } from '../../auth.js';
|
|
13
|
+
import { resolveRemoteSkill } from '../../sync/remote-skill.js';
|
|
14
|
+
const USAGE = 'Usage: newo get-skill <skill-idn> --project <project-idn> --agent <agent-idn> --flow <flow-idn> [--json] [--customer <idn>]';
|
|
15
|
+
export async function handleGetSkillCommand(customerConfig, args, verbose = false) {
|
|
16
|
+
const skillIdn = args._[1];
|
|
17
|
+
const projectIdn = args.project;
|
|
18
|
+
const agentIdn = args.agent;
|
|
19
|
+
const flowIdn = args.flow;
|
|
20
|
+
const asJson = Boolean(args.json);
|
|
21
|
+
if (!skillIdn || !projectIdn || !agentIdn || !flowIdn) {
|
|
22
|
+
console.error('Error: skill IDN, --project, --agent and --flow are required');
|
|
23
|
+
console.error(USAGE);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
const selectedCustomer = requireSingleCustomer(customerConfig, args.customer);
|
|
27
|
+
if (asJson) {
|
|
28
|
+
process.env.NEWO_QUIET_MODE = 'true'; // keep stdout machine-readable for piping
|
|
29
|
+
}
|
|
30
|
+
const token = await getValidAccessToken(selectedCustomer);
|
|
31
|
+
const client = await makeClient(verbose, token);
|
|
32
|
+
if (verbose)
|
|
33
|
+
console.log(`🔍 Resolving skill ${projectIdn}/${agentIdn}/${flowIdn}/${skillIdn}...`);
|
|
34
|
+
const { project, agent, flow, skill } = await resolveRemoteSkill(client, {
|
|
35
|
+
projectIdn,
|
|
36
|
+
agentIdn,
|
|
37
|
+
flowIdn,
|
|
38
|
+
skillIdn
|
|
39
|
+
});
|
|
40
|
+
if (asJson) {
|
|
41
|
+
console.log(JSON.stringify({
|
|
42
|
+
project_idn: project.idn,
|
|
43
|
+
agent_idn: agent.idn,
|
|
44
|
+
flow_idn: flow.idn,
|
|
45
|
+
id: skill.id,
|
|
46
|
+
idn: skill.idn,
|
|
47
|
+
title: skill.title,
|
|
48
|
+
runner_type: skill.runner_type,
|
|
49
|
+
model: skill.model,
|
|
50
|
+
parameters: skill.parameters,
|
|
51
|
+
prompt_script: skill.prompt_script ?? null
|
|
52
|
+
}, null, 2));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
console.log(`📜 Skill: ${project.idn}/${agent.idn}/${flow.idn}/${skill.idn}`);
|
|
56
|
+
console.log(` ID: ${skill.id}`);
|
|
57
|
+
console.log(` Title: ${skill.title}`);
|
|
58
|
+
console.log(` Runner type: ${skill.runner_type}`);
|
|
59
|
+
console.log(` Model: ${skill.model.provider_idn}/${skill.model.model_idn}`);
|
|
60
|
+
if (skill.parameters.length > 0) {
|
|
61
|
+
console.log(` Parameters:`);
|
|
62
|
+
for (const param of skill.parameters) {
|
|
63
|
+
console.log(` ${param.name}${param.default_value !== undefined ? ` = ${JSON.stringify(param.default_value)}` : ''}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
console.log(` Parameters: (none)`);
|
|
68
|
+
}
|
|
69
|
+
console.log(`\n--- prompt_script (${(skill.prompt_script || '').length} chars) ---`);
|
|
70
|
+
console.log(skill.prompt_script || '(empty)');
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=get-skill.js.map
|
|
@@ -16,6 +16,11 @@ Core Commands:
|
|
|
16
16
|
newo conversations [--customer <idn>] [--all] # download user conversations -> conversations.yaml
|
|
17
17
|
newo sandbox "<message>" [--customer <idn>] # test agent in sandbox - single message mode
|
|
18
18
|
newo sandbox --actor <id> "message" # continue existing sandbox conversation
|
|
19
|
+
newo sandbox --list-connectors # list running sandbox connectors (NEW v3.7.5)
|
|
20
|
+
newo sandbox "<msg>" --connector <idn> # chat through a specific connector (NEW v3.7.5)
|
|
21
|
+
newo sandbox --file <path> | --stdin # send long messages from file/stdin (NEW v3.7.5)
|
|
22
|
+
newo get-skill <idn> --project <p> --agent <a> --flow <f> [--json] # inspect live skill on platform (NEW v3.7.5)
|
|
23
|
+
newo update-skill <idn> --project <p> --agent <a> --flow <f> [--model <prov>/<model>] [--script <file>] [--publish] # point-edit skill (NEW v3.7.5)
|
|
19
24
|
newo pull-attributes [--customer <idn>] # download customer + project attributes
|
|
20
25
|
newo list-customers # list available customers
|
|
21
26
|
newo meta [--customer <idn>] # get project metadata (debug)
|
|
@@ -76,6 +81,8 @@ Analytics & Monitoring (NEW):
|
|
|
76
81
|
newo logs --type <types> # filter by type: system, operation, call (comma-separated)
|
|
77
82
|
newo logs --flow <idn> --skill <idn> # filter by flow and/or skill
|
|
78
83
|
newo logs --message <text> # search in log messages
|
|
84
|
+
newo logs --name <ActionName> # filter by action name in data.name, e.g. Gen, GetMemory (NEW v3.7.5)
|
|
85
|
+
newo logs --event-id <uuid> # filter by external event ID (correlate with sandbox --json)
|
|
79
86
|
newo logs --follow, -f # tail mode - continuously poll for new logs
|
|
80
87
|
newo logs --json # output logs as JSON array
|
|
81
88
|
newo logs --raw # output each log as single JSON line (for piping)
|
|
@@ -94,6 +101,12 @@ Flags:
|
|
|
94
101
|
--verbose, -v # enable detailed logging and progress information
|
|
95
102
|
--quiet, -q # minimal output for automation (sandbox only)
|
|
96
103
|
--actor <id> # continue existing sandbox chat with actor/chat ID
|
|
104
|
+
--connector <idn> # sandbox: select connector by connector_idn (default: first running)
|
|
105
|
+
--integration <idn> # sandbox: integration to search connectors in (default: sandbox)
|
|
106
|
+
--file <path> # sandbox: read message text from file
|
|
107
|
+
--stdin # sandbox: read message text from stdin
|
|
108
|
+
--timeout <seconds> # sandbox: max wait for agent response (default: 60)
|
|
109
|
+
--json # sandbox: machine-readable output incl. external_event_id (user+agent turns)
|
|
97
110
|
--confirm # confirm destructive operations without prompting
|
|
98
111
|
--no-publish # skip automatic flow publishing during push operations
|
|
99
112
|
--output, -o <file> # output file path (for export command)
|
|
@@ -201,6 +214,22 @@ Usage Examples:
|
|
|
201
214
|
newo sandbox "Test query" --verbose # With debug info
|
|
202
215
|
newo sandbox "Test query" --quiet # For automation/scripts
|
|
203
216
|
|
|
217
|
+
# Sandbox connector selection + automation (NEW v3.7.5):
|
|
218
|
+
newo sandbox --list-connectors # Show running sandbox connectors
|
|
219
|
+
newo sandbox "ping" --connector vibe_agent # Chat through specific connector
|
|
220
|
+
newo sandbox --file ./chunk1.txt --actor abc123... --json # Long message from file, JSON output
|
|
221
|
+
cat msg.txt | newo sandbox --stdin --timeout 420 --json # From stdin with 7-minute timeout
|
|
222
|
+
# --json output: {actor_id, persona_id, external_event_id, user_external_event_id,
|
|
223
|
+
# agent_external_event_id, response, elapsed_ms, timed_out, ...}
|
|
224
|
+
# Correlate a turn with its logs: newo logs --event-id <external_event_id> --json
|
|
225
|
+
|
|
226
|
+
# Live skill inspection / point edits (NEW v3.7.5):
|
|
227
|
+
newo get-skill structured_generation --project vibe --agent VibeAgent --flow VibeFlow # View live state
|
|
228
|
+
newo get-skill structured_generation --project vibe --agent VibeAgent --flow VibeFlow --json # As JSON
|
|
229
|
+
newo update-skill structured_generation --project vibe --agent VibeAgent --flow VibeFlow \\
|
|
230
|
+
--model openai/gpt54 --publish # Switch model and publish
|
|
231
|
+
newo update-skill my_skill --project p --agent a --flow f --script ./patched.nsl --publish # Replace script
|
|
232
|
+
|
|
204
233
|
# Analytics logs (NEW v3.5.0):
|
|
205
234
|
newo logs # Last 1 hour of logs
|
|
206
235
|
newo logs --hours 24 # Last 24 hours
|
|
@@ -12,7 +12,12 @@
|
|
|
12
12
|
* newo logs --follow # Tail mode (poll for new logs)
|
|
13
13
|
* newo logs --json # Output as JSON
|
|
14
14
|
*/
|
|
15
|
-
import type {
|
|
15
|
+
import type { AxiosInstance } from 'axios';
|
|
16
|
+
import type { MultiCustomerConfig, LogEntry, LogsQueryParams, LogsResponse, CliArgs } from '../../types.js';
|
|
17
|
+
type GetLogsFn = (client: AxiosInstance, params: LogsQueryParams) => Promise<LogsResponse>;
|
|
16
18
|
export declare function handleLogsCommand(customerConfig: MultiCustomerConfig, args: CliArgs, verbose: boolean): Promise<void>;
|
|
19
|
+
export declare function collectLogsForDisplay(client: AxiosInstance, params: LogsQueryParams, nameFilter?: string | null, getLogsFn?: GetLogsFn): Promise<LogEntry[]>;
|
|
20
|
+
export declare function fetchAndDisplayLogs(client: AxiosInstance, params: LogsQueryParams, asJson: boolean, raw: boolean, nameFilter?: string | null, getLogsFn?: GetLogsFn): Promise<void>;
|
|
17
21
|
export declare function printLogsHelp(): void;
|
|
22
|
+
export {};
|
|
18
23
|
//# sourceMappingURL=logs.d.ts.map
|
|
@@ -85,7 +85,14 @@ function formatLogEntryCompact(log, showColors = true) {
|
|
|
85
85
|
export async function handleLogsCommand(customerConfig, args, verbose) {
|
|
86
86
|
// Select customer
|
|
87
87
|
const selectedCustomer = requireSingleCustomer(customerConfig, args.customer);
|
|
88
|
-
|
|
88
|
+
// Keep stdout machine-readable when JSON output is requested (for piping to jq etc.)
|
|
89
|
+
const machineOutput = Boolean(args.json || args.raw);
|
|
90
|
+
if (machineOutput) {
|
|
91
|
+
process.env.NEWO_QUIET_MODE = 'true'; // suppress auth logging on stdout
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
console.log(`📊 Fetching logs for ${selectedCustomer.idn}...`);
|
|
95
|
+
}
|
|
89
96
|
// Get access token and create client
|
|
90
97
|
const token = await getValidAccessToken(selectedCustomer);
|
|
91
98
|
const client = await makeClient(verbose, token);
|
|
@@ -146,21 +153,59 @@ export async function handleLogsCommand(customerConfig, args, verbose) {
|
|
|
146
153
|
const follow = Boolean(args.follow || args.f);
|
|
147
154
|
const asJson = Boolean(args.json);
|
|
148
155
|
const raw = Boolean(args.raw);
|
|
156
|
+
// --name filters by data.name (e.g. action name like Gen or GetMemory).
|
|
157
|
+
// The API has no such query param, so it is applied client-side.
|
|
158
|
+
const nameFilter = args.name ? String(args.name) : null;
|
|
149
159
|
if (follow) {
|
|
150
|
-
await tailLogs(client, params, asJson);
|
|
160
|
+
await tailLogs(client, params, asJson, nameFilter);
|
|
151
161
|
}
|
|
152
162
|
else {
|
|
153
|
-
await fetchAndDisplayLogs(client, params, asJson, raw);
|
|
163
|
+
await fetchAndDisplayLogs(client, params, asJson, raw, nameFilter);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function filterByName(logs, nameFilter) {
|
|
167
|
+
if (!nameFilter)
|
|
168
|
+
return [...logs];
|
|
169
|
+
return logs.filter(log => log.data['name'] === nameFilter);
|
|
170
|
+
}
|
|
171
|
+
export async function collectLogsForDisplay(client, params, nameFilter = null, getLogsFn = getLogs) {
|
|
172
|
+
if (!nameFilter) {
|
|
173
|
+
const response = await getLogsFn(client, params);
|
|
174
|
+
return [...response.items];
|
|
175
|
+
}
|
|
176
|
+
const pageSize = Number.isFinite(params.per) && params.per && params.per > 0 ? params.per : 50;
|
|
177
|
+
let page = Number.isFinite(params.page) && params.page && params.page > 0 ? params.page : 1;
|
|
178
|
+
const logs = [];
|
|
179
|
+
while (true) {
|
|
180
|
+
const response = await getLogsFn(client, {
|
|
181
|
+
...params,
|
|
182
|
+
page,
|
|
183
|
+
per: pageSize
|
|
184
|
+
});
|
|
185
|
+
logs.push(...filterByName(response.items, nameFilter));
|
|
186
|
+
if (response.items.length < pageSize) {
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
page++;
|
|
154
190
|
}
|
|
191
|
+
return logs;
|
|
155
192
|
}
|
|
156
|
-
async function fetchAndDisplayLogs(client, params, asJson, raw) {
|
|
193
|
+
export async function fetchAndDisplayLogs(client, params, asJson, raw, nameFilter = null, getLogsFn = getLogs) {
|
|
157
194
|
try {
|
|
158
|
-
const
|
|
159
|
-
const logs = response.items;
|
|
195
|
+
const logs = await collectLogsForDisplay(client, params, nameFilter, getLogsFn);
|
|
160
196
|
if (asJson) {
|
|
161
197
|
console.log(JSON.stringify(logs, null, 2));
|
|
162
198
|
return;
|
|
163
199
|
}
|
|
200
|
+
// --raw is a machine-readable JSONL contract: stdout must contain only
|
|
201
|
+
// one JSON object per log line, with no banners or empty-result text.
|
|
202
|
+
if (raw) {
|
|
203
|
+
const sortedLogs = [...logs].sort((a, b) => new Date(a.datetime).getTime() - new Date(b.datetime).getTime());
|
|
204
|
+
for (const log of sortedLogs) {
|
|
205
|
+
console.log(JSON.stringify(log));
|
|
206
|
+
}
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
164
209
|
if (logs.length === 0) {
|
|
165
210
|
console.log('\nNo logs found for the specified criteria.');
|
|
166
211
|
return;
|
|
@@ -171,12 +216,7 @@ async function fetchAndDisplayLogs(client, params, asJson, raw) {
|
|
|
171
216
|
// Detect if stdout is a TTY (supports colors)
|
|
172
217
|
const useColors = process.stdout.isTTY !== false;
|
|
173
218
|
for (const log of sortedLogs) {
|
|
174
|
-
|
|
175
|
-
console.log(JSON.stringify(log));
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
console.log(formatLogEntry(log, useColors));
|
|
179
|
-
}
|
|
219
|
+
console.log(formatLogEntry(log, useColors));
|
|
180
220
|
}
|
|
181
221
|
console.log(`\n✅ Displayed ${logs.length} log entries`);
|
|
182
222
|
}
|
|
@@ -185,7 +225,7 @@ async function fetchAndDisplayLogs(client, params, asJson, raw) {
|
|
|
185
225
|
console.error('Failed to fetch logs:', err.response?.status, err.response?.data || err.message);
|
|
186
226
|
}
|
|
187
227
|
}
|
|
188
|
-
async function tailLogs(client, params, asJson) {
|
|
228
|
+
async function tailLogs(client, params, asJson, nameFilter = null) {
|
|
189
229
|
console.log('🔄 Watching for new logs (Ctrl+C to stop)...\n');
|
|
190
230
|
const seenLogIds = new Set();
|
|
191
231
|
let lastCheckTime = params.from_datetime || new Date(Date.now() - 60 * 60 * 1000).toISOString();
|
|
@@ -201,7 +241,7 @@ async function tailLogs(client, params, asJson) {
|
|
|
201
241
|
per: 100
|
|
202
242
|
};
|
|
203
243
|
const response = await getLogs(client, pollParams);
|
|
204
|
-
const logs = response.items;
|
|
244
|
+
const logs = filterByName(response.items, nameFilter);
|
|
205
245
|
// Filter out already seen logs and sort by time
|
|
206
246
|
const newLogs = logs
|
|
207
247
|
.filter(log => !seenLogIds.has(log.log_id))
|
|
@@ -257,6 +297,7 @@ Filter Options:
|
|
|
257
297
|
--flow <idn> Filter by flow IDN
|
|
258
298
|
--skill <idn> Filter by skill IDN
|
|
259
299
|
--message <text> Search in log messages
|
|
300
|
+
--name <ActionName> Filter by action name in data.name, e.g. Gen, GetMemory (client-side)
|
|
260
301
|
--event-id <uuid> Filter by external event ID
|
|
261
302
|
--runtime-id <uuid> Filter by runtime context ID
|
|
262
303
|
--actor-id <uuid> Filter by user actor ID
|
|
@@ -278,6 +319,13 @@ Examples:
|
|
|
278
319
|
newo logs --type call --skill CreateActor # Skill calls for CreateActor
|
|
279
320
|
newo logs --flow CACreatorFlow --follow # Tail logs for specific flow
|
|
280
321
|
newo logs --json --per 100 # Get 100 logs as JSON
|
|
322
|
+
newo logs --type call --name Gen --json # Only Gen action calls
|
|
323
|
+
|
|
324
|
+
Notes:
|
|
325
|
+
The model used for a turn is in data.source.model of the --json output —
|
|
326
|
+
do NOT infer it from actor/agent names.
|
|
327
|
+
external_event_id (newo sandbox --json) correlates a chat turn with its
|
|
328
|
+
logs: newo logs --event-id <id>
|
|
281
329
|
`);
|
|
282
330
|
}
|
|
283
331
|
//# sourceMappingURL=logs.js.map
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Sandbox Chat Command Handler
|
|
3
3
|
* Supports both single-command and interactive modes
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* npx newo sandbox "Hello" --customer <idn> # Single message mode
|
|
7
|
+
* npx newo sandbox --actor <actor_id> "Follow up" # Continue existing chat
|
|
8
|
+
* npx newo sandbox "ping" --connector vibe_agent # Select specific connector (v3.7.5)
|
|
9
|
+
* npx newo sandbox --list-connectors # Show running sandbox connectors (v3.7.5)
|
|
10
|
+
* npx newo sandbox --file ./msg.txt --actor <id> # Message from file (v3.7.5)
|
|
11
|
+
* cat msg.txt | npx newo sandbox --stdin # Message from stdin (v3.7.5)
|
|
12
|
+
* npx newo sandbox "ping" --timeout 420 # Custom response timeout in seconds (v3.7.5)
|
|
13
|
+
* npx newo sandbox "ping" --json # Machine-readable output (v3.7.5)
|
|
4
14
|
*/
|
|
5
15
|
import type { MultiCustomerConfig, CliArgs } from '../../types.js';
|
|
6
16
|
/**
|
|
7
17
|
* Handle sandbox command
|
|
8
|
-
* Usage:
|
|
9
|
-
* npx newo sandbox "Hello" --customer <idn> # Single message mode
|
|
10
|
-
* npx newo sandbox --actor <actor_id> "Follow up" # Continue existing chat
|
|
11
|
-
* npx newo sandbox --interactive # Interactive mode (TBD)
|
|
12
18
|
*/
|
|
13
19
|
export declare function handleSandboxCommand(customerConfig: MultiCustomerConfig, args: CliArgs, verbose: boolean): Promise<void>;
|
|
14
20
|
//# sourceMappingURL=sandbox.d.ts.map
|